@ddd-ts-kit/kernel 0.7.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/README.md +111 -9
- package/dist/application/audit/tenant-scope-of.d.ts +4 -1
- package/dist/application/audit/tenant-scope-of.d.ts.map +1 -1
- package/dist/application/audit/tenant-scope-of.js +6 -2
- package/dist/application/audit/tenant-scope-of.js.map +1 -1
- package/dist/application/cache/tenant-cache-key.d.ts +5 -0
- package/dist/application/cache/tenant-cache-key.d.ts.map +1 -0
- package/dist/application/cache/tenant-cache-key.js +7 -0
- package/dist/application/cache/tenant-cache-key.js.map +1 -0
- package/dist/application/events/execution-context-of-event.d.ts +2 -1
- package/dist/application/events/execution-context-of-event.d.ts.map +1 -1
- package/dist/application/events/execution-context-of-event.js +3 -1
- package/dist/application/events/execution-context-of-event.js.map +1 -1
- package/dist/application/events/integration-event.d.ts +6 -0
- package/dist/application/events/integration-event.d.ts.map +1 -1
- package/dist/application/events/scoped-publisher.d.ts +4 -3
- package/dist/application/events/scoped-publisher.d.ts.map +1 -1
- package/dist/application/events/scoped-publisher.js +11 -5
- package/dist/application/events/scoped-publisher.js.map +1 -1
- package/dist/application/execution/execution-context.d.ts +7 -1
- package/dist/application/execution/execution-context.d.ts.map +1 -1
- package/dist/application/execution/execution-context.js +7 -2
- package/dist/application/execution/execution-context.js.map +1 -1
- package/dist/application/execution/log-fields-of.d.ts.map +1 -1
- package/dist/application/execution/log-fields-of.js +1 -0
- package/dist/application/execution/log-fields-of.js.map +1 -1
- package/dist/application/files/accepts-media-type.d.ts +3 -0
- package/dist/application/files/accepts-media-type.d.ts.map +1 -0
- package/dist/application/files/accepts-media-type.js +11 -0
- package/dist/application/files/accepts-media-type.js.map +1 -0
- package/dist/application/files/assert-expiry.d.ts +3 -0
- package/dist/application/files/assert-expiry.d.ts.map +1 -0
- package/dist/application/files/assert-expiry.js +10 -0
- package/dist/application/files/assert-expiry.js.map +1 -0
- package/dist/application/files/assert-file-key.d.ts +3 -0
- package/dist/application/files/assert-file-key.d.ts.map +1 -0
- package/dist/application/files/assert-file-key.js +10 -0
- package/dist/application/files/assert-file-key.js.map +1 -0
- package/dist/application/files/assert-final-key.d.ts +3 -0
- package/dist/application/files/assert-final-key.d.ts.map +1 -0
- package/dist/application/files/assert-final-key.js +11 -0
- package/dist/application/files/assert-final-key.js.map +1 -0
- package/dist/application/files/content-disposition.d.ts +3 -0
- package/dist/application/files/content-disposition.d.ts.map +1 -0
- package/dist/application/files/content-disposition.js +9 -0
- package/dist/application/files/content-disposition.js.map +1 -0
- package/dist/application/files/content-expectation.d.ts +6 -0
- package/dist/application/files/content-expectation.d.ts.map +1 -0
- package/dist/application/files/content-expectation.js +2 -0
- package/dist/application/files/content-expectation.js.map +1 -0
- package/dist/application/files/content-matches.d.ts +7 -0
- package/dist/application/files/content-matches.d.ts.map +1 -0
- package/dist/application/files/content-matches.js +39 -0
- package/dist/application/files/content-matches.js.map +1 -0
- package/dist/application/files/download-url-options.d.ts +7 -0
- package/dist/application/files/download-url-options.d.ts.map +1 -0
- package/dist/application/files/download-url-options.js +2 -0
- package/dist/application/files/download-url-options.js.map +1 -0
- package/dist/application/files/file-content.d.ts +8 -0
- package/dist/application/files/file-content.d.ts.map +1 -0
- package/dist/application/files/file-content.js +2 -0
- package/dist/application/files/file-content.js.map +1 -0
- package/dist/application/files/file-error.d.ts +28 -0
- package/dist/application/files/file-error.d.ts.map +1 -0
- package/dist/application/files/file-error.js +29 -0
- package/dist/application/files/file-error.js.map +1 -0
- package/dist/application/files/file-metadata.d.ts +10 -0
- package/dist/application/files/file-metadata.d.ts.map +1 -0
- package/dist/application/files/file-metadata.js +2 -0
- package/dist/application/files/file-metadata.js.map +1 -0
- package/dist/application/files/file-source.d.ts +4 -0
- package/dist/application/files/file-source.d.ts.map +1 -0
- package/dist/application/files/file-source.js +2 -0
- package/dist/application/files/file-source.js.map +1 -0
- package/dist/application/files/file-upload.d.ts +25 -0
- package/dist/application/files/file-upload.d.ts.map +1 -0
- package/dist/application/files/file-upload.js +36 -0
- package/dist/application/files/file-upload.js.map +1 -0
- package/dist/application/files/index.d.ts +31 -0
- package/dist/application/files/index.d.ts.map +1 -0
- package/dist/application/files/index.js +31 -0
- package/dist/application/files/index.js.map +1 -0
- package/dist/application/files/inspection-limits.d.ts +8 -0
- package/dist/application/files/inspection-limits.d.ts.map +1 -0
- package/dist/application/files/inspection-limits.js +2 -0
- package/dist/application/files/inspection-limits.js.map +1 -0
- package/dist/application/files/is-file-key.d.ts +7 -0
- package/dist/application/files/is-file-key.d.ts.map +1 -0
- package/dist/application/files/is-file-key.js +11 -0
- package/dist/application/files/is-file-key.js.map +1 -0
- package/dist/application/files/listed-file.d.ts +7 -0
- package/dist/application/files/listed-file.d.ts.map +1 -0
- package/dist/application/files/listed-file.js +2 -0
- package/dist/application/files/listed-file.js.map +1 -0
- package/dist/application/files/max-signed-url-seconds.d.ts +3 -0
- package/dist/application/files/max-signed-url-seconds.d.ts.map +1 -0
- package/dist/application/files/max-signed-url-seconds.js +3 -0
- package/dist/application/files/max-signed-url-seconds.js.map +1 -0
- package/dist/application/files/media-type-of.d.ts +3 -0
- package/dist/application/files/media-type-of.d.ts.map +1 -0
- package/dist/application/files/media-type-of.js +5 -0
- package/dist/application/files/media-type-of.js.map +1 -0
- package/dist/application/files/pending-upload-link.d.ts +10 -0
- package/dist/application/files/pending-upload-link.d.ts.map +1 -0
- package/dist/application/files/pending-upload-link.js +2 -0
- package/dist/application/files/pending-upload-link.js.map +1 -0
- package/dist/application/files/pending-upload.d.ts +15 -0
- package/dist/application/files/pending-upload.d.ts.map +1 -0
- package/dist/application/files/pending-upload.js +2 -0
- package/dist/application/files/pending-upload.js.map +1 -0
- package/dist/application/files/put-options.d.ts +7 -0
- package/dist/application/files/put-options.d.ts.map +1 -0
- package/dist/application/files/put-options.js +2 -0
- package/dist/application/files/put-options.js.map +1 -0
- package/dist/application/files/received-file.d.ts +15 -0
- package/dist/application/files/received-file.d.ts.map +1 -0
- package/dist/application/files/received-file.js +2 -0
- package/dist/application/files/received-file.js.map +1 -0
- package/dist/application/files/scan-verdict.d.ts +8 -0
- package/dist/application/files/scan-verdict.d.ts.map +1 -0
- package/dist/application/files/scan-verdict.js +2 -0
- package/dist/application/files/scan-verdict.js.map +1 -0
- package/dist/application/files/signature-of.d.ts +3 -0
- package/dist/application/files/signature-of.d.ts.map +1 -0
- package/dist/application/files/signature-of.js +28 -0
- package/dist/application/files/signature-of.js.map +1 -0
- package/dist/application/files/signed-download.d.ts +6 -0
- package/dist/application/files/signed-download.d.ts.map +1 -0
- package/dist/application/files/signed-download.js +2 -0
- package/dist/application/files/signed-download.js.map +1 -0
- package/dist/application/files/signed-upload.d.ts +9 -0
- package/dist/application/files/signed-upload.d.ts.map +1 -0
- package/dist/application/files/signed-upload.js +2 -0
- package/dist/application/files/signed-upload.js.map +1 -0
- package/dist/application/files/signed-url.d.ts +6 -0
- package/dist/application/files/signed-url.d.ts.map +1 -0
- package/dist/application/files/signed-url.js +2 -0
- package/dist/application/files/signed-url.js.map +1 -0
- package/dist/application/files/staged-key-of.d.ts +5 -0
- package/dist/application/files/staged-key-of.d.ts.map +1 -0
- package/dist/application/files/staged-key-of.js +7 -0
- package/dist/application/files/staged-key-of.js.map +1 -0
- package/dist/application/files/stored-file.d.ts +16 -0
- package/dist/application/files/stored-file.d.ts.map +1 -0
- package/dist/application/files/stored-file.js +2 -0
- package/dist/application/files/stored-file.js.map +1 -0
- package/dist/application/files/upload-url-options.d.ts +12 -0
- package/dist/application/files/upload-url-options.d.ts.map +1 -0
- package/dist/application/files/upload-url-options.js +2 -0
- package/dist/application/files/upload-url-options.js.map +1 -0
- package/dist/application/ports/file-keys.d.ts +9 -0
- package/dist/application/ports/file-keys.d.ts.map +1 -0
- package/dist/application/ports/file-keys.js +10 -0
- package/dist/application/ports/file-keys.js.map +1 -0
- package/dist/application/ports/file-scanner.d.ts +13 -0
- package/dist/application/ports/file-scanner.d.ts.map +1 -0
- package/dist/application/ports/file-scanner.js +12 -0
- package/dist/application/ports/file-scanner.js.map +1 -0
- package/dist/application/ports/file-storage.d.ts +40 -0
- package/dist/application/ports/file-storage.d.ts.map +1 -0
- package/dist/application/ports/file-storage.js +15 -0
- package/dist/application/ports/file-storage.js.map +1 -0
- package/dist/application/ports/served-file-storage.d.ts +16 -0
- package/dist/application/ports/served-file-storage.d.ts.map +1 -0
- package/dist/application/ports/served-file-storage.js +12 -0
- package/dist/application/ports/served-file-storage.js.map +1 -0
- package/dist/application/ports/tenant-directory.d.ts +8 -0
- package/dist/application/ports/tenant-directory.d.ts.map +1 -0
- package/dist/application/ports/tenant-directory.js +10 -0
- package/dist/application/ports/tenant-directory.js.map +1 -0
- package/dist/application/scheduling/execution-context-of-job.d.ts +3 -1
- package/dist/application/scheduling/execution-context-of-job.d.ts.map +1 -1
- package/dist/application/scheduling/execution-context-of-job.js +1 -1
- package/dist/application/scheduling/execution-context-of-job.js.map +1 -1
- package/dist/application/scheduling/job-execution.d.ts +2 -0
- package/dist/application/scheduling/job-execution.d.ts.map +1 -1
- package/dist/application/scheduling/job-options.d.ts +6 -0
- package/dist/application/scheduling/job-options.d.ts.map +1 -1
- package/dist/application/scheduling/job-policy.d.ts.map +1 -1
- package/dist/application/scheduling/job-policy.js +4 -2
- package/dist/application/scheduling/job-policy.js.map +1 -1
- package/dist/application/session/has-scope.d.ts +5 -0
- package/dist/application/session/has-scope.d.ts.map +1 -0
- package/dist/application/session/has-scope.js +5 -0
- package/dist/application/session/has-scope.js.map +1 -0
- package/dist/application/session/session-scope.d.ts +4 -0
- package/dist/application/session/session-scope.d.ts.map +1 -0
- package/dist/application/session/session-scope.js +2 -0
- package/dist/application/session/session-scope.js.map +1 -0
- package/dist/application/session/session-scopes.d.ts +11 -0
- package/dist/application/session/session-scopes.d.ts.map +1 -0
- package/dist/application/session/session-scopes.js +2 -0
- package/dist/application/session/session-scopes.js.map +1 -0
- package/dist/application/session/session.d.ts +6 -0
- package/dist/application/session/session.d.ts.map +1 -1
- package/dist/application/tenancy/across-tenants.d.ts +12 -0
- package/dist/application/tenancy/across-tenants.d.ts.map +1 -0
- package/dist/application/tenancy/across-tenants.js +47 -0
- package/dist/application/tenancy/across-tenants.js.map +1 -0
- package/dist/application/tenancy/assert-tenant-id.d.ts +3 -0
- package/dist/application/tenancy/assert-tenant-id.d.ts.map +1 -0
- package/dist/application/tenancy/assert-tenant-id.js +10 -0
- package/dist/application/tenancy/assert-tenant-id.js.map +1 -0
- package/dist/application/tenancy/elevation-options.d.ts +12 -0
- package/dist/application/tenancy/elevation-options.d.ts.map +1 -0
- package/dist/application/tenancy/elevation-options.js +2 -0
- package/dist/application/tenancy/elevation-options.js.map +1 -0
- package/dist/application/tenancy/invalid-tenant-elevation-error.d.ts +5 -0
- package/dist/application/tenancy/invalid-tenant-elevation-error.d.ts.map +1 -0
- package/dist/application/tenancy/invalid-tenant-elevation-error.js +8 -0
- package/dist/application/tenancy/invalid-tenant-elevation-error.js.map +1 -0
- package/dist/application/tenancy/invalid-tenant-id-error.d.ts +6 -0
- package/dist/application/tenancy/invalid-tenant-id-error.d.ts.map +1 -0
- package/dist/application/tenancy/invalid-tenant-id-error.js +10 -0
- package/dist/application/tenancy/invalid-tenant-id-error.js.map +1 -0
- package/dist/application/tenancy/is-tenant-id.d.ts +3 -0
- package/dist/application/tenancy/is-tenant-id.d.ts.map +1 -0
- package/dist/application/tenancy/is-tenant-id.js +12 -0
- package/dist/application/tenancy/is-tenant-id.js.map +1 -0
- package/dist/application/tenancy/is-tenant-member.d.ts +4 -0
- package/dist/application/tenancy/is-tenant-member.d.ts.map +1 -0
- package/dist/application/tenancy/is-tenant-member.js +6 -0
- package/dist/application/tenancy/is-tenant-member.js.map +1 -0
- package/dist/application/tenancy/tenant-elevation.d.ts +11 -0
- package/dist/application/tenancy/tenant-elevation.d.ts.map +1 -0
- package/dist/application/tenancy/tenant-elevation.js +2 -0
- package/dist/application/tenancy/tenant-elevation.js.map +1 -0
- package/dist/application/tenancy/tenant-key.d.ts +9 -0
- package/dist/application/tenancy/tenant-key.d.ts.map +1 -0
- package/dist/application/tenancy/tenant-key.js +11 -0
- package/dist/application/tenancy/tenant-key.js.map +1 -0
- package/dist/application/tenancy/tenant-reach-of.d.ts +9 -0
- package/dist/application/tenancy/tenant-reach-of.d.ts.map +1 -0
- package/dist/application/tenancy/tenant-reach-of.js +18 -0
- package/dist/application/tenancy/tenant-reach-of.js.map +1 -0
- package/dist/application/tenancy/tenant-reach.d.ts +12 -0
- package/dist/application/tenancy/tenant-reach.d.ts.map +1 -0
- package/dist/application/tenancy/tenant-reach.js +2 -0
- package/dist/application/tenancy/tenant-reach.js.map +1 -0
- package/dist/application/tenancy/tenants-of.d.ts +8 -0
- package/dist/application/tenancy/tenants-of.d.ts.map +1 -0
- package/dist/application/tenancy/tenants-of.js +14 -0
- package/dist/application/tenancy/tenants-of.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/domain-events/after-commit.d.ts +10 -0
- package/dist/infrastructure/domain-events/after-commit.d.ts.map +1 -0
- package/dist/infrastructure/domain-events/after-commit.js +19 -0
- package/dist/infrastructure/domain-events/after-commit.js.map +1 -0
- package/dist/infrastructure/domain-events/at-commit.d.ts +11 -0
- package/dist/infrastructure/domain-events/at-commit.d.ts.map +1 -0
- package/dist/infrastructure/domain-events/at-commit.js +19 -0
- package/dist/infrastructure/domain-events/at-commit.js.map +1 -0
- package/dist/infrastructure/domain-events/commit-step.d.ts +10 -0
- package/dist/infrastructure/domain-events/commit-step.d.ts.map +1 -0
- package/dist/infrastructure/domain-events/commit-step.js +2 -0
- package/dist/infrastructure/domain-events/commit-step.js.map +1 -0
- package/dist/infrastructure/domain-events/unit-of-work-scope.d.ts +5 -0
- package/dist/infrastructure/domain-events/unit-of-work-scope.d.ts.map +1 -1
- package/dist/infrastructure/domain-events/unit-of-work-scope.js.map +1 -1
- package/dist/infrastructure/domain-events/within-unit-of-work.d.ts +3 -1
- package/dist/infrastructure/domain-events/within-unit-of-work.d.ts.map +1 -1
- package/dist/infrastructure/domain-events/within-unit-of-work.js +32 -5
- package/dist/infrastructure/domain-events/within-unit-of-work.js.map +1 -1
- package/dist/infrastructure/files/accept-every-file-scanner.d.ts +7 -0
- package/dist/infrastructure/files/accept-every-file-scanner.d.ts.map +1 -0
- package/dist/infrastructure/files/accept-every-file-scanner.js +7 -0
- package/dist/infrastructure/files/accept-every-file-scanner.js.map +1 -0
- package/dist/infrastructure/files/collect.d.ts +4 -0
- package/dist/infrastructure/files/collect.d.ts.map +1 -0
- package/dist/infrastructure/files/collect.js +11 -0
- package/dist/infrastructure/files/collect.js.map +1 -0
- package/dist/infrastructure/files/file-grant.d.ts +11 -0
- package/dist/infrastructure/files/file-grant.d.ts.map +1 -0
- package/dist/infrastructure/files/file-grant.js +2 -0
- package/dist/infrastructure/files/file-grant.js.map +1 -0
- package/dist/infrastructure/files/file-inspection.d.ts +22 -0
- package/dist/infrastructure/files/file-inspection.d.ts.map +1 -0
- package/dist/infrastructure/files/file-inspection.js +66 -0
- package/dist/infrastructure/files/file-inspection.js.map +1 -0
- package/dist/infrastructure/files/file-staging.d.ts +59 -0
- package/dist/infrastructure/files/file-staging.d.ts.map +1 -0
- package/dist/infrastructure/files/file-staging.js +142 -0
- package/dist/infrastructure/files/file-staging.js.map +1 -0
- package/dist/infrastructure/files/file-uploads-middleware.d.ts +11 -0
- package/dist/infrastructure/files/file-uploads-middleware.d.ts.map +1 -0
- package/dist/infrastructure/files/file-uploads-middleware.js +25 -0
- package/dist/infrastructure/files/file-uploads-middleware.js.map +1 -0
- package/dist/infrastructure/files/in-memory-file-storage.d.ts +25 -0
- package/dist/infrastructure/files/in-memory-file-storage.d.ts.map +1 -0
- package/dist/infrastructure/files/in-memory-file-storage.js +73 -0
- package/dist/infrastructure/files/in-memory-file-storage.js.map +1 -0
- package/dist/infrastructure/files/is-file-grant.d.ts +3 -0
- package/dist/infrastructure/files/is-file-grant.d.ts.map +1 -0
- package/dist/infrastructure/files/is-file-grant.js +16 -0
- package/dist/infrastructure/files/is-file-grant.js.map +1 -0
- package/dist/infrastructure/files/is-stored-metadata.d.ts +3 -0
- package/dist/infrastructure/files/is-stored-metadata.d.ts.map +1 -0
- package/dist/infrastructure/files/is-stored-metadata.js +8 -0
- package/dist/infrastructure/files/is-stored-metadata.js.map +1 -0
- package/dist/infrastructure/files/local-file-storage-options.d.ts +6 -0
- package/dist/infrastructure/files/local-file-storage-options.d.ts.map +1 -0
- package/dist/infrastructure/files/local-file-storage-options.js +2 -0
- package/dist/infrastructure/files/local-file-storage-options.js.map +1 -0
- package/dist/infrastructure/files/local-file-storage.d.ts +29 -0
- package/dist/infrastructure/files/local-file-storage.d.ts.map +1 -0
- package/dist/infrastructure/files/local-file-storage.js +103 -0
- package/dist/infrastructure/files/local-file-storage.js.map +1 -0
- package/dist/infrastructure/files/local-paths.d.ts +12 -0
- package/dist/infrastructure/files/local-paths.d.ts.map +1 -0
- package/dist/infrastructure/files/local-paths.js +33 -0
- package/dist/infrastructure/files/local-paths.js.map +1 -0
- package/dist/infrastructure/files/purge-staged-files.d.ts +16 -0
- package/dist/infrastructure/files/purge-staged-files.d.ts.map +1 -0
- package/dist/infrastructure/files/purge-staged-files.js +21 -0
- package/dist/infrastructure/files/purge-staged-files.js.map +1 -0
- package/dist/infrastructure/files/self-signed-file-storage.d.ts +23 -0
- package/dist/infrastructure/files/self-signed-file-storage.d.ts.map +1 -0
- package/dist/infrastructure/files/self-signed-file-storage.js +57 -0
- package/dist/infrastructure/files/self-signed-file-storage.js.map +1 -0
- package/dist/infrastructure/files/signed-file-tokens.d.ts +20 -0
- package/dist/infrastructure/files/signed-file-tokens.d.ts.map +1 -0
- package/dist/infrastructure/files/signed-file-tokens.js +45 -0
- package/dist/infrastructure/files/signed-file-tokens.js.map +1 -0
- package/dist/infrastructure/files/signed-link-options.d.ts +10 -0
- package/dist/infrastructure/files/signed-link-options.d.ts.map +1 -0
- package/dist/infrastructure/files/signed-link-options.js +2 -0
- package/dist/infrastructure/files/signed-link-options.js.map +1 -0
- package/dist/infrastructure/files/stored-metadata.d.ts +6 -0
- package/dist/infrastructure/files/stored-metadata.d.ts.map +1 -0
- package/dist/infrastructure/files/stored-metadata.js +2 -0
- package/dist/infrastructure/files/stored-metadata.js.map +1 -0
- package/dist/infrastructure/files/tenant-file-keys.d.ts +20 -0
- package/dist/infrastructure/files/tenant-file-keys.d.ts.map +1 -0
- package/dist/infrastructure/files/tenant-file-keys.js +27 -0
- package/dist/infrastructure/files/tenant-file-keys.js.map +1 -0
- package/dist/infrastructure/files/upload-desk.d.ts +8 -0
- package/dist/infrastructure/files/upload-desk.d.ts.map +1 -0
- package/dist/infrastructure/files/upload-desk.js +2 -0
- package/dist/infrastructure/files/upload-desk.js.map +1 -0
- package/dist/infrastructure/files/without-trailing-slashes.d.ts +3 -0
- package/dist/infrastructure/files/without-trailing-slashes.d.ts.map +1 -0
- package/dist/infrastructure/files/without-trailing-slashes.js +9 -0
- package/dist/infrastructure/files/without-trailing-slashes.js.map +1 -0
- package/dist/infrastructure/in-memory/in-memory-tenant-directory.d.ts +8 -0
- package/dist/infrastructure/in-memory/in-memory-tenant-directory.d.ts.map +1 -0
- package/dist/infrastructure/in-memory/in-memory-tenant-directory.js +12 -0
- package/dist/infrastructure/in-memory/in-memory-tenant-directory.js.map +1 -0
- package/dist/infrastructure/tenancy/tenant-isolation-policies.d.ts +13 -0
- package/dist/infrastructure/tenancy/tenant-isolation-policies.d.ts.map +1 -0
- package/dist/infrastructure/tenancy/tenant-isolation-policies.js +13 -0
- package/dist/infrastructure/tenancy/tenant-isolation-policies.js.map +1 -0
- package/dist/infrastructure/tenancy/tenant-policy-expressions.d.ts +11 -0
- package/dist/infrastructure/tenancy/tenant-policy-expressions.d.ts.map +1 -0
- package/dist/infrastructure/tenancy/tenant-policy-expressions.js +15 -0
- package/dist/infrastructure/tenancy/tenant-policy-expressions.js.map +1 -0
- package/dist/infrastructure/tenancy/tenant-setting-values.d.ts +13 -0
- package/dist/infrastructure/tenancy/tenant-setting-values.d.ts.map +1 -0
- package/dist/infrastructure/tenancy/tenant-setting-values.js +19 -0
- package/dist/infrastructure/tenancy/tenant-setting-values.js.map +1 -0
- package/dist/infrastructure/tenancy/tenant-settings.d.ts +13 -0
- package/dist/infrastructure/tenancy/tenant-settings.d.ts.map +1 -0
- package/dist/infrastructure/tenancy/tenant-settings.js +13 -0
- package/dist/infrastructure/tenancy/tenant-settings.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** A day: a command that staged a file has long committed or rolled back. */
|
|
2
|
+
const A_DAY_MS = 86_400_000;
|
|
3
|
+
/**
|
|
4
|
+
* The scheduled job of the platform that removes what rolled-back or crashed commands left in
|
|
5
|
+
* `staging/`: the files staged more than `olderThanMs` ago (a day by default). Registered under
|
|
6
|
+
* `files.purge-staged`, every hour, by the platform of a project that keeps files.
|
|
7
|
+
*/
|
|
8
|
+
export class PurgeStagedFiles {
|
|
9
|
+
staging;
|
|
10
|
+
clock;
|
|
11
|
+
olderThanMs;
|
|
12
|
+
constructor(staging, clock, olderThanMs = A_DAY_MS) {
|
|
13
|
+
this.staging = staging;
|
|
14
|
+
this.clock = clock;
|
|
15
|
+
this.olderThanMs = olderThanMs;
|
|
16
|
+
}
|
|
17
|
+
async run() {
|
|
18
|
+
await this.staging.purge(new Date(this.clock.now().getTime() - this.olderThanMs));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=purge-staged-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purge-staged-files.js","sourceRoot":"","sources":["../../../src/infrastructure/files/purge-staged-files.ts"],"names":[],"mappings":"AAIA,6EAA6E;AAC7E,MAAM,QAAQ,GAAG,UAAU,CAAC;AAE5B;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAER,OAAO;IACP,KAAK;IACL,WAAW;IAH9B,YACmB,OAAoB,EACpB,KAAY,EACZ,WAAW,GAAW,QAAQ;uBAF9B,OAAO;qBACP,KAAK;2BACL,WAAW;IAC3B,CAAC;IAEJ,KAAK,CAAC,GAAG;QACP,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACpF,CAAC;CACF"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { DownloadUrlOptions } from '../../application/files/download-url-options.js';
|
|
2
|
+
import type { FileSource } from '../../application/files/file-source.js';
|
|
3
|
+
import type { SignedDownload } from '../../application/files/signed-download.js';
|
|
4
|
+
import type { SignedUpload } from '../../application/files/signed-upload.js';
|
|
5
|
+
import type { SignedUrl } from '../../application/files/signed-url.js';
|
|
6
|
+
import type { StoredFile } from '../../application/files/stored-file.js';
|
|
7
|
+
import type { UploadUrlOptions } from '../../application/files/upload-url-options.js';
|
|
8
|
+
import { ServedFileStorage } from '../../application/ports/served-file-storage.js';
|
|
9
|
+
import type { SignedLinkOptions } from './signed-link-options.js';
|
|
10
|
+
/** The signed links of the storages the application serves itself: one token per link, under `baseUrl`. */
|
|
11
|
+
export declare abstract class SelfSignedFileStorage extends ServedFileStorage {
|
|
12
|
+
private readonly tokens;
|
|
13
|
+
private readonly baseUrl;
|
|
14
|
+
protected constructor(options: SignedLinkOptions);
|
|
15
|
+
signedDownloadUrl(key: string, options: DownloadUrlOptions): Promise<SignedUrl>;
|
|
16
|
+
signedUploadUrl(key: string, options: UploadUrlOptions): Promise<SignedUpload>;
|
|
17
|
+
openSigned(token: string): Promise<SignedDownload | undefined>;
|
|
18
|
+
/** Stores what a signed upload link sends, refused beyond the size the link was signed for (`FILE_TOO_LARGE`). */
|
|
19
|
+
acceptSigned(token: string, content: FileSource, mediaType: string): Promise<StoredFile | undefined>;
|
|
20
|
+
/** The token travels in the query, where no router limits its length the way it limits a path parameter. */
|
|
21
|
+
private linkOf;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=self-signed-file-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-signed-file-storage.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/files/self-signed-file-storage.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iDAAiD,CAAC;AAE1F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AAEzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0CAA0C,CAAC;AAC7E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,MAAM,gDAAgD,CAAC;AAEnF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAIlE,2GAA2G;AAC3G,8BAAsB,qBAAsB,SAAQ,iBAAiB;IACnE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAE1C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,SAAS,aAAa,OAAO,EAAE,iBAAiB,EAS/C;IAED,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,SAAS,CAAC,CAM9E;IAED,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,YAAY,CAAC,CAW7E;IAEK,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CASnE;IAED,kHAAkH;IAC5G,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAUzG;IAED,4GAA4G;IAC5G,OAAO,CAAC,MAAM;CAGf"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { assertExpiry } from '../../application/files/assert-expiry.js';
|
|
3
|
+
import { assertFileKey } from '../../application/files/assert-file-key.js';
|
|
4
|
+
import { mediaTypeOf } from '../../application/files/media-type-of.js';
|
|
5
|
+
import { ServedFileStorage } from '../../application/ports/served-file-storage.js';
|
|
6
|
+
import { SystemClock } from '../clock/system-clock.js';
|
|
7
|
+
import { SignedFileTokens } from './signed-file-tokens.js';
|
|
8
|
+
import { withoutTrailingSlashes } from './without-trailing-slashes.js';
|
|
9
|
+
/** The signed links of the storages the application serves itself: one token per link, under `baseUrl`. */
|
|
10
|
+
export class SelfSignedFileStorage extends ServedFileStorage {
|
|
11
|
+
tokens;
|
|
12
|
+
baseUrl;
|
|
13
|
+
constructor(options) {
|
|
14
|
+
super();
|
|
15
|
+
this.tokens = new SignedFileTokens(options.secret ?? randomBytes(32).toString('hex'), options.clock ?? new SystemClock());
|
|
16
|
+
this.baseUrl = withoutTrailingSlashes(options.baseUrl ?? 'http://localhost:3000/files');
|
|
17
|
+
}
|
|
18
|
+
signedDownloadUrl(key, options) {
|
|
19
|
+
const grant = { action: 'download', key: assertFileKey(key) };
|
|
20
|
+
const named = options.fileName === undefined ? grant : { ...grant, fileName: options.fileName };
|
|
21
|
+
const { token, expiresAt } = this.tokens.sign(named, assertExpiry(options.expiresInSeconds));
|
|
22
|
+
return Promise.resolve({ url: this.linkOf(token), expiresAt });
|
|
23
|
+
}
|
|
24
|
+
signedUploadUrl(key, options) {
|
|
25
|
+
const mediaType = mediaTypeOf(options.mediaType);
|
|
26
|
+
const grant = { action: 'upload', key: assertFileKey(key), mediaType, maxBytes: options.maxBytes };
|
|
27
|
+
const { token, expiresAt } = this.tokens.sign(grant, assertExpiry(options.expiresInSeconds));
|
|
28
|
+
return Promise.resolve({
|
|
29
|
+
url: this.linkOf(token),
|
|
30
|
+
method: 'PUT',
|
|
31
|
+
headers: { 'content-type': mediaType },
|
|
32
|
+
expiresAt,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
async openSigned(token) {
|
|
36
|
+
const grant = this.tokens.verify(token, 'download');
|
|
37
|
+
const content = grant === undefined ? undefined : await this.get(grant.key);
|
|
38
|
+
if (grant?.fileName === undefined || content === undefined) {
|
|
39
|
+
return content;
|
|
40
|
+
}
|
|
41
|
+
return { ...content, fileName: grant.fileName };
|
|
42
|
+
}
|
|
43
|
+
/** Stores what a signed upload link sends, refused beyond the size the link was signed for (`FILE_TOO_LARGE`). */
|
|
44
|
+
async acceptSigned(token, content, mediaType) {
|
|
45
|
+
const grant = this.tokens.verify(token, 'upload');
|
|
46
|
+
if (grant?.mediaType === undefined || grant.mediaType !== mediaTypeOf(mediaType)) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
const { key, maxBytes } = grant;
|
|
50
|
+
return this.put(key, content, { mediaType: grant.mediaType, ...(maxBytes === undefined ? {} : { maxBytes }) });
|
|
51
|
+
}
|
|
52
|
+
/** The token travels in the query, where no router limits its length the way it limits a path parameter. */
|
|
53
|
+
linkOf(token) {
|
|
54
|
+
return `${this.baseUrl}?token=${token}`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=self-signed-file-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-signed-file-storage.js","sourceRoot":"","sources":["../../../src/infrastructure/files/self-signed-file-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Clock } from '../../application/ports/clock.js';
|
|
2
|
+
import type { FileGrant } from './file-grant.js';
|
|
3
|
+
/**
|
|
4
|
+
* The tokens of the links a `ServedFileStorage` signs: the grant in base64url, a dot, and its
|
|
5
|
+
* HMAC-SHA256 under the secret. Whoever holds the token holds the grant until it expires; whoever
|
|
6
|
+
* changes a byte of it holds nothing.
|
|
7
|
+
*/
|
|
8
|
+
export declare class SignedFileTokens {
|
|
9
|
+
private readonly secret;
|
|
10
|
+
private readonly clock;
|
|
11
|
+
constructor(secret: string, clock: Clock);
|
|
12
|
+
sign(grant: Omit<FileGrant, 'expiresAt'>, expiresInSeconds: number): {
|
|
13
|
+
token: string;
|
|
14
|
+
expiresAt: Date;
|
|
15
|
+
};
|
|
16
|
+
/** The grant of a genuine, unexpired token for this action, or `undefined`. */
|
|
17
|
+
verify(token: string, action: FileGrant['action']): FileGrant | undefined;
|
|
18
|
+
private signatureOf;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=signed-file-tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signed-file-tokens.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/files/signed-file-tokens.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGjD;;;;GAIG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAFxB,YACmB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,KAAK,EAC3B;IAEJ,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,gBAAgB,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,CAKtG;IAED,+EAA+E;IAC/E,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,CAAC,QAAQ,CAAC,GAAG,SAAS,GAAG,SAAS,CAaxE;IAED,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
import { isFileGrant } from './is-file-grant.js';
|
|
3
|
+
/**
|
|
4
|
+
* The tokens of the links a `ServedFileStorage` signs: the grant in base64url, a dot, and its
|
|
5
|
+
* HMAC-SHA256 under the secret. Whoever holds the token holds the grant until it expires; whoever
|
|
6
|
+
* changes a byte of it holds nothing.
|
|
7
|
+
*/
|
|
8
|
+
export class SignedFileTokens {
|
|
9
|
+
secret;
|
|
10
|
+
clock;
|
|
11
|
+
constructor(secret, clock) {
|
|
12
|
+
this.secret = secret;
|
|
13
|
+
this.clock = clock;
|
|
14
|
+
}
|
|
15
|
+
sign(grant, expiresInSeconds) {
|
|
16
|
+
const expiresAt = Math.floor(this.clock.now().getTime() / 1_000) + expiresInSeconds;
|
|
17
|
+
const payload = Buffer.from(JSON.stringify({ ...grant, expiresAt })).toString('base64url');
|
|
18
|
+
return { token: `${payload}.${this.signatureOf(payload)}`, expiresAt: new Date(expiresAt * 1_000) };
|
|
19
|
+
}
|
|
20
|
+
/** The grant of a genuine, unexpired token for this action, or `undefined`. */
|
|
21
|
+
verify(token, action) {
|
|
22
|
+
const [payload = '', signature = ''] = token.split('.');
|
|
23
|
+
const expected = Buffer.from(this.signatureOf(payload));
|
|
24
|
+
const given = Buffer.from(signature);
|
|
25
|
+
if (expected.length !== given.length || !timingSafeEqual(expected, given)) {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
const grant = parsed(payload);
|
|
29
|
+
const now = this.clock.now().getTime() / 1_000;
|
|
30
|
+
return grant?.action === action && grant.expiresAt > now ? grant : undefined;
|
|
31
|
+
}
|
|
32
|
+
signatureOf(payload) {
|
|
33
|
+
return createHmac('sha256', this.secret).update(payload).digest('base64url');
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function parsed(payload) {
|
|
37
|
+
try {
|
|
38
|
+
const value = JSON.parse(Buffer.from(payload, 'base64url').toString('utf8'));
|
|
39
|
+
return isFileGrant(value) ? value : undefined;
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=signed-file-tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signed-file-tokens.js","sourceRoot":"","sources":["../../../src/infrastructure/files/signed-file-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG1D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IAER,MAAM;IACN,KAAK;IAFxB,YACmB,MAAc,EACd,KAAY;sBADZ,MAAM;qBACN,KAAK;IACrB,CAAC;IAEJ,IAAI,CAAC,KAAmC,EAAE,gBAAwB;QAChE,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,gBAAgB,CAAC;QACpF,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAE3F,OAAO,EAAE,KAAK,EAAE,GAAG,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,EAAE,CAAC;IACtG,CAAC;IAED,+EAA+E;IAC/E,MAAM,CAAC,KAAa,EAAE,MAA2B;QAC/C,MAAM,CAAC,OAAO,GAAG,EAAE,EAAE,SAAS,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QACxD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAErC,IAAI,QAAQ,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;YAC1E,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC9B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,CAAC;QAE/C,OAAO,KAAK,EAAE,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAC/E,CAAC;IAEO,WAAW,CAAC,OAAe;QACjC,OAAO,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAC/E,CAAC;CACF;AAED,SAAS,MAAM,CAAC,OAAe;IAC7B,IAAI,CAAC;QACH,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAEtF,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Clock } from '../../application/ports/clock.js';
|
|
2
|
+
export interface SignedLinkOptions {
|
|
3
|
+
/** Where `signedFileRoutes` of `@ddd-ts-kit/http` answers, as a client reaches it: `http://localhost:3000/files`. A link is `<baseUrl>?token=<token>`. */
|
|
4
|
+
readonly baseUrl?: string;
|
|
5
|
+
/** Signs the links. Left out, a random one is drawn: the links then die with the process. */
|
|
6
|
+
readonly secret?: string;
|
|
7
|
+
/** Reads the expiry of the links. Default: the system clock. */
|
|
8
|
+
readonly clock?: Clock;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=signed-link-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signed-link-options.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/files/signed-link-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AAE9D,MAAM,WAAW,iBAAiB;IAChC,0JAA0J;IAC1J,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,6FAA6F;IAC7F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signed-link-options.js","sourceRoot":"","sources":["../../../src/infrastructure/files/signed-link-options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stored-metadata.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/files/stored-metadata.ts"],"names":[],"mappings":"AAAA,2GAA2G;AAC3G,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stored-metadata.js","sourceRoot":"","sources":["../../../src/infrastructure/files/stored-metadata.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Clock } from '../../application/ports/clock.js';
|
|
2
|
+
import type { ExecutionScope } from '../../application/ports/execution-scope.js';
|
|
3
|
+
import type { FileKeys } from '../../application/ports/file-keys.js';
|
|
4
|
+
import type { IdGenerator } from '../../application/ports/id-generator.js';
|
|
5
|
+
/**
|
|
6
|
+
* Keys of the form `tenants/<tenant>/<area>/<year>/<month>/<id>`, the tenant segment only when
|
|
7
|
+
* the work in progress names a tenant: the files of a tenant then share a prefix that a bucket
|
|
8
|
+
* policy, an export or an erasure can address. A tenant id is a key segment as it is: the kernel
|
|
9
|
+
* refuses any other at every entry (`isTenantId`), so two tenants never share a prefix. An area that would put the key under `staging/`
|
|
10
|
+
* is refused (`INVALID_FILE_KEY`). The id comes from the `IdGenerator`, so a key is
|
|
11
|
+
* not guessable when the generator is not.
|
|
12
|
+
*/
|
|
13
|
+
export declare class TenantFileKeys implements FileKeys {
|
|
14
|
+
private readonly ids;
|
|
15
|
+
private readonly clock;
|
|
16
|
+
private readonly scope?;
|
|
17
|
+
constructor(ids: IdGenerator, clock: Clock, scope?: Pick<ExecutionScope, 'current'> | undefined);
|
|
18
|
+
next(area: string): string;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=tenant-file-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-file-keys.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/files/tenant-file-keys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,kCAAkC,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4CAA4C,CAAC;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAG3E;;;;;;;GAOG;AACH,qBAAa,cAAe,YAAW,QAAQ;IAE3C,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;IAHzB,YACmB,GAAG,EAAE,WAAW,EAChB,KAAK,EAAE,KAAK,EACZ,KAAK,CAAC,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC,YAAA,EACtD;IAEJ,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOzB;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { assertFinalKey } from '../../application/files/assert-final-key.js';
|
|
2
|
+
/**
|
|
3
|
+
* Keys of the form `tenants/<tenant>/<area>/<year>/<month>/<id>`, the tenant segment only when
|
|
4
|
+
* the work in progress names a tenant: the files of a tenant then share a prefix that a bucket
|
|
5
|
+
* policy, an export or an erasure can address. A tenant id is a key segment as it is: the kernel
|
|
6
|
+
* refuses any other at every entry (`isTenantId`), so two tenants never share a prefix. An area that would put the key under `staging/`
|
|
7
|
+
* is refused (`INVALID_FILE_KEY`). The id comes from the `IdGenerator`, so a key is
|
|
8
|
+
* not guessable when the generator is not.
|
|
9
|
+
*/
|
|
10
|
+
export class TenantFileKeys {
|
|
11
|
+
ids;
|
|
12
|
+
clock;
|
|
13
|
+
scope;
|
|
14
|
+
constructor(ids, clock, scope) {
|
|
15
|
+
this.ids = ids;
|
|
16
|
+
this.clock = clock;
|
|
17
|
+
this.scope = scope;
|
|
18
|
+
}
|
|
19
|
+
next(area) {
|
|
20
|
+
const now = this.clock.now();
|
|
21
|
+
const month = String(now.getUTCMonth() + 1).padStart(2, '0');
|
|
22
|
+
const key = `${area}/${String(now.getUTCFullYear())}/${month}/${this.ids.next()}`;
|
|
23
|
+
const tenantId = this.scope?.current()?.tenantId;
|
|
24
|
+
return assertFinalKey(tenantId === undefined ? key : `tenants/${tenantId}/${key}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=tenant-file-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-file-keys.js","sourceRoot":"","sources":["../../../src/infrastructure/files/tenant-file-keys.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,MAAM,6CAA6C,CAAC;AAE7E;;;;;;;GAOG;AACH,MAAM,OAAO,cAAc;IAEN,GAAG;IACH,KAAK;IACL,KAAK;IAHxB,YACmB,GAAgB,EAChB,KAAY,EACZ,KAAuC;mBAFvC,GAAG;qBACH,KAAK;qBACL,KAAK;IACrB,CAAC;IAEJ,IAAI,CAAC,IAAY;QACf,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC7D,MAAM,GAAG,GAAG,GAAG,IAAI,IAAI,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAClF,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,QAAQ,CAAC;QAEjD,OAAO,cAAc,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,QAAQ,IAAI,GAAG,EAAE,CAAC,CAAC;IACrF,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FileKeys } from '../../application/ports/file-keys.js';
|
|
2
|
+
import type { FileStaging } from './file-staging.js';
|
|
3
|
+
/** What `fileUploadsMiddleware` stages a file upload with: the keys of the server and the staging. */
|
|
4
|
+
export interface UploadDesk {
|
|
5
|
+
readonly keys: FileKeys;
|
|
6
|
+
readonly staging: FileStaging;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=upload-desk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-desk.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/files/upload-desk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sCAAsC,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,sGAAsG;AACtG,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;CAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-desk.js","sourceRoot":"","sources":["../../../src/infrastructure/files/upload-desk.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"without-trailing-slashes.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/files/without-trailing-slashes.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ5D"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** `value` without the slashes it ends with. */
|
|
2
|
+
export function withoutTrailingSlashes(value) {
|
|
3
|
+
let end = value.length;
|
|
4
|
+
while (end > 0 && value[end - 1] === '/') {
|
|
5
|
+
end -= 1;
|
|
6
|
+
}
|
|
7
|
+
return value.slice(0, end);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=without-trailing-slashes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"without-trailing-slashes.js","sourceRoot":"","sources":["../../../src/infrastructure/files/without-trailing-slashes.ts"],"names":[],"mappings":"AAAA,gDAAgD;AAChD,MAAM,UAAU,sBAAsB,CAAC,KAAa;IAClD,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC;IAEvB,OAAO,GAAG,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QACzC,GAAG,IAAI,CAAC,CAAC;IACX,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TenantDirectory } from '../../application/ports/tenant-directory.js';
|
|
2
|
+
/** The tenants it was given, for tests and for a project whose tenants are configuration; an id outside the grammar is refused. */
|
|
3
|
+
export declare class InMemoryTenantDirectory implements TenantDirectory {
|
|
4
|
+
private readonly ids;
|
|
5
|
+
constructor(ids: readonly string[]);
|
|
6
|
+
tenants(): Promise<readonly string[]>;
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=in-memory-tenant-directory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-tenant-directory.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/in-memory/in-memory-tenant-directory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAGnF,mIAAmI;AACnI,qBAAa,uBAAwB,YAAW,eAAe;IAC7D,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAoB;IAExC,YAAY,GAAG,EAAE,SAAS,MAAM,EAAE,EAEjC;IAED,OAAO,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAEpC;CACF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { assertTenantId } from '../../application/tenancy/assert-tenant-id.js';
|
|
2
|
+
/** The tenants it was given, for tests and for a project whose tenants are configuration; an id outside the grammar is refused. */
|
|
3
|
+
export class InMemoryTenantDirectory {
|
|
4
|
+
ids;
|
|
5
|
+
constructor(ids) {
|
|
6
|
+
this.ids = ids.map(assertTenantId);
|
|
7
|
+
}
|
|
8
|
+
tenants() {
|
|
9
|
+
return Promise.resolve([...this.ids]);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=in-memory-tenant-directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-tenant-directory.js","sourceRoot":"","sources":["../../../src/infrastructure/in-memory/in-memory-tenant-directory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAE/E,mIAAmI;AACnI,MAAM,OAAO,uBAAuB;IACjB,GAAG,CAAoB;IAExC,YAAY,GAAsB;QAChC,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACrC,CAAC;IAED,OAAO;QACL,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;CACF"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The names of the row-level security policies of a table of tenant data, in every adapter: one
|
|
3
|
+
* per command, because PostgreSQL applies the `using` of a single policy to the rows a `delete`
|
|
4
|
+
* or an `update` targets. Reads see the reach of the work; inserts, updates and deletes only ever
|
|
5
|
+
* touch the rows of its one tenant, elevated or not.
|
|
6
|
+
*/
|
|
7
|
+
export declare const TENANT_ISOLATION_POLICIES: {
|
|
8
|
+
readonly select: 'tenant_isolation_select';
|
|
9
|
+
readonly insert: 'tenant_isolation_insert';
|
|
10
|
+
readonly update: 'tenant_isolation_update';
|
|
11
|
+
readonly delete: 'tenant_isolation_delete';
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=tenant-isolation-policies.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-isolation-policies.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/tenancy/tenant-isolation-policies.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;aACpC,MAAM,EAAE,yBAAyB;aACjC,MAAM,EAAE,yBAAyB;aACjC,MAAM,EAAE,yBAAyB;aACjC,MAAM,EAAE,yBAAyB;CACzB,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The names of the row-level security policies of a table of tenant data, in every adapter: one
|
|
3
|
+
* per command, because PostgreSQL applies the `using` of a single policy to the rows a `delete`
|
|
4
|
+
* or an `update` targets. Reads see the reach of the work; inserts, updates and deletes only ever
|
|
5
|
+
* touch the rows of its one tenant, elevated or not.
|
|
6
|
+
*/
|
|
7
|
+
export const TENANT_ISOLATION_POLICIES = {
|
|
8
|
+
select: 'tenant_isolation_select',
|
|
9
|
+
insert: 'tenant_isolation_insert',
|
|
10
|
+
update: 'tenant_isolation_update',
|
|
11
|
+
delete: 'tenant_isolation_delete',
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=tenant-isolation-policies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-isolation-policies.js","sourceRoot":"","sources":["../../../src/infrastructure/tenancy/tenant-isolation-policies.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,MAAM,EAAE,yBAAyB;IACjC,MAAM,EAAE,yBAAyB;IACjC,MAAM,EAAE,yBAAyB;IACjC,MAAM,EAAE,yBAAyB;CACzB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The expressions of the row-level security policies on a column, quoted as SQL. `read`: the row
|
|
3
|
+
* belongs to `ddd_ts_kit.tenant_id`, to a tenant of `ddd_ts_kit.reach`, or
|
|
4
|
+
* `ddd_ts_kit.every_tenant` is `on`. `write`: the row belongs to `ddd_ts_kit.tenant_id`, whatever
|
|
5
|
+
* an elevation widened. Work that set nothing reads nothing and writes nothing.
|
|
6
|
+
*/
|
|
7
|
+
export declare function tenantPolicyExpressions(column: string): {
|
|
8
|
+
readonly read: string;
|
|
9
|
+
readonly write: string;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=tenant-policy-expressions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-policy-expressions.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/tenancy/tenant-policy-expressions.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAOzG"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TENANT_SETTINGS } from './tenant-settings.js';
|
|
2
|
+
/**
|
|
3
|
+
* The expressions of the row-level security policies on a column, quoted as SQL. `read`: the row
|
|
4
|
+
* belongs to `ddd_ts_kit.tenant_id`, to a tenant of `ddd_ts_kit.reach`, or
|
|
5
|
+
* `ddd_ts_kit.every_tenant` is `on`. `write`: the row belongs to `ddd_ts_kit.tenant_id`, whatever
|
|
6
|
+
* an elevation widened. Work that set nothing reads nothing and writes nothing.
|
|
7
|
+
*/
|
|
8
|
+
export function tenantPolicyExpressions(column) {
|
|
9
|
+
const setting = (name) => `current_setting('${name}', true)`;
|
|
10
|
+
const tenant = `${column} = ${setting(TENANT_SETTINGS.tenant)}`;
|
|
11
|
+
const reach = `${column} = any(string_to_array(${setting(TENANT_SETTINGS.reach)}, ','))`;
|
|
12
|
+
const everyTenant = `${setting(TENANT_SETTINGS.everyTenant)} = 'on'`;
|
|
13
|
+
return { read: `${tenant} or ${reach} or ${everyTenant}`, write: tenant };
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=tenant-policy-expressions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-policy-expressions.js","sourceRoot":"","sources":["../../../src/infrastructure/tenancy/tenant-policy-expressions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,MAAc;IACpD,MAAM,OAAO,GAAG,CAAC,IAAY,EAAU,EAAE,CAAC,oBAAoB,IAAI,UAAU,CAAC;IAC7E,MAAM,MAAM,GAAG,GAAG,MAAM,MAAM,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,EAAE,CAAC;IAChE,MAAM,KAAK,GAAG,GAAG,MAAM,0BAA0B,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC;IACzF,MAAM,WAAW,GAAG,GAAG,OAAO,CAAC,eAAe,CAAC,WAAW,CAAC,SAAS,CAAC;IAErE,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,OAAO,KAAK,OAAO,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ExecutionContext } from '../../application/execution/execution-context.js';
|
|
2
|
+
/**
|
|
3
|
+
* The values of `TENANT_SETTINGS` for the work in progress, which a unit of work under
|
|
4
|
+
* row-level security sets per transaction: empty for work that names no tenant. Every tenant id
|
|
5
|
+
* is checked against the grammar of `isTenantId` again here, the last step before SQL, so that a
|
|
6
|
+
* context built by hand can never set a list or a wildcard; only an elevation sets the reach.
|
|
7
|
+
*/
|
|
8
|
+
export declare function tenantSettingValues(context: ExecutionContext | undefined): {
|
|
9
|
+
tenant: string;
|
|
10
|
+
reach: string;
|
|
11
|
+
everyTenant: string;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=tenant-setting-values.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-setting-values.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/tenancy/tenant-setting-values.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kDAAkD,CAAC;AAGzF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,SAAS,GAAG;IAC1E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB,CAaA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { assertTenantId } from '../../application/tenancy/assert-tenant-id.js';
|
|
2
|
+
/**
|
|
3
|
+
* The values of `TENANT_SETTINGS` for the work in progress, which a unit of work under
|
|
4
|
+
* row-level security sets per transaction: empty for work that names no tenant. Every tenant id
|
|
5
|
+
* is checked against the grammar of `isTenantId` again here, the last step before SQL, so that a
|
|
6
|
+
* context built by hand can never set a list or a wildcard; only an elevation sets the reach.
|
|
7
|
+
*/
|
|
8
|
+
export function tenantSettingValues(context) {
|
|
9
|
+
const tenant = context?.tenantId === undefined ? '' : assertTenantId(context.tenantId);
|
|
10
|
+
const elevation = context?.elevation;
|
|
11
|
+
if (elevation === undefined) {
|
|
12
|
+
return { tenant, reach: '', everyTenant: '' };
|
|
13
|
+
}
|
|
14
|
+
if (elevation.tenants === 'all') {
|
|
15
|
+
return { tenant, reach: '', everyTenant: 'on' };
|
|
16
|
+
}
|
|
17
|
+
return { tenant, reach: elevation.tenants.map(assertTenantId).join(','), everyTenant: '' };
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=tenant-setting-values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-setting-values.js","sourceRoot":"","sources":["../../../src/infrastructure/tenancy/tenant-setting-values.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,+CAA+C,CAAC;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAAqC;IAKvE,MAAM,MAAM,GAAG,OAAO,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACvF,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,CAAC;IAErC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;IAChD,CAAC;IAED,IAAI,SAAS,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QAChC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAClD,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,WAAW,EAAE,EAAE,EAAE,CAAC;AAC7F,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three settings of a transaction that the row-level security policies read:
|
|
3
|
+
* `ddd_ts_kit.tenant_id`, the one tenant a write may name (and a read sees);
|
|
4
|
+
* `ddd_ts_kit.reach`, the other tenants an elevation lets a read see, separated by commas; and
|
|
5
|
+
* `ddd_ts_kit.every_tenant`, `on` only for an elevation over every tenant. Work that is not
|
|
6
|
+
* elevated sets the last two empty, so that nothing a tenant id holds can widen a read.
|
|
7
|
+
*/
|
|
8
|
+
export declare const TENANT_SETTINGS: {
|
|
9
|
+
readonly tenant: 'ddd_ts_kit.tenant_id';
|
|
10
|
+
readonly reach: 'ddd_ts_kit.reach';
|
|
11
|
+
readonly everyTenant: 'ddd_ts_kit.every_tenant';
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=tenant-settings.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-settings.d.ts","sourceRoot":"","sources":["../../../src/infrastructure/tenancy/tenant-settings.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,eAAe;aAC1B,MAAM,EAAE,sBAAsB;aAC9B,KAAK,EAAE,kBAAkB;aACzB,WAAW,EAAE,yBAAyB;CAC9B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three settings of a transaction that the row-level security policies read:
|
|
3
|
+
* `ddd_ts_kit.tenant_id`, the one tenant a write may name (and a read sees);
|
|
4
|
+
* `ddd_ts_kit.reach`, the other tenants an elevation lets a read see, separated by commas; and
|
|
5
|
+
* `ddd_ts_kit.every_tenant`, `on` only for an elevation over every tenant. Work that is not
|
|
6
|
+
* elevated sets the last two empty, so that nothing a tenant id holds can widen a read.
|
|
7
|
+
*/
|
|
8
|
+
export const TENANT_SETTINGS = {
|
|
9
|
+
tenant: 'ddd_ts_kit.tenant_id',
|
|
10
|
+
reach: 'ddd_ts_kit.reach',
|
|
11
|
+
everyTenant: 'ddd_ts_kit.every_tenant',
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=tenant-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-settings.js","sourceRoot":"","sources":["../../../src/infrastructure/tenancy/tenant-settings.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,MAAM,EAAE,sBAAsB;IAC9B,KAAK,EAAE,kBAAkB;IACzB,WAAW,EAAE,yBAAyB;CAC9B,CAAC"}
|