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,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 { BaseFieldSchema } from '../base-field'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* URL Field
|
|
13
|
+
*
|
|
14
|
+
* Text field with URL format validation. Stores web addresses (URLs) and validates
|
|
15
|
+
* them against standard URL format rules. Supports http://, https://, and other
|
|
16
|
+
* protocols. Can be marked as required, unique, or indexed. URL validation ensures
|
|
17
|
+
* data integrity and prevents malformed URLs from being stored. URLs are stored
|
|
18
|
+
* as plain text strings and can be used for links, API endpoints, and web resources.
|
|
19
|
+
*
|
|
20
|
+
* Business Rules:
|
|
21
|
+
* - URL format validation enforced at application level (protocol + domain + optional path)
|
|
22
|
+
* - Supports multiple protocols: http://, https://, ftp://, etc.
|
|
23
|
+
* - Unique constraint optional - useful for preventing duplicate resource links
|
|
24
|
+
* - Indexing recommended for search and lookup operations on URL fields
|
|
25
|
+
* - Constant value 'url' ensures type safety and enables discriminated unions
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const field = {
|
|
30
|
+
* id: 1,
|
|
31
|
+
* name: 'website',
|
|
32
|
+
* type: 'url',
|
|
33
|
+
* required: true,
|
|
34
|
+
* unique: false,
|
|
35
|
+
* indexed: true,
|
|
36
|
+
* default: 'https://example.com'
|
|
37
|
+
* }
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export const UrlFieldSchema = BaseFieldSchema.pipe(
|
|
41
|
+
Schema.extend(
|
|
42
|
+
Schema.Struct({
|
|
43
|
+
type: Schema.Literal('url').pipe(
|
|
44
|
+
Schema.annotations({
|
|
45
|
+
description: "Constant value 'url' for type discrimination in discriminated unions",
|
|
46
|
+
})
|
|
47
|
+
),
|
|
48
|
+
default: Schema.optional(
|
|
49
|
+
Schema.String.pipe(
|
|
50
|
+
Schema.annotations({
|
|
51
|
+
description: 'Default URL value when creating new records',
|
|
52
|
+
})
|
|
53
|
+
)
|
|
54
|
+
),
|
|
55
|
+
})
|
|
56
|
+
),
|
|
57
|
+
Schema.annotations({
|
|
58
|
+
title: 'URL Field',
|
|
59
|
+
description:
|
|
60
|
+
'Text field with URL format validation. Validates web addresses and supports multiple protocols (http://, https://, ftp://, etc.).',
|
|
61
|
+
examples: [
|
|
62
|
+
{
|
|
63
|
+
id: 1,
|
|
64
|
+
name: 'website',
|
|
65
|
+
type: 'url',
|
|
66
|
+
required: true,
|
|
67
|
+
unique: false,
|
|
68
|
+
indexed: true,
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: 2,
|
|
72
|
+
name: 'profile_url',
|
|
73
|
+
type: 'url',
|
|
74
|
+
required: false,
|
|
75
|
+
default: 'https://example.com/profile',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
})
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
export type UrlField = Schema.Schema.Type<typeof UrlFieldSchema>
|
|
@@ -0,0 +1,50 @@
|
|
|
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 { BaseFieldSchema } from '../base-field'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Created By Field
|
|
13
|
+
*
|
|
14
|
+
* Automatically captures the user who created a record.
|
|
15
|
+
* This field is system-managed and cannot be manually edited.
|
|
16
|
+
* Stores a reference to the user ID from the authentication system.
|
|
17
|
+
* Commonly used for audit trails and user activity tracking.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const field = {
|
|
22
|
+
* id: 1,
|
|
23
|
+
* name: 'created_by',
|
|
24
|
+
* type: 'created-by',
|
|
25
|
+
* indexed: true
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export const CreatedByFieldSchema = BaseFieldSchema.pipe(
|
|
30
|
+
Schema.extend(
|
|
31
|
+
Schema.Struct({
|
|
32
|
+
type: Schema.Literal('created-by'),
|
|
33
|
+
})
|
|
34
|
+
),
|
|
35
|
+
Schema.annotations({
|
|
36
|
+
title: 'Created By Field',
|
|
37
|
+
description:
|
|
38
|
+
'Automatically captures the user who created a record. System-managed field that stores user ID reference.',
|
|
39
|
+
examples: [
|
|
40
|
+
{
|
|
41
|
+
id: 1,
|
|
42
|
+
name: 'created_by',
|
|
43
|
+
type: 'created-by',
|
|
44
|
+
indexed: true,
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
})
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
export type CreatedByField = Schema.Schema.Type<typeof CreatedByFieldSchema>
|
|
@@ -0,0 +1,57 @@
|
|
|
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 { BaseFieldSchema } from '../base-field'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Deleted By Field
|
|
13
|
+
*
|
|
14
|
+
* Automatically captures the user who soft-deleted a record.
|
|
15
|
+
* This field is system-managed and cannot be manually edited.
|
|
16
|
+
* Stores a reference to the user ID from the authentication system.
|
|
17
|
+
* Only populated when a record is soft-deleted (when deleted_at is set).
|
|
18
|
+
* NULL indicates the record has not been deleted or was deleted by a system process.
|
|
19
|
+
*
|
|
20
|
+
* Commonly used for:
|
|
21
|
+
* - Audit trails (who deleted what)
|
|
22
|
+
* - Compliance reporting
|
|
23
|
+
* - Accountability tracking
|
|
24
|
+
* - Deletion history
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const field = {
|
|
29
|
+
* id: 1,
|
|
30
|
+
* name: 'deleted_by',
|
|
31
|
+
* type: 'deleted-by',
|
|
32
|
+
* indexed: true
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export const DeletedByFieldSchema = BaseFieldSchema.pipe(
|
|
37
|
+
Schema.extend(
|
|
38
|
+
Schema.Struct({
|
|
39
|
+
type: Schema.Literal('deleted-by'),
|
|
40
|
+
})
|
|
41
|
+
),
|
|
42
|
+
Schema.annotations({
|
|
43
|
+
title: 'Deleted By Field',
|
|
44
|
+
description:
|
|
45
|
+
'Automatically captures the user who soft-deleted a record. System-managed field that stores user ID reference. NULL when record is active or deleted by system process.',
|
|
46
|
+
examples: [
|
|
47
|
+
{
|
|
48
|
+
id: 1,
|
|
49
|
+
name: 'deleted_by',
|
|
50
|
+
type: 'deleted-by',
|
|
51
|
+
indexed: true,
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
})
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
export type DeletedByField = Schema.Schema.Type<typeof DeletedByFieldSchema>
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
export * from './user-field'
|
|
9
|
+
export * from './created-by-field'
|
|
10
|
+
export * from './updated-by-field'
|
|
11
|
+
export * from './deleted-by-field'
|
|
@@ -0,0 +1,51 @@
|
|
|
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 { BaseFieldSchema } from '../base-field'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Updated By Field
|
|
13
|
+
*
|
|
14
|
+
* Automatically captures the user who last modified a record.
|
|
15
|
+
* This field is system-managed and cannot be manually edited.
|
|
16
|
+
* Stores a reference to the user ID from the authentication system.
|
|
17
|
+
* Automatically updates on every record update operation.
|
|
18
|
+
* Commonly used for audit trails and tracking modification history.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const field = {
|
|
23
|
+
* id: 1,
|
|
24
|
+
* name: 'updated_by',
|
|
25
|
+
* type: 'updated-by',
|
|
26
|
+
* indexed: true
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export const UpdatedByFieldSchema = BaseFieldSchema.pipe(
|
|
31
|
+
Schema.extend(
|
|
32
|
+
Schema.Struct({
|
|
33
|
+
type: Schema.Literal('updated-by'),
|
|
34
|
+
})
|
|
35
|
+
),
|
|
36
|
+
Schema.annotations({
|
|
37
|
+
title: 'Updated By Field',
|
|
38
|
+
description:
|
|
39
|
+
'Automatically captures the user who last modified a record. System-managed field that stores user ID reference.',
|
|
40
|
+
examples: [
|
|
41
|
+
{
|
|
42
|
+
id: 1,
|
|
43
|
+
name: 'updated_by',
|
|
44
|
+
type: 'updated-by',
|
|
45
|
+
indexed: true,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
})
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
export type UpdatedByField = Schema.Schema.Type<typeof UpdatedByFieldSchema>
|
|
@@ -0,0 +1,52 @@
|
|
|
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 { BaseFieldSchema } from '../base-field'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* User Field
|
|
13
|
+
*
|
|
14
|
+
* Reference field that links to users from the authentication system.
|
|
15
|
+
* Stores user IDs and can be used for assignments, ownership, or collaboration.
|
|
16
|
+
* Supports single or multiple user selection via allowMultiple flag.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* const field = {
|
|
21
|
+
* id: 1,
|
|
22
|
+
* name: 'assigned_to',
|
|
23
|
+
* type: 'user',
|
|
24
|
+
* required: true,
|
|
25
|
+
* allowMultiple: false
|
|
26
|
+
* }
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export const UserFieldSchema = BaseFieldSchema.pipe(
|
|
30
|
+
Schema.extend(
|
|
31
|
+
Schema.Struct({
|
|
32
|
+
type: Schema.Literal('user'),
|
|
33
|
+
allowMultiple: Schema.optional(Schema.Boolean),
|
|
34
|
+
})
|
|
35
|
+
),
|
|
36
|
+
Schema.annotations({
|
|
37
|
+
title: 'User Field',
|
|
38
|
+
description:
|
|
39
|
+
'Reference field linking to users from authentication system. Supports single or multiple user selection.',
|
|
40
|
+
examples: [
|
|
41
|
+
{
|
|
42
|
+
id: 1,
|
|
43
|
+
name: 'assigned_to',
|
|
44
|
+
type: 'user',
|
|
45
|
+
required: true,
|
|
46
|
+
allowMultiple: false,
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
})
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
export type UserField = Schema.Schema.Type<typeof UserFieldSchema>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Schema } from 'effect'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Validates that min is less than or equal to max when both are specified.
|
|
12
|
+
*
|
|
13
|
+
* This validation is used by numeric field types (integer, decimal, currency, percentage)
|
|
14
|
+
* to ensure that range constraints are logically valid. Returns an error message if
|
|
15
|
+
* validation fails, or undefined if validation passes.
|
|
16
|
+
*
|
|
17
|
+
* @param field - Object containing optional min and max properties
|
|
18
|
+
* @returns Error message if min > max, undefined otherwise
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* validateMinMaxRange({ min: 0, max: 100 }) // undefined (valid)
|
|
23
|
+
* validateMinMaxRange({ min: 100, max: 10 }) // 'min cannot be greater than max'
|
|
24
|
+
* validateMinMaxRange({ min: 0 }) // undefined (only min specified)
|
|
25
|
+
* validateMinMaxRange({ max: 100 }) // undefined (only max specified)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export const validateMinMaxRange = (field: {
|
|
29
|
+
readonly min?: number
|
|
30
|
+
readonly max?: number
|
|
31
|
+
}): string | undefined => {
|
|
32
|
+
if (field.min !== undefined && field.max !== undefined && field.min > field.max) {
|
|
33
|
+
return 'min cannot be greater than max'
|
|
34
|
+
}
|
|
35
|
+
return undefined
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Creates a reusable options array schema for select-type fields.
|
|
40
|
+
*
|
|
41
|
+
* This schema factory is used by single-select and multi-select field types
|
|
42
|
+
* to ensure consistent validation of options arrays. All select fields require
|
|
43
|
+
* at least one option to be meaningful, and option values must be unique.
|
|
44
|
+
*
|
|
45
|
+
* @param fieldType - The type of select field (for error messages)
|
|
46
|
+
* @returns Effect Schema for validating options arrays
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* // Used in single-select field
|
|
51
|
+
* const optionsSchema = createOptionsSchema('single-select')
|
|
52
|
+
* // Used in multi-select field
|
|
53
|
+
* const optionsSchema = createOptionsSchema('multi-select')
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export const createOptionsSchema = (fieldType: 'single-select' | 'multi-select') =>
|
|
57
|
+
Schema.Array(Schema.String).pipe(
|
|
58
|
+
Schema.minItems(1),
|
|
59
|
+
Schema.annotations({
|
|
60
|
+
message: () => `At least one option is required for ${fieldType} field`,
|
|
61
|
+
}),
|
|
62
|
+
Schema.filter((options) => {
|
|
63
|
+
const uniqueOptions = new Set(options)
|
|
64
|
+
return (
|
|
65
|
+
options.length === uniqueOptions.size || 'Options must be unique (duplicate option found)'
|
|
66
|
+
)
|
|
67
|
+
})
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Creates a reusable options array schema for status-type fields with complex option objects.
|
|
72
|
+
*
|
|
73
|
+
* This schema factory is used by status field type to ensure consistent validation
|
|
74
|
+
* of options arrays containing objects with value and optional color properties.
|
|
75
|
+
* Status fields require at least one option, and option values must be unique.
|
|
76
|
+
*
|
|
77
|
+
* @returns Effect Schema for validating status field options arrays
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* ```typescript
|
|
81
|
+
* // Used in status field
|
|
82
|
+
* const optionsSchema = createStatusOptionsSchema()
|
|
83
|
+
* // Validates: [{ value: 'Draft', color: '#6B7280' }, { value: 'Published' }]
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export const createStatusOptionsSchema = () =>
|
|
87
|
+
Schema.Array(
|
|
88
|
+
Schema.Struct({
|
|
89
|
+
value: Schema.String.pipe(Schema.nonEmptyString({ message: () => 'value is required' })),
|
|
90
|
+
color: Schema.optional(
|
|
91
|
+
Schema.String.pipe(
|
|
92
|
+
Schema.pattern(/^#[0-9a-fA-F]{6}$/, {
|
|
93
|
+
message: () => 'Invalid color format - color must be a hex code (e.g., #3B82F6)',
|
|
94
|
+
}),
|
|
95
|
+
Schema.annotations({
|
|
96
|
+
description: 'Hex color code for the status',
|
|
97
|
+
})
|
|
98
|
+
)
|
|
99
|
+
),
|
|
100
|
+
})
|
|
101
|
+
).pipe(
|
|
102
|
+
Schema.minItems(1, { message: () => 'at least one option required' }),
|
|
103
|
+
Schema.filter((options) => {
|
|
104
|
+
const values = options.map((opt) => opt.value)
|
|
105
|
+
const uniqueValues = new Set(values)
|
|
106
|
+
return (
|
|
107
|
+
values.length === uniqueValues.size || 'Options must be unique (duplicate option found)'
|
|
108
|
+
)
|
|
109
|
+
})
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Validates that button fields have required properties based on their action type.
|
|
114
|
+
*
|
|
115
|
+
* This validation is used by button field types to ensure that action-specific
|
|
116
|
+
* properties are provided when needed. For example, buttons with action='url'
|
|
117
|
+
* must have a url property, and buttons with action='automation' must have an
|
|
118
|
+
* automation property.
|
|
119
|
+
*
|
|
120
|
+
* @param field - Object containing action and optional url/automation properties
|
|
121
|
+
* @returns Error message if validation fails, true if validation passes
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* validateButtonAction({ action: 'url', url: 'https://example.com' }) // true (valid)
|
|
126
|
+
* validateButtonAction({ action: 'url' }) // 'url is required when action is url'
|
|
127
|
+
* validateButtonAction({ action: 'automation', automation: 'approve' }) // true (valid)
|
|
128
|
+
* validateButtonAction({ action: 'automation' }) // 'automation is required when action is automation'
|
|
129
|
+
* validateButtonAction({ action: 'custom' }) // true (no requirements)
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export const validateButtonAction = (field: {
|
|
133
|
+
readonly action: string
|
|
134
|
+
readonly url?: string
|
|
135
|
+
readonly automation?: string
|
|
136
|
+
}): string | true => {
|
|
137
|
+
if (field.action === 'url' && !field.url) {
|
|
138
|
+
return 'url is required when action is url'
|
|
139
|
+
}
|
|
140
|
+
if (field.action === 'automation' && !field.automation) {
|
|
141
|
+
return 'automation is required when action is automation'
|
|
142
|
+
}
|
|
143
|
+
return true
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Finds the first duplicate value in an array.
|
|
148
|
+
*
|
|
149
|
+
* This utility function is used for detecting duplicate IDs, field names, or other
|
|
150
|
+
* values that must be unique within a collection. Uses an efficient O(n) algorithm
|
|
151
|
+
* with indexOf to find the first duplicate.
|
|
152
|
+
*
|
|
153
|
+
* @param values - Array of values to check for duplicates
|
|
154
|
+
* @returns The first duplicate value found, or undefined if no duplicates exist
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```typescript
|
|
158
|
+
* findDuplicate(['a', 'b', 'c']) // undefined (no duplicates)
|
|
159
|
+
* findDuplicate(['a', 'b', 'a', 'c']) // 'a' (first duplicate)
|
|
160
|
+
* findDuplicate([1, 2, 3, 2]) // 2 (works with numbers)
|
|
161
|
+
* findDuplicate(['x']) // undefined (single item)
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
export const findDuplicate = <T>(values: ReadonlyArray<T>): T | undefined => {
|
|
165
|
+
return values.find((value, index) => values.indexOf(value) !== index)
|
|
166
|
+
}
|
|
@@ -0,0 +1,216 @@
|
|
|
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 {
|
|
10
|
+
ArrayFieldSchema,
|
|
11
|
+
AutonumberFieldSchema,
|
|
12
|
+
BarcodeFieldSchema,
|
|
13
|
+
ButtonFieldSchema,
|
|
14
|
+
CheckboxFieldSchema,
|
|
15
|
+
ColorFieldSchema,
|
|
16
|
+
CountFieldSchema,
|
|
17
|
+
CreatedAtFieldSchema,
|
|
18
|
+
CreatedByFieldSchema,
|
|
19
|
+
CurrencyFieldSchema,
|
|
20
|
+
DateFieldSchema,
|
|
21
|
+
DecimalFieldSchema,
|
|
22
|
+
DeletedAtFieldSchema,
|
|
23
|
+
DeletedByFieldSchema,
|
|
24
|
+
DurationFieldSchema,
|
|
25
|
+
EmailFieldSchema,
|
|
26
|
+
FormulaFieldSchema,
|
|
27
|
+
GeolocationFieldSchema,
|
|
28
|
+
IntegerFieldSchema,
|
|
29
|
+
JsonFieldSchema,
|
|
30
|
+
LongTextFieldSchema,
|
|
31
|
+
LookupFieldSchema,
|
|
32
|
+
MultiSelectFieldSchema,
|
|
33
|
+
MultipleAttachmentsFieldSchema,
|
|
34
|
+
PercentageFieldSchema,
|
|
35
|
+
PhoneNumberFieldSchema,
|
|
36
|
+
ProgressFieldSchema,
|
|
37
|
+
RatingFieldSchema,
|
|
38
|
+
RelationshipFieldSchema,
|
|
39
|
+
RichTextFieldSchema,
|
|
40
|
+
RollupFieldSchema,
|
|
41
|
+
SingleAttachmentFieldSchema,
|
|
42
|
+
SingleLineTextFieldSchema,
|
|
43
|
+
SingleSelectFieldSchema,
|
|
44
|
+
StatusFieldSchema,
|
|
45
|
+
UnknownFieldSchema,
|
|
46
|
+
UpdatedAtFieldSchema,
|
|
47
|
+
UpdatedByFieldSchema,
|
|
48
|
+
UrlFieldSchema,
|
|
49
|
+
UserFieldSchema,
|
|
50
|
+
} from './field-types'
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Table Fields
|
|
54
|
+
*
|
|
55
|
+
* Collection of all supported field types in a table.
|
|
56
|
+
* Each field type has specific properties and validation rules.
|
|
57
|
+
* Fields are the columns in your database tables and determine
|
|
58
|
+
* what data can be stored and how it is validated.
|
|
59
|
+
*
|
|
60
|
+
* @see docs/specifications/roadmap/tables/fields.md for full specification
|
|
61
|
+
*/
|
|
62
|
+
export const FieldsSchema = Schema.Array(
|
|
63
|
+
Schema.Union(
|
|
64
|
+
// Text field types (individual schemas)
|
|
65
|
+
SingleLineTextFieldSchema,
|
|
66
|
+
LongTextFieldSchema,
|
|
67
|
+
PhoneNumberFieldSchema,
|
|
68
|
+
EmailFieldSchema,
|
|
69
|
+
UrlFieldSchema,
|
|
70
|
+
// Number field types (individual schemas)
|
|
71
|
+
IntegerFieldSchema,
|
|
72
|
+
DecimalFieldSchema,
|
|
73
|
+
CurrencyFieldSchema,
|
|
74
|
+
PercentageFieldSchema,
|
|
75
|
+
// Other field types
|
|
76
|
+
DateFieldSchema,
|
|
77
|
+
CheckboxFieldSchema,
|
|
78
|
+
SingleSelectFieldSchema,
|
|
79
|
+
MultiSelectFieldSchema,
|
|
80
|
+
RelationshipFieldSchema,
|
|
81
|
+
SingleAttachmentFieldSchema,
|
|
82
|
+
MultipleAttachmentsFieldSchema,
|
|
83
|
+
FormulaFieldSchema,
|
|
84
|
+
RollupFieldSchema,
|
|
85
|
+
LookupFieldSchema,
|
|
86
|
+
CountFieldSchema,
|
|
87
|
+
UserFieldSchema,
|
|
88
|
+
CreatedAtFieldSchema,
|
|
89
|
+
CreatedByFieldSchema,
|
|
90
|
+
UpdatedAtFieldSchema,
|
|
91
|
+
UpdatedByFieldSchema,
|
|
92
|
+
DeletedAtFieldSchema,
|
|
93
|
+
DeletedByFieldSchema,
|
|
94
|
+
RatingFieldSchema,
|
|
95
|
+
DurationFieldSchema,
|
|
96
|
+
RichTextFieldSchema,
|
|
97
|
+
StatusFieldSchema,
|
|
98
|
+
ButtonFieldSchema,
|
|
99
|
+
AutonumberFieldSchema,
|
|
100
|
+
BarcodeFieldSchema,
|
|
101
|
+
ColorFieldSchema,
|
|
102
|
+
ProgressFieldSchema,
|
|
103
|
+
GeolocationFieldSchema,
|
|
104
|
+
JsonFieldSchema,
|
|
105
|
+
ArrayFieldSchema,
|
|
106
|
+
// Unknown field type (catch-all for invalid types that will fail during SQL generation)
|
|
107
|
+
UnknownFieldSchema
|
|
108
|
+
)
|
|
109
|
+
).pipe(
|
|
110
|
+
Schema.minItems(1),
|
|
111
|
+
Schema.filter((fields) => {
|
|
112
|
+
const ids = fields.map((field) => field.id)
|
|
113
|
+
const uniqueIds = new Set(ids)
|
|
114
|
+
return ids.length === uniqueIds.size || 'Field IDs must be unique within the table'
|
|
115
|
+
}),
|
|
116
|
+
Schema.filter((fields) => {
|
|
117
|
+
const names = fields.map((field) => field.name)
|
|
118
|
+
const uniqueNames = new Set(names)
|
|
119
|
+
return names.length === uniqueNames.size || 'Field names must be unique within the table'
|
|
120
|
+
}),
|
|
121
|
+
Schema.filter((fields) => {
|
|
122
|
+
// Validate count fields reference existing relationship-type fields
|
|
123
|
+
const countFields = fields.filter((field) => field.type === 'count')
|
|
124
|
+
|
|
125
|
+
const invalidResult = countFields
|
|
126
|
+
.map((countField) => {
|
|
127
|
+
const { relationshipField } = countField as { relationshipField: string }
|
|
128
|
+
return validateComputedFieldRelationship({
|
|
129
|
+
fields,
|
|
130
|
+
computedFieldName: countField.name,
|
|
131
|
+
computedFieldType: 'count',
|
|
132
|
+
relationshipField,
|
|
133
|
+
})
|
|
134
|
+
})
|
|
135
|
+
.find((result) => result !== true)
|
|
136
|
+
|
|
137
|
+
return invalidResult !== undefined ? invalidResult : true
|
|
138
|
+
}),
|
|
139
|
+
Schema.filter((fields) => {
|
|
140
|
+
// Validate rollup fields reference existing relationship-type fields
|
|
141
|
+
const rollupFields = fields.filter((field) => field.type === 'rollup')
|
|
142
|
+
|
|
143
|
+
const invalidResult = rollupFields
|
|
144
|
+
.map((rollupField) => {
|
|
145
|
+
const { relationshipField } = rollupField as { relationshipField: string }
|
|
146
|
+
return validateComputedFieldRelationship({
|
|
147
|
+
fields,
|
|
148
|
+
computedFieldName: rollupField.name,
|
|
149
|
+
computedFieldType: 'rollup',
|
|
150
|
+
relationshipField,
|
|
151
|
+
})
|
|
152
|
+
})
|
|
153
|
+
.find((result) => result !== true)
|
|
154
|
+
|
|
155
|
+
return invalidResult !== undefined ? invalidResult : true
|
|
156
|
+
}),
|
|
157
|
+
Schema.annotations({
|
|
158
|
+
title: 'Table Fields',
|
|
159
|
+
description:
|
|
160
|
+
'Collection of all supported field types. Each field defines a column in the database table with specific validation and behavior.',
|
|
161
|
+
examples: [
|
|
162
|
+
[
|
|
163
|
+
{
|
|
164
|
+
id: 1,
|
|
165
|
+
name: 'email',
|
|
166
|
+
type: 'email' as const,
|
|
167
|
+
required: true,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
id: 2,
|
|
171
|
+
name: 'age',
|
|
172
|
+
type: 'integer' as const,
|
|
173
|
+
min: 0,
|
|
174
|
+
max: 150,
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
],
|
|
178
|
+
})
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
export type Fields = Schema.Schema.Type<typeof FieldsSchema>
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Validate that a computed field (count or rollup) references a valid relationship field.
|
|
185
|
+
*
|
|
186
|
+
* This helper validates that:
|
|
187
|
+
* 1. The relationshipField exists in the current table's fields
|
|
188
|
+
* 2. The relationshipField is a relationship type
|
|
189
|
+
*
|
|
190
|
+
* Used by both count and rollup field validation to ensure they reference valid relationships.
|
|
191
|
+
*
|
|
192
|
+
* @param params - Validation parameters
|
|
193
|
+
* @returns Error message if validation fails, true if valid
|
|
194
|
+
*/
|
|
195
|
+
export const validateComputedFieldRelationship = (params: {
|
|
196
|
+
readonly fields: ReadonlyArray<{ readonly name: string; readonly type: string }>
|
|
197
|
+
readonly computedFieldName: string
|
|
198
|
+
readonly computedFieldType: 'count' | 'rollup'
|
|
199
|
+
readonly relationshipField: string
|
|
200
|
+
}): string | true => {
|
|
201
|
+
const { fields, computedFieldName, computedFieldType, relationshipField } = params
|
|
202
|
+
const fieldsByName = new Map(fields.map((field) => [field.name, field]))
|
|
203
|
+
const referencedField = fieldsByName.get(relationshipField)
|
|
204
|
+
|
|
205
|
+
if (!referencedField) {
|
|
206
|
+
const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1)
|
|
207
|
+
return `${capitalize(computedFieldType)} field "${computedFieldName}" references relationshipField "${relationshipField}" not found in the same table`
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
if (referencedField.type !== 'relationship') {
|
|
211
|
+
const capitalize = (str: string) => str.charAt(0).toUpperCase() + str.slice(1)
|
|
212
|
+
return `${capitalize(computedFieldType)} field "${computedFieldName}" relationshipField "${relationshipField}" must reference a relationship field`
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return true
|
|
216
|
+
}
|