@antelopejs/interface-dms 0.7.4 → 0.8.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.
Files changed (227) hide show
  1. package/CHANGELOG.md +107 -0
  2. package/dist/auth/index.d.ts +3 -3
  3. package/dist/auth/index.js +11 -9
  4. package/dist/auth/index.js.map +1 -1
  5. package/dist/auth/internal/jwt-auth-decorator.d.ts +20 -0
  6. package/dist/auth/internal/jwt-auth-decorator.js +51 -0
  7. package/dist/auth/internal/jwt-auth-decorator.js.map +1 -0
  8. package/dist/auth/internal/request-authenticators.d.ts +12 -0
  9. package/dist/auth/internal/request-authenticators.js +22 -0
  10. package/dist/auth/internal/request-authenticators.js.map +1 -1
  11. package/dist/base/activity-feed.d.ts +6 -6
  12. package/dist/base/block-registry/types.d.ts +16 -0
  13. package/dist/base/block-types.d.ts +1 -0
  14. package/dist/base/block-types.js +1 -0
  15. package/dist/base/block-types.js.map +1 -1
  16. package/dist/base/chart-card.d.ts +15 -0
  17. package/dist/base/chart-card.js +4 -0
  18. package/dist/base/chart-card.js.map +1 -1
  19. package/dist/base/chart-schemas.d.ts +26 -26
  20. package/dist/base/code-block.d.ts +3 -3
  21. package/dist/base/data-types/compare-types.js +19 -13
  22. package/dist/base/data-types/compare-types.js.map +1 -1
  23. package/dist/base/data-types/core.d.ts +11 -0
  24. package/dist/base/data-types/core.js +14 -1
  25. package/dist/base/data-types/core.js.map +1 -1
  26. package/dist/base/data-types/default-types.d.ts +112 -2
  27. package/dist/base/data-types/default-types.js +90 -19
  28. package/dist/base/data-types/default-types.js.map +1 -1
  29. package/dist/base/data-types/field-types.d.ts +10 -4
  30. package/dist/base/data-types/field-types.js +12 -2
  31. package/dist/base/data-types/field-types.js.map +1 -1
  32. package/dist/base/data-types/internal/compare-types.d.ts +3 -0
  33. package/dist/base/data-types/internal/compare-types.js +7 -0
  34. package/dist/base/data-types/internal/compare-types.js.map +1 -1
  35. package/dist/base/empty-state.d.ts +4 -4
  36. package/dist/base/form-block-schema.d.ts +59 -3
  37. package/dist/base/form-block-schema.js +12 -2
  38. package/dist/base/form-block-schema.js.map +1 -1
  39. package/dist/base/form-schema.d.ts +46 -1
  40. package/dist/base/form-schema.js.map +1 -1
  41. package/dist/base/form-types.d.ts +56 -13
  42. package/dist/base/form-types.js +12 -4
  43. package/dist/base/form-types.js.map +1 -1
  44. package/dist/base/guard.d.ts +6 -6
  45. package/dist/base/helpers/archive-mode-helpers.js +6 -2
  46. package/dist/base/helpers/archive-mode-helpers.js.map +1 -1
  47. package/dist/base/index.d.ts +1 -0
  48. package/dist/base/index.js +1 -0
  49. package/dist/base/index.js.map +1 -1
  50. package/dist/base/internal/form-schema.js +2 -0
  51. package/dist/base/internal/form-schema.js.map +1 -1
  52. package/dist/base/internal/layouts.d.ts +4 -0
  53. package/dist/base/key-value-list.d.ts +12 -9
  54. package/dist/base/key-value-list.js +1 -1
  55. package/dist/base/key-value-list.js.map +1 -1
  56. package/dist/base/kpi-card.d.ts +39 -5
  57. package/dist/base/kpi-card.js +18 -6
  58. package/dist/base/kpi-card.js.map +1 -1
  59. package/dist/base/layouts.d.ts +24 -0
  60. package/dist/base/layouts.js.map +1 -1
  61. package/dist/base/live-toggle.d.ts +11 -0
  62. package/dist/base/live-toggle.js +8 -1
  63. package/dist/base/live-toggle.js.map +1 -1
  64. package/dist/base/page-toolbar.d.ts +158 -0
  65. package/dist/base/page-toolbar.js +198 -0
  66. package/dist/base/page-toolbar.js.map +1 -0
  67. package/dist/base/period-selector.d.ts +9 -2
  68. package/dist/base/period-selector.js.map +1 -1
  69. package/dist/base/placeholder.d.ts +2 -2
  70. package/dist/base/section.d.ts +2 -2
  71. package/dist/base/stack.d.ts +2 -2
  72. package/dist/base/stat-group.d.ts +18 -6
  73. package/dist/base/stat-group.js +9 -0
  74. package/dist/base/stat-group.js.map +1 -1
  75. package/dist/base/table-view/column-display.d.ts +9 -5
  76. package/dist/base/table-view/column-display.js +1 -1
  77. package/dist/base/table-view/column-display.js.map +1 -1
  78. package/dist/base/table-view/data-functions.d.ts +26 -7
  79. package/dist/base/table-view/data-functions.js +10 -6
  80. package/dist/base/table-view/data-functions.js.map +1 -1
  81. package/dist/base/table-view/factory.js +24 -13
  82. package/dist/base/table-view/factory.js.map +1 -1
  83. package/dist/base/table-view/internal/auth.d.ts +2 -0
  84. package/dist/base/table-view/internal/auth.js +3 -1
  85. package/dist/base/table-view/internal/auth.js.map +1 -1
  86. package/dist/base/table-view/internal/factory-helpers.d.ts +5 -0
  87. package/dist/base/table-view/internal/factory-helpers.js +55 -11
  88. package/dist/base/table-view/internal/factory-helpers.js.map +1 -1
  89. package/dist/base/table-view/internal/guards.js +19 -2
  90. package/dist/base/table-view/internal/guards.js.map +1 -1
  91. package/dist/base/table-view/internal/realtime.js +17 -0
  92. package/dist/base/table-view/internal/realtime.js.map +1 -1
  93. package/dist/base/table-view/internal/resource-form.js +1 -0
  94. package/dist/base/table-view/internal/resource-form.js.map +1 -1
  95. package/dist/base/table-view/internal/row-actions-schema.d.ts +296 -0
  96. package/dist/base/table-view/internal/row-actions-schema.js +62 -0
  97. package/dist/base/table-view/internal/row-actions-schema.js.map +1 -0
  98. package/dist/base/table-view/internal/validation.d.ts +15 -3
  99. package/dist/base/table-view/internal/validation.js +70 -2
  100. package/dist/base/table-view/internal/validation.js.map +1 -1
  101. package/dist/base/table-view/meta.d.ts +8 -0
  102. package/dist/base/table-view/meta.js +25 -3
  103. package/dist/base/table-view/meta.js.map +1 -1
  104. package/dist/base/table-view/options.d.ts +90 -16
  105. package/dist/base/table-view/options.js.map +1 -1
  106. package/dist/base/table-view/realtime.d.ts +8 -0
  107. package/dist/base/table-view/realtime.js.map +1 -1
  108. package/dist/base/table-view/routes.js +5 -2
  109. package/dist/base/table-view/routes.js.map +1 -1
  110. package/dist/base/table-view/schema.d.ts +36 -30
  111. package/dist/base/table-view/schema.js +11 -57
  112. package/dist/base/table-view/schema.js.map +1 -1
  113. package/dist/base/table-view/source.d.ts +1 -1
  114. package/dist/base/table-view/source.js +4 -1
  115. package/dist/base/table-view/source.js.map +1 -1
  116. package/dist/base/table-view.d.ts +2 -2
  117. package/dist/base/table-view.js.map +1 -1
  118. package/dist/base/top-list-card.d.ts +5 -5
  119. package/dist/base/types/action-target.d.ts +77 -20
  120. package/dist/base/types/confirm-dialog.d.ts +5 -1
  121. package/dist/base/types/custom-button.d.ts +5 -3
  122. package/dist/base/types/field-config.d.ts +4 -4
  123. package/dist/base/types/guards.d.ts +10 -0
  124. package/dist/base/types/row-action.d.ts +6 -1
  125. package/dist/base/types/size.d.ts +3 -1
  126. package/dist/client-ip.d.ts +6 -2
  127. package/dist/client-ip.js +4 -2
  128. package/dist/client-ip.js.map +1 -1
  129. package/dist/component.d.ts +8 -0
  130. package/dist/component.js.map +1 -1
  131. package/dist/data-controllers/members.d.ts +0 -3
  132. package/dist/data-controllers/members.js +30 -8
  133. package/dist/data-controllers/members.js.map +1 -1
  134. package/dist/db/internal/tenantLifecycle.model.js +5 -2
  135. package/dist/db/internal/tenantLifecycle.model.js.map +1 -1
  136. package/dist/guards.js +2 -3
  137. package/dist/guards.js.map +1 -1
  138. package/dist/hooks.d.ts +41 -5
  139. package/dist/hooks.js +5 -1
  140. package/dist/hooks.js.map +1 -1
  141. package/dist/index.d.ts +3 -3
  142. package/dist/index.js +3 -2
  143. package/dist/index.js.map +1 -1
  144. package/dist/internal/invite-membership.d.ts +9 -0
  145. package/dist/internal/invite-membership.js +25 -7
  146. package/dist/internal/invite-membership.js.map +1 -1
  147. package/dist/internal/member-changes.d.ts +24 -0
  148. package/dist/internal/member-changes.js +66 -0
  149. package/dist/internal/member-changes.js.map +1 -0
  150. package/dist/internal/tenant-ownership.d.ts +4 -1
  151. package/dist/internal/tenant-ownership.js +4 -10
  152. package/dist/internal/tenant-ownership.js.map +1 -1
  153. package/dist/invite-extensions.d.ts +0 -9
  154. package/dist/invite-extensions.js +1 -36
  155. package/dist/invite-extensions.js.map +1 -1
  156. package/dist/invite-resolution.js +6 -2
  157. package/dist/invite-resolution.js.map +1 -1
  158. package/dist/invites.js +36 -22
  159. package/dist/invites.js.map +1 -1
  160. package/dist/layout-banners.d.ts +40 -4
  161. package/dist/layout-banners.js +25 -3
  162. package/dist/layout-banners.js.map +1 -1
  163. package/dist/notifications/internal.d.ts +2 -2
  164. package/dist/notifications/internal.js.map +1 -1
  165. package/dist/notifications/sendable.d.ts +3 -2
  166. package/dist/notifications/sendable.js +2 -1
  167. package/dist/notifications/sendable.js.map +1 -1
  168. package/dist/notifications/types.d.ts +9 -0
  169. package/dist/page/controllers.d.ts +44 -0
  170. package/dist/page/controllers.js +14 -1
  171. package/dist/page/controllers.js.map +1 -1
  172. package/dist/page/internal/layout-filter.d.ts +2 -1
  173. package/dist/page/internal/layout-filter.js +3 -1
  174. package/dist/page/internal/layout-filter.js.map +1 -1
  175. package/dist/page/internal/metadata-helpers.d.ts +7 -0
  176. package/dist/page/internal/metadata-helpers.js +13 -2
  177. package/dist/page/internal/metadata-helpers.js.map +1 -1
  178. package/dist/page/internal/page-registration.d.ts +2 -0
  179. package/dist/page/internal/page-registration.js.map +1 -1
  180. package/dist/page/layout-filter.js +31 -10
  181. package/dist/page/layout-filter.js.map +1 -1
  182. package/dist/page/metadata.js +29 -24
  183. package/dist/page/metadata.js.map +1 -1
  184. package/dist/page/types.d.ts +39 -4
  185. package/dist/page/types.js.map +1 -1
  186. package/dist/page.d.ts +1 -1
  187. package/dist/page.js +2 -1
  188. package/dist/page.js.map +1 -1
  189. package/dist/permissions-resolver.d.ts +26 -3
  190. package/dist/permissions-resolver.js +2 -1
  191. package/dist/permissions-resolver.js.map +1 -1
  192. package/dist/permissions.d.ts +7 -3
  193. package/dist/permissions.js +8 -6
  194. package/dist/permissions.js.map +1 -1
  195. package/dist/realtime.d.ts +24 -1
  196. package/dist/realtime.js +7 -1
  197. package/dist/realtime.js.map +1 -1
  198. package/dist/request-tenant.d.ts +17 -13
  199. package/dist/request-tenant.js +54 -42
  200. package/dist/request-tenant.js.map +1 -1
  201. package/dist/tenant-members.d.ts +26 -0
  202. package/dist/tenant-members.js +29 -0
  203. package/dist/tenant-members.js.map +1 -0
  204. package/dist/tenant-ownership.d.ts +4 -1
  205. package/dist/tenant-ownership.js +12 -17
  206. package/dist/tenant-ownership.js.map +1 -1
  207. package/dist/tenant-scoped-model.d.ts +2 -1
  208. package/dist/tenant-scoped-model.js +4 -3
  209. package/dist/tenant-scoped-model.js.map +1 -1
  210. package/docs/1.core/10.layout-banners.md +57 -2
  211. package/docs/1.core/2.pages-and-modules.md +20 -11
  212. package/docs/1.core/4.permissions.md +34 -1
  213. package/docs/1.core/5.tenancy.md +37 -6
  214. package/docs/1.core/7.hooks.md +12 -2
  215. package/docs/1.core/8.realtime.md +24 -3
  216. package/docs/2.auth/2.authentication.md +3 -3
  217. package/docs/3.base/1.introduction.md +1 -0
  218. package/docs/3.base/10.display-blocks.md +20 -2
  219. package/docs/3.base/2.types.md +7 -5
  220. package/docs/3.base/3.forms.md +21 -6
  221. package/docs/3.base/4.tables.md +14 -9
  222. package/docs/3.base/5.charts-and-widgets.md +8 -4
  223. package/docs/3.base/6.layout.md +38 -1
  224. package/docs/3.base/8.data-types.md +14 -7
  225. package/docs/4.notifications/3.sending.md +4 -3
  226. package/docs/5.html-render/1.introduction.md +5 -7
  227. package/package.json +3 -7
