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,195 @@
|
|
|
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 { applyResponsiveOverrides, buildResponsiveClasses } from './responsive-resolver'
|
|
9
|
+
import type { Responsive, VariantOverrides } from '@/domain/models/app/page/common/responsive'
|
|
10
|
+
import type { Breakpoint } from '@/presentation/hooks/use-breakpoint'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Result of merging responsive props
|
|
14
|
+
*/
|
|
15
|
+
export interface MergedResponsiveProps {
|
|
16
|
+
readonly mergedProps: Record<string, unknown> | undefined
|
|
17
|
+
readonly mergedChildren: ReadonlyArray<unknown> | undefined
|
|
18
|
+
readonly mergedContent: string | Record<string, unknown> | undefined
|
|
19
|
+
readonly visibilityClasses: string | undefined
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Configuration for merging responsive props
|
|
24
|
+
*/
|
|
25
|
+
export interface MergeResponsivePropsConfig {
|
|
26
|
+
readonly responsive: Responsive | undefined
|
|
27
|
+
readonly componentProps: Record<string, unknown> | undefined
|
|
28
|
+
readonly children: ReadonlyArray<unknown> | undefined
|
|
29
|
+
readonly content: string | Record<string, unknown> | undefined
|
|
30
|
+
readonly currentBreakpoint: Breakpoint
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Remove className from props object
|
|
35
|
+
*/
|
|
36
|
+
function removeClassNameFromProps(
|
|
37
|
+
props: Record<string, unknown> | undefined
|
|
38
|
+
): Record<string, unknown> | undefined {
|
|
39
|
+
if (!props) return undefined
|
|
40
|
+
|
|
41
|
+
return Object.entries(props)
|
|
42
|
+
.filter(([key]) => key !== 'className')
|
|
43
|
+
.reduce<Record<string, unknown>>((acc, [key, value]) => ({ ...acc, [key]: value }), {})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Check if responsive config has content overrides
|
|
48
|
+
*/
|
|
49
|
+
function hasContentOverrides(responsive: Responsive | undefined): boolean {
|
|
50
|
+
return responsive
|
|
51
|
+
? Object.values(responsive).some(
|
|
52
|
+
(override) => (override as VariantOverrides).content !== undefined
|
|
53
|
+
)
|
|
54
|
+
: false
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Check if responsive config has children overrides
|
|
59
|
+
*/
|
|
60
|
+
function hasChildrenOverrides(responsive: Responsive | undefined): boolean {
|
|
61
|
+
return responsive
|
|
62
|
+
? Object.values(responsive).some(
|
|
63
|
+
(override) => (override as VariantOverrides).children !== undefined
|
|
64
|
+
)
|
|
65
|
+
: false
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Build visibility classes from responsive configuration
|
|
70
|
+
*/
|
|
71
|
+
function buildVisibilityClasses(responsive: Responsive | undefined): string | undefined {
|
|
72
|
+
if (!responsive) return undefined
|
|
73
|
+
|
|
74
|
+
const visibilityConfig = (Object.entries(responsive) as [string, VariantOverrides][])
|
|
75
|
+
.filter(([, overrides]) => overrides.visible !== undefined)
|
|
76
|
+
.reduce<Record<string, boolean>>((acc, [bp, overrides]) => {
|
|
77
|
+
return { ...acc, [bp]: overrides.visible! }
|
|
78
|
+
}, {})
|
|
79
|
+
|
|
80
|
+
// For mobile:false + lg:true pattern, use max-lg:hidden
|
|
81
|
+
if (visibilityConfig.mobile === false && visibilityConfig.lg === true) {
|
|
82
|
+
return 'max-lg:hidden'
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// For mobile:true + lg:false pattern, use lg:hidden
|
|
86
|
+
if (visibilityConfig.mobile === true && visibilityConfig.lg === false) {
|
|
87
|
+
return 'lg:hidden'
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Default fallback: build individual responsive classes
|
|
91
|
+
return Object.entries(visibilityConfig)
|
|
92
|
+
.map(([bp, isVisible]) => {
|
|
93
|
+
if (bp === 'mobile') {
|
|
94
|
+
return isVisible ? '' : 'max-sm:hidden'
|
|
95
|
+
}
|
|
96
|
+
return isVisible ? `${bp}:inline` : `${bp}:hidden`
|
|
97
|
+
})
|
|
98
|
+
.filter(Boolean)
|
|
99
|
+
.join(' ')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Merges responsive overrides with component props (config object signature)
|
|
104
|
+
*/
|
|
105
|
+
export function mergeResponsiveProps(config: MergeResponsivePropsConfig): MergedResponsiveProps
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Merges responsive overrides with component props (individual parameters signature)
|
|
109
|
+
*/
|
|
110
|
+
// eslint-disable-next-line max-params -- Function overload signature
|
|
111
|
+
export function mergeResponsiveProps(
|
|
112
|
+
responsive: Responsive | undefined,
|
|
113
|
+
componentProps: Record<string, unknown> | undefined,
|
|
114
|
+
children: ReadonlyArray<unknown> | undefined,
|
|
115
|
+
content: string | Record<string, unknown> | undefined,
|
|
116
|
+
currentBreakpoint: Breakpoint
|
|
117
|
+
): MergedResponsiveProps
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Implementation
|
|
121
|
+
*/
|
|
122
|
+
// eslint-disable-next-line max-params, max-lines-per-function, complexity -- Implementation handles both signatures
|
|
123
|
+
export function mergeResponsiveProps(
|
|
124
|
+
configOrResponsive: MergeResponsivePropsConfig | Responsive | undefined,
|
|
125
|
+
componentProps?: Record<string, unknown>,
|
|
126
|
+
children?: ReadonlyArray<unknown>,
|
|
127
|
+
content?: string | Record<string, unknown>,
|
|
128
|
+
currentBreakpoint?: Breakpoint
|
|
129
|
+
): MergedResponsiveProps {
|
|
130
|
+
// Support both config object and individual parameters
|
|
131
|
+
const config: MergeResponsivePropsConfig =
|
|
132
|
+
configOrResponsive &&
|
|
133
|
+
typeof configOrResponsive === 'object' &&
|
|
134
|
+
'responsive' in configOrResponsive
|
|
135
|
+
? configOrResponsive
|
|
136
|
+
: {
|
|
137
|
+
responsive: configOrResponsive as Responsive | undefined,
|
|
138
|
+
componentProps: componentProps!,
|
|
139
|
+
children: children!,
|
|
140
|
+
content: content!,
|
|
141
|
+
currentBreakpoint: currentBreakpoint!,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const {
|
|
145
|
+
responsive,
|
|
146
|
+
componentProps: props,
|
|
147
|
+
children: childrenProp,
|
|
148
|
+
content: contentProp,
|
|
149
|
+
currentBreakpoint: breakpoint,
|
|
150
|
+
} = config
|
|
151
|
+
|
|
152
|
+
// Apply responsive overrides for current breakpoint (used for SSR initial render)
|
|
153
|
+
const responsiveOverrides = applyResponsiveOverrides(responsive, breakpoint)
|
|
154
|
+
|
|
155
|
+
// Build CSS-based responsive classes (works without JavaScript via Tailwind media queries)
|
|
156
|
+
const baseClassName = props?.className as string | undefined
|
|
157
|
+
const responsiveClassName = buildResponsiveClasses(responsive, baseClassName)
|
|
158
|
+
|
|
159
|
+
// Merge responsive overrides with base component values
|
|
160
|
+
// For className, use CSS-based responsive classes instead of JS-based overrides
|
|
161
|
+
const mergedPropsWithoutClassName = removeClassNameFromProps(
|
|
162
|
+
responsiveOverrides?.props ? { ...props, ...responsiveOverrides.props } : props
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
const mergedProps: Record<string, unknown> | undefined = responsiveClassName
|
|
166
|
+
? { ...mergedPropsWithoutClassName, className: responsiveClassName }
|
|
167
|
+
: mergedPropsWithoutClassName
|
|
168
|
+
|
|
169
|
+
const mergedChildren = responsiveOverrides?.children ?? childrenProp
|
|
170
|
+
const mergedContent = responsiveOverrides?.content ?? contentProp
|
|
171
|
+
|
|
172
|
+
// Build CSS classes for responsive visibility using Tailwind breakpoint utilities
|
|
173
|
+
// This works without JavaScript by using CSS media queries
|
|
174
|
+
// Skip visibility classes when content/children overrides exist (handled by variant builders)
|
|
175
|
+
const shouldBuildVisibility =
|
|
176
|
+
responsive && !hasContentOverrides(responsive) && !hasChildrenOverrides(responsive)
|
|
177
|
+
|
|
178
|
+
const visibilityClasses = shouldBuildVisibility ? buildVisibilityClasses(responsive) : undefined
|
|
179
|
+
|
|
180
|
+
const mergedPropsWithVisibility = visibilityClasses
|
|
181
|
+
? {
|
|
182
|
+
...mergedProps,
|
|
183
|
+
className: mergedProps?.className
|
|
184
|
+
? `${mergedProps.className} ${visibilityClasses}`
|
|
185
|
+
: visibilityClasses,
|
|
186
|
+
}
|
|
187
|
+
: mergedProps
|
|
188
|
+
|
|
189
|
+
return {
|
|
190
|
+
mergedProps: mergedPropsWithVisibility,
|
|
191
|
+
mergedChildren,
|
|
192
|
+
mergedContent,
|
|
193
|
+
visibilityClasses,
|
|
194
|
+
}
|
|
195
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Responsive, VariantOverrides } from '@/domain/models/app/page/common/responsive'
|
|
9
|
+
import type { Breakpoint } from '@/presentation/hooks/use-breakpoint'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Breakpoint order for progressive enhancement (mobile-first)
|
|
13
|
+
* Shared constant used across all responsive rendering logic
|
|
14
|
+
*/
|
|
15
|
+
export const BREAKPOINT_ORDER: readonly Breakpoint[] = [
|
|
16
|
+
'mobile',
|
|
17
|
+
'sm',
|
|
18
|
+
'md',
|
|
19
|
+
'lg',
|
|
20
|
+
'xl',
|
|
21
|
+
'2xl',
|
|
22
|
+
] as const
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Map breakpoints to Tailwind responsive prefixes
|
|
26
|
+
*/
|
|
27
|
+
const BREAKPOINT_PREFIX: Record<Breakpoint, string> = {
|
|
28
|
+
mobile: '', // Mobile is base (no prefix)
|
|
29
|
+
sm: 'sm:',
|
|
30
|
+
md: 'md:',
|
|
31
|
+
lg: 'lg:',
|
|
32
|
+
xl: 'xl:',
|
|
33
|
+
'2xl': '2xl:',
|
|
34
|
+
} as const
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Gets active breakpoints up to and including current breakpoint
|
|
38
|
+
*
|
|
39
|
+
* @param currentBreakpoint - Current viewport breakpoint
|
|
40
|
+
* @returns Array of active breakpoints in order
|
|
41
|
+
*/
|
|
42
|
+
function getActiveBreakpoints(currentBreakpoint: Breakpoint): readonly Breakpoint[] {
|
|
43
|
+
const currentIndex = BREAKPOINT_ORDER.indexOf(currentBreakpoint)
|
|
44
|
+
return BREAKPOINT_ORDER.slice(0, currentIndex + 1)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Merges className strings
|
|
49
|
+
*
|
|
50
|
+
* Override replaces base (no concatenation)
|
|
51
|
+
*
|
|
52
|
+
* @param base - Base className
|
|
53
|
+
* @param override - Override className
|
|
54
|
+
* @returns Override className if present, else base
|
|
55
|
+
*/
|
|
56
|
+
function mergeClassNames(
|
|
57
|
+
base: string | undefined,
|
|
58
|
+
override: string | undefined
|
|
59
|
+
): string | undefined {
|
|
60
|
+
return override ?? base
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Props value type from VariantOverrides
|
|
65
|
+
*/
|
|
66
|
+
type PropsValue = string | number | boolean | readonly unknown[] | { readonly [x: string]: unknown }
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Props record type from VariantOverrides
|
|
70
|
+
*/
|
|
71
|
+
type PropsRecord = { readonly [x: string]: PropsValue }
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Merges props objects, handling className specially
|
|
75
|
+
*
|
|
76
|
+
* @param base - Base props
|
|
77
|
+
* @param override - Override props
|
|
78
|
+
* @returns Merged props
|
|
79
|
+
*/
|
|
80
|
+
function mergeProps(
|
|
81
|
+
base: PropsRecord | undefined,
|
|
82
|
+
override: PropsRecord | undefined
|
|
83
|
+
): PropsRecord | undefined {
|
|
84
|
+
if (!base && !override) return undefined
|
|
85
|
+
if (!base) return override
|
|
86
|
+
if (!override) return base
|
|
87
|
+
|
|
88
|
+
// Use reduce for functional approach
|
|
89
|
+
const overrideEntries = Object.entries(override).reduce<Record<string, PropsValue>>(
|
|
90
|
+
(acc, [key, value]) => {
|
|
91
|
+
if (key === 'className') {
|
|
92
|
+
const mergedClassName = mergeClassNames(
|
|
93
|
+
base.className as string | undefined,
|
|
94
|
+
value as string
|
|
95
|
+
)
|
|
96
|
+
return mergedClassName !== undefined ? { ...acc, className: mergedClassName } : acc
|
|
97
|
+
}
|
|
98
|
+
return { ...acc, [key]: value }
|
|
99
|
+
},
|
|
100
|
+
{}
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
return { ...base, ...overrideEntries }
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Applies responsive overrides for current breakpoint
|
|
108
|
+
*
|
|
109
|
+
* Uses mobile-first approach: applies base values, then progressively
|
|
110
|
+
* overrides with larger breakpoint values up to current breakpoint.
|
|
111
|
+
*
|
|
112
|
+
* @param responsive - Responsive configuration
|
|
113
|
+
* @param currentBreakpoint - Current viewport breakpoint
|
|
114
|
+
* @returns Merged overrides for current breakpoint
|
|
115
|
+
*/
|
|
116
|
+
export function applyResponsiveOverrides(
|
|
117
|
+
responsive: Responsive | undefined,
|
|
118
|
+
currentBreakpoint: Breakpoint
|
|
119
|
+
): VariantOverrides | undefined {
|
|
120
|
+
if (!responsive) return undefined
|
|
121
|
+
|
|
122
|
+
const activeBreakpoints = getActiveBreakpoints(currentBreakpoint)
|
|
123
|
+
|
|
124
|
+
// Use reduce for functional approach
|
|
125
|
+
const result = activeBreakpoints.reduce<VariantOverrides>((acc, bp) => {
|
|
126
|
+
const overrides = responsive[bp]
|
|
127
|
+
if (!overrides) return acc
|
|
128
|
+
|
|
129
|
+
// Build updated object functionally without let/mutations
|
|
130
|
+
const withProps = overrides.props
|
|
131
|
+
? { ...acc, props: mergeProps(acc.props, overrides.props) }
|
|
132
|
+
: acc
|
|
133
|
+
|
|
134
|
+
const withContent =
|
|
135
|
+
overrides.content !== undefined ? { ...withProps, content: overrides.content } : withProps
|
|
136
|
+
|
|
137
|
+
const withVisible =
|
|
138
|
+
overrides.visible !== undefined ? { ...withContent, visible: overrides.visible } : withContent
|
|
139
|
+
|
|
140
|
+
const withChildren =
|
|
141
|
+
overrides.children !== undefined
|
|
142
|
+
? { ...withVisible, children: overrides.children }
|
|
143
|
+
: withVisible
|
|
144
|
+
|
|
145
|
+
return withChildren
|
|
146
|
+
}, {})
|
|
147
|
+
|
|
148
|
+
return Object.keys(result).length > 0 ? result : undefined
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Builds responsive CSS classes from responsive configuration
|
|
153
|
+
*
|
|
154
|
+
* Converts responsive className overrides into Tailwind responsive prefixes.
|
|
155
|
+
* Uses mobile-first approach: base className from props, then breakpoint-prefixed overrides.
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* ```typescript
|
|
159
|
+
* buildResponsiveClasses(
|
|
160
|
+
* {
|
|
161
|
+
* mobile: { props: { className: 'text-sm' } },
|
|
162
|
+
* md: { props: { className: 'p-8 max-w-4xl' } }
|
|
163
|
+
* },
|
|
164
|
+
* 'p-4' // Base className from props
|
|
165
|
+
* )
|
|
166
|
+
* // Returns: 'text-sm md:p-8 md:max-w-4xl'
|
|
167
|
+
* // Note: mobile override replaces base, md classes prefixed
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* @param responsive - Responsive configuration
|
|
171
|
+
* @param baseClassName - Base className from component props
|
|
172
|
+
* @returns Combined CSS classes with responsive prefixes
|
|
173
|
+
*/
|
|
174
|
+
export function buildResponsiveClasses(
|
|
175
|
+
responsive: Responsive | undefined,
|
|
176
|
+
baseClassName: string | undefined
|
|
177
|
+
): string | undefined {
|
|
178
|
+
if (!responsive) return baseClassName
|
|
179
|
+
|
|
180
|
+
// Extract className from each breakpoint's props
|
|
181
|
+
const classNamesByBreakpoint = BREAKPOINT_ORDER.reduce<Record<string, string>>((acc, bp) => {
|
|
182
|
+
const overrides = responsive[bp]
|
|
183
|
+
const className = overrides?.props?.className as string | undefined
|
|
184
|
+
return className ? { ...acc, [bp]: className } : acc
|
|
185
|
+
}, {})
|
|
186
|
+
|
|
187
|
+
// If no responsive classNames, return base
|
|
188
|
+
if (Object.keys(classNamesByBreakpoint).length === 0) return baseClassName
|
|
189
|
+
|
|
190
|
+
// Determine base classes (mobile override takes precedence over props.className)
|
|
191
|
+
const mobileClassName = classNamesByBreakpoint.mobile
|
|
192
|
+
const effectiveBase = mobileClassName ?? baseClassName
|
|
193
|
+
|
|
194
|
+
// Build responsive classes for breakpoints larger than mobile
|
|
195
|
+
const responsiveClasses = BREAKPOINT_ORDER.filter((bp) => bp !== 'mobile')
|
|
196
|
+
.map((bp) => {
|
|
197
|
+
const className = classNamesByBreakpoint[bp]
|
|
198
|
+
if (!className) return undefined
|
|
199
|
+
|
|
200
|
+
const prefix = BREAKPOINT_PREFIX[bp]
|
|
201
|
+
// Prefix each class with breakpoint
|
|
202
|
+
return className
|
|
203
|
+
.split(' ')
|
|
204
|
+
.filter(Boolean)
|
|
205
|
+
.map((cls) => `${prefix}${cls}`)
|
|
206
|
+
.join(' ')
|
|
207
|
+
})
|
|
208
|
+
.filter(Boolean)
|
|
209
|
+
.join(' ')
|
|
210
|
+
|
|
211
|
+
// Combine base with responsive classes
|
|
212
|
+
return [effectiveBase, responsiveClasses].filter(Boolean).join(' ').trim() || undefined
|
|
213
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
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 { composeAnimation } from '@/presentation/styling/animation-composer'
|
|
9
|
+
import type { Component } from '@/domain/models/app/page/sections'
|
|
10
|
+
import type { Theme } from '@/domain/models/app/theme'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Apply all component-specific animations functionally using composition
|
|
14
|
+
* Compose fadeOut animation for toast components
|
|
15
|
+
* Compose scaleUp animation for card components with scroll trigger
|
|
16
|
+
* Compose float animation for fab components (continuous floating effect)
|
|
17
|
+
*/
|
|
18
|
+
export function applyComponentAnimations(
|
|
19
|
+
type: Component['type'],
|
|
20
|
+
baseStyle: Record<string, unknown> | undefined,
|
|
21
|
+
theme?: Theme
|
|
22
|
+
): Record<string, unknown> | undefined {
|
|
23
|
+
const styleWithFadeOut =
|
|
24
|
+
type === 'toast'
|
|
25
|
+
? composeAnimation({
|
|
26
|
+
baseStyle,
|
|
27
|
+
animationName: 'fadeOut',
|
|
28
|
+
theme,
|
|
29
|
+
defaultDuration: '300ms',
|
|
30
|
+
defaultEasing: 'ease-out',
|
|
31
|
+
})
|
|
32
|
+
: baseStyle
|
|
33
|
+
|
|
34
|
+
const styleWithScaleUp =
|
|
35
|
+
type === 'card'
|
|
36
|
+
? composeAnimation({
|
|
37
|
+
baseStyle: styleWithFadeOut,
|
|
38
|
+
animationName: 'scaleUp',
|
|
39
|
+
theme,
|
|
40
|
+
defaultDuration: '500ms',
|
|
41
|
+
defaultEasing: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
|
|
42
|
+
options: {
|
|
43
|
+
animationPlayState: 'paused',
|
|
44
|
+
animationFillMode: 'forwards',
|
|
45
|
+
opacity: 0,
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
|
+
: styleWithFadeOut
|
|
49
|
+
|
|
50
|
+
const finalStyle =
|
|
51
|
+
type === 'fab'
|
|
52
|
+
? composeAnimation({
|
|
53
|
+
baseStyle: styleWithScaleUp,
|
|
54
|
+
animationName: 'float',
|
|
55
|
+
theme,
|
|
56
|
+
defaultDuration: '3s',
|
|
57
|
+
defaultEasing: 'ease-in-out',
|
|
58
|
+
options: {
|
|
59
|
+
infinite: true,
|
|
60
|
+
},
|
|
61
|
+
})
|
|
62
|
+
: styleWithScaleUp
|
|
63
|
+
|
|
64
|
+
return finalStyle
|
|
65
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
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
|
+
* Build flex-specific classes based on props
|
|
10
|
+
*/
|
|
11
|
+
export function buildFlexClasses(props?: Record<string, unknown>): string {
|
|
12
|
+
const baseClasses = ['flex']
|
|
13
|
+
const alignmentClass =
|
|
14
|
+
props?.align === 'start'
|
|
15
|
+
? 'items-start'
|
|
16
|
+
: props?.align === 'center'
|
|
17
|
+
? 'items-center'
|
|
18
|
+
: props?.align === 'end'
|
|
19
|
+
? 'items-end'
|
|
20
|
+
: undefined
|
|
21
|
+
const gapClass = typeof props?.gap === 'number' ? `gap-${props.gap}` : undefined
|
|
22
|
+
|
|
23
|
+
return [...baseClasses, alignmentClass, gapClass].filter(Boolean).join(' ')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Build grid-specific classes based on columns prop with responsive breakpoints
|
|
28
|
+
*/
|
|
29
|
+
export function buildGridClasses(props?: Record<string, unknown>): string | undefined {
|
|
30
|
+
const baseClasses = ['grid']
|
|
31
|
+
|
|
32
|
+
// Get base column count (default to 1 for mobile-first)
|
|
33
|
+
const baseColumns = typeof props?.columns === 'number' ? props.columns : 1
|
|
34
|
+
const baseClass = `grid-cols-${baseColumns}`
|
|
35
|
+
|
|
36
|
+
// Build responsive classes from responsive property
|
|
37
|
+
const responsive = props?.responsive as Record<string, unknown> | undefined
|
|
38
|
+
const mdColumns = typeof responsive?.md === 'number' ? responsive.md : undefined
|
|
39
|
+
const lgColumns = typeof responsive?.lg === 'number' ? responsive.lg : undefined
|
|
40
|
+
|
|
41
|
+
const mdClass = mdColumns ? `md:grid-cols-${mdColumns}` : undefined
|
|
42
|
+
const lgClass = lgColumns ? `lg:grid-cols-${lgColumns}` : undefined
|
|
43
|
+
|
|
44
|
+
return [...baseClasses, baseClass, mdClass, lgClass].filter(Boolean).join(' ')
|
|
45
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2025 ESSENTIAL SERVICES
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Business Source License 1.1
|
|
5
|
+
* found in the LICENSE.md file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Component } from '@/domain/models/app/page/sections'
|
|
9
|
+
import type { Theme } from '@/domain/models/app/theme'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Component types and their corresponding theme color mapping
|
|
13
|
+
*/
|
|
14
|
+
const COMPONENT_COLOR_MAP: Record<string, keyof NonNullable<Theme['colors']>> = {
|
|
15
|
+
header: 'primary',
|
|
16
|
+
footer: 'secondary',
|
|
17
|
+
hero: 'background',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Apply theme colors to section elements automatically
|
|
22
|
+
*
|
|
23
|
+
* Maps component types to theme colors:
|
|
24
|
+
* - header → theme.colors.primary
|
|
25
|
+
* - footer → theme.colors.secondary
|
|
26
|
+
* - hero → theme.colors.background
|
|
27
|
+
*
|
|
28
|
+
* @param type - Component type
|
|
29
|
+
* @param theme - Theme configuration
|
|
30
|
+
* @returns Style object with background color or undefined
|
|
31
|
+
*/
|
|
32
|
+
export function getSectionColorStyle(
|
|
33
|
+
type: Component['type'],
|
|
34
|
+
theme?: Theme
|
|
35
|
+
): Record<string, unknown> | undefined {
|
|
36
|
+
if (!theme?.colors) return undefined
|
|
37
|
+
|
|
38
|
+
const colorKey = COMPONENT_COLOR_MAP[type]
|
|
39
|
+
if (!colorKey) return undefined
|
|
40
|
+
|
|
41
|
+
const color = theme.colors[colorKey]
|
|
42
|
+
return color ? { backgroundColor: color } : undefined
|
|
43
|
+
}
|
|
@@ -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
|
+
import type { HoverInteraction } from '@/domain/models/app/page/common/interactions/hover-interaction'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Maps hover interaction properties to CSS property names
|
|
12
|
+
*
|
|
13
|
+
* @param hover - Hover interaction configuration
|
|
14
|
+
* @returns Array of CSS property names
|
|
15
|
+
*/
|
|
16
|
+
function getAnimatableProperties(hover: HoverInteraction): ReadonlyArray<string> {
|
|
17
|
+
return [
|
|
18
|
+
(hover.scale !== undefined || hover.transform) && 'transform',
|
|
19
|
+
hover.opacity !== undefined && 'opacity',
|
|
20
|
+
hover.backgroundColor && 'background-color',
|
|
21
|
+
hover.color && 'color',
|
|
22
|
+
hover.borderColor && 'border-color',
|
|
23
|
+
hover.shadow && 'box-shadow',
|
|
24
|
+
].filter((prop): prop is string => Boolean(prop))
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Build CSS transition styles for base element state
|
|
29
|
+
*
|
|
30
|
+
* Generates transition property for smooth hover animations.
|
|
31
|
+
* Applied to the base element to define which properties should animate.
|
|
32
|
+
* Uses explicit transition properties (transitionProperty, transitionDuration, transitionTimingFunction)
|
|
33
|
+
* in camelCase for React style objects.
|
|
34
|
+
*
|
|
35
|
+
* @param hover - Hover interaction configuration
|
|
36
|
+
* @returns Transition style object or undefined
|
|
37
|
+
*/
|
|
38
|
+
export function buildHoverTransitionStyles(
|
|
39
|
+
hover: HoverInteraction | undefined
|
|
40
|
+
): Record<string, string> | undefined {
|
|
41
|
+
if (!hover) return undefined
|
|
42
|
+
|
|
43
|
+
const duration = hover.duration ?? '200ms'
|
|
44
|
+
const easing = hover.easing ?? 'ease-out'
|
|
45
|
+
const transitionProps = getAnimatableProperties(hover)
|
|
46
|
+
|
|
47
|
+
if (transitionProps.length === 0) return undefined
|
|
48
|
+
|
|
49
|
+
return {
|
|
50
|
+
transitionProperty: transitionProps.join(', '),
|
|
51
|
+
transitionDuration: duration,
|
|
52
|
+
transitionTimingFunction: easing,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Converts scale number to transform string
|
|
58
|
+
*
|
|
59
|
+
* @param scale - Scale factor (e.g., 1.05)
|
|
60
|
+
* @returns CSS transform string (e.g., 'scale(1.05)')
|
|
61
|
+
*/
|
|
62
|
+
function scaleToTransform(scale: number): string {
|
|
63
|
+
return `scale(${scale})`
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Build hover effect data for component
|
|
68
|
+
*
|
|
69
|
+
* Returns data attributes and style tag content for hover interactions.
|
|
70
|
+
* Uses a unique identifier to scope hover styles to specific elements.
|
|
71
|
+
*
|
|
72
|
+
* @param hover - Hover interaction configuration
|
|
73
|
+
* @param uniqueId - Unique identifier for the element
|
|
74
|
+
* @returns Hover data object with attributes and styles
|
|
75
|
+
*/
|
|
76
|
+
export function buildHoverData(
|
|
77
|
+
hover: HoverInteraction | undefined,
|
|
78
|
+
uniqueId: string
|
|
79
|
+
):
|
|
80
|
+
| {
|
|
81
|
+
readonly attributes: Record<string, string>
|
|
82
|
+
readonly styleContent: string
|
|
83
|
+
}
|
|
84
|
+
| undefined {
|
|
85
|
+
if (!hover) return undefined
|
|
86
|
+
|
|
87
|
+
// Convert scale to transform if present (scale takes priority over transform)
|
|
88
|
+
const transformValue = hover.scale !== undefined ? scaleToTransform(hover.scale) : hover.transform
|
|
89
|
+
|
|
90
|
+
// Build hover rules list (immutable)
|
|
91
|
+
// Use !important to override inline styles from props.style
|
|
92
|
+
const hoverRules = [
|
|
93
|
+
transformValue && `transform: ${transformValue} !important`,
|
|
94
|
+
hover.opacity !== undefined && `opacity: ${hover.opacity} !important`,
|
|
95
|
+
hover.backgroundColor && `background-color: ${hover.backgroundColor} !important`,
|
|
96
|
+
hover.color && `color: ${hover.color} !important`,
|
|
97
|
+
hover.borderColor && `border-color: ${hover.borderColor} !important`,
|
|
98
|
+
hover.shadow && `box-shadow: ${hover.shadow} !important`,
|
|
99
|
+
].filter((rule): rule is string => Boolean(rule))
|
|
100
|
+
|
|
101
|
+
if (hoverRules.length === 0) return undefined
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
attributes: { 'data-hover-id': uniqueId },
|
|
105
|
+
styleContent: `[data-hover-id="${uniqueId}"]:hover { ${hoverRules.join('; ')} }`,
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
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
|
+
// Barrel export for component styling utilities
|
|
9
|
+
// Files will be added during migration
|