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,201 @@
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
+ * Common Schema.org field definitions
12
+ *
13
+ * This module provides reusable field definitions that are shared across multiple
14
+ * structured data schemas. Using these common fields ensures consistency in:
15
+ * - Validation rules (e.g., email format, URI format)
16
+ * - Annotations (descriptions, formats)
17
+ * - Type definitions
18
+ *
19
+ * Benefits:
20
+ * - **DRY principle**: Single source of truth for common field patterns
21
+ * - **Consistency**: Same validation rules across all schemas
22
+ * - **Maintainability**: Update field definition in one place
23
+ * - **Type safety**: Reusable schema types
24
+ *
25
+ * Usage:
26
+ * ```typescript
27
+ * import { SchemaOrgContext, SchemaOrgEmail, SchemaOrgTelephone } from './common-fields'
28
+ *
29
+ * export const PersonSchema = Schema.Struct({
30
+ * '@context': SchemaOrgContext,
31
+ * email: Schema.optional(SchemaOrgEmail),
32
+ * telephone: Schema.optional(SchemaOrgTelephone),
33
+ * // ... other fields
34
+ * })
35
+ * ```
36
+ */
37
+
38
+ /**
39
+ * Schema.org @context field
40
+ *
41
+ * Required in all Schema.org structured data to indicate the vocabulary being used.
42
+ * Always set to "https://schema.org" for Schema.org compliance.
43
+ *
44
+ * Used in: Person, Organization, LocalBusiness, Product, Article, Breadcrumb, FAQPage, EducationEvent
45
+ */
46
+ export const SchemaOrgContext = Schema.Literal('https://schema.org').annotations({
47
+ description: 'Schema.org context',
48
+ })
49
+
50
+ /**
51
+ * Email address field
52
+ *
53
+ * Validates email format according to RFC 5322.
54
+ * Used for contact information in Person, Organization, and LocalBusiness schemas.
55
+ *
56
+ * Used in: Person, Organization, LocalBusiness
57
+ */
58
+ export const SchemaOrgEmail = Schema.String.annotations({
59
+ description: 'Email address',
60
+ format: 'email',
61
+ })
62
+
63
+ /**
64
+ * Telephone number field
65
+ *
66
+ * Stores telephone number as a string to support international formats.
67
+ * No format validation to allow flexibility (e.g., +1-555-123-4567, (555) 123-4567, etc.)
68
+ *
69
+ * Used in: Person, Organization, LocalBusiness
70
+ */
71
+ export const SchemaOrgTelephone = Schema.String.annotations({
72
+ description: 'Phone number',
73
+ })
74
+
75
+ /**
76
+ * Array of social media profile URLs
77
+ *
78
+ * The "sameAs" property links an entity to its social media profiles for verification.
79
+ * Each URL should be a valid URI pointing to an official social media account.
80
+ *
81
+ * Common platforms: Twitter, LinkedIn, Facebook, GitHub, Instagram, YouTube
82
+ *
83
+ * SEO impact:
84
+ * - Verifies entity's online identity across platforms
85
+ * - Helps search engines understand the entity's social presence
86
+ * - May appear in Knowledge Graph panels
87
+ *
88
+ * Used in: Person, Organization, LocalBusiness
89
+ */
90
+ export const SchemaOrgSameAs = Schema.Array(
91
+ Schema.String.annotations({
92
+ description: 'Social media profile URL',
93
+ format: 'uri',
94
+ })
95
+ ).annotations({
96
+ description: 'Social media profile URLs',
97
+ examples: [
98
+ [
99
+ 'https://twitter.com/example',
100
+ 'https://linkedin.com/in/example',
101
+ 'https://facebook.com/example',
102
+ ],
103
+ ],
104
+ })
105
+
106
+ /**
107
+ * URL field for web resources
108
+ *
109
+ * Validates URI format and is used for various web resource references:
110
+ * - Personal/organization website
111
+ * - Product pages
112
+ * - Profile URLs
113
+ * - Image URLs
114
+ *
115
+ * Used in: Person, Organization, LocalBusiness, Product, Article
116
+ */
117
+ export const SchemaOrgUrl = Schema.String.annotations({
118
+ description: 'URL',
119
+ format: 'uri',
120
+ })
121
+
122
+ /**
123
+ * Image URL field
124
+ *
125
+ * URL to an image resource (JPEG, PNG, WebP, etc.).
126
+ * Used for photos, logos, product images, etc.
127
+ *
128
+ * SEO impact:
129
+ * - Displayed in search result cards
130
+ * - Shown in Knowledge Graph panels
131
+ * - Used in rich results (products, articles, etc.)
132
+ *
133
+ * Used in: Person, Organization, LocalBusiness, Product, Article
134
+ */
135
+ export const SchemaOrgImageUrl = Schema.String.annotations({
136
+ description: 'Image URL',
137
+ format: 'uri',
138
+ })
139
+
140
+ /**
141
+ * Helper: Create optional field
142
+ *
143
+ * Utility function to wrap a schema in Schema.optional() while preserving type inference.
144
+ * Reduces boilerplate when defining optional fields.
145
+ *
146
+ * @example
147
+ * ```typescript
148
+ * // Instead of:
149
+ * email: Schema.optional(SchemaOrgEmail),
150
+ *
151
+ * // You can use:
152
+ * email: optional(SchemaOrgEmail),
153
+ * ```
154
+ */
155
+ export const optional = <A, I, R>(schema: Schema.Schema<A, I, R>) => Schema.optional(schema)
156
+
157
+ /**
158
+ * Helper: Create Schema.org @type field
159
+ *
160
+ * Creates a Schema.Literal for Schema.org @type fields with standard annotation.
161
+ * Reduces duplication across all structured data schemas.
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * // Instead of:
166
+ * '@type': Schema.Literal('Person').annotations({ description: 'Schema.org type' }),
167
+ *
168
+ * // You can use:
169
+ * '@type': schemaType('Person'),
170
+ * ```
171
+ *
172
+ * Used in: Person, Organization, LocalBusiness, Product, Article, Breadcrumb, FAQPage, EducationEvent
173
+ */
174
+ export const schemaType = <T extends string>(type: T) =>
175
+ Schema.Literal(type).annotations({
176
+ description: 'Schema.org type',
177
+ })
178
+
179
+ /**
180
+ * Helper: Create positive integer field
181
+ *
182
+ * Creates a Schema.Int with a minimum value of 1, commonly used for:
183
+ * - Breadcrumb positions (1-indexed)
184
+ * - Review counts
185
+ * - Any count or index that must be positive
186
+ *
187
+ * @example
188
+ * ```typescript
189
+ * // Instead of:
190
+ * position: Schema.Int.pipe(Schema.greaterThanOrEqualTo(1)).annotations({ description: 'Position' }),
191
+ *
192
+ * // You can use:
193
+ * position: positiveInt('Position'),
194
+ * ```
195
+ *
196
+ * Used in: BreadcrumbListItem (position), AggregateRating (reviewCount)
197
+ */
198
+ export const positiveInt = (description: string) =>
199
+ Schema.Int.pipe(Schema.greaterThanOrEqualTo(1)).annotations({
200
+ description,
201
+ })
@@ -0,0 +1,256 @@
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 { positiveInt, schemaType } from './common-fields'
10
+ import { PostalAddressSchema } from './postal-address'
11
+ import { CurrencyCodeSchema } from './product'
12
+
13
+ /**
14
+ * Event attendance mode
15
+ *
16
+ * 3 attendance modes for events:
17
+ * - OfflineEventAttendanceMode: In-person event at physical location
18
+ * - OnlineEventAttendanceMode: Virtual/online event (Zoom, livestream)
19
+ * - MixedEventAttendanceMode: Hybrid event (both in-person and online)
20
+ */
21
+ export const EventAttendanceModeSchema = Schema.Literal(
22
+ 'https://schema.org/OfflineEventAttendanceMode',
23
+ 'https://schema.org/OnlineEventAttendanceMode',
24
+ 'https://schema.org/MixedEventAttendanceMode'
25
+ ).annotations({
26
+ description: 'Event attendance mode',
27
+ })
28
+
29
+ /**
30
+ * Event status
31
+ *
32
+ * 4 event statuses:
33
+ * - EventScheduled: Event is scheduled and happening as planned
34
+ * - EventCancelled: Event has been cancelled
35
+ * - EventPostponed: Event postponed to later date (TBD)
36
+ * - EventRescheduled: Event rescheduled to specific new date
37
+ */
38
+ export const EventStatusSchema = Schema.Literal(
39
+ 'https://schema.org/EventScheduled',
40
+ 'https://schema.org/EventCancelled',
41
+ 'https://schema.org/EventPostponed',
42
+ 'https://schema.org/EventRescheduled'
43
+ ).annotations({
44
+ description: 'Event status',
45
+ })
46
+
47
+ /**
48
+ * Event location (Place)
49
+ *
50
+ * Physical location for in-person or hybrid events.
51
+ * - @type: "Place"
52
+ * - name: Venue name (e.g., "Convention Center", "Library Hall")
53
+ * - address: Venue address (PostalAddress object)
54
+ */
55
+ export const EventLocationSchema = Schema.Struct({
56
+ '@type': schemaType('Place'),
57
+ name: Schema.optional(
58
+ Schema.String.annotations({
59
+ description: 'Venue name',
60
+ })
61
+ ),
62
+ address: Schema.optional(PostalAddressSchema),
63
+ }).annotations({
64
+ description: 'Event location',
65
+ })
66
+
67
+ /**
68
+ * Event organizer
69
+ *
70
+ * Organization or Person organizing the event.
71
+ * - @type: "Organization" or "Person"
72
+ * - name: Organizer name
73
+ * - url: Organizer website/profile URL
74
+ */
75
+ export const EventOrganizerSchema = Schema.Struct({
76
+ '@type': Schema.Literal('Organization', 'Person').annotations({
77
+ description: 'Organizer type',
78
+ }),
79
+ name: Schema.optional(
80
+ Schema.String.annotations({
81
+ description: 'Organizer name',
82
+ })
83
+ ),
84
+ url: Schema.optional(
85
+ Schema.String.annotations({
86
+ description: 'Organizer URL',
87
+ format: 'uri',
88
+ })
89
+ ),
90
+ }).annotations({
91
+ description: 'Event organizer',
92
+ })
93
+
94
+ /**
95
+ * Ticket availability status
96
+ *
97
+ * 4 availability statuses for event tickets:
98
+ * - InStock: Tickets available
99
+ * - OutOfStock: Sold out (temporarily)
100
+ * - PreOrder: Tickets available for pre-order
101
+ * - SoldOut: Permanently sold out
102
+ */
103
+ export const TicketAvailabilitySchema = Schema.Literal(
104
+ 'https://schema.org/InStock',
105
+ 'https://schema.org/OutOfStock',
106
+ 'https://schema.org/PreOrder',
107
+ 'https://schema.org/SoldOut'
108
+ ).annotations({
109
+ description: 'Ticket availability status',
110
+ })
111
+
112
+ /**
113
+ * Event ticket offer
114
+ *
115
+ * Pricing and availability for event tickets.
116
+ * - @type: "Offer"
117
+ * - price: Ticket price (string or number, "0" for free events)
118
+ * - priceCurrency: ISO 4217 currency code (e.g., "USD", "EUR")
119
+ * - availability: Stock status (InStock, OutOfStock, PreOrder, SoldOut)
120
+ * - url: URL to ticket purchase page
121
+ */
122
+ export const EventOfferSchema = Schema.Struct({
123
+ '@type': schemaType('Offer'),
124
+ price: Schema.optional(
125
+ Schema.Union(Schema.String, Schema.Number).annotations({
126
+ description: 'Ticket price',
127
+ })
128
+ ),
129
+ priceCurrency: Schema.optional(CurrencyCodeSchema),
130
+ availability: Schema.optional(TicketAvailabilitySchema),
131
+ url: Schema.optional(
132
+ Schema.String.annotations({
133
+ description: 'Ticket purchase URL',
134
+ format: 'uri',
135
+ })
136
+ ),
137
+ }).annotations({
138
+ description: 'Event ticket offer',
139
+ })
140
+
141
+ /**
142
+ * Schema.org EducationEvent structured data
143
+ *
144
+ * Represents educational events (workshops, courses, training, seminars) for rich results
145
+ * in Google Search and Google Maps. Enables event cards with dates, location, pricing,
146
+ * and registration directly in search results.
147
+ *
148
+ * Required properties:
149
+ * - @type: "EducationEvent" (Schema.org type identifier)
150
+ * - name: Event name (e.g., "React Masterclass", "Photography Workshop")
151
+ * - startDate: Event start date/time (ISO 8601 format)
152
+ *
153
+ * Optional properties:
154
+ * - description: Event description
155
+ * - endDate: Event end date/time (ISO 8601 format)
156
+ * - eventAttendanceMode: In-person, online, or hybrid
157
+ * - eventStatus: Scheduled, cancelled, postponed, or rescheduled
158
+ * - location: Event venue (Place object with name and address)
159
+ * - organizer: Event organizer (Organization or Person)
160
+ * - offers: Ticket pricing (Offer object with price, currency, availability, URL)
161
+ * - maximumAttendeeCapacity: Maximum number of attendees
162
+ * - minimumAttendeeCapacity: Minimum number of attendees
163
+ *
164
+ * Common use cases:
165
+ * - **Workshops**: Hands-on training sessions (e.g., "3-hour React Workshop")
166
+ * - **Courses**: Educational courses (e.g., "8-week Python Bootcamp")
167
+ * - **Seminars**: Lecture-style events (e.g., "AI in Healthcare Seminar")
168
+ * - **Webinars**: Online educational events (eventAttendanceMode: OnlineEventAttendanceMode)
169
+ * - **Hybrid events**: Both in-person and online (eventAttendanceMode: MixedEventAttendanceMode)
170
+ *
171
+ * SEO impact:
172
+ * - **Event rich results**: Cards with date, time, location, price in search
173
+ * - **Google Maps**: Events appear in Google Maps for local discovery
174
+ * - **Event discovery**: Appears in Google's event discovery features
175
+ * - **Calendar integration**: "Add to calendar" button in search results
176
+ * - **Mobile optimization**: One-tap registration, directions, calendar add
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * const educationEvent = {
181
+ * "@type": "EducationEvent",
182
+ * name: "React Masterclass Workshop",
183
+ * description: "Learn advanced React patterns with hands-on exercises",
184
+ * startDate: "2025-02-15T14:00:00-05:00",
185
+ * endDate: "2025-02-15T17:00:00-05:00",
186
+ * eventAttendanceMode: "https://schema.org/MixedEventAttendanceMode",
187
+ * eventStatus: "https://schema.org/EventScheduled",
188
+ * location: {
189
+ * "@type": "Place",
190
+ * name: "Tech Hub Conference Center",
191
+ * address: {
192
+ * "@type": "PostalAddress",
193
+ * streetAddress: "123 Innovation Dr",
194
+ * addressLocality: "San Francisco",
195
+ * addressRegion: "CA",
196
+ * postalCode: "94105",
197
+ * addressCountry: "US"
198
+ * }
199
+ * },
200
+ * organizer: {
201
+ * "@type": "Organization",
202
+ * name: "React Academy",
203
+ * url: "https://reactacademy.com"
204
+ * },
205
+ * offers: {
206
+ * "@type": "Offer",
207
+ * price: "149.00",
208
+ * priceCurrency: "USD",
209
+ * availability: "https://schema.org/InStock",
210
+ * url: "https://reactacademy.com/workshops/react-masterclass"
211
+ * },
212
+ * maximumAttendeeCapacity: 30
213
+ * }
214
+ * ```
215
+ *
216
+ * @see specs/app/pages/meta/structured-data/education-event.schema.json
217
+ */
218
+ export const EducationEventSchema = Schema.Struct({
219
+ '@type': schemaType('EducationEvent'),
220
+ name: Schema.String.annotations({
221
+ description: 'Event name',
222
+ }),
223
+ description: Schema.optional(
224
+ Schema.String.annotations({
225
+ description: 'Event description',
226
+ })
227
+ ),
228
+ startDate: Schema.String.annotations({
229
+ description: 'Event start date/time (ISO 8601)',
230
+ format: 'date-time',
231
+ }),
232
+ endDate: Schema.optional(
233
+ Schema.String.annotations({
234
+ description: 'Event end date/time (ISO 8601)',
235
+ format: 'date-time',
236
+ })
237
+ ),
238
+ eventAttendanceMode: Schema.optional(EventAttendanceModeSchema),
239
+ eventStatus: Schema.optional(EventStatusSchema),
240
+ location: Schema.optional(EventLocationSchema),
241
+ organizer: Schema.optional(EventOrganizerSchema),
242
+ offers: Schema.optional(EventOfferSchema),
243
+ maximumAttendeeCapacity: Schema.optional(positiveInt('Maximum number of attendees')),
244
+ minimumAttendeeCapacity: Schema.optional(positiveInt('Minimum number of attendees')),
245
+ }).annotations({
246
+ title: 'Education Event Schema',
247
+ description: 'Schema.org EducationEvent structured data',
248
+ })
249
+
250
+ export type EventAttendanceMode = Schema.Schema.Type<typeof EventAttendanceModeSchema>
251
+ export type EventStatus = Schema.Schema.Type<typeof EventStatusSchema>
252
+ export type EventLocation = Schema.Schema.Type<typeof EventLocationSchema>
253
+ export type EventOrganizer = Schema.Schema.Type<typeof EventOrganizerSchema>
254
+ export type TicketAvailability = Schema.Schema.Type<typeof TicketAvailabilitySchema>
255
+ export type EventOffer = Schema.Schema.Type<typeof EventOfferSchema>
256
+ export type EducationEvent = Schema.Schema.Type<typeof EducationEventSchema>
@@ -0,0 +1,127 @@
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 { SchemaOrgContext, schemaType } from './common-fields'
10
+
11
+ /**
12
+ * FAQ answer
13
+ *
14
+ * Represents the accepted answer to a question.
15
+ *
16
+ * Required properties:
17
+ * - @type: "Answer" (Schema.org type identifier)
18
+ * - text: The answer text/content
19
+ */
20
+ export const FaqAnswerSchema = Schema.Struct({
21
+ '@type': schemaType('Answer'),
22
+ text: Schema.String.annotations({
23
+ description: 'The answer text',
24
+ }),
25
+ }).annotations({
26
+ description: 'FAQ answer',
27
+ })
28
+
29
+ /**
30
+ * FAQ question with accepted answer
31
+ *
32
+ * Represents a single question-answer pair in an FAQ.
33
+ *
34
+ * Required properties:
35
+ * - @type: "Question" (Schema.org type identifier)
36
+ * - name: The question text
37
+ * - acceptedAnswer: The answer object (Answer type with text)
38
+ */
39
+ export const FaqQuestionSchema = Schema.Struct({
40
+ '@type': schemaType('Question'),
41
+ name: Schema.String.annotations({
42
+ description: 'The question text',
43
+ }),
44
+ acceptedAnswer: FaqAnswerSchema,
45
+ }).annotations({
46
+ description: 'FAQ question',
47
+ })
48
+
49
+ /**
50
+ * Schema.org FAQPage structured data
51
+ *
52
+ * Represents a Frequently Asked Questions page with a list of question-answer pairs.
53
+ * Enables expandable Q&A rich results in Google search, dramatically increasing
54
+ * visibility and click-through rates.
55
+ *
56
+ * Required properties:
57
+ * - @context: "https://schema.org" (Schema.org vocabulary)
58
+ * - @type: "FAQPage" (Schema.org type identifier)
59
+ * - mainEntity: Array of Question objects (each with name and acceptedAnswer)
60
+ *
61
+ * Question structure:
62
+ * - Each question has @type "Question", name (question text), acceptedAnswer
63
+ * - Each acceptedAnswer has @type "Answer", text (answer content)
64
+ * - Questions can include HTML in answer text for formatting (lists, bold, links)
65
+ *
66
+ * Best practices:
67
+ * - **5-10 questions**: Optimal number for comprehensive FAQ
68
+ * - **Concise questions**: Clear, direct questions users would ask
69
+ * - **Detailed answers**: Complete answers that satisfy user intent
70
+ * - **Natural language**: Write questions as users would ask them
71
+ * - **Avoid promotional content**: Focus on answering questions, not selling
72
+ *
73
+ * SEO impact:
74
+ * - **Rich results**: Expandable Q&A boxes in Google search results
75
+ * - **SERP visibility**: Takes up more screen space (higher CTR)
76
+ * - **Answer surfacing**: Users see answers without clicking through
77
+ * - **Featured snippets**: FAQ answers can appear in featured snippets
78
+ * - **Voice search**: Answers optimized for voice search queries
79
+ * - **Support reduction**: Answers in search reduce support ticket volume
80
+ *
81
+ * Google display:
82
+ * - Questions appear as expandable boxes in search results
83
+ * - Users can expand/collapse answers directly in search
84
+ * - Clicking question takes user to FAQ page with answer highlighted
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * const faqPage = {
89
+ * "@context": "https://schema.org",
90
+ * "@type": "FAQPage",
91
+ * mainEntity: [
92
+ * {
93
+ * "@type": "Question",
94
+ * name: "What is the refund policy?",
95
+ * acceptedAnswer: {
96
+ * "@type": "Answer",
97
+ * text: "We offer a 30-day money-back guarantee on all purchases."
98
+ * }
99
+ * },
100
+ * {
101
+ * "@type": "Question",
102
+ * name: "How long does shipping take?",
103
+ * acceptedAnswer: {
104
+ * "@type": "Answer",
105
+ * text: "Standard shipping takes 5-7 business days. Express shipping takes 2-3 business days."
106
+ * }
107
+ * }
108
+ * ]
109
+ * }
110
+ * ```
111
+ *
112
+ * @see specs/app/pages/meta/structured-data/faq-page.schema.json
113
+ */
114
+ export const FaqPageSchema = Schema.Struct({
115
+ '@context': SchemaOrgContext,
116
+ '@type': schemaType('FAQPage'),
117
+ mainEntity: Schema.Array(FaqQuestionSchema).annotations({
118
+ description: 'Array of questions and answers',
119
+ }),
120
+ }).annotations({
121
+ title: 'FAQ Page Schema',
122
+ description: 'Schema.org FAQPage structured data',
123
+ })
124
+
125
+ export type FaqAnswer = Schema.Schema.Type<typeof FaqAnswerSchema>
126
+ export type FaqQuestion = Schema.Schema.Type<typeof FaqQuestionSchema>
127
+ export type FaqPage = Schema.Schema.Type<typeof FaqPageSchema>
@@ -0,0 +1,95 @@
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 { ArticleSchema } from './article'
10
+ import { BreadcrumbSchema } from './breadcrumb'
11
+ import { EducationEventSchema } from './education-event'
12
+ import { FaqPageSchema } from './faq-page'
13
+ import { LocalBusinessSchema } from './local-business'
14
+ import { OrganizationSchema } from './organization'
15
+ import { PersonSchema } from './person'
16
+ import { ProductSchema } from './product'
17
+
18
+ /**
19
+ * Schema.org structured data for search engine understanding
20
+ *
21
+ * Orchestrator schema that combines all 8 structured data types into a single configuration.
22
+ * Each property is optional, allowing pages to include only the relevant structured data types.
23
+ *
24
+ * Available structured data types:
25
+ * - **organization**: Company/organization information for Knowledge Graph
26
+ * - **person**: Individual person profiles for author attribution
27
+ * - **localBusiness**: Local business for maps and local SEO
28
+ * - **product**: E-commerce products for shopping rich results
29
+ * - **article**: Articles/blog posts for content rich results
30
+ * - **breadcrumb**: Navigation hierarchy for breadcrumb trails
31
+ * - **faqPage**: FAQ pages for Q&A rich results
32
+ * - **educationEvent**: Educational events for event discovery
33
+ *
34
+ * Usage patterns:
35
+ * - **Homepage**: organization (company info in Knowledge Graph)
36
+ * - **About page**: organization + person (company + team members)
37
+ * - **Blog post**: article + breadcrumb + person (content with navigation and author)
38
+ * - **Product page**: product + breadcrumb (e-commerce with navigation)
39
+ * - **FAQ page**: faqPage + breadcrumb (Q&A with navigation)
40
+ * - **Event page**: educationEvent + breadcrumb (event with navigation)
41
+ * - **Local business**: localBusiness + organization (location + company info)
42
+ *
43
+ * SEO impact:
44
+ * - **Rich results**: Enables rich snippets in Google search results
45
+ * - **Knowledge Graph**: Company/person information panels
46
+ * - **Maps integration**: Local business map pins and directions
47
+ * - **Event discovery**: Events in Google Search and Google Maps
48
+ * - **E-commerce**: Product cards with pricing and ratings
49
+ * - **Navigation**: Breadcrumb trails replace URLs in search results
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * const structuredData = {
54
+ * organization: {
55
+ * "@context": "https://schema.org",
56
+ * "@type": "Organization",
57
+ * name: "Acme Inc",
58
+ * url: "https://acme.com"
59
+ * },
60
+ * breadcrumb: {
61
+ * "@context": "https://schema.org",
62
+ * "@type": "BreadcrumbList",
63
+ * itemListElement: [...]
64
+ * }
65
+ * }
66
+ * ```
67
+ *
68
+ * @see specs/app/pages/meta/structured-data/structured-data.schema.json
69
+ */
70
+ export const StructuredDataSchema = Schema.Struct({
71
+ organization: Schema.optional(OrganizationSchema),
72
+ person: Schema.optional(PersonSchema),
73
+ localBusiness: Schema.optional(LocalBusinessSchema),
74
+ product: Schema.optional(ProductSchema),
75
+ article: Schema.optional(ArticleSchema),
76
+ breadcrumb: Schema.optional(BreadcrumbSchema),
77
+ faqPage: Schema.optional(FaqPageSchema),
78
+ educationEvent: Schema.optional(EducationEventSchema),
79
+ }).annotations({
80
+ title: 'Structured Data',
81
+ description: 'Schema.org structured data for search engine understanding',
82
+ })
83
+
84
+ export type StructuredData = Schema.Schema.Type<typeof StructuredDataSchema>
85
+
86
+ // Re-export all structured data schemas for convenience
87
+ export * from './postal-address'
88
+ export * from './person'
89
+ export * from './breadcrumb'
90
+ export * from './faq-page'
91
+ export * from './article'
92
+ export * from './organization'
93
+ export * from './local-business'
94
+ export * from './product'
95
+ export * from './education-event'