@@ -73,6 +73,7 @@ abstract class DataType {
73
73
  filter(context, proxy, key, value, mode, row): ValueProxyOrValue<boolean>;
74
74
  filterComponents(): Record<string, ComponentInfoSerialized> & { default: ComponentInfoSerialized };
75
75
  inputComponent(): ComponentInfoSerialized;
76
+ describedInputComponent(): ComponentInfoSerialized;
76
77
  decorateField?(target: unknown, key: PropertyKey, descriptor?: PropertyDescriptor): void;
77
78
  }
78
79
  ```
@@ -85,6 +86,7 @@ abstract class DataType {
85
86
  | `defaultInputComponent()` | Abstract. Returns the input component the type renders. Implemented by every concrete type. |
86
87
  | `getValidation()` | Abstract. Returns the Zod schema for one value of this type, before the field-level adaptation described in [Forms](/docs/interfaces/base/forms). |
87
88
  | `inputComponent()` | The form input. Defaults to `defaultInputComponent()`. |
89
+ | `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. |
88
90
  | `filterComponents()` | The filter inputs, keyed by compare-mode id with a mandatory `default`. Defaults to `{ default: defaultInputComponent() }`. |
89
91
  | `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. |
90
92
  | `decorateField()` | Optional. Called by the `@Column` decorator so the type can add further decorators to the field — this is how the relation types install their join. |
@@ -207,7 +209,7 @@ function serializeType(instance?: DataType): DataTypeSerialized | undefined;
207
209
  | `compareModes` | `string[]` | Ids of the type's compare modes; unregistered ones are dropped. |
208
210
  | `defaultCompareMode` | `string` | Id of the default mode. |
209
211
  | `filterComponents` | `Record<string, FilterComponent>` | Filter inputs by mode id, from `filterComponents()`, with every `noInput` mode's entry replaced by the literal `"noInput"`. |
210
- | `inputComponent` | `ComponentInfoSerialized` | The form input, from `inputComponent()`. |
212
+ | `inputComponent` | `ComponentInfoSerialized` | The input the column's cells and quick filters read the options of, from `describedInputComponent()`. |
211
213
 
212
214
  `FilterComponent` is `ComponentInfoSerialized | "noInput"`. The value-level counterpart, `ComponentOrNoInput`, is described in [Shared Types](/docs/interfaces/base/types).
213
215
 
@@ -232,7 +234,7 @@ function serializeType(instance?: DataType): DataTypeSerialized | undefined;
232
234
  | `NotContains` | `not_contains` | value |
233
235
  | `ArrayContainsString` | `array_contains_string` | value |
234
236
 
235
- `IsEmpty` and `IsNotEmpty` are the two registered with `noInput`. The namespace also exports `escapeRegex(str: string): string`, the helper the substring modes use to make a viewer-supplied value safe inside a pattern.
237
+ `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.
236
238
 
