nextjs-cms 0.0.1 → 0.5.2

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 (302) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +289 -0
  3. package/dist/api/axios/axiosInstance.d.ts +2 -0
  4. package/dist/api/axios/axiosInstance.d.ts.map +1 -0
  5. package/dist/api/axios/axiosInstance.js +8 -0
  6. package/dist/api/index.d.ts +856 -0
  7. package/dist/api/index.d.ts.map +1 -0
  8. package/dist/api/index.js +12 -0
  9. package/dist/api/lib/serverActions.d.ts +240 -0
  10. package/dist/api/lib/serverActions.d.ts.map +1 -0
  11. package/dist/api/lib/serverActions.js +834 -0
  12. package/dist/api/root.d.ts +829 -0
  13. package/dist/api/root.d.ts.map +1 -0
  14. package/dist/api/root.js +30 -0
  15. package/dist/api/routers/accountSettings.d.ts +61 -0
  16. package/dist/api/routers/accountSettings.d.ts.map +1 -0
  17. package/dist/api/routers/accountSettings.js +108 -0
  18. package/dist/api/routers/admins.d.ts +106 -0
  19. package/dist/api/routers/admins.d.ts.map +1 -0
  20. package/dist/api/routers/admins.js +219 -0
  21. package/dist/api/routers/auth.d.ts +48 -0
  22. package/dist/api/routers/auth.d.ts.map +1 -0
  23. package/dist/api/routers/auth.js +25 -0
  24. package/dist/api/routers/categorySection.d.ts +104 -0
  25. package/dist/api/routers/categorySection.d.ts.map +1 -0
  26. package/dist/api/routers/categorySection.js +38 -0
  27. package/dist/api/routers/cmsSettings.d.ts +49 -0
  28. package/dist/api/routers/cmsSettings.d.ts.map +1 -0
  29. package/dist/api/routers/cmsSettings.js +51 -0
  30. package/dist/api/routers/cpanel.d.ts +84 -0
  31. package/dist/api/routers/cpanel.d.ts.map +1 -0
  32. package/dist/api/routers/cpanel.js +216 -0
  33. package/dist/api/routers/files.d.ts +48 -0
  34. package/dist/api/routers/files.d.ts.map +1 -0
  35. package/dist/api/routers/files.js +23 -0
  36. package/dist/api/routers/gallery.d.ts +36 -0
  37. package/dist/api/routers/gallery.d.ts.map +1 -0
  38. package/dist/api/routers/gallery.js +62 -0
  39. package/dist/api/routers/googleAnalytics.d.ts +31 -0
  40. package/dist/api/routers/googleAnalytics.d.ts.map +1 -0
  41. package/dist/api/routers/googleAnalytics.js +7 -0
  42. package/dist/api/routers/hasItemsSection.d.ts +140 -0
  43. package/dist/api/routers/hasItemsSection.d.ts.map +1 -0
  44. package/dist/api/routers/hasItemsSection.js +34 -0
  45. package/dist/api/routers/navigation.d.ts +52 -0
  46. package/dist/api/routers/navigation.d.ts.map +1 -0
  47. package/dist/api/routers/navigation.js +11 -0
  48. package/dist/api/routers/simpleSection.d.ts +58 -0
  49. package/dist/api/routers/simpleSection.d.ts.map +1 -0
  50. package/dist/api/routers/simpleSection.js +12 -0
  51. package/dist/api/trpc.d.ts +107 -0
  52. package/dist/api/trpc.d.ts.map +1 -0
  53. package/dist/api/trpc.js +72 -0
  54. package/dist/auth/axios/axiosInstance.d.ts +2 -0
  55. package/dist/auth/axios/axiosInstance.d.ts.map +1 -0
  56. package/dist/auth/axios/axiosInstance.js +8 -0
  57. package/dist/auth/csrf.d.ts +30 -0
  58. package/dist/auth/csrf.d.ts.map +1 -0
  59. package/dist/auth/csrf.js +76 -0
  60. package/dist/auth/hooks/index.d.ts +4 -0
  61. package/dist/auth/hooks/index.d.ts.map +1 -0
  62. package/dist/auth/hooks/index.js +3 -0
  63. package/dist/auth/hooks/useAxiosPrivate.d.ts +5 -0
  64. package/dist/auth/hooks/useAxiosPrivate.d.ts.map +1 -0
  65. package/dist/auth/hooks/useAxiosPrivate.js +74 -0
  66. package/dist/auth/hooks/useRefreshToken.d.ts +7 -0
  67. package/dist/auth/hooks/useRefreshToken.d.ts.map +1 -0
  68. package/dist/auth/hooks/useRefreshToken.js +79 -0
  69. package/dist/auth/index.d.ts +23 -0
  70. package/dist/auth/index.d.ts.map +1 -0
  71. package/dist/auth/index.js +44 -0
  72. package/dist/auth/jwt.d.ts +6 -0
  73. package/dist/auth/jwt.d.ts.map +1 -0
  74. package/dist/auth/jwt.js +25 -0
  75. package/dist/auth/lib/actions.d.ts +33 -0
  76. package/dist/auth/lib/actions.d.ts.map +1 -0
  77. package/dist/auth/lib/actions.js +209 -0
  78. package/dist/auth/lib/client.d.ts +4 -0
  79. package/dist/auth/lib/client.d.ts.map +1 -0
  80. package/dist/auth/lib/client.js +46 -0
  81. package/dist/auth/lib/index.d.ts +3 -0
  82. package/dist/auth/lib/index.d.ts.map +1 -0
  83. package/dist/auth/lib/index.js +2 -0
  84. package/dist/auth/react.d.ts +106 -0
  85. package/dist/auth/react.d.ts.map +1 -0
  86. package/dist/auth/react.js +347 -0
  87. package/dist/auth/trpc.d.ts +6 -0
  88. package/dist/auth/trpc.d.ts.map +1 -0
  89. package/dist/auth/trpc.js +81 -0
  90. package/dist/core/config/config-loader.d.ts +92 -0
  91. package/dist/core/config/config-loader.d.ts.map +1 -0
  92. package/dist/core/config/config-loader.js +230 -0
  93. package/dist/core/config/index.d.ts +3 -0
  94. package/dist/core/config/index.d.ts.map +1 -0
  95. package/dist/core/config/index.js +1 -0
  96. package/dist/core/config/loader.d.ts +2 -0
  97. package/dist/core/config/loader.d.ts.map +1 -0
  98. package/dist/core/config/loader.js +42 -0
  99. package/dist/core/db/index.d.ts +2 -0
  100. package/dist/core/db/index.d.ts.map +1 -0
  101. package/dist/core/db/index.js +1 -0
  102. package/dist/core/db/table-checker/DbTable.d.ts +6 -0
  103. package/dist/core/db/table-checker/DbTable.d.ts.map +1 -0
  104. package/dist/core/db/table-checker/DbTable.js +5 -0
  105. package/dist/core/db/table-checker/MysqlTable.d.ts +34 -0
  106. package/dist/core/db/table-checker/MysqlTable.d.ts.map +1 -0
  107. package/dist/core/db/table-checker/MysqlTable.js +102 -0
  108. package/dist/core/db/table-checker/index.d.ts +2 -0
  109. package/dist/core/db/table-checker/index.d.ts.map +1 -0
  110. package/dist/core/db/table-checker/index.js +1 -0
  111. package/dist/core/factories/FieldFactory.d.ts +124 -0
  112. package/dist/core/factories/FieldFactory.d.ts.map +1 -0
  113. package/dist/core/factories/FieldFactory.js +411 -0
  114. package/dist/core/factories/SectionFactory.d.ts +110 -0
  115. package/dist/core/factories/SectionFactory.d.ts.map +1 -0
  116. package/dist/core/factories/SectionFactory.js +415 -0
  117. package/dist/core/factories/index.d.ts +3 -0
  118. package/dist/core/factories/index.d.ts.map +1 -0
  119. package/dist/core/factories/index.js +2 -0
  120. package/dist/core/fields/checkbox.d.ts +63 -0
  121. package/dist/core/fields/checkbox.d.ts.map +1 -0
  122. package/dist/core/fields/checkbox.js +62 -0
  123. package/dist/core/fields/color.d.ts +84 -0
  124. package/dist/core/fields/color.d.ts.map +1 -0
  125. package/dist/core/fields/color.js +91 -0
  126. package/dist/core/fields/date.d.ts +100 -0
  127. package/dist/core/fields/date.d.ts.map +1 -0
  128. package/dist/core/fields/date.js +108 -0
  129. package/dist/core/fields/document.d.ts +180 -0
  130. package/dist/core/fields/document.d.ts.map +1 -0
  131. package/dist/core/fields/document.js +277 -0
  132. package/dist/core/fields/field-group.d.ts +18 -0
  133. package/dist/core/fields/field-group.d.ts.map +1 -0
  134. package/dist/core/fields/field-group.js +6 -0
  135. package/dist/core/fields/field.d.ts +126 -0
  136. package/dist/core/fields/field.d.ts.map +1 -0
  137. package/dist/core/fields/field.js +148 -0
  138. package/dist/core/fields/fileField.d.ts +15 -0
  139. package/dist/core/fields/fileField.d.ts.map +1 -0
  140. package/dist/core/fields/fileField.js +5 -0
  141. package/dist/core/fields/index.d.ts +65 -0
  142. package/dist/core/fields/index.d.ts.map +1 -0
  143. package/dist/core/fields/index.js +18 -0
  144. package/dist/core/fields/map.d.ts +167 -0
  145. package/dist/core/fields/map.d.ts.map +1 -0
  146. package/dist/core/fields/map.js +152 -0
  147. package/dist/core/fields/number.d.ts +186 -0
  148. package/dist/core/fields/number.d.ts.map +1 -0
  149. package/dist/core/fields/number.js +241 -0
  150. package/dist/core/fields/password.d.ts +109 -0
  151. package/dist/core/fields/password.d.ts.map +1 -0
  152. package/dist/core/fields/password.js +133 -0
  153. package/dist/core/fields/photo.d.ts +289 -0
  154. package/dist/core/fields/photo.d.ts.map +1 -0
  155. package/dist/core/fields/photo.js +410 -0
  156. package/dist/core/fields/richText.d.ts +295 -0
  157. package/dist/core/fields/richText.d.ts.map +1 -0
  158. package/dist/core/fields/richText.js +338 -0
  159. package/dist/core/fields/select.d.ts +366 -0
  160. package/dist/core/fields/select.d.ts.map +1 -0
  161. package/dist/core/fields/select.js +499 -0
  162. package/dist/core/fields/selectMultiple.d.ts +236 -0
  163. package/dist/core/fields/selectMultiple.d.ts.map +1 -0
  164. package/dist/core/fields/selectMultiple.js +417 -0
  165. package/dist/core/fields/tags.d.ts +131 -0
  166. package/dist/core/fields/tags.d.ts.map +1 -0
  167. package/dist/core/fields/tags.js +105 -0
  168. package/dist/core/fields/text.d.ts +136 -0
  169. package/dist/core/fields/text.d.ts.map +1 -0
  170. package/dist/core/fields/text.js +157 -0
  171. package/dist/core/fields/textArea.d.ts +107 -0
  172. package/dist/core/fields/textArea.d.ts.map +1 -0
  173. package/dist/core/fields/textArea.js +126 -0
  174. package/dist/core/fields/video.d.ts +148 -0
  175. package/dist/core/fields/video.d.ts.map +1 -0
  176. package/dist/core/fields/video.js +248 -0
  177. package/dist/core/helpers/entity.d.ts +8 -0
  178. package/dist/core/helpers/entity.d.ts.map +1 -0
  179. package/dist/core/helpers/entity.js +27 -0
  180. package/dist/core/helpers/index.d.ts +5 -0
  181. package/dist/core/helpers/index.d.ts.map +1 -0
  182. package/dist/core/helpers/index.js +3 -0
  183. package/dist/core/index.d.ts +8 -0
  184. package/dist/core/index.d.ts.map +1 -0
  185. package/dist/core/index.js +7 -0
  186. package/dist/core/sections/category.d.ts +283 -0
  187. package/dist/core/sections/category.d.ts.map +1 -0
  188. package/dist/core/sections/category.js +147 -0
  189. package/dist/core/sections/hasItems.d.ts +632 -0
  190. package/dist/core/sections/hasItems.d.ts.map +1 -0
  191. package/dist/core/sections/hasItems.js +144 -0
  192. package/dist/core/sections/index.d.ts +5 -0
  193. package/dist/core/sections/index.d.ts.map +1 -0
  194. package/dist/core/sections/index.js +4 -0
  195. package/dist/core/sections/section.d.ts +226 -0
  196. package/dist/core/sections/section.d.ts.map +1 -0
  197. package/dist/core/sections/section.js +341 -0
  198. package/dist/core/sections/simple.d.ts +99 -0
  199. package/dist/core/sections/simple.d.ts.map +1 -0
  200. package/dist/core/sections/simple.js +95 -0
  201. package/dist/core/security/dom.d.ts +11 -0
  202. package/dist/core/security/dom.d.ts.map +1 -0
  203. package/dist/core/security/dom.js +92 -0
  204. package/dist/core/submit/ItemEditSubmit.d.ts +76 -0
  205. package/dist/core/submit/ItemEditSubmit.d.ts.map +1 -0
  206. package/dist/core/submit/ItemEditSubmit.js +186 -0
  207. package/dist/core/submit/NewItemSubmit.d.ts +14 -0
  208. package/dist/core/submit/NewItemSubmit.d.ts.map +1 -0
  209. package/dist/core/submit/NewItemSubmit.js +93 -0
  210. package/dist/core/submit/SimpleSectionSubmit.d.ts +13 -0
  211. package/dist/core/submit/SimpleSectionSubmit.d.ts.map +1 -0
  212. package/dist/core/submit/SimpleSectionSubmit.js +93 -0
  213. package/dist/core/submit/index.d.ts +5 -0
  214. package/dist/core/submit/index.d.ts.map +1 -0
  215. package/dist/core/submit/index.js +4 -0
  216. package/dist/core/submit/submit.d.ts +116 -0
  217. package/dist/core/submit/submit.d.ts.map +1 -0
  218. package/dist/core/submit/submit.js +479 -0
  219. package/dist/core/types/index.d.ts +280 -0
  220. package/dist/core/types/index.d.ts.map +1 -0
  221. package/dist/core/types/index.js +1 -0
  222. package/dist/db/client.d.ts +9 -0
  223. package/dist/db/client.d.ts.map +1 -0
  224. package/dist/db/client.js +19 -0
  225. package/dist/db/config.d.ts +6 -0
  226. package/dist/db/config.d.ts.map +1 -0
  227. package/dist/db/config.js +22 -0
  228. package/dist/db/drizzle.config.d.ts +6 -0
  229. package/dist/db/drizzle.config.d.ts.map +1 -0
  230. package/dist/db/drizzle.config.js +18 -0
  231. package/dist/db/index.d.ts +3 -0
  232. package/dist/db/index.d.ts.map +1 -0
  233. package/dist/db/index.js +3 -0
  234. package/dist/db/schema.d.ts +639 -0
  235. package/dist/db/schema.d.ts.map +1 -0
  236. package/dist/db/schema.js +73 -0
  237. package/dist/index.d.ts +7 -1
  238. package/dist/index.d.ts.map +1 -1
  239. package/dist/index.js +7 -1
  240. package/dist/translations/dictionaries/ar.json +279 -0
  241. package/dist/translations/dictionaries/en.json +279 -0
  242. package/dist/translations/index.d.ts +3 -0
  243. package/dist/translations/index.d.ts.map +1 -0
  244. package/dist/translations/index.js +15 -0
  245. package/dist/utils/CpanelApi.d.ts +25 -0
  246. package/dist/utils/CpanelApi.d.ts.map +1 -0
  247. package/dist/utils/CpanelApi.js +64 -0
  248. package/dist/utils/constants.d.ts +14 -0
  249. package/dist/utils/constants.d.ts.map +1 -0
  250. package/dist/utils/constants.js +61 -0
  251. package/dist/utils/index.d.ts +5 -0
  252. package/dist/utils/index.d.ts.map +1 -0
  253. package/dist/utils/index.js +4 -0
  254. package/dist/utils/utils.d.ts +60 -0
  255. package/dist/utils/utils.d.ts.map +1 -0
  256. package/dist/utils/utils.js +132 -0
  257. package/dist/validators/checkbox.d.ts +4 -0
  258. package/dist/validators/checkbox.d.ts.map +1 -0
  259. package/dist/validators/checkbox.js +12 -0
  260. package/dist/validators/color.d.ts +4 -0
  261. package/dist/validators/color.d.ts.map +1 -0
  262. package/dist/validators/color.js +7 -0
  263. package/dist/validators/date.d.ts +4 -0
  264. package/dist/validators/date.d.ts.map +1 -0
  265. package/dist/validators/date.js +5 -0
  266. package/dist/validators/document.d.ts +4 -0
  267. package/dist/validators/document.d.ts.map +1 -0
  268. package/dist/validators/document.js +57 -0
  269. package/dist/validators/index.d.ts +15 -0
  270. package/dist/validators/index.d.ts.map +1 -0
  271. package/dist/validators/index.js +14 -0
  272. package/dist/validators/map.d.ts +4 -0
  273. package/dist/validators/map.d.ts.map +1 -0
  274. package/dist/validators/map.js +5 -0
  275. package/dist/validators/number.d.ts +4 -0
  276. package/dist/validators/number.d.ts.map +1 -0
  277. package/dist/validators/number.js +20 -0
  278. package/dist/validators/password.d.ts +4 -0
  279. package/dist/validators/password.d.ts.map +1 -0
  280. package/dist/validators/password.js +11 -0
  281. package/dist/validators/photo.d.ts +4 -0
  282. package/dist/validators/photo.d.ts.map +1 -0
  283. package/dist/validators/photo.js +100 -0
  284. package/dist/validators/richText.d.ts +4 -0
  285. package/dist/validators/richText.d.ts.map +1 -0
  286. package/dist/validators/richText.js +8 -0
  287. package/dist/validators/select-multiple.d.ts +10 -0
  288. package/dist/validators/select-multiple.d.ts.map +1 -0
  289. package/dist/validators/select-multiple.js +20 -0
  290. package/dist/validators/select.d.ts +4 -0
  291. package/dist/validators/select.d.ts.map +1 -0
  292. package/dist/validators/select.js +5 -0
  293. package/dist/validators/text.d.ts +4 -0
  294. package/dist/validators/text.d.ts.map +1 -0
  295. package/dist/validators/text.js +7 -0
  296. package/dist/validators/textarea.d.ts +4 -0
  297. package/dist/validators/textarea.d.ts.map +1 -0
  298. package/dist/validators/textarea.js +7 -0
  299. package/dist/validators/video.d.ts +4 -0
  300. package/dist/validators/video.d.ts.map +1 -0
  301. package/dist/validators/video.js +57 -0
  302. package/package.json +150 -6
