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,61 @@
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
+ * Unified Permission Type Registry
10
+ *
11
+ * This module provides centralized, reusable permission-related schemas
12
+ * used across the authentication and authorization system.
13
+ *
14
+ * ## Permission Domains
15
+ *
16
+ * ### 1. Resource:Action Permissions
17
+ * Used for API access control (admin plugin, API keys).
18
+ * Pattern: `{ resource: [actions] }` where actions can include '*' for wildcard.
19
+ *
20
+ * ### 2. Role-Based Permissions
21
+ * Hierarchical roles (owner > admin > member > viewer) with predefined capabilities.
22
+ *
23
+ * ### 3. Table/Record Permissions
24
+ * Application-layer permission checking for data access control.
25
+ * See `@/domain/models/app/table/permissions/` for table-specific schemas.
26
+ *
27
+ * ## Usage
28
+ *
29
+ * ```typescript
30
+ * import {
31
+ * ResourceActionPermissionsSchema,
32
+ * StandardRoleSchema,
33
+ * } from '@/domain/models/app/permissions'
34
+ * ```
35
+ */
36
+
37
+ // Resource:Action pattern for API permissions
38
+ export {
39
+ ResourceActionPermissionsSchema,
40
+ ResourceNameSchema,
41
+ ActionNameSchema,
42
+ ActionWithWildcardSchema,
43
+ type ResourceActionPermissions,
44
+ type ResourceName,
45
+ type ActionName,
46
+ type ActionWithWildcard,
47
+ } from './resource-action'
48
+
49
+ // Role definitions
50
+ export {
51
+ StandardRoleSchema,
52
+ AdminLevelRoleSchema,
53
+ UserLevelRoleSchema,
54
+ FlexibleRolesSchema,
55
+ StandardRolesArraySchema,
56
+ type StandardRole,
57
+ type AdminLevelRole,
58
+ type UserLevelRole,
59
+ type FlexibleRoles,
60
+ type StandardRolesArray,
61
+ } from './roles'
@@ -0,0 +1,114 @@
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
+ * Resource Name Schema
12
+ *
13
+ * Validates resource names in the resource:action permission pattern.
14
+ * Must start with a letter and contain only lowercase letters, numbers, underscores, or hyphens.
15
+ *
16
+ * @example
17
+ * Valid: "users", "posts", "api_keys", "user-profiles"
18
+ * Invalid: "123users", "_posts", "User Posts"
19
+ */
20
+ export const ResourceNameSchema = Schema.String.pipe(
21
+ Schema.pattern(/^[a-z][a-z0-9_-]*$/i),
22
+ Schema.annotations({
23
+ title: 'Resource Name',
24
+ description: 'Resource identifier (e.g., "users", "posts", "analytics")',
25
+ examples: ['users', 'posts', 'api_keys', 'user-profiles'],
26
+ })
27
+ )
28
+
29
+ export type ResourceName = Schema.Schema.Type<typeof ResourceNameSchema>
30
+
31
+ /**
32
+ * Action Name Schema
33
+ *
34
+ * Validates action names in the resource:action permission pattern.
35
+ * Must start with a letter and contain only lowercase letters, numbers, underscores, or hyphens.
36
+ *
37
+ * @example
38
+ * Valid: "read", "write", "create", "delete", "list_all"
39
+ * Invalid: "123read", "_write"
40
+ */
41
+ export const ActionNameSchema = Schema.String.pipe(
42
+ Schema.pattern(/^[a-z][a-z0-9_-]*$/i),
43
+ Schema.annotations({
44
+ title: 'Action Name',
45
+ description: 'Action identifier (e.g., "read", "write", "create", "delete")',
46
+ examples: ['read', 'write', 'create', 'update', 'delete', 'list'],
47
+ })
48
+ )
49
+
50
+ export type ActionName = Schema.Schema.Type<typeof ActionNameSchema>
51
+
52
+ /**
53
+ * Action with Wildcard Schema
54
+ *
55
+ * Either a specific action name or "*" for all actions on a resource.
56
+ */
57
+ export const ActionWithWildcardSchema = Schema.Union(Schema.Literal('*'), ActionNameSchema).pipe(
58
+ Schema.annotations({
59
+ title: 'Action',
60
+ description: 'Action name or "*" for all actions',
61
+ examples: ['read', 'write', '*'],
62
+ })
63
+ )
64
+
65
+ export type ActionWithWildcard = Schema.Schema.Type<typeof ActionWithWildcardSchema>
66
+
67
+ /**
68
+ * Resource:Action Permissions Schema (Shared)
69
+ *
70
+ * Defines granular permissions using the resource:action pattern.
71
+ * Each resource maps to an array of allowed actions.
72
+ *
73
+ * This schema is shared between:
74
+ * - Admin plugin (customPermissions)
75
+ * - API Keys plugin (resourcePermissions)
76
+ * - Any future permission-based features
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * {
81
+ * users: ['read', 'list'],
82
+ * posts: ['create', 'read', 'update', 'delete'],
83
+ * analytics: ['*'] // Wildcard for all actions
84
+ * }
85
+ * ```
86
+ */
87
+ export const ResourceActionPermissionsSchema = Schema.Record({
88
+ key: ResourceNameSchema.pipe(
89
+ Schema.annotations({ description: 'Resource name (e.g., "users", "posts")' })
90
+ ),
91
+ value: Schema.Array(ActionWithWildcardSchema).pipe(
92
+ Schema.minItems(1),
93
+ Schema.annotations({ description: 'Allowed actions for this resource' })
94
+ ),
95
+ }).pipe(
96
+ Schema.annotations({
97
+ title: 'Resource:Action Permissions',
98
+ description:
99
+ 'Granular permission definitions using resource:action pattern. Shared across admin, API keys, and other permission contexts.',
100
+ examples: [
101
+ {
102
+ users: ['read', 'list'],
103
+ posts: ['create', 'read', 'update', 'delete'],
104
+ analytics: ['*'],
105
+ },
106
+ {
107
+ comments: ['create', 'read', 'delete'],
108
+ media: ['*'],
109
+ },
110
+ ],
111
+ })
112
+ )
113
+
114
+ export type ResourceActionPermissions = Schema.Schema.Type<typeof ResourceActionPermissionsSchema>
@@ -0,0 +1,120 @@
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
+ * Standard Role Schema
12
+ *
13
+ * The three built-in roles used across the authentication system.
14
+ * These roles have well-defined hierarchies and permissions.
15
+ *
16
+ * Role Hierarchy (highest to lowest):
17
+ * - `admin`: Can manage members and settings
18
+ * - `member`: Standard access to organization resources
19
+ * - `viewer`: Read-only access
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * defaultRole: 'member'
24
+ * creatorRole: 'admin'
25
+ * ```
26
+ */
27
+ export const StandardRoleSchema = Schema.Literal('admin', 'member', 'viewer').pipe(
28
+ Schema.annotations({
29
+ title: 'Standard Role',
30
+ description: 'Built-in role with predefined permissions. Hierarchy: admin > member > viewer',
31
+ examples: ['admin', 'member', 'viewer'],
32
+ })
33
+ )
34
+
35
+ export type StandardRole = Schema.Schema.Type<typeof StandardRoleSchema>
36
+
37
+ /**
38
+ * Admin-Level Role Schema
39
+ *
40
+ * Subset of roles with administrative capabilities.
41
+ * Used for features like role creation/assignment restrictions.
42
+ */
43
+ export const AdminLevelRoleSchema = Schema.Literal('admin').pipe(
44
+ Schema.annotations({
45
+ title: 'Admin-Level Role',
46
+ description: 'Roles with administrative capabilities (admin)',
47
+ examples: ['admin'],
48
+ })
49
+ )
50
+
51
+ export type AdminLevelRole = Schema.Schema.Type<typeof AdminLevelRoleSchema>
52
+
53
+ /**
54
+ * User-Level Role Schema
55
+ *
56
+ * Subset of standard roles for default user role assignment.
57
+ * Used in admin plugin for defaultRole configuration.
58
+ */
59
+ export const UserLevelRoleSchema = Schema.String.pipe(
60
+ Schema.filter(
61
+ (value): value is 'admin' | 'member' | 'viewer' => {
62
+ return value === 'admin' || value === 'member' || value === 'viewer'
63
+ },
64
+ {
65
+ message: () => 'Invalid role. Must be one of: admin, member, viewer',
66
+ }
67
+ ),
68
+ Schema.annotations({
69
+ title: 'User-Level Role',
70
+ description: 'Roles available for default user assignment in admin context',
71
+ examples: ['admin', 'member', 'viewer'],
72
+ })
73
+ )
74
+
75
+ export type UserLevelRole = Schema.Schema.Type<typeof UserLevelRoleSchema>
76
+
77
+ /**
78
+ * Flexible Roles Schema
79
+ *
80
+ * Array of role names as strings for table permissions.
81
+ * Allows both standard roles and custom role names.
82
+ *
83
+ * Use this when:
84
+ * - Custom roles are supported (dynamic roles feature)
85
+ * - Role names come from user configuration
86
+ * - Flexibility is more important than strict validation
87
+ *
88
+ * @example
89
+ * ```typescript
90
+ * roles: ['admin', 'editor', 'custom-role']
91
+ * ```
92
+ */
93
+ export const FlexibleRolesSchema = Schema.Array(Schema.String).pipe(
94
+ Schema.minItems(1),
95
+ Schema.annotations({
96
+ title: 'Flexible Roles',
97
+ description:
98
+ 'Array of role names (supports both standard and custom roles). At least one role required.',
99
+ examples: [['admin'], ['admin', 'member'], ['admin', 'editor', 'custom-role']],
100
+ })
101
+ )
102
+
103
+ export type FlexibleRoles = Schema.Schema.Type<typeof FlexibleRolesSchema>
104
+
105
+ /**
106
+ * Standard Roles Array Schema
107
+ *
108
+ * Array of standard roles only (no custom roles).
109
+ * Use for strict validation when only built-in roles are allowed.
110
+ */
111
+ export const StandardRolesArraySchema = Schema.Array(StandardRoleSchema).pipe(
112
+ Schema.minItems(1),
113
+ Schema.annotations({
114
+ title: 'Standard Roles Array',
115
+ description: 'Array of standard roles only (admin, member, viewer)',
116
+ examples: [['admin'], ['admin', 'member'], ['admin', 'member', 'viewer']],
117
+ })
118
+ )
119
+
120
+ export type StandardRolesArray = Schema.Schema.Type<typeof StandardRolesArraySchema>
@@ -0,0 +1,105 @@
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
+ * Check Constraint Schema
12
+ *
13
+ * Defines a custom CHECK constraint that validates data at the database level.
14
+ * CHECK constraints allow you to enforce complex business rules beyond basic
15
+ * field-level validation.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * const constraint = {
20
+ * name: 'chk_active_members_have_email',
21
+ * check: '(is_active = false) OR (email IS NOT NULL)'
22
+ * }
23
+ * ```
24
+ */
25
+ export const CheckConstraintSchema = Schema.Struct({
26
+ /**
27
+ * Constraint name (must be unique within the table)
28
+ */
29
+ name: Schema.String.pipe(
30
+ Schema.minLength(1),
31
+ Schema.pattern(/^[a-z][a-z0-9_]*$/),
32
+ Schema.annotations({
33
+ title: 'Constraint Name',
34
+ description:
35
+ 'Unique name for the CHECK constraint (lowercase, alphanumeric with underscores)',
36
+ examples: ['chk_active_members_have_email', 'chk_price_positive', 'chk_end_after_start'],
37
+ })
38
+ ),
39
+
40
+ /**
41
+ * SQL check expression
42
+ */
43
+ check: Schema.String.pipe(
44
+ Schema.minLength(1),
45
+ Schema.annotations({
46
+ title: 'Check Expression',
47
+ description: 'PostgreSQL boolean expression that must evaluate to TRUE for valid data',
48
+ examples: [
49
+ '(is_active = false) OR (email IS NOT NULL)',
50
+ 'price > 0',
51
+ 'end_date > start_date',
52
+ "(status = 'completed') OR (completed_at IS NULL)",
53
+ ],
54
+ })
55
+ ),
56
+ })
57
+
58
+ export type CheckConstraint = Schema.Schema.Type<typeof CheckConstraintSchema>
59
+
60
+ /**
61
+ * Check Constraints Schema
62
+ *
63
+ * Array of CHECK constraints applied at the table level.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const constraints = [
68
+ * {
69
+ * name: 'chk_active_members_have_email',
70
+ * check: '(is_active = false) OR (email IS NOT NULL)'
71
+ * },
72
+ * {
73
+ * name: 'chk_price_positive',
74
+ * check: 'price > 0'
75
+ * }
76
+ * ]
77
+ * ```
78
+ */
79
+ export const CheckConstraintsSchema = Schema.Array(CheckConstraintSchema).pipe(
80
+ Schema.annotations({
81
+ title: 'Check Constraints',
82
+ description:
83
+ 'Table-level CHECK constraints for enforcing complex business rules beyond field-level validation',
84
+ examples: [
85
+ [
86
+ {
87
+ name: 'chk_active_members_have_email',
88
+ check: '(is_active = false) OR (email IS NOT NULL)',
89
+ },
90
+ ],
91
+ [
92
+ {
93
+ name: 'chk_price_positive',
94
+ check: 'price > 0',
95
+ },
96
+ {
97
+ name: 'chk_end_after_start',
98
+ check: 'end_date > start_date',
99
+ },
100
+ ],
101
+ ],
102
+ })
103
+ )
104
+
105
+ export type CheckConstraints = Schema.Schema.Type<typeof CheckConstraintsSchema>
@@ -0,0 +1,124 @@
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
+ * Shared cycle detection utilities using depth-first search (DFS)
10
+ * Used for detecting circular dependencies in both formula fields and table relationships
11
+ */
12
+
13
+ /**
14
+ * State tracked during DFS traversal
15
+ */
16
+ type DFSState = {
17
+ readonly visited: ReadonlySet<string>
18
+ readonly recursionStack: ReadonlySet<string>
19
+ readonly cycleNodes: ReadonlyArray<string>
20
+ }
21
+
22
+ /**
23
+ * Result of cycle detection
24
+ */
25
+ type CycleResult = {
26
+ readonly found: boolean
27
+ readonly state: DFSState
28
+ }
29
+
30
+ /**
31
+ * Detect cycles in a dependency graph using depth-first search (DFS)
32
+ *
33
+ * @param dependencyGraph - Map of node name to array of nodes it depends on
34
+ * @returns Array of node names involved in circular dependencies, or empty array if none found
35
+ *
36
+ * @example
37
+ * ```typescript
38
+ * const graph = new Map([
39
+ * ['A', ['B']],
40
+ * ['B', ['C']],
41
+ * ['C', ['A']], // Circular: A -> B -> C -> A
42
+ * ])
43
+ * detectCycles(graph) // ['A', 'B', 'C']
44
+ * ```
45
+ */
46
+ export const detectCycles = (
47
+ dependencyGraph: ReadonlyMap<string, ReadonlyArray<string>>
48
+ ): ReadonlyArray<string> => {
49
+ const hasCycle = (node: string, state: DFSState): CycleResult => {
50
+ if (state.recursionStack.has(node)) {
51
+ // Cycle detected - add to result
52
+ return {
53
+ found: true,
54
+ state: {
55
+ ...state,
56
+ cycleNodes: [...state.cycleNodes, node],
57
+ },
58
+ }
59
+ }
60
+
61
+ if (state.visited.has(node)) {
62
+ // Already processed this node
63
+ return { found: false, state }
64
+ }
65
+
66
+ const newState: DFSState = {
67
+ visited: new Set([...state.visited, node]),
68
+ recursionStack: new Set([...state.recursionStack, node]),
69
+ cycleNodes: state.cycleNodes,
70
+ }
71
+
72
+ const dependencies = dependencyGraph.get(node) || []
73
+ const result = dependencies.reduce<CycleResult>(
74
+ (acc, dep) => {
75
+ if (acc.found || !dependencyGraph.has(dep)) {
76
+ return acc
77
+ }
78
+ const depResult = hasCycle(dep, acc.state)
79
+ if (depResult.found) {
80
+ // Propagate cycle detection
81
+ const cycleNodes = depResult.state.cycleNodes.includes(node)
82
+ ? depResult.state.cycleNodes
83
+ : [...depResult.state.cycleNodes, node]
84
+ return {
85
+ found: true,
86
+ state: {
87
+ ...depResult.state,
88
+ cycleNodes,
89
+ },
90
+ }
91
+ }
92
+ return depResult
93
+ },
94
+ { found: false, state: newState }
95
+ )
96
+
97
+ // Remove from recursion stack after processing (immutable way)
98
+ const finalState: DFSState = {
99
+ ...result.state,
100
+ recursionStack: new Set([...result.state.recursionStack].filter((n) => n !== node)),
101
+ }
102
+
103
+ return { found: result.found, state: finalState }
104
+ }
105
+
106
+ // Check all nodes for cycles
107
+ const initialState: DFSState = {
108
+ visited: new Set(),
109
+ recursionStack: new Set(),
110
+ cycleNodes: [],
111
+ }
112
+
113
+ const result = [...dependencyGraph.keys()].reduce<CycleResult>(
114
+ (acc, nodeName) => {
115
+ if (acc.found || acc.state.visited.has(nodeName)) {
116
+ return acc
117
+ }
118
+ return hasCycle(nodeName, acc.state)
119
+ },
120
+ { found: false, state: initialState }
121
+ )
122
+
123
+ return result.state.cycleNodes
124
+ }
@@ -0,0 +1,153 @@
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
+ * Reserved SQL keywords that cannot be used as table or column names
12
+ * Based on PostgreSQL reserved keywords list
13
+ * @see https://www.postgresql.org/docs/current/sql-keywords-appendix.html
14
+ */
15
+ const SQL_RESERVED_KEYWORDS = new Set([
16
+ 'select',
17
+ 'insert',
18
+ 'update',
19
+ 'delete',
20
+ 'from',
21
+ 'where',
22
+ 'join',
23
+ 'inner',
24
+ 'outer',
25
+ 'left',
26
+ 'right',
27
+ 'full',
28
+ 'cross',
29
+ 'on',
30
+ 'as',
31
+ 'table',
32
+ 'create',
33
+ 'alter',
34
+ 'drop',
35
+ 'truncate',
36
+ 'add',
37
+ 'column',
38
+ 'constraint',
39
+ 'primary',
40
+ 'foreign',
41
+ 'key',
42
+ 'references',
43
+ 'unique',
44
+ 'index',
45
+ 'view',
46
+ 'database',
47
+ 'schema',
48
+ 'grant',
49
+ 'revoke',
50
+ 'transaction',
51
+ 'commit',
52
+ 'rollback',
53
+ 'union',
54
+ 'intersect',
55
+ 'except',
56
+ 'group',
57
+ 'having',
58
+ 'order',
59
+ 'limit',
60
+ 'offset',
61
+ 'distinct',
62
+ 'all',
63
+ 'any',
64
+ 'some',
65
+ 'exists',
66
+ 'in',
67
+ 'between',
68
+ 'like',
69
+ 'ilike',
70
+ 'and',
71
+ 'or',
72
+ 'not',
73
+ 'null',
74
+ 'is',
75
+ 'true',
76
+ 'false',
77
+ 'case',
78
+ 'when',
79
+ 'then',
80
+ 'else',
81
+ 'end',
82
+ 'cast',
83
+ 'default',
84
+ 'check',
85
+ 'user',
86
+ 'current_user',
87
+ 'session_user',
88
+ 'current_date',
89
+ 'current_time',
90
+ 'current_timestamp',
91
+ ])
92
+
93
+ /**
94
+ * Database Identifier Validation (Strict - for field names and column names)
95
+ *
96
+ * Shared validation schema for PostgreSQL identifiers (column names, field names, etc.)
97
+ * Must follow database naming conventions: start with a letter, contain only lowercase
98
+ * letters, numbers, and underscores, maximum 63 characters (PostgreSQL limit).
99
+ *
100
+ * This schema is used for field names and column names which must be strict.
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * 'users'
105
+ * 'email_address'
106
+ * 'created_at'
107
+ * ```
108
+ */
109
+ export const createDatabaseIdentifierSchema = (identifierType: 'table' | 'field' | 'column') =>
110
+ identifierType === 'table'
111
+ ? // Table names: Allow user-friendly format (will be sanitized for database)
112
+ Schema.String.pipe(
113
+ Schema.minLength(1, { message: () => 'This field is required' }),
114
+ Schema.maxLength(63, { message: () => 'Maximum length is 63 characters' }),
115
+ Schema.filter((name) => {
116
+ const trimmed = name.trim()
117
+ if (/^\d/.test(trimmed)) {
118
+ return `Invalid table name '${name}': name must start with a letter`
119
+ }
120
+ if (!/^[a-zA-Z][a-zA-Z0-9_\s-]*$/.test(trimmed)) {
121
+ return `Invalid table name '${name}': name must start with a letter and contain only letters, numbers, underscores, hyphens, or spaces`
122
+ }
123
+ return true
124
+ }),
125
+ Schema.filter((name) => {
126
+ const sanitized = name
127
+ .toLowerCase()
128
+ .replace(/[^a-z0-9_]/g, '_')
129
+ .replace(/_+/g, '_')
130
+ .replace(/^_+|_+$/g, '')
131
+ const isReserved = SQL_RESERVED_KEYWORDS.has(sanitized)
132
+ return (
133
+ !isReserved ||
134
+ `Table name '${name}' resolves to reserved SQL keyword '${sanitized}'. Reserved keywords like SELECT, INSERT, UPDATE, DELETE, etc. are restricted to prevent SQL syntax conflicts. Choose a different name.`
135
+ )
136
+ })
137
+ )
138
+ : // Field/column names: Strict database pattern
139
+ Schema.String.pipe(
140
+ Schema.minLength(1, { message: () => 'This field is required' }),
141
+ Schema.maxLength(63, { message: () => 'Maximum length is 63 characters' }),
142
+ Schema.pattern(/^[a-z][a-z0-9_]*$/, {
143
+ message: () =>
144
+ `Invalid ${identifierType} name pattern. Must follow database naming conventions: start with a letter, contain only lowercase letters, numbers, and underscores, maximum 63 characters (PostgreSQL limit). This name is used in SQL queries, API endpoints, and code generation. Choose descriptive names that clearly indicate the purpose (e.g., "email_address" not "ea").`,
145
+ }),
146
+ Schema.filter((name) => {
147
+ const isReserved = SQL_RESERVED_KEYWORDS.has(name.toLowerCase())
148
+ return (
149
+ !isReserved ||
150
+ `Cannot use reserved SQL keyword '${name}' as ${identifierType} name. Reserved keywords like SELECT, INSERT, UPDATE, DELETE, etc. are restricted to prevent SQL syntax conflicts. Choose a descriptive alternative name (e.g., 'user_record' instead of 'user', 'selection' instead of 'select').`
151
+ )
152
+ })
153
+ )