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,200 @@
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
+ * Short language code (ISO 639-1, used for URLs/routing)
12
+ *
13
+ * 2 lowercase letters only (no country code)
14
+ * Used for URL paths like /en/, /fr/, /es/
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const code1 = 'en' // English
19
+ * const code2 = 'fr' // French
20
+ * const code3 = 'ar' // Arabic
21
+ * ```
22
+ *
23
+ * @see specs/app/languages/language-config.schema.json#/properties/code
24
+ */
25
+ export const LanguageCodeSchema = Schema.String.pipe(
26
+ Schema.pattern(/^[a-z]{2}$/, {
27
+ message: () => 'Language code must be ISO 639-1 format (2 lowercase letters, e.g., "en", "fr")',
28
+ }),
29
+ Schema.annotations({
30
+ title: 'Language Code',
31
+ description: 'Short language code used for URLs and routing (ISO 639-1, 2 letters)',
32
+ examples: ['en', 'fr', 'es', 'de', 'ar', 'he'],
33
+ })
34
+ )
35
+
36
+ /**
37
+ * Full locale code (ISO 639-1 + ISO 3166-1, used for HTML lang attribute)
38
+ *
39
+ * Format: language-COUNTRY (e.g., 'en-US', 'fr-FR')
40
+ * Used for HTML lang attribute and locale-specific formatting
41
+ *
42
+ * @example
43
+ * ```typescript
44
+ * const locale1 = 'en-US' // English (United States)
45
+ * const locale2 = 'fr-FR' // French (France)
46
+ * const locale3 = 'ar-SA' // Arabic (Saudi Arabia)
47
+ * ```
48
+ *
49
+ * @see specs/app/languages/language-config.schema.json#/properties/locale
50
+ */
51
+ export const LanguageLocaleSchema = Schema.String.pipe(
52
+ Schema.pattern(/^[a-z]{2}-[A-Z]{2}$/, {
53
+ message: () => 'Locale must be ISO 639-1 + ISO 3166-1 format (e.g., "en-US", "fr-FR")',
54
+ }),
55
+ Schema.annotations({
56
+ title: 'Language Locale',
57
+ description: 'Full locale code used for HTML lang attribute and locale-specific formatting',
58
+ examples: ['en-US', 'fr-FR', 'es-ES', 'de-DE', 'ar-SA', 'he-IL'],
59
+ })
60
+ )
61
+
62
+ /**
63
+ * Human-readable language name
64
+ *
65
+ * Should use the language's native name for better UX
66
+ * (e.g., "Français" instead of "French", "العربية" instead of "Arabic")
67
+ *
68
+ * @example
69
+ * ```typescript
70
+ * const label1 = 'English'
71
+ * const label2 = 'Français' // French in French
72
+ * const label3 = 'العربية' // Arabic in Arabic
73
+ * ```
74
+ *
75
+ * @see specs/app/languages/language-config.schema.json#/properties/label
76
+ */
77
+ export const LanguageLabelSchema = Schema.String.pipe(
78
+ Schema.annotations({
79
+ title: 'Language Label',
80
+ description: 'Human-readable language name',
81
+ examples: ['English', 'Français', 'Español', 'العربية'],
82
+ })
83
+ )
84
+
85
+ /**
86
+ * Text direction (left-to-right or right-to-left)
87
+ *
88
+ * Controls the base text flow direction:
89
+ * - 'ltr': Left-to-right (default for most languages)
90
+ * - 'rtl': Right-to-left (for Arabic, Hebrew, etc.)
91
+ *
92
+ * @example
93
+ * ```typescript
94
+ * const ltr = 'ltr' // English, French, Spanish
95
+ * const rtl = 'rtl' // Arabic, Hebrew, Persian
96
+ * ```
97
+ *
98
+ * @see specs/app/languages/language-config.schema.json#/properties/direction
99
+ */
100
+ export const LanguageDirectionSchema = Schema.Literal('ltr', 'rtl').pipe(
101
+ Schema.annotations({
102
+ title: 'Text Direction',
103
+ description: 'Text direction (left-to-right or right-to-left)',
104
+ })
105
+ )
106
+
107
+ /**
108
+ * Flag emoji or icon path
109
+ *
110
+ * Can be either:
111
+ * - Unicode emoji: '🇺🇸', '🇫🇷', '🇪🇸' (instant, no loading)
112
+ * - File path: '/flags/us.svg' (custom design, consistent styling)
113
+ *
114
+ * @example
115
+ * ```typescript
116
+ * const emoji = '🇺🇸' // Unicode flag emoji
117
+ * const path = '/flags/us.svg' // Custom SVG flag
118
+ * ```
119
+ *
120
+ * @see specs/app/languages/language-config.schema.json#/properties/flag
121
+ */
122
+ export const LanguageFlagSchema = Schema.String.pipe(
123
+ Schema.annotations({
124
+ title: 'Language Flag',
125
+ description: 'Flag emoji or icon path',
126
+ examples: ['🇺🇸', '🇫🇷', '🇪🇸', '/flags/us.svg'],
127
+ })
128
+ )
129
+
130
+ /**
131
+ * Configuration for a single supported language
132
+ *
133
+ * Defines a language option in the language switcher with:
134
+ * - Short code for URLs (en, fr) - used for routing
135
+ * - Full locale for HTML (en-US, fr-FR) - used for lang attribute
136
+ * - Native language name for better UX
137
+ * - Text direction for RTL language support
138
+ * - Optional flag emoji or icon
139
+ *
140
+ * Key behaviors:
141
+ * - Code, locale, and label are required properties
142
+ * - Code (short) is used for URL paths: /en/, /fr/
143
+ * - Locale (full) is used for HTML lang attribute: lang="en-US"
144
+ * - Direction defaults to 'ltr' when omitted
145
+ * - Flag is optional for minimal configuration
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * // English (US) with all properties
150
+ * const enUS = {
151
+ * code: 'en',
152
+ * locale: 'en-US',
153
+ * label: 'English',
154
+ * direction: 'ltr',
155
+ * flag: '🇺🇸'
156
+ * }
157
+ *
158
+ * // Arabic with RTL support
159
+ * const arSA = {
160
+ * code: 'ar',
161
+ * locale: 'ar-SA',
162
+ * label: 'العربية',
163
+ * direction: 'rtl',
164
+ * flag: '🇸🇦'
165
+ * }
166
+ *
167
+ * // Minimal configuration
168
+ * const deDE = {
169
+ * code: 'de',
170
+ * locale: 'de-DE',
171
+ * label: 'Deutsch'
172
+ * // direction defaults to 'ltr'
173
+ * // flag omitted
174
+ * }
175
+ * ```
176
+ *
177
+ * @see specs/app/languages/language-config.schema.json
178
+ */
179
+ export const LanguageConfigSchema = Schema.Struct({
180
+ code: LanguageCodeSchema,
181
+ locale: Schema.optional(LanguageLocaleSchema).annotations({
182
+ description:
183
+ 'Full locale code (optional - defaults to short code if not specified). Used for HTML lang attribute and hreflang links.',
184
+ }),
185
+ label: LanguageLabelSchema,
186
+ direction: Schema.optional(LanguageDirectionSchema),
187
+ flag: Schema.optional(LanguageFlagSchema),
188
+ }).pipe(
189
+ Schema.annotations({
190
+ title: 'Language Configuration',
191
+ description: 'Configuration for a single supported language',
192
+ })
193
+ )
194
+
195
+ export type LanguageCode = Schema.Schema.Type<typeof LanguageCodeSchema>
196
+ export type LanguageLocale = Schema.Schema.Type<typeof LanguageLocaleSchema>
197
+ export type LanguageLabel = Schema.Schema.Type<typeof LanguageLabelSchema>
198
+ export type LanguageDirection = Schema.Schema.Type<typeof LanguageDirectionSchema>
199
+ export type LanguageFlag = Schema.Schema.Type<typeof LanguageFlagSchema>
200
+ export type LanguageConfig = Schema.Schema.Type<typeof LanguageConfigSchema>
@@ -0,0 +1,205 @@
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 { LanguageConfigSchema } from './language/language-config'
10
+
11
+ /**
12
+ * Short language code for URLs and routing
13
+ *
14
+ * Format: ll (two lowercase letters)
15
+ * - ll: ISO 639-1 language code
16
+ *
17
+ * Used for:
18
+ * - URL paths (e.g., /en/, /fr/, /es/)
19
+ * - Translation dictionary keys
20
+ * - Default language setting
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * const codes = ['en', 'fr', 'es', 'de', 'ar', 'he']
25
+ * ```
26
+ *
27
+ * @see specs/app/languages/languages.schema.json
28
+ */
29
+ export const LanguageCodeSchema = Schema.String.pipe(
30
+ Schema.pattern(/^[a-z]{2}$/, {
31
+ message: () => 'Language code must be 2 lowercase letters (ISO 639-1 format, e.g., en, fr, es)',
32
+ }),
33
+ Schema.annotations({
34
+ title: 'Language Code',
35
+ description: 'Short language code (2 letters) for URLs and routing',
36
+ examples: ['en', 'fr', 'es', 'de', 'ar', 'he'],
37
+ })
38
+ )
39
+
40
+ /**
41
+ * Translation key for centralized translations dictionary
42
+ *
43
+ * Format: Alphanumeric with dots, hyphens, and underscores
44
+ * Convention: Use namespaces for organization (e.g., common.save, nav.home, homepage.hero.title)
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const keys = ['common.save', 'nav.home', 'homepage.hero.title', 'errors.404']
49
+ * ```
50
+ */
51
+ export const TranslationKeySchema = Schema.String.pipe(
52
+ Schema.pattern(/^[a-zA-Z0-9._-]+$/, {
53
+ message: () =>
54
+ 'Translation key must contain only alphanumeric characters, dots, hyphens, and underscores',
55
+ }),
56
+ Schema.annotations({
57
+ title: 'Translation Key',
58
+ description: 'Key for centralized translations dictionary',
59
+ examples: ['common.save', 'nav.home', 'homepage.hero.title', 'errors.404'],
60
+ })
61
+ )
62
+
63
+ /**
64
+ * Translation dictionary for a single language
65
+ *
66
+ * Maps translation keys to localized strings.
67
+ * Use semantic keys that describe meaning, not location.
68
+ * Organize by feature/page for better maintainability.
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const translations = {
73
+ * 'common.save': 'Save',
74
+ * 'common.cancel': 'Cancel',
75
+ * 'nav.home': 'Home',
76
+ * 'homepage.hero.title': 'Welcome to Sovrium'
77
+ * }
78
+ * ```
79
+ */
80
+ export const TranslationDictionarySchema = Schema.Record({
81
+ key: TranslationKeySchema,
82
+ value: Schema.String,
83
+ }).pipe(
84
+ Schema.annotations({
85
+ title: 'Translation Dictionary',
86
+ description: 'Maps translation keys to localized strings for a single language',
87
+ })
88
+ )
89
+
90
+ /**
91
+ * Centralized translations for all supported languages
92
+ *
93
+ * Outer Record key: Short language code (2 letters, e.g., en, fr, es)
94
+ * Outer Record value: Translation dictionary for that language
95
+ *
96
+ * This is the PRIMARY i18n pattern. Use $t:key syntax in ANY string property
97
+ * to reference translations: children arrays, component props, meta properties, etc.
98
+ *
99
+ * @example
100
+ * ```typescript
101
+ * const translations = {
102
+ * 'en': {
103
+ * 'common.save': 'Save',
104
+ * 'nav.home': 'Home'
105
+ * },
106
+ * 'fr': {
107
+ * 'common.save': 'Enregistrer',
108
+ * 'nav.home': 'Accueil'
109
+ * }
110
+ * }
111
+ * ```
112
+ */
113
+ export const TranslationsSchema = Schema.Record({
114
+ key: LanguageCodeSchema,
115
+ value: TranslationDictionarySchema,
116
+ }).pipe(
117
+ Schema.annotations({
118
+ title: 'Centralized Translations',
119
+ description:
120
+ 'Translation dictionaries for all supported languages (keyed by short codes: en, fr, es). Use $t:key syntax to reference translations.',
121
+ })
122
+ )
123
+
124
+ /**
125
+ * Multi-language support configuration for the entire application
126
+ *
127
+ * Provides:
128
+ * - default: Default language short code (required, e.g., 'en', 'fr')
129
+ * - supported: Array of supported languages with metadata (required)
130
+ * - fallback: Language to use when translation is missing (optional, defaults to default language)
131
+ * - detectBrowser: Auto-detect language from browser (optional, defaults to true)
132
+ * - persistSelection: Remember user's language choice in localStorage (optional, defaults to true)
133
+ * - translations: Centralized translation dictionaries (optional, keyed by short codes)
134
+ *
135
+ * Language codes follow a dual pattern:
136
+ * - code: Short code (en, fr) for URLs and translation keys
137
+ * - locale: Full locale (en-US, fr-FR) for HTML lang attribute
138
+ *
139
+ * @example
140
+ * ```typescript
141
+ * const languages = {
142
+ * default: 'en',
143
+ * supported: [
144
+ * { code: 'en', locale: 'en-US', label: 'English', direction: 'ltr' },
145
+ * { code: 'fr', locale: 'fr-FR', label: 'Français', direction: 'ltr' }
146
+ * ],
147
+ * detectBrowser: true,
148
+ * persistSelection: true,
149
+ * translations: {
150
+ * 'en': { 'common.save': 'Save' },
151
+ * 'fr': { 'common.save': 'Enregistrer' }
152
+ * }
153
+ * }
154
+ * ```
155
+ *
156
+ * @see specs/app/languages/languages.schema.json
157
+ */
158
+ export const LanguagesSchema = Schema.Struct({
159
+ default: LanguageCodeSchema,
160
+ supported: Schema.Array(LanguageConfigSchema).pipe(
161
+ Schema.minItems(1),
162
+ Schema.annotations({
163
+ description: 'List of supported languages',
164
+ })
165
+ ),
166
+ fallback: Schema.optional(LanguageCodeSchema),
167
+ detectBrowser: Schema.optional(Schema.Boolean),
168
+ persistSelection: Schema.optional(Schema.Boolean),
169
+ translations: Schema.optional(TranslationsSchema),
170
+ }).pipe(
171
+ Schema.filter((input) => {
172
+ const supportedCodes = new Set(input.supported.map((lang) => lang.code))
173
+
174
+ // Default language must be in supported array
175
+ if (!supportedCodes.has(input.default)) {
176
+ return 'default language must be in supported array'
177
+ }
178
+
179
+ // Fallback language must be in supported array (if specified)
180
+ if (input.fallback && !supportedCodes.has(input.fallback)) {
181
+ return 'fallback language must be in supported array'
182
+ }
183
+
184
+ // If translations are provided, validate they only contain supported languages
185
+ if (input.translations) {
186
+ const translationCodes = Object.keys(input.translations)
187
+ const unsupportedCodes = translationCodes.filter((code) => !supportedCodes.has(code))
188
+ if (unsupportedCodes.length > 0) {
189
+ return `translations contain unsupported language codes: ${unsupportedCodes.join(', ')}. Only these are supported: ${[...supportedCodes].join(', ')}`
190
+ }
191
+ }
192
+
193
+ return undefined
194
+ }),
195
+ Schema.annotations({
196
+ title: 'Languages Configuration',
197
+ description: 'Multi-language support configuration for the entire application',
198
+ })
199
+ )
200
+
201
+ export type LanguageCode = Schema.Schema.Type<typeof LanguageCodeSchema>
202
+ export type TranslationKey = Schema.Schema.Type<typeof TranslationKeySchema>
203
+ export type TranslationDictionary = Schema.Schema.Type<typeof TranslationDictionarySchema>
204
+ export type Translations = Schema.Schema.Type<typeof TranslationsSchema>
205
+ export type Languages = Schema.Schema.Type<typeof LanguagesSchema>
@@ -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
+
10
+ /**
11
+ * NameSchema defines validation rules for application names.
12
+ *
13
+ * Application names must follow npm package naming conventions:
14
+ * - Lowercase only
15
+ * - Maximum 214 characters (including scope for scoped packages)
16
+ * - Cannot start with a dot or underscore
17
+ * - Cannot contain leading/trailing spaces
18
+ * - Cannot contain non-URL-safe characters
19
+ * - Scoped packages: @scope/package-name format allowed
20
+ * - Can include hyphens and underscores (but not at the start)
21
+ *
22
+ * @example
23
+ * ```typescript
24
+ * // Valid names
25
+ * const name1 = 'my-app'
26
+ * const name2 = 'todo-app'
27
+ * const name3 = '@myorg/my-app'
28
+ * const name4 = 'blog-system'
29
+ * const name5 = 'dashboard-admin'
30
+ *
31
+ * // Validate name
32
+ * const validated = Schema.decodeUnknownSync(NameSchema)(name1)
33
+ * ```
34
+ */
35
+ export const NameSchema = Schema.String.pipe(
36
+ Schema.minLength(1, { message: () => 'Name must not be empty' }),
37
+ Schema.maxLength(214, { message: () => 'Name must not exceed 214 characters' }),
38
+ Schema.pattern(/^(?:@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/, {
39
+ message: () =>
40
+ 'Name must be lowercase and follow npm package naming conventions (no leading/trailing spaces, no dots/underscores at start, URL-safe characters only)',
41
+ }),
42
+ Schema.annotations({
43
+ title: 'Application Name',
44
+ description: 'The name of the application (follows npm package naming conventions)',
45
+ examples: ['my-app', 'todo-app', '@myorg/my-app', 'blog-system', 'dashboard-admin'],
46
+ })
47
+ )
48
+
49
+ /**
50
+ * TypeScript type inferred from NameSchema.
51
+ *
52
+ * Use this type for type-safe access to validated application names.
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const name: Name = 'my-app'
57
+ * ```
58
+ */
59
+ export type Name = Schema.Schema.Type<typeof NameSchema>
60
+
61
+ /**
62
+ * Encoded type of NameSchema (what goes in).
63
+ *
64
+ * In this case, it's the same as Name since we don't use transformations.
65
+ */
66
+ export type NameEncoded = Schema.Schema.Encoded<typeof NameSchema>
@@ -0,0 +1,116 @@
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
+ * Click animation types
12
+ *
13
+ * Animations triggered when component is clicked:
14
+ * - pulse: Subtle scale pulse
15
+ * - bounce: Playful bounce effect
16
+ * - shake: Shake horizontally
17
+ * - flash: Quick opacity flash
18
+ * - ripple: Material Design ripple from click point
19
+ * - none: No animation
20
+ */
21
+ export const ClickAnimationSchema = Schema.Literal(
22
+ 'pulse',
23
+ 'bounce',
24
+ 'shake',
25
+ 'flash',
26
+ 'ripple',
27
+ 'none'
28
+ ).annotations({
29
+ description: 'Animation to trigger on click',
30
+ })
31
+
32
+ /**
33
+ * Element ID selector pattern (#elementId)
34
+ *
35
+ * Must start with # followed by a letter, then alphanumeric characters and hyphens.
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const selectors = ['#hero-section', '#pricing', '#contactForm']
40
+ * ```
41
+ */
42
+ export const ElementIdSelectorSchema = Schema.String.pipe(
43
+ Schema.pattern(/^#[a-zA-Z][a-zA-Z0-9-]*$/, {
44
+ message: () =>
45
+ 'Element ID selector must start with # followed by a letter, then alphanumeric characters and hyphens',
46
+ })
47
+ )
48
+
49
+ /**
50
+ * Actions triggered when component is clicked
51
+ *
52
+ * Supports multiple action types (all optional):
53
+ * - animation: Visual feedback animation
54
+ * - navigate: Client-side navigation to internal path or anchor
55
+ * - openUrl: Open external URL
56
+ * - openInNewTab: Open link in new tab (used with openUrl)
57
+ * - scrollTo: Smooth scroll to element by ID
58
+ * - toggleElement: Show/hide element by ID
59
+ * - submitForm: Submit form by ID
60
+ *
61
+ * Multiple actions can be combined (e.g., play animation then navigate).
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * const clickInteraction = {
66
+ * animation: 'pulse',
67
+ * navigate: '/contact'
68
+ * }
69
+ *
70
+ * const externalLink = {
71
+ * animation: 'ripple',
72
+ * openUrl: 'https://example.com',
73
+ * openInNewTab: true
74
+ * }
75
+ *
76
+ * const scrollToSection = {
77
+ * animation: 'ripple',
78
+ * scrollTo: '#pricing-section'
79
+ * }
80
+ * ```
81
+ *
82
+ * @see specs/app/pages/common/interactions/click-interaction.schema.json
83
+ */
84
+ export const ClickInteractionSchema = Schema.Struct({
85
+ animation: Schema.optional(ClickAnimationSchema),
86
+ navigate: Schema.optional(
87
+ Schema.String.annotations({
88
+ description: 'Path to navigate to',
89
+ examples: ['/contact', '/pricing', '#section-id'],
90
+ })
91
+ ),
92
+ openUrl: Schema.optional(
93
+ Schema.String.annotations({
94
+ description: 'External URL to open',
95
+ })
96
+ ),
97
+ openInNewTab: Schema.optional(Schema.Boolean),
98
+ scrollTo: Schema.optional(ElementIdSelectorSchema),
99
+ toggleElement: Schema.optional(
100
+ ElementIdSelectorSchema.annotations({
101
+ description: 'Element ID to show/hide',
102
+ })
103
+ ),
104
+ submitForm: Schema.optional(
105
+ ElementIdSelectorSchema.annotations({
106
+ description: 'Form ID to submit',
107
+ })
108
+ ),
109
+ }).annotations({
110
+ title: 'Click Interaction',
111
+ description: 'Actions triggered when component is clicked',
112
+ })
113
+
114
+ export type ClickAnimation = Schema.Schema.Type<typeof ClickAnimationSchema>
115
+ export type ElementIdSelector = Schema.Schema.Type<typeof ElementIdSelectorSchema>
116
+ export type ClickInteraction = Schema.Schema.Type<typeof ClickInteractionSchema>
@@ -0,0 +1,84 @@
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 { DurationSchema } from './hover-interaction'
10
+
11
+ /**
12
+ * Page load animation types
13
+ *
14
+ * Animations played when page loads:
15
+ * - fadeIn: Fade in smoothly
16
+ * - fadeInUp: Fade in while moving up from below
17
+ * - fadeInDown: Fade in while moving down from above
18
+ * - zoomIn: Zoom in from small to normal size
19
+ * - slideInUp: Slide up into position
20
+ * - slideInDown: Slide down into position
21
+ */
22
+ export const EntranceAnimationTypeSchema = Schema.Literal(
23
+ 'fadeIn',
24
+ 'fadeInUp',
25
+ 'fadeInDown',
26
+ 'zoomIn',
27
+ 'slideInUp',
28
+ 'slideInDown'
29
+ ).annotations({
30
+ description: 'Animation type for page load',
31
+ })
32
+
33
+ /**
34
+ * Animation played when page loads
35
+ *
36
+ * Provides initial page load animations for components.
37
+ * Useful for creating engaging entry experiences.
38
+ *
39
+ * Configuration options:
40
+ * - animation: Animation type (required)
41
+ * - delay: Delay before animation starts (default: '0ms')
42
+ * - duration: Animation duration (default: '600ms')
43
+ * - stagger: Delay between sibling animations (e.g., '50ms', '100ms')
44
+ *
45
+ * Stagger effect: When multiple sibling components have entrance animations,
46
+ * stagger adds incremental delay to each sibling, creating a cascading effect.
47
+ *
48
+ * @example
49
+ * ```typescript
50
+ * const entrance = {
51
+ * animation: 'fadeInUp',
52
+ * delay: '200ms',
53
+ * duration: '800ms'
54
+ * }
55
+ *
56
+ * const staggered = {
57
+ * animation: 'fadeIn',
58
+ * stagger: '100ms' // Each sibling animates 100ms after the previous
59
+ * }
60
+ * ```
61
+ *
62
+ * @see specs/app/pages/common/interactions/entrance-animation.schema.json
63
+ */
64
+ export const EntranceAnimationSchema = Schema.Struct({
65
+ animation: EntranceAnimationTypeSchema,
66
+ delay: Schema.optional(
67
+ DurationSchema.annotations({
68
+ description: 'Delay before animation starts',
69
+ })
70
+ ),
71
+ duration: Schema.optional(DurationSchema),
72
+ stagger: Schema.optional(
73
+ DurationSchema.annotations({
74
+ description: 'Delay between sibling animations',
75
+ examples: ['50ms', '100ms'],
76
+ })
77
+ ),
78
+ }).annotations({
79
+ title: 'Entrance Animation',
80
+ description: 'Animation played when page loads',
81
+ })
82
+
83
+ export type EntranceAnimationType = Schema.Schema.Type<typeof EntranceAnimationTypeSchema>
84
+ export type EntranceAnimation = Schema.Schema.Type<typeof EntranceAnimationSchema>