@aphexcms/cms-core 0.1.10 → 0.1.11

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 (351) hide show
  1. package/package.json +2 -2
  2. package/src/lib/api/assets.ts +75 -0
  3. package/src/lib/api/client.ts +150 -0
  4. package/src/lib/api/documents.ts +102 -0
  5. package/src/lib/api/index.ts +7 -0
  6. package/src/lib/api/organizations.ts +154 -0
  7. package/src/lib/api/types.ts +34 -0
  8. package/src/lib/auth/auth-errors.ts +23 -0
  9. package/src/lib/auth/auth-hooks.ts +132 -0
  10. package/src/lib/auth/provider.ts +25 -0
  11. package/{dist/client/index.js → src/lib/client/index.ts} +18 -7
  12. package/{dist → src/lib}/components/AdminApp.svelte +43 -11
  13. package/{dist/components/index.js → src/lib/components/index.ts} +5 -1
  14. package/src/lib/config.ts +18 -0
  15. package/{dist/db/adapters/index.js → src/lib/db/adapters/index.ts} +0 -1
  16. package/{dist/db/index.js → src/lib/db/index.ts} +2 -1
  17. package/src/lib/db/interfaces/asset.ts +61 -0
  18. package/src/lib/db/interfaces/document.ts +53 -0
  19. package/src/lib/db/interfaces/index.ts +98 -0
  20. package/src/lib/db/interfaces/organization.ts +51 -0
  21. package/src/lib/db/interfaces/schema.ts +13 -0
  22. package/src/lib/db/interfaces/user.ts +16 -0
  23. package/src/lib/db/utils/reference-resolver.ts +119 -0
  24. package/src/lib/define.ts +7 -0
  25. package/{dist/email/index.js → src/lib/email/index.ts} +2 -1
  26. package/src/lib/email/interfaces/email.ts +45 -0
  27. package/src/lib/engine.ts +85 -0
  28. package/src/lib/field-validation/rule.ts +287 -0
  29. package/src/lib/field-validation/utils.ts +91 -0
  30. package/src/lib/hooks.ts +142 -0
  31. package/{dist/index.js → src/lib/index.ts} +2 -1
  32. package/{dist/is-mobile.svelte.js → src/lib/is-mobile.svelte.ts} +5 -3
  33. package/src/lib/routes/assets-by-id.ts +161 -0
  34. package/src/lib/routes/assets-cdn.ts +185 -0
  35. package/src/lib/routes/assets.ts +116 -0
  36. package/src/lib/routes/documents-by-id.ts +188 -0
  37. package/src/lib/routes/documents-publish.ts +211 -0
  38. package/src/lib/routes/documents.ts +172 -0
  39. package/src/lib/routes/index.ts +13 -0
  40. package/src/lib/routes/organizations-by-id.ts +258 -0
  41. package/src/lib/routes/organizations-invitations.ts +183 -0
  42. package/src/lib/routes/organizations-members.ts +301 -0
  43. package/src/lib/routes/organizations-switch.ts +74 -0
  44. package/src/lib/routes/organizations.ts +147 -0
  45. package/src/lib/routes/schemas-by-type.ts +35 -0
  46. package/src/lib/routes/schemas.ts +19 -0
  47. package/src/lib/routes-exports.ts +42 -0
  48. package/src/lib/schema-context.svelte.ts +24 -0
  49. package/src/lib/schema-utils/cleanup.ts +116 -0
  50. package/src/lib/schema-utils/index.ts +4 -0
  51. package/src/lib/schema-utils/utils.ts +47 -0
  52. package/src/lib/schema-utils/validator.ts +58 -0
  53. package/src/lib/server/index.ts +40 -0
  54. package/src/lib/services/asset-service.ts +256 -0
  55. package/src/lib/services/index.ts +6 -0
  56. package/src/lib/storage/adapters/index.ts +2 -0
  57. package/src/lib/storage/adapters/local-storage-adapter.ts +215 -0
  58. package/{dist/storage/index.js → src/lib/storage/index.ts} +4 -2
  59. package/src/lib/storage/interfaces/index.ts +2 -0
  60. package/src/lib/storage/interfaces/storage.ts +114 -0
  61. package/src/lib/storage/providers/storage.ts +83 -0
  62. package/src/lib/types/asset.ts +81 -0
  63. package/src/lib/types/auth.ts +80 -0
  64. package/src/lib/types/config.ts +45 -0
  65. package/src/lib/types/document.ts +38 -0
  66. package/src/lib/types/index.ts +8 -0
  67. package/src/lib/types/organization.ts +119 -0
  68. package/src/lib/types/schemas.ts +156 -0
  69. package/src/lib/types/sidebar.ts +37 -0
  70. package/src/lib/types/user.ts +17 -0
  71. package/src/lib/utils/content-hash.ts +75 -0
  72. package/src/lib/utils/image-url.ts +204 -0
  73. package/src/lib/utils/index.ts +12 -0
  74. package/src/lib/utils/slug.ts +33 -0
  75. package/src/lib/utils.ts +13 -0
  76. package/dist/api/assets.d.ts +0 -48
  77. package/dist/api/assets.d.ts.map +0 -1
  78. package/dist/api/assets.js +0 -52
  79. package/dist/api/client.d.ts +0 -37
  80. package/dist/api/client.d.ts.map +0 -1
  81. package/dist/api/client.js +0 -125
  82. package/dist/api/documents.d.ts +0 -56
  83. package/dist/api/documents.d.ts.map +0 -1
  84. package/dist/api/documents.js +0 -77
  85. package/dist/api/index.d.ts +0 -7
  86. package/dist/api/index.d.ts.map +0 -1
  87. package/dist/api/index.js +0 -5
  88. package/dist/api/organizations.d.ts +0 -101
  89. package/dist/api/organizations.d.ts.map +0 -1
  90. package/dist/api/organizations.js +0 -92
  91. package/dist/api/types.d.ts +0 -23
  92. package/dist/api/types.d.ts.map +0 -1
  93. package/dist/api/types.js +0 -1
  94. package/dist/auth/auth-errors.d.ts +0 -7
  95. package/dist/auth/auth-errors.d.ts.map +0 -1
  96. package/dist/auth/auth-errors.js +0 -13
  97. package/dist/auth/auth-hooks.d.ts +0 -6
  98. package/dist/auth/auth-hooks.d.ts.map +0 -1
  99. package/dist/auth/auth-hooks.js +0 -108
  100. package/dist/auth/provider.d.ts +0 -17
  101. package/dist/auth/provider.d.ts.map +0 -1
  102. package/dist/auth/provider.js +0 -1
  103. package/dist/client/index.d.ts +0 -24
  104. package/dist/client/index.d.ts.map +0 -1
  105. package/dist/components/AdminApp.svelte.d.ts +0 -24
  106. package/dist/components/AdminApp.svelte.d.ts.map +0 -1
  107. package/dist/components/admin/AdminLayout.svelte.d.ts +0 -15
  108. package/dist/components/admin/AdminLayout.svelte.d.ts.map +0 -1
  109. package/dist/components/admin/DocumentEditor.svelte.d.ts +0 -18
  110. package/dist/components/admin/DocumentEditor.svelte.d.ts.map +0 -1
  111. package/dist/components/admin/DocumentTypesList.svelte.d.ts +0 -14
  112. package/dist/components/admin/DocumentTypesList.svelte.d.ts.map +0 -1
  113. package/dist/components/admin/ObjectModal.svelte.d.ts +0 -15
  114. package/dist/components/admin/ObjectModal.svelte.d.ts.map +0 -1
  115. package/dist/components/admin/SchemaField.svelte.d.ts +0 -19
  116. package/dist/components/admin/SchemaField.svelte.d.ts.map +0 -1
  117. package/dist/components/admin/fields/ArrayField.svelte.d.ts +0 -12
  118. package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +0 -1
  119. package/dist/components/admin/fields/BooleanField.svelte.d.ts +0 -13
  120. package/dist/components/admin/fields/BooleanField.svelte.d.ts.map +0 -1
  121. package/dist/components/admin/fields/ImageField.svelte.d.ts +0 -15
  122. package/dist/components/admin/fields/ImageField.svelte.d.ts.map +0 -1
  123. package/dist/components/admin/fields/NumberField.svelte.d.ts +0 -14
  124. package/dist/components/admin/fields/NumberField.svelte.d.ts.map +0 -1
  125. package/dist/components/admin/fields/ReferenceField.svelte.d.ts +0 -12
  126. package/dist/components/admin/fields/ReferenceField.svelte.d.ts.map +0 -1
  127. package/dist/components/admin/fields/SlugField.svelte.d.ts +0 -15
  128. package/dist/components/admin/fields/SlugField.svelte.d.ts.map +0 -1
  129. package/dist/components/admin/fields/StringField.svelte.d.ts +0 -14
  130. package/dist/components/admin/fields/StringField.svelte.d.ts.map +0 -1
  131. package/dist/components/admin/fields/TextareaField.svelte.d.ts +0 -14
  132. package/dist/components/admin/fields/TextareaField.svelte.d.ts.map +0 -1
  133. package/dist/components/fields/index.d.ts +0 -9
  134. package/dist/components/fields/index.d.ts.map +0 -1
  135. package/dist/components/index.d.ts +0 -7
  136. package/dist/components/index.d.ts.map +0 -1
  137. package/dist/components/layout/OrganizationSwitcher.svelte.d.ts +0 -11
  138. package/dist/components/layout/OrganizationSwitcher.svelte.d.ts.map +0 -1
  139. package/dist/components/layout/Sidebar.svelte.d.ts +0 -14
  140. package/dist/components/layout/Sidebar.svelte.d.ts.map +0 -1
  141. package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts +0 -4
  142. package/dist/components/layout/sidebar/AppSidebar.svelte.d.ts.map +0 -1
  143. package/dist/components/layout/sidebar/NavMain.svelte.d.ts +0 -19
  144. package/dist/components/layout/sidebar/NavMain.svelte.d.ts.map +0 -1
  145. package/dist/components/layout/sidebar/NavSecondary.svelte.d.ts +0 -9
  146. package/dist/components/layout/sidebar/NavSecondary.svelte.d.ts.map +0 -1
  147. package/dist/components/layout/sidebar/NavUser.svelte.d.ts +0 -9
  148. package/dist/components/layout/sidebar/NavUser.svelte.d.ts.map +0 -1
  149. package/dist/config.d.ts +0 -3
  150. package/dist/config.d.ts.map +0 -1
  151. package/dist/config.js +0 -15
  152. package/dist/db/adapters/index.d.ts +0 -1
  153. package/dist/db/adapters/index.d.ts.map +0 -1
  154. package/dist/db/index.d.ts +0 -2
  155. package/dist/db/index.d.ts.map +0 -1
  156. package/dist/db/interfaces/asset.d.ts +0 -51
  157. package/dist/db/interfaces/asset.d.ts.map +0 -1
  158. package/dist/db/interfaces/asset.js +0 -1
  159. package/dist/db/interfaces/document.d.ts +0 -36
  160. package/dist/db/interfaces/document.d.ts.map +0 -1
  161. package/dist/db/interfaces/document.js +0 -1
  162. package/dist/db/interfaces/index.d.ts +0 -73
  163. package/dist/db/interfaces/index.d.ts.map +0 -1
  164. package/dist/db/interfaces/index.js +0 -1
  165. package/dist/db/interfaces/organization.d.ts +0 -27
  166. package/dist/db/interfaces/organization.d.ts.map +0 -1
  167. package/dist/db/interfaces/organization.js +0 -1
  168. package/dist/db/interfaces/schema.d.ts +0 -21
  169. package/dist/db/interfaces/schema.d.ts.map +0 -1
  170. package/dist/db/interfaces/schema.js +0 -1
  171. package/dist/db/interfaces/user.d.ts +0 -15
  172. package/dist/db/interfaces/user.d.ts.map +0 -1
  173. package/dist/db/interfaces/user.js +0 -1
  174. package/dist/db/utils/reference-resolver.d.ts +0 -18
  175. package/dist/db/utils/reference-resolver.d.ts.map +0 -1
  176. package/dist/db/utils/reference-resolver.js +0 -80
  177. package/dist/define.d.ts +0 -3
  178. package/dist/define.d.ts.map +0 -1
  179. package/dist/define.js +0 -4
  180. package/dist/email/index.d.ts +0 -2
  181. package/dist/email/index.d.ts.map +0 -1
  182. package/dist/email/interfaces/email.d.ts +0 -42
  183. package/dist/email/interfaces/email.d.ts.map +0 -1
  184. package/dist/email/interfaces/email.js +0 -1
  185. package/dist/engine.d.ts +0 -26
  186. package/dist/engine.d.ts.map +0 -1
  187. package/dist/engine.js +0 -66
  188. package/dist/field-validation/rule.d.ts +0 -51
  189. package/dist/field-validation/rule.d.ts.map +0 -1
  190. package/dist/field-validation/rule.js +0 -221
  191. package/dist/field-validation/utils.d.ts +0 -21
  192. package/dist/field-validation/utils.d.ts.map +0 -1
  193. package/dist/field-validation/utils.js +0 -66
  194. package/dist/hooks.d.ts +0 -23
  195. package/dist/hooks.d.ts.map +0 -1
  196. package/dist/hooks.js +0 -96
  197. package/dist/index.d.ts +0 -2
  198. package/dist/index.d.ts.map +0 -1
  199. package/dist/is-mobile.svelte.d.ts +0 -5
  200. package/dist/is-mobile.svelte.d.ts.map +0 -1
  201. package/dist/routes/assets-by-id.d.ts +0 -5
  202. package/dist/routes/assets-by-id.d.ts.map +0 -1
  203. package/dist/routes/assets-by-id.js +0 -138
  204. package/dist/routes/assets-cdn.d.ts +0 -3
  205. package/dist/routes/assets-cdn.d.ts.map +0 -1
  206. package/dist/routes/assets-cdn.js +0 -155
  207. package/dist/routes/assets.d.ts +0 -4
  208. package/dist/routes/assets.d.ts.map +0 -1
  209. package/dist/routes/assets.js +0 -94
  210. package/dist/routes/documents-by-id.d.ts +0 -5
  211. package/dist/routes/documents-by-id.d.ts.map +0 -1
  212. package/dist/routes/documents-by-id.js +0 -142
  213. package/dist/routes/documents-publish.d.ts +0 -4
  214. package/dist/routes/documents-publish.d.ts.map +0 -1
  215. package/dist/routes/documents-publish.js +0 -151
  216. package/dist/routes/documents.d.ts +0 -4
  217. package/dist/routes/documents.d.ts.map +0 -1
  218. package/dist/routes/documents.js +0 -131
  219. package/dist/routes/index.d.ts +0 -6
  220. package/dist/routes/index.d.ts.map +0 -1
  221. package/dist/routes/index.js +0 -10
  222. package/dist/routes/organizations-by-id.d.ts +0 -5
  223. package/dist/routes/organizations-by-id.d.ts.map +0 -1
  224. package/dist/routes/organizations-by-id.js +0 -187
  225. package/dist/routes/organizations-invitations.d.ts +0 -4
  226. package/dist/routes/organizations-invitations.d.ts.map +0 -1
  227. package/dist/routes/organizations-invitations.js +0 -125
  228. package/dist/routes/organizations-members.d.ts +0 -5
  229. package/dist/routes/organizations-members.d.ts.map +0 -1
  230. package/dist/routes/organizations-members.js +0 -206
  231. package/dist/routes/organizations-switch.d.ts +0 -3
  232. package/dist/routes/organizations-switch.d.ts.map +0 -1
  233. package/dist/routes/organizations-switch.js +0 -53
  234. package/dist/routes/organizations.d.ts +0 -4
  235. package/dist/routes/organizations.d.ts.map +0 -1
  236. package/dist/routes/organizations.js +0 -109
  237. package/dist/routes/schemas-by-type.d.ts +0 -3
  238. package/dist/routes/schemas-by-type.d.ts.map +0 -1
  239. package/dist/routes/schemas-by-type.js +0 -25
  240. package/dist/routes/schemas.d.ts +0 -3
  241. package/dist/routes/schemas.d.ts.map +0 -1
  242. package/dist/routes/schemas.js +0 -11
  243. package/dist/routes-exports.d.ts +0 -14
  244. package/dist/routes-exports.d.ts.map +0 -1
  245. package/dist/routes-exports.js +0 -19
  246. package/dist/schema-context.svelte.d.ts +0 -10
  247. package/dist/schema-context.svelte.d.ts.map +0 -1
  248. package/dist/schema-context.svelte.js +0 -18
  249. package/dist/schema-utils/cleanup.d.ts +0 -21
  250. package/dist/schema-utils/cleanup.d.ts.map +0 -1
  251. package/dist/schema-utils/cleanup.js +0 -80
  252. package/dist/schema-utils/index.d.ts +0 -4
  253. package/dist/schema-utils/index.d.ts.map +0 -1
  254. package/dist/schema-utils/index.js +0 -4
  255. package/dist/schema-utils/utils.d.ts +0 -30
  256. package/dist/schema-utils/utils.d.ts.map +0 -1
  257. package/dist/schema-utils/utils.js +0 -37
  258. package/dist/schema-utils/validator.d.ts +0 -6
  259. package/dist/schema-utils/validator.d.ts.map +0 -1
  260. package/dist/schema-utils/validator.js +0 -45
  261. package/dist/server/index.d.ts +0 -16
  262. package/dist/server/index.d.ts.map +0 -1
  263. package/dist/server/index.js +0 -28
  264. package/dist/services/asset-service.d.ts +0 -86
  265. package/dist/services/asset-service.d.ts.map +0 -1
  266. package/dist/services/asset-service.js +0 -187
  267. package/dist/services/index.d.ts +0 -3
  268. package/dist/services/index.d.ts.map +0 -1
  269. package/dist/services/index.js +0 -4
  270. package/dist/storage/adapters/index.d.ts +0 -2
  271. package/dist/storage/adapters/index.d.ts.map +0 -1
  272. package/dist/storage/adapters/index.js +0 -2
  273. package/dist/storage/adapters/local-storage-adapter.d.ts +0 -54
  274. package/dist/storage/adapters/local-storage-adapter.d.ts.map +0 -1
  275. package/dist/storage/adapters/local-storage-adapter.js +0 -187
  276. package/dist/storage/index.d.ts +0 -3
  277. package/dist/storage/index.d.ts.map +0 -1
  278. package/dist/storage/interfaces/index.d.ts +0 -2
  279. package/dist/storage/interfaces/index.d.ts.map +0 -1
  280. package/dist/storage/interfaces/index.js +0 -2
  281. package/dist/storage/interfaces/storage.d.ts +0 -91
  282. package/dist/storage/interfaces/storage.d.ts.map +0 -1
  283. package/dist/storage/interfaces/storage.js +0 -1
  284. package/dist/storage/providers/storage.d.ts +0 -43
  285. package/dist/storage/providers/storage.d.ts.map +0 -1
  286. package/dist/storage/providers/storage.js +0 -64
  287. package/dist/types/asset.d.ts +0 -73
  288. package/dist/types/asset.d.ts.map +0 -1
  289. package/dist/types/asset.js +0 -2
  290. package/dist/types/auth.d.ts +0 -50
  291. package/dist/types/auth.d.ts.map +0 -1
  292. package/dist/types/auth.js +0 -41
  293. package/dist/types/config.d.ts +0 -47
  294. package/dist/types/config.d.ts.map +0 -1
  295. package/dist/types/config.js +0 -1
  296. package/dist/types/document.d.ts +0 -34
  297. package/dist/types/document.d.ts.map +0 -1
  298. package/dist/types/document.js +0 -1
  299. package/dist/types/index.d.ts +0 -9
  300. package/dist/types/index.d.ts.map +0 -1
  301. package/dist/types/index.js +0 -8
  302. package/dist/types/organization.d.ts +0 -105
  303. package/dist/types/organization.d.ts.map +0 -1
  304. package/dist/types/organization.js +0 -3
  305. package/dist/types/schemas.d.ts +0 -114
  306. package/dist/types/schemas.d.ts.map +0 -1
  307. package/dist/types/schemas.js +0 -1
  308. package/dist/types/sidebar.d.ts +0 -33
  309. package/dist/types/sidebar.d.ts.map +0 -1
  310. package/dist/types/sidebar.js +0 -1
  311. package/dist/types/user.d.ts +0 -14
  312. package/dist/types/user.d.ts.map +0 -1
  313. package/dist/types/user.js +0 -1
  314. package/dist/utils/content-hash.d.ts +0 -22
  315. package/dist/utils/content-hash.d.ts.map +0 -1
  316. package/dist/utils/content-hash.js +0 -67
  317. package/dist/utils/image-url.d.ts +0 -88
  318. package/dist/utils/image-url.d.ts.map +0 -1
  319. package/dist/utils/image-url.js +0 -165
  320. package/dist/utils/index.d.ts +0 -6
  321. package/dist/utils/index.d.ts.map +0 -1
  322. package/dist/utils/index.js +0 -9
  323. package/dist/utils/slug.d.ts +0 -13
  324. package/dist/utils/slug.d.ts.map +0 -1
  325. package/dist/utils/slug.js +0 -30
  326. package/dist/utils.d.ts +0 -13
  327. package/dist/utils.d.ts.map +0 -1
  328. package/dist/utils.js +0 -5
  329. /package/{dist → src/lib}/app.d.ts +0 -0
  330. /package/{dist → src/lib}/auth/MULTI_TENANCY_PLAN.md +0 -0
  331. /package/{dist → src/lib}/components/admin/AdminLayout.svelte +0 -0
  332. /package/{dist → src/lib}/components/admin/DocumentEditor.svelte +0 -0
  333. /package/{dist → src/lib}/components/admin/DocumentTypesList.svelte +0 -0
  334. /package/{dist → src/lib}/components/admin/ObjectModal.svelte +0 -0
  335. /package/{dist → src/lib}/components/admin/SchemaField.svelte +0 -0
  336. /package/{dist → src/lib}/components/admin/fields/ArrayField.svelte +0 -0
  337. /package/{dist → src/lib}/components/admin/fields/BooleanField.svelte +0 -0
  338. /package/{dist → src/lib}/components/admin/fields/ImageField.svelte +0 -0
  339. /package/{dist → src/lib}/components/admin/fields/NumberField.svelte +0 -0
  340. /package/{dist → src/lib}/components/admin/fields/ReferenceField.svelte +0 -0
  341. /package/{dist → src/lib}/components/admin/fields/SlugField.svelte +0 -0
  342. /package/{dist → src/lib}/components/admin/fields/StringField.svelte +0 -0
  343. /package/{dist → src/lib}/components/admin/fields/TextareaField.svelte +0 -0
  344. /package/{dist/components/fields/index.js → src/lib/components/fields/index.ts} +0 -0
  345. /package/{dist → src/lib}/components/layout/OrganizationSwitcher.svelte +0 -0
  346. /package/{dist → src/lib}/components/layout/Sidebar.svelte +0 -0
  347. /package/{dist → src/lib}/components/layout/sidebar/AppSidebar.svelte +0 -0
  348. /package/{dist → src/lib}/components/layout/sidebar/NavMain.svelte +0 -0
  349. /package/{dist → src/lib}/components/layout/sidebar/NavSecondary.svelte +0 -0
  350. /package/{dist → src/lib}/components/layout/sidebar/NavUser.svelte +0 -0
  351. /package/{dist → src/lib}/plugins/README.md +0 -0
