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,166 @@
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 { HttpUrlSchema } from '../common/url'
10
+
11
+ /**
12
+ * Open Graph content type
13
+ *
14
+ * 6 standard Open Graph types for different content:
15
+ * - website: General websites, landing pages (most common, default)
16
+ * - article: Blog posts, news articles (adds publish date, author metadata)
17
+ * - book: Book pages, publications
18
+ * - profile: Personal or company profiles
19
+ * - video: Video content pages (enables video embeds in social feeds)
20
+ * - music: Music content, albums (enables audio players)
21
+ */
22
+ export const OpenGraphTypeSchema = Schema.Literal(
23
+ 'website',
24
+ 'article',
25
+ 'book',
26
+ 'profile',
27
+ 'video',
28
+ 'music'
29
+ ).annotations({
30
+ description: 'Open Graph object type',
31
+ })
32
+
33
+ /**
34
+ * Open Graph locale format
35
+ *
36
+ * Language and territory format: [language]_[TERRITORY]
37
+ * - Pattern: ^[a-z]{2}_[A-Z]{2}$ (2 lowercase + underscore + 2 uppercase)
38
+ * - Examples: en_US (English, United States), fr_FR (French, France), es_ES (Spanish, Spain)
39
+ * - Helps platforms show content to the right audience based on language/region
40
+ */
41
+ export const OpenGraphLocaleSchema = Schema.String.pipe(
42
+ Schema.pattern(/^[a-z]{2}_[A-Z]{2}$/, {
43
+ message: () =>
44
+ 'Locale must be in format language_TERRITORY (e.g., en_US, fr_FR, es_ES, de_DE, ja_JP)',
45
+ })
46
+ ).annotations({
47
+ description: 'Locale in format language_TERRITORY',
48
+ examples: ['en_US', 'fr_FR', 'es_ES'],
49
+ })
50
+
51
+ /**
52
+ * Open Graph determiner
53
+ *
54
+ * Grammatical article that appears before the title in share messages.
55
+ * Used in: "John shared [determiner] [title]"
56
+ *
57
+ * 5 options:
58
+ * - 'a': "Share a Website Builder"
59
+ * - 'an': "Share an Amazing Product"
60
+ * - 'the': "Share the Ultimate Guide to SEO"
61
+ * - 'auto': Platform decides based on title (no article)
62
+ * - '': Empty string (no article)
63
+ *
64
+ * Improves grammar in social sharing messages for better user experience.
65
+ */
66
+ export const OpenGraphDeterminerSchema = Schema.Literal('a', 'an', 'the', 'auto', '').annotations({
67
+ description: 'Word that appears before the title',
68
+ })
69
+
70
+ /**
71
+ * Open Graph protocol metadata for rich social media sharing
72
+ *
73
+ * Defines how pages appear when shared on Facebook, LinkedIn, and other platforms
74
+ * supporting the Open Graph protocol. Creates rich preview cards with images, titles,
75
+ * and descriptions to dramatically increase engagement and click-through rates.
76
+ *
77
+ * Required properties:
78
+ * - title: Page title for social sharing (max 90 chars, shorter than page <title>)
79
+ * - description: Page description (max 200 chars, concise value proposition)
80
+ * - type: Content type (website, article, book, profile, video, music)
81
+ * - url: Canonical URL for this page (absolute URL)
82
+ *
83
+ * Optional properties:
84
+ * - image: Social sharing image URL (recommended: 1200x630px, 1.91:1 aspect ratio)
85
+ * - imageAlt: Alternative text for the image (accessibility, screen readers)
86
+ * - siteName: Overall website/brand name (different from page title)
87
+ * - locale: Content language/territory (en_US, fr_FR, etc.)
88
+ * - determiner: Grammatical article before title (a, an, the, auto, "")
89
+ * - video: Video URL for video content (enables video embeds in feeds)
90
+ * - audio: Audio URL for audio content (enables audio players)
91
+ *
92
+ * Impact:
93
+ * - Rich cards get 2-3x more clicks than plain links
94
+ * - Image is most important element (grabs attention)
95
+ * - Without OG tags: generic unfurl with no image (low engagement)
96
+ * - Complete OG tags: professional social presence
97
+ *
98
+ * @example
99
+ * ```typescript
100
+ * const openGraph = {
101
+ * title: 'Transform Your Business with AI-Powered Analytics',
102
+ * description: 'Get real-time insights, automated reporting, and predictive analytics. Start free trial.',
103
+ * type: 'website',
104
+ * url: 'https://example.com/product',
105
+ * image: 'https://example.com/og-image-1200x630.jpg',
106
+ * imageAlt: 'Dashboard screenshot showing analytics graphs',
107
+ * siteName: 'Acme Analytics',
108
+ * locale: 'en_US'
109
+ * }
110
+ * ```
111
+ *
112
+ * @see specs/app/pages/meta/social/open-graph.schema.json
113
+ */
114
+ export const OpenGraphSchema = Schema.Struct({
115
+ title: Schema.optional(
116
+ Schema.String.pipe(Schema.maxLength(90)).annotations({
117
+ description: 'Open Graph title (may differ from page title)',
118
+ })
119
+ ),
120
+ description: Schema.optional(
121
+ Schema.String.pipe(Schema.maxLength(200)).annotations({
122
+ description: 'Open Graph description',
123
+ })
124
+ ),
125
+ type: Schema.optional(OpenGraphTypeSchema),
126
+ url: Schema.optional(
127
+ HttpUrlSchema.annotations({
128
+ description: 'Canonical URL for this page',
129
+ })
130
+ ),
131
+ image: Schema.optional(
132
+ HttpUrlSchema.annotations({
133
+ description: 'Image URL for social sharing (recommended: 1200x630px)',
134
+ })
135
+ ),
136
+ imageAlt: Schema.optional(
137
+ Schema.String.annotations({
138
+ description: 'Alternative text for the Open Graph image',
139
+ })
140
+ ),
141
+ siteName: Schema.optional(
142
+ Schema.String.annotations({
143
+ description: 'Name of the overall website',
144
+ })
145
+ ),
146
+ locale: Schema.optional(OpenGraphLocaleSchema),
147
+ determiner: Schema.optional(OpenGraphDeterminerSchema),
148
+ video: Schema.optional(
149
+ HttpUrlSchema.annotations({
150
+ description: 'Video URL if sharing video content',
151
+ })
152
+ ),
153
+ audio: Schema.optional(
154
+ HttpUrlSchema.annotations({
155
+ description: 'Audio URL if sharing audio content',
156
+ })
157
+ ),
158
+ }).annotations({
159
+ title: 'Open Graph Metadata',
160
+ description: 'Open Graph protocol metadata for rich social media sharing',
161
+ })
162
+
163
+ export type OpenGraphType = Schema.Schema.Type<typeof OpenGraphTypeSchema>
164
+ export type OpenGraphLocale = Schema.Schema.Type<typeof OpenGraphLocaleSchema>
165
+ export type OpenGraphDeterminer = Schema.Schema.Type<typeof OpenGraphDeterminerSchema>
166
+ export type OpenGraph = Schema.Schema.Type<typeof OpenGraphSchema>
@@ -0,0 +1,190 @@
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 type hint for preloading
12
+ *
13
+ * 8 standard resource types for <link rel="preload" as="...">:
14
+ * - style: CSS stylesheets (critical CSS for above-the-fold content)
15
+ * - script: JavaScript files (critical scripts needed for initial render)
16
+ * - font: Web fonts (WOFF2, WOFF, TTF) - requires crossorigin attribute
17
+ * - image: Images (hero images, above-the-fold images)
18
+ * - video: Video files
19
+ * - audio: Audio files
20
+ * - document: HTML documents (iframes, embeds)
21
+ * - fetch: API data (XHR, Fetch API responses) - prefetch critical API data
22
+ */
23
+ export const PreloadResourceTypeSchema = Schema.Literal(
24
+ 'style',
25
+ 'script',
26
+ 'font',
27
+ 'image',
28
+ 'video',
29
+ 'audio',
30
+ 'document',
31
+ 'fetch'
32
+ ).annotations({
33
+ description: 'Resource type hint',
34
+ })
35
+
36
+ /**
37
+ * CORS setting for preloaded resources
38
+ *
39
+ * 3 options:
40
+ * - true: Anonymous CORS (no credentials) - most common for fonts
41
+ * - false: No CORS (same-origin)
42
+ * - 'anonymous': Explicit anonymous CORS (same as true)
43
+ * - 'use-credentials': CORS with credentials (cookies, auth)
44
+ *
45
+ * Important for fonts:
46
+ * - Web fonts MUST have crossorigin attribute (even from same origin)
47
+ * - Without crossorigin: font downloads twice (preload + actual request)
48
+ * - With crossorigin: font downloads once (preload is reused)
49
+ */
50
+ export const PreloadCrossOriginSchema = Schema.Union(
51
+ Schema.Boolean,
52
+ Schema.Literal('anonymous', 'use-credentials')
53
+ ).annotations({
54
+ description: 'CORS setting for the resource',
55
+ })
56
+
57
+ /**
58
+ * Preload resource configuration
59
+ *
60
+ * Defines a single resource to preload early in page load for performance optimization.
61
+ *
62
+ * Required properties:
63
+ * - href: Resource URL to preload (absolute or relative path)
64
+ * - as: Resource type hint (style, script, font, image, video, audio, document, fetch)
65
+ *
66
+ * Optional properties:
67
+ * - type: MIME type (font/woff2, image/webp, text/css, etc.) - helps browser prioritize
68
+ * - crossorigin: CORS setting (true/false/'anonymous'/'use-credentials') - required for fonts
69
+ * - media: Media query for conditional loading (e.g., "(min-width: 768px)")
70
+ *
71
+ * Common preload patterns:
72
+ * 1. **Critical CSS**: Preload main stylesheet for faster first paint
73
+ * ```typescript
74
+ * { href: './output.css', as: 'style' }
75
+ * ```
76
+ *
77
+ * 2. **Web fonts**: Preload fonts used above-the-fold (crossorigin required!)
78
+ * ```typescript
79
+ * { href: './fonts/MyFont.woff2', as: 'font', type: 'font/woff2', crossorigin: true }
80
+ * ```
81
+ *
82
+ * 3. **Hero images**: Preload above-the-fold images for faster LCP
83
+ * ```typescript
84
+ * { href: './hero.jpg', as: 'image', type: 'image/jpeg' }
85
+ * ```
86
+ *
87
+ * 4. **Critical API data**: Prefetch data needed for initial render
88
+ * ```typescript
89
+ * { href: '/api/posts', as: 'fetch', crossorigin: 'use-credentials' }
90
+ * ```
91
+ *
92
+ * 5. **Responsive images**: Preload images conditionally based on screen size
93
+ * ```typescript
94
+ * { href: './hero-mobile.jpg', as: 'image', media: '(max-width: 767px)' }
95
+ * ```
96
+ *
97
+ * Performance impact:
98
+ * - Preload critical resources before parser discovers them
99
+ * - Reduces time to First Contentful Paint (FCP) by 200-500ms
100
+ * - Reduces Largest Contentful Paint (LCP) by 300-800ms (hero images, fonts)
101
+ * - Improves Core Web Vitals (FCP, LCP, CLS)
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * const preloadItem = {
106
+ * href: './fonts/Inter.woff2',
107
+ * as: 'font',
108
+ * type: 'font/woff2',
109
+ * crossorigin: true
110
+ * }
111
+ * ```
112
+ *
113
+ * @see specs/app/pages/meta/performance/preload.schema.json
114
+ */
115
+ export const PreloadItemSchema = Schema.Struct({
116
+ href: Schema.String.annotations({
117
+ description: 'Resource URL to preload',
118
+ }),
119
+ as: PreloadResourceTypeSchema,
120
+ type: Schema.optional(
121
+ Schema.String.annotations({
122
+ description: 'MIME type for the resource',
123
+ })
124
+ ),
125
+ crossorigin: Schema.optional(PreloadCrossOriginSchema),
126
+ media: Schema.optional(
127
+ Schema.String.annotations({
128
+ description: 'Media query for conditional loading',
129
+ })
130
+ ),
131
+ }).annotations({
132
+ description: 'Preload resource',
133
+ })
134
+
135
+ /**
136
+ * Resource preloading for performance optimization
137
+ *
138
+ * Array of critical resources to preload early in page load.
139
+ * Improves First Contentful Paint (FCP) and Largest Contentful Paint (LCP)
140
+ * by fetching resources before the browser parser discovers them.
141
+ *
142
+ * How preload works:
143
+ * 1. Browser receives <link rel="preload" ...> in <head>
144
+ * 2. Browser downloads resource immediately (high priority)
145
+ * 3. Resource is cached in browser
146
+ * 4. When parser discovers resource later, it's already downloaded (instant load)
147
+ *
148
+ * What to preload:
149
+ * - **Critical CSS**: Main stylesheet for above-the-fold content
150
+ * - **Web fonts**: Fonts used above-the-fold (prevent FOIT/FOUT)
151
+ * - **Hero images**: Largest Contentful Paint (LCP) images
152
+ * - **Critical scripts**: JavaScript needed for initial render
153
+ * - **API data**: Critical data needed for first render
154
+ *
155
+ * What NOT to preload:
156
+ * - Resources below the fold (defer or lazy load instead)
157
+ * - Non-critical resources (wasted bandwidth, slows critical resources)
158
+ * - Too many resources (limit to 3-5 items, prioritize most critical)
159
+ *
160
+ * Performance metrics improved:
161
+ * - First Contentful Paint (FCP): 200-500ms faster
162
+ * - Largest Contentful Paint (LCP): 300-800ms faster
163
+ * - Cumulative Layout Shift (CLS): Reduced by preventing font swaps
164
+ * - Time to Interactive (TTI): Faster by preloading critical scripts
165
+ *
166
+ * @example
167
+ * ```typescript
168
+ * const preload = [
169
+ * // Critical CSS
170
+ * { href: './output.css', as: 'style' },
171
+ * // Web font (crossorigin required!)
172
+ * { href: './fonts/Inter-Bold.woff2', as: 'font', type: 'font/woff2', crossorigin: true },
173
+ * // Hero image (LCP)
174
+ * { href: './hero.jpg', as: 'image', type: 'image/jpeg' },
175
+ * // Critical API data
176
+ * { href: '/api/posts', as: 'fetch', crossorigin: true }
177
+ * ]
178
+ * ```
179
+ *
180
+ * @see specs/app/pages/meta/performance/preload.schema.json
181
+ */
182
+ export const PreloadSchema = Schema.Array(PreloadItemSchema).annotations({
183
+ title: 'Resource Preloading',
184
+ description: 'Preload critical resources for performance optimization',
185
+ })
186
+
187
+ export type PreloadResourceType = Schema.Schema.Type<typeof PreloadResourceTypeSchema>
188
+ export type PreloadCrossOrigin = Schema.Schema.Type<typeof PreloadCrossOriginSchema>
189
+ export type PreloadItem = Schema.Schema.Type<typeof PreloadItemSchema>
190
+ export type Preload = Schema.Schema.Type<typeof PreloadSchema>
@@ -0,0 +1,211 @@
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
+ * Article type
13
+ *
14
+ * 3 article types for different content:
15
+ * - Article: General articles (default, most common)
16
+ * - NewsArticle: News articles (journalistic content, breaking news)
17
+ * - BlogPosting: Blog posts (personal/company blogs, opinion pieces)
18
+ */
19
+ export const ArticleTypeSchema = Schema.Literal(
20
+ 'Article',
21
+ 'NewsArticle',
22
+ 'BlogPosting'
23
+ ).annotations({
24
+ description: 'Article type',
25
+ })
26
+
27
+ /**
28
+ * Article author
29
+ *
30
+ * Author can be either a simple string name or a structured Person/Organization object.
31
+ * - String: Simple author name (e.g., "John Doe")
32
+ * - Object: Structured author with @type (Person/Organization), name, and optional URL
33
+ */
34
+ export const ArticleAuthorSchema = Schema.Union(
35
+ Schema.String,
36
+ Schema.Struct({
37
+ '@type': Schema.Literal('Person', 'Organization').annotations({
38
+ description: 'Author type',
39
+ }),
40
+ name: Schema.optional(
41
+ Schema.String.annotations({
42
+ description: 'Author name',
43
+ })
44
+ ),
45
+ url: Schema.optional(
46
+ Schema.String.annotations({
47
+ description: 'Author profile URL',
48
+ format: 'uri',
49
+ })
50
+ ),
51
+ })
52
+ ).annotations({
53
+ description: 'Article author',
54
+ })
55
+
56
+ /**
57
+ * Publisher logo
58
+ *
59
+ * ImageObject with @type and url for publisher logo.
60
+ * Required for Article structured data to be eligible for rich results.
61
+ */
62
+ export const PublisherLogoSchema = Schema.Struct({
63
+ '@type': schemaType('ImageObject'),
64
+ url: Schema.optional(
65
+ Schema.String.annotations({
66
+ description: 'Logo URL',
67
+ format: 'uri',
68
+ })
69
+ ),
70
+ }).annotations({
71
+ description: 'Publisher logo',
72
+ })
73
+
74
+ /**
75
+ * Article publisher
76
+ *
77
+ * Organization object representing the content publisher.
78
+ * - @type: "Organization" (required)
79
+ * - name: Publisher name (e.g., "Acme Blog", "TechCrunch")
80
+ * - logo: ImageObject with publisher logo URL
81
+ */
82
+ export const ArticlePublisherSchema = Schema.Struct({
83
+ '@type': schemaType('Organization'),
84
+ name: Schema.optional(
85
+ Schema.String.annotations({
86
+ description: 'Publisher name',
87
+ })
88
+ ),
89
+ logo: Schema.optional(PublisherLogoSchema),
90
+ }).annotations({
91
+ description: 'Article publisher',
92
+ })
93
+
94
+ /**
95
+ * Schema.org Article structured data
96
+ *
97
+ * Represents articles, news articles, and blog posts for rich results in Google Search.
98
+ * Enables article cards with images, publication dates, and author attribution.
99
+ *
100
+ * Required properties:
101
+ * - @context: "https://schema.org" (Schema.org vocabulary)
102
+ * - @type: Article type (Article, NewsArticle, BlogPosting)
103
+ * - headline: Article title (shown in search results)
104
+ *
105
+ * Optional properties:
106
+ * - description: Article summary/excerpt
107
+ * - image: Article image URL (string) or array of image URLs (for carousel)
108
+ * - author: Author name (string) or structured Person/Organization object
109
+ * - datePublished: Publication date (ISO 8601 format)
110
+ * - dateModified: Last modification date (ISO 8601 format)
111
+ * - publisher: Publishing organization (Organization object with name and logo)
112
+ * - mainEntityOfPage: Canonical URL for the article
113
+ *
114
+ * Article types:
115
+ * - **Article**: General articles, how-to guides, tutorials
116
+ * - **NewsArticle**: Breaking news, journalism (adds publish date prominence)
117
+ * - **BlogPosting**: Personal/company blog posts, opinion pieces
118
+ *
119
+ * SEO impact:
120
+ * - **Rich results**: Article cards with image, headline, date, author in search
121
+ * - **Google News**: NewsArticle eligible for Google News (with additional requirements)
122
+ * - **Author attribution**: Links content to authors (E-E-A-T signals)
123
+ * - **Publisher branding**: Publisher logo and name shown in results
124
+ * - **Freshness signals**: datePublished and dateModified help ranking for time-sensitive queries
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const article = {
129
+ * "@context": "https://schema.org",
130
+ * "@type": "BlogPosting",
131
+ * headline: "10 Ways to Boost Productivity",
132
+ * description: "Proven strategies to improve your daily productivity",
133
+ * image: "https://example.com/article-image.jpg",
134
+ * author: {
135
+ * "@type": "Person",
136
+ * name: "John Doe",
137
+ * url: "https://example.com/author/johndoe"
138
+ * },
139
+ * datePublished: "2025-01-15T10:00:00Z",
140
+ * dateModified: "2025-01-20T14:30:00Z",
141
+ * publisher: {
142
+ * "@type": "Organization",
143
+ * name: "Acme Blog",
144
+ * logo: {
145
+ * "@type": "ImageObject",
146
+ * url: "https://example.com/logo.png"
147
+ * }
148
+ * },
149
+ * mainEntityOfPage: "https://example.com/blog/productivity-tips"
150
+ * }
151
+ * ```
152
+ *
153
+ * @see specs/app/pages/meta/structured-data/article.schema.json
154
+ */
155
+ export const ArticleSchema = Schema.Struct({
156
+ '@context': SchemaOrgContext,
157
+ '@type': ArticleTypeSchema,
158
+ headline: Schema.String.annotations({
159
+ description: 'Article title',
160
+ }),
161
+ description: Schema.optional(
162
+ Schema.String.annotations({
163
+ description: 'Article summary',
164
+ })
165
+ ),
166
+ image: Schema.optional(
167
+ Schema.Union(
168
+ Schema.String.annotations({
169
+ description: 'Article image URL',
170
+ format: 'uri',
171
+ }),
172
+ Schema.Array(
173
+ Schema.String.annotations({
174
+ description: 'Article image URL',
175
+ format: 'uri',
176
+ })
177
+ )
178
+ ).annotations({
179
+ description: 'Article image(s)',
180
+ })
181
+ ),
182
+ author: Schema.optional(ArticleAuthorSchema),
183
+ datePublished: Schema.optional(
184
+ Schema.String.annotations({
185
+ description: 'Publication date',
186
+ format: 'date-time',
187
+ })
188
+ ),
189
+ dateModified: Schema.optional(
190
+ Schema.String.annotations({
191
+ description: 'Last modification date',
192
+ format: 'date-time',
193
+ })
194
+ ),
195
+ publisher: Schema.optional(ArticlePublisherSchema),
196
+ mainEntityOfPage: Schema.optional(
197
+ Schema.String.annotations({
198
+ description: "Article's canonical URL",
199
+ format: 'uri',
200
+ })
201
+ ),
202
+ }).annotations({
203
+ title: 'Article Schema',
204
+ description: 'Schema.org Article structured data',
205
+ })
206
+
207
+ export type ArticleType = Schema.Schema.Type<typeof ArticleTypeSchema>
208
+ export type ArticleAuthor = Schema.Schema.Type<typeof ArticleAuthorSchema>
209
+ export type PublisherLogo = Schema.Schema.Type<typeof PublisherLogoSchema>
210
+ export type ArticlePublisher = Schema.Schema.Type<typeof ArticlePublisherSchema>
211
+ export type Article = Schema.Schema.Type<typeof ArticleSchema>
@@ -0,0 +1,115 @@
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, positiveInt } from './common-fields'
10
+
11
+ /**
12
+ * Breadcrumb list item
13
+ *
14
+ * Represents a single breadcrumb in the navigation trail.
15
+ *
16
+ * Required properties:
17
+ * - @type: "ListItem" (Schema.org type identifier)
18
+ * - position: Item position in breadcrumb trail (starts at 1)
19
+ * - name: Human-readable breadcrumb label (e.g., "Home", "Products", "Widget")
20
+ *
21
+ * Optional properties:
22
+ * - item: URL to the breadcrumb page (clickable link)
23
+ */
24
+ export const BreadcrumbListItemSchema = Schema.Struct({
25
+ '@type': schemaType('ListItem'),
26
+ position: positiveInt('Item position in breadcrumb trail'),
27
+ name: Schema.String.annotations({
28
+ description: 'Breadcrumb label',
29
+ }),
30
+ item: Schema.optional(
31
+ Schema.String.annotations({
32
+ description: 'URL to the breadcrumb page',
33
+ format: 'uri',
34
+ })
35
+ ),
36
+ }).annotations({
37
+ description: 'Breadcrumb list item',
38
+ })
39
+
40
+ /**
41
+ * Schema.org BreadcrumbList structured data
42
+ *
43
+ * Represents the navigation path (breadcrumb trail) showing the page's position
44
+ * in the site hierarchy. Displayed in Google search results as a breadcrumb trail
45
+ * instead of the full URL, improving click-through rates.
46
+ *
47
+ * Required properties:
48
+ * - @context: "https://schema.org" (Schema.org vocabulary)
49
+ * - @type: "BreadcrumbList" (Schema.org type identifier)
50
+ * - itemListElement: Array of breadcrumb items (ListItem objects)
51
+ *
52
+ * Breadcrumb structure:
53
+ * - Each item has @type "ListItem", position (integer starting at 1), name, and optional item URL
54
+ * - Position determines order: 1 = Home, 2 = Category, 3 = Subcategory, etc.
55
+ * - Name is the human-readable label shown in breadcrumb trail
56
+ * - Item URL is optional but recommended for clickable breadcrumbs
57
+ *
58
+ * Common patterns:
59
+ * - **Home > Category > Page**: 3-level hierarchy for content sites
60
+ * - **Home > Products > Category > Product**: 4-level for e-commerce
61
+ * - **Home > Docs > Section > Article**: 4-level for documentation
62
+ *
63
+ * SEO impact:
64
+ * - **Rich results**: Breadcrumb trail replaces URL in Google search results
65
+ * - **Site structure**: Helps search engines understand site architecture
66
+ * - **Navigation UX**: Users see page context in search results (higher CTR)
67
+ * - **Mobile optimization**: Breadcrumbs save space vs full URL on mobile
68
+ *
69
+ * Google display example:
70
+ * - Without breadcrumbs: "https://example.com/products/electronics/laptop"
71
+ * - With breadcrumbs: "Home › Products › Electronics › Laptop"
72
+ *
73
+ * @example
74
+ * ```typescript
75
+ * const breadcrumb = {
76
+ * "@context": "https://schema.org",
77
+ * "@type": "BreadcrumbList",
78
+ * itemListElement: [
79
+ * {
80
+ * "@type": "ListItem",
81
+ * position: 1,
82
+ * name: "Home",
83
+ * item: "https://example.com"
84
+ * },
85
+ * {
86
+ * "@type": "ListItem",
87
+ * position: 2,
88
+ * name: "Products",
89
+ * item: "https://example.com/products"
90
+ * },
91
+ * {
92
+ * "@type": "ListItem",
93
+ * position: 3,
94
+ * name: "Widget",
95
+ * item: "https://example.com/products/widget"
96
+ * }
97
+ * ]
98
+ * }
99
+ * ```
100
+ *
101
+ * @see specs/app/pages/meta/structured-data/breadcrumb.schema.json
102
+ */
103
+ export const BreadcrumbSchema = Schema.Struct({
104
+ '@context': SchemaOrgContext,
105
+ '@type': schemaType('BreadcrumbList'),
106
+ itemListElement: Schema.Array(BreadcrumbListItemSchema).annotations({
107
+ description: 'Array of breadcrumb items',
108
+ }),
109
+ }).annotations({
110
+ title: 'Breadcrumb Schema',
111
+ description: 'Schema.org BreadcrumbList structured data',
112
+ })
113
+
114
+ export type BreadcrumbListItem = Schema.Schema.Type<typeof BreadcrumbListItemSchema>
115
+ export type Breadcrumb = Schema.Schema.Type<typeof BreadcrumbSchema>