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,61 @@
|
|
|
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
|
+
/**
|
|
9
|
+
* Unified Permission Type Registry
|
|
10
|
+
*
|
|
11
|
+
* This module provides centralized, reusable permission-related schemas
|
|
12
|
+
* used across the authentication and authorization system.
|
|
13
|
+
*
|
|
14
|
+
* ## Permission Domains
|
|
15
|
+
*
|
|
16
|
+
* ### 1. Resource:Action Permissions
|
|
17
|
+
* Used for API access control (admin plugin, API keys).
|
|
18
|
+
* Pattern: `{ resource: [actions] }` where actions can include '*' for wildcard.
|
|
19
|
+
*
|
|
20
|
+
* ### 2. Role-Based Permissions
|
|
21
|
+
* Hierarchical roles (owner > admin > member > viewer) with predefined capabilities.
|
|
22
|
+
*
|
|
23
|
+
* ### 3. Table/Record Permissions
|
|
24
|
+
* Application-layer permission checking for data access control.
|
|
25
|
+
* See `@/domain/models/app/table/permissions/` for table-specific schemas.
|
|
26
|
+
*
|
|
27
|
+
* ## Usage
|
|
28
|
+
*
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import {
|
|
31
|
+
* ResourceActionPermissionsSchema,
|
|
32
|
+
* StandardRoleSchema,
|
|
33
|
+
* } from '@/domain/models/app/permissions'
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
// Resource:Action pattern for API permissions
|
|
38
|
+
export {
|
|
39
|
+
ResourceActionPermissionsSchema,
|
|
40
|
+
ResourceNameSchema,
|
|
41
|
+
ActionNameSchema,
|
|
42
|
+
ActionWithWildcardSchema,
|
|
43
|
+
type ResourceActionPermissions,
|
|
44
|
+
type ResourceName,
|
|
45
|
+
type ActionName,
|
|
46
|
+
type ActionWithWildcard,
|
|
47
|
+
} from './resource-action'
|
|
48
|
+
|
|
49
|
+
// Role definitions
|
|
50
|
+
export {
|
|
51
|
+
StandardRoleSchema,
|
|
52
|
+
AdminLevelRoleSchema,
|
|
53
|
+
UserLevelRoleSchema,
|
|
54
|
+
FlexibleRolesSchema,
|
|
55
|
+
StandardRolesArraySchema,
|
|
56
|
+
type StandardRole,
|
|
57
|
+
type AdminLevelRole,
|
|
58
|
+
type UserLevelRole,
|
|
59
|
+
type FlexibleRoles,
|
|
60
|
+
type StandardRolesArray,
|
|
61
|
+
} from './roles'
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Schema } from 'effect'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Resource Name Schema
|
|
12
|
+
*
|
|
13
|
+
* Validates resource names in the resource:action permission pattern.
|
|
14
|
+
* Must start with a letter and contain only lowercase letters, numbers, underscores, or hyphens.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* Valid: "users", "posts", "api_keys", "user-profiles"
|
|
18
|
+
* Invalid: "123users", "_posts", "User Posts"
|
|
19
|
+
*/
|
|
20
|
+
export const ResourceNameSchema = Schema.String.pipe(
|
|
21
|
+
Schema.pattern(/^[a-z][a-z0-9_-]*$/i),
|
|
22
|
+
Schema.annotations({
|
|
23
|
+
title: 'Resource Name',
|
|
24
|
+
description: 'Resource identifier (e.g., "users", "posts", "analytics")',
|
|
25
|
+
examples: ['users', 'posts', 'api_keys', 'user-profiles'],
|
|
26
|
+
})
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
export type ResourceName = Schema.Schema.Type<typeof ResourceNameSchema>
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Action Name Schema
|
|
33
|
+
*
|
|
34
|
+
* Validates action names in the resource:action permission pattern.
|
|
35
|
+
* Must start with a letter and contain only lowercase letters, numbers, underscores, or hyphens.
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* Valid: "read", "write", "create", "delete", "list_all"
|
|
39
|
+
* Invalid: "123read", "_write"
|
|
40
|
+
*/
|
|
41
|
+
export const ActionNameSchema = Schema.String.pipe(
|
|
42
|
+
Schema.pattern(/^[a-z][a-z0-9_-]*$/i),
|
|
43
|
+
Schema.annotations({
|
|
44
|
+
title: 'Action Name',
|
|
45
|
+
description: 'Action identifier (e.g., "read", "write", "create", "delete")',
|
|
46
|
+
examples: ['read', 'write', 'create', 'update', 'delete', 'list'],
|
|
47
|
+
})
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
export type ActionName = Schema.Schema.Type<typeof ActionNameSchema>
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Action with Wildcard Schema
|
|
54
|
+
*
|
|
55
|
+
* Either a specific action name or "*" for all actions on a resource.
|
|
56
|
+
*/
|
|
57
|
+
export const ActionWithWildcardSchema = Schema.Union(Schema.Literal('*'), ActionNameSchema).pipe(
|
|
58
|
+
Schema.annotations({
|
|
59
|
+
title: 'Action',
|
|
60
|
+
description: 'Action name or "*" for all actions',
|
|
61
|
+
examples: ['read', 'write', '*'],
|
|
62
|
+
})
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
export type ActionWithWildcard = Schema.Schema.Type<typeof ActionWithWildcardSchema>
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Resource:Action Permissions Schema (Shared)
|
|
69
|
+
*
|
|
70
|
+
* Defines granular permissions using the resource:action pattern.
|
|
71
|
+
* Each resource maps to an array of allowed actions.
|
|
72
|
+
*
|
|
73
|
+
* This schema is shared between:
|
|
74
|
+
* - Admin plugin (customPermissions)
|
|
75
|
+
* - API Keys plugin (resourcePermissions)
|
|
76
|
+
* - Any future permission-based features
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* {
|
|
81
|
+
* users: ['read', 'list'],
|
|
82
|
+
* posts: ['create', 'read', 'update', 'delete'],
|
|
83
|
+
* analytics: ['*'] // Wildcard for all actions
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export const ResourceActionPermissionsSchema = Schema.Record({
|
|
88
|
+
key: ResourceNameSchema.pipe(
|
|
89
|
+
Schema.annotations({ description: 'Resource name (e.g., "users", "posts")' })
|
|
90
|
+
),
|
|
91
|
+
value: Schema.Array(ActionWithWildcardSchema).pipe(
|
|
92
|
+
Schema.minItems(1),
|
|
93
|
+
Schema.annotations({ description: 'Allowed actions for this resource' })
|
|
94
|
+
),
|
|
95
|
+
}).pipe(
|
|
96
|
+
Schema.annotations({
|
|
97
|
+
title: 'Resource:Action Permissions',
|
|
98
|
+
description:
|
|
99
|
+
'Granular permission definitions using resource:action pattern. Shared across admin, API keys, and other permission contexts.',
|
|
100
|
+
examples: [
|
|
101
|
+
{
|
|
102
|
+
users: ['read', 'list'],
|
|
103
|
+
posts: ['create', 'read', 'update', 'delete'],
|
|
104
|
+
analytics: ['*'],
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
comments: ['create', 'read', 'delete'],
|
|
108
|
+
media: ['*'],
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
})
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
export type ResourceActionPermissions = Schema.Schema.Type<typeof ResourceActionPermissionsSchema>
|
|
@@ -0,0 +1,120 @@
|
|
|
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
|
+
* Standard Role Schema
|
|
12
|
+
*
|
|
13
|
+
* The three built-in roles used across the authentication system.
|
|
14
|
+
* These roles have well-defined hierarchies and permissions.
|
|
15
|
+
*
|
|
16
|
+
* Role Hierarchy (highest to lowest):
|
|
17
|
+
* - `admin`: Can manage members and settings
|
|
18
|
+
* - `member`: Standard access to organization resources
|
|
19
|
+
* - `viewer`: Read-only access
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* defaultRole: 'member'
|
|
24
|
+
* creatorRole: 'admin'
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export const StandardRoleSchema = Schema.Literal('admin', 'member', 'viewer').pipe(
|
|
28
|
+
Schema.annotations({
|
|
29
|
+
title: 'Standard Role',
|
|
30
|
+
description: 'Built-in role with predefined permissions. Hierarchy: admin > member > viewer',
|
|
31
|
+
examples: ['admin', 'member', 'viewer'],
|
|
32
|
+
})
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
export type StandardRole = Schema.Schema.Type<typeof StandardRoleSchema>
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Admin-Level Role Schema
|
|
39
|
+
*
|
|
40
|
+
* Subset of roles with administrative capabilities.
|
|
41
|
+
* Used for features like role creation/assignment restrictions.
|
|
42
|
+
*/
|
|
43
|
+
export const AdminLevelRoleSchema = Schema.Literal('admin').pipe(
|
|
44
|
+
Schema.annotations({
|
|
45
|
+
title: 'Admin-Level Role',
|
|
46
|
+
description: 'Roles with administrative capabilities (admin)',
|
|
47
|
+
examples: ['admin'],
|
|
48
|
+
})
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
export type AdminLevelRole = Schema.Schema.Type<typeof AdminLevelRoleSchema>
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* User-Level Role Schema
|
|
55
|
+
*
|
|
56
|
+
* Subset of standard roles for default user role assignment.
|
|
57
|
+
* Used in admin plugin for defaultRole configuration.
|
|
58
|
+
*/
|
|
59
|
+
export const UserLevelRoleSchema = Schema.String.pipe(
|
|
60
|
+
Schema.filter(
|
|
61
|
+
(value): value is 'admin' | 'member' | 'viewer' => {
|
|
62
|
+
return value === 'admin' || value === 'member' || value === 'viewer'
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
message: () => 'Invalid role. Must be one of: admin, member, viewer',
|
|
66
|
+
}
|
|
67
|
+
),
|
|
68
|
+
Schema.annotations({
|
|
69
|
+
title: 'User-Level Role',
|
|
70
|
+
description: 'Roles available for default user assignment in admin context',
|
|
71
|
+
examples: ['admin', 'member', 'viewer'],
|
|
72
|
+
})
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
export type UserLevelRole = Schema.Schema.Type<typeof UserLevelRoleSchema>
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Flexible Roles Schema
|
|
79
|
+
*
|
|
80
|
+
* Array of role names as strings for table permissions.
|
|
81
|
+
* Allows both standard roles and custom role names.
|
|
82
|
+
*
|
|
83
|
+
* Use this when:
|
|
84
|
+
* - Custom roles are supported (dynamic roles feature)
|
|
85
|
+
* - Role names come from user configuration
|
|
86
|
+
* - Flexibility is more important than strict validation
|
|
87
|
+
*
|
|
88
|
+
* @example
|
|
89
|
+
* ```typescript
|
|
90
|
+
* roles: ['admin', 'editor', 'custom-role']
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export const FlexibleRolesSchema = Schema.Array(Schema.String).pipe(
|
|
94
|
+
Schema.minItems(1),
|
|
95
|
+
Schema.annotations({
|
|
96
|
+
title: 'Flexible Roles',
|
|
97
|
+
description:
|
|
98
|
+
'Array of role names (supports both standard and custom roles). At least one role required.',
|
|
99
|
+
examples: [['admin'], ['admin', 'member'], ['admin', 'editor', 'custom-role']],
|
|
100
|
+
})
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
export type FlexibleRoles = Schema.Schema.Type<typeof FlexibleRolesSchema>
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Standard Roles Array Schema
|
|
107
|
+
*
|
|
108
|
+
* Array of standard roles only (no custom roles).
|
|
109
|
+
* Use for strict validation when only built-in roles are allowed.
|
|
110
|
+
*/
|
|
111
|
+
export const StandardRolesArraySchema = Schema.Array(StandardRoleSchema).pipe(
|
|
112
|
+
Schema.minItems(1),
|
|
113
|
+
Schema.annotations({
|
|
114
|
+
title: 'Standard Roles Array',
|
|
115
|
+
description: 'Array of standard roles only (admin, member, viewer)',
|
|
116
|
+
examples: [['admin'], ['admin', 'member'], ['admin', 'member', 'viewer']],
|
|
117
|
+
})
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
export type StandardRolesArray = Schema.Schema.Type<typeof StandardRolesArraySchema>
|
|
@@ -0,0 +1,105 @@
|
|
|
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
|
+
* Check Constraint Schema
|
|
12
|
+
*
|
|
13
|
+
* Defines a custom CHECK constraint that validates data at the database level.
|
|
14
|
+
* CHECK constraints allow you to enforce complex business rules beyond basic
|
|
15
|
+
* field-level validation.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* const constraint = {
|
|
20
|
+
* name: 'chk_active_members_have_email',
|
|
21
|
+
* check: '(is_active = false) OR (email IS NOT NULL)'
|
|
22
|
+
* }
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export const CheckConstraintSchema = Schema.Struct({
|
|
26
|
+
/**
|
|
27
|
+
* Constraint name (must be unique within the table)
|
|
28
|
+
*/
|
|
29
|
+
name: Schema.String.pipe(
|
|
30
|
+
Schema.minLength(1),
|
|
31
|
+
Schema.pattern(/^[a-z][a-z0-9_]*$/),
|
|
32
|
+
Schema.annotations({
|
|
33
|
+
title: 'Constraint Name',
|
|
34
|
+
description:
|
|
35
|
+
'Unique name for the CHECK constraint (lowercase, alphanumeric with underscores)',
|
|
36
|
+
examples: ['chk_active_members_have_email', 'chk_price_positive', 'chk_end_after_start'],
|
|
37
|
+
})
|
|
38
|
+
),
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* SQL check expression
|
|
42
|
+
*/
|
|
43
|
+
check: Schema.String.pipe(
|
|
44
|
+
Schema.minLength(1),
|
|
45
|
+
Schema.annotations({
|
|
46
|
+
title: 'Check Expression',
|
|
47
|
+
description: 'PostgreSQL boolean expression that must evaluate to TRUE for valid data',
|
|
48
|
+
examples: [
|
|
49
|
+
'(is_active = false) OR (email IS NOT NULL)',
|
|
50
|
+
'price > 0',
|
|
51
|
+
'end_date > start_date',
|
|
52
|
+
"(status = 'completed') OR (completed_at IS NULL)",
|
|
53
|
+
],
|
|
54
|
+
})
|
|
55
|
+
),
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
export type CheckConstraint = Schema.Schema.Type<typeof CheckConstraintSchema>
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Check Constraints Schema
|
|
62
|
+
*
|
|
63
|
+
* Array of CHECK constraints applied at the table level.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const constraints = [
|
|
68
|
+
* {
|
|
69
|
+
* name: 'chk_active_members_have_email',
|
|
70
|
+
* check: '(is_active = false) OR (email IS NOT NULL)'
|
|
71
|
+
* },
|
|
72
|
+
* {
|
|
73
|
+
* name: 'chk_price_positive',
|
|
74
|
+
* check: 'price > 0'
|
|
75
|
+
* }
|
|
76
|
+
* ]
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export const CheckConstraintsSchema = Schema.Array(CheckConstraintSchema).pipe(
|
|
80
|
+
Schema.annotations({
|
|
81
|
+
title: 'Check Constraints',
|
|
82
|
+
description:
|
|
83
|
+
'Table-level CHECK constraints for enforcing complex business rules beyond field-level validation',
|
|
84
|
+
examples: [
|
|
85
|
+
[
|
|
86
|
+
{
|
|
87
|
+
name: 'chk_active_members_have_email',
|
|
88
|
+
check: '(is_active = false) OR (email IS NOT NULL)',
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
[
|
|
92
|
+
{
|
|
93
|
+
name: 'chk_price_positive',
|
|
94
|
+
check: 'price > 0',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
name: 'chk_end_after_start',
|
|
98
|
+
check: 'end_date > start_date',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
],
|
|
102
|
+
})
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
export type CheckConstraints = Schema.Schema.Type<typeof CheckConstraintsSchema>
|
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
/**
|
|
9
|
+
* Shared cycle detection utilities using depth-first search (DFS)
|
|
10
|
+
* Used for detecting circular dependencies in both formula fields and table relationships
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* State tracked during DFS traversal
|
|
15
|
+
*/
|
|
16
|
+
type DFSState = {
|
|
17
|
+
readonly visited: ReadonlySet<string>
|
|
18
|
+
readonly recursionStack: ReadonlySet<string>
|
|
19
|
+
readonly cycleNodes: ReadonlyArray<string>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Result of cycle detection
|
|
24
|
+
*/
|
|
25
|
+
type CycleResult = {
|
|
26
|
+
readonly found: boolean
|
|
27
|
+
readonly state: DFSState
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Detect cycles in a dependency graph using depth-first search (DFS)
|
|
32
|
+
*
|
|
33
|
+
* @param dependencyGraph - Map of node name to array of nodes it depends on
|
|
34
|
+
* @returns Array of node names involved in circular dependencies, or empty array if none found
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const graph = new Map([
|
|
39
|
+
* ['A', ['B']],
|
|
40
|
+
* ['B', ['C']],
|
|
41
|
+
* ['C', ['A']], // Circular: A -> B -> C -> A
|
|
42
|
+
* ])
|
|
43
|
+
* detectCycles(graph) // ['A', 'B', 'C']
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export const detectCycles = (
|
|
47
|
+
dependencyGraph: ReadonlyMap<string, ReadonlyArray<string>>
|
|
48
|
+
): ReadonlyArray<string> => {
|
|
49
|
+
const hasCycle = (node: string, state: DFSState): CycleResult => {
|
|
50
|
+
if (state.recursionStack.has(node)) {
|
|
51
|
+
// Cycle detected - add to result
|
|
52
|
+
return {
|
|
53
|
+
found: true,
|
|
54
|
+
state: {
|
|
55
|
+
...state,
|
|
56
|
+
cycleNodes: [...state.cycleNodes, node],
|
|
57
|
+
},
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (state.visited.has(node)) {
|
|
62
|
+
// Already processed this node
|
|
63
|
+
return { found: false, state }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const newState: DFSState = {
|
|
67
|
+
visited: new Set([...state.visited, node]),
|
|
68
|
+
recursionStack: new Set([...state.recursionStack, node]),
|
|
69
|
+
cycleNodes: state.cycleNodes,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const dependencies = dependencyGraph.get(node) || []
|
|
73
|
+
const result = dependencies.reduce<CycleResult>(
|
|
74
|
+
(acc, dep) => {
|
|
75
|
+
if (acc.found || !dependencyGraph.has(dep)) {
|
|
76
|
+
return acc
|
|
77
|
+
}
|
|
78
|
+
const depResult = hasCycle(dep, acc.state)
|
|
79
|
+
if (depResult.found) {
|
|
80
|
+
// Propagate cycle detection
|
|
81
|
+
const cycleNodes = depResult.state.cycleNodes.includes(node)
|
|
82
|
+
? depResult.state.cycleNodes
|
|
83
|
+
: [...depResult.state.cycleNodes, node]
|
|
84
|
+
return {
|
|
85
|
+
found: true,
|
|
86
|
+
state: {
|
|
87
|
+
...depResult.state,
|
|
88
|
+
cycleNodes,
|
|
89
|
+
},
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return depResult
|
|
93
|
+
},
|
|
94
|
+
{ found: false, state: newState }
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
// Remove from recursion stack after processing (immutable way)
|
|
98
|
+
const finalState: DFSState = {
|
|
99
|
+
...result.state,
|
|
100
|
+
recursionStack: new Set([...result.state.recursionStack].filter((n) => n !== node)),
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return { found: result.found, state: finalState }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Check all nodes for cycles
|
|
107
|
+
const initialState: DFSState = {
|
|
108
|
+
visited: new Set(),
|
|
109
|
+
recursionStack: new Set(),
|
|
110
|
+
cycleNodes: [],
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const result = [...dependencyGraph.keys()].reduce<CycleResult>(
|
|
114
|
+
(acc, nodeName) => {
|
|
115
|
+
if (acc.found || acc.state.visited.has(nodeName)) {
|
|
116
|
+
return acc
|
|
117
|
+
}
|
|
118
|
+
return hasCycle(nodeName, acc.state)
|
|
119
|
+
},
|
|
120
|
+
{ found: false, state: initialState }
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
return result.state.cycleNodes
|
|
124
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
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
|
+
* Reserved SQL keywords that cannot be used as table or column names
|
|
12
|
+
* Based on PostgreSQL reserved keywords list
|
|
13
|
+
* @see https://www.postgresql.org/docs/current/sql-keywords-appendix.html
|
|
14
|
+
*/
|
|
15
|
+
const SQL_RESERVED_KEYWORDS = new Set([
|
|
16
|
+
'select',
|
|
17
|
+
'insert',
|
|
18
|
+
'update',
|
|
19
|
+
'delete',
|
|
20
|
+
'from',
|
|
21
|
+
'where',
|
|
22
|
+
'join',
|
|
23
|
+
'inner',
|
|
24
|
+
'outer',
|
|
25
|
+
'left',
|
|
26
|
+
'right',
|
|
27
|
+
'full',
|
|
28
|
+
'cross',
|
|
29
|
+
'on',
|
|
30
|
+
'as',
|
|
31
|
+
'table',
|
|
32
|
+
'create',
|
|
33
|
+
'alter',
|
|
34
|
+
'drop',
|
|
35
|
+
'truncate',
|
|
36
|
+
'add',
|
|
37
|
+
'column',
|
|
38
|
+
'constraint',
|
|
39
|
+
'primary',
|
|
40
|
+
'foreign',
|
|
41
|
+
'key',
|
|
42
|
+
'references',
|
|
43
|
+
'unique',
|
|
44
|
+
'index',
|
|
45
|
+
'view',
|
|
46
|
+
'database',
|
|
47
|
+
'schema',
|
|
48
|
+
'grant',
|
|
49
|
+
'revoke',
|
|
50
|
+
'transaction',
|
|
51
|
+
'commit',
|
|
52
|
+
'rollback',
|
|
53
|
+
'union',
|
|
54
|
+
'intersect',
|
|
55
|
+
'except',
|
|
56
|
+
'group',
|
|
57
|
+
'having',
|
|
58
|
+
'order',
|
|
59
|
+
'limit',
|
|
60
|
+
'offset',
|
|
61
|
+
'distinct',
|
|
62
|
+
'all',
|
|
63
|
+
'any',
|
|
64
|
+
'some',
|
|
65
|
+
'exists',
|
|
66
|
+
'in',
|
|
67
|
+
'between',
|
|
68
|
+
'like',
|
|
69
|
+
'ilike',
|
|
70
|
+
'and',
|
|
71
|
+
'or',
|
|
72
|
+
'not',
|
|
73
|
+
'null',
|
|
74
|
+
'is',
|
|
75
|
+
'true',
|
|
76
|
+
'false',
|
|
77
|
+
'case',
|
|
78
|
+
'when',
|
|
79
|
+
'then',
|
|
80
|
+
'else',
|
|
81
|
+
'end',
|
|
82
|
+
'cast',
|
|
83
|
+
'default',
|
|
84
|
+
'check',
|
|
85
|
+
'user',
|
|
86
|
+
'current_user',
|
|
87
|
+
'session_user',
|
|
88
|
+
'current_date',
|
|
89
|
+
'current_time',
|
|
90
|
+
'current_timestamp',
|
|
91
|
+
])
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Database Identifier Validation (Strict - for field names and column names)
|
|
95
|
+
*
|
|
96
|
+
* Shared validation schema for PostgreSQL identifiers (column names, field names, etc.)
|
|
97
|
+
* Must follow database naming conventions: start with a letter, contain only lowercase
|
|
98
|
+
* letters, numbers, and underscores, maximum 63 characters (PostgreSQL limit).
|
|
99
|
+
*
|
|
100
|
+
* This schema is used for field names and column names which must be strict.
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```typescript
|
|
104
|
+
* 'users'
|
|
105
|
+
* 'email_address'
|
|
106
|
+
* 'created_at'
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
export const createDatabaseIdentifierSchema = (identifierType: 'table' | 'field' | 'column') =>
|
|
110
|
+
identifierType === 'table'
|
|
111
|
+
? // Table names: Allow user-friendly format (will be sanitized for database)
|
|
112
|
+
Schema.String.pipe(
|
|
113
|
+
Schema.minLength(1, { message: () => 'This field is required' }),
|
|
114
|
+
Schema.maxLength(63, { message: () => 'Maximum length is 63 characters' }),
|
|
115
|
+
Schema.filter((name) => {
|
|
116
|
+
const trimmed = name.trim()
|
|
117
|
+
if (/^\d/.test(trimmed)) {
|
|
118
|
+
return `Invalid table name '${name}': name must start with a letter`
|
|
119
|
+
}
|
|
120
|
+
if (!/^[a-zA-Z][a-zA-Z0-9_\s-]*$/.test(trimmed)) {
|
|
121
|
+
return `Invalid table name '${name}': name must start with a letter and contain only letters, numbers, underscores, hyphens, or spaces`
|
|
122
|
+
}
|
|
123
|
+
return true
|
|
124
|
+
}),
|
|
125
|
+
Schema.filter((name) => {
|
|
126
|
+
const sanitized = name
|
|
127
|
+
.toLowerCase()
|
|
128
|
+
.replace(/[^a-z0-9_]/g, '_')
|
|
129
|
+
.replace(/_+/g, '_')
|
|
130
|
+
.replace(/^_+|_+$/g, '')
|
|
131
|
+
const isReserved = SQL_RESERVED_KEYWORDS.has(sanitized)
|
|
132
|
+
return (
|
|
133
|
+
!isReserved ||
|
|
134
|
+
`Table name '${name}' resolves to reserved SQL keyword '${sanitized}'. Reserved keywords like SELECT, INSERT, UPDATE, DELETE, etc. are restricted to prevent SQL syntax conflicts. Choose a different name.`
|
|
135
|
+
)
|
|
136
|
+
})
|
|
137
|
+
)
|
|
138
|
+
: // Field/column names: Strict database pattern
|
|
139
|
+
Schema.String.pipe(
|
|
140
|
+
Schema.minLength(1, { message: () => 'This field is required' }),
|
|
141
|
+
Schema.maxLength(63, { message: () => 'Maximum length is 63 characters' }),
|
|
142
|
+
Schema.pattern(/^[a-z][a-z0-9_]*$/, {
|
|
143
|
+
message: () =>
|
|
144
|
+
`Invalid ${identifierType} name pattern. Must follow database naming conventions: start with a letter, contain only lowercase letters, numbers, and underscores, maximum 63 characters (PostgreSQL limit). This name is used in SQL queries, API endpoints, and code generation. Choose descriptive names that clearly indicate the purpose (e.g., "email_address" not "ea").`,
|
|
145
|
+
}),
|
|
146
|
+
Schema.filter((name) => {
|
|
147
|
+
const isReserved = SQL_RESERVED_KEYWORDS.has(name.toLowerCase())
|
|
148
|
+
return (
|
|
149
|
+
!isReserved ||
|
|
150
|
+
`Cannot use reserved SQL keyword '${name}' as ${identifierType} name. Reserved keywords like SELECT, INSERT, UPDATE, DELETE, etc. are restricted to prevent SQL syntax conflicts. Choose a descriptive alternative name (e.g., 'user_record' instead of 'user', 'selection' instead of 'select').`
|
|
151
|
+
)
|
|
152
|
+
})
|
|
153
|
+
)
|