237
239
  ## The Default Types
238
240
 
@@ -264,12 +266,13 @@ function serializeType(instance?: DataType): DataTypeSerialized | undefined;
264
266
 
265
267
  | Options interface | Fields |
266
268
  | --- | --- |
267
- | `StringTypeOptions` | `placeholder?`, `maxLength?`, `minLength?`, `showCount?`, `textarea?`, `rows?`, `fallback?` |
268
- | `NumberTypeOptions` | `min?`, `max?`, `step?`, `placeholder?`, `suffix?`, `fallback?` |
269
+ | `StringTypeOptions` | `placeholder?`, `maxLength?`, `minLength?`, `showCount?`, `textarea?`, `rows?`, `width?`, `fallback?` |
270
+ | `NumberTypeOptions` | `min?`, `max?`, `step?`, `placeholder?`, `suffix?`, `width?`, `fallback?` |
269
271
  | `DateTypeOptions` | `range?`, `multiple?`, `minDate?`, `maxDate?`, `fallback?` |
270
272
  | `BooleanTypeOptions` | `fallback?` |
271
273
  | `SelectTypeOptions` | `items: FormComponents.SelectOption[]`, `placeholder?`, `multiple?`, `deselectable?`, `display?`, `columns?` (cards per row of the `cards` display, 2 by default), `fallback?` |