@@ -0,0 +1,119 @@
1
+ // Organization types for multi-tenancy
2
+ // These match the inferred types from Drizzle schema
3
+
4
+ export type OrganizationRole = 'owner' | 'admin' | 'editor' | 'viewer';
5
+
6
+ export interface Organization {
7
+ id: string;
8
+ name: string;
9
+ slug: string;
10
+ parentOrganizationId: string | null;
11
+ metadata: {
12
+ logo?: string;
13
+ theme?: {
14
+ primaryColor: string;
15
+ fontFamily: string;
16
+ logoUrl: string;
17
+ };
18
+ website?: string;
19
+ settings?: Record<string, any>;
20
+ } | null;
21
+ createdBy: string;
22
+ createdAt: Date;
23
+ updatedAt: Date;
24
+ }
25
+
26
+ export interface NewOrganization {
27
+ name: string;
28
+ slug: string;
29
+ createdBy: string;
30
+ id?: string;
31
+ parentOrganizationId?: string | null;
32
+ metadata?: {
33
+ logo?: string;
34
+ theme?: {
35
+ primaryColor: string;
36
+ fontFamily: string;
37
+ logoUrl: string;
38
+ };
39
+ website?: string;
40
+ settings?: Record<string, any>;
41
+ } | null;
42
+ createdAt?: Date;
43
+ updatedAt?: Date;
44
+ }
45
+
46
+ export interface OrganizationMember {
47
+ id: string;
48
+ createdAt: Date;
49
+ updatedAt: Date;
50
+ organizationId: string;
51
+ userId: string;
52
+ role: OrganizationRole;
53
+ preferences: Record<string, any> | null;
54
+ invitationId: string | null; // Link to invitation (get invitedBy, invitedEmail from there)
55
+ }
56
+
57
+ export interface NewOrganizationMember {
58
+ organizationId: string;
59
+ userId: string;
60
+ role: OrganizationRole;
61
+ id?: string;
62
+ createdAt?: Date;
63
+ updatedAt?: Date;
64
+ preferences?: Record<string, any> | null;
65
+ invitationId?: string | null;
66
+ }
67
+
68
+ export interface Invitation {
69
+ id: string;
70
+ createdAt: Date;
71
+ organizationId: string;
72
+ role: OrganizationRole;
73
+ invitedBy: string;
74
+ email: string;
75
+ token: string;
76
+ expiresAt: Date;
77
+ acceptedAt: Date | null;
78
+ }
79
+
80
+ export interface NewInvitation {
81
+ organizationId: string;
82
+ role: OrganizationRole;
83
+ invitedBy: string;
84
+ email: string;
85
+ token: string;
86
+ expiresAt: Date;
87
+ id?: string;
88
+ createdAt?: Date;
89
+ acceptedAt?: Date | null;
90
+ }
91
+
92
+ export interface UserSession {
93
+ updatedAt: Date;
94
+ userId: string;
95
+ activeOrganizationId: string | null;
96
+ }
97
+
98
+ export interface NewUserSession {
99
+ userId: string;
100
+ updatedAt?: Date;
101
+ activeOrganizationId?: string | null;
102
+ }
103
+
104
+ // Helper type for organization with member info
105
+ export interface OrganizationMembership {
106
+ organization: Organization;
107
+ member: OrganizationMember;
108
+ }
109
+
110
+ // Helper type for member with user info
111
+ export interface OrganizationMemberWithUser {
112
+ member: OrganizationMember;
113
+ user: {
114
+ id: string;
115
+ email: string;
116
+ name: string | null;
117
+ image: string | null;
118
+ };
119
+ }
@@ -0,0 +1,156 @@
1
+ // types/schemas.ts
2
+ import type { Rule } from '../field-validation/rule';
3
+ import type { Icon as LucideIcon } from 'lucide-svelte';
4
+
5
+ // From root types.ts
6
+ export type FieldType =
7
+ | 'string'
8
+ | 'text'
9
+ | 'number'
10
+ | 'boolean'
11
+ | 'slug'
12
+ | 'image'
13
+ | 'array'
14
+ | 'object'
15
+ | 'reference';
16
+
17
+ export interface BaseField {
18
+ name: string;
19
+ type: FieldType;
20
+ title: string;
21
+ description?: string;
22
+ validation?: ((rule: Rule) => Rule) | Array<(rule: Rule) => Rule>;
23
+ }
24
+
25
+ export interface StringField extends BaseField {
26
+ type: 'string';
27
+ maxLength?: number;
28
+ placeholder?: string;
29
+ }
30
+
31
+ export interface TextField extends BaseField {
32
+ type: 'text';
33
+ rows?: number;
34
+ maxLength?: number;
35
+ placeholder?: string;
36
+ }
37
+
38
+ export interface NumberField extends BaseField {
39
+ type: 'number';
40
+ min?: number;
41
+ max?: number;
42
+ }
43
+
44
+ export interface BooleanField extends BaseField {
45
+ type: 'boolean';
46
+ initialValue?: boolean;
47
+ }
48
+
49
+ export interface SlugField extends BaseField {
50
+ type: 'slug';
51
+ source?: string;
52
+ maxLength?: number;
53
+ }
54
+
55
+ export interface ImageField extends BaseField {
56
+ type: 'image';
57
+ accept?: string;
58
+ hotspot?: boolean; // Enable hotspot/crop UI
59
+ metadata?: string[]; // e.g., ['palette', 'exif', 'location']
60
+ fields?: Field[]; // Additional fields like caption, attribution
61
+ private?: boolean; // Default: false (public). Set true to require auth for access
62
+ }
63
+
64
+ export interface TypeReference {
65
+ type: string; // References a SchemaType by name
66
+ title?: string;
67
+ }
68
+
69
+ export interface ArrayField extends BaseField {
70
+ type: 'array';
71
+ of: TypeReference[];
72
+ max?: number;
73
+ }
74
+
75
+ export interface ObjectField extends BaseField {
76
+ type: 'object';
77
+ fields: Field[];
78
+ }
79
+
80
+ export interface ReferenceField extends BaseField {
81
+ type: 'reference';
82
+ to: Array<{ type: string }>;
83
+ }
84
+
85
+ export type Field =
86
+ | StringField
87
+ | TextField
88
+ | NumberField
89
+ | BooleanField
90
+ | SlugField
91
+ | ImageField
92
+ | ArrayField
93
+ | ObjectField
94
+ | ReferenceField;
95
+
96
+ export interface PreviewConfig {
97
+ select?: {
98
+ title?: string;
99
+ subtitle?: string;
100
+ media?: string;
101
+ };
102
+ }
103
+
104
+ export interface DocumentType {
105
+ id: string;
106
+ type: 'document';
107
+ name: string;
108
+ title: string;
109
+ description?: string;
110
+ icon?: typeof LucideIcon;
111
+ fields: Field[];
112
+ preview?: PreviewConfig;
113
+ createdAt: Date | null;
114
+ updatedAt: Date | null;
115
+ }
116
+
117
+ export interface ObjectType {
118
+ type: 'object';
119
+ name: string;
120
+ title: string;
121
+ description?: string;
122
+ icon?: typeof LucideIcon;
123
+ fields: Field[];
124
+ preview?: PreviewConfig;
125
+ }
126
+
127
+ // From db/types.ts
128
+ /**
129
+ * Schema type - represents document and object type definitions stored in the DB
130
+ */
131
+ // Schema type for all definitions
132
+ export interface SchemaType {
133
+ id?: string;
134
+ type: 'document' | 'object';
135
+ name: string;
136
+ title: string;
137
+ description?: string;
138
+ icon?: typeof LucideIcon;
139
+ fields: Field[];
140
+ preview?: PreviewConfig;
141
+ createdAt?: Date | null;
142
+ updatedAt?: Date | null;
143
+ }
144
+
145
+ export interface NewSchemaType {
146
+ id?: string;
147
+ type: 'document' | 'object';
148
+ name: string;
149
+ title: string;
150
+ description?: string;
151
+ icon?: typeof LucideIcon;
152
+ fields: Field[];
153
+ preview?: PreviewConfig;
154
+ createdAt?: Date | null;
155
+ updatedAt?: Date | null;
156
+ }
@@ -0,0 +1,37 @@
1
+ // Sidebar data types - extensible interfaces for admin UI
2
+ export interface SidebarUser {
3
+ id: string;
4
+ email: string;
5
+ name?: string;
6
+ image?: string;
7
+ role?: string;
8
+ }
9
+
10
+ export interface SidebarNavItem {
11
+ href: string;
12
+ label: string;
13
+ icon?: string;
14
+ badge?: string | number;
15
+ }
16
+
17
+ export interface SidebarBranding {
18
+ title?: string;
19
+ logo?: string;
20
+ }
21
+
22
+ export interface SidebarOrganization {
23
+ id: string;
24
+ name: string;
25
+ slug: string;
26
+ role: 'owner' | 'admin' | 'editor' | 'viewer';
27
+ isActive: boolean;
28
+ metadata?: any;
29
+ }
30
+
31
+ export interface SidebarData {
32
+ user: SidebarUser;
33
+ branding?: SidebarBranding;
34
+ navItems?: SidebarNavItem[]; // Optional custom nav items (defaults to Content)
35
+ organizations?: SidebarOrganization[]; // User's organizations for organization switcher
36
+ activeOrganization?: SidebarOrganization; // Currently active organization
37
+ }
@@ -0,0 +1,17 @@
1
+ // Represents the data stored in the cms_user_profiles table.
2
+ export interface UserProfile {
3
+ userId: string;
4
+ role: 'super_admin' | 'admin' | 'editor' | 'viewer';
5
+ preferences?: Record<string, any>;
6
+ }
7
+
8
+ // Represents the core user data from the auth provider.
9
+ export interface AuthUser {
10
+ id: string;
11
+ email: string;
12
+ name?: string;
13
+ image?: string;
14
+ }
15
+
16
+ // The final, combined object, composed from the two types above.
17
+ export interface CMSUser extends AuthUser, Omit<UserProfile, 'userId'> {}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Content hashing utilities for document version tracking
3
+ * Includes timestamp for proper change detection and UX
4
+ */
5
+
6
+ /**
7
+ * Recursively sort object keys for stable JSON serialization
8
+ */
9
+ function sortObject(item: any): any {
10
+ if (item === null || typeof item !== 'object') return item;
11
+
12
+ if (Array.isArray(item)) {
13
+ return item.map(sortObject);
14
+ }
15
+
16
+ const sortedKeys = Object.keys(item).sort();
17
+ const sortedObj: any = {};
18
+ for (const key of sortedKeys) {
19
+ sortedObj[key] = sortObject(item[key]);
20
+ }
21
+ return sortedObj;
22
+ }
23
+
24
+ /**
25
+ * Create a stable hash from any object using a simple hash algorithm
26
+ */
27
+ function simpleHash(str: string): string {
28
+ let hash = 0;
29
+ for (let i = 0; i < str.length; i++) {
30
+ const char = str.charCodeAt(i);
31
+ hash = (hash << 5) - hash + char;
32
+ hash = hash & hash; // Convert to 32-bit integer
33
+ }
34
+ return Math.abs(hash).toString(36); // Base36 for shorter string
35
+ }
36
+
37
+ /**
38
+ * Create a content hash including timestamp for change tracking
39
+ * This matches Sanity's behavior where any interaction creates a publishable state
40
+ */
41
+ export function createContentHash(data: any, includeTimestamp = true): string {
42
+ const hashData = includeTimestamp
43
+ ? {
44
+ ...data,
45
+ _lastModified: new Date().toISOString()
46
+ }
47
+ : data;
48
+
49
+ const stableJson = JSON.stringify(sortObject(hashData));
50
+ return simpleHash(stableJson);
51
+ }
52
+
53
+ /**
54
+ * Create a hash from published data (no timestamp needed as it's already stable)
55
+ */
56
+ export function createPublishedHash(data: any): string {
57
+ return createContentHash(data, false);
58
+ }
59
+
60
+ /**
61
+ * Compare if current draft differs from published version
62
+ */
63
+ export function hasUnpublishedChanges(draftData: any, publishedHash: string | null): boolean {
64
+ if (!publishedHash) return true; // No published version = has changes
65
+
66
+ const publishedDataHash = createPublishedHash(draftData);
67
+ return publishedDataHash !== publishedHash;
68
+ }
69
+
70
+ /**
71
+ * Utility to create a clean published hash when publishing
72
+ */
73
+ export function createHashForPublishing(draftData: any): string {
74
+ return createPublishedHash(draftData);
75
+ }
@@ -0,0 +1,204 @@
1
+ import type { ImageValue, ImageAsset, Asset } from '../types/asset';
2
+
3
+ export interface ImageUrlBuilderOptions {
4
+ width?: number;
5
+ height?: number;
6
+ quality?: number;
7
+ format?: 'jpg' | 'jpeg' | 'png' | 'webp' | 'avif';
8
+ fit?: 'cover' | 'contain' | 'fill' | 'inside' | 'outside';
9
+ auto?: 'format';
10
+ }
11
+
12
+ export interface ImageUrlBuilderConfig {
13
+ baseUrl?: string;
14
+ /**
15
+ * Function to sign asset URLs for secure, time-limited access
16
+ * Used for multi-tenant access without exposing API keys
17
+ */
18
+ signAssetUrl?: (assetId: string) => string;
19
+ }
20
+
21
+ /**
22
+ * Helper to extract URL from various image source types
23
+ * Works with GraphQL responses that include resolved asset data
24
+ */
25
+ function extractUrl(source: any): string | null {
26
+ if (!source) return null;
27
+
28
+ // Direct URL string
29
+ if (typeof source === 'string') {
30
+ return source;
31
+ }
32
+
33
+ // Asset object with url property
34
+ if (typeof source === 'object' && 'url' in source && source.url) {
35
+ return source.url;
36
+ }
37
+
38
+ // ImageValue with resolved asset (from GraphQL)
39
+ if (typeof source === 'object' && 'asset' in source && source.asset) {
40
+ // Check if asset is resolved (has url property)
41
+ if (typeof source.asset === 'object' && 'url' in source.asset) {
42
+ return source.asset.url;
43
+ }
44
+ }
45
+
46
+ return null;
47
+ }
48
+
49
+ export class ImageUrlBuilder {
50
+ private _source: any = null;
51
+ private _options: ImageUrlBuilderOptions = {};
52
+
53
+ /**
54
+ * Set the image source
55
+ */
56
+ image(source: ImageValue | ImageAsset | string | Asset | null | undefined): this {
57
+ this._source = source;
58
+ return this;
59
+ }
60
+
61
+ /**
62
+ * Set width (for future dynamic image rendering)
63
+ */
64
+ width(width: number): this {
65
+ this._options.width = width;
66
+ return this;
67
+ }
68
+
69
+ /**
70
+ * Set height (for future dynamic image rendering)
71
+ */
72
+ height(height: number): this {
73
+ this._options.height = height;
74
+ return this;
75
+ }
76
+
77
+ /**
78
+ * Set both width and height (for future dynamic image rendering)
79
+ */
80
+ size(width: number, height: number): this {
81
+ this._options.width = width;
82
+ this._options.height = height;
83
+ return this;
84
+ }
85
+
86
+ /**
87
+ * Set quality (for future dynamic image rendering)
88
+ */
89
+ quality(quality: number): this {
90
+ this._options.quality = Math.max(1, Math.min(100, quality));
91
+ return this;
92
+ }
93
+
94
+ /**
95
+ * Set format (for future dynamic image rendering)
96
+ */
97
+ format(format: 'jpg' | 'jpeg' | 'png' | 'webp' | 'avif'): this {
98
+ this._options.format = format;
99
+ return this;
100
+ }
101
+
102
+ /**
103
+ * Set fit mode (for future dynamic image rendering)
104
+ */
105
+ fit(fit: 'cover' | 'contain' | 'fill' | 'inside' | 'outside'): this {
106
+ this._options.fit = fit;
107
+ return this;
108
+ }
109
+
110
+ /**
111
+ * Enable automatic format selection (for future dynamic image rendering)
112
+ */
113
+ auto(mode: 'format'): this {
114
+ this._options.auto = mode;
115
+ return this;
116
+ }
117
+
118
+ /**
119
+ * Build the final URL
120
+ * Returns /api/assets/{id}?dl=1 which redirects to the actual S3/R2 URL
121
+ * Transformations (.width(), .quality(), etc) are stored but not yet applied
122
+ *
123
+ * For multi-tenant access, use signAssetUrl config to generate signed URLs
124
+ * TODO: Add dynamic image rendering support
125
+ */
126
+ url(): string | null {
127
+ console.log('[ImageUrlBuilder] url() called with source:', JSON.stringify(this._source));
128
+
129
+ if (!this._source) {
130
+ console.log('[ImageUrlBuilder] No source provided');
131
+ return null;
132
+ }
133
+
134
+ // First try to extract a direct URL (if asset was already resolved)
135
+ const directUrl = extractUrl(this._source);
136
+ if (directUrl) {
137
+ console.log('[ImageUrlBuilder] Using direct URL from resolved asset:', directUrl);
138
+ return directUrl;
139
+ }
140
+
141
+ // Otherwise, build an API URL from the asset reference
142
+ let assetId: string | null = null;
143
+
144
+ if (typeof this._source === 'string') {
145
+ console.log('[ImageUrlBuilder] Source is string:', this._source);
146
+ assetId = this._source;
147
+ } else if (typeof this._source === 'object') {
148
+ console.log('[ImageUrlBuilder] Source is object, checking for asset._ref or _ref');
149
+ if ('asset' in this._source && this._source.asset?._ref) {
150
+ assetId = this._source.asset._ref;
151
+ console.log('[ImageUrlBuilder] Found asset._ref:', assetId);
152
+ } else if ('_ref' in this._source) {
153
+ assetId = this._source._ref;
154
+ console.log('[ImageUrlBuilder] Found _ref:', assetId);
155
+ }
156
+ }
157
+
158
+ if (!assetId) {
159
+ console.warn('[ImageUrlBuilder] Could not extract asset ID from source:', this._source);
160
+ return null;
161
+ }
162
+
163
+ const finalUrl = `/media/${assetId}/image`;
164
+ console.log('[ImageUrlBuilder] Building CDN URL:', finalUrl);
165
+ return finalUrl;
166
+ }
167
+
168
+ /**
169
+ * Alias for url()
170
+ */
171
+ toString(): string | null {
172
+ return this.url();
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Factory function to create an image URL builder
178
+ *
179
+ * Note: Currently returns direct S3/R2 URLs without transformations.
180
+ * The baseUrl parameter is accepted for future compatibility but not currently used
181
+ * since assets already contain their full public URLs.
182
+ *
183
+ * For multi-tenant access with API keys, provide a signAssetUrl function:
184
+ * const urlFor = imageUrlBuilder({
185
+ * signAssetUrl: (assetId) => `/api/assets/${assetId}?token=${generateToken(assetId)}`
186
+ * })
187
+ *
188
+ * Usage:
189
+ * const urlFor = imageUrlBuilder({ baseUrl: 'https://yourdomain.com' })
190
+ * const url = urlFor(image).url() // Returns asset.url directly
191
+ *
192
+ * Future usage with transformations:
193
+ * const url = urlFor(image).width(800).quality(80).url()
194
+ * // Will return transformed image once dynamic rendering is implemented
195
+ */
196
+ export function imageUrlBuilder() {
197
+ return (source?: ImageValue | ImageAsset | string | Asset | null) => {
198
+ const builder = new ImageUrlBuilder();
199
+ if (source) {
200
+ builder.image(source);
201
+ }
202
+ return builder;
203
+ };
204
+ }
@@ -0,0 +1,12 @@
1
+ // Aphex CMS Utilities
2
+
3
+ // Schema utilities
4
+ export * from '../schema-utils/index';
5
+
6
+ // Validation utilities
7
+ export * from '../field-validation/utils';
8
+
9
+ // Other utilities
10
+ export * from './content-hash';
11
+ export * from './slug';
12
+ export * from './image-url';
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Generate a URL-friendly slug from a string
3
+ * @param text - The text to convert to a slug
4
+ * @returns A URL-safe slug string
5
+ */
6
+ export function generateSlug(text: string): string {
7
+ if (!text) return '';
8
+
9
+ return (
10
+ text
11
+ .toString()
12
+ .toLowerCase()
13
+ .trim()
14
+ // Replace spaces and multiple special characters with single hyphens
15
+ .replace(/[^a-z0-9]+/g, '-')
16
+ // Remove leading and trailing hyphens
17
+ .replace(/^-+|-+$/g, '')
18
+ );
19
+ }
20
+
21
+ /**
22
+ * Validate if a string is a valid slug
23
+ * @param slug - The slug to validate
24
+ * @returns Boolean indicating if the slug is valid
25
+ */
26
+ export function isValidSlug(slug: string): boolean {
27
+ if (!slug) return false;
28
+
29
+ // Valid slug: lowercase letters, numbers, and hyphens only
30
+ // Cannot start or end with hyphen
31
+ const slugPattern = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
32
+ return slugPattern.test(slug);
33
+ }
@@ -0,0 +1,13 @@
1
+ import { clsx, type ClassValue } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
7
+
8
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9
+ export type WithoutChild<T> = T extends { child?: any } ? Omit<T, 'child'> : T;
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ export type WithoutChildren<T> = T extends { children?: any } ? Omit<T, 'children'> : T;
12
+ export type WithoutChildrenOrChild<T> = WithoutChildren<WithoutChild<T>>;
13
+ export type WithElementRef<T, U extends HTMLElement = HTMLElement> = T & { ref?: U | null };