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,290 @@
|
|
|
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 { TableIdSchema } from '@/domain/models/app/common/branded-ids'
|
|
10
|
+
import { CheckConstraintsSchema } from './check-constraints'
|
|
11
|
+
import { FieldsSchema } from './fields'
|
|
12
|
+
import { ForeignKeySchema } from './foreign-keys'
|
|
13
|
+
import { IndexesSchema } from './indexes'
|
|
14
|
+
import { NameSchema } from './name'
|
|
15
|
+
import { TablePermissionsSchema } from './permissions'
|
|
16
|
+
import { PrimaryKeySchema } from './primary-key'
|
|
17
|
+
import { SPECIAL_FIELDS, validateFormulaFields } from './table-formula-validation'
|
|
18
|
+
import { validateIndexes } from './table-indexes-validation'
|
|
19
|
+
import { validateTablePermissions } from './table-permissions-validation'
|
|
20
|
+
import { validatePrimaryKey } from './table-primary-key-validation'
|
|
21
|
+
import { validateViews } from './table-views-validation'
|
|
22
|
+
import { UniqueConstraintsSchema } from './unique-constraints'
|
|
23
|
+
import { ViewSchema } from './views'
|
|
24
|
+
|
|
25
|
+
// Re-export SPECIAL_FIELDS for external use
|
|
26
|
+
export { SPECIAL_FIELDS }
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Table Schema
|
|
30
|
+
*
|
|
31
|
+
* Defines a single database table entity with its structure, fields, and constraints.
|
|
32
|
+
* Each table represents a distinct entity (e.g., users, products, orders) with fields
|
|
33
|
+
* that define the data schema. Tables support primary keys, unique constraints, and
|
|
34
|
+
* indexes for efficient data access and integrity.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const userTable = {
|
|
39
|
+
* id: 1,
|
|
40
|
+
* name: 'users',
|
|
41
|
+
* fields: [
|
|
42
|
+
* { id: 1, name: 'email', type: 'email', required: true },
|
|
43
|
+
* { id: 2, name: 'name', type: 'single-line-text', required: true }
|
|
44
|
+
* ],
|
|
45
|
+
* primaryKey: { fields: ['id'] },
|
|
46
|
+
* uniqueConstraints: [{ fields: ['email'] }]
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*
|
|
50
|
+
* @see docs/specifications/roadmap/tables.md for full specification
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Validate table schema including fields, permissions, views, and roles.
|
|
55
|
+
* Orchestrates all validation functions from extracted modules.
|
|
56
|
+
*
|
|
57
|
+
* IMPORTANT: This function uses a generic type parameter instead of an inline type annotation
|
|
58
|
+
* to avoid narrowing the Table type when used with Schema.filter(). Inline type annotations
|
|
59
|
+
* would cause TypeScript to narrow the schema's output type, removing properties like `id`,
|
|
60
|
+
* `required`, etc. from fields — cascading errors to all downstream consumers.
|
|
61
|
+
*
|
|
62
|
+
* @param table - Table to validate (type inferred from Schema.filter)
|
|
63
|
+
* @returns Validation error object if invalid, true if valid
|
|
64
|
+
*/
|
|
65
|
+
type ValidationError = { readonly message: string; readonly path: ReadonlyArray<string> }
|
|
66
|
+
|
|
67
|
+
const validateStructure = (
|
|
68
|
+
table: Record<string, unknown>,
|
|
69
|
+
fieldNames: ReadonlySet<string>
|
|
70
|
+
): ValidationError | undefined => {
|
|
71
|
+
if (table.primaryKey) {
|
|
72
|
+
const primaryKey = table.primaryKey as {
|
|
73
|
+
readonly type: string
|
|
74
|
+
readonly fields?: ReadonlyArray<string>
|
|
75
|
+
}
|
|
76
|
+
const primaryKeyError = validatePrimaryKey(primaryKey, fieldNames)
|
|
77
|
+
if (primaryKeyError) return primaryKeyError
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const indexes = table.indexes as
|
|
81
|
+
| ReadonlyArray<{ readonly name: string; readonly fields: ReadonlyArray<string> }>
|
|
82
|
+
| undefined
|
|
83
|
+
if (indexes && indexes.length > 0) {
|
|
84
|
+
const indexError = validateIndexes(indexes, fieldNames)
|
|
85
|
+
if (indexError) return indexError
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return undefined
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const validateAccessAndViews = (
|
|
92
|
+
table: Record<string, unknown>,
|
|
93
|
+
fields: ReadonlyArray<{
|
|
94
|
+
readonly name: string
|
|
95
|
+
readonly type: string
|
|
96
|
+
readonly formula?: string
|
|
97
|
+
}>,
|
|
98
|
+
fieldNames: ReadonlySet<string>
|
|
99
|
+
): ValidationError | undefined => {
|
|
100
|
+
if (table.permissions) {
|
|
101
|
+
const permissions = table.permissions as {
|
|
102
|
+
readonly fields?: ReadonlyArray<{ readonly field: string }>
|
|
103
|
+
}
|
|
104
|
+
const permissionsError = validateTablePermissions(permissions, fields, fieldNames)
|
|
105
|
+
if (permissionsError) return permissionsError
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const views = table.views as
|
|
109
|
+
| ReadonlyArray<{ readonly id: string | number; readonly isDefault?: boolean }>
|
|
110
|
+
| undefined
|
|
111
|
+
if (views && views.length > 0) {
|
|
112
|
+
const viewsError = validateViews(views, fields, fieldNames)
|
|
113
|
+
if (viewsError) return viewsError
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return undefined
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const validateTableSchema = (table: Record<string, unknown>): ValidationError | true => {
|
|
120
|
+
const fields = table.fields as ReadonlyArray<{
|
|
121
|
+
readonly name: string
|
|
122
|
+
readonly type: string
|
|
123
|
+
readonly formula?: string
|
|
124
|
+
}>
|
|
125
|
+
const fieldNames = new Set(fields.map((field) => field.name))
|
|
126
|
+
|
|
127
|
+
// Validate formula fields (always required)
|
|
128
|
+
const formulaError = validateFormulaFields(fields)
|
|
129
|
+
if (formulaError) return formulaError
|
|
130
|
+
|
|
131
|
+
// Validate structural constraints (primaryKey, indexes)
|
|
132
|
+
const structureError = validateStructure(table, fieldNames)
|
|
133
|
+
if (structureError) return structureError
|
|
134
|
+
|
|
135
|
+
// Validate access control and views (permissions, views)
|
|
136
|
+
const accessError = validateAccessAndViews(table, fields, fieldNames)
|
|
137
|
+
if (accessError) return accessError
|
|
138
|
+
|
|
139
|
+
return true
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export const TableSchema = Schema.Struct({
|
|
143
|
+
id: Schema.optional(TableIdSchema),
|
|
144
|
+
name: NameSchema,
|
|
145
|
+
fields: FieldsSchema,
|
|
146
|
+
primaryKey: Schema.optional(PrimaryKeySchema),
|
|
147
|
+
uniqueConstraints: Schema.optional(UniqueConstraintsSchema),
|
|
148
|
+
indexes: Schema.optional(IndexesSchema),
|
|
149
|
+
views: Schema.optional(Schema.Array(ViewSchema)),
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Composite foreign key constraints.
|
|
153
|
+
*
|
|
154
|
+
* Used for multi-column foreign keys where multiple fields together reference
|
|
155
|
+
* a composite primary key in another table. Single-column foreign keys are
|
|
156
|
+
* automatically created from relationship fields.
|
|
157
|
+
*
|
|
158
|
+
* @example Composite foreign key
|
|
159
|
+
* ```typescript
|
|
160
|
+
* foreignKeys: [{
|
|
161
|
+
* name: 'fk_permissions_tenant_user',
|
|
162
|
+
* fields: ['tenant_id', 'user_id'],
|
|
163
|
+
* referencedTable: 'tenant_users',
|
|
164
|
+
* referencedFields: ['tenant_id', 'user_id']
|
|
165
|
+
* }]
|
|
166
|
+
* ```
|
|
167
|
+
*
|
|
168
|
+
* @see ForeignKeySchema for full configuration options
|
|
169
|
+
*/
|
|
170
|
+
foreignKeys: Schema.optional(Schema.Array(ForeignKeySchema)),
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Custom CHECK constraints for complex business rules.
|
|
174
|
+
*
|
|
175
|
+
* Used to enforce conditional validation at the database level beyond
|
|
176
|
+
* simple field-level constraints. Useful for cross-field validation,
|
|
177
|
+
* conditional requirements, and complex business logic.
|
|
178
|
+
*
|
|
179
|
+
* @example Conditional requirement
|
|
180
|
+
* ```typescript
|
|
181
|
+
* constraints: [{
|
|
182
|
+
* name: 'chk_active_members_have_email',
|
|
183
|
+
* check: '(is_active = false) OR (email IS NOT NULL)'
|
|
184
|
+
* }]
|
|
185
|
+
* ```
|
|
186
|
+
*
|
|
187
|
+
* @example Range validation
|
|
188
|
+
* ```typescript
|
|
189
|
+
* constraints: [{
|
|
190
|
+
* name: 'chk_end_after_start',
|
|
191
|
+
* check: 'end_date > start_date'
|
|
192
|
+
* }]
|
|
193
|
+
* ```
|
|
194
|
+
*
|
|
195
|
+
* @see CheckConstraintsSchema for full configuration options
|
|
196
|
+
*/
|
|
197
|
+
constraints: Schema.optional(CheckConstraintsSchema),
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Table-level permissions (high-level RBAC abstraction).
|
|
201
|
+
*
|
|
202
|
+
* Configures application-layer permission enforcement.
|
|
203
|
+
* Supports public, authenticated, and role-based access control.
|
|
204
|
+
*
|
|
205
|
+
* @example Role-based permissions
|
|
206
|
+
* ```typescript
|
|
207
|
+
* permissions: {
|
|
208
|
+
* read: 'all',
|
|
209
|
+
* comment: 'authenticated',
|
|
210
|
+
* create: ['admin', 'editor'],
|
|
211
|
+
* update: ['admin', 'editor'],
|
|
212
|
+
* delete: ['admin'],
|
|
213
|
+
* }
|
|
214
|
+
* ```
|
|
215
|
+
*
|
|
216
|
+
* @see TablePermissionsSchema for full configuration options
|
|
217
|
+
*/
|
|
218
|
+
permissions: Schema.optional(TablePermissionsSchema),
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Allow destructive operations (column drops, table drops) without confirmation.
|
|
222
|
+
*
|
|
223
|
+
* When set to true, migrations are allowed to drop columns that exist in the database
|
|
224
|
+
* but are not present in the schema. This can result in data loss.
|
|
225
|
+
*
|
|
226
|
+
* When false or undefined, migrations will throw an error if a column needs to be dropped,
|
|
227
|
+
* requiring explicit confirmation to proceed with data loss operations.
|
|
228
|
+
*
|
|
229
|
+
* @default false
|
|
230
|
+
*
|
|
231
|
+
* @example Allow column drops
|
|
232
|
+
* ```typescript
|
|
233
|
+
* {
|
|
234
|
+
* name: 'users',
|
|
235
|
+
* fields: [{ id: 1, name: 'email', type: 'email' }],
|
|
236
|
+
* allowDestructive: true // Allows dropping columns not in schema
|
|
237
|
+
* }
|
|
238
|
+
* ```
|
|
239
|
+
*/
|
|
240
|
+
allowDestructive: Schema.optional(Schema.Boolean),
|
|
241
|
+
}).pipe(
|
|
242
|
+
Schema.filter(validateTableSchema),
|
|
243
|
+
Schema.annotations({
|
|
244
|
+
title: 'Table',
|
|
245
|
+
description:
|
|
246
|
+
'A database table that defines the structure of an entity in your application. Contains fields, constraints, and indexes to organize and validate data.',
|
|
247
|
+
examples: [
|
|
248
|
+
{
|
|
249
|
+
id: 1,
|
|
250
|
+
name: 'users',
|
|
251
|
+
fields: [
|
|
252
|
+
{ id: 1, name: 'email', type: 'email' as const, required: true },
|
|
253
|
+
{ id: 2, name: 'name', type: 'single-line-text' as const, required: true },
|
|
254
|
+
],
|
|
255
|
+
},
|
|
256
|
+
{
|
|
257
|
+
id: 2,
|
|
258
|
+
name: 'products',
|
|
259
|
+
fields: [
|
|
260
|
+
{ id: 1, name: 'title', type: 'single-line-text' as const, required: true },
|
|
261
|
+
{
|
|
262
|
+
id: 2,
|
|
263
|
+
name: 'price',
|
|
264
|
+
type: 'currency' as const,
|
|
265
|
+
required: true,
|
|
266
|
+
currency: 'USD',
|
|
267
|
+
},
|
|
268
|
+
{ id: 3, name: 'description', type: 'long-text' as const, required: false },
|
|
269
|
+
],
|
|
270
|
+
primaryKey: { type: 'composite', fields: ['id'] },
|
|
271
|
+
},
|
|
272
|
+
],
|
|
273
|
+
})
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
export type Table = Schema.Schema.Type<typeof TableSchema>
|
|
277
|
+
|
|
278
|
+
// Re-export all table model schemas and types for convenient imports
|
|
279
|
+
export * from './check-constraints'
|
|
280
|
+
export * from './field-name'
|
|
281
|
+
export * from './field-types'
|
|
282
|
+
export * from './fields'
|
|
283
|
+
export * from './foreign-keys'
|
|
284
|
+
export * from './id'
|
|
285
|
+
export * from './indexes'
|
|
286
|
+
export * from './name'
|
|
287
|
+
export * from './permissions'
|
|
288
|
+
export * from './primary-key'
|
|
289
|
+
export * from './unique-constraints'
|
|
290
|
+
export * from './views'
|
|
@@ -0,0 +1,80 @@
|
|
|
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
|
+
* Database Indexes
|
|
12
|
+
*
|
|
13
|
+
* Custom database indexes for query optimization. Indexes improve query performance by creating efficient lookup structures for specified fields.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```typescript
|
|
17
|
+
* [
|
|
18
|
+
* {
|
|
19
|
+
* "name": "idx_user_email",
|
|
20
|
+
* "fields": [
|
|
21
|
+
* "email"
|
|
22
|
+
* ]
|
|
23
|
+
* },
|
|
24
|
+
* {
|
|
25
|
+
* "name": "idx_user_created",
|
|
26
|
+
* "fields": [
|
|
27
|
+
* "created_at"
|
|
28
|
+
* ],
|
|
29
|
+
* "unique": false
|
|
30
|
+
* }
|
|
31
|
+
* ]
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export const IndexesSchema = Schema.Array(
|
|
35
|
+
Schema.Struct({
|
|
36
|
+
name: Schema.String.pipe(
|
|
37
|
+
Schema.minLength(1, { message: () => 'This field is required' }),
|
|
38
|
+
Schema.pattern(/^[a-z][a-z0-9_]*$/, {
|
|
39
|
+
message: () => "Name of the index. Use descriptive names like 'idx_tablename_fieldname'",
|
|
40
|
+
}),
|
|
41
|
+
Schema.annotations({
|
|
42
|
+
description: "Name of the index. Use descriptive names like 'idx_tablename_fieldname'",
|
|
43
|
+
examples: ['idx_users_email', 'idx_products_sku', 'idx_orders_status'],
|
|
44
|
+
})
|
|
45
|
+
),
|
|
46
|
+
fields: Schema.Array(
|
|
47
|
+
Schema.String.pipe(Schema.minLength(1, { message: () => 'This field is required' }))
|
|
48
|
+
).pipe(Schema.minItems(1, { message: () => 'At least one field is required' })),
|
|
49
|
+
unique: Schema.optional(Schema.Boolean),
|
|
50
|
+
where: Schema.optional(
|
|
51
|
+
Schema.String.pipe(
|
|
52
|
+
Schema.minLength(1, { message: () => 'This field is required' }),
|
|
53
|
+
Schema.annotations({
|
|
54
|
+
description:
|
|
55
|
+
'WHERE clause for partial indexes. Creates an index that includes only rows satisfying the condition. Useful for enforcing uniqueness only on non-NULL values.',
|
|
56
|
+
examples: ['username IS NOT NULL', "status = 'active'", 'deleted_at IS NULL'],
|
|
57
|
+
})
|
|
58
|
+
)
|
|
59
|
+
),
|
|
60
|
+
})
|
|
61
|
+
).pipe(
|
|
62
|
+
Schema.filter((indexes) => {
|
|
63
|
+
const names = indexes.map((index) => index.name)
|
|
64
|
+
const uniqueNames = new Set(names)
|
|
65
|
+
return names.length === uniqueNames.size || 'Index names must be unique within the table'
|
|
66
|
+
}),
|
|
67
|
+
Schema.annotations({
|
|
68
|
+
title: 'Database Indexes',
|
|
69
|
+
description:
|
|
70
|
+
'Custom database indexes for query optimization. Indexes improve query performance by creating efficient lookup structures for specified fields.',
|
|
71
|
+
examples: [
|
|
72
|
+
[
|
|
73
|
+
{ name: 'idx_user_email', fields: ['email'] },
|
|
74
|
+
{ name: 'idx_user_created', fields: ['created_at'], unique: false },
|
|
75
|
+
],
|
|
76
|
+
],
|
|
77
|
+
})
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
export type Indexes = Schema.Schema.Type<typeof IndexesSchema>
|
|
@@ -0,0 +1,37 @@
|
|
|
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 { createDatabaseIdentifierSchema } from './database-identifier'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Table Name
|
|
13
|
+
*
|
|
14
|
+
* Name of the database table
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* "users"
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export const NameSchema = createDatabaseIdentifierSchema('table').pipe(
|
|
22
|
+
Schema.annotations({
|
|
23
|
+
title: 'Name',
|
|
24
|
+
description:
|
|
25
|
+
'User-friendly name for the table. Can contain spaces, mixed case, and special characters. Will be automatically sanitized for database use (lowercase with underscores). Maximum 63 characters. Choose descriptive names that clearly indicate the purpose.',
|
|
26
|
+
examples: [
|
|
27
|
+
'Person',
|
|
28
|
+
'Product',
|
|
29
|
+
'Invoice Item',
|
|
30
|
+
'Customer Email',
|
|
31
|
+
'Shipping Address',
|
|
32
|
+
'My Projects',
|
|
33
|
+
],
|
|
34
|
+
})
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
export type Name = Schema.Schema.Type<typeof NameSchema>
|
|
@@ -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
|
+
import { TablePermissionSchema } from './permission'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Field Permission Schema
|
|
13
|
+
*
|
|
14
|
+
* Defines granular permissions for a specific field within a table.
|
|
15
|
+
* Allows restricting read/write access to individual columns based on roles.
|
|
16
|
+
* Uses the same 3-format permission system as table-level operations.
|
|
17
|
+
*
|
|
18
|
+
* @example Restrict salary field to admins only
|
|
19
|
+
* ```yaml
|
|
20
|
+
* - field: salary
|
|
21
|
+
* read: ['admin', 'hr']
|
|
22
|
+
* write: ['admin']
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @example Make department readable by all, writable by admins
|
|
26
|
+
* ```yaml
|
|
27
|
+
* - field: department
|
|
28
|
+
* read: all
|
|
29
|
+
* write: ['admin']
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export const FieldPermissionSchema = Schema.Struct({
|
|
33
|
+
/**
|
|
34
|
+
* The name of the field this permission applies to.
|
|
35
|
+
*/
|
|
36
|
+
field: Schema.String,
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Who can read (SELECT) this field.
|
|
40
|
+
* If not specified, inherits from table-level read permission.
|
|
41
|
+
*/
|
|
42
|
+
read: Schema.optional(TablePermissionSchema),
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Who can write (INSERT/UPDATE) this field.
|
|
46
|
+
* If not specified, inherits from table-level create/update permission.
|
|
47
|
+
*/
|
|
48
|
+
write: Schema.optional(TablePermissionSchema),
|
|
49
|
+
}).pipe(
|
|
50
|
+
Schema.annotations({
|
|
51
|
+
title: 'Field Permission',
|
|
52
|
+
description:
|
|
53
|
+
"Granular permission for a specific field. Uses same format as table-level: 'all', 'authenticated', or role array.",
|
|
54
|
+
examples: [
|
|
55
|
+
{
|
|
56
|
+
field: 'salary',
|
|
57
|
+
read: ['admin', 'hr'] as readonly string[],
|
|
58
|
+
write: ['admin'] as readonly string[],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
field: 'department',
|
|
62
|
+
read: 'all' as const,
|
|
63
|
+
write: ['admin'] as readonly string[],
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
})
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
export type FieldPermission = Schema.Schema.Type<typeof FieldPermissionSchema>
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Table Field Permissions Array Schema
|
|
73
|
+
*
|
|
74
|
+
* Array of field-level permission configurations for table permissions.
|
|
75
|
+
*/
|
|
76
|
+
export const TableFieldPermissionsSchema = Schema.Array(FieldPermissionSchema).pipe(
|
|
77
|
+
Schema.annotations({
|
|
78
|
+
title: 'Table Field Permissions',
|
|
79
|
+
description: 'Array of field-level permission configurations for table permissions.',
|
|
80
|
+
})
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
export type TableFieldPermissions = Schema.Schema.Type<typeof TableFieldPermissionsSchema>
|
|
@@ -0,0 +1,167 @@
|
|
|
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 { TableFieldPermissionsSchema } from './field-permission'
|
|
10
|
+
import { TablePermissionSchema } from './permission'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Table Permissions Schema
|
|
14
|
+
*
|
|
15
|
+
* Permissions for table operations using a simplified 3-format system.
|
|
16
|
+
* Each operation accepts one of:
|
|
17
|
+
* - `'all'` — Everyone (including unauthenticated users)
|
|
18
|
+
* - `'authenticated'` — Any logged-in user
|
|
19
|
+
* - `['admin', 'editor']` — Specific role names (array)
|
|
20
|
+
*
|
|
21
|
+
* Operations:
|
|
22
|
+
* - `read` — Who can view records
|
|
23
|
+
* - `comment` — Who can add comments to records
|
|
24
|
+
* - `create` — Who can create new records
|
|
25
|
+
* - `update` — Who can modify existing records
|
|
26
|
+
* - `delete` — Who can remove records
|
|
27
|
+
*
|
|
28
|
+
* Omitted operations default to deny (no access).
|
|
29
|
+
*
|
|
30
|
+
* @example Role-based permissions
|
|
31
|
+
* ```yaml
|
|
32
|
+
* permissions:
|
|
33
|
+
* read: all
|
|
34
|
+
* comment: authenticated
|
|
35
|
+
* create: ['admin', 'editor']
|
|
36
|
+
* update: ['admin', 'editor']
|
|
37
|
+
* delete: ['admin']
|
|
38
|
+
* ```
|
|
39
|
+
*
|
|
40
|
+
* @example Minimal read-only public table
|
|
41
|
+
* ```yaml
|
|
42
|
+
* permissions:
|
|
43
|
+
* read: all
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export const TablePermissionsSchema = Schema.Struct({
|
|
47
|
+
/**
|
|
48
|
+
* READ permission — who can view records from this table.
|
|
49
|
+
*/
|
|
50
|
+
read: Schema.optional(TablePermissionSchema),
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* COMMENT permission — who can add comments to records.
|
|
54
|
+
*/
|
|
55
|
+
comment: Schema.optional(TablePermissionSchema),
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* CREATE permission — who can create new records in this table.
|
|
59
|
+
*/
|
|
60
|
+
create: Schema.optional(TablePermissionSchema),
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* UPDATE permission — who can modify existing records in this table.
|
|
64
|
+
*/
|
|
65
|
+
update: Schema.optional(TablePermissionSchema),
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* DELETE permission — who can remove records from this table.
|
|
69
|
+
*/
|
|
70
|
+
delete: Schema.optional(TablePermissionSchema),
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Field-level permissions for granular column access control.
|
|
74
|
+
*
|
|
75
|
+
* Allows restricting read/write access to specific fields based on roles.
|
|
76
|
+
* Uses the same 3-format permission system as table-level operations.
|
|
77
|
+
*
|
|
78
|
+
* @example Restrict salary field to admins
|
|
79
|
+
* ```yaml
|
|
80
|
+
* fields:
|
|
81
|
+
* - field: salary
|
|
82
|
+
* read: ['admin', 'hr']
|
|
83
|
+
* write: ['admin']
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
fields: Schema.optional(TableFieldPermissionsSchema),
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* INHERIT — inherit permissions from a parent table by name.
|
|
90
|
+
*
|
|
91
|
+
* When set, this table inherits all permissions from the specified parent table.
|
|
92
|
+
* Any explicitly defined permissions on this table take precedence over inherited ones.
|
|
93
|
+
* Circular inheritance chains are detected and rejected at configuration time.
|
|
94
|
+
*
|
|
95
|
+
* @example Inherit permissions from parent table
|
|
96
|
+
* ```yaml
|
|
97
|
+
* permissions:
|
|
98
|
+
* inherit: articles
|
|
99
|
+
* ```
|
|
100
|
+
*
|
|
101
|
+
* @future Not yet implemented — target design for permission inheritance feature.
|
|
102
|
+
*/
|
|
103
|
+
inherit: Schema.optional(
|
|
104
|
+
Schema.String.pipe(
|
|
105
|
+
Schema.nonEmptyString({ message: () => 'inherit table name must not be empty' }),
|
|
106
|
+
Schema.annotations({
|
|
107
|
+
description: 'Name of the parent table to inherit permissions from',
|
|
108
|
+
})
|
|
109
|
+
)
|
|
110
|
+
),
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* OVERRIDE — override specific inherited permissions.
|
|
114
|
+
*
|
|
115
|
+
* Only meaningful when `inherit` is set. Allows overriding specific
|
|
116
|
+
* permission operations from the parent table while inheriting the rest.
|
|
117
|
+
*
|
|
118
|
+
* @example Override read permission from inherited parent
|
|
119
|
+
* ```yaml
|
|
120
|
+
* permissions:
|
|
121
|
+
* inherit: articles
|
|
122
|
+
* override:
|
|
123
|
+
* read: ['admin']
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @future Not yet implemented — target design for permission inheritance feature.
|
|
127
|
+
*/
|
|
128
|
+
override: Schema.optional(
|
|
129
|
+
Schema.Struct({
|
|
130
|
+
read: Schema.optional(TablePermissionSchema),
|
|
131
|
+
comment: Schema.optional(TablePermissionSchema),
|
|
132
|
+
create: Schema.optional(TablePermissionSchema),
|
|
133
|
+
update: Schema.optional(TablePermissionSchema),
|
|
134
|
+
delete: Schema.optional(TablePermissionSchema),
|
|
135
|
+
})
|
|
136
|
+
),
|
|
137
|
+
}).pipe(
|
|
138
|
+
Schema.annotations({
|
|
139
|
+
title: 'Table Permissions',
|
|
140
|
+
description:
|
|
141
|
+
"Permissions for table operations. Each operation accepts 'all', 'authenticated', or a role array. Omitted operations default to deny.",
|
|
142
|
+
examples: [
|
|
143
|
+
// Public read, admin-only write
|
|
144
|
+
{
|
|
145
|
+
read: 'all' as const,
|
|
146
|
+
comment: 'authenticated' as const,
|
|
147
|
+
create: ['admin'] as readonly string[],
|
|
148
|
+
update: ['admin'] as readonly string[],
|
|
149
|
+
delete: ['admin'] as readonly string[],
|
|
150
|
+
},
|
|
151
|
+
// Role-based with field restrictions
|
|
152
|
+
{
|
|
153
|
+
read: 'all' as const,
|
|
154
|
+
create: ['admin', 'editor'] as readonly string[],
|
|
155
|
+
update: ['admin', 'editor'] as readonly string[],
|
|
156
|
+
delete: ['admin'] as readonly string[],
|
|
157
|
+
},
|
|
158
|
+
],
|
|
159
|
+
})
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
export type TablePermissions = Schema.Schema.Type<typeof TablePermissionsSchema>
|
|
163
|
+
|
|
164
|
+
// Re-export sub-schemas for external use
|
|
165
|
+
export * from './permission'
|
|
166
|
+
export * from './field-permission'
|
|
167
|
+
export * from './permission-evaluator'
|