272
- | `EmailTypeOptions`, `ColorTypeOptions`, `UrlTypeOptions`, `RichTextTypeOptions` | `placeholder?`, `fallback?` |
274
+ | `EmailTypeOptions`, `ColorTypeOptions`, `RichTextTypeOptions` | `placeholder?`, `fallback?` |
275
+ | `UrlTypeOptions` | `placeholder?`, `preview?` (`"avatar"` \| `"image"`: shown read-only, the URL is drawn as the image it points to; the form still edits it as text), `fallback?` |
273
276
  | `PasswordTypeOptions` | `placeholder?`, `minLength?`, `confirmPassword?`, `confirmPlaceholder?`, `fallback?` |
274
277
  | `PhoneTypeOptions` | `placeholder?`, `requiredPrefix?`, `fallback?` |
275
278
  | `StringTimeTypeOptions` | `placeholder?`, `min?`, `max?`, `fallback?` |
@@ -279,6 +282,7 @@ Notes on the ones whose behaviour is not obvious from the options:
279
282
  - `StringType` renders a textarea instead of a single-line input when `textarea` is set, and passes `rows` to it.
280
283
  - `StringType` with `showCount` shows the characters typed, out of `maxLength` when set ("4 / 60"), in its input or under its textarea.
281
284
  - `NumberType` hands `suffix` (an i18n key with `$`, or a literal) to its input, which writes it after the field; the value stays a number. `PriceType` inherits it; `PercentageType` keeps its own `%`.
