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,210 @@
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 tailwindcss from '@tailwindcss/postcss'
9
+ import { Console, Effect } from 'effect'
10
+ import postcss from 'postcss'
11
+ import {
12
+ getOrComputeCachedCSS,
13
+ getThemeCacheKey,
14
+ type CompiledCSS,
15
+ } from '@/infrastructure/css/cache/css-cache-service'
16
+ import { generateAnimationStyles } from '@/infrastructure/css/styles/animation-styles-generator'
17
+ import {
18
+ generateComponentsLayer,
19
+ generateUtilitiesLayer,
20
+ } from '@/infrastructure/css/styles/component-layer-generators'
21
+ import {
22
+ generateThemeBorderRadius,
23
+ generateThemeBreakpoints,
24
+ generateThemeColors,
25
+ generateThemeFonts,
26
+ generateThemeShadows,
27
+ generateThemeSpacing,
28
+ } from '@/infrastructure/css/theme/theme-generators'
29
+ import { generateBaseLayer } from '@/infrastructure/css/theme/theme-layer-generators'
30
+ import { CSSCompilationError } from '@/infrastructure/errors/css-compilation-error'
31
+ import { logDebug, logError } from '@/infrastructure/logging/logger'
32
+ import type { App } from '@/domain/models/app'
33
+ import type { Theme } from '@/domain/models/app/theme'
34
+
35
+ // Re-export CompiledCSS type for external use
36
+ export type { CompiledCSS } from '@/infrastructure/css/cache/css-cache-service'
37
+
38
+ /**
39
+ * Generate complete Tailwind @theme CSS from app theme
40
+ */
41
+ function generateThemeCSS(theme?: Theme): string {
42
+ if (!theme) return ''
43
+
44
+ const themeTokens = [
45
+ generateThemeColors(theme.colors),
46
+ generateThemeFonts(theme.fonts),
47
+ generateThemeSpacing(theme.spacing),
48
+ generateThemeShadows(theme.shadows),
49
+ generateThemeBorderRadius(theme.borderRadius),
50
+ generateThemeBreakpoints(theme.breakpoints),
51
+ ].filter(Boolean)
52
+
53
+ if (themeTokens.length === 0) return ''
54
+
55
+ return `@theme {\n${themeTokens.join('\n')}\n }`
56
+ }
57
+
58
+ /**
59
+ * Static CSS imports and custom variants
60
+ */
61
+ const STATIC_IMPORTS = `@import 'tailwindcss';
62
+ @import 'tw-animate-css';
63
+ /*---break---
64
+ */
65
+ @custom-variant dark (&:is(.dark *));`
66
+
67
+ /**
68
+ * Final base layer for global resets
69
+ * Note: Removed hardcoded utilities (border-border, bg-background, etc.)
70
+ * These should be defined in the app theme if needed
71
+ */
72
+ const FINAL_BASE_LAYER = ''
73
+
74
+ /**
75
+ * Build dynamic SOURCE_CSS with theme tokens
76
+ * Generates Tailwind CSS with @theme directive based on app theme
77
+ */
78
+ function buildSourceCSS(theme?: Theme): string {
79
+ const themeCSS = generateThemeCSS(theme)
80
+ const animationCSS = generateAnimationStyles(theme?.animations, theme)
81
+ const baseLayerCSS = generateBaseLayer(theme)
82
+ const componentsLayerCSS = generateComponentsLayer(theme)
83
+ const utilitiesLayerCSS = generateUtilitiesLayer()
84
+
85
+ return [
86
+ STATIC_IMPORTS,
87
+ baseLayerCSS,
88
+ componentsLayerCSS,
89
+ utilitiesLayerCSS,
90
+ '/*---break---\n */',
91
+ themeCSS,
92
+ '/*---break---\n */',
93
+ animationCSS,
94
+ '/*---break---\n */',
95
+ FINAL_BASE_LAYER,
96
+ ]
97
+ .filter(Boolean)
98
+ .join('\n\n ')
99
+ }
100
+
101
+ /**
102
+ * Internal CSS compilation logic (without caching)
103
+ * Generates and compiles Tailwind CSS from theme configuration
104
+ */
105
+ const compileCSSInternal = (theme?: Theme): Effect.Effect<CompiledCSS, CSSCompilationError> =>
106
+ Effect.gen(function* () {
107
+ // Build SOURCE_CSS with theme
108
+ const sourceCSS = buildSourceCSS(theme)
109
+
110
+ // Diagnostic logging for CI debugging
111
+ yield* Console.log(`CSS Compiler - Source CSS length: ${sourceCSS.length} bytes`)
112
+ yield* Console.log(
113
+ `CSS Compiler - Contains @import 'tailwindcss': ${sourceCSS.includes("@import 'tailwindcss'")}`
114
+ )
115
+ yield* Console.log(
116
+ `CSS Compiler - Contains @import 'tw-animate-css': ${sourceCSS.includes("@import 'tw-animate-css'")}`
117
+ )
118
+
119
+ // Process CSS through PostCSS with Tailwind plugin
120
+ const result = yield* Effect.tryPromise({
121
+ try: async () => {
122
+ // Verify PostCSS and Tailwind plugin are available
123
+ if (!postcss || typeof postcss !== 'function') {
124
+ // eslint-disable-next-line unicorn/no-useless-promise-resolve-reject
125
+ return Promise.reject(new Error('PostCSS is not available'))
126
+ }
127
+ if (!tailwindcss || typeof tailwindcss !== 'function') {
128
+ // eslint-disable-next-line unicorn/no-useless-promise-resolve-reject
129
+ return Promise.reject(new Error('Tailwind CSS plugin is not available'))
130
+ }
131
+
132
+ // Cast needed: @tailwindcss/postcss bundles its own PostCSS types
133
+ // which are structurally identical but nominally different from top-level postcss
134
+ const processor = postcss([tailwindcss() as postcss.AcceptedPlugin])
135
+ return await processor.process(sourceCSS, {
136
+ from: process.cwd() + '/src/styles/global.css', // Source context for import resolution
137
+ to: undefined, // No output file (in-memory compilation)
138
+ })
139
+ },
140
+ catch: (error) => {
141
+ // Enhanced error logging for CI debugging
142
+ logError('CSS Compilation Error Details', error)
143
+ logDebug(`Error type: ${error instanceof Error ? error.constructor.name : typeof error}`)
144
+ logDebug(`Error message: ${error instanceof Error ? error.message : String(error)}`)
145
+ if (error instanceof Error && error.stack) {
146
+ logDebug(`Error stack: ${error.stack}`)
147
+ }
148
+ logDebug(`Source CSS preview (first 500 chars): ${sourceCSS.slice(0, 500)}`)
149
+
150
+ return new CSSCompilationError(error)
151
+ },
152
+ })
153
+
154
+ yield* Console.log('CSS compiled and cached')
155
+
156
+ // Create compiled CSS result
157
+ return {
158
+ css: result.css,
159
+ timestamp: Date.now(),
160
+ }
161
+ })
162
+
163
+ /**
164
+ * Compiles Tailwind CSS using PostCSS with @tailwindcss/postcss plugin
165
+ *
166
+ * This function:
167
+ * 1. Extracts theme from app config (if provided)
168
+ * 2. Generates dynamic SOURCE_CSS with @theme tokens
169
+ * 3. Processes through PostCSS with Tailwind CSS v4 plugin
170
+ * 4. Returns the compiled CSS string
171
+ * 5. Caches the result in memory per theme (subsequent requests use cache)
172
+ *
173
+ * Uses getOrComputeCachedCSS for declarative caching with normalized theme keys.
174
+ * Same theme content always produces the same cache key regardless of property order.
175
+ *
176
+ * @param app - Optional app configuration containing theme
177
+ * @returns Effect that yields compiled CSS string or CSSCompilationError
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * // Without theme (minimal CSS)
182
+ * const program = Effect.gen(function* () {
183
+ * const result = yield* compileCSS()
184
+ * console.log(`Compiled ${result.css.length} bytes of CSS`)
185
+ * })
186
+ *
187
+ * // With app theme
188
+ * const programWithTheme = Effect.gen(function* () {
189
+ * const result = yield* compileCSS(app)
190
+ * console.log(`Compiled ${result.css.length} bytes of CSS with theme`)
191
+ * })
192
+ *
193
+ * Effect.runPromise(program)
194
+ * ```
195
+ */
196
+ export const compileCSS = (app?: App): Effect.Effect<CompiledCSS, CSSCompilationError> =>
197
+ Effect.gen(function* () {
198
+ const theme = app?.theme
199
+ const cacheKey = getThemeCacheKey(theme)
200
+
201
+ // Use declarative cache helper with theme-based key
202
+ const result = yield* getOrComputeCachedCSS(cacheKey, compileCSSInternal(theme))
203
+
204
+ // Log cache status (hit if timestamp is old, compiled if fresh)
205
+ if (Date.now() - result.timestamp > 100) {
206
+ yield* Console.log('CSS cache hit')
207
+ }
208
+
209
+ return result
210
+ })
@@ -0,0 +1,20 @@
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 { Layer } from 'effect'
9
+ import { CSSCompiler } from '@/application/ports/services/css-compiler'
10
+ import { compileCSS } from '@/infrastructure/css/compiler'
11
+
12
+ /**
13
+ * Live implementation of CSSCompiler using PostCSS and Tailwind
14
+ *
15
+ * This layer provides the production implementation of CSS compilation
16
+ * using the infrastructure's PostCSS-based compiler.
17
+ */
18
+ export const CSSCompilerLive = Layer.succeed(CSSCompiler, {
19
+ compile: compileCSS,
20
+ })
@@ -0,0 +1,25 @@
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
+ * CSS Infrastructure Module
10
+ *
11
+ * Provides CSS compilation utilities using Tailwind CSS via PostCSS.
12
+ * Compiles Tailwind CSS on-demand for development and production builds.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { compileCSS } from '@/infrastructure/css'
17
+ *
18
+ * const program = Effect.gen(function* () {
19
+ * const compiledCSS = yield* compileCSS()
20
+ * return compiledCSS
21
+ * })
22
+ * ```
23
+ */
24
+
25
+ export { compileCSS } from './compiler'
@@ -0,0 +1,177 @@
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 { resolveTokenReference } from '@/infrastructure/css/theme/theme-token-resolver'
9
+ import type { Theme } from '@/domain/models/app/theme'
10
+ import type { AnimationConfigObject, AnimationsConfig } from '@/domain/models/app/theme/animations'
11
+
12
+ /**
13
+ * Generate @keyframes CSS for a single animation
14
+ * Supports token references like $colors.primary
15
+ *
16
+ * @param name - Animation name
17
+ * @param keyframes - Keyframe steps definition
18
+ * @param theme - Optional theme for token resolution
19
+ * @returns CSS @keyframes rule as string
20
+ *
21
+ * @example
22
+ * generateKeyframes('fade-in', { '0%': { opacity: 0 }, '100%': { opacity: 1 } })
23
+ * // => '@keyframes fade-in {\n 0% { opacity: 0; }\n 100% { opacity: 1; }\n}'
24
+ */
25
+ export function generateKeyframes(
26
+ name: string,
27
+ keyframes: Record<string, unknown>,
28
+ theme?: Theme
29
+ ): string {
30
+ const keyframeSteps = Object.entries(keyframes)
31
+ .map(([step, props]) => {
32
+ const propsStr =
33
+ typeof props === 'object' && props !== undefined
34
+ ? Object.entries(props as Record<string, unknown>)
35
+ .map(([prop, val]) => {
36
+ const resolvedValue = resolveTokenReference(val, theme)
37
+ return `${prop}: ${resolvedValue};`
38
+ })
39
+ .join(' ')
40
+ : ''
41
+ return ` ${step} { ${propsStr} }`
42
+ })
43
+ .join('\n')
44
+
45
+ return `@keyframes ${name} {\n${keyframeSteps}\n}`
46
+ }
47
+
48
+ /**
49
+ * Generate animation shorthand CSS
50
+ *
51
+ * @param name - Animation name
52
+ * @param duration - Optional duration (default: '300ms')
53
+ * @param easing - Optional easing function (default: 'ease')
54
+ * @param delay - Optional delay (default: '0ms')
55
+ * @returns CSS animation class as string
56
+ *
57
+ * @example
58
+ * generateAnimationClass('fade-in', '500ms', 'ease-in-out')
59
+ * // => '.animate-fade-in { animation: fade-in 500ms ease-in-out 0ms; }'
60
+ */
61
+ export function generateAnimationClass(
62
+ name: string,
63
+ duration?: string,
64
+ easing?: string,
65
+ delay?: string
66
+ ): string {
67
+ const dur = duration || '300ms'
68
+ const ease = easing || 'ease'
69
+ const del = delay || '0ms'
70
+ return `.animate-${name} { animation: ${name} ${dur} ${ease} ${del}; }`
71
+ }
72
+
73
+ /**
74
+ * Check if animation name is a reserved design token property
75
+ *
76
+ * @param name - Property name to check
77
+ * @returns True if reserved, false otherwise
78
+ */
79
+ export function isReservedAnimationProperty(name: string): boolean {
80
+ return name === 'duration' || name === 'easing' || name === 'keyframes'
81
+ }
82
+
83
+ /**
84
+ * Process animation config object
85
+ * Returns array of CSS strings (keyframes + optional animation class)
86
+ *
87
+ * @param name - Animation name
88
+ * @param animConfig - Animation configuration object
89
+ * @param theme - Optional theme for token resolution
90
+ * @returns Array of CSS rules (keyframes and optional animation class)
91
+ */
92
+ export function processAnimationConfigObject(
93
+ name: string,
94
+ animConfig: AnimationConfigObject,
95
+ theme?: Theme
96
+ ): readonly string[] {
97
+ if (!animConfig.keyframes) return []
98
+
99
+ const keyframesCSS = generateKeyframes(name, animConfig.keyframes, theme)
100
+
101
+ if (animConfig.enabled === false) {
102
+ return [keyframesCSS]
103
+ }
104
+
105
+ const animationClass = generateAnimationClass(
106
+ name,
107
+ animConfig.duration,
108
+ animConfig.easing,
109
+ animConfig.delay
110
+ )
111
+
112
+ return [keyframesCSS, animationClass]
113
+ }
114
+
115
+ /**
116
+ * Process a single legacy animation config entry
117
+ * Returns array of CSS strings (keyframes + optional animation class)
118
+ *
119
+ * @param name - Animation name
120
+ * @param config - Animation configuration (can be boolean, string, or object)
121
+ * @param theme - Optional theme for token resolution
122
+ * @returns Array of CSS rules
123
+ */
124
+ export function processLegacyAnimationEntry(
125
+ name: string,
126
+ config: unknown,
127
+ theme?: Theme
128
+ ): readonly string[] {
129
+ if (isReservedAnimationProperty(name)) return []
130
+ if (typeof config === 'boolean' && !config) return []
131
+ if (typeof config === 'string') return []
132
+ if (typeof config === 'object' && config !== undefined) {
133
+ return processAnimationConfigObject(name, config as AnimationConfigObject, theme)
134
+ }
135
+ return []
136
+ }
137
+
138
+ /**
139
+ * Generate @keyframes and animation CSS from domain animations config
140
+ * Supports both nested design tokens and legacy flat animations
141
+ *
142
+ * @param animations - Animations configuration from theme
143
+ * @param theme - Optional theme for token resolution
144
+ * @returns Complete animation CSS as string
145
+ *
146
+ * @example
147
+ * generateAnimationStyles(theme.animations, theme)
148
+ * // => '@keyframes fade-in { ... }\n.animate-fade-in { ... }'
149
+ */
150
+ export function generateAnimationStyles(animations?: AnimationsConfig, theme?: Theme): string {
151
+ if (!animations || Object.keys(animations).length === 0) return ''
152
+
153
+ // Extract nested design tokens if present
154
+ const keyframesTokens = animations.keyframes as
155
+ | Record<string, Record<string, unknown>>
156
+ | undefined
157
+
158
+ // Generate keyframes from nested design tokens (immutable)
159
+ const nestedKeyframesCSS =
160
+ keyframesTokens && typeof keyframesTokens === 'object'
161
+ ? Object.entries(keyframesTokens).flatMap(([name, keyframes]) =>
162
+ keyframes && typeof keyframes === 'object'
163
+ ? [generateKeyframes(name, keyframes, theme)]
164
+ : []
165
+ )
166
+ : []
167
+
168
+ // Process legacy flat animations (backwards compatibility, immutable)
169
+ const legacyAnimationsCSS = Object.entries(animations).flatMap(([name, config]) =>
170
+ processLegacyAnimationEntry(name, config, theme)
171
+ )
172
+
173
+ // Combine all CSS (immutable)
174
+ const animationCSS: readonly string[] = [...nestedKeyframesCSS, ...legacyAnimationsCSS]
175
+
176
+ return animationCSS.join('\n')
177
+ }
@@ -0,0 +1,147 @@
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
+ * Click interaction animations
10
+ *
11
+ * Provides CSS animations for click interactions (pulse, ripple, bounce, etc.)
12
+ * These animations are separate from entrance/exit animations provided by tw-animate-css
13
+ *
14
+ * Architecture: Infrastructure Layer (CSS generation)
15
+ * - Supports click interaction schema (animation: pulse, ripple, bounce, shake, flash, none)
16
+ * - Generates @keyframes and utility classes for click feedback
17
+ */
18
+
19
+ /**
20
+ * Pulse animation CSS - subtle scale pulse
21
+ */
22
+ const PULSE_ANIMATION_CSS = `
23
+ @keyframes pulse {
24
+ 0%, 100% {
25
+ transform: scale(1);
26
+ opacity: 1;
27
+ }
28
+ 50% {
29
+ transform: scale(1.05);
30
+ opacity: 0.9;
31
+ }
32
+ }
33
+
34
+ .animate-pulse {
35
+ animation: pulse 300ms ease-in-out;
36
+ }`
37
+
38
+ /**
39
+ * Bounce animation CSS - playful bounce effect
40
+ */
41
+ const BOUNCE_ANIMATION_CSS = `
42
+ @keyframes bounce {
43
+ 0%, 100% {
44
+ transform: translateY(0);
45
+ }
46
+ 25% {
47
+ transform: translateY(-8px);
48
+ }
49
+ 50% {
50
+ transform: translateY(-4px);
51
+ }
52
+ 75% {
53
+ transform: translateY(-2px);
54
+ }
55
+ }
56
+
57
+ .animate-bounce {
58
+ animation: bounce 300ms ease-out;
59
+ }`
60
+
61
+ /**
62
+ * Shake animation CSS - horizontal shake
63
+ */
64
+ const SHAKE_ANIMATION_CSS = `
65
+ @keyframes shake {
66
+ 0%, 100% {
67
+ transform: translateX(0);
68
+ }
69
+ 10%, 30%, 50%, 70%, 90% {
70
+ transform: translateX(-4px);
71
+ }
72
+ 20%, 40%, 60%, 80% {
73
+ transform: translateX(4px);
74
+ }
75
+ }
76
+
77
+ .animate-shake {
78
+ animation: shake 300ms ease-in-out;
79
+ }`
80
+
81
+ /**
82
+ * Flash animation CSS - quick opacity flash
83
+ */
84
+ const FLASH_ANIMATION_CSS = `
85
+ @keyframes flash {
86
+ 0%, 100% {
87
+ opacity: 1;
88
+ }
89
+ 25%, 75% {
90
+ opacity: 0.4;
91
+ }
92
+ 50% {
93
+ opacity: 1;
94
+ }
95
+ }
96
+
97
+ .animate-flash {
98
+ animation: flash 300ms ease-in-out;
99
+ }`
100
+
101
+ /**
102
+ * Ripple animation CSS - Material Design ripple
103
+ */
104
+ const RIPPLE_ANIMATION_CSS = `
105
+ @keyframes ripple {
106
+ 0% {
107
+ transform: scale(0);
108
+ opacity: 1;
109
+ }
110
+ 100% {
111
+ transform: scale(4);
112
+ opacity: 0;
113
+ }
114
+ }
115
+
116
+ .animate-ripple {
117
+ position: relative;
118
+ overflow: hidden;
119
+ }
120
+
121
+ .animate-ripple::after {
122
+ content: '';
123
+ position: absolute;
124
+ top: 50%;
125
+ left: 50%;
126
+ width: 100px;
127
+ height: 100px;
128
+ background: rgba(255, 255, 255, 0.5);
129
+ border-radius: 50%;
130
+ transform: translate(-50%, -50%) scale(0);
131
+ animation: ripple 600ms ease-out;
132
+ }`
133
+
134
+ /**
135
+ * Generate CSS for click interaction animations
136
+ *
137
+ * Returns CSS string with @keyframes and .animate-* utility classes
138
+ * for all click interaction animation types
139
+ */
140
+ export function generateClickAnimationCSS(): string {
141
+ return `/* Click interaction animations */
142
+ ${PULSE_ANIMATION_CSS}
143
+ ${BOUNCE_ANIMATION_CSS}
144
+ ${SHAKE_ANIMATION_CSS}
145
+ ${FLASH_ANIMATION_CSS}
146
+ ${RIPPLE_ANIMATION_CSS}`
147
+ }