@@ -0,0 +1,126 @@
1
+ import { Field, baseFieldConfigSchema } from './field';
2
+ import { entityKind } from '../helpers';
3
+ import * as z from 'zod';
4
+ import { escapeHTML } from '../security/dom';
5
+ const configSchema = z.strictObject({
6
+ placeholder: z.string().optional().describe('The placeholder text for the field'),
7
+ minLength: z.number().optional().describe('The minimum length of the field value'),
8
+ maxLength: z.number().optional().describe('The maximum length of the field value'),
9
+ /**
10
+ * Whether to sanitize the value before saving it to the database.
11
+ * If true, the value will be escaped to prevent XSS attacks.
12
+ * If false, the value will be saved as is (raw input).
13
+ * @default false
14
+ */
15
+ sanitize: z.boolean().optional().describe('Sanitize the value before saving'),
16
+ });
17
+ export class TextAreaField extends Field {
18
+ static [entityKind] = 'TextAreaField';
19
+ maxLength;
20
+ minLength;
21
+ placeholder;
22
+ sanitize;
23
+ constructor(config) {
24
+ super(config, 'textarea');
25
+ this.maxLength = config.maxLength;
26
+ this.minLength = config.minLength;
27
+ this.placeholder = config.placeholder;
28
+ this.sanitize = config.sanitize ?? false;
29
+ }
30
+ exportForClient() {
31
+ return {
32
+ ...super.exportForClient(),
33
+ maxLength: this.maxLength,
34
+ minLength: this.minLength,
35
+ placeholder: this.placeholder,
36
+ sanitize: this.sanitize,
37
+ };
38
+ }
39
+ /**
40
+ * Sanitize the value
41
+ */
42
+ sanitizeValue() {
43
+ /**
44
+ * Check if the value is not undefined
45
+ */
46
+ if (this.value !== undefined && this.sanitize) {
47
+ /**
48
+ * Sanitize the value
49
+ */
50
+ this.value = escapeHTML(this.value);
51
+ }
52
+ }
53
+ /**
54
+ * Get the value of the field
55
+ */
56
+ getValue() {
57
+ return this.value;
58
+ }
59
+ checkRequired() {
60
+ /**
61
+ * Check if the field is required
62
+ */
63
+ if (this.required) {
64
+ if (!this.value || this.value.trim().length === 0) {
65
+ throw new Error(`Field ${this.label} is required`);
66
+ }
67
+ }
68
+ }
69
+ /**
70
+ * Prepare the field for submission
71
+ */
72
+ async prepareForSubmission() {
73
+ /**
74
+ * Sanitize the value
75
+ */
76
+ this.sanitizeValue();
77
+ /**
78
+ * Check minimum length
79
+ */
80
+ if (this.minLength) {
81
+ if (this.minLength > this.value.length) {
82
+ throw new Error(`Field ${this.label} must be at least ${this.minLength} characters long`);
83
+ }
84
+ }
85
+ /**
86
+ * Check maximum length
87
+ */
88
+ if (this.maxLength) {
89
+ if (this.maxLength < this.value.length) {
90
+ throw new Error(`Field ${this.label} must be at most ${this.maxLength} characters long`);
91
+ }
92
+ }
93
+ }
94
+ }
95
+ const optionsSchema = z.strictObject({
96
+ ...baseFieldConfigSchema.shape,
97
+ ...configSchema.shape,
98
+ });
99
+ const textAreaFieldConfigSchema = z.strictObject({
100
+ ...optionsSchema.shape,
101
+ type: z.literal('textarea').describe('The type of the field'),
102
+ build: z.function().output(z.instanceof(TextAreaField)).describe('Build a TextAreaField instance from this config'),
103
+ });
104
+ /**
105
+ * Helper function to create a textarea field configuration
106
+ * Returns a config object with a build() method that can be serialized and used anywhere
107
+ * @param field
108
+ */
109
+ export function textAreaField(field) {
110
+ /**
111
+ * Validate the field config
112
+ */
113
+ const result = optionsSchema.safeParse(field);
114
+ if (!result.success) {
115
+ throw new Error(`[Field: ${field.name}]: ${z.prettifyError(result.error)}`);
116
+ }
117
+ const config = {
118
+ ...field,
119
+ type: 'textarea',
120
+ build() {
121
+ // Use the original field config directly (it doesn't have build() method)
122
+ return new TextAreaField(field);
123
+ },
124
+ };
125
+ return config;
126
+ }
@@ -0,0 +1,148 @@
1
+ import type { BaseFieldConfig } from './field';
2
+ import { entityKind } from '../helpers';
3
+ import { FileField } from './fileField';
4
+ import * as z from 'zod';
5
+ declare const configSchema: z.ZodObject<{
6
+ /**
7
+ * Maximum file size
8
+ */
9
+ maxFileSize: z.ZodOptional<z.ZodObject<{
10
+ size: z.ZodNumber;
11
+ unit: z.ZodEnum<{
12
+ kb: "kb";
13
+ mb: "mb";
14
+ }>;
15
+ }, z.core.$strict>>;
16
+ /**
17
+ * Allowed file types
18
+ * @default ['mp4']
19
+ */
20
+ type: z.ZodOptional<z.ZodArray<z.ZodEnum<{
21
+ mp4: "mp4";
22
+ webm: "webm";
23
+ ogg: "ogg";
24
+ }>>>;
25
+ }, z.core.$strict>;
26
+ type Config = z.infer<typeof configSchema>;
27
+ export declare class VideoField extends FileField<'video', Config> {
28
+ static readonly [entityKind]: string;
29
+ readonly maxFileSize: {
30
+ size: number;
31
+ unit: 'kb' | 'mb';
32
+ };
33
+ readonly mimeType: string[];
34
+ readonly extensions: string[];
35
+ /**
36
+ * _file is the file object if it's present
37
+ * Whereas the value is the path to the file
38
+ */
39
+ private _file;
40
+ private _buffer;
41
+ private _folder;
42
+ private _allowedExtensions;
43
+ readonly uploadsFolder: string;
44
+ constructor(config: BaseFieldConfig<Config>, file?: File);
45
+ exportForClient(): {
46
+ maxFileSize: {
47
+ size: number;
48
+ unit: "kb" | "mb";
49
+ };
50
+ extensions: string[];
51
+ mimeType: string[];
52
+ type: "video";
53
+ name: string;
54
+ label: string;
55
+ required: boolean;
56
+ conditionalFields: import("../types").ConditionalField[];
57
+ readonly: boolean;
58
+ defaultValue: any;
59
+ value: any;
60
+ };
61
+ readChunkFromFile({ arrayBuffer, length, startPosition, }: {
62
+ readonly arrayBuffer: ArrayBuffer;
63
+ readonly length: number;
64
+ readonly startPosition?: number;
65
+ }): Promise<Uint8Array>;
66
+ /**
67
+ * Write the file to the disk
68
+ */
69
+ writeToFile(): Promise<void>;
70
+ postSubmit(folder: string): Promise<void>;
71
+ postSubmitRollback(): Promise<void>;
72
+ /**
73
+ * Get the value of the field
74
+ */
75
+ getValue(): string;
76
+ setFileName(value: string): void;
77
+ setValue(value: any): void;
78
+ setFile(file: File): void;
79
+ checkRequired(): void;
80
+ /**
81
+ * Prepare the field for submission
82
+ */
83
+ prepareForSubmission(): Promise<void>;
84
+ }
85
+ export type VideoFieldClientConfig = ReturnType<VideoField['exportForClient']>;
86
+ declare const optionsSchema: z.ZodObject<{
87
+ /**
88
+ * Maximum file size
89
+ */
90
+ maxFileSize: z.ZodOptional<z.ZodObject<{
91
+ size: z.ZodNumber;
92
+ unit: z.ZodEnum<{
93
+ kb: "kb";
94
+ mb: "mb";
95
+ }>;
96
+ }, z.core.$strict>>;
97
+ /**
98
+ * Allowed file types
99
+ * @default ['mp4']
100
+ */
101
+ type: z.ZodOptional<z.ZodArray<z.ZodEnum<{
102
+ mp4: "mp4";
103
+ webm: "webm";
104
+ ogg: "ogg";
105
+ }>>>;
106
+ name: z.ZodString;
107
+ label: z.ZodOptional<z.ZodString>;
108
+ required: z.ZodOptional<z.ZodBoolean>;
109
+ defaultValue: z.ZodOptional<z.ZodAny>;
110
+ order: z.ZodOptional<z.ZodNumber>;
111
+ conditionalRules: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types").ConditionalRule, import("../types").ConditionalRule>>>;
112
+ adminGenerated: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodLiteral<false>, z.ZodLiteral<"readonly">]>>;
113
+ }, z.core.$strict>;
114
+ declare const videoFieldConfigSchema: z.ZodObject<{
115
+ type: z.ZodLiteral<"video">;
116
+ build: z.ZodFunction<z.core.$ZodFunctionArgs, z.ZodCustom<VideoField, VideoField>>;
117
+ /**
118
+ * Maximum file size
119
+ */
120
+ maxFileSize: z.ZodOptional<z.ZodObject<{
121
+ size: z.ZodNumber;
122
+ unit: z.ZodEnum<{
123
+ kb: "kb";
124
+ mb: "mb";
125
+ }>;
126
+ }, z.core.$strict>>;
127
+ name: z.ZodString;
128
+ label: z.ZodOptional<z.ZodString>;
129
+ required: z.ZodOptional<z.ZodBoolean>;
130
+ defaultValue: z.ZodOptional<z.ZodAny>;
131
+ order: z.ZodOptional<z.ZodNumber>;
132
+ conditionalRules: z.ZodOptional<z.ZodArray<z.ZodCustom<import("../types").ConditionalRule, import("../types").ConditionalRule>>>;
133
+ adminGenerated: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<true>, z.ZodLiteral<false>, z.ZodLiteral<"readonly">]>>;
134
+ }, z.core.$strict>;
135
+ /**
136
+ * Video field configuration type
137
+ * This is a plain object that can be serialized and used anywhere
138
+ * The build() method allows creating a VideoField instance when needed
139
+ */
140
+ export type VideoFieldConfig = z.infer<typeof videoFieldConfigSchema>;
141
+ /**
142
+ * Helper function to create a video field configuration
143
+ * Returns a config object with a build() method that can be serialized and used anywhere
144
+ * @param field
145
+ */
146
+ export declare function videoField(field: z.infer<typeof optionsSchema>): VideoFieldConfig;
147
+ export {};
148
+ //# sourceMappingURL=video.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.d.ts","sourceRoot":"","sources":["../../../src/core/fields/video.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAIvC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAA;AAExB,QAAA,MAAM,YAAY;IACd;;OAEG;;;;;;;;IAQH;;;OAGG;;;;;;kBAKL,CAAA;AAEF,KAAK,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAA;AAE1C,qBAAa,UAAW,SAAQ,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC;IACtD,gBAAyB,CAAC,UAAU,CAAC,EAAE,MAAM,CAAe;IAC5D,QAAQ,CAAC,WAAW,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAA;KAAE,CAAA;IACzD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,CAAA;IAE7B;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAkB;IAC/B,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,OAAO,CAAoB;IACnC,OAAO,CAAC,kBAAkB,CAAU;IACpC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAyC;gBAC3D,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI;IA6BxC,eAAe;;kBA1CD,MAAM;kBAAQ,IAAI,GAAG,IAAI;;;;;;;;;;;;;IAmDjD,iBAAiB,CAAC,EACpB,WAAW,EACX,MAAM,EACN,aAAiB,GACpB,EAAE;QACC,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAA;QACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;QACvB,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAClC,GAAG,OAAO,CAAC,UAAU,CAAC;IAevB;;OAEG;IACG,WAAW;IAiCK,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKzC,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC;IAczD;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIX,WAAW,CAAC,KAAK,EAAE,MAAM;IAIvB,QAAQ,CAAC,KAAK,EAAE,GAAG;IAQnB,OAAO,CAAC,IAAI,EAAE,IAAI;IAK3B,aAAa;IAYb;;OAEG;IACG,oBAAoB;CAoD7B;AAED,MAAM,MAAM,sBAAsB,GAAG,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,CAAA;AAE9E,QAAA,MAAM,aAAa;IAxPf;;OAEG;;;;;;;;IAQH;;;OAGG;;;;;;;;;;;;;kBA8OL,CAAA;AAEF,QAAA,MAAM,sBAAsB;;;IA7PxB;;OAEG;;;;;;;;;;;;;;;kBA+PL,CAAA;AAEF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAA;AAErE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,GAAG,gBAAgB,CAmBjF"}
@@ -0,0 +1,248 @@
1
+ import { baseFieldConfigSchema } from './field';
2
+ import { entityKind } from '../helpers';
3
+ import fs from 'fs';
4
+ import { customAlphabet } from 'nanoid';
5
+ import path from 'path';
6
+ import { FileField } from './fileField';
7
+ import { getCMSConfig } from '../config';
8
+ import * as z from 'zod';
9
+ const configSchema = z.strictObject({
10
+ /**
11
+ * Maximum file size
12
+ */
13
+ maxFileSize: z
14
+ .strictObject({
15
+ size: z.number().describe('The size value'),
16
+ unit: z.enum(['kb', 'mb']).describe('The unit of the size'),
17
+ })
18
+ .optional()
19
+ .describe('Maximum file size'),
20
+ /**
21
+ * Allowed file types
22
+ * @default ['mp4']
23
+ */
24
+ type: z
25
+ .array(z.enum(['mp4', 'webm', 'ogg']))
26
+ .optional()
27
+ .describe('Allowed file types'),
28
+ });
29
+ export class VideoField extends FileField {
30
+ static [entityKind] = 'VideoField';
31
+ maxFileSize;
32
+ mimeType;
33
+ extensions;
34
+ /**
35
+ * _file is the file object if it's present
36
+ * Whereas the value is the path to the file
37
+ */
38
+ _file;
39
+ _buffer;
40
+ _folder;
41
+ _allowedExtensions;
42
+ uploadsFolder = getCMSConfig().files.upload.uploadPath;
43
+ constructor(config, file) {
44
+ super(config, 'video');
45
+ this._file = file;
46
+ this.extensions = config.type ?? ['mp4'];
47
+ this.maxFileSize = config.maxFileSize ?? { size: 2, unit: 'mb' };
48
+ /**
49
+ * Extract the mime types from the extensions
50
+ * @link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
51
+ */
52
+ this.mimeType = this.extensions.map((e) => {
53
+ switch (e) {
54
+ case 'mp4':
55
+ return 'video/mp4';
56
+ case 'webm':
57
+ return 'video/webm';
58
+ case 'ogg':
59
+ return 'video/ogg';
60
+ default:
61
+ return '';
62
+ }
63
+ });
64
+ /**
65
+ * Set the allowed extensions, add jpg if jpeg is present
66
+ */
67
+ this._allowedExtensions = this.extensions;
68
+ }
69
+ exportForClient() {
70
+ return {
71
+ ...super.exportForClient(),
72
+ maxFileSize: this.maxFileSize,
73
+ extensions: this._allowedExtensions,
74
+ mimeType: this.mimeType,
75
+ };
76
+ }
77
+ async readChunkFromFile({ arrayBuffer, length, startPosition = 0, }) {
78
+ return new Promise(async (resolve, reject) => {
79
+ try {
80
+ if (arrayBuffer) {
81
+ const buffer = new Uint8Array(arrayBuffer, startPosition, length);
82
+ resolve(buffer);
83
+ }
84
+ else {
85
+ reject(new Error('Error reading file'));
86
+ }
87
+ }
88
+ catch (error) {
89
+ reject(new Error('Error reading file'));
90
+ }
91
+ });
92
+ }
93
+ /**
94
+ * Write the file to the disk
95
+ */
96
+ async writeToFile() {
97
+ if (!this._folder) {
98
+ throw new Error(`${this.label}: Folder is not set. Make sure to set the folder by call postSubmit() before writing the file to disk`);
99
+ }
100
+ if (!this._buffer) {
101
+ throw new Error(`${this.label}: Buffer is not set. Make sure to call prepareForSubmission() before writing the file to disk`);
102
+ }
103
+ try {
104
+ /**
105
+ * If .videos, and 'sectionName' folders don't exist, create them
106
+ */
107
+ const vdieosFolder = path.join(this.uploadsFolder, '.videos', this._folder);
108
+ if (!fs.existsSync(vdieosFolder)) {
109
+ fs.mkdirSync(vdieosFolder, { recursive: true });
110
+ }
111
+ /**
112
+ * Write the file to disk
113
+ */
114
+ await fs.promises.writeFile(path.join(this.uploadsFolder, '.videos', this._folder, this.value), this._buffer);
115
+ }
116
+ catch (error) {
117
+ throw new Error(`${this.label}: Error writing file to disk ${error.message}`);
118
+ }
119
+ }
120
+ async postSubmit(folder) {
121
+ this._folder = folder;
122
+ await this.writeToFile();
123
+ }
124
+ async postSubmitRollback() {
125
+ if (!this._folder) {
126
+ throw new Error(`${this.label}: Folder is not set. Make sure to set the folder before writing the file to disk`);
127
+ }
128
+ try {
129
+ const pathToFile = path.join(this.uploadsFolder, '.videos', this._folder, this.value);
130
+ await fs.promises.unlink(pathToFile);
131
+ }
132
+ catch (error) {
133
+ throw new Error(`${this.label}: Error deleting file from disk`);
134
+ }
135
+ }
136
+ /**
137
+ * Get the value of the field
138
+ */
139
+ getValue() {
140
+ return this.value;
141
+ }
142
+ setFileName(value) {
143
+ this.value = value;
144
+ }
145
+ setValue(value) {
146
+ if (typeof value === 'string') {
147
+ this.setFileName(value);
148
+ return;
149
+ }
150
+ this.setFile(value);
151
+ }
152
+ setFile(file) {
153
+ if (!file || file.size === 0 || file.name?.trim() === '')
154
+ return;
155
+ this._file = file;
156
+ }
157
+ checkRequired() {
158
+ /**
159
+ * Check if the field is required
160
+ * If it is, check if the file is present
161
+ * If it's not, throw an error
162
+ * Note: Those values are coming from the browser (not safe)
163
+ */
164
+ if ((this.required && !this._file) || !this._file?.type || !this._file?.name || !this._file?.size) {
165
+ throw new Error(`Field ${this.label} is required`);
166
+ }
167
+ }
168
+ /**
169
+ * Prepare the field for submission
170
+ */
171
+ async prepareForSubmission() {
172
+ if (!this._file)
173
+ return;
174
+ /**
175
+ * Check the actual file size
176
+ */
177
+ const arrayBuffer = await this._file.arrayBuffer();
178
+ this._buffer = Buffer.from(arrayBuffer);
179
+ if (!this._buffer.length) {
180
+ throw new Error(`Field ${this.label} is required`);
181
+ }
182
+ /**
183
+ * Check extension
184
+ */
185
+ const ext = this._file.name.split('.').pop();
186
+ if (!ext || !this.extensions.includes(ext)) {
187
+ throw new Error(`${this.label}: Invalid file type or extension. Allowed extensions: ${this.extensions.join(', ')}`);
188
+ }
189
+ /**
190
+ * Read the first 4100 bytes of the file
191
+ */
192
+ const chunkBuffer = await this.readChunkFromFile({ arrayBuffer, length: 4100 });
193
+ /**
194
+ * Get the file type from the buffer
195
+ */
196
+ const { fileTypeFromBuffer } = await import('file-type');
197
+ const fileType = await fileTypeFromBuffer(chunkBuffer);
198
+ /**
199
+ * If the file type is invalid, return an error
200
+ */
201
+ if (!fileType) {
202
+ throw new Error(`${this.label}: Invalid file type`);
203
+ }
204
+ /**
205
+ * Don't just trust the file extension
206
+ * Check the `fileType.ext` against the allowed extensions
207
+ */
208
+ if (!fileType.ext || !this.extensions.includes(fileType.ext)) {
209
+ throw new Error(`${this.label}: Invalid file type or extension. Allowed extensions: ${this.extensions.join(', ')}`);
210
+ }
211
+ /**
212
+ * Generate a random name for the file
213
+ */
214
+ this.value = customAlphabet('1234567890abcdef', 21)();
215
+ }
216
+ }
217
+ const optionsSchema = z.strictObject({
218
+ ...baseFieldConfigSchema.shape,
219
+ ...configSchema.shape,
220
+ });
221
+ const videoFieldConfigSchema = z.strictObject({
222
+ ...optionsSchema.shape,
223
+ type: z.literal('video').describe('The type of the field'),
224
+ build: z.function().output(z.instanceof(VideoField)).describe('Build a VideoField instance from this config'),
225
+ });
226
+ /**
227
+ * Helper function to create a video field configuration
228
+ * Returns a config object with a build() method that can be serialized and used anywhere
229
+ * @param field
230
+ */
231
+ export function videoField(field) {
232
+ /**
233
+ * Validate the field config
234
+ */
235
+ const result = optionsSchema.safeParse(field);
236
+ if (!result.success) {
237
+ throw new Error(`[Field: ${field.name}]: ${z.prettifyError(result.error)}`);
238
+ }
239
+ const config = {
240
+ ...field,
241
+ type: 'video',
242
+ build() {
243
+ // Use the original field config directly (it doesn't have build() method)
244
+ return new VideoField(field);
245
+ },
246
+ };
247
+ return config;
248
+ }
@@ -0,0 +1,8 @@
1
+ export declare const entityKind: unique symbol;
2
+ export declare const hasOwnEntityKind: unique symbol;
3
+ export interface LZEntity {
4
+ [entityKind]: string;
5
+ }
6
+ export type LZEntityClass<T> = ((abstract new (...args: any[]) => T) | (new (...args: any[]) => T)) & LZEntity;
7
+ export declare function is<T extends LZEntityClass<any>>(value: any, type: T): value is InstanceType<T>;
8
+ //# sourceMappingURL=entity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../src/core/helpers/entity.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,eAA8B,CAAA;AACrD,eAAO,MAAM,gBAAgB,eAAoC,CAAA;AAEjE,MAAM,WAAW,QAAQ;IACrB,CAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAA;AAE9G,wBAAgB,EAAE,CAAC,CAAC,SAAS,aAAa,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,KAAK,IAAI,YAAY,CAAC,CAAC,CAAC,CAiC9F"}
@@ -0,0 +1,27 @@
1
+ export const entityKind = Symbol.for('lz:entityKind');
2
+ export const hasOwnEntityKind = Symbol.for('lz:hasOwnEntityKind');
3
+ export function is(value, type) {
4
+ if (!value || typeof value !== 'object') {
5
+ return false;
6
+ }
7
+ if (value instanceof type) {
8
+ return true;
9
+ }
10
+ if (!Object.prototype.hasOwnProperty.call(type, entityKind)) {
11
+ throw new Error(`Class "${type.name ?? '<unknown>'}" doesn't look like a LZ entity. If this is incorrect and the class is provided by LZ, please report this as a bug.`);
12
+ }
13
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment,@typescript-eslint/no-unsafe-member-access
14
+ let cls = value.constructor;
15
+ if (cls) {
16
+ // Traverse the prototype chain to find the entityKind
17
+ while (cls) {
18
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
19
+ if (entityKind in cls && cls[entityKind] === type[entityKind]) {
20
+ return true;
21
+ }
22
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
23
+ cls = Object.getPrototypeOf(cls);
24
+ }
25
+ }
26
+ return false;
27
+ }
@@ -0,0 +1,5 @@
1
+ export { is } from './entity';
2
+ export { entityKind } from './entity';
3
+ export type { LZEntity } from './entity';
4
+ export { hasOwnEntityKind } from './entity';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/helpers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAA;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AACrC,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { is } from './entity';
2
+ export { entityKind } from './entity';
3
+ export { hasOwnEntityKind } from './entity';
@@ -0,0 +1,8 @@
1
+ export * from './config';
2
+ export * from './factories';
3
+ export * from './fields';
4
+ export * from './sections';
5
+ export * from './submit';
6
+ export * from './db';
7
+ export * from './helpers';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAA;AACxB,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,UAAU,CAAA;AACxB,cAAc,MAAM,CAAA;AACpB,cAAc,WAAW,CAAA"}
@@ -0,0 +1,7 @@
1
+ export * from './config';
2
+ export * from './factories';
3
+ export * from './fields';
4
+ export * from './sections';
5
+ export * from './submit';
6
+ export * from './db';
7
+ export * from './helpers';