285
+ - `NumberType` (and the types extending it) and a single-line `StringType` hand `width` (`FormComponents.InputWidth`) to their input: `"compact"` sizes it for a short value from `sm` up, `"full"` fills the row, and left out the input is compact when `min` / `max` fit in 6 digits or `maxLength` is 16 or less.
282
286
  - `DateType` overrides `filter` so `is`, `is_not` and `is_between` compare whole UTC days rather than instants, and adds a range picker as the filter component for `is_between`. Its schema accepts a `Date` or an ISO-shaped string and transforms it to a `Date`; with `multiple` the value becomes an array, and with `range` it becomes `{ start, end }`, `end` on or after `start` (a pair `[start, end]` is still read and validates to the same object).
283
287
  - `BooleanType` uses a two-option select as its filter component, so a viewer picks "checked"/"unchecked" rather than typing a value.
284
288
  - `SelectType` validates against the `value`s of its `items`, as an enum or an array of that enum when `multiple` is set.
@@ -317,9 +321,12 @@ declare customerId: string;
317
321
  | `deselectable` | `boolean` | Allow clearing the selection. |
318
322
  | `filterOnly` | `boolean` | Skip the join entirely: the raw scalar id stays in the list output and the funnel filter runs equality on it. |
319
323
  | `addForm` | `{ displayName?: string; description?: string }` | Title and description of the drawer the picker's "add" entry opens ("New customer"). `$`-prefixed: i18n keys. Default to "New entry". |
