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,107 @@
|
|
|
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
|
+
* Email Infrastructure Module
|
|
10
|
+
*
|
|
11
|
+
* Provides email functionality using Nodemailer with Better Auth integration.
|
|
12
|
+
*
|
|
13
|
+
* ## Configuration
|
|
14
|
+
*
|
|
15
|
+
* Set the following environment variables for production SMTP:
|
|
16
|
+
*
|
|
17
|
+
* ```bash
|
|
18
|
+
* SMTP_HOST=smtp.example.com # SMTP server hostname
|
|
19
|
+
* SMTP_PORT=587 # SMTP port (587 for TLS, 465 for SSL)
|
|
20
|
+
* SMTP_USER=your-username # SMTP authentication username
|
|
21
|
+
* SMTP_PASS=your-password # SMTP authentication password
|
|
22
|
+
* SMTP_SECURE=false # Use SSL (optional, auto-detected from port)
|
|
23
|
+
* SMTP_FROM=noreply@example.com # Default "from" email address
|
|
24
|
+
* SMTP_FROM_NAME=Your App # Default "from" display name
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* If SMTP_HOST is not set, emails are sent via Ethereal (test SMTP service).
|
|
28
|
+
*
|
|
29
|
+
* ## Usage
|
|
30
|
+
*
|
|
31
|
+
* ### Direct Usage (async/await)
|
|
32
|
+
* ```typescript
|
|
33
|
+
* import { sendEmail } from '@/infrastructure/email'
|
|
34
|
+
*
|
|
35
|
+
* await sendEmail({
|
|
36
|
+
* to: 'user@example.com',
|
|
37
|
+
* subject: 'Welcome',
|
|
38
|
+
* html: '<h1>Welcome!</h1>',
|
|
39
|
+
* text: 'Welcome!',
|
|
40
|
+
* })
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* ### Effect Service Usage
|
|
44
|
+
* ```typescript
|
|
45
|
+
* import { Email, EmailLive } from '@/infrastructure/email'
|
|
46
|
+
* import { Effect } from 'effect'
|
|
47
|
+
*
|
|
48
|
+
* const program = Effect.gen(function* () {
|
|
49
|
+
* const email = yield* Email
|
|
50
|
+
* yield* email.sendWithDefaultFrom({
|
|
51
|
+
* to: 'user@example.com',
|
|
52
|
+
* subject: 'Welcome',
|
|
53
|
+
* html: '<h1>Welcome!</h1>',
|
|
54
|
+
* })
|
|
55
|
+
* }).pipe(Effect.provide(EmailLive))
|
|
56
|
+
* ```
|
|
57
|
+
*
|
|
58
|
+
* ### Using Templates
|
|
59
|
+
* ```typescript
|
|
60
|
+
* import { sendEmail, passwordResetEmail } from '@/infrastructure/email'
|
|
61
|
+
*
|
|
62
|
+
* const template = passwordResetEmail({
|
|
63
|
+
* userName: 'John',
|
|
64
|
+
* resetUrl: 'https://example.com/reset?token=...',
|
|
65
|
+
* })
|
|
66
|
+
*
|
|
67
|
+
* await sendEmail({
|
|
68
|
+
* to: 'user@example.com',
|
|
69
|
+
* ...template,
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
*
|
|
73
|
+
* @module
|
|
74
|
+
*/
|
|
75
|
+
|
|
76
|
+
// Nodemailer configuration and transporter
|
|
77
|
+
export {
|
|
78
|
+
transporter,
|
|
79
|
+
getDefaultFrom,
|
|
80
|
+
getEmailConfig,
|
|
81
|
+
createTransporter,
|
|
82
|
+
verifyConnection,
|
|
83
|
+
type EmailConfig,
|
|
84
|
+
type SendMailOptions,
|
|
85
|
+
} from './nodemailer'
|
|
86
|
+
|
|
87
|
+
// Effect service layer
|
|
88
|
+
export {
|
|
89
|
+
Email,
|
|
90
|
+
EmailLive,
|
|
91
|
+
EmailError,
|
|
92
|
+
EmailConnectionError,
|
|
93
|
+
sendEmail,
|
|
94
|
+
sendEmailWithOptions,
|
|
95
|
+
type EmailService,
|
|
96
|
+
} from './email-service'
|
|
97
|
+
|
|
98
|
+
// Email configuration with Effect logging
|
|
99
|
+
export { getEmailConfigFromEffect } from './email-config'
|
|
100
|
+
|
|
101
|
+
// Email templates
|
|
102
|
+
export {
|
|
103
|
+
passwordResetEmail,
|
|
104
|
+
emailVerificationEmail,
|
|
105
|
+
type PasswordResetEmailData,
|
|
106
|
+
type EmailVerificationData,
|
|
107
|
+
} from './templates'
|
|
@@ -0,0 +1,125 @@
|
|
|
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 nodemailer from 'nodemailer'
|
|
9
|
+
import { getEmailConfigFromEffect } from './email-config'
|
|
10
|
+
import type Mail from 'nodemailer/lib/mailer'
|
|
11
|
+
import type SMTPTransport from 'nodemailer/lib/smtp-transport'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Email configuration from environment variables
|
|
15
|
+
*
|
|
16
|
+
* Required environment variables:
|
|
17
|
+
* - SMTP_HOST: SMTP server hostname (e.g., smtp.gmail.com)
|
|
18
|
+
* - SMTP_PORT: SMTP server port (e.g., 587 for TLS, 465 for SSL)
|
|
19
|
+
* - SMTP_USER: SMTP authentication username
|
|
20
|
+
* - SMTP_PASS: SMTP authentication password
|
|
21
|
+
*
|
|
22
|
+
* Optional environment variables:
|
|
23
|
+
* - SMTP_SECURE: Use SSL (true for port 465, false for other ports)
|
|
24
|
+
* - SMTP_FROM: Default "from" email address
|
|
25
|
+
* - SMTP_FROM_NAME: Default "from" display name
|
|
26
|
+
*/
|
|
27
|
+
export interface EmailConfig {
|
|
28
|
+
readonly host: string
|
|
29
|
+
readonly port: number
|
|
30
|
+
readonly secure: boolean
|
|
31
|
+
readonly auth: {
|
|
32
|
+
readonly user: string
|
|
33
|
+
readonly pass: string
|
|
34
|
+
}
|
|
35
|
+
readonly from: {
|
|
36
|
+
readonly email: string
|
|
37
|
+
readonly name: string
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Get email configuration from environment variables
|
|
43
|
+
*
|
|
44
|
+
* Uses Effect.Config under the hood for type-safe configuration with:
|
|
45
|
+
* - Automatic validation
|
|
46
|
+
* - Secret handling (passwords redacted in logs)
|
|
47
|
+
* - Composable defaults
|
|
48
|
+
*
|
|
49
|
+
* In production, SMTP_HOST is required. In development, falls back to
|
|
50
|
+
* localhost:1025 (Mailpit) for local email testing.
|
|
51
|
+
*
|
|
52
|
+
* Environment Variables:
|
|
53
|
+
* - SMTP_HOST: SMTP server hostname (required in production)
|
|
54
|
+
* - SMTP_PORT: SMTP server port (default: 587)
|
|
55
|
+
* - SMTP_SECURE: Use SSL/TLS (default: false for port 587, true for port 465)
|
|
56
|
+
* - SMTP_USER: SMTP authentication username
|
|
57
|
+
* - SMTP_PASS: SMTP authentication password
|
|
58
|
+
* - SMTP_FROM: Default "from" email address (default: noreply@sovrium.com)
|
|
59
|
+
* - SMTP_FROM_NAME: Default "from" display name (default: 'Sovrium')
|
|
60
|
+
*
|
|
61
|
+
* @see https://mailpit.axllent.org/ for local development email testing
|
|
62
|
+
* @see ./email-config.ts for Effect-based configuration (preferred for new code)
|
|
63
|
+
*/
|
|
64
|
+
export function getEmailConfig(): EmailConfig {
|
|
65
|
+
return getEmailConfigFromEffect()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Create a nodemailer transporter from configuration
|
|
70
|
+
*/
|
|
71
|
+
/* eslint-disable functional/prefer-immutable-types -- nodemailer transporter is inherently mutable */
|
|
72
|
+
export function createTransporter(
|
|
73
|
+
config: Readonly<EmailConfig>
|
|
74
|
+
): nodemailer.Transporter<SMTPTransport.SentMessageInfo> {
|
|
75
|
+
return nodemailer.createTransport({
|
|
76
|
+
host: config.host,
|
|
77
|
+
port: config.port,
|
|
78
|
+
secure: config.secure,
|
|
79
|
+
auth: config.auth,
|
|
80
|
+
})
|
|
81
|
+
}
|
|
82
|
+
/* eslint-enable functional/prefer-immutable-types */
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Pre-configured transporter using environment variables
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* ```typescript
|
|
89
|
+
* import { transporter, getDefaultFrom } from '@/infrastructure/email/nodemailer'
|
|
90
|
+
*
|
|
91
|
+
* await transporter.sendMail({
|
|
92
|
+
* from: getDefaultFrom(),
|
|
93
|
+
* to: 'user@example.com',
|
|
94
|
+
* subject: 'Hello',
|
|
95
|
+
* text: 'Hello World',
|
|
96
|
+
* })
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
const config = getEmailConfig()
|
|
100
|
+
export const transporter = createTransporter(config)
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get the default "from" address formatted for email headers
|
|
104
|
+
*/
|
|
105
|
+
export function getDefaultFrom(): string {
|
|
106
|
+
const { email, name } = config.from
|
|
107
|
+
return `"${name}" <${email}>`
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Send email options type (re-exported for convenience)
|
|
112
|
+
*/
|
|
113
|
+
export type SendMailOptions = Mail.Options
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Verify SMTP connection
|
|
117
|
+
*
|
|
118
|
+
* Useful for health checks and startup validation.
|
|
119
|
+
*
|
|
120
|
+
* @returns Promise that resolves if connection is valid
|
|
121
|
+
* @throws Error if connection fails
|
|
122
|
+
*/
|
|
123
|
+
export async function verifyConnection(): Promise<boolean> {
|
|
124
|
+
return transporter.verify()
|
|
125
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
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
|
+
* Email template data types for Better Auth integration
|
|
10
|
+
*/
|
|
11
|
+
export interface PasswordResetEmailData {
|
|
12
|
+
readonly userName?: string
|
|
13
|
+
readonly resetUrl: string
|
|
14
|
+
readonly expiresIn?: string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface EmailVerificationData {
|
|
18
|
+
readonly userName?: string
|
|
19
|
+
readonly verifyUrl: string
|
|
20
|
+
readonly expiresIn?: string
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Email CSS styles
|
|
25
|
+
*/
|
|
26
|
+
const EMAIL_STYLES = `
|
|
27
|
+
body {
|
|
28
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
29
|
+
line-height: 1.6;
|
|
30
|
+
color: #333;
|
|
31
|
+
max-width: 600px;
|
|
32
|
+
margin: 0 auto;
|
|
33
|
+
padding: 20px;
|
|
34
|
+
background-color: #f5f5f5;
|
|
35
|
+
}
|
|
36
|
+
.container {
|
|
37
|
+
background-color: #ffffff;
|
|
38
|
+
border-radius: 8px;
|
|
39
|
+
padding: 40px;
|
|
40
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
41
|
+
}
|
|
42
|
+
.header {
|
|
43
|
+
text-align: center;
|
|
44
|
+
margin-bottom: 30px;
|
|
45
|
+
}
|
|
46
|
+
.logo {
|
|
47
|
+
font-size: 28px;
|
|
48
|
+
font-weight: bold;
|
|
49
|
+
color: #1a1a1a;
|
|
50
|
+
}
|
|
51
|
+
.content {
|
|
52
|
+
margin-bottom: 30px;
|
|
53
|
+
}
|
|
54
|
+
.button {
|
|
55
|
+
display: inline-block;
|
|
56
|
+
background-color: #0066cc;
|
|
57
|
+
color: #ffffff !important;
|
|
58
|
+
text-decoration: none;
|
|
59
|
+
padding: 14px 28px;
|
|
60
|
+
border-radius: 6px;
|
|
61
|
+
font-weight: 600;
|
|
62
|
+
margin: 20px 0;
|
|
63
|
+
}
|
|
64
|
+
.button:hover {
|
|
65
|
+
background-color: #0052a3;
|
|
66
|
+
}
|
|
67
|
+
.footer {
|
|
68
|
+
text-align: center;
|
|
69
|
+
margin-top: 30px;
|
|
70
|
+
padding-top: 20px;
|
|
71
|
+
border-top: 1px solid #eee;
|
|
72
|
+
color: #666;
|
|
73
|
+
font-size: 12px;
|
|
74
|
+
}
|
|
75
|
+
.link-fallback {
|
|
76
|
+
word-break: break-all;
|
|
77
|
+
color: #666;
|
|
78
|
+
font-size: 12px;
|
|
79
|
+
margin-top: 15px;
|
|
80
|
+
}
|
|
81
|
+
.warning {
|
|
82
|
+
background-color: #fff3cd;
|
|
83
|
+
border: 1px solid #ffc107;
|
|
84
|
+
border-radius: 4px;
|
|
85
|
+
padding: 12px;
|
|
86
|
+
margin-top: 20px;
|
|
87
|
+
font-size: 13px;
|
|
88
|
+
color: #856404;
|
|
89
|
+
}
|
|
90
|
+
`
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Base email layout wrapper
|
|
94
|
+
*
|
|
95
|
+
* Provides consistent styling for all email templates.
|
|
96
|
+
*/
|
|
97
|
+
function emailLayout(content: string): string {
|
|
98
|
+
const year = new Date().getFullYear()
|
|
99
|
+
return `<!DOCTYPE html>
|
|
100
|
+
<html lang="en">
|
|
101
|
+
<head>
|
|
102
|
+
<meta charset="UTF-8">
|
|
103
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
104
|
+
<title>Sovrium</title>
|
|
105
|
+
<style>${EMAIL_STYLES}</style>
|
|
106
|
+
</head>
|
|
107
|
+
<body>
|
|
108
|
+
<div class="container">
|
|
109
|
+
<div class="header"><div class="logo">Sovrium</div></div>
|
|
110
|
+
${content}
|
|
111
|
+
<div class="footer">
|
|
112
|
+
<p>© ${year} ESSENTIAL SERVICES. All rights reserved.</p>
|
|
113
|
+
<p>This email was sent by Sovrium. If you didn't request this, please ignore this email.</p>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</body>
|
|
117
|
+
</html>`
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Password reset email template
|
|
122
|
+
*
|
|
123
|
+
* Used by Better Auth's sendResetPassword callback.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const { subject, html, text } = passwordResetEmail({
|
|
128
|
+
* userName: 'John',
|
|
129
|
+
* resetUrl: 'https://app.sovrium.com/reset-password?token=...',
|
|
130
|
+
* expiresIn: '1 hour',
|
|
131
|
+
* })
|
|
132
|
+
* ```
|
|
133
|
+
*/
|
|
134
|
+
export function passwordResetEmail(data: PasswordResetEmailData): {
|
|
135
|
+
readonly subject: string
|
|
136
|
+
readonly html: string
|
|
137
|
+
readonly text: string
|
|
138
|
+
} {
|
|
139
|
+
const greeting = data.userName ? `Hi ${data.userName},` : 'Hi,'
|
|
140
|
+
const expiry = data.expiresIn ?? '1 hour'
|
|
141
|
+
|
|
142
|
+
const content = `
|
|
143
|
+
<div class="content">
|
|
144
|
+
<p>${greeting}</p>
|
|
145
|
+
<p>We received a request to reset your password for your Sovrium account.</p>
|
|
146
|
+
<p>Click the button below to reset your password:</p>
|
|
147
|
+
<p style="text-align: center;">
|
|
148
|
+
<a href="${data.resetUrl}" class="button">Reset Password</a>
|
|
149
|
+
</p>
|
|
150
|
+
<p class="link-fallback">
|
|
151
|
+
If the button doesn't work, copy and paste this link into your browser:<br>
|
|
152
|
+
${data.resetUrl}
|
|
153
|
+
</p>
|
|
154
|
+
<div class="warning">
|
|
155
|
+
This link will expire in ${expiry}. If you didn't request a password reset, you can safely ignore this email.
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
`
|
|
159
|
+
|
|
160
|
+
const text = `
|
|
161
|
+
${greeting}
|
|
162
|
+
|
|
163
|
+
We received a request to reset your password for your Sovrium account.
|
|
164
|
+
|
|
165
|
+
Reset your password by visiting this link:
|
|
166
|
+
${data.resetUrl}
|
|
167
|
+
|
|
168
|
+
This link will expire in ${expiry}.
|
|
169
|
+
|
|
170
|
+
If you didn't request a password reset, you can safely ignore this email.
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
© ${new Date().getFullYear()} ESSENTIAL SERVICES. All rights reserved.
|
|
174
|
+
`.trim()
|
|
175
|
+
|
|
176
|
+
return {
|
|
177
|
+
subject: 'Reset your Sovrium password',
|
|
178
|
+
html: emailLayout(content),
|
|
179
|
+
text,
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Email verification template
|
|
185
|
+
*
|
|
186
|
+
* Used by Better Auth's sendVerificationEmail callback.
|
|
187
|
+
*
|
|
188
|
+
* @example
|
|
189
|
+
* ```typescript
|
|
190
|
+
* const { subject, html, text } = emailVerificationEmail({
|
|
191
|
+
* userName: 'John',
|
|
192
|
+
* verifyUrl: 'https://app.sovrium.com/verify-email?token=...',
|
|
193
|
+
* expiresIn: '24 hours',
|
|
194
|
+
* })
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
197
|
+
export function emailVerificationEmail(data: EmailVerificationData): {
|
|
198
|
+
readonly subject: string
|
|
199
|
+
readonly html: string
|
|
200
|
+
readonly text: string
|
|
201
|
+
} {
|
|
202
|
+
const greeting = data.userName ? `Hi ${data.userName},` : 'Hi,'
|
|
203
|
+
const expiry = data.expiresIn ?? '24 hours'
|
|
204
|
+
|
|
205
|
+
const content = `
|
|
206
|
+
<div class="content">
|
|
207
|
+
<p>${greeting}</p>
|
|
208
|
+
<p>Welcome to Sovrium! Please verify your email address to complete your registration.</p>
|
|
209
|
+
<p>Click the button below to verify your email:</p>
|
|
210
|
+
<p style="text-align: center;">
|
|
211
|
+
<a href="${data.verifyUrl}" class="button">Verify Email</a>
|
|
212
|
+
</p>
|
|
213
|
+
<p class="link-fallback">
|
|
214
|
+
If the button doesn't work, copy and paste this link into your browser:<br>
|
|
215
|
+
${data.verifyUrl}
|
|
216
|
+
</p>
|
|
217
|
+
<div class="warning">
|
|
218
|
+
This link will expire in ${expiry}. If you didn't create a Sovrium account, you can safely ignore this email.
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
`
|
|
222
|
+
|
|
223
|
+
const text = `
|
|
224
|
+
${greeting}
|
|
225
|
+
|
|
226
|
+
Welcome to Sovrium! Please verify your email address to complete your registration.
|
|
227
|
+
|
|
228
|
+
Verify your email by visiting this link:
|
|
229
|
+
${data.verifyUrl}
|
|
230
|
+
|
|
231
|
+
This link will expire in ${expiry}.
|
|
232
|
+
|
|
233
|
+
If you didn't create a Sovrium account, you can safely ignore this email.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
© ${new Date().getFullYear()} ESSENTIAL SERVICES. All rights reserved.
|
|
237
|
+
`.trim()
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
subject: 'Verify your Sovrium email address',
|
|
241
|
+
html: emailLayout(content),
|
|
242
|
+
text,
|
|
243
|
+
}
|
|
244
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
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 { Data } from 'effect'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Error when user fields are used without auth configuration
|
|
12
|
+
*
|
|
13
|
+
* User fields (user, created-by, updated-by) require Better Auth's users table.
|
|
14
|
+
* This error is thrown when tables with these field types are defined but
|
|
15
|
+
* no auth configuration is present in the app schema.
|
|
16
|
+
*/
|
|
17
|
+
export class AuthConfigRequiredForUserFields extends Data.TaggedError(
|
|
18
|
+
'AuthConfigRequiredForUserFields'
|
|
19
|
+
)<{
|
|
20
|
+
readonly message: string
|
|
21
|
+
}> {}
|
|
@@ -0,0 +1,16 @@
|
|
|
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 { createTaggedError } from '@/domain/errors/create-tagged-error'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Auth Error
|
|
12
|
+
*
|
|
13
|
+
* Tagged error for authentication failures.
|
|
14
|
+
*/
|
|
15
|
+
export const AuthError = createTaggedError('AuthError')
|
|
16
|
+
export type AuthError = InstanceType<typeof AuthError>
|
|
@@ -0,0 +1,14 @@
|
|
|
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 { createTaggedError } from '@/domain/errors/create-tagged-error'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Error class for CSS compilation failures
|
|
12
|
+
*/
|
|
13
|
+
export const CSSCompilationError = createTaggedError('CSSCompilationError')
|
|
14
|
+
export type CSSCompilationError = InstanceType<typeof CSSCompilationError>
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
* Infrastructure Error Classes Module
|
|
10
|
+
*
|
|
11
|
+
* Centralized error definitions for infrastructure layer failures.
|
|
12
|
+
* All errors use tagged union pattern (_tag property) for type-safe error handling.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import { ServerCreationError } from '@/infrastructure/errors'
|
|
17
|
+
*
|
|
18
|
+
* throw new ServerCreationError(error)
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
export { AuthConfigRequiredForUserFields } from './auth-config-required-error'
|
|
23
|
+
export { AuthError } from './auth-error'
|
|
24
|
+
export { CSSCompilationError } from './css-compilation-error'
|
|
25
|
+
export { SchemaInitializationError } from './schema-initialization-error'
|
|
26
|
+
export { ServerCreationError } from './server-creation-error'
|
|
@@ -0,0 +1,19 @@
|
|
|
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 { Data } from 'effect'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Error during schema initialization
|
|
12
|
+
*
|
|
13
|
+
* This error is thrown when database schema initialization fails,
|
|
14
|
+
* indicating that table creation or migration failed.
|
|
15
|
+
*/
|
|
16
|
+
export class SchemaInitializationError extends Data.TaggedError('SchemaInitializationError')<{
|
|
17
|
+
readonly message: string
|
|
18
|
+
readonly cause?: unknown
|
|
19
|
+
}> {}
|
|
@@ -0,0 +1,14 @@
|
|
|
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 { createTaggedError } from '@/domain/errors/create-tagged-error'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Error class for server creation failures
|
|
12
|
+
*/
|
|
13
|
+
export const ServerCreationError = createTaggedError('ServerCreationError')
|
|
14
|
+
export type ServerCreationError = InstanceType<typeof ServerCreationError>
|