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,63 @@
|
|
|
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
|
+
* Two-Factor Authentication Plugin Configuration
|
|
12
|
+
*
|
|
13
|
+
* Enables TOTP-based two-factor authentication.
|
|
14
|
+
* Users can set up 2FA using authenticator apps.
|
|
15
|
+
*
|
|
16
|
+
* Configuration options:
|
|
17
|
+
* - issuer: Name shown in authenticator apps (e.g., "MyApp")
|
|
18
|
+
* - backupCodes: Generate backup codes for account recovery
|
|
19
|
+
* - digits: Number of digits in TOTP code (default: 6)
|
|
20
|
+
* - period: Time period for code rotation in seconds (default: 30)
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* // Simple enable
|
|
25
|
+
* { plugins: { twoFactor: true } }
|
|
26
|
+
*
|
|
27
|
+
* // With configuration
|
|
28
|
+
* { plugins: { twoFactor: { issuer: 'MyApp', backupCodes: true } } }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export const TwoFactorConfigSchema = Schema.Union(
|
|
32
|
+
Schema.Boolean,
|
|
33
|
+
Schema.Struct({
|
|
34
|
+
issuer: Schema.optional(
|
|
35
|
+
Schema.String.pipe(
|
|
36
|
+
Schema.annotations({ description: 'Issuer name shown in authenticator apps' })
|
|
37
|
+
)
|
|
38
|
+
),
|
|
39
|
+
backupCodes: Schema.optional(
|
|
40
|
+
Schema.Boolean.pipe(Schema.annotations({ description: 'Generate backup codes for recovery' }))
|
|
41
|
+
),
|
|
42
|
+
digits: Schema.optional(
|
|
43
|
+
Schema.Number.pipe(
|
|
44
|
+
Schema.between(4, 8),
|
|
45
|
+
Schema.annotations({ description: 'Number of digits in TOTP code (4-8)' })
|
|
46
|
+
)
|
|
47
|
+
),
|
|
48
|
+
period: Schema.optional(
|
|
49
|
+
Schema.Number.pipe(
|
|
50
|
+
Schema.positive(),
|
|
51
|
+
Schema.annotations({ description: 'Code rotation period in seconds' })
|
|
52
|
+
)
|
|
53
|
+
),
|
|
54
|
+
})
|
|
55
|
+
).pipe(
|
|
56
|
+
Schema.annotations({
|
|
57
|
+
title: 'Two-Factor Authentication Configuration',
|
|
58
|
+
description: 'TOTP-based two-factor authentication',
|
|
59
|
+
examples: [true, { issuer: 'MyApp', backupCodes: true }],
|
|
60
|
+
})
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
export type TwoFactorConfig = Schema.Schema.Type<typeof TwoFactorConfigSchema>
|
|
@@ -0,0 +1,179 @@
|
|
|
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
|
+
* Built-in Role Names
|
|
12
|
+
*
|
|
13
|
+
* These roles are always available without configuration.
|
|
14
|
+
* They cannot be redefined by custom role definitions.
|
|
15
|
+
*
|
|
16
|
+
* Hierarchy (highest to lowest):
|
|
17
|
+
* - admin (80): Can manage members and settings
|
|
18
|
+
* - member (40): Standard access to organization resources
|
|
19
|
+
* - viewer (10): Read-only access
|
|
20
|
+
*/
|
|
21
|
+
export const BUILT_IN_ROLES = ['admin', 'member', 'viewer'] as const
|
|
22
|
+
|
|
23
|
+
export const BUILT_IN_ROLE_LEVELS: Readonly<Record<string, number>> = {
|
|
24
|
+
admin: 80,
|
|
25
|
+
member: 40,
|
|
26
|
+
viewer: 10,
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Built-in Role Schema
|
|
31
|
+
*
|
|
32
|
+
* The three built-in roles with predefined hierarchy levels.
|
|
33
|
+
*/
|
|
34
|
+
export const BuiltInRoleSchema = Schema.Literal('admin', 'member', 'viewer').pipe(
|
|
35
|
+
Schema.annotations({
|
|
36
|
+
title: 'Built-in Role',
|
|
37
|
+
description: 'Built-in role with predefined hierarchy. Levels: admin=80, member=40, viewer=10',
|
|
38
|
+
examples: ['admin', 'member', 'viewer'],
|
|
39
|
+
})
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
export type BuiltInRole = Schema.Schema.Type<typeof BuiltInRoleSchema>
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Role Name Schema
|
|
46
|
+
*
|
|
47
|
+
* Validates role naming convention: lowercase, alphanumeric, hyphens allowed.
|
|
48
|
+
* Must start with a letter.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* 'editor' // valid
|
|
53
|
+
* 'content-manager' // valid
|
|
54
|
+
* 'Editor' // invalid (uppercase)
|
|
55
|
+
* '123role' // invalid (starts with number)
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export const RoleNameSchema = Schema.String.pipe(
|
|
59
|
+
Schema.pattern(/^[a-z][a-z0-9-]*$/),
|
|
60
|
+
Schema.annotations({
|
|
61
|
+
title: 'Role Name',
|
|
62
|
+
description: 'Role name: lowercase, alphanumeric, hyphens. Must start with a letter.',
|
|
63
|
+
examples: ['editor', 'content-manager', 'moderator'],
|
|
64
|
+
})
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
export type RoleName = Schema.Schema.Type<typeof RoleNameSchema>
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Custom Role Definition Schema
|
|
71
|
+
*
|
|
72
|
+
* Defines a custom role with an optional description and hierarchy level.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```typescript
|
|
76
|
+
* { name: 'editor', description: 'Can edit content', level: 30 }
|
|
77
|
+
* { name: 'moderator' }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export const RoleDefinitionSchema = Schema.Struct({
|
|
81
|
+
name: RoleNameSchema,
|
|
82
|
+
description: Schema.optional(
|
|
83
|
+
Schema.String.pipe(
|
|
84
|
+
Schema.annotations({ description: 'Human-readable description of the role' })
|
|
85
|
+
)
|
|
86
|
+
),
|
|
87
|
+
level: Schema.optional(
|
|
88
|
+
Schema.Number.pipe(
|
|
89
|
+
Schema.annotations({
|
|
90
|
+
description:
|
|
91
|
+
'Hierarchy level (higher = more permissions). Built-in: admin=80, member=40, viewer=10',
|
|
92
|
+
})
|
|
93
|
+
)
|
|
94
|
+
),
|
|
95
|
+
}).pipe(
|
|
96
|
+
Schema.annotations({
|
|
97
|
+
title: 'Role Definition',
|
|
98
|
+
description:
|
|
99
|
+
'Custom role definition with name, optional description, and optional hierarchy level.',
|
|
100
|
+
examples: [
|
|
101
|
+
{ name: 'editor', description: 'Can edit content', level: 30 },
|
|
102
|
+
{ name: 'moderator', level: 20 },
|
|
103
|
+
{ name: 'contributor' },
|
|
104
|
+
],
|
|
105
|
+
})
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
export type RoleDefinition = Schema.Schema.Type<typeof RoleDefinitionSchema>
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Roles Config Schema
|
|
112
|
+
*
|
|
113
|
+
* Array of custom role definitions. Empty array is valid (only built-in roles).
|
|
114
|
+
*
|
|
115
|
+
* Validates:
|
|
116
|
+
* - Role names are unique
|
|
117
|
+
* - Custom role names don't conflict with built-in role names
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* [] // valid: only built-in roles
|
|
122
|
+
* [{ name: 'editor', level: 30 }, { name: 'moderator', level: 20 }]
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export const RolesConfigSchema = Schema.Array(RoleDefinitionSchema).pipe(
|
|
126
|
+
Schema.filter((roles) => {
|
|
127
|
+
// Check for duplicate names
|
|
128
|
+
const names = roles.map((r) => r.name)
|
|
129
|
+
const uniqueNames = new Set(names)
|
|
130
|
+
if (uniqueNames.size !== names.length) {
|
|
131
|
+
const duplicates = names.filter((name, i) => names.indexOf(name) !== i)
|
|
132
|
+
return `Duplicate role names: ${duplicates.join(', ')}`
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Check for conflicts with built-in roles
|
|
136
|
+
const conflicts = names.filter((name) => (BUILT_IN_ROLES as readonly string[]).includes(name))
|
|
137
|
+
if (conflicts.length > 0) {
|
|
138
|
+
return `Custom role names cannot conflict with built-in roles: ${conflicts.join(', ')}`
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return undefined
|
|
142
|
+
}),
|
|
143
|
+
Schema.annotations({
|
|
144
|
+
title: 'Roles Configuration',
|
|
145
|
+
description: 'Array of custom role definitions. Built-in roles are always available.',
|
|
146
|
+
examples: [
|
|
147
|
+
[],
|
|
148
|
+
[
|
|
149
|
+
{ name: 'editor', description: 'Can edit content', level: 30 },
|
|
150
|
+
{ name: 'moderator', level: 20 },
|
|
151
|
+
],
|
|
152
|
+
],
|
|
153
|
+
})
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
export type RolesConfig = Schema.Schema.Type<typeof RolesConfigSchema>
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Default Role Schema
|
|
160
|
+
*
|
|
161
|
+
* Accepts built-in roles and custom role names.
|
|
162
|
+
* Defaults to 'member' when not specified.
|
|
163
|
+
*
|
|
164
|
+
* @example
|
|
165
|
+
* ```typescript
|
|
166
|
+
* 'viewer' // built-in role
|
|
167
|
+
* 'editor' // custom role (must be defined in auth.roles)
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export const DefaultRoleSchema = Schema.String.pipe(
|
|
171
|
+
Schema.annotations({
|
|
172
|
+
title: 'Default Role',
|
|
173
|
+
description:
|
|
174
|
+
'Role assigned to new users by default. Accepts built-in roles or custom role names. Defaults to member.',
|
|
175
|
+
examples: ['member', 'viewer', 'editor'],
|
|
176
|
+
})
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
export type DefaultRole = Schema.Schema.Type<typeof DefaultRoleSchema>
|
|
@@ -0,0 +1,191 @@
|
|
|
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 { OAuthProviderSchema } from './oauth/providers'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Email and Password Strategy Schema
|
|
13
|
+
*
|
|
14
|
+
* Traditional credential-based authentication.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* { type: 'emailAndPassword' }
|
|
19
|
+
* { type: 'emailAndPassword', minPasswordLength: 12, requireEmailVerification: true }
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
export const EmailAndPasswordStrategySchema = Schema.Struct({
|
|
23
|
+
type: Schema.Literal('emailAndPassword'),
|
|
24
|
+
minPasswordLength: Schema.optional(
|
|
25
|
+
Schema.Number.pipe(
|
|
26
|
+
Schema.between(6, 128),
|
|
27
|
+
Schema.annotations({ description: 'Minimum password length (6-128, default: 8)' })
|
|
28
|
+
)
|
|
29
|
+
),
|
|
30
|
+
maxPasswordLength: Schema.optional(
|
|
31
|
+
Schema.Number.pipe(
|
|
32
|
+
Schema.between(8, 256),
|
|
33
|
+
Schema.annotations({ description: 'Maximum password length (8-256, default: 128)' })
|
|
34
|
+
)
|
|
35
|
+
),
|
|
36
|
+
requireEmailVerification: Schema.optional(
|
|
37
|
+
Schema.Boolean.pipe(
|
|
38
|
+
Schema.annotations({
|
|
39
|
+
description: 'Require email verification before sign-in (default: false)',
|
|
40
|
+
})
|
|
41
|
+
)
|
|
42
|
+
),
|
|
43
|
+
autoSignIn: Schema.optional(
|
|
44
|
+
Schema.Boolean.pipe(
|
|
45
|
+
Schema.annotations({ description: 'Auto sign in after signup (default: true)' })
|
|
46
|
+
)
|
|
47
|
+
),
|
|
48
|
+
}).pipe(
|
|
49
|
+
Schema.annotations({
|
|
50
|
+
title: 'Email and Password Strategy',
|
|
51
|
+
description: 'Traditional credential-based authentication strategy',
|
|
52
|
+
examples: [
|
|
53
|
+
{ type: 'emailAndPassword' as const },
|
|
54
|
+
{ type: 'emailAndPassword' as const, minPasswordLength: 12 },
|
|
55
|
+
],
|
|
56
|
+
})
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
export type EmailAndPasswordStrategy = Schema.Schema.Type<typeof EmailAndPasswordStrategySchema>
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Magic Link Strategy Schema
|
|
63
|
+
*
|
|
64
|
+
* Passwordless authentication via email link.
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```typescript
|
|
68
|
+
* { type: 'magicLink' }
|
|
69
|
+
* { type: 'magicLink', expirationMinutes: 30 }
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export const MagicLinkStrategySchema = Schema.Struct({
|
|
73
|
+
type: Schema.Literal('magicLink'),
|
|
74
|
+
expirationMinutes: Schema.optional(
|
|
75
|
+
Schema.Number.pipe(
|
|
76
|
+
Schema.positive(),
|
|
77
|
+
Schema.annotations({ description: 'Link expiration time in minutes (default: 15)' })
|
|
78
|
+
)
|
|
79
|
+
),
|
|
80
|
+
}).pipe(
|
|
81
|
+
Schema.annotations({
|
|
82
|
+
title: 'Magic Link Strategy',
|
|
83
|
+
description: 'Passwordless authentication via email link',
|
|
84
|
+
examples: [
|
|
85
|
+
{ type: 'magicLink' as const },
|
|
86
|
+
{ type: 'magicLink' as const, expirationMinutes: 30 },
|
|
87
|
+
],
|
|
88
|
+
})
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
export type MagicLinkStrategy = Schema.Schema.Type<typeof MagicLinkStrategySchema>
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* OAuth Strategy Schema
|
|
95
|
+
*
|
|
96
|
+
* Social login with OAuth providers.
|
|
97
|
+
* Credentials are loaded from environment variables.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```typescript
|
|
101
|
+
* { type: 'oauth', providers: ['google', 'github'] }
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
export const OAuthStrategySchema = Schema.Struct({
|
|
105
|
+
type: Schema.Literal('oauth'),
|
|
106
|
+
providers: Schema.NonEmptyArray(OAuthProviderSchema).pipe(
|
|
107
|
+
Schema.annotations({
|
|
108
|
+
description: 'OAuth providers to enable. Credentials loaded from environment variables.',
|
|
109
|
+
})
|
|
110
|
+
),
|
|
111
|
+
}).pipe(
|
|
112
|
+
Schema.annotations({
|
|
113
|
+
title: 'OAuth Strategy',
|
|
114
|
+
description: 'Social login with OAuth providers (google, github, microsoft, slack, gitlab)',
|
|
115
|
+
examples: [{ type: 'oauth' as const, providers: ['google', 'github'] }],
|
|
116
|
+
})
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
export type OAuthStrategy = Schema.Schema.Type<typeof OAuthStrategySchema>
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Auth Strategy Schema
|
|
123
|
+
*
|
|
124
|
+
* Discriminated union of all supported authentication strategy types.
|
|
125
|
+
* The `type` field determines which strategy configuration applies.
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ```typescript
|
|
129
|
+
* { type: 'emailAndPassword', minPasswordLength: 12 }
|
|
130
|
+
* { type: 'magicLink' }
|
|
131
|
+
* { type: 'oauth', providers: ['google', 'github'] }
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export const AuthStrategySchema = Schema.Union(
|
|
135
|
+
EmailAndPasswordStrategySchema,
|
|
136
|
+
MagicLinkStrategySchema,
|
|
137
|
+
OAuthStrategySchema
|
|
138
|
+
).pipe(
|
|
139
|
+
Schema.annotations({
|
|
140
|
+
title: 'Auth Strategy',
|
|
141
|
+
description:
|
|
142
|
+
'Authentication strategy configuration. Discriminated by `type` field: emailAndPassword, magicLink, or oauth.',
|
|
143
|
+
examples: [
|
|
144
|
+
{ type: 'emailAndPassword' as const },
|
|
145
|
+
{ type: 'magicLink' as const },
|
|
146
|
+
{ type: 'oauth' as const, providers: ['google', 'github'] },
|
|
147
|
+
],
|
|
148
|
+
})
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
export type AuthStrategy = Schema.Schema.Type<typeof AuthStrategySchema>
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Auth Strategies Array Schema
|
|
155
|
+
*
|
|
156
|
+
* Non-empty array of authentication strategies.
|
|
157
|
+
* At least one strategy must be defined.
|
|
158
|
+
*
|
|
159
|
+
* Validates:
|
|
160
|
+
* - At least one strategy is present
|
|
161
|
+
* - No duplicate strategy types
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* [{ type: 'emailAndPassword' }]
|
|
166
|
+
* [{ type: 'emailAndPassword', minPasswordLength: 12 }, { type: 'oauth', providers: ['google'] }]
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
export const AuthStrategiesSchema = Schema.NonEmptyArray(AuthStrategySchema).pipe(
|
|
170
|
+
Schema.filter((strategies) => {
|
|
171
|
+
const types = strategies.map((s) => s.type)
|
|
172
|
+
const uniqueTypes = new Set(types)
|
|
173
|
+
if (uniqueTypes.size !== types.length) {
|
|
174
|
+
return 'Duplicate strategy types are not allowed. Each strategy type can only appear once.'
|
|
175
|
+
}
|
|
176
|
+
return undefined
|
|
177
|
+
}),
|
|
178
|
+
Schema.annotations({
|
|
179
|
+
title: 'Auth Strategies',
|
|
180
|
+
description: 'Array of authentication strategies. At least one required, no duplicates.',
|
|
181
|
+
examples: [
|
|
182
|
+
[{ type: 'emailAndPassword' as const }],
|
|
183
|
+
[
|
|
184
|
+
{ type: 'emailAndPassword' as const, minPasswordLength: 12 },
|
|
185
|
+
{ type: 'oauth' as const, providers: ['google'] },
|
|
186
|
+
],
|
|
187
|
+
],
|
|
188
|
+
})
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
export type AuthStrategies = Schema.Schema.Type<typeof AuthStrategiesSchema>
|
|
@@ -0,0 +1,127 @@
|
|
|
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 type { EmailAndPasswordConfig } from './methods/email-and-password'
|
|
9
|
+
import type { MagicLinkConfig } from './methods/magic-link'
|
|
10
|
+
import type { OAuthConfig } from './oauth'
|
|
11
|
+
import type { AdminConfig } from './plugins/admin'
|
|
12
|
+
import type { TwoFactorConfig } from './plugins/two-factor'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Auth Configuration for Validation
|
|
16
|
+
*
|
|
17
|
+
* Interface representing the flattened auth configuration structure
|
|
18
|
+
* used for cross-field validation.
|
|
19
|
+
*/
|
|
20
|
+
export interface AuthConfigForValidation {
|
|
21
|
+
readonly emailAndPassword?: EmailAndPasswordConfig
|
|
22
|
+
readonly magicLink?: MagicLinkConfig
|
|
23
|
+
readonly oauth?: OAuthConfig
|
|
24
|
+
readonly admin?: AdminConfig
|
|
25
|
+
readonly twoFactor?: TwoFactorConfig
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Validation Result
|
|
30
|
+
*/
|
|
31
|
+
export interface ValidationResult {
|
|
32
|
+
readonly success: boolean
|
|
33
|
+
readonly message?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Check if a specific authentication method is enabled
|
|
38
|
+
*/
|
|
39
|
+
export const isMethodEnabled = (
|
|
40
|
+
config: AuthConfigForValidation | undefined,
|
|
41
|
+
method: 'emailAndPassword' | 'magicLink' | 'oauth'
|
|
42
|
+
): boolean => {
|
|
43
|
+
if (!config) return false
|
|
44
|
+
const value = config[method]
|
|
45
|
+
if (typeof value === 'boolean') return value
|
|
46
|
+
return value !== undefined
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Validation Rules for Auth Configuration
|
|
51
|
+
*
|
|
52
|
+
* These rules ensure incompatible features aren't combined
|
|
53
|
+
* and that required dependencies are met.
|
|
54
|
+
*/
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Rule 1: Two-factor authentication requires a primary auth method
|
|
58
|
+
*
|
|
59
|
+
* 2FA is a second factor and requires a primary authentication method
|
|
60
|
+
* like emailAndPassword.
|
|
61
|
+
*/
|
|
62
|
+
export const validateTwoFactorRequiresPrimary = (
|
|
63
|
+
config: AuthConfigForValidation
|
|
64
|
+
): ValidationResult => {
|
|
65
|
+
const hasTwoFactor = config.twoFactor
|
|
66
|
+
|
|
67
|
+
if (!hasTwoFactor) {
|
|
68
|
+
return { success: true }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const hasEmailAndPassword = isMethodEnabled(config, 'emailAndPassword')
|
|
72
|
+
|
|
73
|
+
if (!hasEmailAndPassword) {
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
message: 'Two-factor authentication requires emailAndPassword authentication',
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return { success: true }
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Rule 2: OAuth requires at least one provider
|
|
85
|
+
*
|
|
86
|
+
* If OAuth is configured, it must have at least one provider.
|
|
87
|
+
* This is already enforced by Schema.NonEmptyArray but we
|
|
88
|
+
* include it for explicit documentation.
|
|
89
|
+
*/
|
|
90
|
+
export const validateOAuthHasProviders = (config: AuthConfigForValidation): ValidationResult => {
|
|
91
|
+
if (!config.oauth) {
|
|
92
|
+
return { success: true }
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const { providers } = config.oauth
|
|
96
|
+
if (!providers || providers.length === 0) {
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
message: 'OAuth configuration requires at least one provider',
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return { success: true }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Run all validation rules
|
|
108
|
+
*
|
|
109
|
+
* Returns the first validation failure or success.
|
|
110
|
+
*/
|
|
111
|
+
export const validateAuthConfig = (config: AuthConfigForValidation): ValidationResult => {
|
|
112
|
+
const rules = [validateTwoFactorRequiresPrimary, validateOAuthHasProviders]
|
|
113
|
+
|
|
114
|
+
return rules.reduce<ValidationResult>((acc, rule) => (acc.success ? rule(config) : acc), {
|
|
115
|
+
success: true,
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Check if a specific authentication method is enabled (alias)
|
|
121
|
+
*/
|
|
122
|
+
export const hasAuthMethod = (
|
|
123
|
+
config: AuthConfigForValidation,
|
|
124
|
+
methodName: 'emailAndPassword' | 'magicLink' | 'oauth'
|
|
125
|
+
): boolean => {
|
|
126
|
+
return isMethodEnabled(config, methodName)
|
|
127
|
+
}
|