324
+ | `filterBy` | `{ field, from }` | List only the target rows whose `field` equals the form's current value of the field `from`, e.g. `{ field: "customerId", from: "customerId" }` for a site among its customer's sites. `field` must be filterable on the target (`filterable: true` or `@Filter`); `decorateField` throws otherwise. |
320
325
  | `fallback` | `string` | Text used in place of an empty value. |
321
326
 
322
- When the target controller exposes a `new` endpoint and has form fields, the picker also carries an inline "add" form built from the target's `new` fields, plus the permission id of the target's `add` action.
327
+ 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.
328
+
329
+ 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 is the bulk of the component — the target's fields, its validation schema, its own relations' add forms — 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.
323
330
 
324
331
  `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 `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`.
325
332
 
@@ -338,7 +345,7 @@ When the target controller exposes a `new` endpoint and has form fields, the pic
338
345
  | `addressLine2` | no | Supplementary delivery information. |
339
346
  | `countrySubdivision` | no | Region, state or province. |
340
347
 
341
- The type's options are `placeholder` (one string per address component), `autocomplete`, an optional `dataApiController` with a `keyMapping` of `label` / `value` for picking an existing address, and `fallback`. `AddressAutocomplete` configures the geocoder:
348
+ The type's options are `placeholder` (one string per address component), `autocomplete`, `defaultCountry` (the ISO 3166-1 alpha-2 country shown while the address has none and whose places the street suggestions list first, written with the first part typed: an address left empty stays empty), an optional `dataApiController` with a `keyMapping` of `label` / `value` for picking an existing address, and `fallback`. `AddressAutocomplete` configures the geocoder:
342
349
 
343
350
  | Option | Type | Description |
344
351
  | --- | --- | --- |
@@ -33,7 +33,7 @@ A `SendableNotification` is immutable and holds no recipient, so you can build o
33
33
  | `toUser` | `(userId: string, options?: SendOptions) => Promise<void>` | Send to one user. |
34
34
  | `toUsers` | `(userIds: string[], options?: SendOptions) => Promise<void>` | Send to a list of users. |
35
35
  | `toUsersIdempotently` | `(userIds: string[], idempotencyKey: string, options?: SendOptions) => Promise<void>` | Send a durable event once per recipient, including after dismissal. |
36
- | `toRoles` | `(roleIds: string[], options?: SendOptions) => Promise<void>` | Send to every user holding at least one of the roles. |
36
+ | `toRoles` | `(roleIds: string[], options?: RoleSendOptions) => Promise<void>` | Send to every user holding at least one of the roles, in `options.tenantId` when set. |
37
37
  | `broadcast` | `(options?: SendOptions) => Promise<void>` | Send to every user. |
38
38
 
39
39
  ## Building a Notification
@@ -146,10 +146,10 @@ await shipped.toUsers([ownerId, managerId], { readScope: "shared" });
146
146
  `toRoles(roleIds, options?)` resolves the users that hold any of the given roles and sends to them. An empty `roleIds` array sends nothing, and so does a set of roles nobody holds.
147
147
 
148
148
  ```typescript
