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,170 @@
|
|
|
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
|
+
* Component reference name (kebab-case identifier)
|
|
12
|
+
*
|
|
13
|
+
* Name of the component to reference (must match a component name in the components array).
|
|
14
|
+
* Uses kebab-case format for consistency with web standards.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const ref1 = 'icon-badge'
|
|
19
|
+
* const ref2 = 'section-header'
|
|
20
|
+
* const ref3 = 'call-to-action'
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @see specs/app/components/common/component-reference.schema.json#/properties/$ref
|
|
24
|
+
*/
|
|
25
|
+
export const ComponentReferenceNameSchema = Schema.String.pipe(
|
|
26
|
+
Schema.pattern(/^[a-z][a-z0-9-]*$/, {
|
|
27
|
+
message: () =>
|
|
28
|
+
'Component reference name must start with lowercase letter and contain only lowercase letters, numbers, and hyphens (kebab-case)',
|
|
29
|
+
}),
|
|
30
|
+
Schema.annotations({
|
|
31
|
+
title: 'Component Reference Name',
|
|
32
|
+
description: 'Name of the component to reference (kebab-case)',
|
|
33
|
+
examples: ['icon-badge', 'section-header', 'call-to-action'],
|
|
34
|
+
})
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Component variables (for template substitution)
|
|
39
|
+
*
|
|
40
|
+
* Variables to substitute in the component template.
|
|
41
|
+
* Keys are alphanumeric identifiers, values are strings, numbers, or booleans.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```typescript
|
|
45
|
+
* const vars = {
|
|
46
|
+
* color: 'orange',
|
|
47
|
+
* icon: 'users',
|
|
48
|
+
* text: '6 à 15 personnes',
|
|
49
|
+
* count: 10,
|
|
50
|
+
* enabled: true,
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* @see specs/app/components/common/component-reference.schema.json#/properties/vars
|
|
55
|
+
*/
|
|
56
|
+
export const ComponentVarsSchema = Schema.Record({
|
|
57
|
+
key: Schema.String.pipe(
|
|
58
|
+
Schema.pattern(/^[a-zA-Z][a-zA-Z0-9]*$/, {
|
|
59
|
+
message: () =>
|
|
60
|
+
'Component variable key must start with a letter and contain only alphanumeric characters',
|
|
61
|
+
}),
|
|
62
|
+
Schema.annotations({
|
|
63
|
+
title: 'Component Variable Key',
|
|
64
|
+
description: 'Variable name (alphanumeric)',
|
|
65
|
+
examples: ['color', 'icon', 'text', 'titleColor'],
|
|
66
|
+
})
|
|
67
|
+
),
|
|
68
|
+
value: Schema.Union(Schema.String, Schema.Number, Schema.Boolean),
|
|
69
|
+
}).pipe(
|
|
70
|
+
Schema.annotations({
|
|
71
|
+
title: 'Component Variables',
|
|
72
|
+
description: 'Variables to substitute in the component template',
|
|
73
|
+
})
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Simple Component Reference (reference to a component by name without variables)
|
|
78
|
+
*
|
|
79
|
+
* Simplified syntax for referencing components that don't require variable substitution.
|
|
80
|
+
* Uses the `component` property to identify the component by name.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const simpleReference = {
|
|
85
|
+
* component: 'shared-component'
|
|
86
|
+
* }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export const SimpleComponentReferenceSchema = Schema.Struct({
|
|
90
|
+
component: ComponentReferenceNameSchema,
|
|
91
|
+
}).pipe(
|
|
92
|
+
Schema.annotations({
|
|
93
|
+
title: 'Simple Component Reference',
|
|
94
|
+
description: 'Reference to a component by name without variable substitution',
|
|
95
|
+
})
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Component Reference (reference to a reusable component template with variable substitution)
|
|
100
|
+
*
|
|
101
|
+
* Allows referencing and customizing predefined component templates.
|
|
102
|
+
* Supports two syntaxes:
|
|
103
|
+
* 1. Full syntax: { $ref: 'component-name', vars: {...} }
|
|
104
|
+
* 2. Shorthand syntax: { component: 'component-name' } (vars default to empty object)
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ```typescript
|
|
108
|
+
* // Full syntax
|
|
109
|
+
* const reference1 = {
|
|
110
|
+
* $ref: 'icon-badge',
|
|
111
|
+
* vars: {
|
|
112
|
+
* color: 'orange',
|
|
113
|
+
* icon: 'users',
|
|
114
|
+
* text: '6 à 15 personnes',
|
|
115
|
+
* },
|
|
116
|
+
* }
|
|
117
|
+
*
|
|
118
|
+
* // Shorthand syntax
|
|
119
|
+
* const reference2 = {
|
|
120
|
+
* component: 'shared-component',
|
|
121
|
+
* }
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @see specs/app/components/common/component-reference.schema.json
|
|
125
|
+
*/
|
|
126
|
+
const FullComponentReferenceSchema = Schema.Struct({
|
|
127
|
+
$ref: ComponentReferenceNameSchema,
|
|
128
|
+
vars: ComponentVarsSchema,
|
|
129
|
+
}).pipe(
|
|
130
|
+
Schema.annotations({
|
|
131
|
+
title: 'Component Reference (Full Syntax)',
|
|
132
|
+
description: 'Reference to a reusable component template with variable substitution',
|
|
133
|
+
})
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
const ShorthandComponentReferenceSchema = Schema.Struct({
|
|
137
|
+
component: ComponentReferenceNameSchema,
|
|
138
|
+
}).pipe(
|
|
139
|
+
Schema.annotations({
|
|
140
|
+
title: 'Component Reference (Shorthand)',
|
|
141
|
+
description: 'Shorthand reference to a reusable component without variables',
|
|
142
|
+
})
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
const HybridComponentReferenceSchema = Schema.Struct({
|
|
146
|
+
component: ComponentReferenceNameSchema,
|
|
147
|
+
vars: ComponentVarsSchema,
|
|
148
|
+
}).pipe(
|
|
149
|
+
Schema.annotations({
|
|
150
|
+
title: 'Component Reference (Hybrid)',
|
|
151
|
+
description: 'Shorthand component reference with variable substitution',
|
|
152
|
+
})
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
export const ComponentReferenceSchema = Schema.Union(
|
|
156
|
+
FullComponentReferenceSchema,
|
|
157
|
+
HybridComponentReferenceSchema,
|
|
158
|
+
ShorthandComponentReferenceSchema
|
|
159
|
+
).pipe(
|
|
160
|
+
Schema.annotations({
|
|
161
|
+
title: 'Component Reference',
|
|
162
|
+
description:
|
|
163
|
+
'Reference to a reusable component template. Supports full syntax ($ref + vars), hybrid syntax (component + vars), or shorthand (component name only).',
|
|
164
|
+
})
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
export type ComponentReferenceName = Schema.Schema.Type<typeof ComponentReferenceNameSchema>
|
|
168
|
+
export type ComponentVars = Schema.Schema.Type<typeof ComponentVarsSchema>
|
|
169
|
+
export type SimpleComponentReference = Schema.Schema.Type<typeof SimpleComponentReferenceSchema>
|
|
170
|
+
export type ComponentReference = Schema.Schema.Type<typeof ComponentReferenceSchema>
|
|
@@ -0,0 +1,81 @@
|
|
|
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 { ComponentChildrenSchema } from './common/component-children'
|
|
10
|
+
import { ComponentPropsSchema } from './common/component-props'
|
|
11
|
+
import { ComponentReferenceNameSchema } from './common/component-reference'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Component template name identifier (same pattern as component reference name)
|
|
15
|
+
*
|
|
16
|
+
* Must be in kebab-case:
|
|
17
|
+
* - Start with lowercase letter
|
|
18
|
+
* - Contain only lowercase letters, numbers, and hyphens
|
|
19
|
+
* - Used for data-testid generation: data-testid="component-{name}"
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const names = ['icon-badge', 'section-header', 'feature-card', 'cta-button-2']
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export const ComponentTemplateNameSchema = ComponentReferenceNameSchema.annotations({
|
|
27
|
+
title: 'Component Template Name',
|
|
28
|
+
description: 'Unique component template identifier in kebab-case',
|
|
29
|
+
examples: ['icon-badge', 'section-header', 'feature-card', 'cta-button-2'],
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Reusable UI component template with variable placeholders
|
|
34
|
+
*
|
|
35
|
+
* A component template defines the structure of a reusable component that can be
|
|
36
|
+
* instantiated multiple times with different data via component references.
|
|
37
|
+
*
|
|
38
|
+
* Required properties:
|
|
39
|
+
* - name: Unique identifier (kebab-case)
|
|
40
|
+
* - type: Component type (container, flex, grid, card, text, button, etc.)
|
|
41
|
+
*
|
|
42
|
+
* Optional properties:
|
|
43
|
+
* - props: Component properties (may contain $variable placeholders)
|
|
44
|
+
* - children: Nested child components
|
|
45
|
+
* - content: Text content (may contain $variable placeholders)
|
|
46
|
+
*
|
|
47
|
+
* @example
|
|
48
|
+
* ```typescript
|
|
49
|
+
* const component = {
|
|
50
|
+
* name: 'icon-badge',
|
|
51
|
+
* type: 'badge',
|
|
52
|
+
* props: { color: '$color' },
|
|
53
|
+
* children: [
|
|
54
|
+
* { type: 'icon', props: { name: '$icon', size: 4 } },
|
|
55
|
+
* { type: 'text', props: { level: 'span' }, content: '$text' }
|
|
56
|
+
* ]
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*
|
|
60
|
+
* @see specs/app/components/component/component.schema.json
|
|
61
|
+
*/
|
|
62
|
+
export const ComponentTemplateSchema = Schema.Struct({
|
|
63
|
+
name: ComponentTemplateNameSchema,
|
|
64
|
+
type: Schema.String.annotations({
|
|
65
|
+
description: 'Component type',
|
|
66
|
+
examples: ['container', 'flex', 'grid', 'card', 'text', 'button'],
|
|
67
|
+
}),
|
|
68
|
+
props: Schema.optional(ComponentPropsSchema),
|
|
69
|
+
children: Schema.optional(ComponentChildrenSchema),
|
|
70
|
+
content: Schema.optional(
|
|
71
|
+
Schema.String.annotations({
|
|
72
|
+
description: 'Text content (may contain $variable references)',
|
|
73
|
+
})
|
|
74
|
+
),
|
|
75
|
+
}).annotations({
|
|
76
|
+
title: 'Component Template',
|
|
77
|
+
description: 'A reusable UI component template with variable placeholders',
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
export type ComponentTemplateName = Schema.Schema.Type<typeof ComponentTemplateNameSchema>
|
|
81
|
+
export type ComponentTemplate = Schema.Schema.Type<typeof ComponentTemplateSchema>
|
|
@@ -0,0 +1,65 @@
|
|
|
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 { ComponentTemplateSchema } from './component/component'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Array of reusable UI component templates
|
|
13
|
+
*
|
|
14
|
+
* Components provide a library that can be referenced across pages
|
|
15
|
+
* using the $ref pattern. Each component defines a template with variable
|
|
16
|
+
* placeholders ($variable) that are substituted when the component is instantiated.
|
|
17
|
+
*
|
|
18
|
+
* Benefits:
|
|
19
|
+
* - DRY: Define once, reuse multiple times
|
|
20
|
+
* - Consistency: Centralized updates affect all instances
|
|
21
|
+
* - Maintainability: Single source of truth for UI patterns
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const components = [
|
|
26
|
+
* {
|
|
27
|
+
* name: 'icon-badge',
|
|
28
|
+
* type: 'badge',
|
|
29
|
+
* props: { color: '$color' },
|
|
30
|
+
* children: [
|
|
31
|
+
* { type: 'icon', props: { name: '$icon' } },
|
|
32
|
+
* { type: 'text', content: '$text' }
|
|
33
|
+
* ]
|
|
34
|
+
* },
|
|
35
|
+
* {
|
|
36
|
+
* name: 'section-header',
|
|
37
|
+
* type: 'container',
|
|
38
|
+
* props: { className: 'text-center mb-12' },
|
|
39
|
+
* children: [
|
|
40
|
+
* { type: 'text', props: { level: 'h2' }, content: '$title' },
|
|
41
|
+
* { type: 'text', props: { level: 'p' }, content: '$subtitle' }
|
|
42
|
+
* ]
|
|
43
|
+
* }
|
|
44
|
+
* ]
|
|
45
|
+
* ```
|
|
46
|
+
*
|
|
47
|
+
* @see specs/app/components/components.schema.json
|
|
48
|
+
*/
|
|
49
|
+
export const ComponentsSchema = Schema.Array(ComponentTemplateSchema).pipe(
|
|
50
|
+
Schema.filter((components) => {
|
|
51
|
+
const names = components.map((component) => component.name)
|
|
52
|
+
const uniqueNames = new Set(names)
|
|
53
|
+
return (
|
|
54
|
+
names.length === uniqueNames.size ||
|
|
55
|
+
'Component names must be unique within the components array'
|
|
56
|
+
)
|
|
57
|
+
}),
|
|
58
|
+
Schema.annotations({
|
|
59
|
+
title: 'Reusable Components',
|
|
60
|
+
description:
|
|
61
|
+
'Array of reusable UI component templates with variable substitution for use across pages',
|
|
62
|
+
})
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
export type Components = Schema.Schema.Type<typeof ComponentsSchema>
|
|
@@ -0,0 +1,83 @@
|
|
|
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
|
+
* Maximum length for application descriptions.
|
|
12
|
+
* This limit prevents UI/database issues with very long descriptions.
|
|
13
|
+
* Set to 2000 to accommodate long-form descriptions while preventing abuse.
|
|
14
|
+
*/
|
|
15
|
+
const DESCRIPTION_MAX_LENGTH = 2000
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* DescriptionSchema defines validation rules for application descriptions.
|
|
19
|
+
*
|
|
20
|
+
* Application descriptions must be single-line strings:
|
|
21
|
+
* - No line breaks allowed (\n, \r, or \r\n)
|
|
22
|
+
* - Maximum 2000 characters
|
|
23
|
+
* - Can contain any characters except line breaks
|
|
24
|
+
* - Empty strings are allowed
|
|
25
|
+
* - Unicode characters and emojis are supported
|
|
26
|
+
* - Special characters, spaces, and tabs are allowed
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* // Valid descriptions
|
|
31
|
+
* const desc1 = 'A simple application'
|
|
32
|
+
* const desc2 = 'My app - with special characters!@#$%'
|
|
33
|
+
* const desc3 = 'Très bien! 你好 🎉'
|
|
34
|
+
* const desc4 = ''
|
|
35
|
+
*
|
|
36
|
+
* // Invalid descriptions (contain line breaks or too long)
|
|
37
|
+
* const invalid1 = 'Multi\nline' // ❌ Contains \n
|
|
38
|
+
* const invalid2 = 'Windows\r\nbreak' // ❌ Contains \r\n
|
|
39
|
+
* const invalid3 = 'Mac\rbreak' // ❌ Contains \r
|
|
40
|
+
* const invalid4 = 'x'.repeat(2001) // ❌ Exceeds 2000 characters
|
|
41
|
+
*
|
|
42
|
+
* // Validate description
|
|
43
|
+
* const validated = Schema.decodeUnknownSync(DescriptionSchema)(desc1)
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export const DescriptionSchema = Schema.String.pipe(
|
|
47
|
+
Schema.pattern(/^[^\r\n]*$/, {
|
|
48
|
+
message: () => 'Description must be a single line (line breaks are not allowed)',
|
|
49
|
+
}),
|
|
50
|
+
Schema.maxLength(DESCRIPTION_MAX_LENGTH, {
|
|
51
|
+
message: () =>
|
|
52
|
+
`Description must be ${DESCRIPTION_MAX_LENGTH} characters or less (current length exceeds limit)`,
|
|
53
|
+
}),
|
|
54
|
+
Schema.annotations({
|
|
55
|
+
title: 'Application Description',
|
|
56
|
+
description: `A single-line description of the application (max ${DESCRIPTION_MAX_LENGTH} characters, no line breaks)`,
|
|
57
|
+
examples: [
|
|
58
|
+
'A simple application',
|
|
59
|
+
'My app - with special characters!@#$%',
|
|
60
|
+
'Très bien! 你好 🎉',
|
|
61
|
+
'Full-featured e-commerce platform with cart, checkout & payment processing',
|
|
62
|
+
],
|
|
63
|
+
})
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* TypeScript type inferred from DescriptionSchema.
|
|
68
|
+
*
|
|
69
|
+
* Use this type for type-safe access to validated description strings.
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const description: Description = 'A simple application'
|
|
74
|
+
* ```
|
|
75
|
+
*/
|
|
76
|
+
export type Description = Schema.Schema.Type<typeof DescriptionSchema>
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Encoded type of DescriptionSchema (what goes in).
|
|
80
|
+
*
|
|
81
|
+
* In this case, it's the same as Description since we don't use transformations.
|
|
82
|
+
*/
|
|
83
|
+
export type DescriptionEncoded = Schema.Schema.Encoded<typeof DescriptionSchema>
|
|
@@ -0,0 +1,258 @@
|
|
|
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 { BuiltInAnalyticsSchema } from './analytics'
|
|
10
|
+
import { AuthSchema } from './auth'
|
|
11
|
+
import { BUILT_IN_ROLES } from './auth/roles'
|
|
12
|
+
import { ComponentsSchema } from './components'
|
|
13
|
+
import { DescriptionSchema } from './description'
|
|
14
|
+
import { LanguagesSchema } from './languages'
|
|
15
|
+
import { NameSchema } from './name'
|
|
16
|
+
import { PagesSchema } from './pages'
|
|
17
|
+
import { TablesSchema } from './tables'
|
|
18
|
+
import { ThemeSchema } from './theme'
|
|
19
|
+
import { VersionSchema } from './version'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Helper to extract role names from a permission value.
|
|
23
|
+
* Permissions can be 'all', 'authenticated', or an array of role names.
|
|
24
|
+
*/
|
|
25
|
+
const extractRolesFromPermission = (permission: unknown): readonly string[] => {
|
|
26
|
+
if (!permission) return []
|
|
27
|
+
if (typeof permission === 'string') return [] // 'all' or 'authenticated'
|
|
28
|
+
if (Array.isArray(permission)) return permission as readonly string[]
|
|
29
|
+
return []
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* AppSchema defines the structure of an application configuration.
|
|
34
|
+
*
|
|
35
|
+
* This schema represents the core metadata for any application built
|
|
36
|
+
* with Sovrium, including its name, optional version, and optional description.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```typescript
|
|
40
|
+
* const myApp = {
|
|
41
|
+
* name: 'todo-app',
|
|
42
|
+
* version: '1.0.0',
|
|
43
|
+
* description: 'A simple todo list application',
|
|
44
|
+
* }
|
|
45
|
+
*
|
|
46
|
+
* const validated = Schema.decodeUnknownSync(AppSchema)(myApp)
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export const AppSchema = Schema.Struct({
|
|
50
|
+
/**
|
|
51
|
+
* The name of the application.
|
|
52
|
+
*
|
|
53
|
+
* Must follow npm package naming conventions:
|
|
54
|
+
* - Lowercase only
|
|
55
|
+
* - Maximum 214 characters (including scope for scoped packages)
|
|
56
|
+
* - Cannot start with a dot or underscore
|
|
57
|
+
* - Cannot contain leading/trailing spaces
|
|
58
|
+
* - Cannot contain non-URL-safe characters
|
|
59
|
+
* - Scoped packages: @scope/package-name format allowed
|
|
60
|
+
* - Can include hyphens and underscores (but not at the start)
|
|
61
|
+
*/
|
|
62
|
+
name: NameSchema,
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The version of the application (optional).
|
|
66
|
+
*
|
|
67
|
+
* Must follow Semantic Versioning (SemVer) 2.0.0 specification:
|
|
68
|
+
* - Format: MAJOR.MINOR.PATCH (e.g., 1.0.0)
|
|
69
|
+
* - No leading zeros in version components
|
|
70
|
+
* - Optional pre-release identifiers (e.g., 1.0.0-alpha)
|
|
71
|
+
* - Optional build metadata (e.g., 1.0.0+build.123)
|
|
72
|
+
*/
|
|
73
|
+
version: Schema.optional(VersionSchema),
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* A description of the application (optional).
|
|
77
|
+
*
|
|
78
|
+
* Must be a single-line string:
|
|
79
|
+
* - No line breaks allowed (\n, \r, or \r\n)
|
|
80
|
+
* - No maximum length restriction
|
|
81
|
+
* - Can contain any characters except line breaks
|
|
82
|
+
* - Unicode characters and emojis are supported
|
|
83
|
+
*/
|
|
84
|
+
description: Schema.optional(DescriptionSchema),
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Data tables that define the data structure (optional).
|
|
88
|
+
*
|
|
89
|
+
* Collection of database tables that define the data structure of your application.
|
|
90
|
+
* Each table represents an entity (e.g., users, products, orders) with fields that
|
|
91
|
+
* define the schema. Tables support relationships, indexes, constraints, and various
|
|
92
|
+
* field types.
|
|
93
|
+
*/
|
|
94
|
+
tables: Schema.optional(TablesSchema),
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Design system configuration (optional).
|
|
98
|
+
*
|
|
99
|
+
* Unified design tokens for colors, typography, spacing, animations, breakpoints,
|
|
100
|
+
* shadows, and border radius. Theme applies globally to all pages via className
|
|
101
|
+
* utilities and CSS variables.
|
|
102
|
+
*/
|
|
103
|
+
theme: Schema.optional(ThemeSchema),
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Multi-language support configuration (optional).
|
|
107
|
+
*
|
|
108
|
+
* Defines supported languages, default language, translations, and i18n behavior
|
|
109
|
+
* (browser detection, persistence). Pages reference translations using $t: syntax.
|
|
110
|
+
*/
|
|
111
|
+
languages: Schema.optional(LanguagesSchema),
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Authentication configuration (optional).
|
|
115
|
+
*
|
|
116
|
+
* Enables authentication features including email/password authentication,
|
|
117
|
+
* user management, and organization support. Configure authentication providers
|
|
118
|
+
* and optional plugins (admin, organization) based on application requirements.
|
|
119
|
+
*/
|
|
120
|
+
auth: Schema.optional(AuthSchema),
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Built-in analytics configuration (optional).
|
|
124
|
+
*
|
|
125
|
+
* Enables first-party, privacy-friendly analytics tracking without cookies
|
|
126
|
+
* or external dependencies. Configure data retention, excluded paths,
|
|
127
|
+
* session timeout, and Do Not Track behavior.
|
|
128
|
+
*/
|
|
129
|
+
analytics: Schema.optional(BuiltInAnalyticsSchema),
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Reusable UI components (optional).
|
|
133
|
+
*
|
|
134
|
+
* Array of reusable component templates with variable substitution. Components are
|
|
135
|
+
* defined once at app level and referenced across pages using $ref syntax with
|
|
136
|
+
* $vars for dynamic content.
|
|
137
|
+
*/
|
|
138
|
+
components: Schema.optional(ComponentsSchema),
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Marketing and content pages (optional).
|
|
142
|
+
*
|
|
143
|
+
* Array of page configurations with server-side rendering support. Pages use a
|
|
144
|
+
* component-based system with comprehensive metadata, theming, and i18n support.
|
|
145
|
+
* Minimum of 1 page required when pages property is present.
|
|
146
|
+
*/
|
|
147
|
+
pages: Schema.optional(PagesSchema),
|
|
148
|
+
}).pipe(
|
|
149
|
+
Schema.filter((app) => {
|
|
150
|
+
const userFieldTypes = new Set(['user', 'created-by', 'updated-by'])
|
|
151
|
+
const hasUserFields =
|
|
152
|
+
app.tables?.some((table) => table.fields.some((field) => userFieldTypes.has(field.type))) ??
|
|
153
|
+
false
|
|
154
|
+
|
|
155
|
+
if (hasUserFields && !app.auth) {
|
|
156
|
+
return 'User fields (user, created-by, updated-by) require auth configuration'
|
|
157
|
+
}
|
|
158
|
+
return true
|
|
159
|
+
}),
|
|
160
|
+
Schema.filter((app) => {
|
|
161
|
+
// Only validate role references in permissions when auth is explicitly configured.
|
|
162
|
+
// Without auth, custom role names in permissions are accepted (no validation context).
|
|
163
|
+
if (!app.auth || !app.tables || app.tables.length === 0) {
|
|
164
|
+
return true
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Build set of all valid roles: built-in + custom auth.roles
|
|
168
|
+
const customRoleNames = app.auth.roles?.map((role) => role.name) ?? []
|
|
169
|
+
const validRoles = new Set<string>([...BUILT_IN_ROLES, ...customRoleNames])
|
|
170
|
+
|
|
171
|
+
// Check all tables for invalid role references
|
|
172
|
+
const permissionKeys = ['create', 'read', 'update', 'delete', 'comment'] as const
|
|
173
|
+
const validationErrors = app.tables
|
|
174
|
+
.filter((table) => table.permissions)
|
|
175
|
+
.flatMap((table) => {
|
|
176
|
+
const tablePermissions = table.permissions as Record<string, unknown>
|
|
177
|
+
const allPermissionRoles = permissionKeys.flatMap((key) =>
|
|
178
|
+
extractRolesFromPermission(tablePermissions[key])
|
|
179
|
+
)
|
|
180
|
+
const invalidRole = allPermissionRoles.find((role) => !validRoles.has(role))
|
|
181
|
+
if (!invalidRole) return []
|
|
182
|
+
const sortedValidRoles = Array.from(validRoles).toSorted((a, b) => a.localeCompare(b))
|
|
183
|
+
return [
|
|
184
|
+
`Table '${table.name}' permissions reference undefined role '${invalidRole}'. Valid roles: ${sortedValidRoles.join(', ')}`,
|
|
185
|
+
]
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
return validationErrors.length > 0 ? validationErrors[0] : true
|
|
189
|
+
}),
|
|
190
|
+
Schema.annotations({
|
|
191
|
+
title: 'Application Configuration',
|
|
192
|
+
description:
|
|
193
|
+
'Complete application configuration including name, version, description, and data tables. This is the root schema for Sovrium applications.',
|
|
194
|
+
examples: [
|
|
195
|
+
{
|
|
196
|
+
name: 'todo-app',
|
|
197
|
+
version: '1.0.0',
|
|
198
|
+
description: 'A simple todo list application',
|
|
199
|
+
tables: [
|
|
200
|
+
{
|
|
201
|
+
id: 1,
|
|
202
|
+
name: 'tasks',
|
|
203
|
+
fields: [
|
|
204
|
+
{
|
|
205
|
+
id: 1,
|
|
206
|
+
name: 'title',
|
|
207
|
+
type: 'single-line-text' as const,
|
|
208
|
+
required: true,
|
|
209
|
+
},
|
|
210
|
+
{ id: 2, name: 'completed', type: 'checkbox' as const, required: true },
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
],
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
name: '@myorg/dashboard',
|
|
217
|
+
version: '2.0.0-beta.1',
|
|
218
|
+
description: 'Admin dashboard for analytics and reporting',
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
name: 'blog-system',
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
})
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* TypeScript type inferred from AppSchema.
|
|
229
|
+
*
|
|
230
|
+
* Use this type for type-safe access to validated application data.
|
|
231
|
+
*
|
|
232
|
+
* @example
|
|
233
|
+
* ```typescript
|
|
234
|
+
* const app: App = {
|
|
235
|
+
* name: 'my-app',
|
|
236
|
+
* }
|
|
237
|
+
* ```
|
|
238
|
+
*/
|
|
239
|
+
export type App = Schema.Schema.Type<typeof AppSchema>
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Encoded type of AppSchema (what goes in).
|
|
243
|
+
*
|
|
244
|
+
* In this case, it's the same as App since we don't use transformations.
|
|
245
|
+
*/
|
|
246
|
+
export type AppEncoded = Schema.Schema.Encoded<typeof AppSchema>
|
|
247
|
+
|
|
248
|
+
// Re-export all domain model schemas and types for convenient imports
|
|
249
|
+
export * from './analytics'
|
|
250
|
+
export * from './name'
|
|
251
|
+
export * from './version'
|
|
252
|
+
export * from './description'
|
|
253
|
+
export * from './tables'
|
|
254
|
+
export * from './theme'
|
|
255
|
+
export * from './languages'
|
|
256
|
+
export * from './auth'
|
|
257
|
+
export * from './components'
|
|
258
|
+
export * from './pages'
|