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,115 @@
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
+ * Spacing Configuration
12
+ *
13
+ * Spacing design tokens for consistent layout. Supports both Tailwind utility
14
+ * classes (py-16, px-4) and raw CSS values (4rem, 16px, 1.5em).
15
+ *
16
+ * **Behavior Specifications**:
17
+ * - Validates Tailwind spacing utilities (py-16, px-4, gap-6, etc.)
18
+ * - Validates responsive spacing with Tailwind breakpoints (py-16 sm:py-20)
19
+ * - Validates centering and width constraints (max-w-7xl mx-auto px-4)
20
+ * - Validates consistent spacing scale (gap-small, gap, gap-large)
21
+ * - Validates custom CSS spacing values (2rem, 16px, 1.5em)
22
+ * - Supports hierarchical content width constraints (container, container-small, container-xsmall)
23
+ *
24
+ * **Token Categories**:
25
+ * - Section spacing: Vertical rhythm for page sections (py-16 sm:py-20)
26
+ * - Container spacing: Width constraints and centering (max-w-7xl mx-auto px-4)
27
+ * - Gap spacing: Space between flex/grid items (gap-6)
28
+ * - Padding spacing: Internal component spacing (p-6, p-4, p-8)
29
+ * - Margin spacing: External component spacing (m-6, m-4, m-8)
30
+ *
31
+ * @example
32
+ * ```typescript
33
+ * // Complete spacing system
34
+ * const spacing = {
35
+ * section: 'py-16 sm:py-20',
36
+ * container: 'max-w-7xl mx-auto px-4',
37
+ * 'container-small': 'max-w-4xl mx-auto px-4',
38
+ * 'container-xsmall': 'max-w-2xl mx-auto px-4',
39
+ * gap: 'gap-6',
40
+ * 'gap-small': 'gap-4',
41
+ * 'gap-large': 'gap-8',
42
+ * padding: 'p-6',
43
+ * 'padding-small': 'p-4',
44
+ * 'padding-large': 'p-8',
45
+ * margin: 'm-6',
46
+ * 'margin-small': 'm-4',
47
+ * 'margin-large': 'm-8'
48
+ * }
49
+ * ```
50
+ *
51
+ * @see specs/app/theme/spacing/spacing.schema.json
52
+ */
53
+ export const SpacingConfigSchema = Schema.Record({
54
+ key: Schema.String.pipe(
55
+ Schema.pattern(/^[a-z]+(-[a-z]+)*$/, {
56
+ message: () => 'Spacing key must use kebab-case (e.g., container-small, not containerSmall)',
57
+ }),
58
+ Schema.annotations({
59
+ title: 'Spacing Token Name',
60
+ description: 'Kebab-case name for spacing token (e.g., container-small, not containerSmall)',
61
+ examples: [
62
+ 'section',
63
+ 'container',
64
+ 'container-small',
65
+ 'gap',
66
+ 'gap-small',
67
+ 'padding',
68
+ 'margin',
69
+ ],
70
+ })
71
+ ),
72
+ value: Schema.String.pipe(
73
+ Schema.annotations({
74
+ title: 'Spacing Value',
75
+ description:
76
+ 'Spacing value as Tailwind utility classes or CSS values (rem, px, em, %). Supports responsive variants (sm:, md:, lg:) and multiple classes.',
77
+ examples: [
78
+ 'py-16',
79
+ 'px-4',
80
+ 'py-16 sm:py-20',
81
+ 'max-w-7xl mx-auto px-4',
82
+ 'gap-6',
83
+ 'p-6',
84
+ 'm-6',
85
+ '4rem',
86
+ '16px',
87
+ '1.5em',
88
+ ],
89
+ })
90
+ ),
91
+ }).pipe(
92
+ Schema.annotations({
93
+ title: 'Spacing Configuration',
94
+ description: 'Spacing design tokens for consistent layout',
95
+ examples: [
96
+ {
97
+ section: 'py-16 sm:py-20',
98
+ container: 'max-w-7xl mx-auto px-4',
99
+ 'container-small': 'max-w-4xl mx-auto px-4',
100
+ 'container-xsmall': 'max-w-2xl mx-auto px-4',
101
+ gap: 'gap-6',
102
+ 'gap-small': 'gap-4',
103
+ 'gap-large': 'gap-8',
104
+ padding: 'p-6',
105
+ 'padding-small': 'p-4',
106
+ 'padding-large': 'p-8',
107
+ margin: 'm-6',
108
+ 'margin-small': 'm-4',
109
+ 'margin-large': 'm-8',
110
+ },
111
+ ],
112
+ })
113
+ )
114
+
115
+ export type SpacingConfig = Schema.Schema.Type<typeof SpacingConfigSchema>
@@ -0,0 +1,66 @@
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 { AnimationsConfigSchema } from './theme/animations'
10
+ import { BorderRadiusConfigSchema } from './theme/border-radius'
11
+ import { BreakpointsConfigSchema } from './theme/breakpoints'
12
+ import { ColorsConfigSchema } from './theme/colors'
13
+ import { FontsConfigSchema } from './theme/fonts'
14
+ import { ShadowsConfigSchema } from './theme/shadows'
15
+ import { SpacingConfigSchema } from './theme/spacing'
16
+
17
+ /**
18
+ * Theme configuration orchestrating all design token categories
19
+ *
20
+ * Provides a unified design system by composing:
21
+ * - colors: Visual identity and branding
22
+ * - fonts: Typography system
23
+ * - spacing: Layout rhythm and whitespace
24
+ * - animations: Motion design library
25
+ * - breakpoints: Responsive system thresholds
26
+ * - shadows: Elevation and depth
27
+ * - borderRadius: Corner styling
28
+ *
29
+ * All properties are optional, allowing minimal themes (colors-only)
30
+ * or comprehensive design systems (all 7 categories).
31
+ *
32
+ * @example
33
+ * ```typescript
34
+ * const minimalTheme = {
35
+ * colors: { primary: '#007bff' }
36
+ * }
37
+ *
38
+ * const completeTheme = {
39
+ * colors: { primary: '#007bff' },
40
+ * fonts: { body: { family: 'Inter' } },
41
+ * spacing: { section: '4rem' },
42
+ * animations: { fadeIn: true },
43
+ * breakpoints: { md: '768px' },
44
+ * shadows: { md: '0 4px 6px -1px rgb(0 0 0 / 0.1)' },
45
+ * borderRadius: { md: '0.375rem' }
46
+ * }
47
+ * ```
48
+ *
49
+ * @see specs/app/theme/theme.schema.json
50
+ */
51
+ export const ThemeSchema = Schema.Struct({
52
+ colors: Schema.optional(ColorsConfigSchema),
53
+ fonts: Schema.optional(FontsConfigSchema),
54
+ spacing: Schema.optional(SpacingConfigSchema),
55
+ animations: Schema.optional(AnimationsConfigSchema),
56
+ breakpoints: Schema.optional(BreakpointsConfigSchema),
57
+ shadows: Schema.optional(ShadowsConfigSchema),
58
+ borderRadius: Schema.optional(BorderRadiusConfigSchema),
59
+ }).pipe(
60
+ Schema.annotations({
61
+ title: 'Theme Configuration',
62
+ description: 'Design tokens for colors, typography, spacing, and animations',
63
+ })
64
+ )
65
+
66
+ export type Theme = Schema.Schema.Type<typeof ThemeSchema>
@@ -0,0 +1,87 @@
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
+ * VersionSchema defines validation rules for application versions.
12
+ *
13
+ * Application versions must follow Semantic Versioning (SemVer) 2.0.0 specification:
14
+ * - Format: MAJOR.MINOR.PATCH (e.g., 1.0.0)
15
+ * - Each component must be a non-negative integer without leading zeros
16
+ * - Optional pre-release identifiers after hyphen (e.g., 1.0.0-alpha, 1.0.0-beta.1)
17
+ * - Optional build metadata after plus sign (e.g., 1.0.0+build.123)
18
+ *
19
+ * Valid version format:
20
+ * - MAJOR version: Incremented for incompatible API changes
21
+ * - MINOR version: Incremented for backwards-compatible functionality additions
22
+ * - PATCH version: Incremented for backwards-compatible bug fixes
23
+ * - Pre-release: Hyphen followed by dot-separated identifiers (alphanumeric + hyphen)
24
+ * - Build metadata: Plus sign followed by dot-separated identifiers (alphanumeric + hyphen)
25
+ *
26
+ * @see https://semver.org/
27
+ *
28
+ * @example
29
+ * ```typescript
30
+ * // Valid versions
31
+ * const version1 = '1.0.0'
32
+ * const version2 = '0.0.1'
33
+ * const version3 = '1.2.3'
34
+ * const version4 = '1.0.0-alpha'
35
+ * const version5 = '1.0.0-beta.1'
36
+ * const version6 = '2.0.0-rc.1'
37
+ * const version7 = '1.0.0+build.123'
38
+ * const version8 = '1.0.0-alpha+001'
39
+ *
40
+ * // Validate version
41
+ * const validated = Schema.decodeUnknownSync(VersionSchema)(version1)
42
+ * ```
43
+ */
44
+ export const VersionSchema = Schema.String.pipe(
45
+ Schema.minLength(5, { message: () => 'Version must not be empty (minimum format: 0.0.0)' }),
46
+ Schema.pattern(
47
+ /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/,
48
+ {
49
+ message: () =>
50
+ 'Version must follow Semantic Versioning format (MAJOR.MINOR.PATCH, e.g., 1.0.0). No leading zeros allowed. Optional pre-release (-alpha) and build metadata (+build.123) are supported.',
51
+ }
52
+ ),
53
+ Schema.annotations({
54
+ title: 'Application Version',
55
+ description:
56
+ 'The version of the application following Semantic Versioning (SemVer) 2.0.0 specification',
57
+ examples: [
58
+ '1.0.0',
59
+ '0.0.1',
60
+ '1.2.3',
61
+ '1.0.0-alpha',
62
+ '1.0.0-beta.1',
63
+ '2.0.0-rc.1',
64
+ '1.0.0+build.123',
65
+ '1.0.0-alpha+001',
66
+ ],
67
+ })
68
+ )
69
+
70
+ /**
71
+ * TypeScript type inferred from VersionSchema.
72
+ *
73
+ * Use this type for type-safe access to validated version strings.
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * const version: Version = '1.0.0'
78
+ * ```
79
+ */
80
+ export type Version = Schema.Schema.Type<typeof VersionSchema>
81
+
82
+ /**
83
+ * Encoded type of VersionSchema (what goes in).
84
+ *
85
+ * In this case, it's the same as Version since we don't use transformations.
86
+ */
87
+ export type VersionEncoded = Schema.Schema.Encoded<typeof VersionSchema>
@@ -0,0 +1,91 @@
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
+ * Record Comment Domain Model
12
+ *
13
+ * Represents a comment on a table record with:
14
+ * - Content validation (non-empty, max 10,000 chars)
15
+ * - Support for @mentions stored as @[user_id]
16
+ * - Auto-injected user_id from session
17
+ * - Timestamps for audit trail
18
+ */
19
+
20
+ /**
21
+ * Comment ID - UUID string
22
+ */
23
+ export const CommentIdSchema = Schema.String.pipe(
24
+ Schema.pattern(/^[a-f0-9-]+$/, {
25
+ message: () => 'Comment ID must be a valid UUID',
26
+ }),
27
+ Schema.brand('CommentId')
28
+ )
29
+
30
+ export type CommentId = typeof CommentIdSchema.Type
31
+
32
+ /**
33
+ * Comment Content - non-empty, max 10,000 characters
34
+ * Supports @mentions as @[user_id] format
35
+ */
36
+ export const CommentContentSchema = Schema.String.pipe(
37
+ Schema.minLength(1, { message: () => 'Comment content cannot be empty' }),
38
+ Schema.maxLength(10_000, {
39
+ message: () => 'Comment content cannot exceed 10,000 characters',
40
+ })
41
+ )
42
+
43
+ export type CommentContent = typeof CommentContentSchema.Type
44
+
45
+ /**
46
+ * Record Comment Schema
47
+ */
48
+ export const RecordCommentSchema = Schema.Struct({
49
+ id: CommentIdSchema,
50
+ recordId: Schema.String,
51
+ tableId: Schema.String,
52
+ userId: Schema.String,
53
+ content: CommentContentSchema,
54
+ createdAt: Schema.Date,
55
+ updatedAt: Schema.optionalWith(Schema.Date, { nullable: true }),
56
+ deletedAt: Schema.optionalWith(Schema.Date, { nullable: true }),
57
+ })
58
+
59
+ export type RecordComment = typeof RecordCommentSchema.Type
60
+
61
+ /**
62
+ * Create Comment Input - content only (other fields auto-injected)
63
+ */
64
+ export const CreateCommentInputSchema = Schema.Struct({
65
+ content: CommentContentSchema,
66
+ })
67
+
68
+ export type CreateCommentInput = typeof CreateCommentInputSchema.Type
69
+
70
+ /**
71
+ * Comment with User Metadata (for API responses)
72
+ */
73
+ export const CommentWithUserSchema = Schema.Struct({
74
+ id: CommentIdSchema,
75
+ recordId: Schema.String,
76
+ tableId: Schema.String,
77
+ userId: Schema.String,
78
+ content: CommentContentSchema,
79
+ createdAt: Schema.Date,
80
+ user: Schema.optionalWith(
81
+ Schema.Struct({
82
+ id: Schema.String,
83
+ name: Schema.String,
84
+ email: Schema.String,
85
+ image: Schema.optionalWith(Schema.String, { nullable: true }),
86
+ }),
87
+ { nullable: true }
88
+ ),
89
+ })
90
+
91
+ export type CommentWithUser = typeof CommentWithUserSchema.Type
@@ -0,0 +1,49 @@
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
+ /**
9
+ * Content Parsing - Pure Functions
10
+ *
11
+ * Domain layer utilities for parsing schema content.
12
+ * These are pure functions with no side effects.
13
+ */
14
+
15
+ import { load as parseYaml } from 'js-yaml'
16
+ import type { SchemaFormat } from './format-detection'
17
+ import type { AppEncoded } from '@/domain/models/app'
18
+
19
+ /**
20
+ * Parse JSON content to AppEncoded
21
+ */
22
+ export const parseJsonContent = (content: string): AppEncoded => JSON.parse(content) as AppEncoded
23
+
24
+ /**
25
+ * Parse YAML content to AppEncoded
26
+ */
27
+ export const parseYamlContent = (content: string): AppEncoded => parseYaml(content) as AppEncoded
28
+
29
+ /**
30
+ * Parse schema content based on detected format
31
+ * Falls back to trying JSON first, then YAML if format is undefined
32
+ */
33
+ export const parseSchemaContent = (
34
+ content: string,
35
+ format: SchemaFormat | undefined
36
+ ): AppEncoded => {
37
+ if (format === 'json') {
38
+ return parseJsonContent(content)
39
+ }
40
+ if (format === 'yaml') {
41
+ return parseYamlContent(content)
42
+ }
43
+ // Last fallback: try JSON first, then YAML
44
+ try {
45
+ return parseJsonContent(content)
46
+ } catch {
47
+ return parseYamlContent(content)
48
+ }
49
+ }
@@ -0,0 +1,69 @@
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
+ /**
9
+ * Format Detection - Pure Functions
10
+ *
11
+ * Domain layer utilities for detecting schema file formats.
12
+ * These are pure functions with no side effects.
13
+ */
14
+
15
+ /** Supported schema formats */
16
+ export type SchemaFormat = 'json' | 'yaml'
17
+
18
+ /** Format detection result */
19
+ export type FormatDetectionResult = SchemaFormat | 'unsupported'
20
+
21
+ /**
22
+ * Detect file format from file extension
23
+ */
24
+ export const detectFormat = (filePath: string): FormatDetectionResult => {
25
+ const lowerPath = filePath.toLowerCase()
26
+ if (lowerPath.endsWith('.json')) return 'json'
27
+ if (lowerPath.endsWith('.yaml') || lowerPath.endsWith('.yml')) return 'yaml'
28
+ return 'unsupported'
29
+ }
30
+
31
+ /**
32
+ * Extract file extension from path
33
+ */
34
+ export const getFileExtension = (filePath: string): string => {
35
+ const match = filePath.match(/\.([^.]+)$/)
36
+ return match?.[1] ?? ''
37
+ }
38
+
39
+ /**
40
+ * Detect format from Content-Type header
41
+ */
42
+ export const detectFormatFromContentType = (contentType: string): SchemaFormat | undefined => {
43
+ if (contentType.includes('application/json')) return 'json'
44
+ if (contentType.includes('application/x-yaml') || contentType.includes('text/yaml')) return 'yaml'
45
+ return undefined
46
+ }
47
+
48
+ /**
49
+ * Detect format from URL file extension
50
+ */
51
+ export const detectFormatFromUrl = (url: string): SchemaFormat | undefined => {
52
+ const urlLower = url.toLowerCase()
53
+ if (urlLower.endsWith('.json')) return 'json'
54
+ if (urlLower.endsWith('.yaml') || urlLower.endsWith('.yml')) return 'yaml'
55
+ return undefined
56
+ }
57
+
58
+ /**
59
+ * Check if a string value looks like inline JSON
60
+ */
61
+ export const isInlineJson = (value: string): boolean => value.trim().startsWith('{')
62
+
63
+ /**
64
+ * Check if a string value is a URL
65
+ */
66
+ export const isUrl = (value: string): boolean => {
67
+ const trimmed = value.trim()
68
+ return trimmed.startsWith('http://') || trimmed.startsWith('https://')
69
+ }
@@ -0,0 +1,9 @@
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 './format-detection'
9
+ export * from './content-parsing'
@@ -0,0 +1,184 @@
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
+ /**
9
+ * Route parameters extracted from a dynamic path
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const params = { slug: 'hello-world', id: '123' }
14
+ * ```
15
+ */
16
+ export type RouteParams = Readonly<Record<string, string>>
17
+
18
+ /**
19
+ * Result of matching a URL against a route pattern
20
+ */
21
+ export type RouteMatch = {
22
+ readonly matched: boolean
23
+ readonly params: RouteParams
24
+ }
25
+
26
+ /**
27
+ * Converts a route pattern with dynamic segments into a regular expression
28
+ *
29
+ * Dynamic segments are defined with a colon prefix (e.g., :id, :slug)
30
+ *
31
+ * @param pattern - Route pattern (e.g., '/blog/:slug', '/products/:id')
32
+ * @returns Regular expression to match URLs and capture parameters
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const regex = patternToRegex('/blog/:slug')
37
+ * // Returns: /^\/blog\/([^/]+)$/
38
+ *
39
+ * const regex2 = patternToRegex('/users/:userId/posts/:postId')
40
+ * // Returns: /^\/users\/([^/]+)\/posts\/([^/]+)$/
41
+ * ```
42
+ */
43
+ function patternToRegex(pattern: string): Readonly<RegExp> {
44
+ // Escape forward slashes and convert :param to capture groups
45
+ const regexPattern = pattern
46
+ .split('/')
47
+ .map((segment) => {
48
+ if (segment.startsWith(':')) {
49
+ // Dynamic segment - capture any characters except forward slash
50
+ return '([^/]+)'
51
+ }
52
+ // Static segment - escape special regex characters
53
+ return segment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
54
+ })
55
+ .join('/')
56
+
57
+ return new RegExp(`^${regexPattern}$`)
58
+ }
59
+
60
+ /**
61
+ * Extracts parameter names from a route pattern
62
+ *
63
+ * @param pattern - Route pattern (e.g., '/blog/:slug')
64
+ * @returns Array of parameter names (e.g., ['slug'])
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * const params = extractParamNames('/blog/:slug')
69
+ * // Returns: ['slug']
70
+ *
71
+ * const params2 = extractParamNames('/users/:userId/posts/:postId')
72
+ * // Returns: ['userId', 'postId']
73
+ * ```
74
+ */
75
+ function extractParamNames(pattern: string): readonly string[] {
76
+ return pattern
77
+ .split('/')
78
+ .filter((segment) => segment.startsWith(':'))
79
+ .map((segment) => segment.slice(1)) // Remove colon prefix
80
+ }
81
+
82
+ /**
83
+ * Matches a URL path against a route pattern and extracts parameters
84
+ *
85
+ * Pure function with no side effects
86
+ *
87
+ * @param pattern - Route pattern with optional dynamic segments (e.g., '/blog/:slug')
88
+ * @param urlPath - Actual URL path to match (e.g., '/blog/hello-world')
89
+ * @returns Match result with extracted parameters
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * // Static route
94
+ * matchRoute('/about', '/about')
95
+ * // Returns: { matched: true, params: {} }
96
+ *
97
+ * // Dynamic route with single parameter
98
+ * matchRoute('/blog/:slug', '/blog/hello-world')
99
+ * // Returns: { matched: true, params: { slug: 'hello-world' } }
100
+ *
101
+ * // Dynamic route with multiple parameters
102
+ * matchRoute('/users/:userId/posts/:postId', '/users/123/posts/456')
103
+ * // Returns: { matched: true, params: { userId: '123', postId: '456' } }
104
+ *
105
+ * // No match
106
+ * matchRoute('/blog/:slug', '/products/123')
107
+ * // Returns: { matched: false, params: {} }
108
+ * ```
109
+ */
110
+ export function matchRoute(pattern: string, urlPath: string): RouteMatch {
111
+ // Static route - exact match
112
+ if (!pattern.includes(':')) {
113
+ return {
114
+ matched: pattern === urlPath,
115
+ params: {},
116
+ }
117
+ }
118
+
119
+ // Dynamic route - use regex matching
120
+ const regex = patternToRegex(pattern)
121
+ const match = urlPath.match(regex)
122
+
123
+ if (!match) {
124
+ return {
125
+ matched: false,
126
+ params: {},
127
+ }
128
+ }
129
+
130
+ // Extract parameter names and values
131
+ const paramNames = extractParamNames(pattern)
132
+ const paramValues = match.slice(1) // Remove full match, keep capture groups
133
+
134
+ // Use reduce to build params object functionally (no mutation)
135
+ const params = paramNames.reduce<Record<string, string>>((acc, name, i) => {
136
+ const value = paramValues[i]
137
+ if (name && value) {
138
+ return { ...acc, [name]: value }
139
+ }
140
+ return acc
141
+ }, {})
142
+
143
+ return {
144
+ matched: true,
145
+ params,
146
+ }
147
+ }
148
+
149
+ /**
150
+ * Finds the first matching route from a list of patterns
151
+ *
152
+ * Pure function with no side effects
153
+ *
154
+ * @param patterns - Array of route patterns to try
155
+ * @param urlPath - URL path to match
156
+ * @returns Index of matched pattern and extracted parameters, or undefined if no match
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * const patterns = ['/about', '/blog/:slug', '/products/:id']
161
+ * const result = findMatchingRoute(patterns, '/blog/hello-world')
162
+ * // Returns: { index: 1, params: { slug: 'hello-world' } }
163
+ *
164
+ * const result2 = findMatchingRoute(patterns, '/not-found')
165
+ * // Returns: undefined
166
+ * ```
167
+ */
168
+ export function findMatchingRoute(
169
+ patterns: readonly string[],
170
+ urlPath: string
171
+ ): { readonly index: number; readonly params: RouteParams } | undefined {
172
+ // Use findIndex + map to avoid imperative loop
173
+ const matchResult = patterns
174
+ .map((pattern, index) => ({ pattern, index }))
175
+ .filter(({ pattern }) => pattern !== undefined && pattern !== '')
176
+ .find(({ pattern }) => matchRoute(pattern, urlPath).matched)
177
+
178
+ if (!matchResult) {
179
+ return undefined
180
+ }
181
+
182
+ const match = matchRoute(matchResult.pattern, urlPath)
183
+ return { index: matchResult.index, params: match.params }
184
+ }