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,135 @@
|
|
|
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
|
+
* Feature configuration with enabled flag and custom config
|
|
12
|
+
*
|
|
13
|
+
* Complex feature definition with:
|
|
14
|
+
* - enabled: Boolean toggle for the feature
|
|
15
|
+
* - config: Flexible configuration object (additionalProperties: true)
|
|
16
|
+
*
|
|
17
|
+
* Use this when a feature requires additional configuration beyond a simple boolean.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const animations = {
|
|
22
|
+
* enabled: true,
|
|
23
|
+
* config: {
|
|
24
|
+
* duration: 300,
|
|
25
|
+
* easing: 'ease-in-out'
|
|
26
|
+
* }
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export const FeatureConfigSchema = Schema.Struct({
|
|
31
|
+
enabled: Schema.optional(
|
|
32
|
+
Schema.Boolean.annotations({
|
|
33
|
+
description: 'Whether the feature is enabled',
|
|
34
|
+
})
|
|
35
|
+
),
|
|
36
|
+
config: Schema.optional(
|
|
37
|
+
Schema.Record({
|
|
38
|
+
key: Schema.String,
|
|
39
|
+
value: Schema.Unknown,
|
|
40
|
+
}).annotations({
|
|
41
|
+
description: 'Feature-specific configuration data',
|
|
42
|
+
})
|
|
43
|
+
),
|
|
44
|
+
}).annotations({
|
|
45
|
+
description: 'Feature configuration with enabled flag and custom config',
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Feature value - either a boolean flag or a configuration object
|
|
50
|
+
*
|
|
51
|
+
* Supports two patterns:
|
|
52
|
+
* 1. Simple boolean: true/false for basic feature toggles
|
|
53
|
+
* 2. Configuration object: { enabled, config } for features requiring settings
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* const features = {
|
|
58
|
+
* darkMode: true, // Simple boolean
|
|
59
|
+
* liveChat: { // Complex configuration
|
|
60
|
+
* enabled: true,
|
|
61
|
+
* config: {
|
|
62
|
+
* provider: 'intercom',
|
|
63
|
+
* appId: 'abc123'
|
|
64
|
+
* }
|
|
65
|
+
* }
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export const FeatureValueSchema = Schema.Union(
|
|
70
|
+
Schema.Boolean.annotations({
|
|
71
|
+
description: 'Simple feature flag',
|
|
72
|
+
}),
|
|
73
|
+
FeatureConfigSchema
|
|
74
|
+
).annotations({
|
|
75
|
+
description: 'Feature value - either a boolean flag or a configuration object',
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Client-side feature toggles
|
|
80
|
+
*
|
|
81
|
+
* Record of feature flags controlling client-side behavior.
|
|
82
|
+
* Each feature can be either a simple boolean or a complex configuration object.
|
|
83
|
+
*
|
|
84
|
+
* Common use cases:
|
|
85
|
+
* - darkMode: Enable dark theme
|
|
86
|
+
* - animations: Control UI animations
|
|
87
|
+
* - analytics: Toggle tracking
|
|
88
|
+
* - cookieConsent: GDPR compliance
|
|
89
|
+
* - liveChat: Customer support widget
|
|
90
|
+
*
|
|
91
|
+
* Features are:
|
|
92
|
+
* - Accessible in client JavaScript as window.FEATURES
|
|
93
|
+
* - Stored in data-* attributes for CSS/JS access
|
|
94
|
+
* - Persisted in localStorage for user preferences
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```typescript
|
|
98
|
+
* const features = {
|
|
99
|
+
* darkMode: true,
|
|
100
|
+
* animations: {
|
|
101
|
+
* enabled: true,
|
|
102
|
+
* config: {
|
|
103
|
+
* duration: 300,
|
|
104
|
+
* easing: 'ease-in-out'
|
|
105
|
+
* }
|
|
106
|
+
* },
|
|
107
|
+
* cookieConsent: false,
|
|
108
|
+
* liveChat: {
|
|
109
|
+
* enabled: true,
|
|
110
|
+
* config: {
|
|
111
|
+
* provider: 'intercom',
|
|
112
|
+
* appId: 'abc123'
|
|
113
|
+
* }
|
|
114
|
+
* }
|
|
115
|
+
* }
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @see specs/app/pages/scripts/features/features.schema.json
|
|
119
|
+
*/
|
|
120
|
+
export const FeaturesSchema = Schema.Record({
|
|
121
|
+
key: Schema.String.pipe(
|
|
122
|
+
Schema.pattern(/^[a-zA-Z][a-zA-Z0-9]*$/, {
|
|
123
|
+
message: () =>
|
|
124
|
+
'Feature name must be camelCase starting with a letter (e.g., darkMode, liveChat, cookieConsent)',
|
|
125
|
+
})
|
|
126
|
+
),
|
|
127
|
+
value: FeatureValueSchema,
|
|
128
|
+
}).annotations({
|
|
129
|
+
title: 'Feature Flags',
|
|
130
|
+
description: 'Client-side feature toggles',
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
export type FeatureConfig = Schema.Schema.Type<typeof FeatureConfigSchema>
|
|
134
|
+
export type FeatureValue = Schema.Schema.Type<typeof FeatureValueSchema>
|
|
135
|
+
export type Features = Schema.Schema.Type<typeof FeaturesSchema>
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Schema } from 'effect'
|
|
9
|
+
import { ScriptPositionSchema } from './external-scripts'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Inline JavaScript code snippet
|
|
13
|
+
*
|
|
14
|
+
* Defines an inline script tag with JavaScript code.
|
|
15
|
+
*
|
|
16
|
+
* Required properties:
|
|
17
|
+
* - code: JavaScript code to execute (raw JS, no <script> tags)
|
|
18
|
+
*
|
|
19
|
+
* Optional properties:
|
|
20
|
+
* - position: Where to insert script (head, body-start, body-end)
|
|
21
|
+
* - async: Wrap code in async IIFE (async function)
|
|
22
|
+
*
|
|
23
|
+
* Use cases:
|
|
24
|
+
* - Global config: window.APP_CONFIG initialization
|
|
25
|
+
* - Theme restoration: Apply saved theme before paint (avoid FOUC)
|
|
26
|
+
* - Analytics: Tracking code initialization
|
|
27
|
+
* - Feature detection: Check browser capabilities
|
|
28
|
+
*
|
|
29
|
+
* Performance considerations:
|
|
30
|
+
* - Pros: No network request, executes immediately
|
|
31
|
+
* - Cons: Not cached, repeated on every page load
|
|
32
|
+
* - Recommendation: Keep inline scripts < 1KB, use external for larger code
|
|
33
|
+
*
|
|
34
|
+
* Security (CSP):
|
|
35
|
+
* - Inline scripts require 'unsafe-inline' or nonce/hash in CSP header
|
|
36
|
+
* - Use nonce: <script nonce="random123">...</script>
|
|
37
|
+
* - Or hash: CSP header script-src 'sha256-{hash}'
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* const configScript = {
|
|
42
|
+
* code: "window.config = { apiUrl: 'https://api.example.com' };",
|
|
43
|
+
* position: 'head'
|
|
44
|
+
* }
|
|
45
|
+
*
|
|
46
|
+
* const analyticsScript = {
|
|
47
|
+
* code: "console.log('Page loaded');",
|
|
48
|
+
* position: 'body-end'
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @see specs/app/pages/scripts/inline-scripts/inline-scripts.schema.json
|
|
53
|
+
*/
|
|
54
|
+
export const InlineScriptSchema = Schema.Struct({
|
|
55
|
+
code: Schema.String.annotations({
|
|
56
|
+
description: 'JavaScript code to execute',
|
|
57
|
+
}),
|
|
58
|
+
position: Schema.optional(ScriptPositionSchema),
|
|
59
|
+
async: Schema.optional(
|
|
60
|
+
Schema.Boolean.annotations({
|
|
61
|
+
description: 'Wrap in async IIFE',
|
|
62
|
+
default: false,
|
|
63
|
+
})
|
|
64
|
+
),
|
|
65
|
+
}).annotations({
|
|
66
|
+
description: 'Inline JavaScript code snippet',
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Inline JavaScript code snippets
|
|
71
|
+
*
|
|
72
|
+
* Array of inline scripts injected into the HTML document.
|
|
73
|
+
* Scripts execute in order (synchronous by default).
|
|
74
|
+
*
|
|
75
|
+
* Common use cases:
|
|
76
|
+
* - Configuration: window.APP_CONFIG = {...}
|
|
77
|
+
* - Theme restoration: Apply dark mode before paint
|
|
78
|
+
* - Analytics initialization: gtag(), Plausible tracking
|
|
79
|
+
* - Event listeners: DOMContentLoaded handlers
|
|
80
|
+
*
|
|
81
|
+
* Best practices:
|
|
82
|
+
* - Keep scripts small (< 1KB) - larger code should be external
|
|
83
|
+
* - Use for critical initialization only (theme, config)
|
|
84
|
+
* - Position head scripts for pre-render logic
|
|
85
|
+
* - Position body-end scripts for post-render logic
|
|
86
|
+
*
|
|
87
|
+
* Security:
|
|
88
|
+
* - Inline scripts require CSP nonce or hash
|
|
89
|
+
* - Escape user input to prevent XSS
|
|
90
|
+
* - Never inject untrusted code
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* const inlineScripts = [
|
|
95
|
+
* {
|
|
96
|
+
* code: "window.config = { apiUrl: 'https://api.example.com' };",
|
|
97
|
+
* position: 'head'
|
|
98
|
+
* },
|
|
99
|
+
* {
|
|
100
|
+
* code: "console.log('Page loaded');",
|
|
101
|
+
* position: 'body-end'
|
|
102
|
+
* }
|
|
103
|
+
* ]
|
|
104
|
+
* ```
|
|
105
|
+
*
|
|
106
|
+
* @see specs/app/pages/scripts/inline-scripts/inline-scripts.schema.json
|
|
107
|
+
*/
|
|
108
|
+
export const InlineScriptsSchema = Schema.Array(InlineScriptSchema).annotations({
|
|
109
|
+
title: 'Inline Scripts',
|
|
110
|
+
description: 'Inline JavaScript code snippets',
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
export type InlineScript = Schema.Schema.Type<typeof InlineScriptSchema>
|
|
114
|
+
export type InlineScripts = Schema.Schema.Type<typeof InlineScriptsSchema>
|
|
@@ -0,0 +1,102 @@
|
|
|
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 { ExternalScriptsSchema } from './external-scripts'
|
|
10
|
+
import { FeaturesSchema } from './features'
|
|
11
|
+
import { InlineScriptsSchema } from './inline-scripts'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Client scripts configuration
|
|
15
|
+
*
|
|
16
|
+
* Orchestrates all client-side scripts, features, and configuration.
|
|
17
|
+
*
|
|
18
|
+
* Properties (all optional):
|
|
19
|
+
* - features: Client-side feature toggles (boolean flags or config objects)
|
|
20
|
+
* - externalScripts: External JavaScript dependencies from CDN
|
|
21
|
+
* - inlineScripts: Inline JavaScript code snippets
|
|
22
|
+
* - config: Client-side configuration data (flexible schema)
|
|
23
|
+
*
|
|
24
|
+
* Use cases:
|
|
25
|
+
* - SPA initialization: Load framework (Alpine.js, htmx) + inline config
|
|
26
|
+
* - Analytics: External script (Google Analytics) + inline tracking code
|
|
27
|
+
* - Feature flags: Toggle features based on environment or user preferences
|
|
28
|
+
* - Third-party services: Auth0, Sentry, Intercom configuration
|
|
29
|
+
*
|
|
30
|
+
* Loading order:
|
|
31
|
+
* 1. External scripts (async/defer respected)
|
|
32
|
+
* 2. Inline scripts (execute after external scripts load)
|
|
33
|
+
* 3. Config available as window.APP_CONFIG
|
|
34
|
+
*
|
|
35
|
+
* Performance:
|
|
36
|
+
* - Load scripts only where needed (per-page customization)
|
|
37
|
+
* - Use async for non-dependent scripts (analytics, ads)
|
|
38
|
+
* - Use defer for frameworks (preserve order, non-blocking)
|
|
39
|
+
* - Keep inline scripts < 1KB (larger code should be external)
|
|
40
|
+
*
|
|
41
|
+
* Security:
|
|
42
|
+
* - Config is public (sent to client), NO SECRETS
|
|
43
|
+
* - Never include API keys, passwords, private tokens in config
|
|
44
|
+
* - Use HTTPS for external scripts (no http://)
|
|
45
|
+
* - Add integrity hashes for CDN scripts
|
|
46
|
+
* - Inline scripts require CSP nonce or hash
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```typescript
|
|
50
|
+
* const scripts = {
|
|
51
|
+
* features: {
|
|
52
|
+
* darkMode: true,
|
|
53
|
+
* animations: {
|
|
54
|
+
* enabled: true,
|
|
55
|
+
* config: {
|
|
56
|
+
* duration: 300,
|
|
57
|
+
* easing: 'ease-in-out'
|
|
58
|
+
* }
|
|
59
|
+
* },
|
|
60
|
+
* analytics: false
|
|
61
|
+
* },
|
|
62
|
+
* externalScripts: [
|
|
63
|
+
* {
|
|
64
|
+
* src: 'https://cdn.example.com/script.js',
|
|
65
|
+
* async: true
|
|
66
|
+
* }
|
|
67
|
+
* ],
|
|
68
|
+
* inlineScripts: [
|
|
69
|
+
* {
|
|
70
|
+
* code: "console.log('Page loaded');",
|
|
71
|
+
* position: 'body-end'
|
|
72
|
+
* }
|
|
73
|
+
* ],
|
|
74
|
+
* config: {
|
|
75
|
+
* apiUrl: 'https://api.example.com',
|
|
76
|
+
* environment: 'production'
|
|
77
|
+
* }
|
|
78
|
+
* }
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* @see specs/app/pages/scripts/scripts.schema.json
|
|
82
|
+
*/
|
|
83
|
+
export const ScriptsSchema = Schema.Struct({
|
|
84
|
+
features: Schema.optional(FeaturesSchema),
|
|
85
|
+
externalScripts: Schema.optional(ExternalScriptsSchema),
|
|
86
|
+
// Support 'external' as an alias for 'externalScripts' (test shorthand)
|
|
87
|
+
external: Schema.optional(ExternalScriptsSchema),
|
|
88
|
+
inlineScripts: Schema.optional(InlineScriptsSchema),
|
|
89
|
+
config: Schema.optional(
|
|
90
|
+
Schema.Record({
|
|
91
|
+
key: Schema.String,
|
|
92
|
+
value: Schema.Unknown,
|
|
93
|
+
}).annotations({
|
|
94
|
+
description: 'Client-side configuration data',
|
|
95
|
+
})
|
|
96
|
+
),
|
|
97
|
+
}).annotations({
|
|
98
|
+
title: 'Client Scripts Configuration',
|
|
99
|
+
description: 'Client-side scripts, features, and external dependencies',
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
export type Scripts = Schema.Schema.Type<typeof ScriptsSchema>
|
|
@@ -0,0 +1,298 @@
|
|
|
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 { ComponentPropsSchema } from '../component/common/component-props'
|
|
10
|
+
import { ComponentReferenceSchema } from '../component/common/component-reference'
|
|
11
|
+
import { InteractionsSchema } from './common/interactions/interactions'
|
|
12
|
+
import { ResponsiveSchema } from './common/responsive'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Component type enum for page sections
|
|
16
|
+
*
|
|
17
|
+
* Comprehensive set of component types for building pages:
|
|
18
|
+
* - Layout: section, container, flex, grid, div, modal, sidebar, hero, navigation, header, footer, main, article, aside, nav
|
|
19
|
+
* - Content: text, single-line-text, heading, paragraph, h1, h2, h3, h4, h5, h6, icon, image, avatar, thumbnail, hero-image, customHTML, span, p, code, pre
|
|
20
|
+
* - Interactive: button, link, a, accordion, dropdown
|
|
21
|
+
* - Grouping: card, badge, timeline, list-item, speech-bubble, card-with-header, card-header, card-body, card-footer
|
|
22
|
+
* - Media: video, audio, iframe
|
|
23
|
+
* - Forms: form, input
|
|
24
|
+
* - Feedback: toast, spinner, alert
|
|
25
|
+
* - UI Elements: fab (floating action button), list
|
|
26
|
+
*/
|
|
27
|
+
export const ComponentTypeSchema = Schema.Literal(
|
|
28
|
+
'section',
|
|
29
|
+
'container',
|
|
30
|
+
'flex',
|
|
31
|
+
'grid',
|
|
32
|
+
'card',
|
|
33
|
+
'card-with-header',
|
|
34
|
+
'card-header',
|
|
35
|
+
'card-body',
|
|
36
|
+
'card-footer',
|
|
37
|
+
'text',
|
|
38
|
+
'single-line-text',
|
|
39
|
+
'heading',
|
|
40
|
+
'paragraph',
|
|
41
|
+
'h1',
|
|
42
|
+
'h2',
|
|
43
|
+
'h3',
|
|
44
|
+
'h4',
|
|
45
|
+
'h5',
|
|
46
|
+
'h6',
|
|
47
|
+
'icon',
|
|
48
|
+
'image',
|
|
49
|
+
'img',
|
|
50
|
+
'avatar',
|
|
51
|
+
'thumbnail',
|
|
52
|
+
'hero-image',
|
|
53
|
+
'button',
|
|
54
|
+
'link',
|
|
55
|
+
'a',
|
|
56
|
+
'timeline',
|
|
57
|
+
'accordion',
|
|
58
|
+
'badge',
|
|
59
|
+
'speech-bubble',
|
|
60
|
+
'customHTML',
|
|
61
|
+
'video',
|
|
62
|
+
'audio',
|
|
63
|
+
'iframe',
|
|
64
|
+
'form',
|
|
65
|
+
'input',
|
|
66
|
+
'div',
|
|
67
|
+
'span',
|
|
68
|
+
'modal',
|
|
69
|
+
'sidebar',
|
|
70
|
+
'toast',
|
|
71
|
+
'hero',
|
|
72
|
+
'hero-section',
|
|
73
|
+
'fab',
|
|
74
|
+
'spinner',
|
|
75
|
+
'list',
|
|
76
|
+
'list-item',
|
|
77
|
+
'dropdown',
|
|
78
|
+
'navigation',
|
|
79
|
+
'alert',
|
|
80
|
+
'p',
|
|
81
|
+
'code',
|
|
82
|
+
'pre',
|
|
83
|
+
'header',
|
|
84
|
+
'footer',
|
|
85
|
+
'main',
|
|
86
|
+
'article',
|
|
87
|
+
'aside',
|
|
88
|
+
'nav',
|
|
89
|
+
'responsive-grid'
|
|
90
|
+
).annotations({
|
|
91
|
+
description: 'Component type for page building',
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Direct component definition for page sections
|
|
96
|
+
*
|
|
97
|
+
* A component can be either inline (direct definition) or referenced (component template).
|
|
98
|
+
* Direct components allow full customization without creating a reusable component template.
|
|
99
|
+
*
|
|
100
|
+
* Required properties:
|
|
101
|
+
* - type: Component type (17 options)
|
|
102
|
+
*
|
|
103
|
+
* Optional properties:
|
|
104
|
+
* - props: Component properties (className, id, style, etc.)
|
|
105
|
+
* - children: Nested child components (recursive, unlimited depth)
|
|
106
|
+
* - content: Text content (for text components)
|
|
107
|
+
* - interactions: Interactive behaviors (hover, click, scroll, entrance)
|
|
108
|
+
* - responsive: Breakpoint-specific overrides for responsive design
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const component = {
|
|
113
|
+
* type: 'section',
|
|
114
|
+
* props: {
|
|
115
|
+
* id: 'hero',
|
|
116
|
+
* className: 'min-h-screen bg-gradient'
|
|
117
|
+
* },
|
|
118
|
+
* children: [
|
|
119
|
+
* {
|
|
120
|
+
* type: 'text',
|
|
121
|
+
* props: { level: 'h1' },
|
|
122
|
+
* content: 'Welcome'
|
|
123
|
+
* }
|
|
124
|
+
* ],
|
|
125
|
+
* interactions: {
|
|
126
|
+
* entrance: { animation: 'fadeIn' }
|
|
127
|
+
* },
|
|
128
|
+
* responsive: {
|
|
129
|
+
* md: {
|
|
130
|
+
* props: { className: 'min-h-screen bg-gradient-2xl' }
|
|
131
|
+
* }
|
|
132
|
+
* }
|
|
133
|
+
* }
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* @see specs/app/pages/sections/sections.schema.json
|
|
137
|
+
*/
|
|
138
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Recursive schema with suspended types requires any for circular reference resolution
|
|
139
|
+
export const ComponentSchema: Schema.Schema<any, any, never> = Schema.Struct({
|
|
140
|
+
type: ComponentTypeSchema,
|
|
141
|
+
props: Schema.optional(ComponentPropsSchema),
|
|
142
|
+
children: Schema.optional(
|
|
143
|
+
Schema.Array(
|
|
144
|
+
Schema.Union(
|
|
145
|
+
Schema.suspend(() => SectionItemSchema).pipe(
|
|
146
|
+
Schema.annotations({
|
|
147
|
+
identifier: 'SectionItem',
|
|
148
|
+
})
|
|
149
|
+
),
|
|
150
|
+
Schema.String
|
|
151
|
+
)
|
|
152
|
+
).pipe(
|
|
153
|
+
Schema.annotations({
|
|
154
|
+
identifier: 'Children',
|
|
155
|
+
description: 'Array of child components or text strings',
|
|
156
|
+
})
|
|
157
|
+
)
|
|
158
|
+
),
|
|
159
|
+
content: Schema.optional(
|
|
160
|
+
Schema.Union(
|
|
161
|
+
Schema.String,
|
|
162
|
+
Schema.Record({ key: Schema.String, value: Schema.Unknown })
|
|
163
|
+
).annotations({
|
|
164
|
+
description:
|
|
165
|
+
'Text content for text components, or structured content object (e.g., { button: { text, animation } })',
|
|
166
|
+
})
|
|
167
|
+
),
|
|
168
|
+
interactions: Schema.optional(InteractionsSchema),
|
|
169
|
+
responsive: Schema.optional(ResponsiveSchema),
|
|
170
|
+
i18n: Schema.optional(
|
|
171
|
+
Schema.Record({
|
|
172
|
+
key: Schema.String.pipe(
|
|
173
|
+
Schema.pattern(/^[a-z]{2}(-[A-Z]{2})?$/, {
|
|
174
|
+
message: () => 'Language code must be ISO 639-1 format (e.g., en-US, fr-FR)',
|
|
175
|
+
})
|
|
176
|
+
),
|
|
177
|
+
value: Schema.Struct({
|
|
178
|
+
content: Schema.optional(
|
|
179
|
+
Schema.String.annotations({
|
|
180
|
+
description: 'Translated content text',
|
|
181
|
+
})
|
|
182
|
+
),
|
|
183
|
+
props: Schema.optional(ComponentPropsSchema),
|
|
184
|
+
}),
|
|
185
|
+
}).annotations({
|
|
186
|
+
description: 'Localized translations per language for this component',
|
|
187
|
+
})
|
|
188
|
+
),
|
|
189
|
+
}).annotations({
|
|
190
|
+
description: 'Direct component definition',
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Section item - either a direct component or a component reference
|
|
195
|
+
*
|
|
196
|
+
* Sections support three patterns:
|
|
197
|
+
* 1. Direct component: Inline definition with type, props, children, etc.
|
|
198
|
+
* 2. Simple component reference: Reference by name with { component: 'name' }
|
|
199
|
+
* 3. Component reference with vars: Reference with variable substitution { $ref: 'name', vars: {} }
|
|
200
|
+
*
|
|
201
|
+
* This hybrid approach enables:
|
|
202
|
+
* - Quick prototyping with inline components
|
|
203
|
+
* - Reusability through component references
|
|
204
|
+
* - Flexibility to mix all patterns
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* ```typescript
|
|
208
|
+
* const sections = [
|
|
209
|
+
* // Direct component
|
|
210
|
+
* {
|
|
211
|
+
* type: 'section',
|
|
212
|
+
* props: { id: 'hero' },
|
|
213
|
+
* children: [
|
|
214
|
+
* { type: 'text', content: 'Welcome' }
|
|
215
|
+
* ]
|
|
216
|
+
* },
|
|
217
|
+
* // Simple component reference
|
|
218
|
+
* {
|
|
219
|
+
* component: 'shared-component'
|
|
220
|
+
* },
|
|
221
|
+
* // Component reference with variables
|
|
222
|
+
* {
|
|
223
|
+
* $ref: 'section-header',
|
|
224
|
+
* vars: {
|
|
225
|
+
* title: 'Our Features',
|
|
226
|
+
* subtitle: 'Everything you need'
|
|
227
|
+
* }
|
|
228
|
+
* }
|
|
229
|
+
* ]
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export const SectionItemSchema = Schema.Union(
|
|
233
|
+
ComponentSchema,
|
|
234
|
+
ComponentReferenceSchema
|
|
235
|
+
).annotations({
|
|
236
|
+
description:
|
|
237
|
+
'A page section that can be either a component or component reference (with optional variables)',
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Array of page content sections
|
|
242
|
+
*
|
|
243
|
+
* The main content structure for pages, consisting of stacked sections.
|
|
244
|
+
* Each section can be nested arbitrarily deep through the children array.
|
|
245
|
+
*
|
|
246
|
+
* Sections enable:
|
|
247
|
+
* - Component composition (nest components to build layouts)
|
|
248
|
+
* - Reusability (reference components with $ref)
|
|
249
|
+
* - Responsive design (override props per breakpoint)
|
|
250
|
+
* - Interactivity (add hover, click, scroll, entrance behaviors)
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```typescript
|
|
254
|
+
* const sections = [
|
|
255
|
+
* {
|
|
256
|
+
* type: 'section',
|
|
257
|
+
* props: {
|
|
258
|
+
* id: 'hero',
|
|
259
|
+
* className: 'min-h-screen bg-gradient'
|
|
260
|
+
* },
|
|
261
|
+
* children: [
|
|
262
|
+
* {
|
|
263
|
+
* type: 'container',
|
|
264
|
+
* props: { maxWidth: 'max-w-7xl' },
|
|
265
|
+
* children: [
|
|
266
|
+
* {
|
|
267
|
+
* type: 'text',
|
|
268
|
+
* props: {
|
|
269
|
+
* level: 'h1',
|
|
270
|
+
* className: 'text-6xl font-bold'
|
|
271
|
+
* },
|
|
272
|
+
* content: 'Welcome to Our Platform'
|
|
273
|
+
* }
|
|
274
|
+
* ]
|
|
275
|
+
* }
|
|
276
|
+
* ]
|
|
277
|
+
* },
|
|
278
|
+
* {
|
|
279
|
+
* $ref: 'section-header',
|
|
280
|
+
* vars: {
|
|
281
|
+
* title: 'Our Features',
|
|
282
|
+
* subtitle: 'Everything you need to succeed'
|
|
283
|
+
* }
|
|
284
|
+
* }
|
|
285
|
+
* ]
|
|
286
|
+
* ```
|
|
287
|
+
*
|
|
288
|
+
* @see specs/app/pages/sections/sections.schema.json
|
|
289
|
+
*/
|
|
290
|
+
export const SectionsSchema = Schema.Array(SectionItemSchema).annotations({
|
|
291
|
+
title: 'Page Sections',
|
|
292
|
+
description: 'Array of page content sections',
|
|
293
|
+
})
|
|
294
|
+
|
|
295
|
+
export type ComponentType = Schema.Schema.Type<typeof ComponentTypeSchema>
|
|
296
|
+
export type Component = Schema.Schema.Type<typeof ComponentSchema>
|
|
297
|
+
export type SectionItem = Schema.Schema.Type<typeof SectionItemSchema>
|
|
298
|
+
export type Sections = Schema.Schema.Type<typeof SectionsSchema>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { Schema } from 'effect'
|
|
9
|
+
import { PageSchema } from './page'
|
|
10
|
+
import type { Page, PageEncoded } from './page'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Pages Schema
|
|
14
|
+
*
|
|
15
|
+
* Array of page configurations for the application. At least one page is required.
|
|
16
|
+
*
|
|
17
|
+
* Typical pages include:
|
|
18
|
+
* - Homepage (/)
|
|
19
|
+
* - About (/about)
|
|
20
|
+
* - Pricing (/pricing)
|
|
21
|
+
* - Contact (/contact)
|
|
22
|
+
* - Blog (/blog)
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const pages: Pages = [
|
|
27
|
+
* {
|
|
28
|
+
* name: 'Home',
|
|
29
|
+
* path: '/',
|
|
30
|
+
* meta: { lang: 'en-US', title: 'Home', description: 'Welcome' },
|
|
31
|
+
* sections: []
|
|
32
|
+
* },
|
|
33
|
+
* {
|
|
34
|
+
* name: 'About',
|
|
35
|
+
* path: '/about',
|
|
36
|
+
* meta: { lang: 'en-US', title: 'About', description: 'About us' },
|
|
37
|
+
* sections: []
|
|
38
|
+
* }
|
|
39
|
+
* ]
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export const PagesSchema = Schema.Array(PageSchema).pipe(
|
|
43
|
+
Schema.minItems(1),
|
|
44
|
+
Schema.annotations({
|
|
45
|
+
identifier: 'Pages',
|
|
46
|
+
title: 'Pages',
|
|
47
|
+
description:
|
|
48
|
+
'Marketing and content pages with server-side rendering support. Pages use a component-based layout system with reusable component templates for building landing pages, about pages, pricing pages, and other public-facing content. Supports comprehensive metadata, theming, and structured data for SEO optimization.',
|
|
49
|
+
})
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* TypeScript type for Pages array
|
|
54
|
+
*/
|
|
55
|
+
export type Pages = typeof PagesSchema.Type
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Re-export Page schema and types from page module
|
|
59
|
+
*/
|
|
60
|
+
export { PageSchema }
|
|
61
|
+
export type { Page, PageEncoded }
|