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.
- package/CHANGELOG.md +3497 -0
- package/LICENSE.md +147 -0
- package/LICENSE_EE.md +297 -0
- package/README.md +321 -0
- package/drizzle/0000_melted_kabuki.sql +163 -0
- package/drizzle/meta/0000_snapshot.json +1216 -0
- package/drizzle/meta/_journal.json +13 -0
- package/package.json +167 -0
- package/schemas/0.0.1/app.openapi.json +70 -0
- package/schemas/0.0.1/app.schema.json +7961 -0
- package/schemas/0.0.2/app.openapi.json +80 -0
- package/schemas/0.0.2/app.schema.json +8829 -0
- package/schemas/development/app.openapi.json +70 -0
- package/schemas/development/app.schema.json +7456 -0
- package/src/application/errors/app-validation-error.ts +14 -0
- package/src/application/errors/static-generation-error.ts +16 -0
- package/src/application/metadata/favicon-transformer.ts +127 -0
- package/src/application/models/server.ts +27 -0
- package/src/application/ports/models/user-metadata.ts +36 -0
- package/src/application/ports/models/user-session.ts +34 -0
- package/src/application/ports/repositories/activity-log-repository.ts +68 -0
- package/src/application/ports/repositories/activity-repository.ts +49 -0
- package/src/application/ports/repositories/analytics-repository.ts +164 -0
- package/src/application/ports/repositories/auth-repository.ts +33 -0
- package/src/application/ports/repositories/batch-repository.ts +86 -0
- package/src/application/ports/repositories/comment-repository.ts +150 -0
- package/src/application/ports/repositories/index.ts +41 -0
- package/src/application/ports/repositories/table-repository.ts +139 -0
- package/src/application/ports/services/css-compiler.ts +55 -0
- package/src/application/ports/services/index.ts +16 -0
- package/src/application/ports/services/page-renderer.ts +79 -0
- package/src/application/ports/services/server-factory.ts +80 -0
- package/src/application/ports/services/static-site-generator.ts +82 -0
- package/src/application/use-cases/activity/programs.ts +66 -0
- package/src/application/use-cases/analytics/collect-page-view.ts +114 -0
- package/src/application/use-cases/analytics/purge-old-data.ts +40 -0
- package/src/application/use-cases/analytics/query-campaigns.ts +43 -0
- package/src/application/use-cases/analytics/query-devices.ts +36 -0
- package/src/application/use-cases/analytics/query-overview.ts +50 -0
- package/src/application/use-cases/analytics/query-pages.ts +40 -0
- package/src/application/use-cases/analytics/query-referrers.ts +43 -0
- package/src/application/use-cases/analytics/ua-parser.ts +89 -0
- package/src/application/use-cases/analytics/visitor-hash.ts +77 -0
- package/src/application/use-cases/auth/bootstrap-admin.ts +270 -0
- package/src/application/use-cases/list-activity-logs.ts +123 -0
- package/src/application/use-cases/server/generate-static-helpers.ts +374 -0
- package/src/application/use-cases/server/generate-static.ts +287 -0
- package/src/application/use-cases/server/start-server.ts +118 -0
- package/src/application/use-cases/server/startup-error-handler.ts +69 -0
- package/src/application/use-cases/server/static-content-generators.ts +182 -0
- package/src/application/use-cases/server/static-language-generators.ts +181 -0
- package/src/application/use-cases/server/static-url-rewriter.ts +237 -0
- package/src/application/use-cases/server/translation-replacer.ts +164 -0
- package/src/application/use-cases/tables/activity-programs.ts +93 -0
- package/src/application/use-cases/tables/batch-operations.ts +156 -0
- package/src/application/use-cases/tables/comment-programs.ts +436 -0
- package/src/application/use-cases/tables/permissions/permissions.ts +25 -0
- package/src/application/use-cases/tables/programs.ts +435 -0
- package/src/application/use-cases/tables/table-operations.ts +412 -0
- package/src/application/use-cases/tables/user-role.ts +52 -0
- package/src/application/use-cases/tables/utils/display-formatter.ts +471 -0
- package/src/application/use-cases/tables/utils/field-read-filter.ts +189 -0
- package/src/application/use-cases/tables/utils/list-helpers.ts +122 -0
- package/src/application/use-cases/tables/utils/record-transformer.ts +319 -0
- package/src/cli.ts +370 -0
- package/src/domain/errors/create-tagged-error.ts +36 -0
- package/src/domain/errors/index.ts +78 -0
- package/src/domain/models/api/analytics.ts +179 -0
- package/src/domain/models/api/auth.ts +231 -0
- package/src/domain/models/api/common.ts +60 -0
- package/src/domain/models/api/error.ts +89 -0
- package/src/domain/models/api/health.ts +38 -0
- package/src/domain/models/api/index.ts +42 -0
- package/src/domain/models/api/request.ts +132 -0
- package/src/domain/models/api/tables.ts +444 -0
- package/src/domain/models/app/analytics/index.ts +129 -0
- package/src/domain/models/app/auth/config.ts +116 -0
- package/src/domain/models/app/auth/index.ts +230 -0
- package/src/domain/models/app/auth/methods/email-and-password.ts +67 -0
- package/src/domain/models/app/auth/methods/index.ts +11 -0
- package/src/domain/models/app/auth/methods/magic-link.ts +54 -0
- package/src/domain/models/app/auth/oauth/index.ts +8 -0
- package/src/domain/models/app/auth/oauth/providers.ts +105 -0
- package/src/domain/models/app/auth/plugins/admin.ts +130 -0
- package/src/domain/models/app/auth/plugins/index.ts +74 -0
- package/src/domain/models/app/auth/plugins/two-factor.ts +63 -0
- package/src/domain/models/app/auth/roles.ts +179 -0
- package/src/domain/models/app/auth/strategies.ts +191 -0
- package/src/domain/models/app/auth/validation.ts +127 -0
- package/src/domain/models/app/common/branded-ids.ts +200 -0
- package/src/domain/models/app/common/definitions.ts +187 -0
- package/src/domain/models/app/component/common/component-children.ts +119 -0
- package/src/domain/models/app/component/common/component-props.ts +89 -0
- package/src/domain/models/app/component/common/component-reference.ts +170 -0
- package/src/domain/models/app/component/component.ts +81 -0
- package/src/domain/models/app/components.ts +65 -0
- package/src/domain/models/app/description.ts +83 -0
- package/src/domain/models/app/index.ts +258 -0
- package/src/domain/models/app/language/language-config.ts +200 -0
- package/src/domain/models/app/languages.ts +205 -0
- package/src/domain/models/app/name.ts +66 -0
- package/src/domain/models/app/page/common/interactions/click-interaction.ts +116 -0
- package/src/domain/models/app/page/common/interactions/entrance-animation.ts +84 -0
- package/src/domain/models/app/page/common/interactions/hover-interaction.ts +144 -0
- package/src/domain/models/app/page/common/interactions/interactions.ts +64 -0
- package/src/domain/models/app/page/common/interactions/scroll-interaction.ts +93 -0
- package/src/domain/models/app/page/common/responsive.ts +114 -0
- package/src/domain/models/app/page/common/url.ts +35 -0
- package/src/domain/models/app/page/common/variable-reference.ts +53 -0
- package/src/domain/models/app/page/id.ts +44 -0
- package/src/domain/models/app/page/index.ts +270 -0
- package/src/domain/models/app/page/meta/analytics.ts +248 -0
- package/src/domain/models/app/page/meta/custom-elements.ts +180 -0
- package/src/domain/models/app/page/meta/dns-prefetch.ts +77 -0
- package/src/domain/models/app/page/meta/favicon-set.ts +203 -0
- package/src/domain/models/app/page/meta/favicon.ts +50 -0
- package/src/domain/models/app/page/meta/favicons-config.ts +73 -0
- package/src/domain/models/app/page/meta/index.ts +278 -0
- package/src/domain/models/app/page/meta/open-graph.ts +166 -0
- package/src/domain/models/app/page/meta/preload.ts +190 -0
- package/src/domain/models/app/page/meta/structured-data/article.ts +211 -0
- package/src/domain/models/app/page/meta/structured-data/breadcrumb.ts +115 -0
- package/src/domain/models/app/page/meta/structured-data/common-fields.ts +201 -0
- package/src/domain/models/app/page/meta/structured-data/education-event.ts +256 -0
- package/src/domain/models/app/page/meta/structured-data/faq-page.ts +127 -0
- package/src/domain/models/app/page/meta/structured-data/index.ts +95 -0
- package/src/domain/models/app/page/meta/structured-data/local-business.ts +247 -0
- package/src/domain/models/app/page/meta/structured-data/organization.ts +171 -0
- package/src/domain/models/app/page/meta/structured-data/person.ts +138 -0
- package/src/domain/models/app/page/meta/structured-data/postal-address.ts +106 -0
- package/src/domain/models/app/page/meta/structured-data/product.ts +214 -0
- package/src/domain/models/app/page/meta/twitter-card.ts +217 -0
- package/src/domain/models/app/page/name.ts +38 -0
- package/src/domain/models/app/page/path.ts +21 -0
- package/src/domain/models/app/page/scripts/external-scripts.ts +163 -0
- package/src/domain/models/app/page/scripts/features.ts +135 -0
- package/src/domain/models/app/page/scripts/inline-scripts.ts +114 -0
- package/src/domain/models/app/page/scripts/scripts.ts +102 -0
- package/src/domain/models/app/page/sections.ts +298 -0
- package/src/domain/models/app/pages.ts +61 -0
- package/src/domain/models/app/permissions/index.ts +61 -0
- package/src/domain/models/app/permissions/resource-action.ts +114 -0
- package/src/domain/models/app/permissions/roles.ts +120 -0
- package/src/domain/models/app/table/check-constraints.ts +105 -0
- package/src/domain/models/app/table/cycle-detection.ts +124 -0
- package/src/domain/models/app/table/database-identifier.ts +153 -0
- package/src/domain/models/app/table/field-name.ts +36 -0
- package/src/domain/models/app/table/field-types/advanced/array-field.ts +33 -0
- package/src/domain/models/app/table/field-types/advanced/autonumber-field.ts +54 -0
- package/src/domain/models/app/table/field-types/advanced/button-field.ts +56 -0
- package/src/domain/models/app/table/field-types/advanced/color-field.ts +57 -0
- package/src/domain/models/app/table/field-types/advanced/count-field.ts +54 -0
- package/src/domain/models/app/table/field-types/advanced/formula-field.ts +58 -0
- package/src/domain/models/app/table/field-types/advanced/geolocation-field.ts +49 -0
- package/src/domain/models/app/table/field-types/advanced/index.ts +16 -0
- package/src/domain/models/app/table/field-types/advanced/json-field.ts +25 -0
- package/src/domain/models/app/table/field-types/advanced/unknown-field.ts +85 -0
- package/src/domain/models/app/table/field-types/base-field.ts +42 -0
- package/src/domain/models/app/table/field-types/date-time/created-at-field.ts +49 -0
- package/src/domain/models/app/table/field-types/date-time/date-field.ts +95 -0
- package/src/domain/models/app/table/field-types/date-time/deleted-at-field.ts +56 -0
- package/src/domain/models/app/table/field-types/date-time/duration-field.ts +73 -0
- package/src/domain/models/app/table/field-types/date-time/index.ts +12 -0
- package/src/domain/models/app/table/field-types/date-time/updated-at-field.ts +50 -0
- package/src/domain/models/app/table/field-types/index.ts +19 -0
- package/src/domain/models/app/table/field-types/media/barcode-field.ts +58 -0
- package/src/domain/models/app/table/field-types/media/index.ts +10 -0
- package/src/domain/models/app/table/field-types/media/multiple-attachments-field.ts +80 -0
- package/src/domain/models/app/table/field-types/media/single-attachment-field.ts +81 -0
- package/src/domain/models/app/table/field-types/numeric/currency-field.ts +144 -0
- package/src/domain/models/app/table/field-types/numeric/decimal-field.ts +113 -0
- package/src/domain/models/app/table/field-types/numeric/index.ts +13 -0
- package/src/domain/models/app/table/field-types/numeric/integer-field.ts +98 -0
- package/src/domain/models/app/table/field-types/numeric/percentage-field.ts +115 -0
- package/src/domain/models/app/table/field-types/numeric/progress-field.ts +71 -0
- package/src/domain/models/app/table/field-types/numeric/rating-field.ts +74 -0
- package/src/domain/models/app/table/field-types/relational/index.ts +10 -0
- package/src/domain/models/app/table/field-types/relational/lookup-field.ts +46 -0
- package/src/domain/models/app/table/field-types/relational/relationship-field.ts +112 -0
- package/src/domain/models/app/table/field-types/relational/rollup-field.ts +58 -0
- package/src/domain/models/app/table/field-types/selection/checkbox-field.ts +51 -0
- package/src/domain/models/app/table/field-types/selection/index.ts +11 -0
- package/src/domain/models/app/table/field-types/selection/multi-select-field.ts +68 -0
- package/src/domain/models/app/table/field-types/selection/single-select-field.ts +54 -0
- package/src/domain/models/app/table/field-types/selection/status-field.ts +37 -0
- package/src/domain/models/app/table/field-types/text/email-field.ts +80 -0
- package/src/domain/models/app/table/field-types/text/index.ts +13 -0
- package/src/domain/models/app/table/field-types/text/long-text-field.ts +77 -0
- package/src/domain/models/app/table/field-types/text/phone-number-field.ts +82 -0
- package/src/domain/models/app/table/field-types/text/rich-text-field.ts +66 -0
- package/src/domain/models/app/table/field-types/text/single-line-text-field.ts +79 -0
- package/src/domain/models/app/table/field-types/text/url-field.ts +81 -0
- package/src/domain/models/app/table/field-types/user/created-by-field.ts +50 -0
- package/src/domain/models/app/table/field-types/user/deleted-by-field.ts +57 -0
- package/src/domain/models/app/table/field-types/user/index.ts +11 -0
- package/src/domain/models/app/table/field-types/user/updated-by-field.ts +51 -0
- package/src/domain/models/app/table/field-types/user/user-field.ts +52 -0
- package/src/domain/models/app/table/field-types/validation-utils.ts +166 -0
- package/src/domain/models/app/table/fields.ts +216 -0
- package/src/domain/models/app/table/foreign-keys.ts +111 -0
- package/src/domain/models/app/table/formula-keywords.ts +326 -0
- package/src/domain/models/app/table/id.ts +31 -0
- package/src/domain/models/app/table/index.ts +290 -0
- package/src/domain/models/app/table/indexes.ts +80 -0
- package/src/domain/models/app/table/name.ts +37 -0
- package/src/domain/models/app/table/permissions/field-permission.ts +83 -0
- package/src/domain/models/app/table/permissions/index.ts +167 -0
- package/src/domain/models/app/table/permissions/permission-evaluator.ts +372 -0
- package/src/domain/models/app/table/permissions/permission.ts +49 -0
- package/src/domain/models/app/table/primary-key.ts +62 -0
- package/src/domain/models/app/table/table-formula-validation.ts +168 -0
- package/src/domain/models/app/table/table-indexes-validation.ts +38 -0
- package/src/domain/models/app/table/table-permissions-validation.ts +77 -0
- package/src/domain/models/app/table/table-primary-key-validation.ts +49 -0
- package/src/domain/models/app/table/table-views-validation.ts +408 -0
- package/src/domain/models/app/table/unique-constraints.ts +79 -0
- package/src/domain/models/app/table/views/fields.ts +28 -0
- package/src/domain/models/app/table/views/filters.ts +162 -0
- package/src/domain/models/app/table/views/group-by.ts +32 -0
- package/src/domain/models/app/table/views/id.ts +50 -0
- package/src/domain/models/app/table/views/index.ts +177 -0
- package/src/domain/models/app/table/views/name.ts +32 -0
- package/src/domain/models/app/table/views/permissions.ts +98 -0
- package/src/domain/models/app/table/views/sorts.ts +31 -0
- package/src/domain/models/app/tables.ts +695 -0
- package/src/domain/models/app/theme/animations.ts +208 -0
- package/src/domain/models/app/theme/border-radius.ts +58 -0
- package/src/domain/models/app/theme/breakpoints.ts +62 -0
- package/src/domain/models/app/theme/colors.ts +110 -0
- package/src/domain/models/app/theme/fonts.ts +164 -0
- package/src/domain/models/app/theme/shadows.ts +61 -0
- package/src/domain/models/app/theme/spacing.ts +115 -0
- package/src/domain/models/app/theme.ts +66 -0
- package/src/domain/models/app/version.ts +87 -0
- package/src/domain/models/record-comment.ts +91 -0
- package/src/domain/utils/content-parsing.ts +49 -0
- package/src/domain/utils/format-detection.ts +69 -0
- package/src/domain/utils/index.ts +9 -0
- package/src/domain/utils/route-matcher.ts +184 -0
- package/src/domain/utils/translation-resolver.ts +170 -0
- package/src/index.ts +208 -0
- package/src/infrastructure/analytics/tracking-script.ts +48 -0
- package/src/infrastructure/auth/better-auth/auth.ts +216 -0
- package/src/infrastructure/auth/better-auth/email-handlers.ts +162 -0
- package/src/infrastructure/auth/better-auth/index.ts +16 -0
- package/src/infrastructure/auth/better-auth/layer.ts +97 -0
- package/src/infrastructure/auth/better-auth/plugins/admin.ts +56 -0
- package/src/infrastructure/auth/better-auth/plugins/magic-link.ts +31 -0
- package/src/infrastructure/auth/better-auth/plugins/two-factor.ts +19 -0
- package/src/infrastructure/auth/better-auth/schema.ts +152 -0
- package/src/infrastructure/auth/index.ts +27 -0
- package/src/infrastructure/css/cache/css-cache-service.ts +130 -0
- package/src/infrastructure/css/compiler.ts +210 -0
- package/src/infrastructure/css/css-compiler-live.ts +20 -0
- package/src/infrastructure/css/index.ts +25 -0
- package/src/infrastructure/css/styles/animation-styles-generator.ts +177 -0
- package/src/infrastructure/css/styles/click-animations.ts +147 -0
- package/src/infrastructure/css/styles/component-layer-generators.ts +147 -0
- package/src/infrastructure/css/theme/theme-generators.ts +130 -0
- package/src/infrastructure/css/theme/theme-layer-generators.ts +219 -0
- package/src/infrastructure/css/theme/theme-token-resolver.ts +76 -0
- package/src/infrastructure/database/activity-queries.ts +111 -0
- package/src/infrastructure/database/auth/auth-validation.ts +101 -0
- package/src/infrastructure/database/drizzle/db-bun.ts +17 -0
- package/src/infrastructure/database/drizzle/db.ts +17 -0
- package/src/infrastructure/database/drizzle/index.ts +16 -0
- package/src/infrastructure/database/drizzle/layer.ts +34 -0
- package/src/infrastructure/database/drizzle/migrate.ts +77 -0
- package/src/infrastructure/database/drizzle/schema/activity-log.ts +111 -0
- package/src/infrastructure/database/drizzle/schema/analytics-page-views.ts +116 -0
- package/src/infrastructure/database/drizzle/schema/migration-audit.ts +68 -0
- package/src/infrastructure/database/drizzle/schema/record-comments.ts +79 -0
- package/src/infrastructure/database/drizzle/schema.ts +12 -0
- package/src/infrastructure/database/field-utils.ts +87 -0
- package/src/infrastructure/database/filter-operators.ts +136 -0
- package/src/infrastructure/database/formula/formula-trigger-generators.ts +114 -0
- package/src/infrastructure/database/formula/formula-utils.ts +440 -0
- package/src/infrastructure/database/generators/index-generators.ts +152 -0
- package/src/infrastructure/database/generators/trigger-generators.ts +154 -0
- package/src/infrastructure/database/index.ts +35 -0
- package/src/infrastructure/database/lookup/lookup-expression-generators.ts +356 -0
- package/src/infrastructure/database/lookup/lookup-expressions.ts +116 -0
- package/src/infrastructure/database/lookup/lookup-view-generators.ts +403 -0
- package/src/infrastructure/database/lookup/lookup-view-helpers.ts +65 -0
- package/src/infrastructure/database/lookup/lookup-view-triggers.ts +121 -0
- package/src/infrastructure/database/migration-audit-trail.ts +375 -0
- package/src/infrastructure/database/repositories/activity-log-repository-live.ts +99 -0
- package/src/infrastructure/database/repositories/activity-repository-live.ts +21 -0
- package/src/infrastructure/database/repositories/analytics-repository-live.ts +316 -0
- package/src/infrastructure/database/repositories/auth-repository-live.ts +42 -0
- package/src/infrastructure/database/repositories/batch-repository-live.ts +29 -0
- package/src/infrastructure/database/repositories/comment-repository-live.ts +39 -0
- package/src/infrastructure/database/repositories/table-repository-live.ts +38 -0
- package/src/infrastructure/database/schema/schema-dependency-sorting.ts +142 -0
- package/src/infrastructure/database/schema/schema-initializer.ts +598 -0
- package/src/infrastructure/database/schema-migration/column-detection.ts +286 -0
- package/src/infrastructure/database/schema-migration/constants.ts +31 -0
- package/src/infrastructure/database/schema-migration/constraint-sync.ts +288 -0
- package/src/infrastructure/database/schema-migration/index-sync.ts +108 -0
- package/src/infrastructure/database/schema-migration/index.ts +66 -0
- package/src/infrastructure/database/schema-migration/migration-statements.ts +106 -0
- package/src/infrastructure/database/schema-migration/rename-detection.ts +87 -0
- package/src/infrastructure/database/schema-migration/table-operations.ts +65 -0
- package/src/infrastructure/database/schema-migration/type-utils.ts +98 -0
- package/src/infrastructure/database/schema-migration/types.ts +14 -0
- package/src/infrastructure/database/schema-migration-helpers.ts +53 -0
- package/src/infrastructure/database/session-context.ts +20 -0
- package/src/infrastructure/database/sql/sql-check-constraints.ts +252 -0
- package/src/infrastructure/database/sql/sql-column-generators.ts +174 -0
- package/src/infrastructure/database/sql/sql-execution.ts +245 -0
- package/src/infrastructure/database/sql/sql-field-predicates.ts +81 -0
- package/src/infrastructure/database/sql/sql-generators.ts +91 -0
- package/src/infrastructure/database/sql/sql-junction-tables.ts +79 -0
- package/src/infrastructure/database/sql/sql-key-constraints.ts +210 -0
- package/src/infrastructure/database/sql/sql-type-mappings.ts +106 -0
- package/src/infrastructure/database/sql/sql-utils.ts +53 -0
- package/src/infrastructure/database/table-live-layers.ts +30 -0
- package/src/infrastructure/database/table-operations/column-generators.ts +82 -0
- package/src/infrastructure/database/table-operations/create-table-sql.ts +81 -0
- package/src/infrastructure/database/table-operations/index.ts +55 -0
- package/src/infrastructure/database/table-operations/migration-utils.ts +157 -0
- package/src/infrastructure/database/table-operations/table-effects.ts +234 -0
- package/src/infrastructure/database/table-operations/table-features.ts +96 -0
- package/src/infrastructure/database/table-operations/type-compatibility.ts +58 -0
- package/src/infrastructure/database/table-operations.ts +47 -0
- package/src/infrastructure/database/table-queries/batch/batch-create.ts +80 -0
- package/src/infrastructure/database/table-queries/batch/batch-delete.ts +212 -0
- package/src/infrastructure/database/table-queries/batch/batch-helpers.ts +124 -0
- package/src/infrastructure/database/table-queries/batch/batch-restore.ts +161 -0
- package/src/infrastructure/database/table-queries/batch/batch-update.ts +146 -0
- package/src/infrastructure/database/table-queries/batch/batch-upsert.ts +357 -0
- package/src/infrastructure/database/table-queries/batch/batch.ts +14 -0
- package/src/infrastructure/database/table-queries/crud/crud-read.ts +351 -0
- package/src/infrastructure/database/table-queries/crud/crud-write.ts +399 -0
- package/src/infrastructure/database/table-queries/crud/crud.ts +16 -0
- package/src/infrastructure/database/table-queries/index.ts +11 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/authorship-helpers.ts +152 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/create-record-helpers.ts +90 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/delete-helpers.ts +163 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/record-fetch-helpers.ts +79 -0
- package/src/infrastructure/database/table-queries/mutation-helpers/update-helpers.ts +74 -0
- package/src/infrastructure/database/table-queries/query-helpers/activity-log-helpers.ts +53 -0
- package/src/infrastructure/database/table-queries/query-helpers/activity-queries.ts +106 -0
- package/src/infrastructure/database/table-queries/query-helpers/aggregation-helpers.ts +314 -0
- package/src/infrastructure/database/table-queries/query-helpers/comment-queries.ts +414 -0
- package/src/infrastructure/database/table-queries/query-helpers/record-validation-queries.ts +126 -0
- package/src/infrastructure/database/table-queries/query-helpers/trash-helpers.ts +58 -0
- package/src/infrastructure/database/table-queries/shared/error-handling.ts +47 -0
- package/src/infrastructure/database/table-queries/shared/typed-execute.ts +27 -0
- package/src/infrastructure/database/table-queries/shared/user-join-helpers.ts +38 -0
- package/src/infrastructure/database/table-queries/shared/validation.ts +39 -0
- package/src/infrastructure/database/views/view-generators.ts +258 -0
- package/src/infrastructure/devtools/devtools-layer.ts +43 -0
- package/src/infrastructure/devtools/index.ts +8 -0
- package/src/infrastructure/email/email-config.ts +103 -0
- package/src/infrastructure/email/email-service.ts +152 -0
- package/src/infrastructure/email/index.ts +107 -0
- package/src/infrastructure/email/nodemailer.ts +125 -0
- package/src/infrastructure/email/templates.ts +244 -0
- package/src/infrastructure/errors/auth-config-required-error.ts +21 -0
- package/src/infrastructure/errors/auth-error.ts +16 -0
- package/src/infrastructure/errors/css-compilation-error.ts +14 -0
- package/src/infrastructure/errors/index.ts +26 -0
- package/src/infrastructure/errors/schema-initialization-error.ts +19 -0
- package/src/infrastructure/errors/server-creation-error.ts +14 -0
- package/src/infrastructure/filesystem/copy-directory.ts +136 -0
- package/src/infrastructure/layers/app-layer.ts +61 -0
- package/src/infrastructure/layers/page-renderer-layer.ts +41 -0
- package/src/infrastructure/logging/index.ts +8 -0
- package/src/infrastructure/logging/logger.ts +204 -0
- package/src/infrastructure/schema/file-loader.ts +53 -0
- package/src/infrastructure/schema/index.ts +15 -0
- package/src/infrastructure/schema/remote-loader.ts +48 -0
- package/src/infrastructure/server/index.ts +26 -0
- package/src/infrastructure/server/language-detection.ts +87 -0
- package/src/infrastructure/server/lifecycle.ts +67 -0
- package/src/infrastructure/server/route-setup/api-routes.ts +310 -0
- package/src/infrastructure/server/route-setup/auth-route-utils.ts +399 -0
- package/src/infrastructure/server/route-setup/auth-routes.ts +245 -0
- package/src/infrastructure/server/route-setup/openapi-routes.ts +45 -0
- package/src/infrastructure/server/route-setup/openapi-schema.ts +120 -0
- package/src/infrastructure/server/route-setup/page-routes.ts +219 -0
- package/src/infrastructure/server/route-setup/static-assets.ts +191 -0
- package/src/infrastructure/server/server-factory-live.ts +45 -0
- package/src/infrastructure/server/server.ts +275 -0
- package/src/infrastructure/server/ssg-adapter.ts +196 -0
- package/src/infrastructure/server/static-site-generator-live.ts +20 -0
- package/src/infrastructure/utils/accept-language-parser.ts +106 -0
- package/src/infrastructure/utils/glob-matcher.ts +50 -0
- package/src/presentation/api/client.ts +114 -0
- package/src/presentation/api/middleware/auth.ts +233 -0
- package/src/presentation/api/middleware/table.ts +155 -0
- package/src/presentation/api/middleware/validation.ts +88 -0
- package/src/presentation/api/routes/activity/get-activity-by-id-handler.ts +77 -0
- package/src/presentation/api/routes/activity/index.ts +28 -0
- package/src/presentation/api/routes/activity.ts +339 -0
- package/src/presentation/api/routes/analytics.ts +328 -0
- package/src/presentation/api/routes/auth.ts +169 -0
- package/src/presentation/api/routes/index.ts +11 -0
- package/src/presentation/api/routes/tables/activity-handlers.ts +57 -0
- package/src/presentation/api/routes/tables/batch-permission-helpers.ts +163 -0
- package/src/presentation/api/routes/tables/batch-routes.ts +355 -0
- package/src/presentation/api/routes/tables/comment-handlers.ts +377 -0
- package/src/presentation/api/routes/tables/create-record-helpers.ts +179 -0
- package/src/presentation/api/routes/tables/effect-runner.ts +58 -0
- package/src/presentation/api/routes/tables/error-handlers.ts +53 -0
- package/src/presentation/api/routes/tables/field-permission-validation.ts +167 -0
- package/src/presentation/api/routes/tables/filter-parser.ts +75 -0
- package/src/presentation/api/routes/tables/formula-parser.ts +118 -0
- package/src/presentation/api/routes/tables/index.ts +113 -0
- package/src/presentation/api/routes/tables/list-records-filter.ts +54 -0
- package/src/presentation/api/routes/tables/param-parsers.ts +59 -0
- package/src/presentation/api/routes/tables/record-handlers.ts +484 -0
- package/src/presentation/api/routes/tables/record-routes.ts +53 -0
- package/src/presentation/api/routes/tables/record-update-handler.ts +200 -0
- package/src/presentation/api/routes/tables/sort-validation.ts +85 -0
- package/src/presentation/api/routes/tables/table-routes.ts +76 -0
- package/src/presentation/api/routes/tables/timezone-validation.ts +41 -0
- package/src/presentation/api/routes/tables/upsert-helpers.ts +471 -0
- package/src/presentation/api/routes/tables/utils.ts +159 -0
- package/src/presentation/api/routes/tables/view-routes.ts +51 -0
- package/src/presentation/api/routes/tables.ts +9 -0
- package/src/presentation/api/utils/context-helpers.ts +43 -0
- package/src/presentation/api/utils/error-sanitizer.ts +235 -0
- package/src/presentation/api/utils/field-permission-validator.ts +53 -0
- package/src/presentation/api/utils/filter-field-validator.ts +90 -0
- package/src/presentation/api/utils/index.ts +13 -0
- package/src/presentation/api/utils/run-effect.ts +94 -0
- package/src/presentation/api/utils/validate-request.ts +89 -0
- package/src/presentation/api/validation/index.ts +29 -0
- package/src/presentation/api/validation/rules/field-rules.ts +158 -0
- package/src/presentation/api/validation/rules/record-rules.ts +73 -0
- package/src/presentation/cli/index.ts +19 -0
- package/src/presentation/cli/schema-loader.ts +172 -0
- package/src/presentation/hooks/use-breakpoint.ts +155 -0
- package/src/presentation/rendering/render-error-pages.tsx +60 -0
- package/src/presentation/rendering/render-homepage.tsx +137 -0
- package/src/presentation/scripts/script-renderers.ts +112 -0
- package/src/presentation/styling/animation-composer.ts +117 -0
- package/src/presentation/styling/index.ts +13 -0
- package/src/presentation/styling/parse-style.ts +243 -0
- package/src/presentation/styling/style-utils.ts +50 -0
- package/src/presentation/styling/theme-colors.ts +53 -0
- package/src/presentation/translations/component-utils.ts +54 -0
- package/src/presentation/translations/index.ts +16 -0
- package/src/presentation/translations/translation-resolver.ts +22 -0
- package/src/presentation/ui/languages/language-switcher.tsx +119 -0
- package/src/presentation/ui/metadata/analytics-builders.tsx +174 -0
- package/src/presentation/ui/metadata/analytics-head.tsx +39 -0
- package/src/presentation/ui/metadata/custom-elements-builders.tsx +157 -0
- package/src/presentation/ui/metadata/extract-component-meta.ts +108 -0
- package/src/presentation/ui/metadata/head-elements.tsx +164 -0
- package/src/presentation/ui/metadata/index.tsx +35 -0
- package/src/presentation/ui/metadata/meta-utils.tsx +42 -0
- package/src/presentation/ui/metadata/open-graph-meta.tsx +57 -0
- package/src/presentation/ui/metadata/structured-data-from-component.tsx +134 -0
- package/src/presentation/ui/metadata/structured-data.tsx +88 -0
- package/src/presentation/ui/metadata/twitter-card-meta.tsx +80 -0
- package/src/presentation/ui/pages/DefaultHomePage.tsx +43 -0
- package/src/presentation/ui/pages/DefaultPageConfigs.ts +220 -0
- package/src/presentation/ui/pages/DynamicPage.tsx +307 -0
- package/src/presentation/ui/pages/ErrorPage.tsx +25 -0
- package/src/presentation/ui/pages/NotFoundPage.tsx +25 -0
- package/src/presentation/ui/pages/PageBodyScripts.tsx +242 -0
- package/src/presentation/ui/pages/PageBodyStyles.ts +52 -0
- package/src/presentation/ui/pages/PageHead.tsx +380 -0
- package/src/presentation/ui/pages/PageLangResolver.ts +58 -0
- package/src/presentation/ui/pages/PageMain.tsx +58 -0
- package/src/presentation/ui/pages/PageMetadata.ts +168 -0
- package/src/presentation/ui/pages/PageMetadataI18n.ts +169 -0
- package/src/presentation/ui/pages/PageScripts.ts +78 -0
- package/src/presentation/ui/pages/SectionRenderer.tsx +67 -0
- package/src/presentation/ui/pages/SectionSpacing.tsx +131 -0
- package/src/presentation/ui/sections/component-renderer.tsx +426 -0
- package/src/presentation/ui/sections/component-renderer.types.ts +33 -0
- package/src/presentation/ui/sections/components/component-reference-handler.tsx +74 -0
- package/src/presentation/ui/sections/components/component-resolution.ts +65 -0
- package/src/presentation/ui/sections/components/index.ts +9 -0
- package/src/presentation/ui/sections/hero.tsx +394 -0
- package/src/presentation/ui/sections/props/component-builder.ts +183 -0
- package/src/presentation/ui/sections/props/element-props.ts +179 -0
- package/src/presentation/ui/sections/props/index.ts +9 -0
- package/src/presentation/ui/sections/props/prop-conversion.ts +171 -0
- package/src/presentation/ui/sections/props/props-builder-config.ts +42 -0
- package/src/presentation/ui/sections/props/props-builder.ts +296 -0
- package/src/presentation/ui/sections/renderers/element-renderers/html-element-renderer.tsx +124 -0
- package/src/presentation/ui/sections/renderers/element-renderers/index.ts +59 -0
- package/src/presentation/ui/sections/renderers/element-renderers/interactive-renderers.tsx +231 -0
- package/src/presentation/ui/sections/renderers/element-renderers/media-renderers.tsx +102 -0
- package/src/presentation/ui/sections/renderers/element-renderers/text-content-renderers.tsx +42 -0
- package/src/presentation/ui/sections/renderers/element-renderers.ts +53 -0
- package/src/presentation/ui/sections/renderers/html-element-helpers.ts +100 -0
- package/src/presentation/ui/sections/renderers/specialized-renderers.tsx +212 -0
- package/src/presentation/ui/sections/rendering/component-dispatch-config.ts +31 -0
- package/src/presentation/ui/sections/rendering/component-registry/index.ts +39 -0
- package/src/presentation/ui/sections/rendering/component-registry/interactive-components.ts +54 -0
- package/src/presentation/ui/sections/rendering/component-registry/media-components.ts +36 -0
- package/src/presentation/ui/sections/rendering/component-registry/special-components.tsx +153 -0
- package/src/presentation/ui/sections/rendering/component-registry/structural-components.ts +215 -0
- package/src/presentation/ui/sections/rendering/component-registry/text-components.ts +57 -0
- package/src/presentation/ui/sections/rendering/component-registry-helpers.tsx +29 -0
- package/src/presentation/ui/sections/rendering/component-registry.tsx +21 -0
- package/src/presentation/ui/sections/rendering/component-type-dispatcher.tsx +33 -0
- package/src/presentation/ui/sections/rendering/index.ts +9 -0
- package/src/presentation/ui/sections/responsive/responsive-children-builder.tsx +96 -0
- package/src/presentation/ui/sections/responsive/responsive-content-builder.tsx +95 -0
- package/src/presentation/ui/sections/responsive/responsive-props-merger.ts +195 -0
- package/src/presentation/ui/sections/responsive/responsive-resolver.ts +213 -0
- package/src/presentation/ui/sections/styling/animation-composer-wrapper.ts +65 -0
- package/src/presentation/ui/sections/styling/class-builders.ts +45 -0
- package/src/presentation/ui/sections/styling/color-resolver.ts +43 -0
- package/src/presentation/ui/sections/styling/hover-interaction-handler.ts +107 -0
- package/src/presentation/ui/sections/styling/index.ts +9 -0
- package/src/presentation/ui/sections/styling/interaction-props-builder.ts +55 -0
- package/src/presentation/ui/sections/styling/shadow-resolver.ts +83 -0
- package/src/presentation/ui/sections/styling/spacing-resolver.ts +104 -0
- package/src/presentation/ui/sections/styling/style-processor.ts +170 -0
- package/src/presentation/ui/sections/styling/theme-tokens.ts +184 -0
- package/src/presentation/ui/sections/translations/i18n-content-resolver.ts +198 -0
- package/src/presentation/ui/sections/translations/index.ts +9 -0
- package/src/presentation/ui/sections/translations/translation-handler.ts +143 -0
- package/src/presentation/ui/sections/translations/variable-substitution.ts +225 -0
- package/src/presentation/ui/sections/utils/time-parser.ts +82 -0
- package/src/presentation/utils/link-attributes.ts +50 -0
- package/src/presentation/utils/string-utils.ts +58 -0
- package/src/presentation/utils/styles.ts +50 -0
- package/tsconfig.json +46 -0
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Schema } from 'effect'
|
|
9
|
+
import { PageIdSchema } from './id'
|
|
10
|
+
import { MetaSchema } from './meta'
|
|
11
|
+
import { PageNameSchema } from './name'
|
|
12
|
+
import { PagePathSchema } from './path'
|
|
13
|
+
import { ScriptsSchema } from './scripts/scripts'
|
|
14
|
+
import { SectionsSchema } from './sections'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Page Schema
|
|
18
|
+
*
|
|
19
|
+
* Represents a complete page configuration with metadata, layout, sections, and scripts.
|
|
20
|
+
*
|
|
21
|
+
* Marketing and content pages with server-side rendering support. Pages use a component-based
|
|
22
|
+
* layout system with reusable component templates for building landing pages, about pages, pricing
|
|
23
|
+
* pages, and other public-facing content.
|
|
24
|
+
*
|
|
25
|
+
* ## Key Features
|
|
26
|
+
*
|
|
27
|
+
* - **Component-Based Layout**: Compose pages from reusable component templates defined at app level
|
|
28
|
+
* - **Theme Integration**: Pages use app.theme{} tokens via className utilities
|
|
29
|
+
* - **i18n Support**: Multi-language pages with $t: translation references
|
|
30
|
+
* - **Responsive Design**: Single page adapts to all viewports (mobile, tablet, desktop)
|
|
31
|
+
* - **SEO Optimization**: Comprehensive metadata, structured data, social sharing
|
|
32
|
+
*
|
|
33
|
+
* ## Architecture Notes
|
|
34
|
+
*
|
|
35
|
+
* - **Theme**: Defined at app level (app.theme{}), NOT in individual pages
|
|
36
|
+
* - **Components**: Defined at app level (app.components[]), NOT in individual pages
|
|
37
|
+
* - **Sections**: Reference component templates using $ref syntax with $vars substitution
|
|
38
|
+
* - **Styling**: Pages use className with theme tokens, not page-level theme
|
|
39
|
+
*
|
|
40
|
+
* ## Component References
|
|
41
|
+
*
|
|
42
|
+
* Sections can reference component templates defined at app level using $ref syntax:
|
|
43
|
+
*
|
|
44
|
+
* ```typescript
|
|
45
|
+
* {
|
|
46
|
+
* sections: [
|
|
47
|
+
* {
|
|
48
|
+
* : '#/components/hero',
|
|
49
|
+
* $vars: {
|
|
50
|
+
* title: 'Welcome to Our Platform',
|
|
51
|
+
* ctaLabel: 'Get Started'
|
|
52
|
+
* }
|
|
53
|
+
* }
|
|
54
|
+
* ]
|
|
55
|
+
* }
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* The component template is resolved and variables ($title, $ctaLabel) are substituted
|
|
59
|
+
* at runtime.
|
|
60
|
+
*
|
|
61
|
+
* ## Translation References
|
|
62
|
+
*
|
|
63
|
+
* Pages support internationalization via $t: translation references:
|
|
64
|
+
*
|
|
65
|
+
* ```typescript
|
|
66
|
+
* {
|
|
67
|
+
* meta: {
|
|
68
|
+
* lang: 'en',
|
|
69
|
+
* title: '$t:hero.title'
|
|
70
|
+
* },
|
|
71
|
+
* sections: [
|
|
72
|
+
* {
|
|
73
|
+
* type: 'h1',
|
|
74
|
+
* children: ['$t:hero.title']
|
|
75
|
+
* }
|
|
76
|
+
* ]
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* Translation keys resolve based on meta.lang from app.languages{} configuration.
|
|
81
|
+
*
|
|
82
|
+
* ## Responsive Design
|
|
83
|
+
*
|
|
84
|
+
* Pages adapt to different viewports using responsive className utilities:
|
|
85
|
+
*
|
|
86
|
+
* ```typescript
|
|
87
|
+
* {
|
|
88
|
+
* type: 'section',
|
|
89
|
+
* props: {
|
|
90
|
+
* className: 'py-12 md:py-20 lg:py-32'
|
|
91
|
+
* }
|
|
92
|
+
* }
|
|
93
|
+
* ```
|
|
94
|
+
*
|
|
95
|
+
* Mobile-first approach: base styles for mobile, breakpoints for larger screens.
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* // Minimal page with required properties
|
|
100
|
+
* const minimalPage: Page = {
|
|
101
|
+
* name: 'Home',
|
|
102
|
+
* path: '/',
|
|
103
|
+
* meta: {
|
|
104
|
+
* lang: 'en-US',
|
|
105
|
+
* title: 'Welcome',
|
|
106
|
+
* description: 'Welcome to our platform'
|
|
107
|
+
* },
|
|
108
|
+
* sections: []
|
|
109
|
+
* }
|
|
110
|
+
*
|
|
111
|
+
* // Complete page with all properties
|
|
112
|
+
* const completePage: Page = {
|
|
113
|
+
* id: 'homepage',
|
|
114
|
+
* name: 'Home',
|
|
115
|
+
* path: '/',
|
|
116
|
+
* meta: {
|
|
117
|
+
* lang: 'en-US',
|
|
118
|
+
* title: 'Welcome',
|
|
119
|
+
* description: 'Welcome to our platform',
|
|
120
|
+
* openGraph: {
|
|
121
|
+
* title: 'Welcome to Our Platform',
|
|
122
|
+
* type: 'website',
|
|
123
|
+
* url: 'https://example.com',
|
|
124
|
+
* image: 'https://example.com/og-image.jpg'
|
|
125
|
+
* }
|
|
126
|
+
* },
|
|
127
|
+
* sections: [
|
|
128
|
+
* {
|
|
129
|
+
* : '#/components/hero',
|
|
130
|
+
* $vars: {
|
|
131
|
+
* title: 'Welcome',
|
|
132
|
+
* ctaLabel: 'Get Started'
|
|
133
|
+
* }
|
|
134
|
+
* }
|
|
135
|
+
* ],
|
|
136
|
+
* scripts: {
|
|
137
|
+
* features: {
|
|
138
|
+
* analytics: true
|
|
139
|
+
* }
|
|
140
|
+
* }
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* @see {@link https://schema.org Schema.org} for structured data
|
|
145
|
+
* @see {@link MetaSchema} for metadata configuration
|
|
146
|
+
* @see {@link SectionsSchema} for sections configuration
|
|
147
|
+
* @see {@link ScriptsSchema} for scripts configuration
|
|
148
|
+
*/
|
|
149
|
+
export const PageSchema = Schema.Struct({
|
|
150
|
+
/**
|
|
151
|
+
* Optional unique identifier for the page
|
|
152
|
+
*
|
|
153
|
+
* Used for internal references and tracking
|
|
154
|
+
*/
|
|
155
|
+
id: Schema.optional(PageIdSchema),
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Human-readable name for the page
|
|
159
|
+
*
|
|
160
|
+
* Used for identification in admin interfaces and as internal identifier.
|
|
161
|
+
* Required field that serves as a unique identifier separate from the URL path.
|
|
162
|
+
*
|
|
163
|
+
* @example "home"
|
|
164
|
+
* @example "about"
|
|
165
|
+
*/
|
|
166
|
+
name: PageNameSchema,
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* URL path where the page is accessible
|
|
170
|
+
*
|
|
171
|
+
* - Root path: `/` (homepage)
|
|
172
|
+
* - Nested paths: `/about`, `/products/pricing`
|
|
173
|
+
*
|
|
174
|
+
* @example "/"
|
|
175
|
+
* @example "/about"
|
|
176
|
+
* @example "/products/pricing"
|
|
177
|
+
*/
|
|
178
|
+
path: PagePathSchema,
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Page metadata for SEO, social sharing, and analytics
|
|
182
|
+
*
|
|
183
|
+
* Optional - if not provided, uses default metadata based on page name/path
|
|
184
|
+
*
|
|
185
|
+
* Includes:
|
|
186
|
+
* - Basic SEO (title, description, keywords)
|
|
187
|
+
* - Social media (Open Graph, Twitter Card)
|
|
188
|
+
* - Structured data (Schema.org)
|
|
189
|
+
* - Performance hints (preload, DNS prefetch)
|
|
190
|
+
* - Analytics configuration
|
|
191
|
+
*/
|
|
192
|
+
meta: Schema.optional(MetaSchema),
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Page sections containing content
|
|
196
|
+
*
|
|
197
|
+
* Sections can be:
|
|
198
|
+
* - Direct components: { type, props, children }
|
|
199
|
+
* - Component references: { $ref, $vars }
|
|
200
|
+
*
|
|
201
|
+
* Component references resolve to app.components[] with variable substitution
|
|
202
|
+
*/
|
|
203
|
+
sections: SectionsSchema,
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Optional client-side scripts and features
|
|
207
|
+
*
|
|
208
|
+
* Manages:
|
|
209
|
+
* - Feature flags (analytics, chat widget)
|
|
210
|
+
* - External scripts (CDN resources)
|
|
211
|
+
* - Inline scripts (custom JavaScript)
|
|
212
|
+
* - Client configuration
|
|
213
|
+
*/
|
|
214
|
+
scripts: Schema.optional(ScriptsSchema),
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Optional page-level variables for substitution in sections
|
|
218
|
+
*
|
|
219
|
+
* Variables can be referenced in section content, props, and children using
|
|
220
|
+
* $variableName syntax. These variables are substituted at runtime.
|
|
221
|
+
*
|
|
222
|
+
* Page-level variables provide values for sections without component references.
|
|
223
|
+
* They complement component-level vars (from $ref with $vars) for direct sections.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```typescript
|
|
227
|
+
* {
|
|
228
|
+
* vars: {
|
|
229
|
+
* siteName: 'Sovrium',
|
|
230
|
+
* primaryColor: 'blue'
|
|
231
|
+
* },
|
|
232
|
+
* sections: [
|
|
233
|
+
* {
|
|
234
|
+
* type: 'heading',
|
|
235
|
+
* content: 'Welcome to $siteName' // → 'Welcome to Sovrium'
|
|
236
|
+
* },
|
|
237
|
+
* {
|
|
238
|
+
* type: 'button',
|
|
239
|
+
* props: {
|
|
240
|
+
* className: 'bg-$primaryColor' // → 'bg-blue'
|
|
241
|
+
* }
|
|
242
|
+
* }
|
|
243
|
+
* ]
|
|
244
|
+
* }
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
vars: Schema.optional(
|
|
248
|
+
Schema.Record({
|
|
249
|
+
key: Schema.String,
|
|
250
|
+
value: Schema.Union(Schema.String, Schema.Number, Schema.Boolean),
|
|
251
|
+
})
|
|
252
|
+
),
|
|
253
|
+
}).pipe(
|
|
254
|
+
Schema.annotations({
|
|
255
|
+
identifier: 'Page',
|
|
256
|
+
title: 'Page',
|
|
257
|
+
description:
|
|
258
|
+
'Complete page configuration with metadata, layout, sections, and scripts. Pages use a component-based layout system with reusable component templates.',
|
|
259
|
+
})
|
|
260
|
+
)
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* TypeScript type for a Page
|
|
264
|
+
*/
|
|
265
|
+
export type Page = typeof PageSchema.Type
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* TypeScript type for an encoded Page (before validation)
|
|
269
|
+
*/
|
|
270
|
+
export type PageEncoded = typeof PageSchema.Encoded
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Schema } from 'effect'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Analytics provider name
|
|
12
|
+
*
|
|
13
|
+
* 6 supported analytics platforms:
|
|
14
|
+
* - google: Google Analytics 4 (most popular, 60% market share)
|
|
15
|
+
* - plausible: Privacy-focused, GDPR-compliant, no cookies
|
|
16
|
+
* - matomo: Open-source, self-hosted, privacy-focused
|
|
17
|
+
* - fathom: Privacy-first, simple, GDPR-compliant
|
|
18
|
+
* - posthog: Product analytics, session replay, feature flags
|
|
19
|
+
* - mixpanel: Product analytics, funnel analysis, cohort analysis
|
|
20
|
+
*/
|
|
21
|
+
export const AnalyticsProviderNameSchema = Schema.Literal(
|
|
22
|
+
'google',
|
|
23
|
+
'plausible',
|
|
24
|
+
'matomo',
|
|
25
|
+
'fathom',
|
|
26
|
+
'posthog',
|
|
27
|
+
'mixpanel'
|
|
28
|
+
).annotations({
|
|
29
|
+
description: 'Analytics provider name',
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Analytics script configuration
|
|
34
|
+
*
|
|
35
|
+
* External JavaScript file to load for analytics provider.
|
|
36
|
+
*
|
|
37
|
+
* Required properties:
|
|
38
|
+
* - src: Script source URL (CDN or provider-hosted)
|
|
39
|
+
*
|
|
40
|
+
* Optional properties:
|
|
41
|
+
* - async: Load asynchronously (default: true, recommended for analytics)
|
|
42
|
+
* - defer: Defer execution until DOM loaded
|
|
43
|
+
*/
|
|
44
|
+
export const AnalyticsScriptSchema = Schema.Struct({
|
|
45
|
+
src: Schema.String.annotations({
|
|
46
|
+
description: 'Script source URL',
|
|
47
|
+
format: 'uri',
|
|
48
|
+
}),
|
|
49
|
+
async: Schema.optional(
|
|
50
|
+
Schema.Boolean.annotations({
|
|
51
|
+
description: 'Load script asynchronously',
|
|
52
|
+
default: true,
|
|
53
|
+
})
|
|
54
|
+
),
|
|
55
|
+
defer: Schema.optional(
|
|
56
|
+
Schema.Boolean.annotations({
|
|
57
|
+
description: 'Defer script execution',
|
|
58
|
+
})
|
|
59
|
+
),
|
|
60
|
+
}).annotations({
|
|
61
|
+
description: 'Analytics script',
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Analytics provider configuration
|
|
66
|
+
*
|
|
67
|
+
* Defines a single analytics provider with scripts, initialization, and settings.
|
|
68
|
+
*
|
|
69
|
+
* Required properties:
|
|
70
|
+
* - name: Provider name (google, plausible, matomo, fathom, posthog, mixpanel)
|
|
71
|
+
*
|
|
72
|
+
* Optional properties:
|
|
73
|
+
* - enabled: Whether provider is active (default: true)
|
|
74
|
+
* - scripts: Array of external scripts to load
|
|
75
|
+
* - initScript: Inline JavaScript for provider initialization
|
|
76
|
+
* - dnsPrefetch: Domain to DNS prefetch (performance optimization)
|
|
77
|
+
* - config: Provider-specific configuration (tracking IDs, privacy settings, features)
|
|
78
|
+
*
|
|
79
|
+
* Common pattern:
|
|
80
|
+
* 1. Load external script(s) from CDN (scripts array)
|
|
81
|
+
* 2. Run initialization code (initScript)
|
|
82
|
+
* 3. Configure with provider settings (config object)
|
|
83
|
+
*
|
|
84
|
+
* Performance optimization:
|
|
85
|
+
* - async: true (default) - non-blocking script load
|
|
86
|
+
* - dnsPrefetch: Early DNS resolution for faster script load
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* const googleAnalytics = {
|
|
91
|
+
* name: 'google',
|
|
92
|
+
* enabled: true,
|
|
93
|
+
* scripts: [
|
|
94
|
+
* {
|
|
95
|
+
* src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXX',
|
|
96
|
+
* async: true
|
|
97
|
+
* }
|
|
98
|
+
* ],
|
|
99
|
+
* initScript: `
|
|
100
|
+
* window.dataLayer = window.dataLayer || [];
|
|
101
|
+
* function gtag(){dataLayer.push(arguments);}
|
|
102
|
+
* gtag('js', new Date());
|
|
103
|
+
* gtag('config', 'G-XXXXX');
|
|
104
|
+
* `,
|
|
105
|
+
* dnsPrefetch: 'https://www.googletagmanager.com',
|
|
106
|
+
* config: {
|
|
107
|
+
* trackingId: 'G-XXXXX',
|
|
108
|
+
* anonymizeIp: true
|
|
109
|
+
* }
|
|
110
|
+
* }
|
|
111
|
+
*
|
|
112
|
+
* const plausible = {
|
|
113
|
+
* name: 'plausible',
|
|
114
|
+
* enabled: true,
|
|
115
|
+
* scripts: [
|
|
116
|
+
* {
|
|
117
|
+
* src: 'https://plausible.io/js/script.js',
|
|
118
|
+
* async: true,
|
|
119
|
+
* defer: true
|
|
120
|
+
* }
|
|
121
|
+
* ],
|
|
122
|
+
* dnsPrefetch: 'https://plausible.io',
|
|
123
|
+
* config: {
|
|
124
|
+
* domain: 'example.com'
|
|
125
|
+
* }
|
|
126
|
+
* }
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @see specs/app/pages/meta/analytics/analytics.schema.json
|
|
130
|
+
*/
|
|
131
|
+
export const AnalyticsProviderSchema = Schema.Struct({
|
|
132
|
+
name: AnalyticsProviderNameSchema,
|
|
133
|
+
enabled: Schema.optional(
|
|
134
|
+
Schema.Boolean.annotations({
|
|
135
|
+
description: 'Whether this provider is enabled',
|
|
136
|
+
default: true,
|
|
137
|
+
})
|
|
138
|
+
),
|
|
139
|
+
scripts: Schema.optional(Schema.Array(AnalyticsScriptSchema)),
|
|
140
|
+
initScript: Schema.optional(
|
|
141
|
+
Schema.String.annotations({
|
|
142
|
+
description: 'Inline JavaScript to initialize the analytics',
|
|
143
|
+
})
|
|
144
|
+
),
|
|
145
|
+
dnsPrefetch: Schema.optional(
|
|
146
|
+
Schema.String.annotations({
|
|
147
|
+
description: 'Domain to DNS prefetch for this provider',
|
|
148
|
+
format: 'uri',
|
|
149
|
+
})
|
|
150
|
+
),
|
|
151
|
+
config: Schema.optional(
|
|
152
|
+
Schema.Record({
|
|
153
|
+
key: Schema.String,
|
|
154
|
+
value: Schema.Unknown,
|
|
155
|
+
}).annotations({
|
|
156
|
+
description: 'Provider-specific configuration',
|
|
157
|
+
})
|
|
158
|
+
),
|
|
159
|
+
}).annotations({
|
|
160
|
+
description: 'Analytics provider',
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Analytics configuration for multiple providers
|
|
165
|
+
*
|
|
166
|
+
* Manages analytics tracking across one or more analytics platforms.
|
|
167
|
+
* Supports simultaneous tracking with multiple providers for:
|
|
168
|
+
* - Transition periods (migrating between providers)
|
|
169
|
+
* - Compliance (privacy-friendly for EU, full-featured for others)
|
|
170
|
+
* - Comparison (data quality validation)
|
|
171
|
+
* - Redundancy (backup if one fails)
|
|
172
|
+
*
|
|
173
|
+
* Required properties:
|
|
174
|
+
* - providers: Array of analytics provider configurations
|
|
175
|
+
*
|
|
176
|
+
* Provider categories:
|
|
177
|
+
* 1. **Privacy-focused** (GDPR-compliant, no cookies):
|
|
178
|
+
* - plausible: < 1KB, simple dashboards
|
|
179
|
+
* - matomo: Open-source, self-hosted
|
|
180
|
+
* - fathom: Minimal, privacy-first
|
|
181
|
+
*
|
|
182
|
+
* 2. **Full-featured** (detailed analytics):
|
|
183
|
+
* - google: Free, most popular, integrates with Ads
|
|
184
|
+
* - posthog: Product analytics, session replay, feature flags
|
|
185
|
+
* - mixpanel: Funnel analysis, cohorts, retention
|
|
186
|
+
*
|
|
187
|
+
* Integration notes:
|
|
188
|
+
* - All scripts load asynchronously (non-blocking)
|
|
189
|
+
* - DNS prefetch optimizes external script loading
|
|
190
|
+
* - Config object flexible (additionalProperties: true)
|
|
191
|
+
* - Each provider independent (isolated initialization)
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* ```typescript
|
|
195
|
+
* const analytics = {
|
|
196
|
+
* providers: [
|
|
197
|
+
* // Privacy-friendly for all users
|
|
198
|
+
* {
|
|
199
|
+
* name: 'plausible',
|
|
200
|
+
* enabled: true,
|
|
201
|
+
* scripts: [
|
|
202
|
+
* {
|
|
203
|
+
* src: 'https://plausible.io/js/script.js',
|
|
204
|
+
* async: true
|
|
205
|
+
* }
|
|
206
|
+
* ],
|
|
207
|
+
* config: {
|
|
208
|
+
* domain: 'example.com'
|
|
209
|
+
* }
|
|
210
|
+
* },
|
|
211
|
+
* // Full-featured for detailed insights
|
|
212
|
+
* {
|
|
213
|
+
* name: 'google',
|
|
214
|
+
* enabled: true,
|
|
215
|
+
* scripts: [
|
|
216
|
+
* {
|
|
217
|
+
* src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXX',
|
|
218
|
+
* async: true
|
|
219
|
+
* }
|
|
220
|
+
* ],
|
|
221
|
+
* initScript: `
|
|
222
|
+
* window.dataLayer = window.dataLayer || [];
|
|
223
|
+
* function gtag(){dataLayer.push(arguments);}
|
|
224
|
+
* gtag('js', new Date());
|
|
225
|
+
* gtag('config', 'G-XXXXX');
|
|
226
|
+
* `,
|
|
227
|
+
* config: {
|
|
228
|
+
* trackingId: 'G-XXXXX',
|
|
229
|
+
* anonymizeIp: true
|
|
230
|
+
* }
|
|
231
|
+
* }
|
|
232
|
+
* ]
|
|
233
|
+
* }
|
|
234
|
+
* ```
|
|
235
|
+
*
|
|
236
|
+
* @see specs/app/pages/meta/analytics/analytics.schema.json
|
|
237
|
+
*/
|
|
238
|
+
export const AnalyticsSchema = Schema.Struct({
|
|
239
|
+
providers: Schema.Array(AnalyticsProviderSchema),
|
|
240
|
+
}).annotations({
|
|
241
|
+
title: 'Analytics Configuration',
|
|
242
|
+
description: 'Configuration for analytics providers',
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
export type AnalyticsProviderName = Schema.Schema.Type<typeof AnalyticsProviderNameSchema>
|
|
246
|
+
export type AnalyticsScript = Schema.Schema.Type<typeof AnalyticsScriptSchema>
|
|
247
|
+
export type AnalyticsProvider = Schema.Schema.Type<typeof AnalyticsProviderSchema>
|
|
248
|
+
export type Analytics = Schema.Schema.Type<typeof AnalyticsSchema>
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Schema } from 'effect'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Custom head element type
|
|
12
|
+
*
|
|
13
|
+
* 5 HTML elements allowed in <head>:
|
|
14
|
+
* - meta: Metadata (charset, viewport, theme-color, etc.)
|
|
15
|
+
* - link: External resources (stylesheets, preconnect, dns-prefetch)
|
|
16
|
+
* - script: JavaScript files or inline code
|
|
17
|
+
* - style: Inline CSS styles
|
|
18
|
+
* - base: Base URL for relative URLs
|
|
19
|
+
*/
|
|
20
|
+
export const CustomElementTypeSchema = Schema.Literal(
|
|
21
|
+
'meta',
|
|
22
|
+
'link',
|
|
23
|
+
'script',
|
|
24
|
+
'style',
|
|
25
|
+
'base'
|
|
26
|
+
).annotations({
|
|
27
|
+
description: 'HTML element type',
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Custom head element
|
|
32
|
+
*
|
|
33
|
+
* Allows adding arbitrary HTML elements to the page <head> section.
|
|
34
|
+
* Useful for custom meta tags, third-party integrations, or special configurations.
|
|
35
|
+
*
|
|
36
|
+
* Required properties:
|
|
37
|
+
* - type: HTML element type (meta, link, script, style, base)
|
|
38
|
+
*
|
|
39
|
+
* Optional properties:
|
|
40
|
+
* - attrs: Object of HTML attributes (kebab-case keys, string values)
|
|
41
|
+
* - content: Inner content for script or style elements
|
|
42
|
+
*
|
|
43
|
+
* Common use cases:
|
|
44
|
+
* - Custom meta tags: theme-color, apple-mobile-web-app-capable
|
|
45
|
+
* - Preconnect/DNS prefetch: Speed up external resource loading
|
|
46
|
+
* - Third-party scripts: Analytics, chat widgets not covered by analytics config
|
|
47
|
+
* - Inline styles: Critical CSS for above-the-fold content
|
|
48
|
+
*
|
|
49
|
+
* Attribute naming:
|
|
50
|
+
* - Keys must be kebab-case (data-theme, http-equiv, charset)
|
|
51
|
+
* - Values are always strings
|
|
52
|
+
* - Pattern: ^[a-zA-Z][a-zA-Z0-9-]*$
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* const themeColorMeta = {
|
|
57
|
+
* type: 'meta',
|
|
58
|
+
* attrs: {
|
|
59
|
+
* name: 'theme-color',
|
|
60
|
+
* content: '#FFAF00'
|
|
61
|
+
* }
|
|
62
|
+
* }
|
|
63
|
+
*
|
|
64
|
+
* const viewportMeta = {
|
|
65
|
+
* type: 'meta',
|
|
66
|
+
* attrs: {
|
|
67
|
+
* name: 'viewport',
|
|
68
|
+
* content: 'width=device-width, initial-scale=1'
|
|
69
|
+
* }
|
|
70
|
+
* }
|
|
71
|
+
*
|
|
72
|
+
* const preconnectLink = {
|
|
73
|
+
* type: 'link',
|
|
74
|
+
* attrs: {
|
|
75
|
+
* rel: 'preconnect',
|
|
76
|
+
* href: 'https://fonts.gstatic.com'
|
|
77
|
+
* }
|
|
78
|
+
* }
|
|
79
|
+
*
|
|
80
|
+
* const inlineScript = {
|
|
81
|
+
* type: 'script',
|
|
82
|
+
* content: "console.log('Custom script');"
|
|
83
|
+
* }
|
|
84
|
+
*
|
|
85
|
+
* const criticalCSS = {
|
|
86
|
+
* type: 'style',
|
|
87
|
+
* content: 'body { margin: 0; padding: 0; }'
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @see specs/app/pages/meta/custom-elements/custom-elements.schema.json
|
|
92
|
+
*/
|
|
93
|
+
export const CustomElementSchema = Schema.Struct({
|
|
94
|
+
type: CustomElementTypeSchema,
|
|
95
|
+
attrs: Schema.optional(
|
|
96
|
+
Schema.Record({
|
|
97
|
+
key: Schema.String.pipe(
|
|
98
|
+
Schema.pattern(/^[a-zA-Z][a-zA-Z0-9-]*$/, {
|
|
99
|
+
message: () =>
|
|
100
|
+
'Attribute name must start with a letter and contain only letters, numbers, and hyphens (kebab-case)',
|
|
101
|
+
})
|
|
102
|
+
),
|
|
103
|
+
value: Schema.String,
|
|
104
|
+
}).annotations({
|
|
105
|
+
description: 'Element attributes',
|
|
106
|
+
})
|
|
107
|
+
),
|
|
108
|
+
content: Schema.optional(
|
|
109
|
+
Schema.String.annotations({
|
|
110
|
+
description: 'Inner content for script or style elements',
|
|
111
|
+
})
|
|
112
|
+
),
|
|
113
|
+
}).annotations({
|
|
114
|
+
description: 'Custom head element',
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Additional custom elements to add to the page head
|
|
119
|
+
*
|
|
120
|
+
* Array of custom HTML elements injected into the <head> section.
|
|
121
|
+
* Provides escape hatch for custom meta tags, scripts, styles not
|
|
122
|
+
* covered by dedicated schemas (analytics, favicons, social, etc.).
|
|
123
|
+
*
|
|
124
|
+
* Common use cases:
|
|
125
|
+
* - Mobile web app meta tags (apple-mobile-web-app-capable, mobile-web-app-capable)
|
|
126
|
+
* - Theme customization (theme-color, color-scheme)
|
|
127
|
+
* - Performance optimization (preconnect, dns-prefetch for custom CDNs)
|
|
128
|
+
* - Third-party integrations (chat widgets, analytics not in analytics schema)
|
|
129
|
+
* - Critical CSS (inline styles for above-the-fold content)
|
|
130
|
+
*
|
|
131
|
+
* Order matters:
|
|
132
|
+
* - Meta tags: First (charset, viewport)
|
|
133
|
+
* - Preconnect/DNS prefetch: Early (before scripts that use those domains)
|
|
134
|
+
* - Styles: Before visual content
|
|
135
|
+
* - Scripts: Last (unless critical)
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const customElements = [
|
|
140
|
+
* // Mobile web app configuration
|
|
141
|
+
* {
|
|
142
|
+
* type: 'meta',
|
|
143
|
+
* attrs: {
|
|
144
|
+
* name: 'apple-mobile-web-app-capable',
|
|
145
|
+
* content: 'yes'
|
|
146
|
+
* }
|
|
147
|
+
* },
|
|
148
|
+
* {
|
|
149
|
+
* type: 'meta',
|
|
150
|
+
* attrs: {
|
|
151
|
+
* name: 'theme-color',
|
|
152
|
+
* content: '#FFAF00'
|
|
153
|
+
* }
|
|
154
|
+
* },
|
|
155
|
+
* // Performance optimization
|
|
156
|
+
* {
|
|
157
|
+
* type: 'link',
|
|
158
|
+
* attrs: {
|
|
159
|
+
* rel: 'preconnect',
|
|
160
|
+
* href: 'https://fonts.gstatic.com'
|
|
161
|
+
* }
|
|
162
|
+
* },
|
|
163
|
+
* // Critical CSS
|
|
164
|
+
* {
|
|
165
|
+
* type: 'style',
|
|
166
|
+
* content: 'body{margin:0}*{box-sizing:border-box}'
|
|
167
|
+
* }
|
|
168
|
+
* ]
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* @see specs/app/pages/meta/custom-elements/custom-elements.schema.json
|
|
172
|
+
*/
|
|
173
|
+
export const CustomElementsSchema = Schema.Array(CustomElementSchema).annotations({
|
|
174
|
+
title: 'Custom Head Elements',
|
|
175
|
+
description: 'Additional custom elements to add to the page head',
|
|
176
|
+
})
|
|
177
|
+
|
|
178
|
+
export type CustomElementType = Schema.Schema.Type<typeof CustomElementTypeSchema>
|
|
179
|
+
export type CustomElement = Schema.Schema.Type<typeof CustomElementSchema>
|
|
180
|
+
export type CustomElements = Schema.Schema.Type<typeof CustomElementsSchema>
|