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,270 @@
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 { PageIdSchema } from './id'
10
+ import { MetaSchema } from './meta'
11
+ import { PageNameSchema } from './name'
12
+ import { PagePathSchema } from './path'
13
+ import { ScriptsSchema } from './scripts/scripts'
14
+ import { SectionsSchema } from './sections'
15
+
16
+ /**
17
+ * Page Schema
18
+ *
19
+ * Represents a complete page configuration with metadata, layout, sections, and scripts.
20
+ *
21
+ * Marketing and content pages with server-side rendering support. Pages use a component-based
22
+ * layout system with reusable component templates for building landing pages, about pages, pricing
23
+ * pages, and other public-facing content.
24
+ *
25
+ * ## Key Features
26
+ *
27
+ * - **Component-Based Layout**: Compose pages from reusable component templates defined at app level
28
+ * - **Theme Integration**: Pages use app.theme{} tokens via className utilities
29
+ * - **i18n Support**: Multi-language pages with $t: translation references
30
+ * - **Responsive Design**: Single page adapts to all viewports (mobile, tablet, desktop)
31
+ * - **SEO Optimization**: Comprehensive metadata, structured data, social sharing
32
+ *
33
+ * ## Architecture Notes
34
+ *
35
+ * - **Theme**: Defined at app level (app.theme{}), NOT in individual pages
36
+ * - **Components**: Defined at app level (app.components[]), NOT in individual pages
37
+ * - **Sections**: Reference component templates using $ref syntax with $vars substitution
38
+ * - **Styling**: Pages use className with theme tokens, not page-level theme
39
+ *
40
+ * ## Component References
41
+ *
42
+ * Sections can reference component templates defined at app level using $ref syntax:
43
+ *
44
+ * ```typescript
45
+ * {
46
+ * sections: [
47
+ * {
48
+ * : '#/components/hero',
49
+ * $vars: {
50
+ * title: 'Welcome to Our Platform',
51
+ * ctaLabel: 'Get Started'
52
+ * }
53
+ * }
54
+ * ]
55
+ * }
56
+ * ```
57
+ *
58
+ * The component template is resolved and variables ($title, $ctaLabel) are substituted
59
+ * at runtime.
60
+ *
61
+ * ## Translation References
62
+ *
63
+ * Pages support internationalization via $t: translation references:
64
+ *
65
+ * ```typescript
66
+ * {
67
+ * meta: {
68
+ * lang: 'en',
69
+ * title: '$t:hero.title'
70
+ * },
71
+ * sections: [
72
+ * {
73
+ * type: 'h1',
74
+ * children: ['$t:hero.title']
75
+ * }
76
+ * ]
77
+ * }
78
+ * ```
79
+ *
80
+ * Translation keys resolve based on meta.lang from app.languages{} configuration.
81
+ *
82
+ * ## Responsive Design
83
+ *
84
+ * Pages adapt to different viewports using responsive className utilities:
85
+ *
86
+ * ```typescript
87
+ * {
88
+ * type: 'section',
89
+ * props: {
90
+ * className: 'py-12 md:py-20 lg:py-32'
91
+ * }
92
+ * }
93
+ * ```
94
+ *
95
+ * Mobile-first approach: base styles for mobile, breakpoints for larger screens.
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * // Minimal page with required properties
100
+ * const minimalPage: Page = {
101
+ * name: 'Home',
102
+ * path: '/',
103
+ * meta: {
104
+ * lang: 'en-US',
105
+ * title: 'Welcome',
106
+ * description: 'Welcome to our platform'
107
+ * },
108
+ * sections: []
109
+ * }
110
+ *
111
+ * // Complete page with all properties
112
+ * const completePage: Page = {
113
+ * id: 'homepage',
114
+ * name: 'Home',
115
+ * path: '/',
116
+ * meta: {
117
+ * lang: 'en-US',
118
+ * title: 'Welcome',
119
+ * description: 'Welcome to our platform',
120
+ * openGraph: {
121
+ * title: 'Welcome to Our Platform',
122
+ * type: 'website',
123
+ * url: 'https://example.com',
124
+ * image: 'https://example.com/og-image.jpg'
125
+ * }
126
+ * },
127
+ * sections: [
128
+ * {
129
+ * : '#/components/hero',
130
+ * $vars: {
131
+ * title: 'Welcome',
132
+ * ctaLabel: 'Get Started'
133
+ * }
134
+ * }
135
+ * ],
136
+ * scripts: {
137
+ * features: {
138
+ * analytics: true
139
+ * }
140
+ * }
141
+ * }
142
+ * ```
143
+ *
144
+ * @see {@link https://schema.org Schema.org} for structured data
145
+ * @see {@link MetaSchema} for metadata configuration
146
+ * @see {@link SectionsSchema} for sections configuration
147
+ * @see {@link ScriptsSchema} for scripts configuration
148
+ */
149
+ export const PageSchema = Schema.Struct({
150
+ /**
151
+ * Optional unique identifier for the page
152
+ *
153
+ * Used for internal references and tracking
154
+ */
155
+ id: Schema.optional(PageIdSchema),
156
+
157
+ /**
158
+ * Human-readable name for the page
159
+ *
160
+ * Used for identification in admin interfaces and as internal identifier.
161
+ * Required field that serves as a unique identifier separate from the URL path.
162
+ *
163
+ * @example "home"
164
+ * @example "about"
165
+ */
166
+ name: PageNameSchema,
167
+
168
+ /**
169
+ * URL path where the page is accessible
170
+ *
171
+ * - Root path: `/` (homepage)
172
+ * - Nested paths: `/about`, `/products/pricing`
173
+ *
174
+ * @example "/"
175
+ * @example "/about"
176
+ * @example "/products/pricing"
177
+ */
178
+ path: PagePathSchema,
179
+
180
+ /**
181
+ * Page metadata for SEO, social sharing, and analytics
182
+ *
183
+ * Optional - if not provided, uses default metadata based on page name/path
184
+ *
185
+ * Includes:
186
+ * - Basic SEO (title, description, keywords)
187
+ * - Social media (Open Graph, Twitter Card)
188
+ * - Structured data (Schema.org)
189
+ * - Performance hints (preload, DNS prefetch)
190
+ * - Analytics configuration
191
+ */
192
+ meta: Schema.optional(MetaSchema),
193
+
194
+ /**
195
+ * Page sections containing content
196
+ *
197
+ * Sections can be:
198
+ * - Direct components: { type, props, children }
199
+ * - Component references: { $ref, $vars }
200
+ *
201
+ * Component references resolve to app.components[] with variable substitution
202
+ */
203
+ sections: SectionsSchema,
204
+
205
+ /**
206
+ * Optional client-side scripts and features
207
+ *
208
+ * Manages:
209
+ * - Feature flags (analytics, chat widget)
210
+ * - External scripts (CDN resources)
211
+ * - Inline scripts (custom JavaScript)
212
+ * - Client configuration
213
+ */
214
+ scripts: Schema.optional(ScriptsSchema),
215
+
216
+ /**
217
+ * Optional page-level variables for substitution in sections
218
+ *
219
+ * Variables can be referenced in section content, props, and children using
220
+ * $variableName syntax. These variables are substituted at runtime.
221
+ *
222
+ * Page-level variables provide values for sections without component references.
223
+ * They complement component-level vars (from $ref with $vars) for direct sections.
224
+ *
225
+ * @example
226
+ * ```typescript
227
+ * {
228
+ * vars: {
229
+ * siteName: 'Sovrium',
230
+ * primaryColor: 'blue'
231
+ * },
232
+ * sections: [
233
+ * {
234
+ * type: 'heading',
235
+ * content: 'Welcome to $siteName' // → 'Welcome to Sovrium'
236
+ * },
237
+ * {
238
+ * type: 'button',
239
+ * props: {
240
+ * className: 'bg-$primaryColor' // → 'bg-blue'
241
+ * }
242
+ * }
243
+ * ]
244
+ * }
245
+ * ```
246
+ */
247
+ vars: Schema.optional(
248
+ Schema.Record({
249
+ key: Schema.String,
250
+ value: Schema.Union(Schema.String, Schema.Number, Schema.Boolean),
251
+ })
252
+ ),
253
+ }).pipe(
254
+ Schema.annotations({
255
+ identifier: 'Page',
256
+ title: 'Page',
257
+ description:
258
+ 'Complete page configuration with metadata, layout, sections, and scripts. Pages use a component-based layout system with reusable component templates.',
259
+ })
260
+ )
261
+
262
+ /**
263
+ * TypeScript type for a Page
264
+ */
265
+ export type Page = typeof PageSchema.Type
266
+
267
+ /**
268
+ * TypeScript type for an encoded Page (before validation)
269
+ */
270
+ export type PageEncoded = typeof PageSchema.Encoded
@@ -0,0 +1,248 @@
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
+ * Analytics provider name
12
+ *
13
+ * 6 supported analytics platforms:
14
+ * - google: Google Analytics 4 (most popular, 60% market share)
15
+ * - plausible: Privacy-focused, GDPR-compliant, no cookies
16
+ * - matomo: Open-source, self-hosted, privacy-focused
17
+ * - fathom: Privacy-first, simple, GDPR-compliant
18
+ * - posthog: Product analytics, session replay, feature flags
19
+ * - mixpanel: Product analytics, funnel analysis, cohort analysis
20
+ */
21
+ export const AnalyticsProviderNameSchema = Schema.Literal(
22
+ 'google',
23
+ 'plausible',
24
+ 'matomo',
25
+ 'fathom',
26
+ 'posthog',
27
+ 'mixpanel'
28
+ ).annotations({
29
+ description: 'Analytics provider name',
30
+ })
31
+
32
+ /**
33
+ * Analytics script configuration
34
+ *
35
+ * External JavaScript file to load for analytics provider.
36
+ *
37
+ * Required properties:
38
+ * - src: Script source URL (CDN or provider-hosted)
39
+ *
40
+ * Optional properties:
41
+ * - async: Load asynchronously (default: true, recommended for analytics)
42
+ * - defer: Defer execution until DOM loaded
43
+ */
44
+ export const AnalyticsScriptSchema = Schema.Struct({
45
+ src: Schema.String.annotations({
46
+ description: 'Script source URL',
47
+ format: 'uri',
48
+ }),
49
+ async: Schema.optional(
50
+ Schema.Boolean.annotations({
51
+ description: 'Load script asynchronously',
52
+ default: true,
53
+ })
54
+ ),
55
+ defer: Schema.optional(
56
+ Schema.Boolean.annotations({
57
+ description: 'Defer script execution',
58
+ })
59
+ ),
60
+ }).annotations({
61
+ description: 'Analytics script',
62
+ })
63
+
64
+ /**
65
+ * Analytics provider configuration
66
+ *
67
+ * Defines a single analytics provider with scripts, initialization, and settings.
68
+ *
69
+ * Required properties:
70
+ * - name: Provider name (google, plausible, matomo, fathom, posthog, mixpanel)
71
+ *
72
+ * Optional properties:
73
+ * - enabled: Whether provider is active (default: true)
74
+ * - scripts: Array of external scripts to load
75
+ * - initScript: Inline JavaScript for provider initialization
76
+ * - dnsPrefetch: Domain to DNS prefetch (performance optimization)
77
+ * - config: Provider-specific configuration (tracking IDs, privacy settings, features)
78
+ *
79
+ * Common pattern:
80
+ * 1. Load external script(s) from CDN (scripts array)
81
+ * 2. Run initialization code (initScript)
82
+ * 3. Configure with provider settings (config object)
83
+ *
84
+ * Performance optimization:
85
+ * - async: true (default) - non-blocking script load
86
+ * - dnsPrefetch: Early DNS resolution for faster script load
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * const googleAnalytics = {
91
+ * name: 'google',
92
+ * enabled: true,
93
+ * scripts: [
94
+ * {
95
+ * src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXX',
96
+ * async: true
97
+ * }
98
+ * ],
99
+ * initScript: `
100
+ * window.dataLayer = window.dataLayer || [];
101
+ * function gtag(){dataLayer.push(arguments);}
102
+ * gtag('js', new Date());
103
+ * gtag('config', 'G-XXXXX');
104
+ * `,
105
+ * dnsPrefetch: 'https://www.googletagmanager.com',
106
+ * config: {
107
+ * trackingId: 'G-XXXXX',
108
+ * anonymizeIp: true
109
+ * }
110
+ * }
111
+ *
112
+ * const plausible = {
113
+ * name: 'plausible',
114
+ * enabled: true,
115
+ * scripts: [
116
+ * {
117
+ * src: 'https://plausible.io/js/script.js',
118
+ * async: true,
119
+ * defer: true
120
+ * }
121
+ * ],
122
+ * dnsPrefetch: 'https://plausible.io',
123
+ * config: {
124
+ * domain: 'example.com'
125
+ * }
126
+ * }
127
+ * ```
128
+ *
129
+ * @see specs/app/pages/meta/analytics/analytics.schema.json
130
+ */
131
+ export const AnalyticsProviderSchema = Schema.Struct({
132
+ name: AnalyticsProviderNameSchema,
133
+ enabled: Schema.optional(
134
+ Schema.Boolean.annotations({
135
+ description: 'Whether this provider is enabled',
136
+ default: true,
137
+ })
138
+ ),
139
+ scripts: Schema.optional(Schema.Array(AnalyticsScriptSchema)),
140
+ initScript: Schema.optional(
141
+ Schema.String.annotations({
142
+ description: 'Inline JavaScript to initialize the analytics',
143
+ })
144
+ ),
145
+ dnsPrefetch: Schema.optional(
146
+ Schema.String.annotations({
147
+ description: 'Domain to DNS prefetch for this provider',
148
+ format: 'uri',
149
+ })
150
+ ),
151
+ config: Schema.optional(
152
+ Schema.Record({
153
+ key: Schema.String,
154
+ value: Schema.Unknown,
155
+ }).annotations({
156
+ description: 'Provider-specific configuration',
157
+ })
158
+ ),
159
+ }).annotations({
160
+ description: 'Analytics provider',
161
+ })
162
+
163
+ /**
164
+ * Analytics configuration for multiple providers
165
+ *
166
+ * Manages analytics tracking across one or more analytics platforms.
167
+ * Supports simultaneous tracking with multiple providers for:
168
+ * - Transition periods (migrating between providers)
169
+ * - Compliance (privacy-friendly for EU, full-featured for others)
170
+ * - Comparison (data quality validation)
171
+ * - Redundancy (backup if one fails)
172
+ *
173
+ * Required properties:
174
+ * - providers: Array of analytics provider configurations
175
+ *
176
+ * Provider categories:
177
+ * 1. **Privacy-focused** (GDPR-compliant, no cookies):
178
+ * - plausible: < 1KB, simple dashboards
179
+ * - matomo: Open-source, self-hosted
180
+ * - fathom: Minimal, privacy-first
181
+ *
182
+ * 2. **Full-featured** (detailed analytics):
183
+ * - google: Free, most popular, integrates with Ads
184
+ * - posthog: Product analytics, session replay, feature flags
185
+ * - mixpanel: Funnel analysis, cohorts, retention
186
+ *
187
+ * Integration notes:
188
+ * - All scripts load asynchronously (non-blocking)
189
+ * - DNS prefetch optimizes external script loading
190
+ * - Config object flexible (additionalProperties: true)
191
+ * - Each provider independent (isolated initialization)
192
+ *
193
+ * @example
194
+ * ```typescript
195
+ * const analytics = {
196
+ * providers: [
197
+ * // Privacy-friendly for all users
198
+ * {
199
+ * name: 'plausible',
200
+ * enabled: true,
201
+ * scripts: [
202
+ * {
203
+ * src: 'https://plausible.io/js/script.js',
204
+ * async: true
205
+ * }
206
+ * ],
207
+ * config: {
208
+ * domain: 'example.com'
209
+ * }
210
+ * },
211
+ * // Full-featured for detailed insights
212
+ * {
213
+ * name: 'google',
214
+ * enabled: true,
215
+ * scripts: [
216
+ * {
217
+ * src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXX',
218
+ * async: true
219
+ * }
220
+ * ],
221
+ * initScript: `
222
+ * window.dataLayer = window.dataLayer || [];
223
+ * function gtag(){dataLayer.push(arguments);}
224
+ * gtag('js', new Date());
225
+ * gtag('config', 'G-XXXXX');
226
+ * `,
227
+ * config: {
228
+ * trackingId: 'G-XXXXX',
229
+ * anonymizeIp: true
230
+ * }
231
+ * }
232
+ * ]
233
+ * }
234
+ * ```
235
+ *
236
+ * @see specs/app/pages/meta/analytics/analytics.schema.json
237
+ */
238
+ export const AnalyticsSchema = Schema.Struct({
239
+ providers: Schema.Array(AnalyticsProviderSchema),
240
+ }).annotations({
241
+ title: 'Analytics Configuration',
242
+ description: 'Configuration for analytics providers',
243
+ })
244
+
245
+ export type AnalyticsProviderName = Schema.Schema.Type<typeof AnalyticsProviderNameSchema>
246
+ export type AnalyticsScript = Schema.Schema.Type<typeof AnalyticsScriptSchema>
247
+ export type AnalyticsProvider = Schema.Schema.Type<typeof AnalyticsProviderSchema>
248
+ export type Analytics = Schema.Schema.Type<typeof AnalyticsSchema>
@@ -0,0 +1,180 @@
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
+ * Custom head element type
12
+ *
13
+ * 5 HTML elements allowed in <head>:
14
+ * - meta: Metadata (charset, viewport, theme-color, etc.)
15
+ * - link: External resources (stylesheets, preconnect, dns-prefetch)
16
+ * - script: JavaScript files or inline code
17
+ * - style: Inline CSS styles
18
+ * - base: Base URL for relative URLs
19
+ */
20
+ export const CustomElementTypeSchema = Schema.Literal(
21
+ 'meta',
22
+ 'link',
23
+ 'script',
24
+ 'style',
25
+ 'base'
26
+ ).annotations({
27
+ description: 'HTML element type',
28
+ })
29
+
30
+ /**
31
+ * Custom head element
32
+ *
33
+ * Allows adding arbitrary HTML elements to the page <head> section.
34
+ * Useful for custom meta tags, third-party integrations, or special configurations.
35
+ *
36
+ * Required properties:
37
+ * - type: HTML element type (meta, link, script, style, base)
38
+ *
39
+ * Optional properties:
40
+ * - attrs: Object of HTML attributes (kebab-case keys, string values)
41
+ * - content: Inner content for script or style elements
42
+ *
43
+ * Common use cases:
44
+ * - Custom meta tags: theme-color, apple-mobile-web-app-capable
45
+ * - Preconnect/DNS prefetch: Speed up external resource loading
46
+ * - Third-party scripts: Analytics, chat widgets not covered by analytics config
47
+ * - Inline styles: Critical CSS for above-the-fold content
48
+ *
49
+ * Attribute naming:
50
+ * - Keys must be kebab-case (data-theme, http-equiv, charset)
51
+ * - Values are always strings
52
+ * - Pattern: ^[a-zA-Z][a-zA-Z0-9-]*$
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const themeColorMeta = {
57
+ * type: 'meta',
58
+ * attrs: {
59
+ * name: 'theme-color',
60
+ * content: '#FFAF00'
61
+ * }
62
+ * }
63
+ *
64
+ * const viewportMeta = {
65
+ * type: 'meta',
66
+ * attrs: {
67
+ * name: 'viewport',
68
+ * content: 'width=device-width, initial-scale=1'
69
+ * }
70
+ * }
71
+ *
72
+ * const preconnectLink = {
73
+ * type: 'link',
74
+ * attrs: {
75
+ * rel: 'preconnect',
76
+ * href: 'https://fonts.gstatic.com'
77
+ * }
78
+ * }
79
+ *
80
+ * const inlineScript = {
81
+ * type: 'script',
82
+ * content: "console.log('Custom script');"
83
+ * }
84
+ *
85
+ * const criticalCSS = {
86
+ * type: 'style',
87
+ * content: 'body { margin: 0; padding: 0; }'
88
+ * }
89
+ * ```
90
+ *
91
+ * @see specs/app/pages/meta/custom-elements/custom-elements.schema.json
92
+ */
93
+ export const CustomElementSchema = Schema.Struct({
94
+ type: CustomElementTypeSchema,
95
+ attrs: Schema.optional(
96
+ Schema.Record({
97
+ key: Schema.String.pipe(
98
+ Schema.pattern(/^[a-zA-Z][a-zA-Z0-9-]*$/, {
99
+ message: () =>
100
+ 'Attribute name must start with a letter and contain only letters, numbers, and hyphens (kebab-case)',
101
+ })
102
+ ),
103
+ value: Schema.String,
104
+ }).annotations({
105
+ description: 'Element attributes',
106
+ })
107
+ ),
108
+ content: Schema.optional(
109
+ Schema.String.annotations({
110
+ description: 'Inner content for script or style elements',
111
+ })
112
+ ),
113
+ }).annotations({
114
+ description: 'Custom head element',
115
+ })
116
+
117
+ /**
118
+ * Additional custom elements to add to the page head
119
+ *
120
+ * Array of custom HTML elements injected into the <head> section.
121
+ * Provides escape hatch for custom meta tags, scripts, styles not
122
+ * covered by dedicated schemas (analytics, favicons, social, etc.).
123
+ *
124
+ * Common use cases:
125
+ * - Mobile web app meta tags (apple-mobile-web-app-capable, mobile-web-app-capable)
126
+ * - Theme customization (theme-color, color-scheme)
127
+ * - Performance optimization (preconnect, dns-prefetch for custom CDNs)
128
+ * - Third-party integrations (chat widgets, analytics not in analytics schema)
129
+ * - Critical CSS (inline styles for above-the-fold content)
130
+ *
131
+ * Order matters:
132
+ * - Meta tags: First (charset, viewport)
133
+ * - Preconnect/DNS prefetch: Early (before scripts that use those domains)
134
+ * - Styles: Before visual content
135
+ * - Scripts: Last (unless critical)
136
+ *
137
+ * @example
138
+ * ```typescript
139
+ * const customElements = [
140
+ * // Mobile web app configuration
141
+ * {
142
+ * type: 'meta',
143
+ * attrs: {
144
+ * name: 'apple-mobile-web-app-capable',
145
+ * content: 'yes'
146
+ * }
147
+ * },
148
+ * {
149
+ * type: 'meta',
150
+ * attrs: {
151
+ * name: 'theme-color',
152
+ * content: '#FFAF00'
153
+ * }
154
+ * },
155
+ * // Performance optimization
156
+ * {
157
+ * type: 'link',
158
+ * attrs: {
159
+ * rel: 'preconnect',
160
+ * href: 'https://fonts.gstatic.com'
161
+ * }
162
+ * },
163
+ * // Critical CSS
164
+ * {
165
+ * type: 'style',
166
+ * content: 'body{margin:0}*{box-sizing:border-box}'
167
+ * }
168
+ * ]
169
+ * ```
170
+ *
171
+ * @see specs/app/pages/meta/custom-elements/custom-elements.schema.json
172
+ */
173
+ export const CustomElementsSchema = Schema.Array(CustomElementSchema).annotations({
174
+ title: 'Custom Head Elements',
175
+ description: 'Additional custom elements to add to the page head',
176
+ })
177
+
178
+ export type CustomElementType = Schema.Schema.Type<typeof CustomElementTypeSchema>
179
+ export type CustomElement = Schema.Schema.Type<typeof CustomElementSchema>
180
+ export type CustomElements = Schema.Schema.Type<typeof CustomElementsSchema>