@beechcms/core 0.8.0 → 0.9.0
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/dist/auth/account-email.d.ts +3 -0
- package/dist/auth/account-email.d.ts.map +1 -0
- package/dist/auth/account-email.js +9 -0
- package/dist/auth/password-reset-token.repository.d.ts +13 -2
- package/dist/auth/password-reset-token.repository.d.ts.map +1 -1
- package/dist/auth/user.repository.d.ts +69 -4
- package/dist/auth/user.repository.d.ts.map +1 -1
- package/dist/automations-grammar-words.d.ts +2 -0
- package/dist/automations-grammar-words.d.ts.map +1 -0
- package/dist/automations-grammar-words.js +8 -0
- package/dist/automations.repository.interface.d.ts +19 -0
- package/dist/automations.repository.interface.d.ts.map +1 -0
- package/dist/automations.repository.interface.js +3 -0
- package/dist/automations.runner.interface.d.ts +10 -0
- package/dist/automations.runner.interface.d.ts.map +1 -0
- package/dist/automations.runner.interface.js +3 -0
- package/dist/automations.runner.stub.d.ts +5 -0
- package/dist/automations.runner.stub.d.ts.map +1 -0
- package/dist/automations.runner.stub.js +7 -0
- package/dist/automations.types.d.ts +75 -0
- package/dist/automations.types.d.ts.map +1 -0
- package/dist/automations.types.js +3 -0
- package/dist/clock.d.ts +25 -0
- package/dist/clock.d.ts.map +1 -0
- package/dist/clock.js +11 -0
- package/dist/common/canonical-json.d.ts +31 -0
- package/dist/common/canonical-json.d.ts.map +1 -0
- package/dist/common/canonical-json.js +91 -0
- package/dist/content/content-scan.repository.d.ts +1 -1
- package/dist/content/content.repository.d.ts +154 -3
- package/dist/content/content.repository.d.ts.map +1 -1
- package/dist/content/content.repository.js +62 -0
- package/dist/content/deletion-ledger.d.ts +39 -0
- package/dist/content/deletion-ledger.d.ts.map +1 -0
- package/dist/content/deletion-ledger.js +3 -0
- package/dist/content/seed-media-purge.repository.d.ts +34 -0
- package/dist/content/seed-media-purge.repository.d.ts.map +1 -0
- package/dist/content/seed-media-purge.repository.js +3 -0
- package/dist/content/seed.repository.d.ts +14 -0
- package/dist/content/seed.repository.d.ts.map +1 -1
- package/dist/content-scan.repository.d.ts +9 -0
- package/dist/content-scan.repository.d.ts.map +1 -0
- package/dist/content-scan.repository.js +3 -0
- package/dist/content.repository.d.ts +247 -0
- package/dist/content.repository.d.ts.map +1 -0
- package/dist/content.repository.js +59 -0
- package/dist/dashboard-layout/content-view.d.ts +757 -0
- package/dist/dashboard-layout/content-view.d.ts.map +1 -0
- package/dist/dashboard-layout/content-view.js +285 -0
- package/dist/dashboard-layout/content-view.repository.d.ts +39 -0
- package/dist/dashboard-layout/content-view.repository.d.ts.map +1 -0
- package/dist/dashboard-layout/content-view.repository.js +3 -0
- package/dist/dashboard-layout/dashboard-layout.d.ts +5 -0
- package/dist/dashboard-layout/dashboard-layout.d.ts.map +1 -1
- package/dist/dashboard-layout/dashboard-layout.js +17 -9
- package/dist/dashboard-layout/kanban/kanban.d.ts +32 -18
- package/dist/dashboard-layout/kanban/kanban.d.ts.map +1 -1
- package/dist/dashboard-layout/kanban/kanban.js +45 -21
- package/dist/dashboard-layout/seed-layout.d.ts +22 -31
- package/dist/dashboard-layout/seed-layout.d.ts.map +1 -1
- package/dist/dashboard-layout/seed-layout.js +93 -18
- package/dist/dashboard-layout/seed-layout.repository.d.ts +1 -5
- package/dist/dashboard-layout/seed-layout.repository.d.ts.map +1 -1
- package/dist/dashboard-layout.d.ts +154 -0
- package/dist/dashboard-layout.d.ts.map +1 -0
- package/dist/dashboard-layout.js +186 -0
- package/dist/dashboard-layout.repository.d.ts +18 -0
- package/dist/dashboard-layout.repository.d.ts.map +1 -0
- package/dist/dashboard-layout.repository.js +3 -0
- package/dist/dashboard-permissions.d.ts +3 -0
- package/dist/dashboard-permissions.d.ts.map +1 -0
- package/dist/dashboard-permissions.js +11 -0
- package/dist/dashboard-scopes.d.ts +12 -0
- package/dist/dashboard-scopes.d.ts.map +1 -0
- package/dist/dashboard-scopes.js +30 -0
- package/dist/define-seed.d.ts +3 -0
- package/dist/define-seed.d.ts.map +1 -0
- package/dist/define-seed.js +5 -0
- package/dist/demo-data.repository.d.ts +5 -0
- package/dist/demo-data.repository.d.ts.map +1 -0
- package/dist/demo-data.repository.js +3 -0
- package/dist/email.provider.d.ts +32 -0
- package/dist/email.provider.d.ts.map +1 -0
- package/dist/email.provider.js +4 -0
- package/dist/engine/ddl/ddl.d.ts +247 -0
- package/dist/engine/ddl/ddl.d.ts.map +1 -0
- package/dist/engine/ddl/ddl.js +653 -0
- package/dist/engine/ddl/schema-mutator.d.ts +29 -0
- package/dist/engine/ddl/schema-mutator.d.ts.map +1 -0
- package/dist/engine/ddl/schema-mutator.js +3 -0
- package/dist/engine/ddl/seed-ddl-destructive.d.ts +40 -0
- package/dist/engine/ddl/seed-ddl-destructive.d.ts.map +1 -0
- package/dist/engine/ddl/seed-ddl-destructive.js +149 -0
- package/dist/engine/ddl/seed-ddl.d.ts +43 -0
- package/dist/engine/ddl/seed-ddl.d.ts.map +1 -0
- package/dist/engine/ddl/seed-ddl.js +115 -0
- package/dist/engine/ddl/seed-purge-guards.d.ts +7 -0
- package/dist/engine/ddl/seed-purge-guards.d.ts.map +1 -0
- package/dist/engine/ddl/seed-purge-guards.js +19 -0
- package/dist/engine/engine.d.ts +4 -3
- package/dist/engine/engine.d.ts.map +1 -1
- package/dist/engine/engine.js +4 -3
- package/dist/engine/introspection/introspection.d.ts +101 -0
- package/dist/engine/introspection/introspection.d.ts.map +1 -0
- package/dist/engine/introspection/introspection.js +127 -0
- package/dist/engine/introspection/relation-audit.d.ts +46 -0
- package/dist/engine/introspection/relation-audit.d.ts.map +1 -0
- package/dist/engine/introspection/relation-audit.js +103 -0
- package/dist/engine/introspection/schema-fingerprint.d.ts +74 -0
- package/dist/engine/introspection/schema-fingerprint.d.ts.map +1 -0
- package/dist/engine/introspection/schema-fingerprint.js +102 -0
- package/dist/engine/introspection.d.ts +101 -0
- package/dist/engine/introspection.d.ts.map +1 -0
- package/dist/engine/introspection.js +127 -0
- package/dist/engine/localization/localization.d.ts +127 -0
- package/dist/engine/localization/localization.d.ts.map +1 -0
- package/dist/engine/localization/localization.js +212 -0
- package/dist/engine/localization.d.ts +127 -0
- package/dist/engine/localization.d.ts.map +1 -0
- package/dist/engine/localization.js +212 -0
- package/dist/engine/privacy/policies.d.ts +58 -0
- package/dist/engine/privacy/policies.d.ts.map +1 -0
- package/dist/engine/privacy/policies.js +191 -0
- package/dist/engine/privacy/privacy.service.d.ts +78 -0
- package/dist/engine/privacy/privacy.service.d.ts.map +1 -0
- package/dist/engine/privacy/privacy.service.js +138 -0
- package/dist/engine/privacy.service.d.ts.map +1 -1
- package/dist/engine/query/active-clause.d.ts +19 -0
- package/dist/engine/query/active-clause.d.ts.map +1 -0
- package/dist/engine/query/active-clause.js +27 -0
- package/dist/engine/query/query.d.ts +36 -0
- package/dist/engine/query/query.d.ts.map +1 -0
- package/dist/engine/query/query.js +393 -0
- package/dist/engine/query/relations.d.ts +28 -0
- package/dist/engine/query/relations.d.ts.map +1 -0
- package/dist/engine/query/relations.js +25 -0
- package/dist/engine/query/serialize.d.ts +22 -0
- package/dist/engine/query/serialize.d.ts.map +1 -0
- package/dist/engine/query/serialize.js +175 -0
- package/dist/engine/schema-fingerprint.d.ts +73 -0
- package/dist/engine/schema-fingerprint.d.ts.map +1 -0
- package/dist/engine/schema-fingerprint.js +97 -0
- package/dist/engine/seed-registry.d.ts.map +1 -1
- package/dist/engine/seeds/candidate-ids.d.ts +14 -0
- package/dist/engine/seeds/candidate-ids.d.ts.map +1 -0
- package/dist/engine/seeds/candidate-ids.js +40 -0
- package/dist/engine/seeds/define-seed.d.ts +3 -0
- package/dist/engine/seeds/define-seed.d.ts.map +1 -0
- package/dist/engine/seeds/define-seed.js +5 -0
- package/dist/engine/seeds/seed-definition-diff.d.ts +38 -0
- package/dist/engine/seeds/seed-definition-diff.d.ts.map +1 -0
- package/dist/engine/seeds/seed-definition-diff.js +51 -0
- package/dist/engine/seeds/seed-registry.d.ts +88 -0
- package/dist/engine/seeds/seed-registry.d.ts.map +1 -0
- package/dist/engine/seeds/seed-registry.js +194 -0
- package/dist/engine/seeds/seed-types-generator.d.ts +25 -0
- package/dist/engine/seeds/seed-types-generator.d.ts.map +1 -0
- package/dist/engine/seeds/seed-types-generator.js +116 -0
- package/dist/engine/seeds/seed-validation.d.ts +35 -0
- package/dist/engine/seeds/seed-validation.d.ts.map +1 -0
- package/dist/engine/seeds/seed-validation.js +384 -0
- package/dist/engine/seeds/seeds.d.ts +20 -0
- package/dist/engine/seeds/seeds.d.ts.map +1 -0
- package/dist/engine/seeds/seeds.js +21 -0
- package/dist/engine/seeds/tag-migration.d.ts +73 -0
- package/dist/engine/seeds/tag-migration.d.ts.map +1 -0
- package/dist/engine/seeds/tag-migration.js +212 -0
- package/dist/engine/seeds/tag-options.d.ts +15 -0
- package/dist/engine/seeds/tag-options.d.ts.map +1 -0
- package/dist/engine/seeds/tag-options.js +111 -0
- package/dist/engine/seeds/tag-value.d.ts +31 -0
- package/dist/engine/seeds/tag-value.d.ts.map +1 -0
- package/dist/engine/seeds/tag-value.js +51 -0
- package/dist/engine/types.d.ts +59 -7
- package/dist/engine/types.d.ts.map +1 -1
- package/dist/engine/validation/cache.d.ts.map +1 -1
- package/dist/engine/validation/cache.js +20 -4
- package/dist/engine/validation/emptiness.d.ts +12 -0
- package/dist/engine/validation/emptiness.d.ts.map +1 -0
- package/dist/engine/validation/emptiness.js +33 -0
- package/dist/engine/validation/index.d.ts +11 -0
- package/dist/engine/validation/index.d.ts.map +1 -1
- package/dist/engine/validation/index.js +29 -33
- package/dist/engine/validation/primitives.d.ts +12 -0
- package/dist/engine/validation/primitives.d.ts.map +1 -1
- package/dist/engine/validation/primitives.js +22 -0
- package/dist/engine/validation/richtext-sanitizer.d.ts +9 -1
- package/dist/engine/validation/richtext-sanitizer.d.ts.map +1 -1
- package/dist/engine/validation/richtext-sanitizer.js +36 -7
- package/dist/engine/validation/schema-builders.d.ts +16 -0
- package/dist/engine/validation/schema-builders.d.ts.map +1 -1
- package/dist/engine/validation/schema-builders.js +125 -18
- package/dist/engine.d.ts +144 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +741 -0
- package/dist/file-types.d.ts +13 -0
- package/dist/file-types.d.ts.map +1 -0
- package/dist/file-types.js +85 -0
- package/dist/hooks.d.ts +29 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +3 -0
- package/dist/id-generator.d.ts +26 -0
- package/dist/id-generator.d.ts.map +1 -0
- package/dist/id-generator.js +12 -0
- package/dist/idempotency.repository.d.ts +13 -0
- package/dist/idempotency.repository.d.ts.map +1 -0
- package/dist/idempotency.repository.js +3 -0
- package/dist/index.d.ts +34 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +34 -11
- package/dist/kanban-position.repository.d.ts +19 -0
- package/dist/kanban-position.repository.d.ts.map +1 -0
- package/dist/kanban-position.repository.js +3 -0
- package/dist/kanban.d.ts +75 -0
- package/dist/kanban.d.ts.map +1 -0
- package/dist/kanban.js +82 -0
- package/dist/layout-permissions.d.ts +3 -0
- package/dist/layout-permissions.d.ts.map +1 -0
- package/dist/layout-permissions.js +11 -0
- package/dist/media/file-types.d.ts +12 -0
- package/dist/media/file-types.d.ts.map +1 -1
- package/dist/media/file-types.js +24 -4
- package/dist/media/image-transformer.d.ts +34 -0
- package/dist/media/image-transformer.d.ts.map +1 -0
- package/dist/media/image-transformer.js +3 -0
- package/dist/media/magic-bytes.d.ts.map +1 -1
- package/dist/media/magic-bytes.js +19 -9
- package/dist/media/media-transform.d.ts +92 -0
- package/dist/media/media-transform.d.ts.map +1 -0
- package/dist/media/media-transform.js +197 -0
- package/dist/media/media.repository.d.ts +5 -0
- package/dist/media/media.repository.d.ts.map +1 -1
- package/dist/media.repository.d.ts +61 -0
- package/dist/media.repository.d.ts.map +1 -0
- package/dist/media.repository.js +3 -0
- package/dist/notifications/notification.repository.d.ts +11 -2
- package/dist/notifications/notification.repository.d.ts.map +1 -1
- package/dist/oauth/authorization-code.repository.d.ts +10 -5
- package/dist/oauth/authorization-code.repository.d.ts.map +1 -1
- package/dist/oauth/role-guard.d.ts +30 -11
- package/dist/oauth/role-guard.d.ts.map +1 -1
- package/dist/oauth/role-guard.js +27 -5
- package/dist/oauth/token.repository.d.ts +2 -0
- package/dist/oauth/token.repository.d.ts.map +1 -1
- package/dist/policies.d.ts +10 -0
- package/dist/policies.d.ts.map +1 -0
- package/dist/policies.js +33 -0
- package/dist/queue/queue.interface.d.ts +9 -1
- package/dist/queue/queue.interface.d.ts.map +1 -1
- package/dist/queue/queue.stub.d.ts +1 -1
- package/dist/queue/queue.stub.d.ts.map +1 -1
- package/dist/queue/queue.stub.js +2 -3
- package/dist/queue.interface.d.ts +39 -0
- package/dist/queue.interface.d.ts.map +1 -0
- package/dist/queue.interface.js +3 -0
- package/dist/queue.stub.d.ts +6 -0
- package/dist/queue.stub.d.ts.map +1 -0
- package/dist/queue.stub.js +8 -0
- package/dist/rate-limit/token-bucket-rate-limiter.d.ts +7 -0
- package/dist/rate-limit/token-bucket-rate-limiter.d.ts.map +1 -1
- package/dist/rate-limit/token-bucket-rate-limiter.js +66 -0
- package/dist/rbac/evaluate.d.ts +57 -0
- package/dist/rbac/evaluate.d.ts.map +1 -0
- package/dist/rbac/evaluate.js +113 -0
- package/dist/rbac/invitation.repository.d.ts +84 -0
- package/dist/rbac/invitation.repository.d.ts.map +1 -0
- package/dist/rbac/invitation.repository.js +3 -0
- package/dist/rbac/permissions.d.ts +39 -0
- package/dist/rbac/permissions.d.ts.map +1 -0
- package/dist/rbac/permissions.js +43 -0
- package/dist/rbac/types.d.ts +130 -0
- package/dist/rbac/types.d.ts.map +1 -0
- package/dist/rbac/types.js +4 -0
- package/dist/relations.d.ts +28 -0
- package/dist/relations.d.ts.map +1 -0
- package/dist/relations.js +25 -0
- package/dist/richtext-render.d.ts +11 -0
- package/dist/richtext-render.d.ts.map +1 -0
- package/dist/richtext-render.js +87 -0
- package/dist/richtext.d.ts +11 -0
- package/dist/richtext.d.ts.map +1 -0
- package/dist/richtext.js +13 -0
- package/dist/scheduler.interface.d.ts +4 -0
- package/dist/scheduler.interface.d.ts.map +1 -0
- package/dist/scheduler.interface.js +3 -0
- package/dist/scheduler.stub.d.ts +5 -0
- package/dist/scheduler.stub.d.ts.map +1 -0
- package/dist/scheduler.stub.js +7 -0
- package/dist/schema/canonical.d.ts +15 -0
- package/dist/schema/canonical.d.ts.map +1 -0
- package/dist/schema/canonical.js +37 -0
- package/dist/schema/define.d.ts +42 -0
- package/dist/schema/define.d.ts.map +1 -0
- package/dist/schema/define.js +56 -0
- package/dist/schema/emit.d.ts +14 -0
- package/dist/schema/emit.d.ts.map +1 -0
- package/dist/schema/emit.js +43 -0
- package/dist/schema/index.d.ts +12 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +13 -0
- package/dist/schema/manifest-seeds.d.ts +12 -0
- package/dist/schema/manifest-seeds.d.ts.map +1 -0
- package/dist/schema/manifest-seeds.js +48 -0
- package/dist/schema/manifest-validation.d.ts +13 -0
- package/dist/schema/manifest-validation.d.ts.map +1 -0
- package/dist/schema/manifest-validation.js +41 -0
- package/dist/schema/manifest.types.d.ts +54 -0
- package/dist/schema/manifest.types.d.ts.map +1 -0
- package/dist/schema/manifest.types.js +7 -0
- package/dist/schema-mutator.d.ts +26 -0
- package/dist/schema-mutator.d.ts.map +1 -0
- package/dist/schema-mutator.js +3 -0
- package/dist/search/search.repository.d.ts +5 -4
- package/dist/search/search.repository.d.ts.map +1 -1
- package/dist/search/vector-extractor.d.ts.map +1 -1
- package/dist/search/vector-extractor.js +23 -2
- package/dist/search/vector.repository.d.ts +2 -1
- package/dist/search/vector.repository.d.ts.map +1 -1
- package/dist/security/time-trap-token.repository.d.ts +5 -3
- package/dist/security/time-trap-token.repository.d.ts.map +1 -1
- package/dist/seed-ddl-destructive.d.ts +40 -0
- package/dist/seed-ddl-destructive.d.ts.map +1 -0
- package/dist/seed-ddl-destructive.js +149 -0
- package/dist/seed-ddl.d.ts +40 -0
- package/dist/seed-ddl.d.ts.map +1 -0
- package/dist/seed-ddl.js +100 -0
- package/dist/seed-layout.d.ts +145 -0
- package/dist/seed-layout.d.ts.map +1 -0
- package/dist/seed-layout.js +192 -0
- package/dist/seed-layout.repository.d.ts +22 -0
- package/dist/seed-layout.repository.d.ts.map +1 -0
- package/dist/seed-layout.repository.js +3 -0
- package/dist/seed-registry.d.ts +71 -0
- package/dist/seed-registry.d.ts.map +1 -0
- package/dist/seed-registry.js +143 -0
- package/dist/seed-types-generator.d.ts +1 -1
- package/dist/seed-types-generator.d.ts.map +1 -1
- package/dist/seed-validation.d.ts +23 -0
- package/dist/seed-validation.d.ts.map +1 -0
- package/dist/seed-validation.js +224 -0
- package/dist/seed.repository.d.ts +37 -0
- package/dist/seed.repository.d.ts.map +1 -0
- package/dist/seed.repository.js +3 -0
- package/dist/seeds.d.ts +20 -0
- package/dist/seeds.d.ts.map +1 -0
- package/dist/seeds.js +21 -0
- package/dist/settings/site-settings.repository.d.ts +8 -0
- package/dist/settings/site-settings.repository.d.ts.map +1 -1
- package/dist/site-settings.repository.d.ts +16 -0
- package/dist/site-settings.repository.d.ts.map +1 -0
- package/dist/site-settings.repository.js +3 -0
- package/dist/slug-utils.d.ts +18 -0
- package/dist/slug-utils.d.ts.map +1 -0
- package/dist/slug-utils.js +32 -0
- package/dist/storage.d.ts +46 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +3 -0
- package/dist/transfer/csv.d.ts +34 -0
- package/dist/transfer/csv.d.ts.map +1 -0
- package/dist/transfer/csv.js +135 -0
- package/dist/transfer/flat-seed.d.ts +13 -0
- package/dist/transfer/flat-seed.d.ts.map +1 -0
- package/dist/transfer/flat-seed.js +50 -0
- package/dist/transfer/index.d.ts +7 -0
- package/dist/transfer/index.d.ts.map +1 -0
- package/dist/transfer/index.js +8 -0
- package/dist/transfer/ndjson.d.ts +25 -0
- package/dist/transfer/ndjson.d.ts.map +1 -0
- package/dist/transfer/ndjson.js +62 -0
- package/dist/transfer/row-mapping.d.ts +36 -0
- package/dist/transfer/row-mapping.d.ts.map +1 -0
- package/dist/transfer/row-mapping.js +97 -0
- package/dist/transfer/transfer.constants.d.ts +20 -0
- package/dist/transfer/transfer.constants.d.ts.map +1 -0
- package/dist/transfer/transfer.constants.js +21 -0
- package/dist/transfer/transfer.types.d.ts +46 -0
- package/dist/transfer/transfer.types.d.ts.map +1 -0
- package/dist/transfer/transfer.types.js +6 -0
- package/dist/types.d.ts +243 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/validation.d.ts +50 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +660 -0
- package/dist/webhook-validation.d.ts +3 -0
- package/dist/webhook-validation.d.ts.map +1 -0
- package/dist/webhook-validation.js +6 -0
- package/package.json +11 -6
- package/dist/.tsbuildinfo +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account-email.d.ts","sourceRoot":"","sources":["../../src/auth/account-email.ts"],"names":[],"mappings":"AAMA,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAG1D"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2024–2026 Flavio De Musso
|
|
3
|
+
const ACCOUNT_EMAIL_REGEX = /^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$/;
|
|
4
|
+
const MAX_ACCOUNT_EMAIL_LENGTH = 254;
|
|
5
|
+
/** Validates the trimmed, lowercased account identifier used by login and account writes. */
|
|
6
|
+
export function isValidAccountEmail(email) {
|
|
7
|
+
const normalizedEmail = email.trim().toLowerCase();
|
|
8
|
+
return normalizedEmail.length <= MAX_ACCOUNT_EMAIL_LENGTH && ACCOUNT_EMAIL_REGEX.test(normalizedEmail);
|
|
9
|
+
}
|
|
@@ -8,6 +8,12 @@ export interface ValidatedResetToken {
|
|
|
8
8
|
userId: string;
|
|
9
9
|
email: string;
|
|
10
10
|
}
|
|
11
|
+
export interface RedeemPasswordResetInput {
|
|
12
|
+
tokenId: string;
|
|
13
|
+
userId: string;
|
|
14
|
+
newPasswordHash: string;
|
|
15
|
+
nowTimestamp: number;
|
|
16
|
+
}
|
|
11
17
|
export interface IPasswordResetTokenRepository {
|
|
12
18
|
/**
|
|
13
19
|
* Marks all pending (unused) tokens for the user as consumed before issuing a new one.
|
|
@@ -22,7 +28,12 @@ export interface IPasswordResetTokenRepository {
|
|
|
22
28
|
* Returns null if the token is expired, already used, or not found.
|
|
23
29
|
*/
|
|
24
30
|
findValidByHashWithEmail(tokenHash: string, nowTimestamp: number): Promise<ValidatedResetToken | null>;
|
|
25
|
-
/**
|
|
26
|
-
|
|
31
|
+
/**
|
|
32
|
+
* Redeems a token in one atomic unit: burns it, replaces the user's password hash and revokes
|
|
33
|
+
* every refresh token. Either all three land or none do.
|
|
34
|
+
* Returns `true` for the single caller that burned the token, `false` (writing nothing) when it
|
|
35
|
+
* was already redeemed by a concurrent request.
|
|
36
|
+
*/
|
|
37
|
+
redeem(input: RedeemPasswordResetInput): Promise<boolean>;
|
|
27
38
|
}
|
|
28
39
|
//# sourceMappingURL=password-reset-token.repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"password-reset-token.repository.d.ts","sourceRoot":"","sources":["../../src/auth/password-reset-token.repository.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,6BAA6B;IAC5C;;;OAGG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtE,0FAA0F;IAC1F,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEpD;;;;OAIG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAEtG
|
|
1
|
+
{"version":3,"file":"password-reset-token.repository.d.ts","sourceRoot":"","sources":["../../src/auth/password-reset-token.repository.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,eAAe,EAAE,MAAM,CAAA;IACvB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,6BAA6B;IAC5C;;;OAGG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEtE,0FAA0F;IAC1F,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEpD;;;;OAIG;IACH,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAAA;IAEtG;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,wBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAC1D"}
|
|
@@ -1,12 +1,43 @@
|
|
|
1
|
+
import type { AdminGuardedResult, PageRequest } from '../rbac/types.js';
|
|
1
2
|
export interface UserRecord {
|
|
2
3
|
id: string;
|
|
3
4
|
email: string;
|
|
4
5
|
name: string | null;
|
|
5
6
|
surname: string | null;
|
|
6
7
|
passwordHash: string;
|
|
8
|
+
/**
|
|
9
|
+
* System-level account type ('admin' | 'editor').
|
|
10
|
+
* - 'admin': Developer / instance owner with full system access and Seed Builder control.
|
|
11
|
+
* - 'editor': Generic Beech CMS user whose permissions are managed via RBAC assignments.
|
|
12
|
+
* (Note: 'editor' is retained as technical debt for DB CHECK constraint and backwards compatibility).
|
|
13
|
+
*/
|
|
7
14
|
role: string;
|
|
8
15
|
avatarUrl: string | null;
|
|
9
16
|
notificationPreferences: string;
|
|
17
|
+
/**
|
|
18
|
+
* Reversible deactivation (`users.is_active`). A deactivated account keeps its rows,
|
|
19
|
+
* its assignments and its refresh tokens, but is refused at every authorization
|
|
20
|
+
* boundary — which is what makes revocation instant despite 15-minute access JWTs.
|
|
21
|
+
*/
|
|
22
|
+
isActive: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Administrative projection of an account. Deliberately carries NO `passwordHash`:
|
|
26
|
+
* account listings must never put credential material on the wire.
|
|
27
|
+
*/
|
|
28
|
+
export interface AccountSummary {
|
|
29
|
+
id: string;
|
|
30
|
+
email: string;
|
|
31
|
+
name: string | null;
|
|
32
|
+
surname: string | null;
|
|
33
|
+
/**
|
|
34
|
+
* Developer/owner axis ('admin' | 'editor'), orthogonal to RBAC permissions.
|
|
35
|
+
* - 'admin' = Developer / Owner
|
|
36
|
+
* - 'editor' = Generic Beech user (RBAC-gated)
|
|
37
|
+
*/
|
|
38
|
+
role: string;
|
|
39
|
+
isActive: boolean;
|
|
40
|
+
createdAt: number;
|
|
10
41
|
}
|
|
11
42
|
export interface NewUserInput {
|
|
12
43
|
id: string;
|
|
@@ -16,6 +47,15 @@ export interface NewUserInput {
|
|
|
16
47
|
name: string | null;
|
|
17
48
|
surname: string | null;
|
|
18
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* The (role, scope) grant `createInitialAdmin` writes in the same transaction as the
|
|
52
|
+
* account itself, so the first administrator can never exist without one.
|
|
53
|
+
*/
|
|
54
|
+
export interface InitialRoleGrant {
|
|
55
|
+
id: string;
|
|
56
|
+
roleId: string;
|
|
57
|
+
scope: string;
|
|
58
|
+
}
|
|
19
59
|
export interface IUserRepository {
|
|
20
60
|
/**
|
|
21
61
|
* Returns the total number of registered users.
|
|
@@ -29,11 +69,15 @@ export interface IUserRepository {
|
|
|
29
69
|
/** Inserts a new user record. */
|
|
30
70
|
create(user: NewUserInput): Promise<void>;
|
|
31
71
|
/**
|
|
32
|
-
* Atomically creates the first administrator account
|
|
33
|
-
* setup-completed marker row inserted in the same transaction.
|
|
34
|
-
*
|
|
72
|
+
* Atomically creates the first administrator account AND its `roleGrant`,
|
|
73
|
+
* guarded by a setup-completed marker row inserted in the same transaction.
|
|
74
|
+
* The account can never exist without its role: callers must resolve the
|
|
75
|
+
* grant before calling this, so a missing or unresolvable role aborts setup
|
|
76
|
+
* with nothing written instead of leaving a stranded, unrecoverable admin.
|
|
77
|
+
* Returns false instead of throwing when setup was already completed
|
|
78
|
+
* concurrently.
|
|
35
79
|
*/
|
|
36
|
-
createInitialAdmin(user: NewUserInput): Promise<boolean>;
|
|
80
|
+
createInitialAdmin(user: NewUserInput, roleGrant: InitialRoleGrant): Promise<boolean>;
|
|
37
81
|
/** Updates the user's display name, surname, and/or email address. */
|
|
38
82
|
updateProfile(userId: string, fields: {
|
|
39
83
|
name?: string;
|
|
@@ -42,6 +86,11 @@ export interface IUserRepository {
|
|
|
42
86
|
}): Promise<void>;
|
|
43
87
|
/** Replaces the user's stored password hash after a successful password change. */
|
|
44
88
|
updatePasswordHash(userId: string, newPasswordHash: string): Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Replaces the password hash and revokes every active refresh token of the user in one
|
|
91
|
+
* atomic write, so a password change can never leave old sessions valid.
|
|
92
|
+
*/
|
|
93
|
+
changePasswordAndRevokeSessions(userId: string, newPasswordHash: string, nowTimestamp: number): Promise<void>;
|
|
45
94
|
/** Sets or clears the user's avatar URL. */
|
|
46
95
|
updateAvatarUrl(userId: string, avatarUrl: string | null): Promise<void>;
|
|
47
96
|
/** Persists the user's notification preferences as a JSON string. */
|
|
@@ -52,5 +101,21 @@ export interface IUserRepository {
|
|
|
52
101
|
* an unrelated account exists.
|
|
53
102
|
*/
|
|
54
103
|
emailBelongsToAnotherUser(email: string, currentUserId: string): Promise<boolean>;
|
|
104
|
+
/** One page of accounts, oldest first, without credential material. */
|
|
105
|
+
listAccounts(page: PageRequest): Promise<AccountSummary[]>;
|
|
106
|
+
/** One account by id, without credential material. Null when absent. */
|
|
107
|
+
findAccountById(userId: string): Promise<AccountSummary | null>;
|
|
108
|
+
/**
|
|
109
|
+
* Flips `users.is_active`. `not-found` when the user does not exist.
|
|
110
|
+
* Reversible by design (brief §4): rows, assignments and tokens are all preserved.
|
|
111
|
+
* Deactivation returns `last-global-admin` and changes nothing when the account is the
|
|
112
|
+
* last active global administrator.
|
|
113
|
+
*/
|
|
114
|
+
setActive(userId: string, isActive: boolean): Promise<AdminGuardedResult>;
|
|
115
|
+
/**
|
|
116
|
+
* Read-only twin of the deactivation guard in {@link setActive}: is this account the last
|
|
117
|
+
* active global administrator? ADVISORY — see `IRoleAssignmentRepository.isLastGlobalAdminAssignment`.
|
|
118
|
+
*/
|
|
119
|
+
isLastGlobalAdmin(userId: string): Promise<boolean>;
|
|
55
120
|
}
|
|
56
121
|
//# sourceMappingURL=user.repository.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.repository.d.ts","sourceRoot":"","sources":["../../src/auth/user.repository.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,uBAAuB,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"user.repository.d.ts","sourceRoot":"","sources":["../../src/auth/user.repository.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automations-grammar-words.d.ts","sourceRoot":"","sources":["../src/automations-grammar-words.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,yBAAyB,aAKpC,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2024–2026 Flavio De Musso
|
|
3
|
+
export const AUTOMATION_RESERVED_WORDS = new Set([
|
|
4
|
+
'this', 'batch', 'all', 'firstone', 'lastone', 'byid', 'where',
|
|
5
|
+
'array',
|
|
6
|
+
'count', 'sum', 'avg', 'min', 'max', 'pluck',
|
|
7
|
+
'true', 'false', 'null',
|
|
8
|
+
]);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Automation, AutomationAction, AutomationTrigger, AutomationTriggerEvent, WhenNode } from './automations.types.js';
|
|
2
|
+
export interface CreateAutomationInput {
|
|
3
|
+
seed_slug: string;
|
|
4
|
+
name: string;
|
|
5
|
+
triggers: AutomationTrigger[];
|
|
6
|
+
trigger_conditions: WhenNode | null;
|
|
7
|
+
actions: AutomationAction[];
|
|
8
|
+
}
|
|
9
|
+
export type UpdateAutomationInput = Partial<CreateAutomationInput>;
|
|
10
|
+
export interface IAutomationRepository {
|
|
11
|
+
list(seedSlug: string): Promise<Automation[]>;
|
|
12
|
+
findById(id: string): Promise<Automation | null>;
|
|
13
|
+
create(input: CreateAutomationInput): Promise<string>;
|
|
14
|
+
update(id: string, input: UpdateAutomationInput): Promise<void>;
|
|
15
|
+
toggle(id: string, enabled: boolean): Promise<void>;
|
|
16
|
+
delete(id: string): Promise<void>;
|
|
17
|
+
findActive(seedSlug: string, event: AutomationTriggerEvent): Promise<Automation[]>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=automations.repository.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automations.repository.interface.d.ts","sourceRoot":"","sources":["../src/automations.repository.interface.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAE/H,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,iBAAiB,EAAE,CAAA;IAC7B,kBAAkB,EAAE,QAAQ,GAAG,IAAI,CAAA;IACnC,OAAO,EAAE,gBAAgB,EAAE,CAAA;CAC5B;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAA;AAElE,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IAC7C,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAA;IAChD,MAAM,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACrD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/D,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;CACnF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { AutomationTriggerEvent } from './automations.types.js';
|
|
2
|
+
export interface AutomationEventPayload {
|
|
3
|
+
seedSlug: string;
|
|
4
|
+
event: AutomationTriggerEvent;
|
|
5
|
+
entry: Record<string, unknown>;
|
|
6
|
+
}
|
|
7
|
+
export interface IAutomationRunner {
|
|
8
|
+
run(payload: AutomationEventPayload): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=automations.runner.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automations.runner.interface.d.ts","sourceRoot":"","sources":["../src/automations.runner.interface.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAA;AAEpE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,sBAAsB,CAAA;IAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACpD"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IAutomationRunner, AutomationEventPayload } from './automations.runner.interface.js';
|
|
2
|
+
export declare class NoOpAutomationRunner implements IAutomationRunner {
|
|
3
|
+
run(_payload: AutomationEventPayload): Promise<void>;
|
|
4
|
+
}
|
|
5
|
+
//# sourceMappingURL=automations.runner.stub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automations.runner.stub.d.ts","sourceRoot":"","sources":["../src/automations.runner.stub.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAA;AAElG,qBAAa,oBAAqB,YAAW,iBAAiB;IACtD,GAAG,CAAC,QAAQ,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC;CAG3D"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export type AutomationTriggerEvent = 'create' | 'update' | 'delete' | 'cron';
|
|
2
|
+
export interface AutomationTrigger {
|
|
3
|
+
event: AutomationTriggerEvent;
|
|
4
|
+
cron?: string | null;
|
|
5
|
+
}
|
|
6
|
+
export interface TriggerCondition {
|
|
7
|
+
field: string;
|
|
8
|
+
op: 'eq' | 'neq' | 'contains' | 'gt' | 'lt' | 'isempty' | 'isnotempty';
|
|
9
|
+
value: unknown;
|
|
10
|
+
}
|
|
11
|
+
export type WhenOperand = {
|
|
12
|
+
kind: 'literal';
|
|
13
|
+
value: unknown;
|
|
14
|
+
} | {
|
|
15
|
+
kind: 'ref';
|
|
16
|
+
key: string;
|
|
17
|
+
};
|
|
18
|
+
export type WhenOp = 'eq' | 'neq' | 'gt' | 'gte' | 'lt' | 'lte' | 'contains' | 'startswith' | 'endswith' | 'in' | 'notin' | 'isempty' | 'isnotempty' | 'matches';
|
|
19
|
+
export interface WhenPredicate {
|
|
20
|
+
kind: 'predicate';
|
|
21
|
+
left: WhenOperand;
|
|
22
|
+
op: WhenOp;
|
|
23
|
+
right?: WhenOperand;
|
|
24
|
+
}
|
|
25
|
+
export interface WhenGroup {
|
|
26
|
+
kind: 'group';
|
|
27
|
+
op: 'AND' | 'OR';
|
|
28
|
+
children: WhenNode[];
|
|
29
|
+
negate?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export type WhenNode = WhenPredicate | WhenGroup;
|
|
32
|
+
export interface SetVariableAction {
|
|
33
|
+
type: 'set_variable';
|
|
34
|
+
name: string;
|
|
35
|
+
seed_slug?: string;
|
|
36
|
+
fixed_id?: string;
|
|
37
|
+
column?: string;
|
|
38
|
+
filters?: TriggerCondition[];
|
|
39
|
+
order_by?: string;
|
|
40
|
+
order?: 'asc' | 'desc';
|
|
41
|
+
/** @deprecated Read but ignored at runtime. Removed on next save. */
|
|
42
|
+
load_type?: 'fruit' | 'branch';
|
|
43
|
+
}
|
|
44
|
+
export type AutomationAction = {
|
|
45
|
+
type: 'webhook';
|
|
46
|
+
url: string;
|
|
47
|
+
method?: 'POST' | 'GET' | 'PUT';
|
|
48
|
+
headers?: Record<string, string>;
|
|
49
|
+
body_template?: string;
|
|
50
|
+
} | {
|
|
51
|
+
type: 'send_mail';
|
|
52
|
+
to: string;
|
|
53
|
+
subject_template: string;
|
|
54
|
+
body_template: string;
|
|
55
|
+
} | {
|
|
56
|
+
type: 'edit_field';
|
|
57
|
+
field: string;
|
|
58
|
+
value: unknown;
|
|
59
|
+
} | {
|
|
60
|
+
type: 'create_entry';
|
|
61
|
+
seed_slug: string;
|
|
62
|
+
field_map: Record<string, string>;
|
|
63
|
+
} | SetVariableAction;
|
|
64
|
+
export interface Automation {
|
|
65
|
+
id: string;
|
|
66
|
+
seed_slug: string;
|
|
67
|
+
name: string;
|
|
68
|
+
enabled: boolean;
|
|
69
|
+
triggers: AutomationTrigger[];
|
|
70
|
+
trigger_conditions: WhenNode | null;
|
|
71
|
+
actions: AutomationAction[];
|
|
72
|
+
created_at: number;
|
|
73
|
+
updated_at: number;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=automations.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"automations.types.d.ts","sourceRoot":"","sources":["../src/automations.types.ts"],"names":[],"mappings":"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"}
|
package/dist/clock.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Time abstraction. Hides direct calls to {@link Date.now} so callers can
|
|
3
|
+
* swap in deterministic clocks during tests without resorting to global
|
|
4
|
+
* timer mocks (e.g. vi.useFakeTimers, sinon, monkey-patching Date).
|
|
5
|
+
*/
|
|
6
|
+
export interface IClock {
|
|
7
|
+
/**
|
|
8
|
+
* Returns the current Unix timestamp in milliseconds.
|
|
9
|
+
* Equivalent to Date.now() in production.
|
|
10
|
+
* Overridable in tests for deterministic time-sensitive assertions.
|
|
11
|
+
*/
|
|
12
|
+
now(): number;
|
|
13
|
+
/**
|
|
14
|
+
* Returns the current Unix timestamp in whole seconds.
|
|
15
|
+
* Equivalent to Math.floor(Date.now() / 1000) in production.
|
|
16
|
+
* Used by JWT issuance, session expiry, and analytics day-bucket computations.
|
|
17
|
+
*/
|
|
18
|
+
nowSeconds(): number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Production singleton. Delegates to the host runtime clock. Stateless and
|
|
22
|
+
* therefore safe to share across requests.
|
|
23
|
+
*/
|
|
24
|
+
export declare const SystemClock: IClock;
|
|
25
|
+
//# sourceMappingURL=clock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../src/clock.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,WAAW,MAAM;IACrB;;;;OAIG;IACH,GAAG,IAAI,MAAM,CAAA;IAEb;;;;OAIG;IACH,UAAU,IAAI,MAAM,CAAA;CACrB;AAID;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,MAGzB,CAAA"}
|
package/dist/clock.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2024–2026 Flavio De Musso
|
|
3
|
+
const MILLISECONDS_PER_SECOND = 1000;
|
|
4
|
+
/**
|
|
5
|
+
* Production singleton. Delegates to the host runtime clock. Stateless and
|
|
6
|
+
* therefore safe to share across requests.
|
|
7
|
+
*/
|
|
8
|
+
export const SystemClock = {
|
|
9
|
+
now: () => Date.now(),
|
|
10
|
+
nowSeconds: () => Math.floor(Date.now() / MILLISECONDS_PER_SECOND),
|
|
11
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module common/canonical-json
|
|
3
|
+
* Deterministic JSON serialization, shared by two callers that must never disagree:
|
|
4
|
+
* the manifest writer (`schema/canonical.ts`, authoring-side) and the schema fingerprint
|
|
5
|
+
* (`engine/schema-fingerprint.ts`, runtime-side). The public API's Idempotency-Key request
|
|
6
|
+
* fingerprint also hashes it, so equivalent payloads with reordered JSON keys match.
|
|
7
|
+
*
|
|
8
|
+
* Moved here in sprint 2 because the fingerprint runs inside the Worker and `schema/` is the one
|
|
9
|
+
* module the Worker must never import. The BYTES ARE FROZEN — sprint 1 declared this format a
|
|
10
|
+
* compatibility surface, and a published client's fingerprint is only comparable as long as it
|
|
11
|
+
* stays byte-stable. Changing key ordering, indentation or the trailing newline invalidates every
|
|
12
|
+
* already-published client and requires a `SCHEMA_FINGERPRINT_VERSION` bump.
|
|
13
|
+
*/
|
|
14
|
+
/** Thrown when a value cannot survive a JSON round-trip. */
|
|
15
|
+
export declare class CanonicalSerializationError extends Error {
|
|
16
|
+
/** Dotted path to the offending value, e.g. `seeds[0].branches[2].validate`. */
|
|
17
|
+
readonly path: string;
|
|
18
|
+
/** What was found there, e.g. `function`. */
|
|
19
|
+
readonly found: string;
|
|
20
|
+
constructor(
|
|
21
|
+
/** Dotted path to the offending value, e.g. `seeds[0].branches[2].validate`. */
|
|
22
|
+
path: string,
|
|
23
|
+
/** What was found there, e.g. `function`. */
|
|
24
|
+
found: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Serializes any value to its canonical form: keys sorted, two-space indentation, trailing newline.
|
|
28
|
+
* Stable across key insertion order and across authoring order.
|
|
29
|
+
*/
|
|
30
|
+
export declare function canonicalStringify(value: unknown): string;
|
|
31
|
+
//# sourceMappingURL=canonical-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-json.d.ts","sourceRoot":"","sources":["../../src/common/canonical-json.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH,4DAA4D;AAC5D,qBAAa,2BAA4B,SAAQ,KAAK;IAElD,gFAAgF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,6CAA6C;IAC7C,QAAQ,CAAC,KAAK,EAAE,MAAM;;IAHtB,gFAAgF;IACvE,IAAI,EAAE,MAAM;IACrB,6CAA6C;IACpC,KAAK,EAAE,MAAM;CAQzB;AA+CD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEzD"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Copyright (c) 2024–2026 Flavio De Musso
|
|
3
|
+
/**
|
|
4
|
+
* @module common/canonical-json
|
|
5
|
+
* Deterministic JSON serialization, shared by two callers that must never disagree:
|
|
6
|
+
* the manifest writer (`schema/canonical.ts`, authoring-side) and the schema fingerprint
|
|
7
|
+
* (`engine/schema-fingerprint.ts`, runtime-side). The public API's Idempotency-Key request
|
|
8
|
+
* fingerprint also hashes it, so equivalent payloads with reordered JSON keys match.
|
|
9
|
+
*
|
|
10
|
+
* Moved here in sprint 2 because the fingerprint runs inside the Worker and `schema/` is the one
|
|
11
|
+
* module the Worker must never import. The BYTES ARE FROZEN — sprint 1 declared this format a
|
|
12
|
+
* compatibility surface, and a published client's fingerprint is only comparable as long as it
|
|
13
|
+
* stays byte-stable. Changing key ordering, indentation or the trailing newline invalidates every
|
|
14
|
+
* already-published client and requires a `SCHEMA_FINGERPRINT_VERSION` bump.
|
|
15
|
+
*/
|
|
16
|
+
/** Thrown when a value cannot survive a JSON round-trip. */
|
|
17
|
+
export class CanonicalSerializationError extends Error {
|
|
18
|
+
path;
|
|
19
|
+
found;
|
|
20
|
+
constructor(
|
|
21
|
+
/** Dotted path to the offending value, e.g. `seeds[0].branches[2].validate`. */
|
|
22
|
+
path,
|
|
23
|
+
/** What was found there, e.g. `function`. */
|
|
24
|
+
found) {
|
|
25
|
+
super(`Manifest value at '${path}' is a ${found}, which cannot be persisted. ` +
|
|
26
|
+
`A manifest holds serializable JSON only — no callbacks, class instances, Date, Map, Set or RegExp.`);
|
|
27
|
+
this.path = path;
|
|
28
|
+
this.found = found;
|
|
29
|
+
this.name = 'CanonicalSerializationError';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function describe(value) {
|
|
33
|
+
if (value === null)
|
|
34
|
+
return null;
|
|
35
|
+
const type = typeof value;
|
|
36
|
+
if (type === 'function')
|
|
37
|
+
return 'function';
|
|
38
|
+
if (type === 'symbol')
|
|
39
|
+
return 'symbol';
|
|
40
|
+
if (type === 'bigint')
|
|
41
|
+
return 'bigint';
|
|
42
|
+
if (type === 'undefined')
|
|
43
|
+
return 'undefined';
|
|
44
|
+
if (type === 'number' && !Number.isFinite(value))
|
|
45
|
+
return 'non-finite number';
|
|
46
|
+
if (type !== 'object')
|
|
47
|
+
return null;
|
|
48
|
+
if (Array.isArray(value))
|
|
49
|
+
return null;
|
|
50
|
+
const proto = Object.getPrototypeOf(value);
|
|
51
|
+
if (proto !== Object.prototype && proto !== null)
|
|
52
|
+
return value.constructor?.name ?? 'class instance';
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Canonicalizes one value: object keys sorted lexicographically, `undefined` properties dropped,
|
|
57
|
+
* array ORDER preserved (branch order is the physical column order — it is data, not formatting).
|
|
58
|
+
*/
|
|
59
|
+
function canonicalize(value, path) {
|
|
60
|
+
const offence = describe(value);
|
|
61
|
+
if (offence)
|
|
62
|
+
throw new CanonicalSerializationError(path, offence);
|
|
63
|
+
if (value === null)
|
|
64
|
+
return null;
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
return Array.from({ length: value.length }, (_, index) => {
|
|
67
|
+
const item = Object.hasOwn(value, index) ? value[index] : undefined;
|
|
68
|
+
if (item === undefined)
|
|
69
|
+
throw new CanonicalSerializationError(`${path}[${index}]`, 'undefined');
|
|
70
|
+
return canonicalize(item, `${path}[${index}]`);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
if (typeof value === 'object') {
|
|
74
|
+
const out = Object.create(null);
|
|
75
|
+
for (const key of Object.keys(value).sort()) {
|
|
76
|
+
const child = value[key];
|
|
77
|
+
if (child === undefined)
|
|
78
|
+
continue;
|
|
79
|
+
out[key] = canonicalize(child, path ? `${path}.${key}` : key);
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
return value;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Serializes any value to its canonical form: keys sorted, two-space indentation, trailing newline.
|
|
87
|
+
* Stable across key insertion order and across authoring order.
|
|
88
|
+
*/
|
|
89
|
+
export function canonicalStringify(value) {
|
|
90
|
+
return `${JSON.stringify(canonicalize(value, ''), null, 2)}\n`;
|
|
91
|
+
}
|
|
@@ -2,7 +2,7 @@ import type { Seed } from '../engine/types.js';
|
|
|
2
2
|
export interface IContentScanRepository {
|
|
3
3
|
/**
|
|
4
4
|
* Scans across all registered seeds to identify media keys that are currently referenced
|
|
5
|
-
* by any content entry. Used for orphaned media detection and storage analytics.
|
|
5
|
+
* by any content entry, live or draft. Used for orphaned media detection and storage analytics.
|
|
6
6
|
*/
|
|
7
7
|
getReferencedMediaKeys(seeds: Seed[]): Promise<Set<string>>;
|
|
8
8
|
}
|