sovrium 0.0.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 (527) hide show
  1. package/CHANGELOG.md +3497 -0
  2. package/LICENSE.md +147 -0
  3. package/LICENSE_EE.md +297 -0
  4. package/README.md +321 -0
  5. package/drizzle/0000_melted_kabuki.sql +163 -0
  6. package/drizzle/meta/0000_snapshot.json +1216 -0
  7. package/drizzle/meta/_journal.json +13 -0
  8. package/package.json +167 -0
  9. package/schemas/0.0.1/app.openapi.json +70 -0
  10. package/schemas/0.0.1/app.schema.json +7961 -0
  11. package/schemas/0.0.2/app.openapi.json +80 -0
  12. package/schemas/0.0.2/app.schema.json +8829 -0
  13. package/schemas/development/app.openapi.json +70 -0
  14. package/schemas/development/app.schema.json +7456 -0
  15. package/src/application/errors/app-validation-error.ts +14 -0
  16. package/src/application/errors/static-generation-error.ts +16 -0
  17. package/src/application/metadata/favicon-transformer.ts +127 -0
  18. package/src/application/models/server.ts +27 -0
  19. package/src/application/ports/models/user-metadata.ts +36 -0
  20. package/src/application/ports/models/user-session.ts +34 -0
  21. package/src/application/ports/repositories/activity-log-repository.ts +68 -0
  22. package/src/application/ports/repositories/activity-repository.ts +49 -0
  23. package/src/application/ports/repositories/analytics-repository.ts +164 -0
  24. package/src/application/ports/repositories/auth-repository.ts +33 -0
  25. package/src/application/ports/repositories/batch-repository.ts +86 -0
  26. package/src/application/ports/repositories/comment-repository.ts +150 -0
  27. package/src/application/ports/repositories/index.ts +41 -0
  28. package/src/application/ports/repositories/table-repository.ts +139 -0
  29. package/src/application/ports/services/css-compiler.ts +55 -0
  30. package/src/application/ports/services/index.ts +16 -0
  31. package/src/application/ports/services/page-renderer.ts +79 -0
  32. package/src/application/ports/services/server-factory.ts +80 -0
  33. package/src/application/ports/services/static-site-generator.ts +82 -0
  34. package/src/application/use-cases/activity/programs.ts +66 -0
  35. package/src/application/use-cases/analytics/collect-page-view.ts +114 -0
  36. package/src/application/use-cases/analytics/purge-old-data.ts +40 -0
  37. package/src/application/use-cases/analytics/query-campaigns.ts +43 -0
  38. package/src/application/use-cases/analytics/query-devices.ts +36 -0
  39. package/src/application/use-cases/analytics/query-overview.ts +50 -0
  40. package/src/application/use-cases/analytics/query-pages.ts +40 -0
  41. package/src/application/use-cases/analytics/query-referrers.ts +43 -0
  42. package/src/application/use-cases/analytics/ua-parser.ts +89 -0
  43. package/src/application/use-cases/analytics/visitor-hash.ts +77 -0
  44. package/src/application/use-cases/auth/bootstrap-admin.ts +270 -0
  45. package/src/application/use-cases/list-activity-logs.ts +123 -0
  46. package/src/application/use-cases/server/generate-static-helpers.ts +374 -0
  47. package/src/application/use-cases/server/generate-static.ts +287 -0
  48. package/src/application/use-cases/server/start-server.ts +118 -0
  49. package/src/application/use-cases/server/startup-error-handler.ts +69 -0
  50. package/src/application/use-cases/server/static-content-generators.ts +182 -0
  51. package/src/application/use-cases/server/static-language-generators.ts +181 -0
  52. package/src/application/use-cases/server/static-url-rewriter.ts +237 -0
  53. package/src/application/use-cases/server/translation-replacer.ts +164 -0
  54. package/src/application/use-cases/tables/activity-programs.ts +93 -0
  55. package/src/application/use-cases/tables/batch-operations.ts +156 -0
  56. package/src/application/use-cases/tables/comment-programs.ts +436 -0
  57. package/src/application/use-cases/tables/permissions/permissions.ts +25 -0
  58. package/src/application/use-cases/tables/programs.ts +435 -0
  59. package/src/application/use-cases/tables/table-operations.ts +412 -0
  60. package/src/application/use-cases/tables/user-role.ts +52 -0
  61. package/src/application/use-cases/tables/utils/display-formatter.ts +471 -0
  62. package/src/application/use-cases/tables/utils/field-read-filter.ts +189 -0
  63. package/src/application/use-cases/tables/utils/list-helpers.ts +122 -0
  64. package/src/application/use-cases/tables/utils/record-transformer.ts +319 -0
  65. package/src/cli.ts +370 -0
  66. package/src/domain/errors/create-tagged-error.ts +36 -0
  67. package/src/domain/errors/index.ts +78 -0
  68. package/src/domain/models/api/analytics.ts +179 -0
  69. package/src/domain/models/api/auth.ts +231 -0
  70. package/src/domain/models/api/common.ts +60 -0
  71. package/src/domain/models/api/error.ts +89 -0
  72. package/src/domain/models/api/health.ts +38 -0
  73. package/src/domain/models/api/index.ts +42 -0
  74. package/src/domain/models/api/request.ts +132 -0
  75. package/src/domain/models/api/tables.ts +444 -0
  76. package/src/domain/models/app/analytics/index.ts +129 -0
  77. package/src/domain/models/app/auth/config.ts +116 -0
  78. package/src/domain/models/app/auth/index.ts +230 -0
  79. package/src/domain/models/app/auth/methods/email-and-password.ts +67 -0
  80. package/src/domain/models/app/auth/methods/index.ts +11 -0
  81. package/src/domain/models/app/auth/methods/magic-link.ts +54 -0
  82. package/src/domain/models/app/auth/oauth/index.ts +8 -0
  83. package/src/domain/models/app/auth/oauth/providers.ts +105 -0
  84. package/src/domain/models/app/auth/plugins/admin.ts +130 -0
  85. package/src/domain/models/app/auth/plugins/index.ts +74 -0
  86. package/src/domain/models/app/auth/plugins/two-factor.ts +63 -0
  87. package/src/domain/models/app/auth/roles.ts +179 -0
  88. package/src/domain/models/app/auth/strategies.ts +191 -0
  89. package/src/domain/models/app/auth/validation.ts +127 -0
  90. package/src/domain/models/app/common/branded-ids.ts +200 -0
  91. package/src/domain/models/app/common/definitions.ts +187 -0
  92. package/src/domain/models/app/component/common/component-children.ts +119 -0
  93. package/src/domain/models/app/component/common/component-props.ts +89 -0
  94. package/src/domain/models/app/component/common/component-reference.ts +170 -0
  95. package/src/domain/models/app/component/component.ts +81 -0
  96. package/src/domain/models/app/components.ts +65 -0
  97. package/src/domain/models/app/description.ts +83 -0
  98. package/src/domain/models/app/index.ts +258 -0
  99. package/src/domain/models/app/language/language-config.ts +200 -0
  100. package/src/domain/models/app/languages.ts +205 -0
  101. package/src/domain/models/app/name.ts +66 -0
  102. package/src/domain/models/app/page/common/interactions/click-interaction.ts +116 -0
  103. package/src/domain/models/app/page/common/interactions/entrance-animation.ts +84 -0
  104. package/src/domain/models/app/page/common/interactions/hover-interaction.ts +144 -0
  105. package/src/domain/models/app/page/common/interactions/interactions.ts +64 -0
  106. package/src/domain/models/app/page/common/interactions/scroll-interaction.ts +93 -0
  107. package/src/domain/models/app/page/common/responsive.ts +114 -0
  108. package/src/domain/models/app/page/common/url.ts +35 -0
  109. package/src/domain/models/app/page/common/variable-reference.ts +53 -0
  110. package/src/domain/models/app/page/id.ts +44 -0
  111. package/src/domain/models/app/page/index.ts +270 -0
  112. package/src/domain/models/app/page/meta/analytics.ts +248 -0
  113. package/src/domain/models/app/page/meta/custom-elements.ts +180 -0
  114. package/src/domain/models/app/page/meta/dns-prefetch.ts +77 -0
  115. package/src/domain/models/app/page/meta/favicon-set.ts +203 -0
  116. package/src/domain/models/app/page/meta/favicon.ts +50 -0
  117. package/src/domain/models/app/page/meta/favicons-config.ts +73 -0
  118. package/src/domain/models/app/page/meta/index.ts +278 -0
  119. package/src/domain/models/app/page/meta/open-graph.ts +166 -0
  120. package/src/domain/models/app/page/meta/preload.ts +190 -0
  121. package/src/domain/models/app/page/meta/structured-data/article.ts +211 -0
  122. package/src/domain/models/app/page/meta/structured-data/breadcrumb.ts +115 -0
  123. package/src/domain/models/app/page/meta/structured-data/common-fields.ts +201 -0
  124. package/src/domain/models/app/page/meta/structured-data/education-event.ts +256 -0
  125. package/src/domain/models/app/page/meta/structured-data/faq-page.ts +127 -0
  126. package/src/domain/models/app/page/meta/structured-data/index.ts +95 -0
  127. package/src/domain/models/app/page/meta/structured-data/local-business.ts +247 -0
  128. package/src/domain/models/app/page/meta/structured-data/organization.ts +171 -0
  129. package/src/domain/models/app/page/meta/structured-data/person.ts +138 -0
  130. package/src/domain/models/app/page/meta/structured-data/postal-address.ts +106 -0
  131. package/src/domain/models/app/page/meta/structured-data/product.ts +214 -0
  132. package/src/domain/models/app/page/meta/twitter-card.ts +217 -0
  133. package/src/domain/models/app/page/name.ts +38 -0
  134. package/src/domain/models/app/page/path.ts +21 -0
  135. package/src/domain/models/app/page/scripts/external-scripts.ts +163 -0
  136. package/src/domain/models/app/page/scripts/features.ts +135 -0
  137. package/src/domain/models/app/page/scripts/inline-scripts.ts +114 -0
  138. package/src/domain/models/app/page/scripts/scripts.ts +102 -0
  139. package/src/domain/models/app/page/sections.ts +298 -0
  140. package/src/domain/models/app/pages.ts +61 -0
  141. package/src/domain/models/app/permissions/index.ts +61 -0
  142. package/src/domain/models/app/permissions/resource-action.ts +114 -0
  143. package/src/domain/models/app/permissions/roles.ts +120 -0
  144. package/src/domain/models/app/table/check-constraints.ts +105 -0
  145. package/src/domain/models/app/table/cycle-detection.ts +124 -0
  146. package/src/domain/models/app/table/database-identifier.ts +153 -0
  147. package/src/domain/models/app/table/field-name.ts +36 -0
  148. package/src/domain/models/app/table/field-types/advanced/array-field.ts +33 -0
  149. package/src/domain/models/app/table/field-types/advanced/autonumber-field.ts +54 -0
  150. package/src/domain/models/app/table/field-types/advanced/button-field.ts +56 -0
  151. package/src/domain/models/app/table/field-types/advanced/color-field.ts +57 -0
  152. package/src/domain/models/app/table/field-types/advanced/count-field.ts +54 -0
  153. package/src/domain/models/app/table/field-types/advanced/formula-field.ts +58 -0
  154. package/src/domain/models/app/table/field-types/advanced/geolocation-field.ts +49 -0
  155. package/src/domain/models/app/table/field-types/advanced/index.ts +16 -0
  156. package/src/domain/models/app/table/field-types/advanced/json-field.ts +25 -0
  157. package/src/domain/models/app/table/field-types/advanced/unknown-field.ts +85 -0
  158. package/src/domain/models/app/table/field-types/base-field.ts +42 -0
  159. package/src/domain/models/app/table/field-types/date-time/created-at-field.ts +49 -0
  160. package/src/domain/models/app/table/field-types/date-time/date-field.ts +95 -0
  161. package/src/domain/models/app/table/field-types/date-time/deleted-at-field.ts +56 -0
  162. package/src/domain/models/app/table/field-types/date-time/duration-field.ts +73 -0
  163. package/src/domain/models/app/table/field-types/date-time/index.ts +12 -0
  164. package/src/domain/models/app/table/field-types/date-time/updated-at-field.ts +50 -0
  165. package/src/domain/models/app/table/field-types/index.ts +19 -0
  166. package/src/domain/models/app/table/field-types/media/barcode-field.ts +58 -0
  167. package/src/domain/models/app/table/field-types/media/index.ts +10 -0
  168. package/src/domain/models/app/table/field-types/media/multiple-attachments-field.ts +80 -0
  169. package/src/domain/models/app/table/field-types/media/single-attachment-field.ts +81 -0
  170. package/src/domain/models/app/table/field-types/numeric/currency-field.ts +144 -0
  171. package/src/domain/models/app/table/field-types/numeric/decimal-field.ts +113 -0
  172. package/src/domain/models/app/table/field-types/numeric/index.ts +13 -0
  173. package/src/domain/models/app/table/field-types/numeric/integer-field.ts +98 -0
  174. package/src/domain/models/app/table/field-types/numeric/percentage-field.ts +115 -0
  175. package/src/domain/models/app/table/field-types/numeric/progress-field.ts +71 -0
  176. package/src/domain/models/app/table/field-types/numeric/rating-field.ts +74 -0
  177. package/src/domain/models/app/table/field-types/relational/index.ts +10 -0
  178. package/src/domain/models/app/table/field-types/relational/lookup-field.ts +46 -0
  179. package/src/domain/models/app/table/field-types/relational/relationship-field.ts +112 -0
  180. package/src/domain/models/app/table/field-types/relational/rollup-field.ts +58 -0
  181. package/src/domain/models/app/table/field-types/selection/checkbox-field.ts +51 -0
  182. package/src/domain/models/app/table/field-types/selection/index.ts +11 -0
  183. package/src/domain/models/app/table/field-types/selection/multi-select-field.ts +68 -0
  184. package/src/domain/models/app/table/field-types/selection/single-select-field.ts +54 -0
  185. package/src/domain/models/app/table/field-types/selection/status-field.ts +37 -0
  186. package/src/domain/models/app/table/field-types/text/email-field.ts +80 -0
  187. package/src/domain/models/app/table/field-types/text/index.ts +13 -0
  188. package/src/domain/models/app/table/field-types/text/long-text-field.ts +77 -0
  189. package/src/domain/models/app/table/field-types/text/phone-number-field.ts +82 -0
  190. package/src/domain/models/app/table/field-types/text/rich-text-field.ts +66 -0
  191. package/src/domain/models/app/table/field-types/text/single-line-text-field.ts +79 -0
  192. package/src/domain/models/app/table/field-types/text/url-field.ts +81 -0
  193. package/src/domain/models/app/table/field-types/user/created-by-field.ts +50 -0
  194. package/src/domain/models/app/table/field-types/user/deleted-by-field.ts +57 -0
  195. package/src/domain/models/app/table/field-types/user/index.ts +11 -0
  196. package/src/domain/models/app/table/field-types/user/updated-by-field.ts +51 -0
  197. package/src/domain/models/app/table/field-types/user/user-field.ts +52 -0
  198. package/src/domain/models/app/table/field-types/validation-utils.ts +166 -0
  199. package/src/domain/models/app/table/fields.ts +216 -0
  200. package/src/domain/models/app/table/foreign-keys.ts +111 -0
  201. package/src/domain/models/app/table/formula-keywords.ts +326 -0
  202. package/src/domain/models/app/table/id.ts +31 -0
  203. package/src/domain/models/app/table/index.ts +290 -0
  204. package/src/domain/models/app/table/indexes.ts +80 -0
  205. package/src/domain/models/app/table/name.ts +37 -0
  206. package/src/domain/models/app/table/permissions/field-permission.ts +83 -0
  207. package/src/domain/models/app/table/permissions/index.ts +167 -0
  208. package/src/domain/models/app/table/permissions/permission-evaluator.ts +372 -0
  209. package/src/domain/models/app/table/permissions/permission.ts +49 -0
  210. package/src/domain/models/app/table/primary-key.ts +62 -0
  211. package/src/domain/models/app/table/table-formula-validation.ts +168 -0
  212. package/src/domain/models/app/table/table-indexes-validation.ts +38 -0
  213. package/src/domain/models/app/table/table-permissions-validation.ts +77 -0
  214. package/src/domain/models/app/table/table-primary-key-validation.ts +49 -0
  215. package/src/domain/models/app/table/table-views-validation.ts +408 -0
  216. package/src/domain/models/app/table/unique-constraints.ts +79 -0
  217. package/src/domain/models/app/table/views/fields.ts +28 -0
  218. package/src/domain/models/app/table/views/filters.ts +162 -0
  219. package/src/domain/models/app/table/views/group-by.ts +32 -0
  220. package/src/domain/models/app/table/views/id.ts +50 -0
  221. package/src/domain/models/app/table/views/index.ts +177 -0
  222. package/src/domain/models/app/table/views/name.ts +32 -0
  223. package/src/domain/models/app/table/views/permissions.ts +98 -0
  224. package/src/domain/models/app/table/views/sorts.ts +31 -0
  225. package/src/domain/models/app/tables.ts +695 -0
  226. package/src/domain/models/app/theme/animations.ts +208 -0
  227. package/src/domain/models/app/theme/border-radius.ts +58 -0
  228. package/src/domain/models/app/theme/breakpoints.ts +62 -0
  229. package/src/domain/models/app/theme/colors.ts +110 -0
  230. package/src/domain/models/app/theme/fonts.ts +164 -0
  231. package/src/domain/models/app/theme/shadows.ts +61 -0
  232. package/src/domain/models/app/theme/spacing.ts +115 -0
  233. package/src/domain/models/app/theme.ts +66 -0
  234. package/src/domain/models/app/version.ts +87 -0
  235. package/src/domain/models/record-comment.ts +91 -0
  236. package/src/domain/utils/content-parsing.ts +49 -0
  237. package/src/domain/utils/format-detection.ts +69 -0
  238. package/src/domain/utils/index.ts +9 -0
  239. package/src/domain/utils/route-matcher.ts +184 -0
  240. package/src/domain/utils/translation-resolver.ts +170 -0
  241. package/src/index.ts +208 -0
  242. package/src/infrastructure/analytics/tracking-script.ts +48 -0
  243. package/src/infrastructure/auth/better-auth/auth.ts +216 -0
  244. package/src/infrastructure/auth/better-auth/email-handlers.ts +162 -0
  245. package/src/infrastructure/auth/better-auth/index.ts +16 -0
  246. package/src/infrastructure/auth/better-auth/layer.ts +97 -0
  247. package/src/infrastructure/auth/better-auth/plugins/admin.ts +56 -0
  248. package/src/infrastructure/auth/better-auth/plugins/magic-link.ts +31 -0
  249. package/src/infrastructure/auth/better-auth/plugins/two-factor.ts +19 -0
  250. package/src/infrastructure/auth/better-auth/schema.ts +152 -0
  251. package/src/infrastructure/auth/index.ts +27 -0
  252. package/src/infrastructure/css/cache/css-cache-service.ts +130 -0
  253. package/src/infrastructure/css/compiler.ts +210 -0
  254. package/src/infrastructure/css/css-compiler-live.ts +20 -0
  255. package/src/infrastructure/css/index.ts +25 -0
  256. package/src/infrastructure/css/styles/animation-styles-generator.ts +177 -0
  257. package/src/infrastructure/css/styles/click-animations.ts +147 -0
  258. package/src/infrastructure/css/styles/component-layer-generators.ts +147 -0
  259. package/src/infrastructure/css/theme/theme-generators.ts +130 -0
  260. package/src/infrastructure/css/theme/theme-layer-generators.ts +219 -0
  261. package/src/infrastructure/css/theme/theme-token-resolver.ts +76 -0
  262. package/src/infrastructure/database/activity-queries.ts +111 -0
  263. package/src/infrastructure/database/auth/auth-validation.ts +101 -0
  264. package/src/infrastructure/database/drizzle/db-bun.ts +17 -0
  265. package/src/infrastructure/database/drizzle/db.ts +17 -0
  266. package/src/infrastructure/database/drizzle/index.ts +16 -0
  267. package/src/infrastructure/database/drizzle/layer.ts +34 -0
  268. package/src/infrastructure/database/drizzle/migrate.ts +77 -0
  269. package/src/infrastructure/database/drizzle/schema/activity-log.ts +111 -0
  270. package/src/infrastructure/database/drizzle/schema/analytics-page-views.ts +116 -0
  271. package/src/infrastructure/database/drizzle/schema/migration-audit.ts +68 -0
  272. package/src/infrastructure/database/drizzle/schema/record-comments.ts +79 -0
  273. package/src/infrastructure/database/drizzle/schema.ts +12 -0
  274. package/src/infrastructure/database/field-utils.ts +87 -0
  275. package/src/infrastructure/database/filter-operators.ts +136 -0
  276. package/src/infrastructure/database/formula/formula-trigger-generators.ts +114 -0
  277. package/src/infrastructure/database/formula/formula-utils.ts +440 -0
  278. package/src/infrastructure/database/generators/index-generators.ts +152 -0
  279. package/src/infrastructure/database/generators/trigger-generators.ts +154 -0
  280. package/src/infrastructure/database/index.ts +35 -0
  281. package/src/infrastructure/database/lookup/lookup-expression-generators.ts +356 -0
  282. package/src/infrastructure/database/lookup/lookup-expressions.ts +116 -0
  283. package/src/infrastructure/database/lookup/lookup-view-generators.ts +403 -0
  284. package/src/infrastructure/database/lookup/lookup-view-helpers.ts +65 -0
  285. package/src/infrastructure/database/lookup/lookup-view-triggers.ts +121 -0
  286. package/src/infrastructure/database/migration-audit-trail.ts +375 -0
  287. package/src/infrastructure/database/repositories/activity-log-repository-live.ts +99 -0
  288. package/src/infrastructure/database/repositories/activity-repository-live.ts +21 -0
  289. package/src/infrastructure/database/repositories/analytics-repository-live.ts +316 -0
  290. package/src/infrastructure/database/repositories/auth-repository-live.ts +42 -0
  291. package/src/infrastructure/database/repositories/batch-repository-live.ts +29 -0
  292. package/src/infrastructure/database/repositories/comment-repository-live.ts +39 -0
  293. package/src/infrastructure/database/repositories/table-repository-live.ts +38 -0
  294. package/src/infrastructure/database/schema/schema-dependency-sorting.ts +142 -0
  295. package/src/infrastructure/database/schema/schema-initializer.ts +598 -0
  296. package/src/infrastructure/database/schema-migration/column-detection.ts +286 -0
  297. package/src/infrastructure/database/schema-migration/constants.ts +31 -0
  298. package/src/infrastructure/database/schema-migration/constraint-sync.ts +288 -0
  299. package/src/infrastructure/database/schema-migration/index-sync.ts +108 -0
  300. package/src/infrastructure/database/schema-migration/index.ts +66 -0
  301. package/src/infrastructure/database/schema-migration/migration-statements.ts +106 -0
  302. package/src/infrastructure/database/schema-migration/rename-detection.ts +87 -0
  303. package/src/infrastructure/database/schema-migration/table-operations.ts +65 -0
  304. package/src/infrastructure/database/schema-migration/type-utils.ts +98 -0
  305. package/src/infrastructure/database/schema-migration/types.ts +14 -0
  306. package/src/infrastructure/database/schema-migration-helpers.ts +53 -0
  307. package/src/infrastructure/database/session-context.ts +20 -0
  308. package/src/infrastructure/database/sql/sql-check-constraints.ts +252 -0
  309. package/src/infrastructure/database/sql/sql-column-generators.ts +174 -0
  310. package/src/infrastructure/database/sql/sql-execution.ts +245 -0
  311. package/src/infrastructure/database/sql/sql-field-predicates.ts +81 -0
  312. package/src/infrastructure/database/sql/sql-generators.ts +91 -0
  313. package/src/infrastructure/database/sql/sql-junction-tables.ts +79 -0
  314. package/src/infrastructure/database/sql/sql-key-constraints.ts +210 -0
  315. package/src/infrastructure/database/sql/sql-type-mappings.ts +106 -0
  316. package/src/infrastructure/database/sql/sql-utils.ts +53 -0
  317. package/src/infrastructure/database/table-live-layers.ts +30 -0
  318. package/src/infrastructure/database/table-operations/column-generators.ts +82 -0
  319. package/src/infrastructure/database/table-operations/create-table-sql.ts +81 -0
  320. package/src/infrastructure/database/table-operations/index.ts +55 -0
  321. package/src/infrastructure/database/table-operations/migration-utils.ts +157 -0
  322. package/src/infrastructure/database/table-operations/table-effects.ts +234 -0
  323. package/src/infrastructure/database/table-operations/table-features.ts +96 -0
  324. package/src/infrastructure/database/table-operations/type-compatibility.ts +58 -0
  325. package/src/infrastructure/database/table-operations.ts +47 -0
  326. package/src/infrastructure/database/table-queries/batch/batch-create.ts +80 -0
  327. package/src/infrastructure/database/table-queries/batch/batch-delete.ts +212 -0
  328. package/src/infrastructure/database/table-queries/batch/batch-helpers.ts +124 -0
  329. package/src/infrastructure/database/table-queries/batch/batch-restore.ts +161 -0
  330. package/src/infrastructure/database/table-queries/batch/batch-update.ts +146 -0
  331. package/src/infrastructure/database/table-queries/batch/batch-upsert.ts +357 -0
  332. package/src/infrastructure/database/table-queries/batch/batch.ts +14 -0
  333. package/src/infrastructure/database/table-queries/crud/crud-read.ts +351 -0
  334. package/src/infrastructure/database/table-queries/crud/crud-write.ts +399 -0
  335. package/src/infrastructure/database/table-queries/crud/crud.ts +16 -0
  336. package/src/infrastructure/database/table-queries/index.ts +11 -0
  337. package/src/infrastructure/database/table-queries/mutation-helpers/authorship-helpers.ts +152 -0
  338. package/src/infrastructure/database/table-queries/mutation-helpers/create-record-helpers.ts +90 -0
  339. package/src/infrastructure/database/table-queries/mutation-helpers/delete-helpers.ts +163 -0
  340. package/src/infrastructure/database/table-queries/mutation-helpers/record-fetch-helpers.ts +79 -0
  341. package/src/infrastructure/database/table-queries/mutation-helpers/update-helpers.ts +74 -0
  342. package/src/infrastructure/database/table-queries/query-helpers/activity-log-helpers.ts +53 -0
  343. package/src/infrastructure/database/table-queries/query-helpers/activity-queries.ts +106 -0
  344. package/src/infrastructure/database/table-queries/query-helpers/aggregation-helpers.ts +314 -0
  345. package/src/infrastructure/database/table-queries/query-helpers/comment-queries.ts +414 -0
  346. package/src/infrastructure/database/table-queries/query-helpers/record-validation-queries.ts +126 -0
  347. package/src/infrastructure/database/table-queries/query-helpers/trash-helpers.ts +58 -0
  348. package/src/infrastructure/database/table-queries/shared/error-handling.ts +47 -0
  349. package/src/infrastructure/database/table-queries/shared/typed-execute.ts +27 -0
  350. package/src/infrastructure/database/table-queries/shared/user-join-helpers.ts +38 -0
  351. package/src/infrastructure/database/table-queries/shared/validation.ts +39 -0
  352. package/src/infrastructure/database/views/view-generators.ts +258 -0
  353. package/src/infrastructure/devtools/devtools-layer.ts +43 -0
  354. package/src/infrastructure/devtools/index.ts +8 -0
  355. package/src/infrastructure/email/email-config.ts +103 -0
  356. package/src/infrastructure/email/email-service.ts +152 -0
  357. package/src/infrastructure/email/index.ts +107 -0
  358. package/src/infrastructure/email/nodemailer.ts +125 -0
  359. package/src/infrastructure/email/templates.ts +244 -0
  360. package/src/infrastructure/errors/auth-config-required-error.ts +21 -0
  361. package/src/infrastructure/errors/auth-error.ts +16 -0
  362. package/src/infrastructure/errors/css-compilation-error.ts +14 -0
  363. package/src/infrastructure/errors/index.ts +26 -0
  364. package/src/infrastructure/errors/schema-initialization-error.ts +19 -0
  365. package/src/infrastructure/errors/server-creation-error.ts +14 -0
  366. package/src/infrastructure/filesystem/copy-directory.ts +136 -0
  367. package/src/infrastructure/layers/app-layer.ts +61 -0
  368. package/src/infrastructure/layers/page-renderer-layer.ts +41 -0
  369. package/src/infrastructure/logging/index.ts +8 -0
  370. package/src/infrastructure/logging/logger.ts +204 -0
  371. package/src/infrastructure/schema/file-loader.ts +53 -0
  372. package/src/infrastructure/schema/index.ts +15 -0
  373. package/src/infrastructure/schema/remote-loader.ts +48 -0
  374. package/src/infrastructure/server/index.ts +26 -0
  375. package/src/infrastructure/server/language-detection.ts +87 -0
  376. package/src/infrastructure/server/lifecycle.ts +67 -0
  377. package/src/infrastructure/server/route-setup/api-routes.ts +310 -0
  378. package/src/infrastructure/server/route-setup/auth-route-utils.ts +399 -0
  379. package/src/infrastructure/server/route-setup/auth-routes.ts +245 -0
  380. package/src/infrastructure/server/route-setup/openapi-routes.ts +45 -0
  381. package/src/infrastructure/server/route-setup/openapi-schema.ts +120 -0
  382. package/src/infrastructure/server/route-setup/page-routes.ts +219 -0
  383. package/src/infrastructure/server/route-setup/static-assets.ts +191 -0
  384. package/src/infrastructure/server/server-factory-live.ts +45 -0
  385. package/src/infrastructure/server/server.ts +275 -0
  386. package/src/infrastructure/server/ssg-adapter.ts +196 -0
  387. package/src/infrastructure/server/static-site-generator-live.ts +20 -0
  388. package/src/infrastructure/utils/accept-language-parser.ts +106 -0
  389. package/src/infrastructure/utils/glob-matcher.ts +50 -0
  390. package/src/presentation/api/client.ts +114 -0
  391. package/src/presentation/api/middleware/auth.ts +233 -0
  392. package/src/presentation/api/middleware/table.ts +155 -0
  393. package/src/presentation/api/middleware/validation.ts +88 -0
  394. package/src/presentation/api/routes/activity/get-activity-by-id-handler.ts +77 -0
  395. package/src/presentation/api/routes/activity/index.ts +28 -0
  396. package/src/presentation/api/routes/activity.ts +339 -0
  397. package/src/presentation/api/routes/analytics.ts +328 -0
  398. package/src/presentation/api/routes/auth.ts +169 -0
  399. package/src/presentation/api/routes/index.ts +11 -0
  400. package/src/presentation/api/routes/tables/activity-handlers.ts +57 -0
  401. package/src/presentation/api/routes/tables/batch-permission-helpers.ts +163 -0
  402. package/src/presentation/api/routes/tables/batch-routes.ts +355 -0
  403. package/src/presentation/api/routes/tables/comment-handlers.ts +377 -0
  404. package/src/presentation/api/routes/tables/create-record-helpers.ts +179 -0
  405. package/src/presentation/api/routes/tables/effect-runner.ts +58 -0
  406. package/src/presentation/api/routes/tables/error-handlers.ts +53 -0
  407. package/src/presentation/api/routes/tables/field-permission-validation.ts +167 -0
  408. package/src/presentation/api/routes/tables/filter-parser.ts +75 -0
  409. package/src/presentation/api/routes/tables/formula-parser.ts +118 -0
  410. package/src/presentation/api/routes/tables/index.ts +113 -0
  411. package/src/presentation/api/routes/tables/list-records-filter.ts +54 -0
  412. package/src/presentation/api/routes/tables/param-parsers.ts +59 -0
  413. package/src/presentation/api/routes/tables/record-handlers.ts +484 -0
  414. package/src/presentation/api/routes/tables/record-routes.ts +53 -0
  415. package/src/presentation/api/routes/tables/record-update-handler.ts +200 -0
  416. package/src/presentation/api/routes/tables/sort-validation.ts +85 -0
  417. package/src/presentation/api/routes/tables/table-routes.ts +76 -0
  418. package/src/presentation/api/routes/tables/timezone-validation.ts +41 -0
  419. package/src/presentation/api/routes/tables/upsert-helpers.ts +471 -0
  420. package/src/presentation/api/routes/tables/utils.ts +159 -0
  421. package/src/presentation/api/routes/tables/view-routes.ts +51 -0
  422. package/src/presentation/api/routes/tables.ts +9 -0
  423. package/src/presentation/api/utils/context-helpers.ts +43 -0
  424. package/src/presentation/api/utils/error-sanitizer.ts +235 -0
  425. package/src/presentation/api/utils/field-permission-validator.ts +53 -0
  426. package/src/presentation/api/utils/filter-field-validator.ts +90 -0
  427. package/src/presentation/api/utils/index.ts +13 -0
  428. package/src/presentation/api/utils/run-effect.ts +94 -0
  429. package/src/presentation/api/utils/validate-request.ts +89 -0
  430. package/src/presentation/api/validation/index.ts +29 -0
  431. package/src/presentation/api/validation/rules/field-rules.ts +158 -0
  432. package/src/presentation/api/validation/rules/record-rules.ts +73 -0
  433. package/src/presentation/cli/index.ts +19 -0
  434. package/src/presentation/cli/schema-loader.ts +172 -0
  435. package/src/presentation/hooks/use-breakpoint.ts +155 -0
  436. package/src/presentation/rendering/render-error-pages.tsx +60 -0
  437. package/src/presentation/rendering/render-homepage.tsx +137 -0
  438. package/src/presentation/scripts/script-renderers.ts +112 -0
  439. package/src/presentation/styling/animation-composer.ts +117 -0
  440. package/src/presentation/styling/index.ts +13 -0
  441. package/src/presentation/styling/parse-style.ts +243 -0
  442. package/src/presentation/styling/style-utils.ts +50 -0
  443. package/src/presentation/styling/theme-colors.ts +53 -0
  444. package/src/presentation/translations/component-utils.ts +54 -0
  445. package/src/presentation/translations/index.ts +16 -0
  446. package/src/presentation/translations/translation-resolver.ts +22 -0
  447. package/src/presentation/ui/languages/language-switcher.tsx +119 -0
  448. package/src/presentation/ui/metadata/analytics-builders.tsx +174 -0
  449. package/src/presentation/ui/metadata/analytics-head.tsx +39 -0
  450. package/src/presentation/ui/metadata/custom-elements-builders.tsx +157 -0
  451. package/src/presentation/ui/metadata/extract-component-meta.ts +108 -0
  452. package/src/presentation/ui/metadata/head-elements.tsx +164 -0
  453. package/src/presentation/ui/metadata/index.tsx +35 -0
  454. package/src/presentation/ui/metadata/meta-utils.tsx +42 -0
  455. package/src/presentation/ui/metadata/open-graph-meta.tsx +57 -0
  456. package/src/presentation/ui/metadata/structured-data-from-component.tsx +134 -0
  457. package/src/presentation/ui/metadata/structured-data.tsx +88 -0
  458. package/src/presentation/ui/metadata/twitter-card-meta.tsx +80 -0
  459. package/src/presentation/ui/pages/DefaultHomePage.tsx +43 -0
  460. package/src/presentation/ui/pages/DefaultPageConfigs.ts +220 -0
  461. package/src/presentation/ui/pages/DynamicPage.tsx +307 -0
  462. package/src/presentation/ui/pages/ErrorPage.tsx +25 -0
  463. package/src/presentation/ui/pages/NotFoundPage.tsx +25 -0
  464. package/src/presentation/ui/pages/PageBodyScripts.tsx +242 -0
  465. package/src/presentation/ui/pages/PageBodyStyles.ts +52 -0
  466. package/src/presentation/ui/pages/PageHead.tsx +380 -0
  467. package/src/presentation/ui/pages/PageLangResolver.ts +58 -0
  468. package/src/presentation/ui/pages/PageMain.tsx +58 -0
  469. package/src/presentation/ui/pages/PageMetadata.ts +168 -0
  470. package/src/presentation/ui/pages/PageMetadataI18n.ts +169 -0
  471. package/src/presentation/ui/pages/PageScripts.ts +78 -0
  472. package/src/presentation/ui/pages/SectionRenderer.tsx +67 -0
  473. package/src/presentation/ui/pages/SectionSpacing.tsx +131 -0
  474. package/src/presentation/ui/sections/component-renderer.tsx +426 -0
  475. package/src/presentation/ui/sections/component-renderer.types.ts +33 -0
  476. package/src/presentation/ui/sections/components/component-reference-handler.tsx +74 -0
  477. package/src/presentation/ui/sections/components/component-resolution.ts +65 -0
  478. package/src/presentation/ui/sections/components/index.ts +9 -0
  479. package/src/presentation/ui/sections/hero.tsx +394 -0
  480. package/src/presentation/ui/sections/props/component-builder.ts +183 -0
  481. package/src/presentation/ui/sections/props/element-props.ts +179 -0
  482. package/src/presentation/ui/sections/props/index.ts +9 -0
  483. package/src/presentation/ui/sections/props/prop-conversion.ts +171 -0
  484. package/src/presentation/ui/sections/props/props-builder-config.ts +42 -0
  485. package/src/presentation/ui/sections/props/props-builder.ts +296 -0
  486. package/src/presentation/ui/sections/renderers/element-renderers/html-element-renderer.tsx +124 -0
  487. package/src/presentation/ui/sections/renderers/element-renderers/index.ts +59 -0
  488. package/src/presentation/ui/sections/renderers/element-renderers/interactive-renderers.tsx +231 -0
  489. package/src/presentation/ui/sections/renderers/element-renderers/media-renderers.tsx +102 -0
  490. package/src/presentation/ui/sections/renderers/element-renderers/text-content-renderers.tsx +42 -0
  491. package/src/presentation/ui/sections/renderers/element-renderers.ts +53 -0
  492. package/src/presentation/ui/sections/renderers/html-element-helpers.ts +100 -0
  493. package/src/presentation/ui/sections/renderers/specialized-renderers.tsx +212 -0
  494. package/src/presentation/ui/sections/rendering/component-dispatch-config.ts +31 -0
  495. package/src/presentation/ui/sections/rendering/component-registry/index.ts +39 -0
  496. package/src/presentation/ui/sections/rendering/component-registry/interactive-components.ts +54 -0
  497. package/src/presentation/ui/sections/rendering/component-registry/media-components.ts +36 -0
  498. package/src/presentation/ui/sections/rendering/component-registry/special-components.tsx +153 -0
  499. package/src/presentation/ui/sections/rendering/component-registry/structural-components.ts +215 -0
  500. package/src/presentation/ui/sections/rendering/component-registry/text-components.ts +57 -0
  501. package/src/presentation/ui/sections/rendering/component-registry-helpers.tsx +29 -0
  502. package/src/presentation/ui/sections/rendering/component-registry.tsx +21 -0
  503. package/src/presentation/ui/sections/rendering/component-type-dispatcher.tsx +33 -0
  504. package/src/presentation/ui/sections/rendering/index.ts +9 -0
  505. package/src/presentation/ui/sections/responsive/responsive-children-builder.tsx +96 -0
  506. package/src/presentation/ui/sections/responsive/responsive-content-builder.tsx +95 -0
  507. package/src/presentation/ui/sections/responsive/responsive-props-merger.ts +195 -0
  508. package/src/presentation/ui/sections/responsive/responsive-resolver.ts +213 -0
  509. package/src/presentation/ui/sections/styling/animation-composer-wrapper.ts +65 -0
  510. package/src/presentation/ui/sections/styling/class-builders.ts +45 -0
  511. package/src/presentation/ui/sections/styling/color-resolver.ts +43 -0
  512. package/src/presentation/ui/sections/styling/hover-interaction-handler.ts +107 -0
  513. package/src/presentation/ui/sections/styling/index.ts +9 -0
  514. package/src/presentation/ui/sections/styling/interaction-props-builder.ts +55 -0
  515. package/src/presentation/ui/sections/styling/shadow-resolver.ts +83 -0
  516. package/src/presentation/ui/sections/styling/spacing-resolver.ts +104 -0
  517. package/src/presentation/ui/sections/styling/style-processor.ts +170 -0
  518. package/src/presentation/ui/sections/styling/theme-tokens.ts +184 -0
  519. package/src/presentation/ui/sections/translations/i18n-content-resolver.ts +198 -0
  520. package/src/presentation/ui/sections/translations/index.ts +9 -0
  521. package/src/presentation/ui/sections/translations/translation-handler.ts +143 -0
  522. package/src/presentation/ui/sections/translations/variable-substitution.ts +225 -0
  523. package/src/presentation/ui/sections/utils/time-parser.ts +82 -0
  524. package/src/presentation/utils/link-attributes.ts +50 -0
  525. package/src/presentation/utils/string-utils.ts +58 -0
  526. package/src/presentation/utils/styles.ts +50 -0
  527. package/tsconfig.json +46 -0
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ import { Schema } from 'effect'
9
+ import { BaseFieldSchema } from '../base-field'
10
+
11
+ /**
12
+ * URL Field
13
+ *
14
+ * Text field with URL format validation. Stores web addresses (URLs) and validates
15
+ * them against standard URL format rules. Supports http://, https://, and other
16
+ * protocols. Can be marked as required, unique, or indexed. URL validation ensures
17
+ * data integrity and prevents malformed URLs from being stored. URLs are stored
18
+ * as plain text strings and can be used for links, API endpoints, and web resources.
19
+ *
20
+ * Business Rules:
21
+ * - URL format validation enforced at application level (protocol + domain + optional path)
22
+ * - Supports multiple protocols: http://, https://, ftp://, etc.
23
+ * - Unique constraint optional - useful for preventing duplicate resource links
24
+ * - Indexing recommended for search and lookup operations on URL fields
25
+ * - Constant value 'url' ensures type safety and enables discriminated unions
26
+ *
27
+ * @example
28
+ * ```typescript
29
+ * const field = {
30
+ * id: 1,
31
+ * name: 'website',
32
+ * type: 'url',
33
+ * required: true,
34
+ * unique: false,
35
+ * indexed: true,
36
+ * default: 'https://example.com'
37
+ * }
38
+ * ```
39
+ */
40
+ export const UrlFieldSchema = BaseFieldSchema.pipe(
41
+ Schema.extend(
42
+ Schema.Struct({
43
+ type: Schema.Literal('url').pipe(
44
+ Schema.annotations({
45
+ description: "Constant value 'url' for type discrimination in discriminated unions",
46
+ })
47
+ ),
48
+ default: Schema.optional(
49
+ Schema.String.pipe(
50
+ Schema.annotations({
51
+ description: 'Default URL value when creating new records',
52
+ })
53
+ )
54
+ ),
55
+ })
56
+ ),
57
+ Schema.annotations({
58
+ title: 'URL Field',
59
+ description:
60
+ 'Text field with URL format validation. Validates web addresses and supports multiple protocols (http://, https://, ftp://, etc.).',
61
+ examples: [
62
+ {
63
+ id: 1,
64
+ name: 'website',
65
+ type: 'url',
66
+ required: true,
67
+ unique: false,
68
+ indexed: true,
69
+ },
70
+ {
71
+ id: 2,
72
+ name: 'profile_url',
73
+ type: 'url',
74
+ required: false,
75
+ default: 'https://example.com/profile',
76
+ },
77
+ ],
78
+ })
79
+ )
80
+
81
+ export type UrlField = Schema.Schema.Type<typeof UrlFieldSchema>
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ import { Schema } from 'effect'
9
+ import { BaseFieldSchema } from '../base-field'
10
+
11
+ /**
12
+ * Created By Field
13
+ *
14
+ * Automatically captures the user who created a record.
15
+ * This field is system-managed and cannot be manually edited.
16
+ * Stores a reference to the user ID from the authentication system.
17
+ * Commonly used for audit trails and user activity tracking.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const field = {
22
+ * id: 1,
23
+ * name: 'created_by',
24
+ * type: 'created-by',
25
+ * indexed: true
26
+ * }
27
+ * ```
28
+ */
29
+ export const CreatedByFieldSchema = BaseFieldSchema.pipe(
30
+ Schema.extend(
31
+ Schema.Struct({
32
+ type: Schema.Literal('created-by'),
33
+ })
34
+ ),
35
+ Schema.annotations({
36
+ title: 'Created By Field',
37
+ description:
38
+ 'Automatically captures the user who created a record. System-managed field that stores user ID reference.',
39
+ examples: [
40
+ {
41
+ id: 1,
42
+ name: 'created_by',
43
+ type: 'created-by',
44
+ indexed: true,
45
+ },
46
+ ],
47
+ })
48
+ )
49
+
50
+ export type CreatedByField = Schema.Schema.Type<typeof CreatedByFieldSchema>
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ import { Schema } from 'effect'
9
+ import { BaseFieldSchema } from '../base-field'
10
+
11
+ /**
12
+ * Deleted By Field
13
+ *
14
+ * Automatically captures the user who soft-deleted a record.
15
+ * This field is system-managed and cannot be manually edited.
16
+ * Stores a reference to the user ID from the authentication system.
17
+ * Only populated when a record is soft-deleted (when deleted_at is set).
18
+ * NULL indicates the record has not been deleted or was deleted by a system process.
19
+ *
20
+ * Commonly used for:
21
+ * - Audit trails (who deleted what)
22
+ * - Compliance reporting
23
+ * - Accountability tracking
24
+ * - Deletion history
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const field = {
29
+ * id: 1,
30
+ * name: 'deleted_by',
31
+ * type: 'deleted-by',
32
+ * indexed: true
33
+ * }
34
+ * ```
35
+ */
36
+ export const DeletedByFieldSchema = BaseFieldSchema.pipe(
37
+ Schema.extend(
38
+ Schema.Struct({
39
+ type: Schema.Literal('deleted-by'),
40
+ })
41
+ ),
42
+ Schema.annotations({
43
+ title: 'Deleted By Field',
44
+ description:
45
+ 'Automatically captures the user who soft-deleted a record. System-managed field that stores user ID reference. NULL when record is active or deleted by system process.',
46
+ examples: [
47
+ {
48
+ id: 1,
49
+ name: 'deleted_by',
50
+ type: 'deleted-by',
51
+ indexed: true,
52
+ },
53
+ ],
54
+ })
55
+ )
56
+
57
+ export type DeletedByField = Schema.Schema.Type<typeof DeletedByFieldSchema>
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ export * from './user-field'
9
+ export * from './created-by-field'
10
+ export * from './updated-by-field'
11
+ export * from './deleted-by-field'
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ import { Schema } from 'effect'
9
+ import { BaseFieldSchema } from '../base-field'
10
+
11
+ /**
12
+ * Updated By Field
13
+ *
14
+ * Automatically captures the user who last modified a record.
15
+ * This field is system-managed and cannot be manually edited.
16
+ * Stores a reference to the user ID from the authentication system.
17
+ * Automatically updates on every record update operation.
18
+ * Commonly used for audit trails and tracking modification history.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const field = {
23
+ * id: 1,
24
+ * name: 'updated_by',
25
+ * type: 'updated-by',
26
+ * indexed: true
27
+ * }
28
+ * ```
29
+ */
30
+ export const UpdatedByFieldSchema = BaseFieldSchema.pipe(
31
+ Schema.extend(
32
+ Schema.Struct({
33
+ type: Schema.Literal('updated-by'),
34
+ })
35
+ ),
36
+ Schema.annotations({
37
+ title: 'Updated By Field',
38
+ description:
39
+ 'Automatically captures the user who last modified a record. System-managed field that stores user ID reference.',
40
+ examples: [
41
+ {
42
+ id: 1,
43
+ name: 'updated_by',
44
+ type: 'updated-by',
45
+ indexed: true,
46
+ },
47
+ ],
48
+ })
49
+ )
50
+
51
+ export type UpdatedByField = Schema.Schema.Type<typeof UpdatedByFieldSchema>
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ import { Schema } from 'effect'
9
+ import { BaseFieldSchema } from '../base-field'
10
+
11
+ /**
12
+ * User Field
13
+ *
14
+ * Reference field that links to users from the authentication system.
15
+ * Stores user IDs and can be used for assignments, ownership, or collaboration.
16
+ * Supports single or multiple user selection via allowMultiple flag.
17
+ *
18
+ * @example
19
+ * ```typescript
20
+ * const field = {
21
+ * id: 1,
22
+ * name: 'assigned_to',
23
+ * type: 'user',
24
+ * required: true,
25
+ * allowMultiple: false
26
+ * }
27
+ * ```
28
+ */
29
+ export const UserFieldSchema = BaseFieldSchema.pipe(
30
+ Schema.extend(
31
+ Schema.Struct({
32
+ type: Schema.Literal('user'),
33
+ allowMultiple: Schema.optional(Schema.Boolean),
34
+ })
35
+ ),
36
+ Schema.annotations({
37
+ title: 'User Field',
38
+ description:
39
+ 'Reference field linking to users from authentication system. Supports single or multiple user selection.',
40
+ examples: [
41
+ {
42
+ id: 1,
43
+ name: 'assigned_to',
44
+ type: 'user',
45
+ required: true,
46
+ allowMultiple: false,
47
+ },
48
+ ],
49
+ })
50
+ )
51
+
52
+ export type UserField = Schema.Schema.Type<typeof UserFieldSchema>
@@ -0,0 +1,166 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ import { Schema } from 'effect'
9
+
10
+ /**
11
+ * Validates that min is less than or equal to max when both are specified.
12
+ *
13
+ * This validation is used by numeric field types (integer, decimal, currency, percentage)
14
+ * to ensure that range constraints are logically valid. Returns an error message if
15
+ * validation fails, or undefined if validation passes.
16
+ *
17
+ * @param field - Object containing optional min and max properties
18
+ * @returns Error message if min > max, undefined otherwise
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * validateMinMaxRange({ min: 0, max: 100 }) // undefined (valid)
23
+ * validateMinMaxRange({ min: 100, max: 10 }) // 'min cannot be greater than max'
24
+ * validateMinMaxRange({ min: 0 }) // undefined (only min specified)
25
+ * validateMinMaxRange({ max: 100 }) // undefined (only max specified)
26
+ * ```
27
+ */
28
+ export const validateMinMaxRange = (field: {
29
+ readonly min?: number
30
+ readonly max?: number
31
+ }): string | undefined => {
32
+ if (field.min !== undefined && field.max !== undefined && field.min > field.max) {
33
+ return 'min cannot be greater than max'
34
+ }
35
+ return undefined
36
+ }
37
+
38
+ /**
39
+ * Creates a reusable options array schema for select-type fields.
40
+ *
41
+ * This schema factory is used by single-select and multi-select field types
42
+ * to ensure consistent validation of options arrays. All select fields require
43
+ * at least one option to be meaningful, and option values must be unique.
44
+ *
45
+ * @param fieldType - The type of select field (for error messages)
46
+ * @returns Effect Schema for validating options arrays
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * // Used in single-select field
51
+ * const optionsSchema = createOptionsSchema('single-select')
52
+ * // Used in multi-select field
53
+ * const optionsSchema = createOptionsSchema('multi-select')
54
+ * ```
55
+ */
56
+ export const createOptionsSchema = (fieldType: 'single-select' | 'multi-select') =>
57
+ Schema.Array(Schema.String).pipe(
58
+ Schema.minItems(1),
59
+ Schema.annotations({
60
+ message: () => `At least one option is required for ${fieldType} field`,
61
+ }),
62
+ Schema.filter((options) => {
63
+ const uniqueOptions = new Set(options)
64
+ return (
65
+ options.length === uniqueOptions.size || 'Options must be unique (duplicate option found)'
66
+ )
67
+ })
68
+ )
69
+
70
+ /**
71
+ * Creates a reusable options array schema for status-type fields with complex option objects.
72
+ *
73
+ * This schema factory is used by status field type to ensure consistent validation
74
+ * of options arrays containing objects with value and optional color properties.
75
+ * Status fields require at least one option, and option values must be unique.
76
+ *
77
+ * @returns Effect Schema for validating status field options arrays
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * // Used in status field
82
+ * const optionsSchema = createStatusOptionsSchema()
83
+ * // Validates: [{ value: 'Draft', color: '#6B7280' }, { value: 'Published' }]
84
+ * ```
85
+ */
86
+ export const createStatusOptionsSchema = () =>
87
+ Schema.Array(
88
+ Schema.Struct({
89
+ value: Schema.String.pipe(Schema.nonEmptyString({ message: () => 'value is required' })),
90
+ color: Schema.optional(
91
+ Schema.String.pipe(
92
+ Schema.pattern(/^#[0-9a-fA-F]{6}$/, {
93
+ message: () => 'Invalid color format - color must be a hex code (e.g., #3B82F6)',
94
+ }),
95
+ Schema.annotations({
96
+ description: 'Hex color code for the status',
97
+ })
98
+ )
99
+ ),
100
+ })
101
+ ).pipe(
102
+ Schema.minItems(1, { message: () => 'at least one option required' }),
103
+ Schema.filter((options) => {
104
+ const values = options.map((opt) => opt.value)
105
+ const uniqueValues = new Set(values)
106
+ return (
107
+ values.length === uniqueValues.size || 'Options must be unique (duplicate option found)'
108
+ )
109
+ })
110
+ )
111
+
112
+ /**
113
+ * Validates that button fields have required properties based on their action type.
114
+ *
115
+ * This validation is used by button field types to ensure that action-specific
116
+ * properties are provided when needed. For example, buttons with action='url'
117
+ * must have a url property, and buttons with action='automation' must have an
118
+ * automation property.
119
+ *
120
+ * @param field - Object containing action and optional url/automation properties
121
+ * @returns Error message if validation fails, true if validation passes
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * validateButtonAction({ action: 'url', url: 'https://example.com' }) // true (valid)
126
+ * validateButtonAction({ action: 'url' }) // 'url is required when action is url'
127
+ * validateButtonAction({ action: 'automation', automation: 'approve' }) // true (valid)
128
+ * validateButtonAction({ action: 'automation' }) // 'automation is required when action is automation'
129
+ * validateButtonAction({ action: 'custom' }) // true (no requirements)
130
+ * ```
131
+ */
132
+ export const validateButtonAction = (field: {
133
+ readonly action: string
134
+ readonly url?: string
135
+ readonly automation?: string
136
+ }): string | true => {
137
+ if (field.action === 'url' && !field.url) {
138
+ return 'url is required when action is url'
139
+ }
140
+ if (field.action === 'automation' && !field.automation) {
141
+ return 'automation is required when action is automation'
142
+ }
143
+ return true
144
+ }
145
+
146
+ /**
147
+ * Finds the first duplicate value in an array.
148
+ *
149
+ * This utility function is used for detecting duplicate IDs, field names, or other
150
+ * values that must be unique within a collection. Uses an efficient O(n) algorithm
151
+ * with indexOf to find the first duplicate.
152
+ *
153
+ * @param values - Array of values to check for duplicates
154
+ * @returns The first duplicate value found, or undefined if no duplicates exist
155
+ *
156
+ * @example
157
+ * ```typescript
158
+ * findDuplicate(['a', 'b', 'c']) // undefined (no duplicates)
159
+ * findDuplicate(['a', 'b', 'a', 'c']) // 'a' (first duplicate)
160
+ * findDuplicate([1, 2, 3, 2]) // 2 (works with numbers)
161
+ * findDuplicate(['x']) // undefined (single item)
162
+ * ```
163
+ */
164
+ export const findDuplicate = <T>(values: ReadonlyArray<T>): T | undefined => {
165
+ return values.find((value, index) => values.indexOf(value) !== index)
166
+ }
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Copyright (c) 2025 ESSENTIAL SERVICES
3
+ *
4
+ * This source code is licensed under the Business Source License 1.1
5
+ * found in the LICENSE.md file in the root directory of this source tree.
6
+ */
7
+
8
+ import { Schema } from 'effect'
9
+ import {
10
+ ArrayFieldSchema,
11
+ AutonumberFieldSchema,
12
+ BarcodeFieldSchema,
13
+ ButtonFieldSchema,
14
+ CheckboxFieldSchema,
15
+ ColorFieldSchema,
16
+ CountFieldSchema,
17
+ CreatedAtFieldSchema,
18
+ CreatedByFieldSchema,
19
+ CurrencyFieldSchema,
20
+ DateFieldSchema,
21
+ DecimalFieldSchema,
22
+ DeletedAtFieldSchema,
23
+ DeletedByFieldSchema,
24
+ DurationFieldSchema,
25
+ EmailFieldSchema,
26
+ FormulaFieldSchema,
27
+ GeolocationFieldSchema,
28
+ IntegerFieldSchema,
29
+ JsonFieldSchema,
30
+ LongTextFieldSchema,
31
+ LookupFieldSchema,
32
+ MultiSelectFieldSchema,
33
+ MultipleAttachmentsFieldSchema,
34
+ PercentageFieldSchema,
35
+ PhoneNumberFieldSchema,
36
+ ProgressFieldSchema,
37
+ RatingFieldSchema,
38
+ RelationshipFieldSchema,
39
+ RichTextFieldSchema,
40
+ RollupFieldSchema,
41
+ SingleAttachmentFieldSchema,
42
+ SingleLineTextFieldSchema,
43
+ SingleSelectFieldSchema,
44
+ StatusFieldSchema,
45
+ UnknownFieldSchema,
46
+ UpdatedAtFieldSchema,
47
+ UpdatedByFieldSchema,
48
+ UrlFieldSchema,
49
+ UserFieldSchema,
50
+ } from './field-types'
51
+
52
+ /**
53
+ * Table Fields
54
+ *
55
+ * Collection of all supported field types in a table.
56
+ * Each field type has specific properties and validation rules.
57
+ * Fields are the columns in your database tables and determine
58
+ * what data can be stored and how it is validated.
59
+ *
60
+ * @see docs/specifications/roadmap/tables/fields.md for full specification
61
+ */
62
+ export const FieldsSchema = Schema.Array(
63
+ Schema.Union(
64
+ // Text field types (individual schemas)
65
+ SingleLineTextFieldSchema,
66
+ LongTextFieldSchema,
67
+ PhoneNumberFieldSchema,
68
+ EmailFieldSchema,
69
+ UrlFieldSchema,
70
+ // Number field types (individual schemas)
71
+ IntegerFieldSchema,
72
+ DecimalFieldSchema,
73
+ CurrencyFieldSchema,
74
+ PercentageFieldSchema,
75
+ // Other field types
76
+ DateFieldSchema,
77
+ CheckboxFieldSchema,
78
+ SingleSelectFieldSchema,
79
+ MultiSelectFieldSchema,
80
+ RelationshipFieldSchema,
81
+ SingleAttachmentFieldSchema,
82
+ MultipleAttachmentsFieldSchema,
83
+ FormulaFieldSchema,
84
+ RollupFieldSchema,
85
+ LookupFieldSchema,
86
+ CountFieldSchema,
87
+ UserFieldSchema,
88
+ CreatedAtFieldSchema,
89
+ CreatedByFieldSchema,
90
+ UpdatedAtFieldSchema,
91
+ UpdatedByFieldSchema,
92
+ DeletedAtFieldSchema,
93
+ DeletedByFieldSchema,
94
+ RatingFieldSchema,
95
+ DurationFieldSchema,
96
+ RichTextFieldSchema,
97
+ StatusFieldSchema,
98
+ ButtonFieldSchema,
99
+ AutonumberFieldSchema,
100
+ BarcodeFieldSchema,
101
+ ColorFieldSchema,
102
+ ProgressFieldSchema,
103
+ GeolocationFieldSchema,
104
+ JsonFieldSchema,
105
+ ArrayFieldSchema,
106
+ // Unknown field type (catch-all for invalid types that will fail during SQL generation)
107
+ UnknownFieldSchema
108
+ )
109
+ ).pipe(
110
+ Schema.minItems(1),
111
+ Schema.filter((fields) => {
112
+ const ids = fields.map((field) => field.id)
113
+ const uniqueIds = new Set(ids)
114
+ return ids.length === uniqueIds.size || 'Field IDs must be unique within the table'
115
+ }),
116
+ Schema.filter((fields) => {
117
+ const names = fields.map((field) => field.name)
118
+ const uniqueNames = new Set(names)
119
+ return names.length === uniqueNames.size || 'Field names must be unique within the table'
120
+ }),
121
+ Schema.filter((fields) => {
122
+ // Validate count fields reference existing relationship-type fields
123
+ const countFields = fields.filter((field) => field.type === 'count')
124
+
125
+ const invalidResult = countFields
126
+ .map((countField) => {
127
+ const { relationshipField } = countField as { relationshipField: string }
128
+ return validateComputedFieldRelationship({
129
+ fields,
130
+ computedFieldName: countField.name,
131
+ computedFieldType: 'count',
132
+ relationshipField,
133
+ })
134
+ })
135
+ .find((result) => result !== true)
136
+
137
+ return invalidResult !== undefined ? invalidResult : true
138
+ }),
139
+ Schema.filter((fields) => {
140
+ // Validate rollup fields reference existing relationship-type fields
141
+ const rollupFields = fields.filter((field) => field.type === 'rollup')
142
+
143
+ const invalidResult = rollupFields
144
+ .map((rollupField) => {
145
+ const { relationshipField } = rollupField as { relationshipField: string }
146
+ return validateComputedFieldRelationship({
147
+ fields,
148
+ computedFieldName: rollupField.name,
149
+ computedFieldType: 'rollup',
150
+ relationshipField,
151
+ })
152
+ })
153
+ .find((result) => result !== true)
154
+
155
+ return invalidResult !== undefined ? invalidResult : true
156
+ }),
157
+ Schema.annotations({
158
+ title: 'Table Fields',
159
+ description:
160
+ 'Collection of all supported field types. Each field defines a column in the database table with specific validation and behavior.',
161
+ examples: [
162
+ [
163
+ {
164
+ id: 1,
165
+ name: 'email',
166
+ type: 'email' as const,
167
+ required: true,
168
+ },
169
+ {
170
+ id: 2,
171
+ name: 'age',
172
+ type: 'integer' as const,
173
+ min: 0,
174
+ max: 150,
175
+ },
176
+ ],
177
+ ],
178
+ })
179
+ )
180
+
181
+ export type Fields = Schema.Schema.Type<typeof FieldsSchema>
182
+
183
+ /**
184
+ * Validate that a computed field (count or rollup) references a valid relationship field.
185
+ *
186
+ * This helper validates that:
187
+ * 1. The relationshipField exists in the current table's fields
188
+ * 2. The relationshipField is a relationship type
189
+ *
190
+ * Used by both count and rollup field validation to ensure they reference valid relationships.
191
+ *
192
+ * @param params - Validation parameters
193
+ * @returns Error message if validation fails, true if valid
194
+ */
195
+ export const validateComputedFieldRelationship = (params: {
196
+ readonly fields: ReadonlyArray<{ readonly name: string; readonly type: string }>
197
+ readonly computedFieldName: string
198
+ readonly computedFieldType: 'count' | 'rollup'
199
+ readonly relationshipField: string
200
+ }): string | true => {
201
+ const { fields, computedFieldName, computedFieldType, relationshipField } = params
202
+ const fieldsByName = new Map(fields.map((field) => [field.name, field]))
203
+ const referencedField = fieldsByName.get(relationshipField)
204
+
205
+ if (!referencedField) {
206
+ const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1)
207
+ return `${capitalize(computedFieldType)} field "${computedFieldName}" references relationshipField "${relationshipField}" not found in the same table`
208
+ }
209
+
210
+ if (referencedField.type !== 'relationship') {
211
+ const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1)
212
+ return `${capitalize(computedFieldType)} field "${computedFieldName}" relationshipField "${relationshipField}" must reference a relationship field`
213
+ }
214
+
215
+ return true
216
+ }