149
- await shipped.toRoles([adminRoleId], { readScope: "shared" });
149
+ await shipped.toRoles([adminRoleId], { readScope: "shared", tenantId });
150
150
  ```
151
151
 
152
- Role ids are the DMS role identifiers described in the DMS tenancy and permissions guide; membership is resolved across tenants, so a user holding the role in any tenant is included.
152
+ Role ids are the DMS role identifiers described in the DMS tenancy and permissions guide, and they belong to a tenant. `tenantId` (`RoleSendOptions`) restricts the recipients to that tenant's members; without it, membership is resolved across tenants, so a user holding the role in any tenant is included.
153
153
 
154
154
  ## Broadcasting
155
155
 
@@ -168,6 +168,7 @@ Every dispatch method accepts an optional `SendOptions` object.
168
168
  | `readScope` | `ReadScope` (optional) | Read-state grouping for a multi-recipient send. Defaults to `"individual"` — see [Read Scope](/docs/interfaces/notifications/categories-and-subjects#read-scope). |
169
169
  | `idempotencyKey` | `string` (optional) | Stable event key, unique across producers: prefix it with your module ID. Reusing it for a recipient preserves the original notification and dismissal state. |
170
170
  | `dedupe` | `boolean` (optional) | `false` stores every unkeyed send, even one identical to a notification the recipient got less than 10 seconds earlier. Defaults to `true`; see below. |
171
+ | `tenantId` | `string` (optional, `toRoles` only: `RoleSendOptions`) | Only the members of this tenant holding the roles; every tenant when unset. |
171
172
 
172
173
  Pick `"shared"` for alerts that only need one person to act on them, and `"individual"` for anything each recipient has to see for themselves.
173
174
 
@@ -255,7 +255,7 @@ Types the `htmlRender` block of the DMS module configuration in `antelope.config
255
255
  | Option | Type | Description |
256
256
  | ------ | ---- | ----------- |
257
257
  | `renderEndpoint` | `string` | Absolute URL `GenerateHtml` posts to. Default `http://localhost:3001/api/html/render`. |
258
- | `serviceSecret` | `string` | Secret used to sign the service token that authenticates the render call. Default `"dev"` — set a strong value in production. |
258
+ | `serviceSecret` | `string` | Secret used to sign the service token that authenticates the render call. Default `"dev"`, which the DMS refuses in production. |
259
259
  | `serviceTokenLifetime` | `number` | Lifetime of that service token, in milliseconds. The frontend render server rejects a token valid for more than five minutes. Default `300000` (5 minutes). |
