@antelopejs/interface-dms 0.10.4 → 0.13.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/CHANGELOG.md +126 -0
- package/README.md +21 -10
- package/dist/attachments.d.ts +15 -2
- package/dist/attachments.js +14 -1
- package/dist/attachments.js.map +1 -1
- package/dist/auth/db/models/sessions.model.d.ts +7 -5
- package/dist/auth/db/models/sessions.model.js +2 -9
- package/dist/auth/db/models/sessions.model.js.map +1 -1
- package/dist/auth/db/models/userExternalIdentities.model.d.ts +7 -5
- package/dist/auth/db/models/users.model.d.ts +7 -5
- package/dist/auth/db/tables/users.table.d.ts +2 -2
- package/dist/auth/db/tables/users.table.js.map +1 -1
- package/dist/auth/index.d.ts +4 -4
- package/dist/auth/internal/jwt-auth-decorator.d.ts +1 -1
- package/dist/auth/internal/jwt-auth-decorator.js +6 -3
- package/dist/auth/internal/jwt-auth-decorator.js.map +1 -1
- package/dist/auth/internal/request-authenticators.d.ts +12 -0
- package/dist/auth/internal/request-authenticators.js +53 -10
- package/dist/auth/internal/request-authenticators.js.map +1 -1
- package/dist/base/activity-feed.d.ts +34 -32
- package/dist/base/activity-feed.js +2 -0
- package/dist/base/activity-feed.js.map +1 -1
- package/dist/base/banner.d.ts +12 -10
- package/dist/base/banner.js +2 -0
- package/dist/base/banner.js.map +1 -1
- package/dist/base/block-registry/internal/describe.js +4 -12
- package/dist/base/block-registry/internal/describe.js.map +1 -1
- package/dist/base/block-registry/internal/ui.js +1 -1
- package/dist/base/block-registry/internal/ui.js.map +1 -1
- package/dist/base/card.d.ts +11 -9
- package/dist/base/card.js +2 -0
- package/dist/base/card.js.map +1 -1
- package/dist/base/chart-card.d.ts +4 -2
- package/dist/base/chart-card.js +2 -0
- package/dist/base/chart-card.js.map +1 -1
- package/dist/base/chart-schemas.d.ts +148 -148
- package/dist/base/chart.d.ts +65 -0
- package/dist/base/chart.js +65 -0
- package/dist/base/chart.js.map +1 -1
- package/dist/base/code-block.d.ts +5 -3
- package/dist/base/code-block.js +2 -0
- package/dist/base/code-block.js.map +1 -1
- package/dist/base/custom.d.ts +5 -0
- package/dist/base/custom.js +5 -0
- package/dist/base/custom.js.map +1 -1
- package/dist/base/data-types/default/address.d.ts +5 -0
- package/dist/base/data-types/default/address.js +5 -0
- package/dist/base/data-types/default/address.js.map +1 -1
- package/dist/base/data-types/default/choices.d.ts +20 -0
- package/dist/base/data-types/default/choices.js +20 -0
- package/dist/base/data-types/default/choices.js.map +1 -1
- package/dist/base/data-types/default/files.d.ts +22 -5
- package/dist/base/data-types/default/files.js +20 -0
- package/dist/base/data-types/default/files.js.map +1 -1
- package/dist/base/data-types/default/numbers.d.ts +15 -0
- package/dist/base/data-types/default/numbers.js +25 -9
- package/dist/base/data-types/default/numbers.js.map +1 -1
- package/dist/base/data-types/default/relations.d.ts +10 -2
- package/dist/base/data-types/default/relations.js +9 -6
- package/dist/base/data-types/default/relations.js.map +1 -1
- package/dist/base/data-types/default/strings.d.ts +25 -0
- package/dist/base/data-types/default/strings.js +25 -0
- package/dist/base/data-types/default/strings.js.map +1 -1
- package/dist/base/data-types/default-types.d.ts +1 -1
- package/dist/base/data-types/field-types.d.ts +10 -0
- package/dist/base/data-types/field-types.js +10 -0
- package/dist/base/data-types/field-types.js.map +1 -1
- package/dist/base/data-types/internal/relation-endpoints.js +1 -0
- package/dist/base/data-types/internal/relation-endpoints.js.map +1 -1
- package/dist/base/data-types/status-type.d.ts +5 -0
- package/dist/base/data-types/status-type.js +5 -0
- package/dist/base/data-types/status-type.js.map +1 -1
- package/dist/base/display.d.ts +6 -6
- package/dist/base/empty-state.d.ts +15 -13
- package/dist/base/empty-state.js +2 -0
- package/dist/base/empty-state.js.map +1 -1
- package/dist/base/form-block-schema.d.ts +50 -50
- package/dist/base/form-schema.d.ts +2 -0
- package/dist/base/form-schema.js +2 -0
- package/dist/base/form-schema.js.map +1 -1
- package/dist/base/grid.d.ts +4 -0
- package/dist/base/grid.js +4 -0
- package/dist/base/grid.js.map +1 -1
- package/dist/base/guard.d.ts +30 -28
- package/dist/base/guard.js +2 -0
- package/dist/base/guard.js.map +1 -1
- package/dist/base/helpers/archive-mode-helpers.d.ts +1 -1
- package/dist/base/helpers/file-refs.js +15 -15
- package/dist/base/helpers/file-refs.js.map +1 -1
- package/dist/base/internal/form-schema-validation.js +7 -1
- package/dist/base/internal/form-schema-validation.js.map +1 -1
- package/dist/base/internal/realtime-topics.js.map +1 -1
- package/dist/base/internal/searchable.d.ts +2 -1
- package/dist/base/internal/searchable.js +1 -3
- package/dist/base/internal/searchable.js.map +1 -1
- package/dist/base/key-value-list.d.ts +21 -19
- package/dist/base/key-value-list.js +2 -0
- package/dist/base/key-value-list.js.map +1 -1
- package/dist/base/kpi-card.d.ts +4 -2
- package/dist/base/kpi-card.js +2 -0
- package/dist/base/kpi-card.js.map +1 -1
- package/dist/base/live-toggle.d.ts +2 -0
- package/dist/base/live-toggle.js +2 -0
- package/dist/base/live-toggle.js.map +1 -1
- package/dist/base/meter.d.ts +23 -21
- package/dist/base/meter.js +2 -0
- package/dist/base/meter.js.map +1 -1
- package/dist/base/nav-card-grid.d.ts +24 -19
- package/dist/base/nav-card-grid.js +5 -0
- package/dist/base/nav-card-grid.js.map +1 -1
- package/dist/base/page-toolbar.d.ts +2 -0
- package/dist/base/page-toolbar.js +2 -0
- package/dist/base/page-toolbar.js.map +1 -1
- package/dist/base/period-selector.d.ts +3 -1
- package/dist/base/period-selector.js +2 -0
- package/dist/base/period-selector.js.map +1 -1
- package/dist/base/placeholder.d.ts +2 -0
- package/dist/base/placeholder.js +2 -0
- package/dist/base/placeholder.js.map +1 -1
- package/dist/base/resource-form-schema.d.ts +2 -2
- package/dist/base/searchable.d.ts +3 -2
- package/dist/base/searchable.js +2 -2
- package/dist/base/searchable.js.map +1 -1
- package/dist/base/section.d.ts +6 -2
- package/dist/base/section.js +4 -0
- package/dist/base/section.js.map +1 -1
- package/dist/base/stack.d.ts +6 -0
- package/dist/base/stack.js +6 -0
- package/dist/base/stack.js.map +1 -1
- package/dist/base/stat-group.d.ts +16 -14
- package/dist/base/stat-group.js +2 -0
- package/dist/base/stat-group.js.map +1 -1
- package/dist/base/tab.d.ts +10 -8
- package/dist/base/tab.js +2 -0
- package/dist/base/tab.js.map +1 -1
- package/dist/base/table-view/column-display.d.ts +1 -1
- package/dist/base/table-view/column-display.js.map +1 -1
- package/dist/base/table-view/data-functions.d.ts +10 -4
- package/dist/base/table-view/data-functions.js.map +1 -1
- package/dist/base/table-view/factory.d.ts +5 -0
- package/dist/base/table-view/factory.js +8 -4
- package/dist/base/table-view/factory.js.map +1 -1
- package/dist/base/table-view/internal/auth.d.ts +17 -3
- package/dist/base/table-view/internal/auth.js +26 -5
- package/dist/base/table-view/internal/auth.js.map +1 -1
- package/dist/base/table-view/internal/column-conditions.d.ts +8 -1
- package/dist/base/table-view/internal/column-conditions.js +25 -13
- package/dist/base/table-view/internal/column-conditions.js.map +1 -1
- package/dist/base/table-view/internal/column-display.d.ts +1 -2
- package/dist/base/table-view/internal/column-display.js +3 -9
- package/dist/base/table-view/internal/column-display.js.map +1 -1
- package/dist/base/table-view/internal/factory-helpers.d.ts +1 -1
- package/dist/base/table-view/internal/factory-helpers.js +17 -14
- package/dist/base/table-view/internal/factory-helpers.js.map +1 -1
- package/dist/base/table-view/internal/factory-lifecycle-created.d.ts +2 -3
- package/dist/base/table-view/internal/factory-lifecycle-created.js +5 -5
- package/dist/base/table-view/internal/factory-lifecycle-created.js.map +1 -1
- package/dist/base/table-view/internal/factory-lifecycle-filter.d.ts +2 -2
- package/dist/base/table-view/internal/factory-private-actions.d.ts +2 -2
- package/dist/base/table-view/internal/files.d.ts +2 -1
- package/dist/base/table-view/internal/files.js +14 -5
- package/dist/base/table-view/internal/files.js.map +1 -1
- package/dist/base/table-view/internal/footer.d.ts +3 -3
- package/dist/base/table-view/internal/footer.js +16 -15
- package/dist/base/table-view/internal/footer.js.map +1 -1
- package/dist/base/table-view/internal/guards.d.ts +27 -5
- package/dist/base/table-view/internal/guards.js +133 -49
- package/dist/base/table-view/internal/guards.js.map +1 -1
- package/dist/base/table-view/internal/meta-helpers.d.ts +1 -1
- package/dist/base/table-view/internal/meta-helpers.js +3 -4
- package/dist/base/table-view/internal/meta-helpers.js.map +1 -1
- package/dist/base/table-view/internal/meta.js +2 -3
- package/dist/base/table-view/internal/meta.js.map +1 -1
- package/dist/base/table-view/internal/option-contract.d.ts +9 -1
- package/dist/base/table-view/internal/option-footer.d.ts +2 -2
- package/dist/base/table-view/internal/option-row-actions.d.ts +1 -1
- package/dist/base/table-view/internal/realtime.d.ts +52 -11
- package/dist/base/table-view/internal/realtime.js +23 -16
- package/dist/base/table-view/internal/realtime.js.map +1 -1
- package/dist/base/table-view/internal/resource-form.d.ts +1 -1
- package/dist/base/table-view/internal/resource-form.js +1 -1
- package/dist/base/table-view/internal/resource-form.js.map +1 -1
- package/dist/base/table-view/internal/row-actions-schema.d.ts +12 -12
- package/dist/base/table-view/internal/row-rule-shape.d.ts +11 -5
- package/dist/base/table-view/internal/row-rule-shape.js +60 -30
- package/dist/base/table-view/internal/row-rule-shape.js.map +1 -1
- package/dist/base/table-view/internal/row-rules.d.ts +28 -1
- package/dist/base/table-view/internal/row-rules.js +8 -19
- package/dist/base/table-view/internal/row-rules.js.map +1 -1
- package/dist/base/table-view/internal/tabs.d.ts +1 -1
- package/dist/base/table-view/internal/tabs.js +1 -4
- package/dist/base/table-view/internal/tabs.js.map +1 -1
- package/dist/base/table-view/internal/validation.d.ts +2 -2
- package/dist/base/table-view/internal/validation.js +7 -7
- package/dist/base/table-view/internal/validation.js.map +1 -1
- package/dist/base/table-view/meta.d.ts +7 -6
- package/dist/base/table-view/meta.js +12 -7
- package/dist/base/table-view/meta.js.map +1 -1
- package/dist/base/table-view/resource-form.d.ts +3 -1
- package/dist/base/table-view/resource-form.js +2 -0
- package/dist/base/table-view/resource-form.js.map +1 -1
- package/dist/base/table-view/routes.d.ts +73 -21
- package/dist/base/table-view/routes.js +13 -10
- package/dist/base/table-view/routes.js.map +1 -1
- package/dist/base/table-view/schema.d.ts +157 -152
- package/dist/base/table-view/schema.js +2 -1
- package/dist/base/table-view/schema.js.map +1 -1
- package/dist/base/table-view/source.js +4 -1
- package/dist/base/table-view/source.js.map +1 -1
- package/dist/base/table-view.d.ts +1 -1
- package/dist/base/table-view.js.map +1 -1
- package/dist/base/top-list-card.d.ts +35 -33
- package/dist/base/top-list-card.js +2 -0
- package/dist/base/top-list-card.js.map +1 -1
- package/dist/base/types/error.js +5 -2
- package/dist/base/types/error.js.map +1 -1
- package/dist/base/types/guards.d.ts +4 -4
- package/dist/base/types/json.d.ts +1 -10
- package/dist/base/types/row-action.d.ts +7 -7
- package/dist/component-options/confirm-dialog.d.ts +2 -0
- package/dist/component-options/confirm-dialog.js.map +1 -1
- package/dist/component-options/data-type.d.ts +2 -2
- package/dist/component-options/data-type.js +7 -7
- package/dist/component-options/data-type.js.map +1 -1
- package/dist/component-options/page-layout.d.ts +3 -2
- package/dist/component-options/page-layout.js.map +1 -1
- package/dist/component-options/row-action.d.ts +14 -9
- package/dist/component-slots.d.ts +11 -2
- package/dist/component-slots.js +1 -0
- package/dist/component-slots.js.map +1 -1
- package/dist/component.d.ts +7 -8
- package/dist/component.js +17 -25
- package/dist/component.js.map +1 -1
- package/dist/data-controllers/members.d.ts +11 -7
- package/dist/data-controllers/members.js +1 -1
- package/dist/data-controllers/members.js.map +1 -1
- package/dist/data-controllers/roles.d.ts +32 -10
- package/dist/db/internal/exportJobs.model.d.ts +7 -5
- package/dist/db/internal/inviteResolutions.model.d.ts +7 -5
- package/dist/db/internal/tenantLifecycle.model.d.ts +15 -7
- package/dist/db/internal/tenantLifecycle.model.js +16 -7
- package/dist/db/internal/tenantLifecycle.model.js.map +1 -1
- package/dist/db/models/roles.model.d.ts +7 -5
- package/dist/db/models/tenantMembers.model.d.ts +7 -5
- package/dist/db/models/tenants.model.d.ts +7 -5
- package/dist/db/models/user_invites.model.d.ts +7 -5
- package/dist/guards.d.ts +1 -1
- package/dist/hooks.d.ts +1 -2
- package/dist/hooks.js +33 -26
- package/dist/hooks.js.map +1 -1
- package/dist/internal/attachments.d.ts +2 -2
- package/dist/internal/component-builder.js +2 -1
- package/dist/internal/component-builder.js.map +1 -1
- package/dist/internal/component-serialization.d.ts +2 -4
- package/dist/internal/component-serialization.js +4 -3
- package/dist/internal/component-serialization.js.map +1 -1
- package/dist/internal/component-slots.d.ts +19 -2
- package/dist/internal/component-slots.js +35 -12
- package/dist/internal/component-slots.js.map +1 -1
- package/dist/internal/component-watch-filter.d.ts +11 -0
- package/dist/internal/component-watch-filter.js +22 -0
- package/dist/internal/component-watch-filter.js.map +1 -0
- package/dist/internal/component-watches.js +0 -1
- package/dist/internal/component-watches.js.map +1 -1
- package/dist/internal/own-entry.d.ts +7 -0
- package/dist/internal/own-entry.js +13 -0
- package/dist/internal/own-entry.js.map +1 -0
- package/dist/internal/uploads.d.ts +30 -0
- package/dist/internal/uploads.js +19 -0
- package/dist/internal/uploads.js.map +1 -1
- package/dist/invite-extension-payloads.d.ts +14 -2
- package/dist/invite-extensions/internal/delivery.js +1 -2
- package/dist/invite-extensions/internal/delivery.js.map +1 -1
- package/dist/invite-extensions/internal/edit.d.ts +2 -1
- package/dist/invite-extensions/internal/edit.js +8 -9
- package/dist/invite-extensions/internal/edit.js.map +1 -1
- package/dist/invite-extensions/internal/form-slot.js +8 -15
- package/dist/invite-extensions/internal/form-slot.js.map +1 -1
- package/dist/invite-extensions/internal/payload-slices.d.ts +33 -3
- package/dist/invite-extensions/internal/payload-slices.js +84 -19
- package/dist/invite-extensions/internal/payload-slices.js.map +1 -1
- package/dist/invite-extensions/internal/types.d.ts +10 -1
- package/dist/invite-resolution.js +6 -4
- package/dist/invite-resolution.js.map +1 -1
- package/dist/json.d.ts +10 -0
- package/dist/json.js +3 -0
- package/dist/json.js.map +1 -0
- package/dist/layout-banners.d.ts +5 -2
- package/dist/layout-banners.js.map +1 -1
- package/dist/page/controllers.d.ts +2 -2
- package/dist/page/internal/extension-validation.js +3 -2
- package/dist/page/internal/extension-validation.js.map +1 -1
- package/dist/page/internal/metadata-layout.js +1 -1
- package/dist/page/internal/metadata-layout.js.map +1 -1
- package/dist/page/internal/metadata-publish.js +3 -2
- package/dist/page/internal/metadata-publish.js.map +1 -1
- package/dist/page/internal/metadata-registration.js +5 -4
- package/dist/page/internal/metadata-registration.js.map +1 -1
- package/dist/page/internal/metadata-upload-registration.d.ts +4 -2
- package/dist/page/internal/metadata-upload-registration.js +13 -4
- package/dist/page/internal/metadata-upload-registration.js.map +1 -1
- package/dist/page/internal/metadata-uploads.d.ts +5 -5
- package/dist/page/internal/metadata-uploads.js +4 -8
- package/dist/page/internal/metadata-uploads.js.map +1 -1
- package/dist/page/internal/page-record.d.ts +2 -3
- package/dist/page/internal/page-record.js +23 -16
- package/dist/page/internal/page-record.js.map +1 -1
- package/dist/page/layout-filter.js +17 -6
- package/dist/page/layout-filter.js.map +1 -1
- package/dist/page/metadata.js +5 -7
- package/dist/page/metadata.js.map +1 -1
- package/dist/request-tenant.d.ts +10 -4
- package/dist/request-tenant.js +16 -34
- package/dist/request-tenant.js.map +1 -1
- package/dist/tenant-export.d.ts +2 -1
- package/dist/tenant-lifecycle.d.ts +43 -4
- package/dist/tenant-lifecycle.js +97 -18
- package/dist/tenant-lifecycle.js.map +1 -1
- package/dist/types.d.ts +20 -0
- package/dist/uploads.d.ts +1 -1
- package/dist/uploads.js +39 -60
- package/dist/uploads.js.map +1 -1
- package/dist/utils/fire-and-forget.js.map +1 -1
- package/dist/utils/internal/decorated-class.d.ts +14 -0
- package/dist/utils/internal/decorated-class.js +37 -0
- package/dist/utils/internal/decorated-class.js.map +1 -0
- package/dist/utils/internal/type-check.d.ts +9 -0
- package/dist/utils/internal/type-check.js +13 -5
- package/dist/utils/internal/type-check.js.map +1 -1
- package/dist/utils/internal/value-parser.d.ts +1 -1
- package/dist/utils/internal/value-parser.js +22 -9
- package/dist/utils/internal/value-parser.js.map +1 -1
- package/dist/watch-actions.d.ts +1 -1
- package/docs/1.core/1.introduction.md +82 -77
- package/docs/1.core/10.layout-banners.md +57 -45
- package/docs/1.core/11.modules-and-dynamic-menus.md +178 -0
- package/docs/1.core/12.frontend-modules-and-request-helpers.md +155 -0
- package/docs/1.core/13.tenant-data-export.md +120 -0
- package/docs/1.core/2.pages-and-modules.md +140 -367
- package/docs/1.core/3.components.md +21 -22
- package/docs/1.core/4.permissions.md +92 -71
- package/docs/1.core/5.tenancy.md +150 -86
- package/docs/1.core/6.invites.md +90 -65
- package/docs/1.core/7.hooks.md +96 -166
- package/docs/1.core/8.realtime.md +44 -45
- package/docs/1.core/9.quick-actions.md +37 -30
- package/docs/2.auth/1.introduction.md +33 -35
- package/docs/2.auth/2.authentication.md +60 -38
- package/docs/2.auth/3.tokens-and-sessions.md +56 -55
- package/docs/2.auth/4.users.md +79 -51
- package/docs/2.auth/5.external-identities.md +25 -26
- package/docs/3.base/1.introduction.md +64 -60
- package/docs/3.base/10.display-blocks.md +15 -16
- package/docs/3.base/11.page-layouts.md +270 -0
- package/docs/3.base/12.table-row-actions.md +122 -0
- package/docs/3.base/13.table-filters-and-forms.md +104 -0
- package/docs/3.base/14.table-events-and-helpers.md +114 -0
- package/docs/3.base/15.table-sources-and-gates.md +24 -0
- package/docs/3.base/2.types.md +44 -41
- package/docs/3.base/3.forms.md +27 -28
- package/docs/3.base/4.tables.md +35 -368
- package/docs/3.base/5.charts-and-widgets.md +28 -29
- package/docs/3.base/6.layout.md +21 -270
- package/docs/3.base/8.data-types.md +39 -40
- package/docs/3.base/9.helpers.md +36 -38
- package/docs/4.notifications/1.introduction.md +22 -26
- package/docs/4.notifications/2.categories-and-subjects.md +58 -55
- package/docs/4.notifications/3.sending.md +72 -68
- package/docs/5.html-render/1.introduction.md +119 -81
- package/docs/5.html-render/2.built-in-emails.md +71 -51
- package/docs/index.md +18 -29
- package/docs/tsconfig.json +4 -0
- package/package.json +11 -11
- package/docs/images/emails-admin-invite.png +0 -0
- package/docs/images/emails-change-notice.png +0 -0
- package/docs/images/emails-change-verification.png +0 -0
- package/docs/images/emails-digest-logo-dark.png +0 -0
- package/docs/images/emails-digest-logo-light.png +0 -0
- package/docs/images/emails-digest.png +0 -0
- package/docs/images/emails-export-partial.png +0 -0
- package/docs/images/emails-export-ready.png +0 -0
- package/docs/images/emails-reset-password.png +0 -0
- package/docs/images/emails-two-factor.png +0 -0
- package/docs/images/emails-user-validation.png +0 -0
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: "Data
|
|
2
|
+
title: "Data types"
|
|
3
3
|
description: "A data type is the single object that answers everything the DMS needs to know about one value: which input component edits it, which Zod schema validates it, which comparison modes its filter offers, and whether the…"
|
|
4
|
+
mode: reference
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
# Data Types
|
|
7
|
-
|
|
8
7
|
## Overview
|
|
9
8
|
|
|
10
9
|
A data type is the single object that answers everything the DMS needs to know about one value: which input component edits it, which Zod schema validates it, which comparison modes its filter offers, and whether the field it sits on needs extra decorators. `FormField.type` and `ColumnOptions.type` both take one, which is why a form field and a table column of the same type behave identically.
|
|
@@ -20,11 +19,11 @@ import {
|
|
|
20
19
|
} from "@antelopejs/interface-dms/base/data-types";
|
|
21
20
|
```
|
|
22
21
|
|
|
23
|
-
The `data-types` subpath re-exports the built-in catalogues, so `DefaultDataTypes`, `DefaultDataCompareTypes` and `StatusType` are all reachable from it. They also have their own modules
|
|
22
|
+
The `data-types` subpath re-exports the built-in catalogues, so `DefaultDataTypes`, `DefaultDataCompareTypes` and `StatusType` are all reachable from it. They also have their own modules, `data-types/default-types`, `data-types/compare-types` and `data-types/status-type`, and much of the DMS imports them from there.
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
The `base` barrel does **not** re-export the data types. Import them from the `data-types` subpath.
|
|
26
25
|
|
|
27
|
-
## Use a
|
|
26
|
+
## Use a data type
|
|
28
27
|
|
|
29
28
|
Instantiate the type with its options and hand the instance to the field or the column.
|
|
30
29
|
|
|
@@ -57,9 +56,9 @@ const form = Form({
|
|
|
57
56
|
|
|
58
57
|
An instance is reusable: the same object can back a form field and a table column, since it holds only its configuration.
|
|
59
58
|
|
|
60
|
-
## The DataType
|
|
59
|
+
## The `DataType` contract
|
|
61
60
|
|
|
62
|
-
```typescript
|
|
61
|
+
```typescript fragment
|
|
63
62
|
abstract class DataType {
|
|
64
63
|
constructor(
|
|
65
64
|
readonly compareModes: Class<DataCompareMode>[] = [],
|
|
@@ -89,9 +88,9 @@ abstract class DataType {
|
|
|
89
88
|
| `describedInputComponent()` | The input as it is described where nothing is entered through it: a table column's type (its cells, cards and quick filters read the options) and a read-only form field. Defaults to `inputComponent()`; a type leaves out what only an editable control uses, as a relation leaves out its add form. |
|
|
90
89
|
| `filterComponents()` | The filter inputs, keyed by compare-mode id with a mandatory `default`. Defaults to `{ default: defaultInputComponent() }`. |
|
|
91
90
|
| `filter()` | Applies a filter for one compare mode. The base implementation looks the mode up in the compare-mode registry and delegates to it; a type overrides it when a mode needs different semantics. |
|
|
92
|
-
| `decorateField()` | Optional. Called by the `@Column` decorator so the type can add further decorators to the field
|
|
91
|
+
| `decorateField()` | Optional. Called by the `@Column` decorator so the type can add further decorators to the field. The relation types install their join this way. |
|
|
93
92
|
|
|
94
|
-
### Write a
|
|
93
|
+
### Write a custom type
|
|
95
94
|
|
|
96
95
|
`StatusType` is the smallest complete example: a boolean rendered as an online/offline indicator whose labels and colours are configurable.
|
|
97
96
|
|
|
@@ -122,13 +121,13 @@ export class StatusType extends DataType {
|
|
|
122
121
|
super(
|
|
123
122
|
[DefaultDataCompareTypes.Is, DefaultDataCompareTypes.IsNot],
|
|
124
123
|
DefaultDataCompareTypes.Is,
|
|
125
|
-
options
|
|
124
|
+
options,
|
|
126
125
|
);
|
|
127
126
|
}
|
|
128
127
|
|
|
129
128
|
protected defaultInputComponent() {
|
|
130
129
|
const component = FormComponents.InputCheckbox();
|
|
131
|
-
component.options = this.options;
|
|
130
|
+
component.options = { label: this.options.onlineLabel };
|
|
132
131
|
return component;
|
|
133
132
|
}
|
|
134
133
|
|
|
@@ -138,32 +137,32 @@ export class StatusType extends DataType {
|
|
|
138
137
|
}
|
|
139
138
|
```
|
|
140
139
|
|
|
141
|
-
Three pieces make it a type: the `@RegisterDataType("status")` decorator puts it in the registry under an id, the `super()` call declares the compare modes and stores the options, and the two abstract members supply the input and the schema. `StatusType` itself is exported by the `data-types` subpath and is one of the three column types a kanban board can group by
|
|
140
|
+
Three pieces make it a type: the `@RegisterDataType("status")` decorator puts it in the registry under an id, the `super()` call declares the compare modes and stores the options, and the two abstract members supply the input and the schema. `StatusType` itself is exported by the `data-types` subpath and is one of the three column types a kanban board can group by. See [Tables](/docs/interfaces/base/tables).
|
|
142
141
|
|
|
143
|
-
## The
|
|
142
|
+
## The registry
|
|
144
143
|
|
|
145
|
-
### RegisterDataType
|
|
144
|
+
### `RegisterDataType`
|
|
146
145
|
|
|
147
|
-
```typescript
|
|
146
|
+
```typescript fragment
|
|
148
147
|
const RegisterDataType: (id: string) => ClassDecorator<Class<DataType>>;
|
|
149
148
|
```
|
|
150
149
|
|
|
151
|
-
Registers the decorated class under `id`, in both directions: `CreateDataType` looks up the class by id, and `getDataTypeId` recovers the id from an instance. An id must be unique
|
|
150
|
+
Registers the decorated class under `id`, in both directions: `CreateDataType` looks up the class by id, and `getDataTypeId` recovers the id from an instance. An id must be unique. Registering twice under the same string replaces the earlier class.
|
|
152
151
|
|
|
153
|
-
### RegisterDataCompareMode
|
|
152
|
+
### `RegisterDataCompareMode`
|
|
154
153
|
|
|
155
|
-
```typescript
|
|
154
|
+
```typescript fragment
|
|
156
155
|
const RegisterDataCompareMode: (
|
|
157
156
|
id: string,
|
|
158
157
|
noInput?: boolean,
|
|
159
158
|
) => ClassDecorator<Class<DataCompareMode>>;
|
|
160
159
|
```
|
|
161
160
|
|
|
162
|
-
Registers a compare mode. The decorator instantiates the class immediately and keeps that single instance, so a compare mode is stateless. `noInput` marks a mode that needs no value from the viewer
|
|
161
|
+
Registers a compare mode. The decorator instantiates the class immediately and keeps that single instance, so a compare mode is stateless. `noInput` marks a mode that needs no value from the viewer. `serializeType` replaces its filter component with the literal `"noInput"`.
|
|
163
162
|
|
|
164
163
|
`DataCompareMode` is the interface a mode implements:
|
|
165
164
|
|
|
166
|
-
```typescript
|
|
165
|
+
```typescript fragment
|
|
167
166
|
interface DataCompareMode {
|
|
168
167
|
filter(
|
|
169
168
|
context: RequestContext,
|
|
@@ -177,17 +176,17 @@ interface DataCompareMode {
|
|
|
177
176
|
|
|
178
177
|
`proxy` is the database value proxy for the field being filtered and `row` the proxy for the whole row, both from `@antelopejs/interface-database`, so a mode builds a database-side predicate rather than filtering in memory.
|
|
179
178
|
|
|
180
|
-
### CreateDataType
|
|
179
|
+
### `CreateDataType`
|
|
181
180
|
|
|
182
|
-
```typescript
|
|
181
|
+
```typescript fragment
|
|
183
182
|
function CreateDataType(id: string, options?: unknown): DataType;
|
|
184
183
|
```
|
|
185
184
|
|
|
186
|
-
Instantiates a registered type by id, forwarding `options` to its constructor. It asserts on an unknown id with the message `Unknown type <id>`. Use it when the type is chosen at runtime
|
|
185
|
+
Instantiates a registered type by id, forwarding `options` to its constructor. It asserts on an unknown id with the message `Unknown type <id>`. Use it when the type is chosen at runtime, from configuration or from a description another module produced, rather than written in the source.
|
|
187
186
|
|
|
188
|
-
### getDataTypeId
|
|
187
|
+
### `getDataTypeId`
|
|
189
188
|
|
|
190
|
-
```typescript
|
|
189
|
+
```typescript fragment
|
|
191
190
|
function getDataTypeId(instance: DataType): string | undefined;
|
|
192
191
|
```
|
|
193
192
|
|
|
@@ -195,7 +194,7 @@ Returns the id an instance's class was registered under, or `undefined` when the
|
|
|
195
194
|
|
|
196
195
|
## Serialization
|
|
197
196
|
|
|
198
|
-
```typescript
|
|
197
|
+
```typescript fragment
|
|
199
198
|
function serializeType(instance?: DataType): DataTypeSerialized | undefined;
|
|
200
199
|
```
|
|
201
200
|
|
|
@@ -211,9 +210,9 @@ function serializeType(instance?: DataType): DataTypeSerialized | undefined;
|
|
|
211
210
|
| `filterComponents` | `Record<string, FilterComponent>` | Filter inputs by mode id, from `filterComponents()`, with every `noInput` mode's entry replaced by the literal `"noInput"`. |
|
|
212
211
|
| `inputComponent` | `ComponentInfoSerialized` | The input the column's cells and quick filters read the options of, from `describedInputComponent()`. |
|
|
213
212
|
|
|
214
|
-
`FilterComponent` is `ComponentInfoSerialized | "noInput"`. The value-level counterpart, `ComponentOrNoInput`, is described in [Shared
|
|
213
|
+
`FilterComponent` is `ComponentInfoSerialized | "noInput"`. The value-level counterpart, `ComponentOrNoInput`, is described in [Shared types](/docs/interfaces/base/types).
|
|
215
214
|
|
|
216
|
-
## Compare
|
|
215
|
+
## Compare modes
|
|
217
216
|
|
|
218
217
|
`DefaultDataCompareTypes` holds the built-in modes. Each entry is a class; you reference the class in a type's `compareModes`, and the string id is what appears in a serialized type and in a filter query.
|
|
219
218
|
|
|
@@ -238,7 +237,7 @@ The ordering modes and `is_between` send a date value to the value proxy as epoc
|
|
|
238
237
|
|
|
239
238
|
`IsEmpty` and `IsNotEmpty` are the two registered with `noInput`. `Include`, `Exclude` and `ArrayContainsString` read a `null` or missing list as an empty one, so a row saved without a value never fails the query: it is left out by `include` and `array_contains_string`, and kept by `exclude`. The namespace also exports `escapeRegex(str: string): string`, the helper the substring modes use to make a viewer-supplied value safe inside a pattern.
|
|
240
239
|
|
|
241
|
-
## The
|
|
240
|
+
## The default types
|
|
242
241
|
|
|
243
242
|
`DefaultDataTypes` is the built-in catalogue. Every class takes its options object as its only constructor argument, and most of them accept a `fallback` string used in place of an empty value.
|
|
244
243
|
|
|
@@ -264,7 +263,7 @@ The ordering modes and `is_between` send a date value to the value proxy as epoc
|
|
|
264
263
|
| `FileType` | `file` | none | file upload |
|
|
265
264
|
| `ImageType` | `image` | none | image upload |
|
|
266
265
|
|
|
267
|
-
### Scalar
|
|
266
|
+
### Scalar types
|
|
268
267
|
|
|
269
268
|
| Options interface | Fields |
|
|
270
269
|
| --- | --- |
|
|
@@ -293,13 +292,13 @@ Notes on the ones whose behaviour is not obvious from the options:
|
|
|
293
292
|
- `PercentageType` is a `NumberType` whose options default to `min: 0`, `max: 1` and `step: 0.01`; the stored value is a fraction while the input works in whole percent.
|
|
294
293
|
- `PhoneType` only validates the E.164 pattern when `requiredPrefix` is set; otherwise any string passes.
|
|
295
294
|
- `ColorType` validates a six-digit `#RRGGBB` string.
|
|
296
|
-
- `StringTimeType` validates a **number
|
|
295
|
+
- `StringTimeType` validates a **number**: a time of day expressed as a number, bounded by `min` and `max`.
|
|
297
296
|
|
|
298
297
|
### Relations
|
|
299
298
|
|
|
300
|
-
`RelationType<T>` points a field at another data controller. Its input is a searchable picker whose `searchUrl` is the target controller's `select` endpoint
|
|
299
|
+
`RelationType<T>` points a field at another data controller. Its input is a searchable picker whose `searchUrl` is the target controller's `select` endpoint. Unless `filterOnly` is set, its `decorateField` installs a data-api `Foreign` join so list rows carry the resolved related row instead of the raw foreign key.
|
|
301
300
|
|
|
302
|
-
```typescript
|
|
301
|
+
```typescript fragment
|
|
303
302
|
import { DefaultDataTypes } from "@antelopejs/interface-dms/base/data-types";
|
|
304
303
|
import { Column } from "@antelopejs/interface-dms/base/table-view";
|
|
305
304
|
|
|
@@ -329,9 +328,9 @@ declare customerId: string;
|
|
|
329
328
|
|
|
330
329
|
With `filterBy`, the picker sends the table filter syntax to the `select` endpoint (`filter_<field>=is:<value>`), which honors only the filters the target controller declares. It searches again when `from` changes and clears a pick made for its previous value; the pair a record loaded with is kept, and while `from` is empty every row is offered. It narrows what is offered only: a rule that must hold on save belongs to the module's routes.
|
|
331
330
|
|
|
332
|
-
When the target controller exposes a `new` endpoint and has form fields, the picker of an editable form field also carries an inline "add" form built from the target's `new` fields, plus the permission id of the target's `add` action. That form
|
|
331
|
+
When the target controller exposes a `new` endpoint and has form fields, the picker of an editable form field also carries an inline "add" form built from the target's `new` fields, plus the permission id of the target's `add` action. That form (the target's fields, its validation schema, its own relations' add forms) is the bulk of the component, so a table column's type, its filter and a read-only field leave it out: they read the related rows through the `select` route, and a filter only picks among them.
|
|
333
332
|
|
|
334
|
-
`CascaderRelationType<T>` is the same idea for a self-referencing table: the target's `select` endpoint returns a flat list, and the widget rebuilds the tree client-side. Its cell and its field name the picked row by its path, read by `?ids=` for the picked rows and then each level of their ancestors. Its `keyMapping` is required and adds `parent
|
|
333
|
+
`CascaderRelationType<T>` is the same idea for a self-referencing table: the target's `select` endpoint returns a flat list, and the widget rebuilds the tree client-side. Its cell and its field name the picked row by its path, read by `?ids=` for the picked rows and then each level of their ancestors. Its `keyMapping` is required and adds `parent`, the field pointing at the parent row, which must itself carry `@Select()`, alongside the required `label` and `value`. It adds `maxDepth` and `leafOnly` to the relation options, and supports the same `filterOnly` behaviour. In a table cell it shows the path of the picked node ("Electronics / Audio"); a `multiple` one shows a badge per picked node, named by its own label with its path on hover, and folds those past three into `+N`.
|
|
335
334
|
|
|
336
335
|
### Address
|
|
337
336
|
|
|
@@ -358,14 +357,14 @@ The type's options are `placeholder` (one string per address component), `autoco
|
|
|
358
357
|
| `limit` | `number` | Maximum number of suggestions. Defaults to `5`. |
|
|
359
358
|
| `placeholder` | `string` | Search field placeholder. |
|
|
360
359
|
|
|
361
|
-
### Files and
|
|
360
|
+
### Files and images
|
|
362
361
|
|
|
363
362
|
`FileTypeOptions` has `multiple?`, `constraints?: UploadConstraints`, `path?`, `storage?` and `fallback?`. `ImageTypeOptions` has `multiple?`, `max?`, `constraints?`, `path?`, `storage?` and `resize?`, the `FormComponents.ImageResizeOptions` the input applies client-side before uploading ([Forms](/docs/interfaces/base/forms)). Both accept `attachmentField?` for a stable native field identity and `visibility?: "private" | "public"`, defaulting to private. `constraints` is the `UploadConstraints` type from `@antelopejs/interface-file-storage`; `storage` names the storage backend and `path` the prefix uploads land under.
|
|
364
363
|
|
|
365
|
-
A file value is the resource key as a string. Metadata-based validation checks configured constraints, matching `allowedMimetypes` patterns including the `type/*` form. A native field's save integration also validates upload provenance and canonical metadata before persistence. Existing unclassified legacy values may be retained, but cannot be introduced as new native attachments or read through the native metadata endpoint. A storage outage propagates as a server error rather than becoming a field validation error. An image value is an `ImageValue
|
|
364
|
+
A file value is the resource key as a string. Metadata-based validation checks configured constraints, matching `allowedMimetypes` patterns including the `type/*` form. A native field's save integration also validates upload provenance and canonical metadata before persistence. Existing unclassified legacy values may be retained, but cannot be introduced as new native attachments or read through the native metadata endpoint. A storage outage propagates as a server error rather than becoming a field validation error. An image value is an `ImageValue`, `{ key: string; alt?: string; principal?: boolean }`, and `ImageType` defaults `allowedMimetypes` to `["image/*"]`, caps the array at `max` when `multiple` is set, and rejects a list with more than one `principal` image.
|
|
366
365
|
|
|
367
366
|
Both types enable the table view's native file handling: authorized saves promote staging keys, and successful edits or deletes clean removed native references. Failed saves retain promoted objects; cleanup is not reference-counted across records. See [File storage](/docs/components/file-storage) for authorization, visibility, retries, and custom save routes, and [Helpers](/docs/interfaces/base/helpers) for comparing references within records.
|
|
368
367
|
|
|
369
|
-
## Next
|
|
368
|
+
## Next steps
|
|
370
369
|
|
|
371
|
-
- [Helpers](/docs/interfaces/base/helpers)
|
|
370
|
+
- [Helpers](/docs/interfaces/base/helpers): Search, export jobs, file references and the archive-mode defaults.
|
package/docs/3.base/9.helpers.md
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Helpers"
|
|
3
3
|
description: "A few small surfaces sit beside the components and support them: the `@Searchable` decorator that tells a list route which columns free-text search covers, the export-job runner behind every long download, the…"
|
|
4
|
+
mode: reference
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
# Helpers
|
|
7
|
-
|
|
8
7
|
## Overview
|
|
9
8
|
|
|
10
|
-
A few small surfaces sit beside the components and support them: the `@Searchable` decorator that tells a list route which columns free-text search covers, the export-job runner behind every long download, the tenant-export archive built on top of it, and two helper modules
|
|
9
|
+
A few small surfaces sit beside the components and support them: the `@Searchable` decorator that tells a list route which columns free-text search covers, the export-job runner behind every long download, the tenant-export archive built on top of it, and two helper modules, file references and archive-mode defaults, that the table view uses internally and that are available when you build equivalent routes yourself.
|
|
11
10
|
|
|
12
11
|
```typescript
|
|
13
12
|
import { Searchable, SearchableMeta } from "@antelopejs/interface-dms/base/searchable";
|
|
@@ -19,11 +18,11 @@ import { startTenantExportJob } from "@antelopejs/interface-dms/base/tenant-expo
|
|
|
19
18
|
|
|
20
19
|
`Searchable`, `SearchableMeta` and everything in `export-jobs` and `tenant-export-archive` are also exported from the package root, `@antelopejs/interface-dms/base`. The two `helpers/*` modules are not in that barrel and are imported from their own subpath.
|
|
21
20
|
|
|
22
|
-
## Make
|
|
21
|
+
## Make columns searchable
|
|
23
22
|
|
|
24
23
|
`@Searchable(compareMode?)` is a property decorator on a data controller field. It records the field, and the compare mode used to match it, on the controller's `SearchableMeta`. The list route reads that record when the request carries a `search` query parameter and ORs one condition per recorded field into the query. A field does not have to be `filterable` to be searched: it is matched with its data-api filter when it has one, and otherwise with the filter of its `@Column` type. A controller with no searchable field ignores the parameter.
|
|
25
24
|
|
|
26
|
-
```typescript
|
|
25
|
+
```typescript fragment
|
|
27
26
|
import { Listable } from "@antelopejs/interface-data-api/metadata";
|
|
28
27
|
import { DefaultDataTypes } from "@antelopejs/interface-dms/base/data-types";
|
|
29
28
|
import { Searchable } from "@antelopejs/interface-dms/base/searchable";
|
|
@@ -50,9 +49,9 @@ export class customerDataAPI extends DataController(/* … */) {
|
|
|
50
49
|
| --- | --- |
|
|
51
50
|
| `compareMode` | Id of a registered `DataCompareMode` used to match this field. Defaults to `"contains"`. |
|
|
52
51
|
|
|
53
|
-
The id is the one the mode was registered under with `@RegisterDataCompareMode
|
|
52
|
+
The id is the one the mode was registered under with `@RegisterDataCompareMode`. `"contains"`, `"is"`, `"array_contains_string"` and the rest of the catalog are listed in [Data types](/docs/interfaces/base/data-types).
|
|
54
53
|
|
|
55
|
-
### SearchableMeta
|
|
54
|
+
### `SearchableMeta`
|
|
56
55
|
|
|
57
56
|
`SearchableMeta` is the metadata object the decorator writes to. Read it with `GetMetadata(controller, SearchableMeta)` from `@antelopejs/interface-core`.
|
|
58
57
|
|
|
@@ -62,7 +61,7 @@ The id is the one the mode was registered under with `@RegisterDataCompareMode`
|
|
|
62
61
|
| `setSearchableField(key, compareMode)` | Records one field. Called by the decorator. |
|
|
63
62
|
| `getSearchableFields()` | Returns the same record. |
|
|
64
63
|
|
|
65
|
-
## Run an
|
|
64
|
+
## Run an export job
|
|
66
65
|
|
|
67
66
|
`runExportJob` starts a background job, hands you a ticket immediately, and leaves the generation running. The pattern is three routes: one that starts the job, one that reports its progress, one that streams the finished file. The table view's export action is built on exactly these three, and any route of your own can reuse them.
|
|
68
67
|
|
|
@@ -133,9 +132,9 @@ export class ReportPage extends PageController("report", {
|
|
|
133
132
|
}
|
|
134
133
|
```
|
|
135
134
|
|
|
136
|
-
### RunExportJobOptions
|
|
135
|
+
### `RunExportJobOptions`
|
|
137
136
|
|
|
138
|
-
```typescript
|
|
137
|
+
```typescript fragment
|
|
139
138
|
function runExportJob<TContext = unknown>(
|
|
140
139
|
opts: RunExportJobOptions<TContext>,
|
|
141
140
|
): Promise<ExportJobTicket>;
|
|
@@ -172,7 +171,7 @@ interface ExportJobFailure {
|
|
|
172
171
|
}
|
|
173
172
|
```
|
|
174
173
|
|
|
175
|
-
The summary is stored on the job and surfaced on its status, so a consumer can tell a complete export from one that succeeded with holes. `source` names the part that failed
|
|
174
|
+
The summary is stored on the job and surfaced on its status, so a consumer can tell a complete export from one that succeeded with holes. `source` names the part that failed, usually a contributing module id.
|
|
176
175
|
|
|
177
176
|
By default a job is deleted once it has been downloaded. Set `retainUntilExpiry` for a scope whose jobs outlive their first download: one that surfaces a job history, or one whose result is reached through a delivered link.
|
|
178
177
|
|
|
@@ -182,7 +181,7 @@ By default a job is deleted once it has been downloaded. Set `retainUntilExpiry`
|
|
|
182
181
|
| `extension` | `string` | Echo of the requested extension. |
|
|
183
182
|
| `filename` | `string` | Echo of the requested base name. |
|
|
184
183
|
|
|
185
|
-
### ExportJobGenerateContext
|
|
184
|
+
### `ExportJobGenerateContext`
|
|
186
185
|
|
|
187
186
|
| Field | Type | Description |
|
|
188
187
|
| --- | --- | --- |
|
|
@@ -190,12 +189,12 @@ By default a job is deleted once it has been downloaded. Set `retainUntilExpiry`
|
|
|
190
189
|
| `tenantId` | `string` | Tenant the job belongs to. |
|
|
191
190
|
| `localPath` | `string` | Path your generator writes the file to. |
|
|
192
191
|
| `context` | `TContext` | The payload passed as `context` to `runExportJob`. |
|
|
193
|
-
| `reportProgress` | `(progress: number) => Promise<void>` | Records progress. The value is floored and clamped to `0
|
|
192
|
+
| `reportProgress` | `(progress: number) => Promise<void>` | Records progress. The value is floored and clamped to `0` through `99`; repeating the last value writes nothing. Throws once the job is aborted. |
|
|
194
193
|
| `signal` | `AbortSignal` | Aborted when the job exceeds `maxExecutionTimeMs`. |
|
|
195
194
|
|
|
196
|
-
### Status and
|
|
195
|
+
### Status and download
|
|
197
196
|
|
|
198
|
-
```typescript
|
|
197
|
+
```typescript fragment
|
|
199
198
|
function getExportJobStatus<TContext = unknown>(
|
|
200
199
|
ctx: RequestContext,
|
|
201
200
|
user: User,
|
|
@@ -211,19 +210,19 @@ function downloadExportJob<TContext = unknown>(
|
|
|
211
210
|
): Promise<void>;
|
|
212
211
|
```
|
|
213
212
|
|
|
214
|
-
`ExportJobStatus` carries `status: ExportStatus`, `progress: number`, and the optional `error`, `filename`, `extension`, `result` and `expiresAt`. `ExportStatus` is the `pending` / `completed` / `failed` enum from [Shared
|
|
213
|
+
`ExportJobStatus` carries `status: ExportStatus`, `progress: number`, and the optional `error`, `filename`, `extension`, `result` and `expiresAt`. `ExportStatus` is the `pending` / `completed` / `failed` enum from [Shared types](/docs/interfaces/base/types). `result` is the `ExportJobResultSummary` the generator returned, present once the job completed; `expiresAt` is when the sweep will drop the record and its stored file.
|
|
215
214
|
|
|
216
|
-
`getExportJobExpiry(record)` computes that moment from a record directly
|
|
215
|
+
`getExportJobExpiry(record)` computes that moment from a record directly: `updatedAt` plus `EXPORT_TTL_MS`, which is one day.
|
|
217
216
|
|
|
218
|
-
`downloadExportJob` requires a completed job with a stored result
|
|
217
|
+
`downloadExportJob` requires a completed job with a stored result. Anything else fails with `400` or `500`. It sets `Content-Disposition` (with a filename built by `buildExportFilename`), `Content-Length` when the size is known, and `Access-Control-Expose-Headers`, then pipes the stored object to the response. The function returns as soon as the pipe is set up rather than awaiting it; once the response stream closes, the stored object and the job record are both deleted.
|
|
219
218
|
|
|
220
219
|
`loadExportJobForUser(ctx, user, jobId, access?)` is the shared step underneath both: it resolves the tenant, loads the record, runs the access checks, and returns the model, the record and the parsed context. Use it when you need the record itself rather than its status.
|
|
221
220
|
|
|
222
|
-
`downloadExportJob` deletes the stored object and the job record once the response stream closes
|
|
221
|
+
`downloadExportJob` deletes the stored object and the job record once the response stream closes, unless the job was started with `retainUntilExpiry`, in which case both survive until the sweep.
|
|
223
222
|
|
|
224
|
-
### List a
|
|
223
|
+
### List a caller's jobs
|
|
225
224
|
|
|
226
|
-
```typescript
|
|
225
|
+
```typescript fragment
|
|
227
226
|
function listExportJobs(
|
|
228
227
|
ctx: RequestContext,
|
|
229
228
|
user: User,
|
|
@@ -231,11 +230,11 @@ function listExportJobs(
|
|
|
231
230
|
): Promise<ExportJobSummary[]>;
|
|
232
231
|
```
|
|
233
232
|
|
|
234
|
-
Returns the caller's own jobs, most recent first
|
|
233
|
+
Returns the caller's own jobs, most recent first: the history a scope such as a tenant data export surfaces next to its request action. `ListExportJobsOptions` narrows it: `scope` restricts to one scope, `limit` caps the count and defaults to 20.
|
|
235
234
|
|
|
236
235
|
`ExportJobSummary` extends `ExportJobStatus` with `jobId`, `scope` and `createdAt`. Listing is scoped to the caller, so it needs no access options: another user's jobs are never returned.
|
|
237
236
|
|
|
238
|
-
### Access
|
|
237
|
+
### Access checks
|
|
239
238
|
|
|
240
239
|
| Option | Type | Description |
|
|
241
240
|
| --- | --- | --- |
|
|
@@ -244,19 +243,18 @@ Returns the caller's own jobs, most recent first — the history a scope such as
|
|
|
244
243
|
|
|
245
244
|
`ExportJobOwnership<TContext>` carries only `isOwnedBy`; `ExportJobAccessOptions<TContext>` extends it with `scope`. The job's `userId` is always compared against the caller regardless of what you pass, and every failed check answers `403`.
|
|
246
245
|
|
|
247
|
-
### Formats and
|
|
246
|
+
### Formats and delivery
|
|
248
247
|
|
|
249
248
|
An export format is an `Exporter`, and a delivery mode is a `Deliverer`. Both are looked up by id.
|
|
250
249
|
|
|
251
250
|
```typescript
|
|
252
251
|
import {
|
|
253
|
-
DEFAULT_DELIVERY,
|
|
254
252
|
DEFAULT_EXPORT_FORMAT,
|
|
255
|
-
getDeliverer,
|
|
256
253
|
getExporter,
|
|
257
254
|
} from "@antelopejs/interface-dms/base/export-jobs";
|
|
258
255
|
|
|
259
|
-
const
|
|
256
|
+
const localPath = "/tmp/export.csv";
|
|
257
|
+
const exporter = await getExporter(DEFAULT_EXPORT_FORMAT); // "csv"
|
|
260
258
|
const writer = exporter.createWriter(localPath);
|
|
261
259
|
writer.writeHeaders(["id", "name"]);
|
|
262
260
|
writer.appendRow(["id", "name"], { id: "1", name: "Ada" });
|
|
@@ -269,8 +267,8 @@ writer.close();
|
|
|
269
267
|
| `ExportWriter` | `{ writeHeaders(headers), appendRow(headers, row), close() }` | Incremental writer for one file. |
|
|
270
268
|
| `Deliverer` | `{ validate?(options: ExportJobDeliveryOptions): void; deliver(exportRecord, resultPath): Promise<void> }` | One delivery mode. `validate` runs when the job is created, so an unusable delivery fails fast rather than after generation. |
|
|
271
269
|
| `ExportJobDeliveryOptions` | `{ delivery: string; deliveryPath?: string }` | What `validate` is given. |
|
|
272
|
-
| `getExporter(format)` | `Exporter
|
|
273
|
-
| `getDeliverer(delivery)` | `Deliverer
|
|
270
|
+
| `getExporter(format)` | `Promise<Exporter>` | Resolves to the format's exporter. Rejects with `400` for an unknown format. |
|
|
271
|
+
| `getDeliverer(delivery)` | `Promise<Deliverer>` | Resolves to the delivery mode's deliverer. Rejects with `400` for an unknown delivery mode. |
|
|
274
272
|
| `DEFAULT_EXPORT_FORMAT` | `"csv"` | The format `csv` writes a BOM-prefixed comma-separated file; array values are joined with `;` and dates written as ISO strings. |
|
|
275
273
|
| `DEFAULT_DELIVERY` | `"download"` | Keeps the result in storage for the download route. |
|
|
276
274
|
| `EMAIL_DELIVERY` | `"email"` | Mails the recipient a link instead. Requires `deliveryPath`: the link is that path with `?exportJob=<jobId>` appended. |
|
|
@@ -279,7 +277,7 @@ writer.close();
|
|
|
279
277
|
|
|
280
278
|
`buildExportFilename(base, extension)` produces the name sent to the browser: the base and an ISO timestamp, both stripped of anything outside `[a-zA-Z0-9._-]`, joined by `-` and suffixed with the extension.
|
|
281
279
|
|
|
282
|
-
### Storage and
|
|
280
|
+
### Storage and maintenance
|
|
283
281
|
|
|
284
282
|
| Function | Signature | Description |
|
|
285
283
|
| --- | --- | --- |
|
|
@@ -290,7 +288,7 @@ writer.close();
|
|
|
290
288
|
| `sweepStaleExportsAllTenants` | `(ttlMs) => Promise<void>` | Deletes every job whose `updatedAt` is older than `ttlMs`, in every tenant, along with its stored file. |
|
|
291
289
|
| `deleteAllExportsForTenant` | `(tenantId) => Promise<void>` | Deletes every job of one tenant and its stored files. |
|
|
292
290
|
|
|
293
|
-
## Export a
|
|
291
|
+
## Export a tenant's data
|
|
294
292
|
|
|
295
293
|
`startTenantExportJob` runs the tenant data export as a background job: it asks every registered contributor for its slice, assembles the answers into one ZIP, and hands you the same ticket `runExportJob` does.
|
|
296
294
|
|
|
@@ -334,17 +332,17 @@ export class ExportsPage extends PageController("exports", {
|
|
|
334
332
|
}
|
|
335
333
|
```
|
|
336
334
|
|
|
337
|
-
`StartTenantExportJobOptions` is `ctx`, `user`, `scope`, `filename`, and the optional `delivery`, `deliveryPath` and `maxExecutionTimeMs
|
|
335
|
+
`StartTenantExportJobOptions` is `ctx`, `user`, `scope`, `filename`, and the optional `delivery`, `deliveryPath` and `maxExecutionTimeMs`: the same fields `runExportJob` takes, minus the ones the archive fixes itself: the extension is `TENANT_EXPORT_EXTENSION` (`"zip"`), the content type `TENANT_EXPORT_CONTENT_TYPE` (`"application/zip"`), and `retainUntilExpiry` is always on, since the archive is reachable from a delivered link and from the job history long after the first download.
|
|
338
336
|
|
|
339
337
|
`buildTenantExportArchive(options)` is the step underneath, for a caller that runs the archive outside a job. Its `BuildTenantExportArchiveOptions` are `tenantId`, the `localPath` to write the ZIP to, an `AbortSignal`, and an optional `reportProgress`; it resolves to the `ExportJobResultSummary` describing which contributors failed.
|
|
340
338
|
|
|
341
339
|
Contributing to the archive is the other side of this: a module registers a handler on the `TENANT_DATA_EXPORT` hook of the [Core](/docs/interfaces/core/introduction) domain, and that hook's page covers the archive sink, the manifest and what a failing contributor does to the result.
|
|
342
340
|
|
|
343
|
-
## Track
|
|
341
|
+
## Track file references
|
|
344
342
|
|
|
345
343
|
A `file` or `image` column stores keys into file storage, not the bytes. The helpers in `helpers/file-refs` compare or remap references in the supplied records. They do not authorize access, validate upload provenance, or determine whether another record still references an object. Use the [native save integration](/docs/components/file-storage#custom-save-routes) for promotion and cleanup in custom write routes.
|
|
346
344
|
|
|
347
|
-
```typescript
|
|
345
|
+
```typescript fragment
|
|
348
346
|
import {
|
|
349
347
|
collectFileRefs,
|
|
350
348
|
dedupeRefs,
|
|
@@ -379,7 +377,7 @@ The three functions that inspect columns take the column map first. An entry onl
|
|
|
379
377
|
|
|
380
378
|
`FileRef` is `{ key: string; storage?: string }`. The `storage` is read from the data type's `storage` option when it declares one, and left undefined otherwise, so a ref always carries the storage its key belongs to.
|
|
381
379
|
|
|
382
|
-
## Archive
|
|
380
|
+
## Archive mode defaults
|
|
383
381
|
|
|
384
382
|
`applyArchiveModeDefaultRules(rowActions, archiveField)` derives the row-action rules that make archive mode coherent: archived rows offer restore and delete, live rows offer edit, duplicate and archive. `TableView` calls it for you when `archiveMode` is set; call it directly only when you assemble `TableViewRowActionOptions` yourself.
|
|
385
383
|
|
|
@@ -401,7 +399,7 @@ const rowActions = applyArchiveModeDefaultRules(
|
|
|
401
399
|
| `restore` | `{ field: archiveField, equals: true }` |
|
|
402
400
|
| `delete` | `{ field: archiveField, equals: true }` |
|
|
403
401
|
|
|
404
|
-
The function returns a new options object
|
|
402
|
+
The function returns a new options object; it skips only actions you turned off:
|
|
405
403
|
|
|
406
404
|
| Value you passed | Result |
|
|
407
405
|
| --- | --- |
|
|
@@ -409,6 +407,6 @@ The function returns a new options object and never rewrites a decision you made
|
|
|
409
407
|
| `true` | `{ isEnabled: true, rule: <default> }` |
|
|
410
408
|
| `false`, or a config with `isEnabled: false` | Left as is; no rule added. |
|
|
411
409
|
| A config without a `rule` | The config, plus the default rule. |
|
|
412
|
-
| A config with a `rule` |
|
|
410
|
+
| A config with a `rule` | The config, with its rule ANDed with the default rule. |
|
|
413
411
|
|
|
414
|
-
Passing `undefined` as `rowActions` yields an object carrying only the five defaults. The rule shapes themselves are documented in [Shared
|
|
412
|
+
Passing `undefined` as `rowActions` yields an object carrying only the five defaults. The rule shapes themselves are documented in [Shared types](/docs/interfaces/base/types), and how the table view consumes them in [Tables](/docs/interfaces/base/tables).
|
|
@@ -1,41 +1,38 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: "Introduction"
|
|
3
3
|
description: "How backend code puts a message in a user's notification list: categories, subjects and sending."
|
|
4
|
+
mode: explanation
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
The `notifications` domain of `@antelopejs/interface-dms` is how backend code puts a message in a user's notification list. It has two halves. You declare a taxonomy once, and you use a builder every time you send.
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
The taxonomy is two levels deep. A **category** groups related notifications. A **subject** sits under a category and names one kind of message. Every notification is filed under a subject. Users choose what they receive per subject in their notification settings, so the subject you pick decides how the user sees the message grouped and whether the DMS delivers it at all.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
You declare both levels at import time, with `NotificationCategory()` first and then the `NotificationSubject()` calls under it. Sending is a chain of calls. `Notification()` opens a builder, the setters fill in the icon, title, description and subject, and `.build()` returns an immutable `SendableNotification`. You dispatch that to one user, a list of users, the holders of a set of roles, or every user.
|
|
11
12
|
|
|
12
|
-
The
|
|
13
|
+
The [Read notifications](/docs/auth-and-tenancy/authentication#read-notifications) walkthrough shows the open notification bell with one unread message, and describes how a click marks a message read and how a new message reaches every open session of its recipient. The [Notification preferences](/docs/auth-and-tenancy/authentication#notification-preferences) walkthrough shows the System category expanded to its subjects.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
## What the domain gives you
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
- **
|
|
21
|
-
- **
|
|
22
|
-
- **
|
|
23
|
-
- **Type-checked builder** — The builder tracks which fields have been supplied in its type parameter, so `.build()` does not compile until icon, title, description and subject are all set.
|
|
24
|
-
- **Four dispatch targets** — Send to one user, a list of users, every user holding at least one of a set of roles, or every user.
|
|
25
|
-
- **Shared or individual read state** — A multi-recipient send can give each recipient their own read state, or group the copies so one recipient reading it clears it for all of them.
|
|
26
|
-
- **Preference-aware delivery** — Sends are silently skipped for users who turned the subject off, and `togglePermission` marks the subjects users may not turn off.
|
|
17
|
+
- **A two-level taxonomy.** Categories group subjects, and subjects classify notifications. The DMS stores a user's preferences under the `categoryId:subjectId` pair.
|
|
18
|
+
- **Declarative registration.** `NotificationCategory()` and `NotificationSubject()` register at import time and return plain info objects that you keep as constants and pass around.
|
|
19
|
+
- **Built-in system subjects.** `GeneralSubject`, `SecuritySubject`, `AccountSubject`, `CollaborationSubject` and `AutomationSubject` cover the common platform messages, so you declare nothing for them.
|
|
20
|
+
- **A type-checked builder.** The builder tracks the fields you have supplied in its type parameter, so `.build()` does not compile until the icon, the title, the description and the subject are all set.
|
|
21
|
+
- **Four dispatch targets.** You send to one user, to a list of users, to every user holding at least one of a set of roles, or to every user.
|
|
22
|
+
- **Shared or individual read state.** A multi-recipient send can give each recipient their own read state. It can also group the copies, so that one recipient reading the notification marks it read for all of them.
|
|
23
|
+
- **Preference-aware delivery.** The DMS skips a send without an error for a user who turned the subject off. `togglePermission` marks the subjects that users may not turn off.
|
|
27
24
|
|
|
28
25
|
## Dependencies
|
|
29
26
|
|
|
30
|
-
This interface relies on the following AntelopeJS
|
|
27
|
+
This interface relies on the following AntelopeJS package:
|
|
31
28
|
|
|
32
|
-
- [
|
|
29
|
+
- [`@antelopejs/interface-core`](https://github.com/AntelopeJS/interface-core) provides the interface functions and registration proxies that reach the DMS implementation.
|
|
33
30
|
|
|
34
|
-
The implementation lives in the DMS module, so the interface only works in a project that loads `@antelopejs/dms`. Sending to users and roles uses the DMS user and role identifiers
|
|
31
|
+
The implementation lives in the DMS module, so the interface only works in a project that loads `@antelopejs/dms`. Sending to users and roles uses the DMS user and role identifiers that the DMS auth and tenancy guide describes.
|
|
35
32
|
|
|
36
|
-
##
|
|
33
|
+
## A first notification
|
|
37
34
|
|
|
38
|
-
The following example declares a category with one subject and sends a notification
|
|
35
|
+
The following example declares a category with one subject and sends a notification under it.
|
|
39
36
|
|
|
40
37
|
```typescript
|
|
41
38
|
import {
|
|
@@ -44,7 +41,6 @@ import {
|
|
|
44
41
|
NotificationSubject,
|
|
45
42
|
} from "@antelopejs/interface-dms/notifications";
|
|
46
43
|
|
|
47
|
-
// Declared at import time — the category first, then its subjects
|
|
48
44
|
export const shopCategory = NotificationCategory("shop", {
|
|
49
45
|
labelKey: "shop.notifications.categories.shop",
|
|
50
46
|
descriptionKey: "shop.notifications.categories.shop_desc",
|
|
@@ -73,9 +69,9 @@ export async function notifyOrderShipped(
|
|
|
73
69
|
}
|
|
74
70
|
```
|
|
75
71
|
|
|
76
|
-
The user sees the notification in the dashboard, and finds an `orders`
|
|
72
|
+
The category comes first in the file because the DMS refuses a subject whose category it has not registered yet. The user sees the notification in the dashboard, and finds an `orders` switch under a `shop` group in their notification settings.
|
|
77
73
|
|
|
78
|
-
##
|
|
74
|
+
## Pages in this section
|
|
79
75
|
|
|
80
|
-
- [Categories and
|
|
81
|
-
- [Sending
|
|
76
|
+
- [Categories and subjects](/docs/interfaces/notifications/categories-and-subjects) covers declaring categories and subjects, controlling what users may turn off, and the built-in system subjects.
|
|
77
|
+
- [Sending notifications](/docs/interfaces/notifications/sending) covers building a notification, dispatching it to users, roles or everyone, and the rules that decide delivery.
|