260
260
 
261
261
  The DMS merges the block you supply over those defaults, so a configuration only needs the keys it changes:
@@ -263,13 +263,12 @@ The DMS merges the block you supply over those defaults, so a configuration only
263
263
  ```typescript
264
264
  import { defineConfig } from "@antelopejs/interface-core/config";
265
265
 
266
- const renderSecret = process.env.DMS_HTML_RENDER_SECRET;
267
- if (!renderSecret) {
268
- throw new Error("DMS_HTML_RENDER_SECRET is not set");
269
- }
270
-
271
266
  export default defineConfig({
272
267
  name: "acme-admin",
268
+ // Read at start; a production start without it is refused by the DMS.
269
+ envOverrides: {
270
+ DMS_HTML_RENDER_SECRET: "modules.dms.config.htmlRender.serviceSecret",
271
+ },
273
272
  modules: {
274
273
  dms: {
275
274
  source: {
@@ -280,7 +279,6 @@ export default defineConfig({
280
279
  config: {
281
280
  htmlRender: {
282
281
  renderEndpoint: "https://admin.example.com/api/html/render",
283
- serviceSecret: renderSecret,
284
282
  },
285
283
  },
286
284
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/interface-dms",
3
- "version": "0.7.4",
3
+ "version": "0.8.0",
4
4
  "description": "Public AntelopeJS interfaces of the DMS: pages, components, permissions, tenancy, auth, notifications and HTML rendering.",
5
5
  "keywords": [
6
6
  "antelopejs",
@@ -45,7 +45,6 @@
45
45
  "knip:all": "knip"
46
46
  },
47
47
  "dependencies": {
48
- "jsonwebtoken": "^9.0.3",
49
48
  "randomstring": "^1.3.1",
50
49
  "zod": "~3.24.2",
51
50
  "zod-to-json-schema": "~3.24.6"
@@ -53,9 +52,8 @@
53
52
  "peerDependencies": {
54
53
  "@antelopejs/interface-api": ">=0.0.15 <1.0.0",
55
54
  "@antelopejs/interface-api-util": ">=0.1.3 <1.0.0",
56
- "@antelopejs/interface-auth": ">=0.0.7 <1.0.0",
57
55
  "@antelopejs/interface-core": ">=0.2.4 <1.0.0",
58
- "@antelopejs/interface-data-api": ">=0.2.2 <1.0.0",
56
+ "@antelopejs/interface-data-api": ">=0.3.0 <1.0.0",
59
57
  "@antelopejs/interface-database": ">=0.1.10 <1.0.0",
60
58
  "@antelopejs/interface-database-decorators": ">=0.1.9 <1.0.0",
61
59
  "@antelopejs/interface-file-storage": ">=0.1.4 <1.0.0"
@@ -63,13 +61,11 @@
63
61
  "devDependencies": {
64
62
  "@antelopejs/interface-api": ">=0.0.15 <1.0.0",
65
63
  "@antelopejs/interface-api-util": ">=0.1.3 <1.0.0",
66
- "@antelopejs/interface-auth": ">=0.0.7 <1.0.0",
67
64
  "@antelopejs/interface-core": ">=0.2.4 <1.0.0",
68
- "@antelopejs/interface-data-api": ">=0.2.2 <1.0.0",
65
+ "@antelopejs/interface-data-api": ">=0.3.0 <1.0.0",
69
66
  "@antelopejs/interface-database": ">=0.1.10 <1.0.0",
70
67
  "@antelopejs/interface-database-decorators": ">=0.1.9 <1.0.0",
71
68
  "@antelopejs/interface-file-storage": ">=0.1.4 <1.0.0",
72
- "@types/jsonwebtoken": "^9.0.10",
73
69
  "@types/node": "^24.0.0",
74
70
  "@types/randomstring": "^1.3.0",
75
71
  "knip": "^6.34.0",