@antelopejs/interface-dms 0.10.3 → 0.12.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 (377) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/README.md +21 -10
  3. package/dist/attachments.d.ts +15 -2
  4. package/dist/attachments.js +14 -1
  5. package/dist/attachments.js.map +1 -1
  6. package/dist/auth/db/models/sessions.model.d.ts +7 -5
  7. package/dist/auth/db/models/sessions.model.js +2 -9
  8. package/dist/auth/db/models/sessions.model.js.map +1 -1
  9. package/dist/auth/db/models/userExternalIdentities.model.d.ts +7 -5
  10. package/dist/auth/db/models/users.model.d.ts +7 -5
  11. package/dist/auth/db/tables/users.table.d.ts +4 -2
  12. package/dist/auth/db/tables/users.table.js.map +1 -1
  13. package/dist/auth/index.d.ts +4 -4
  14. package/dist/auth/internal/jwt-auth-decorator.d.ts +1 -1
  15. package/dist/auth/internal/jwt-auth-decorator.js +6 -3
  16. package/dist/auth/internal/jwt-auth-decorator.js.map +1 -1
  17. package/dist/auth/internal/request-authenticators.d.ts +12 -0
  18. package/dist/auth/internal/request-authenticators.js +53 -10
  19. package/dist/auth/internal/request-authenticators.js.map +1 -1
  20. package/dist/base/activity-feed.d.ts +34 -32
  21. package/dist/base/activity-feed.js +2 -0
  22. package/dist/base/activity-feed.js.map +1 -1
  23. package/dist/base/banner.d.ts +12 -10
  24. package/dist/base/banner.js +2 -0
  25. package/dist/base/banner.js.map +1 -1
  26. package/dist/base/block-registry/internal/describe.js +3 -9
  27. package/dist/base/block-registry/internal/describe.js.map +1 -1
  28. package/dist/base/block-registry/internal/ui.js +1 -1
  29. package/dist/base/block-registry/internal/ui.js.map +1 -1
  30. package/dist/base/card.d.ts +11 -9
  31. package/dist/base/card.js +2 -0
  32. package/dist/base/card.js.map +1 -1
  33. package/dist/base/chart-card.d.ts +4 -2
  34. package/dist/base/chart-card.js +2 -0
  35. package/dist/base/chart-card.js.map +1 -1
  36. package/dist/base/chart-schemas.d.ts +148 -148
  37. package/dist/base/chart.d.ts +65 -0
  38. package/dist/base/chart.js +65 -0
  39. package/dist/base/chart.js.map +1 -1
  40. package/dist/base/code-block.d.ts +5 -3
  41. package/dist/base/code-block.js +2 -0
  42. package/dist/base/code-block.js.map +1 -1
  43. package/dist/base/custom.d.ts +5 -0
  44. package/dist/base/custom.js +5 -0
  45. package/dist/base/custom.js.map +1 -1
  46. package/dist/base/data-types/default/address.d.ts +5 -0
  47. package/dist/base/data-types/default/address.js +5 -0
  48. package/dist/base/data-types/default/address.js.map +1 -1
  49. package/dist/base/data-types/default/choices.d.ts +20 -0
  50. package/dist/base/data-types/default/choices.js +20 -0
  51. package/dist/base/data-types/default/choices.js.map +1 -1
  52. package/dist/base/data-types/default/files.d.ts +22 -5
  53. package/dist/base/data-types/default/files.js +20 -0
  54. package/dist/base/data-types/default/files.js.map +1 -1
  55. package/dist/base/data-types/default/numbers.d.ts +15 -0
  56. package/dist/base/data-types/default/numbers.js +25 -9
  57. package/dist/base/data-types/default/numbers.js.map +1 -1
  58. package/dist/base/data-types/default/relations.d.ts +10 -2
  59. package/dist/base/data-types/default/relations.js +9 -6
  60. package/dist/base/data-types/default/relations.js.map +1 -1
  61. package/dist/base/data-types/default/strings.d.ts +25 -0
  62. package/dist/base/data-types/default/strings.js +25 -0
  63. package/dist/base/data-types/default/strings.js.map +1 -1
  64. package/dist/base/data-types/default-types.d.ts +1 -1
  65. package/dist/base/data-types/field-types.d.ts +10 -0
  66. package/dist/base/data-types/field-types.js +10 -0
  67. package/dist/base/data-types/field-types.js.map +1 -1
  68. package/dist/base/data-types/internal/relation-endpoints.js +1 -0
  69. package/dist/base/data-types/internal/relation-endpoints.js.map +1 -1
  70. package/dist/base/data-types/status-type.d.ts +5 -0
  71. package/dist/base/data-types/status-type.js +5 -0
  72. package/dist/base/data-types/status-type.js.map +1 -1
  73. package/dist/base/display.d.ts +6 -6
  74. package/dist/base/empty-state.d.ts +15 -13
  75. package/dist/base/empty-state.js +2 -0
  76. package/dist/base/empty-state.js.map +1 -1
  77. package/dist/base/form-block-schema.d.ts +50 -50
  78. package/dist/base/form-schema.d.ts +2 -0
  79. package/dist/base/form-schema.js +2 -0
  80. package/dist/base/form-schema.js.map +1 -1
  81. package/dist/base/grid.d.ts +4 -0
  82. package/dist/base/grid.js +4 -0
  83. package/dist/base/grid.js.map +1 -1
  84. package/dist/base/guard.d.ts +30 -28
  85. package/dist/base/guard.js +2 -0
  86. package/dist/base/guard.js.map +1 -1
  87. package/dist/base/helpers/archive-mode-helpers.d.ts +1 -1
  88. package/dist/base/helpers/file-refs.js +15 -15
  89. package/dist/base/helpers/file-refs.js.map +1 -1
  90. package/dist/base/internal/form-schema-validation.js +7 -1
  91. package/dist/base/internal/form-schema-validation.js.map +1 -1
  92. package/dist/base/internal/realtime-topics.js.map +1 -1
  93. package/dist/base/internal/searchable.d.ts +2 -1
  94. package/dist/base/internal/searchable.js +1 -3
  95. package/dist/base/internal/searchable.js.map +1 -1
  96. package/dist/base/key-value-list.d.ts +21 -19
  97. package/dist/base/key-value-list.js +2 -0
  98. package/dist/base/key-value-list.js.map +1 -1
  99. package/dist/base/kpi-card.d.ts +4 -2
  100. package/dist/base/kpi-card.js +2 -0
  101. package/dist/base/kpi-card.js.map +1 -1
  102. package/dist/base/live-toggle.d.ts +2 -0
  103. package/dist/base/live-toggle.js +2 -0
  104. package/dist/base/live-toggle.js.map +1 -1
  105. package/dist/base/meter.d.ts +23 -21
  106. package/dist/base/meter.js +2 -0
  107. package/dist/base/meter.js.map +1 -1
  108. package/dist/base/nav-card-grid.d.ts +24 -19
  109. package/dist/base/nav-card-grid.js +5 -0
  110. package/dist/base/nav-card-grid.js.map +1 -1
  111. package/dist/base/page-toolbar.d.ts +2 -0
  112. package/dist/base/page-toolbar.js +2 -0
  113. package/dist/base/page-toolbar.js.map +1 -1
  114. package/dist/base/period-selector.d.ts +3 -1
  115. package/dist/base/period-selector.js +2 -0
  116. package/dist/base/period-selector.js.map +1 -1
  117. package/dist/base/placeholder.d.ts +2 -0
  118. package/dist/base/placeholder.js +2 -0
  119. package/dist/base/placeholder.js.map +1 -1
  120. package/dist/base/resource-form-schema.d.ts +2 -2
  121. package/dist/base/searchable.d.ts +3 -2
  122. package/dist/base/searchable.js +2 -2
  123. package/dist/base/searchable.js.map +1 -1
  124. package/dist/base/section.d.ts +6 -2
  125. package/dist/base/section.js +4 -0
  126. package/dist/base/section.js.map +1 -1
  127. package/dist/base/stack.d.ts +6 -0
  128. package/dist/base/stack.js +6 -0
  129. package/dist/base/stack.js.map +1 -1
  130. package/dist/base/stat-group.d.ts +16 -14
  131. package/dist/base/stat-group.js +2 -0
  132. package/dist/base/stat-group.js.map +1 -1
  133. package/dist/base/tab.d.ts +10 -8
  134. package/dist/base/tab.js +2 -0
  135. package/dist/base/tab.js.map +1 -1
  136. package/dist/base/table-view/column-display.d.ts +1 -1
  137. package/dist/base/table-view/column-display.js.map +1 -1
  138. package/dist/base/table-view/data-functions.d.ts +10 -4
  139. package/dist/base/table-view/data-functions.js.map +1 -1
  140. package/dist/base/table-view/factory.d.ts +5 -0
  141. package/dist/base/table-view/factory.js +8 -4
  142. package/dist/base/table-view/factory.js.map +1 -1
  143. package/dist/base/table-view/internal/auth.d.ts +17 -3
  144. package/dist/base/table-view/internal/auth.js +26 -5
  145. package/dist/base/table-view/internal/auth.js.map +1 -1
  146. package/dist/base/table-view/internal/column-conditions.d.ts +8 -1
  147. package/dist/base/table-view/internal/column-conditions.js +25 -13
  148. package/dist/base/table-view/internal/column-conditions.js.map +1 -1
  149. package/dist/base/table-view/internal/column-display.d.ts +1 -2
  150. package/dist/base/table-view/internal/column-display.js +3 -9
  151. package/dist/base/table-view/internal/column-display.js.map +1 -1
  152. package/dist/base/table-view/internal/factory-helpers.d.ts +1 -1
  153. package/dist/base/table-view/internal/factory-helpers.js +17 -14
  154. package/dist/base/table-view/internal/factory-helpers.js.map +1 -1
  155. package/dist/base/table-view/internal/factory-lifecycle-created.d.ts +2 -3
  156. package/dist/base/table-view/internal/factory-lifecycle-created.js +5 -5
  157. package/dist/base/table-view/internal/factory-lifecycle-created.js.map +1 -1
  158. package/dist/base/table-view/internal/factory-lifecycle-filter.d.ts +2 -2
  159. package/dist/base/table-view/internal/factory-private-actions.d.ts +2 -2
  160. package/dist/base/table-view/internal/files.d.ts +2 -1
  161. package/dist/base/table-view/internal/files.js +14 -5
  162. package/dist/base/table-view/internal/files.js.map +1 -1
  163. package/dist/base/table-view/internal/footer.d.ts +3 -3
  164. package/dist/base/table-view/internal/footer.js +16 -15
  165. package/dist/base/table-view/internal/footer.js.map +1 -1
  166. package/dist/base/table-view/internal/guards.d.ts +27 -5
  167. package/dist/base/table-view/internal/guards.js +127 -49
  168. package/dist/base/table-view/internal/guards.js.map +1 -1
  169. package/dist/base/table-view/internal/meta-helpers.d.ts +1 -1
  170. package/dist/base/table-view/internal/meta-helpers.js +3 -4
  171. package/dist/base/table-view/internal/meta-helpers.js.map +1 -1
  172. package/dist/base/table-view/internal/meta.js +2 -3
  173. package/dist/base/table-view/internal/meta.js.map +1 -1
  174. package/dist/base/table-view/internal/option-contract.d.ts +1 -1
  175. package/dist/base/table-view/internal/option-footer.d.ts +2 -2
  176. package/dist/base/table-view/internal/option-row-actions.d.ts +1 -1
  177. package/dist/base/table-view/internal/realtime.d.ts +52 -11
  178. package/dist/base/table-view/internal/realtime.js +23 -16
  179. package/dist/base/table-view/internal/realtime.js.map +1 -1
  180. package/dist/base/table-view/internal/resource-form.d.ts +1 -1
  181. package/dist/base/table-view/internal/resource-form.js +1 -1
  182. package/dist/base/table-view/internal/resource-form.js.map +1 -1
  183. package/dist/base/table-view/internal/row-actions-schema.d.ts +12 -12
  184. package/dist/base/table-view/internal/row-rule-shape.d.ts +11 -5
  185. package/dist/base/table-view/internal/row-rule-shape.js +60 -30
  186. package/dist/base/table-view/internal/row-rule-shape.js.map +1 -1
  187. package/dist/base/table-view/internal/row-rules.d.ts +28 -1
  188. package/dist/base/table-view/internal/row-rules.js +8 -19
  189. package/dist/base/table-view/internal/row-rules.js.map +1 -1
  190. package/dist/base/table-view/internal/tabs.d.ts +1 -1
  191. package/dist/base/table-view/internal/tabs.js +1 -4
  192. package/dist/base/table-view/internal/tabs.js.map +1 -1
  193. package/dist/base/table-view/internal/validation.d.ts +2 -2
  194. package/dist/base/table-view/internal/validation.js +7 -7
  195. package/dist/base/table-view/internal/validation.js.map +1 -1
  196. package/dist/base/table-view/meta.d.ts +7 -6
  197. package/dist/base/table-view/meta.js +12 -7
  198. package/dist/base/table-view/meta.js.map +1 -1
  199. package/dist/base/table-view/resource-form.d.ts +3 -1
  200. package/dist/base/table-view/resource-form.js +2 -0
  201. package/dist/base/table-view/resource-form.js.map +1 -1
  202. package/dist/base/table-view/routes.d.ts +73 -21
  203. package/dist/base/table-view/routes.js +13 -10
  204. package/dist/base/table-view/routes.js.map +1 -1
  205. package/dist/base/table-view/schema.d.ts +152 -152
  206. package/dist/base/table-view/source.js +4 -1
  207. package/dist/base/table-view/source.js.map +1 -1
  208. package/dist/base/table-view.d.ts +1 -1
  209. package/dist/base/table-view.js.map +1 -1
  210. package/dist/base/top-list-card.d.ts +35 -33
  211. package/dist/base/top-list-card.js +2 -0
  212. package/dist/base/top-list-card.js.map +1 -1
  213. package/dist/base/types/error.js +5 -2
  214. package/dist/base/types/error.js.map +1 -1
  215. package/dist/base/types/guards.d.ts +4 -4
  216. package/dist/base/types/json.d.ts +1 -10
  217. package/dist/base/types/row-action.d.ts +7 -7
  218. package/dist/component-options/confirm-dialog.d.ts +2 -0
  219. package/dist/component-options/confirm-dialog.js.map +1 -1
  220. package/dist/component-options/data-type.d.ts +2 -2
  221. package/dist/component-options/data-type.js +7 -7
  222. package/dist/component-options/data-type.js.map +1 -1
  223. package/dist/component-options/row-action.d.ts +14 -9
  224. package/dist/component-slots.d.ts +11 -2
  225. package/dist/component-slots.js +1 -0
  226. package/dist/component-slots.js.map +1 -1
  227. package/dist/component.d.ts +7 -8
  228. package/dist/component.js +17 -25
  229. package/dist/component.js.map +1 -1
  230. package/dist/data-controllers/members.d.ts +11 -7
  231. package/dist/data-controllers/members.js +1 -1
  232. package/dist/data-controllers/members.js.map +1 -1
  233. package/dist/data-controllers/roles.d.ts +32 -10
  234. package/dist/db/internal/exportJobs.model.d.ts +7 -5
  235. package/dist/db/internal/inviteResolutions.model.d.ts +7 -5
  236. package/dist/db/internal/tenantLifecycle.model.d.ts +7 -5
  237. package/dist/db/models/roles.model.d.ts +7 -5
  238. package/dist/db/models/tenantMembers.model.d.ts +7 -5
  239. package/dist/db/models/tenants.model.d.ts +7 -5
  240. package/dist/db/models/user_invites.model.d.ts +7 -5
  241. package/dist/db/tables/tenants.table.d.ts +9 -0
  242. package/dist/db/tables/tenants.table.js +4 -0
  243. package/dist/db/tables/tenants.table.js.map +1 -1
  244. package/dist/guards.d.ts +1 -1
  245. package/dist/hooks.d.ts +10 -9
  246. package/dist/hooks.js +42 -33
  247. package/dist/hooks.js.map +1 -1
  248. package/dist/internal/attachments.d.ts +2 -2
  249. package/dist/internal/component-builder.js +2 -1
  250. package/dist/internal/component-builder.js.map +1 -1
  251. package/dist/internal/component-serialization.d.ts +2 -4
  252. package/dist/internal/component-serialization.js +4 -3
  253. package/dist/internal/component-serialization.js.map +1 -1
  254. package/dist/internal/component-slots.d.ts +19 -2
  255. package/dist/internal/component-slots.js +35 -12
  256. package/dist/internal/component-slots.js.map +1 -1
  257. package/dist/internal/component-watch-filter.d.ts +11 -0
  258. package/dist/internal/component-watch-filter.js +22 -0
  259. package/dist/internal/component-watch-filter.js.map +1 -0
  260. package/dist/internal/component-watches.js +0 -1
  261. package/dist/internal/component-watches.js.map +1 -1
  262. package/dist/internal/own-entry.d.ts +7 -0
  263. package/dist/internal/own-entry.js +13 -0
  264. package/dist/internal/own-entry.js.map +1 -0
  265. package/dist/invite-extension-payloads.d.ts +14 -2
  266. package/dist/invite-extensions/internal/delivery.js +1 -2
  267. package/dist/invite-extensions/internal/delivery.js.map +1 -1
  268. package/dist/invite-extensions/internal/edit.d.ts +2 -1
  269. package/dist/invite-extensions/internal/edit.js +8 -9
  270. package/dist/invite-extensions/internal/edit.js.map +1 -1
  271. package/dist/invite-extensions/internal/form-slot.js +8 -15
  272. package/dist/invite-extensions/internal/form-slot.js.map +1 -1
  273. package/dist/invite-extensions/internal/payload-slices.d.ts +33 -3
  274. package/dist/invite-extensions/internal/payload-slices.js +84 -19
  275. package/dist/invite-extensions/internal/payload-slices.js.map +1 -1
  276. package/dist/invite-extensions/internal/types.d.ts +10 -1
  277. package/dist/invite-resolution.js +6 -4
  278. package/dist/invite-resolution.js.map +1 -1
  279. package/dist/json.d.ts +10 -0
  280. package/dist/json.js +3 -0
  281. package/dist/json.js.map +1 -0
  282. package/dist/layout-banners.d.ts +5 -2
  283. package/dist/layout-banners.js.map +1 -1
  284. package/dist/page/controllers.d.ts +2 -2
  285. package/dist/page/internal/extension-validation.js +3 -2
  286. package/dist/page/internal/extension-validation.js.map +1 -1
  287. package/dist/page/internal/metadata-layout.js +1 -1
  288. package/dist/page/internal/metadata-layout.js.map +1 -1
  289. package/dist/page/internal/metadata-publish.js +3 -2
  290. package/dist/page/internal/metadata-publish.js.map +1 -1
  291. package/dist/page/internal/metadata-registration.js +5 -4
  292. package/dist/page/internal/metadata-registration.js.map +1 -1
  293. package/dist/page/internal/metadata-upload-registration.d.ts +3 -1
  294. package/dist/page/internal/metadata-upload-registration.js +9 -0
  295. package/dist/page/internal/metadata-upload-registration.js.map +1 -1
  296. package/dist/page/internal/metadata-uploads.d.ts +18 -5
  297. package/dist/page/internal/metadata-uploads.js +7 -8
  298. package/dist/page/internal/metadata-uploads.js.map +1 -1
  299. package/dist/page/internal/page-record.d.ts +2 -3
  300. package/dist/page/internal/page-record.js +19 -14
  301. package/dist/page/internal/page-record.js.map +1 -1
  302. package/dist/page/layout-filter.js +17 -6
  303. package/dist/page/layout-filter.js.map +1 -1
  304. package/dist/page/metadata.js +5 -7
  305. package/dist/page/metadata.js.map +1 -1
  306. package/dist/request-tenant.d.ts +10 -4
  307. package/dist/request-tenant.js +16 -34
  308. package/dist/request-tenant.js.map +1 -1
  309. package/dist/tenant-export.d.ts +2 -1
  310. package/dist/tenant-lifecycle.d.ts +13 -4
  311. package/dist/tenant-lifecycle.js +51 -18
  312. package/dist/tenant-lifecycle.js.map +1 -1
  313. package/dist/types.d.ts +20 -0
  314. package/dist/uploads.js +42 -59
  315. package/dist/uploads.js.map +1 -1
  316. package/dist/utils/fire-and-forget.js.map +1 -1
  317. package/dist/utils/internal/decorated-class.d.ts +14 -0
  318. package/dist/utils/internal/decorated-class.js +37 -0
  319. package/dist/utils/internal/decorated-class.js.map +1 -0
  320. package/dist/utils/internal/type-check.d.ts +9 -0
  321. package/dist/utils/internal/type-check.js +13 -5
  322. package/dist/utils/internal/type-check.js.map +1 -1
  323. package/dist/utils/internal/value-parser.d.ts +1 -1
  324. package/dist/utils/internal/value-parser.js +22 -9
  325. package/dist/utils/internal/value-parser.js.map +1 -1
  326. package/dist/watch-actions.d.ts +1 -1
  327. package/docs/1.core/1.introduction.md +82 -77
  328. package/docs/1.core/10.layout-banners.md +57 -45
  329. package/docs/1.core/11.modules-and-dynamic-menus.md +178 -0
  330. package/docs/1.core/12.frontend-modules-and-request-helpers.md +155 -0
  331. package/docs/1.core/13.tenant-data-export.md +120 -0
  332. package/docs/1.core/2.pages-and-modules.md +140 -367
  333. package/docs/1.core/3.components.md +21 -22
  334. package/docs/1.core/4.permissions.md +92 -71
  335. package/docs/1.core/5.tenancy.md +112 -86
  336. package/docs/1.core/6.invites.md +90 -65
  337. package/docs/1.core/7.hooks.md +96 -166
  338. package/docs/1.core/8.realtime.md +44 -45
  339. package/docs/1.core/9.quick-actions.md +37 -30
  340. package/docs/2.auth/1.introduction.md +33 -35
  341. package/docs/2.auth/2.authentication.md +60 -38
  342. package/docs/2.auth/3.tokens-and-sessions.md +56 -55
  343. package/docs/2.auth/4.users.md +82 -52
  344. package/docs/2.auth/5.external-identities.md +25 -26
  345. package/docs/3.base/1.introduction.md +64 -60
  346. package/docs/3.base/10.display-blocks.md +15 -16
  347. package/docs/3.base/11.page-layouts.md +273 -0
  348. package/docs/3.base/12.table-row-actions.md +122 -0
  349. package/docs/3.base/13.table-filters-and-forms.md +104 -0
  350. package/docs/3.base/14.table-events-and-helpers.md +114 -0
  351. package/docs/3.base/15.table-sources-and-gates.md +24 -0
  352. package/docs/3.base/2.types.md +44 -41
  353. package/docs/3.base/3.forms.md +27 -28
  354. package/docs/3.base/4.tables.md +34 -367
  355. package/docs/3.base/5.charts-and-widgets.md +28 -29
  356. package/docs/3.base/6.layout.md +21 -270
  357. package/docs/3.base/8.data-types.md +39 -40
  358. package/docs/3.base/9.helpers.md +36 -38
  359. package/docs/4.notifications/1.introduction.md +22 -26
  360. package/docs/4.notifications/2.categories-and-subjects.md +58 -55
  361. package/docs/4.notifications/3.sending.md +72 -68
  362. package/docs/5.html-render/1.introduction.md +119 -81
  363. package/docs/5.html-render/2.built-in-emails.md +71 -51
  364. package/docs/index.md +18 -29
  365. package/docs/tsconfig.json +4 -0
  366. package/package.json +12 -12
  367. package/docs/images/emails-admin-invite.png +0 -0
  368. package/docs/images/emails-change-notice.png +0 -0
  369. package/docs/images/emails-change-verification.png +0 -0
  370. package/docs/images/emails-digest-logo-dark.png +0 -0
  371. package/docs/images/emails-digest-logo-light.png +0 -0
  372. package/docs/images/emails-digest.png +0 -0
  373. package/docs/images/emails-export-partial.png +0 -0
  374. package/docs/images/emails-export-ready.png +0 -0
  375. package/docs/images/emails-reset-password.png +0 -0
  376. package/docs/images/emails-two-factor.png +0 -0
  377. package/docs/images/emails-user-validation.png +0 -0
@@ -1,19 +1,18 @@
1
1
  ---
2
2
  title: "Invites"
3
- description: "An invite brings a person into a tenant by email."
3
+ description: "Invite functions, the UserInvite table and model, invite extensions, durable invite resolution, and invite availability."
4
+ mode: reference
4
5
  ---
5
6
 
6
- # Invites
7
-
8
7
  ## Overview
9
8
 
10
- An invite brings a person into a tenant by email. `inviteUserToTenant` is the entry point: when the email already belongs to a user it grants them membership directly, and otherwise it creates a token-bearing invite row the person redeems later. The two outcomes are distinguished by the `kind` field of the result.
9
+ An invite brings a person into a tenant by email. `inviteUserToTenant` is the entry point. When the email already belongs to a user, it grants them membership directly. Otherwise it creates an invite row with a token, which the person redeems later. The `kind` field of the result tells the two outcomes apart.
11
10
 
12
- The functions live in `@antelopejs/interface-dms/invites`; the `UserInvite` table and its model live in `@antelopejs/interface-dms/db`.
11
+ The functions live in `@antelopejs/interface-dms/invites`. The `UserInvite` table and its model live in `@antelopejs/interface-dms/db`.
13
12
 
14
- ## Invite a User
13
+ ## Invite a user
15
14
 
16
- ```typescript
15
+ ```typescript fragment
17
16
  import { inviteUserToTenant } from "@antelopejs/interface-dms/invites";
18
17
 
19
18
  const result = await inviteUserToTenant({
@@ -38,17 +37,17 @@ return { inviteId: result.inviteId, token: result.token };
38
37
  | Option | Type | Description |
39
38
  | ------ | ---- | ----------- |
40
39
  | `tenantId` | `string` | Tenant the person is invited into. Required. |
41
- | `email` | `string` | Email to look up and, failing that, to invite. Required. |
40
+ | `email` | `string` | Email to look up, and to invite when no account has it. Required. |
42
41
  | `firstname` | `string \| null` | Invitee's first name, stored on the invite row and used to address the email. Defaults to `null`. |
43
42
  | `lastname` | `string \| null` | Invitee's last name. Defaults to `null`. |
44
43
  | `language` | `string` | Language stored on the invite row. Defaults to `"en"`. |
45
44
  | `roleIds` | `string[]` | Roles granted on join. Defaults to `[]`. |
46
45
  | `asTenantOwner` | `boolean` | Grant tenant ownership on join. Defaults to `false`. |
47
- | `sendEmail` | `boolean` | Dispatch the admin invite email after the row is created. Defaults to `false`. |
48
- | `awaitEmailDelivery` | `boolean` | With `sendEmail`, wait for the email and report its outcome as `emailDelivery` instead of sending it in the background. Defaults to `false`. |
49
- | `inviterName` | `string` | Name of the sender shown in the invitation email. |
46
+ | `sendEmail` | `boolean` | Send the invitation email through `sendAdminInviteEmail` after the row is created. Defaults to `false`. |
47
+ | `awaitEmailDelivery` | `boolean` | With `sendEmail`, wait for the email and report its outcome as `emailDelivery`, instead of sending it in the background. Defaults to `false`. |
48
+ | `inviterName` | `string` | Name of the sender, shown in the invitation email. |
50
49
  | `invitedBy` | `string \| null` | Id of the inviting user, stored on the invitation. |
51
- | `extensions` | `InviteExtensionPayloads` | Payloads keyed by registered invite extension key. |
50
+ | `extensions` | `InviteExtensionPayloads` | Payloads keyed by the key of a registered invite extension. |
52
51
 
53
52
  ### `InviteUserToTenantResult`
54
53
 
@@ -67,11 +66,15 @@ interface InvitedUserResult {
67
66
  }
68
67
  ```
69
68
 
70
- The `"added"` branch runs `applyTenantOwnership` with `roleIds` and `asTenantOwner` ([Tenancy](/docs/interfaces/core/tenancy)), so the member hooks fire and no token is generated. The `"invited"` branch creates the invite row through `createUserInviteToken`, then dispatches the email when `sendEmail` is set. By default that is fire-and-forget: the call does not wait on delivery and does not fail when delivery does.
69
+ The whole call goes through [`changeTenantMembers`](/docs/interfaces/core/tenancy#changetenantmembers), so it respects tenant lifecycle admission.
71
70
 
72
- Pass `awaitEmailDelivery: true` when someone is waiting on the answer and has to learn that the email did not leave. The call then waits for the email and sets `emailDelivery` to `"sent"` or `"failed"`. It still does not throw: the invitation is kept either way, so the caller can offer to resend it. The failure's details (the provider's error) go to the server log only; tell the user something generic. The DMS members **Invite** form and the pending invitations' **Resend** action both work this way.
71
+ The `"added"` branch writes the membership the way `applyTenantOwnership` does, with `roleIds` and `asTenantOwner` ([Tenancy](/docs/interfaces/core/tenancy)). The member hooks fire and no token is generated. The branch then delivers the `extensions` payloads to their extensions at once, because no invitation exists to wait on. A delivery failure at that point is logged and not raised, since the user is already a member.
73
72
 
74
- ```typescript
73
+ The `"invited"` branch creates the invite row the way `createUserInviteToken` does, then sends the email when `sendEmail` is set. By default the email goes out in the background. The call does not wait for delivery and does not fail when delivery fails.
74
+
75
+ Pass `awaitEmailDelivery: true` when someone waits for the answer and must learn that the email did not leave. The call then waits for the email and sets `emailDelivery` to `"sent"` or `"failed"`. It still does not throw. The invitation is kept either way, so the caller can offer to resend it. The details of the failure, such as the provider's error, go to the server log only, so show the user a generic message. The DMS members **Invite** form and the **Resend** action on pending invitations both work this way.
76
+
77
+ ```typescript fragment
75
78
  const result = await inviteUserToTenant({
76
79
  tenantId,
77
80
  email: "alice@example.com",
@@ -84,13 +87,13 @@ if (result.kind === "invited" && result.emailDelivery === "failed") {
84
87
  }
85
88
  ```
86
89
 
87
- The function is deliberately side-effect-light: it does not throw on duplicates and performs no context-specific pre-checks. Decide in the caller what "already a member" should answer.
90
+ `inviteUserToTenant` does not throw on duplicates and runs no checks specific to a context. Decide in the caller what to answer when the person is already a member.
88
91
 
89
- ## Create an Invite Token Directly
92
+ ## Create an invite token directly
90
93
 
91
- `createUserInviteToken` is the lower-level half — it always creates a row and never touches memberships or email.
94
+ `createUserInviteToken` is the lower-level function. It always creates a row, and it never touches memberships or email.
92
95
 
93
- ```typescript
96
+ ```typescript fragment
94
97
  import { createUserInviteToken } from "@antelopejs/interface-dms/invites";
95
98
 
96
99
  const { inviteId, token } = await createUserInviteToken({
@@ -102,15 +105,28 @@ const { inviteId, token } = await createUserInviteToken({
102
105
  });
103
106
  ```
104
107
 
105
- `CreateUserInviteTokenOptions` requires `tenantId`, `email`, `language`, `roleIds` and `asTenantOwner`; `firstname` and `lastname` are optional and default to `null`. Optional `invitedBy` records the sender and `extensions` carries `InviteExtensionPayloads`. `replacementReason` selects `"replaced"` (default) or `"resent"` when retiring an existing invitation. `CreateUserInviteTokenResult` is `{ inviteId: string; token: string }`.
108
+ `CreateUserInviteTokenOptions` has these fields:
106
109
 
107
- Optional `replacesInvite: UserInvite` identifies the exact incarnation being replaced, including a retained snapshot during a retry.
110
+ | Option | Type | Description |
111
+ | ------ | ---- | ----------- |
112
+ | `tenantId` | `string` | Required. |
113
+ | `email` | `string` | Required. Stored trimmed and lowercased. |
114
+ | `language` | `string` | Required. |
115
+ | `roleIds` | `string[]` | Required. |
116
+ | `asTenantOwner` | `boolean` | Required. |
117
+ | `firstname`, `lastname` | `string \| null` | Optional. Default to `null`. |
118
+ | `invitedBy` | `string \| null` | Optional. Records the sender. `null` when nobody signed in sent it. |
119
+ | `extensions` | `InviteExtensionPayloads` | Optional. |
120
+ | `replacementReason` | `"replaced" \| "resent"` | How to report the retirement of an invitation this one displaces. Defaults to `"replaced"`. A resend passes `"resent"`, which reissues the same invitation, so contributors do not undo what it carries. |
121
+ | `replacesInvite` | `UserInvite` | The exact incarnation to replace, including a retained snapshot during a retry. |
122
+
123
+ `CreateUserInviteTokenResult` is `{ inviteId: string; token: string }`.
108
124
 
109
- `inviteeDisplayName(firstname?, lastname?)` joins the two into the name the invite email addresses the person by, and returns `undefined` when the invite carries neither. `inviteUserToTenant` calls it for you; call it yourself when you render your own invite surface from a stored row, so the fallback for a nameless invite matches what the email does.
125
+ An existing invite for the same email in the same tenant is retired through a durable decision. Completion invokes `Hook.INVITE_DELETED` for the old invitation, creates the replacement through `Hook.INVITE_BEING_CREATED` and `Hook.INVITE_CREATED`, and removes the old row. A failed completion can replay hooks with the same delivery identity. See [Durable invite resolution](#durable-invite-resolution) and [Hooks](/docs/interfaces/core/hooks).
110
126
 
111
- An existing invite for the same email in the same tenant is retired through a durable decision. Completion invokes `Hook.INVITE_DELETED` for the old invitation, then creates the replacement through `Hook.INVITE_BEING_CREATED` and `Hook.INVITE_CREATED`, and removes the old row. Failed completion can replay hooks with the same delivery identity; see [durable invite resolution](#durable-invite-resolution) and [Hooks](/docs/interfaces/core/hooks).
127
+ `inviteeDisplayName(firstname?, lastname?)` joins the two names into the name the invite email uses, and returns `undefined` when the invite carries neither. `inviteUserToTenant` calls it for you. Call it yourself when you render your own invite screen from a stored row, so a nameless invite falls back the same way the email does.
112
128
 
113
- ## Token Constants
129
+ ## Token constants
114
130
 
115
131
  | Constant | Value | Meaning |
116
132
  | -------- | ----- | ------- |
@@ -124,24 +140,27 @@ import {
124
140
  } from "@antelopejs/interface-dms/invites";
125
141
  ```
126
142
 
127
- ## The `UserInvite` Table
143
+ ## The `UserInvite` table
128
144
 
129
- Table `user_invites` in the `dms-tenant` schema, so invites are per-tenant like memberships. The table-name constant `USER_INVITES_TABLE_NAME` is exported next to it.
145
+ Table `user_invites` in the `dms-tenant` schema, so invites are per tenant, like memberships. The table-name constant `USER_INVITES_TABLE_NAME` is exported next to it.
130
146
 
131
147
  | Field | Type | Notes |
132
148
  | ----- | ---- | ----- |
133
- | `_id` | `string` | Invite id — the `inviteId` the create functions return. |
134
- | `createdAt` | `Date` | Creation time, indexed. |
135
- | `email` | `string` | Indexed. |
149
+ | `_id` | `string` | Invite id. The create functions return it as `inviteId`. |
150
+ | `createdAt` | `Date` | Creation time. Indexed across tenant instances. |
151
+ | `email` | `string` | Stored trimmed and lowercased. Indexed across tenant instances. |
136
152
  | `firstname` | `string \| null` | Invitee's first name, when the invite carried one. |
137
153
  | `lastname` | `string \| null` | Invitee's last name, when the invite carried one. |
138
154
  | `roles_ids` | `string[]` | Related to `Role`, many. Roles to grant on redemption. |
139
155
  | `language` | `string` | Language the invite was issued in. |
140
- | `token` | `string` | Indexed. The secret handed to the invitee. |
156
+ | `token` | `string` | The secret handed to the invitee. Indexed across tenant instances. |
141
157
  | `asTenantOwner` | `boolean` | Grant tenant ownership on redemption. |
142
- | `expiresAt` | `Date` | Indexed. `INVITE_EXPIRY_DAYS` after creation. |
158
+ | `expiresAt` | `Date` | `INVITE_EXPIRY_DAYS` after creation. Indexed across tenant instances. |
159
+ | `creationResolutionId` | `string`, optional | Set on a replacement. The replacement is actionable only after the resolution that created it completes. |
160
+ | `invitedBy` | `string \| null`, optional | Id of the user who sent the invitation or last resent it. `null` for an invitation created outside a signed-in request, such as an import or a module. |
161
+ | `extensions` | `InviteExtensionPayloads \| null` | Payloads attached through `RegisterInviteExtension`, keyed by extension key. Delivered when the invitee joins, and deleted with the row when they do not. |
143
162
 
144
- Note the field is `roles_ids`, not `roleIds` — the membership field of that name lives on `TenantMember` ([Tenancy](/docs/interfaces/core/tenancy)).
163
+ The field is `roles_ids`, not `roleIds`. The membership field `roleIds` lives on `TenantMember` ([Tenancy](/docs/interfaces/core/tenancy)).
145
164
 
146
165
  ## `UserInviteModel`
147
166
 
@@ -152,9 +171,9 @@ Note the field is `roles_ids`, not `roleIds` — the membership field of that na
152
171
  | `getByEmail(email)` | `Promise<UserInvite \| undefined>` |
153
172
  | `getByToken(token)` | `Promise<UserInvite \| undefined>` |
154
173
  | `getByTokenWithTenant(token)` | `Promise<{ invite: UserInvite; tenantId: string } \| undefined>` |
155
- | `deleteByToken(token)` | Deletes every row carrying the token |
174
+ | `deleteByToken(token)` | Deletes every row that carries the token. |
156
175
 
157
- Invitations are stored with their e-mail trimmed and lowercased, and `getByEmail` normalizes its argument the same way, so the casing a caller passes does not matter.
176
+ `getByEmail` trims and lowercases its argument the same way the stored email is, so the casing a caller passes does not matter.
158
177
 
159
178
  ```ts docs-check
160
179
  import { GetModel } from "@antelopejs/interface-database-decorators";
@@ -166,28 +185,28 @@ export async function hasExpiredInvite(tenantId: string, email: string): Promise
166
185
  }
167
186
  ```
168
187
 
169
- `getByTokenWithTenant` reports the tenant the row came from, which is what a redemption flow needs: the person following an invite link is not authenticated yet, so there is no tenant claim to bind the handle to.
188
+ `getByTokenWithTenant` reports the tenant the row came from. A redemption flow needs it, because the person who follows an invite link is not authenticated yet, so no tenant claim exists to bind the handle to.
170
189
 
171
- Raw deletion, including `deleteByToken`, does not coordinate durable decisions or extension cleanup. Use the invite-resolution contract below for terminal actions, not direct model writes.
190
+ Raw deletion, `deleteByToken` included, does not coordinate durable decisions or extension cleanup. For terminal actions, use the invite resolution contract below instead of direct model writes.
172
191
 
173
192
  ## `RegisterInviteExtension`
174
193
 
175
- `RegisterInviteExtension<T>(options: InviteExtensionOptions<T>): () => void`, from `@antelopejs/interface-dms/invite-extensions`, contributes fields to the members invite form. Registration belongs to the module and is removed when it stops; the returned function removes it earlier.
194
+ `RegisterInviteExtension<T>(options: InviteExtensionOptions<T>): () => void`, from `@antelopejs/interface-dms/invite-extensions`, adds fields to the members invite form. The registration belongs to the module and is removed when the module stops. The returned function removes it earlier.
176
195
 
177
196
  | Option | Type | Contract |
178
197
  | --- | --- | --- |
179
- | `key` | `string` | Required non-empty namespace. Must not contain `__`, the field-id separator. |
180
- | `component` | `FormBuilder` | Required form whose fields join the invite modal. |
181
- | `schema` | `ZodType<T, ZodTypeDef, unknown>` | Required validator at submission and delivery. Uses unprefixed field ids; callbacks receive parsed output `T`. |
182
- | `onAccept` | `InviteAcceptHandler<T>` | Required callback after membership exists. |
183
- | `onCleanup` | `InviteCleanupHandler<T>` | Optional cleanup on cancellation, replacement, expiry or member removal, never acceptance. |
184
- | `editable` | `boolean` | Defaults to `true`. `false` makes fields read-only on the pending-invitation edit form. |
185
- | `onUpdate` | `InviteUpdateHandler<T>` | Called after a changed pending payload is stored. Failure is logged, not raised to the caller. |
186
- | `label` | `string` | Heading, defaulting to the form's title. |
198
+ | `key` | `string` | Required, non-empty namespace. It must not contain `__`, the separator between the key and a field id. Registration throws otherwise. |
199
+ | `component` | `FormBuilder` | Required. The form whose fields join the invite modal. |
200
+ | `schema` | `ZodType<T, ZodTypeDef, unknown>` | Required. Validates the payload at submission and again at delivery. Its keys are the field ids of `component`, without the prefix. Callbacks receive the parsed output `T`. |
201
+ | `onAccept` | `InviteAcceptHandler<T>` | Required. Called after the membership exists. |
202
+ | `onCleanup` | `InviteCleanupHandler<T>` | Optional. Called on cancellation, replacement, expiry, or member removal, and never on acceptance. |
203
+ | `editable` | `boolean` | Defaults to `true`. `false` shows the fields read-only on the edit form of a pending invitation. |
204
+ | `onUpdate` | `InviteUpdateHandler<T>` | Called after a changed payload on a pending invitation is stored. A failure is logged and not raised to the caller. |
205
+ | `label` | `string` | Heading of the contributed block. Defaults to the title of the form. |
187
206
  | `description` | `string` | Description of the contribution. |
188
- | `placement` | `InviteExtensionPlacement` | Optional `side` (`"before"`, `"after"`, `"end"`), `anchorField`, and numeric `order`. Defaults to end, order 0. |
207
+ | `placement` | `InviteExtensionPlacement` | Optional `side` (`"before"`, `"after"`, `"end"`), `anchorField`, and numeric `order`. Defaults to the end, order 0. |
189
208
 
190
- `anchorField` names a top-level field or group of the invite form. Without an anchor, `before` places the contribution first; `after` and `end` append it. Lower orders come first, with extension keys breaking ties. Form field ids are namespaced by `key`; stored `InviteExtensionPayloads` is `Record<string, unknown>`, keyed by extension.
209
+ `anchorField` names a top-level field or field group of the invite form. Without an anchor, `before` places the contribution first, and `after` and `end` append it. Lower orders come first, and extension keys break ties. The key namespaces the form field ids. The stored `InviteExtensionPayloads` type is `Record<string, InviteExtensionJson>`, keyed by extension, where `InviteExtensionJson` is a JSON value that may be read-only.
191
210
 
192
211
  ### Callback contracts
193
212
 
@@ -197,32 +216,38 @@ Raw deletion, including `deleteByToken`, does not coordinate durable decisions o
197
216
  | `InviteUpdateHandler<T>` | `(payload: T, previous: T \| undefined, context: InviteExtensionContext)` | `MaybePromise<void>` |
198
217
  | `InviteCleanupHandler<T>` | `(payload: T \| undefined, context: InviteCleanupContext)` | `MaybePromise<void>` |
199
218
 
200
- `InviteExtensionContext` has `tenantId`, `email`, and optional `deliveryId` and `inviteId`. Direct addition of an existing account calls `onAccept` without an `inviteId`. `previous` is undefined when no old payload exists or it no longer validates.
219
+ `InviteExtensionContext` has `tenantId`, `email`, and optional `deliveryId` and `inviteId`. When an existing account is added directly, `onAccept` runs without an `inviteId`. `previous` is `undefined` when no old payload exists or the old payload no longer validates.
220
+
221
+ `InviteCleanupContext` has `tenantId`, `reason: "invite-deleted" | "member-removed"`, and optional `deliveryId`, `inviteId`, `email` and `userId`. Invite cleanup sets `inviteId`. Member cleanup sets `userId`. Durable delivery may replay concurrently with the same `deliveryId`, so deduplicate external effects and scope the cleanup of invite resources to `inviteId`. The [durable delivery guidance](/docs/building/backend-services#extension-and-hook-delivery) lists the operational obligations.
201
222
 
202
- `InviteCleanupContext` has `tenantId`, `reason: "invite-deleted" | "member-removed"`, and optional `deliveryId`, `inviteId`, `email`, and `userId`. Invite cleanup identifies the invitation; member cleanup identifies the user. Durable delivery may replay concurrently with the same `deliveryId`: deduplicate external effects and scope invite resource cleanup to `inviteId`. See [durable delivery guidance](/docs/building/backend-services#extension-and-hook-delivery) for operational obligations.
223
+ ## Durable invite resolution
203
224
 
204
- ## Durable Invite Resolution
225
+ The functions in `@antelopejs/interface-dms/invite-resolution` coordinate competing terminal actions. They do not authorize the caller. Prefer the higher-level invitation entry points, unless you implement a terminal action yourself.
205
226
 
206
- The functions in `@antelopejs/interface-dms/invite-resolution` coordinate competing terminal actions. They do not authorize the caller. Prefer the higher-level invitation entry points unless implementing a terminal action yourself.
227
+ | Function | Signature | Result |
228
+ | --- | --- | --- |
229
+ | `loadInviteForAction` | `(tenantId: string, inviteId: string) => Promise<UserInvite \| undefined>` | Loads the exact invitation, or its durable snapshot after the live row is gone. |
230
+ | `assertInviteReady` | `(tenantId: string, invite: UserInvite) => Promise<void>` | Rejects with HTTP 409 (`Invitation creation is still pending`) while the creation of a replacement is incomplete. |
231
+ | `decideInvite` | `(input: ResolveInviteInput) => Promise<InviteResolution>` | Records one permanent terminal outcome before any effect. A conflicting reason or user rejects with HTTP 409, and so does conflicting replacement content. A new acceptance of an expired invitation also rejects with 409. |
232
+ | `completeInviteResolution` | `(resolution: InviteResolution) => Promise<void>` | Enters tenant lifecycle admission through `changeTenantMembers` and replays the effects. A callback failure retains the snapshot for a retry. |
207
233
 
208
- | Function | Signature and result |
209
- | --- | --- |
210
- | `loadInviteForAction` | `(tenantId: string, inviteId: string) => Promise<UserInvite \| undefined>` — loads the exact invitation or its durable snapshot after the live row is gone. |
211
- | `assertInviteReady` | `(tenantId: string, invite: UserInvite) => Promise<void>` — rejects with HTTP 409 while a replacement's creation is incomplete. |
212
- | `decideInvite` | `(input: ResolveInviteInput) => Promise<InviteResolution>` — records one permanent terminal outcome before effects. Conflicting reason, user or replacement content rejects with HTTP 409. A new acceptance of an expired invitation also rejects. |
213
- | `completeInviteResolution` | `(resolution: InviteResolution) => Promise<void>` — enters tenant lifecycle admission and replays effects; callback failures retain the snapshot for retry. |
234
+ `ResolveInviteInput` contains `tenantId`, `invite: UserInvite`, `reason: InviteResolutionReason`, and optional `userId` and `replacement: UserInvite`. `InviteResolutionReason` is `"accepted" | "cancelled" | "replaced" | "resent" | "expired"`. The API captures the extension keys itself, so callers do not supply them.
214
235
 
215
- `ResolveInviteInput` contains `tenantId`, `invite: UserInvite`, `reason: InviteResolutionReason`, and optional `userId` and `replacement: UserInvite`. `InviteResolutionReason` is `"accepted" | "cancelled" | "replaced" | "resent" | "expired"`. The API captures extension keys itself; callers do not supply them.
236
+ `InviteResolution`, from `@antelopejs/interface-dms/db`, is the stored decision and retry snapshot. Its fields are `_id`, `tenantId`, `reason`, nullable `userId`, `invite`, optional `inviteToken`, nullable `replacement`, `extensionKeys`, `revision`, `membershipPhase`, `replacementPhase`, `completed` and `decidedAt`. Both phase fields use `InviteMembershipPhase` (`"pending" | "applying" | "applied"`). Treat a resolution as a read-only result and pass it back to completion. Do not change the model to advance phases.
216
237
 
217
- `InviteResolution` (from `/db/tables/inviteResolutions.table`) is the stored decision and retry snapshot: `_id`, `tenantId`, `reason`, nullable `userId`, `invite`, optional `inviteToken`, nullable `replacement`, `extensionKeys`, `revision`, `membershipPhase`, `replacementPhase`, `completed`, and `decidedAt`. Both phase fields use `InviteMembershipPhase` (`"pending" | "applying" | "applied"`). Treat these as read-only results and pass the decision back to completion; do not mutate the model to advance phases.
238
+ Custom producers of memberships or invitations must follow [tenant lifecycle admission](/docs/interfaces/core/tenancy#tenant-lifecycle-admission). Every competing terminal path must decide before it produces effects. A durable decision does not make external effects exactly-once, so callback implementations still own their idempotency.
218
239
 
219
- Custom membership/invite producers must follow [tenant lifecycle admission](/docs/interfaces/core/tenancy#tenant-lifecycle-admission), and all competing terminal paths must decide before producing effects. A durable decision does not make external effects exactly-once; callback implementations still own idempotency.
240
+ ## Mark the invite action unavailable
220
241
 
221
- ## Mark the Invite Action Unavailable
242
+ `RegisterInviteAvailability`, from `@antelopejs/interface-dms/invite-extensions`, lets a module disable the **Invite** button of the members page while one of its conditions holds, such as a plan whose seats are all taken. The resolver is an `InviteAvailabilityResolver`. It runs once per request while the page layout is built, with a `ComponentFilterContext` that carries `tenantId` and `user`. It returns one of three values:
222
243
 
223
- `RegisterInviteAvailability`, from `@antelopejs/interface-dms/invite-extensions`, lets a module disable the members page's **Invite** button while one of its conditions holds — a plan whose seats are all taken, say. The resolver runs per request while the page layout is built, with `{ tenantId, user }`; returning `{ reason }` disables the button and shows the reason next to it, `undefined` leaves it enabled. The first resolver to refuse wins, and one that throws is logged and ignored.
244
+ - `{ reason }` disables the button and shows the reason next to it. A `$`-prefixed reason resolves as an i18n key.
245
+ - `{ hidden: true }` hides the button.
246
+ - `undefined` leaves the button enabled.
224
247
 
225
- ```typescript
248
+ Resolvers run in registration order, and the first one that refuses wins. A resolver that throws is logged and ignored.
249
+
250
+ ```typescript fragment
226
251
  import { RegisterInviteAvailability } from "@antelopejs/interface-dms/invite-extensions";
227
252
 
228
253
  RegisterInviteAvailability(async ({ tenantId }) =>
@@ -232,8 +257,8 @@ RegisterInviteAvailability(async ({ tenantId }) =>
232
257
  );
233
258
  ```
234
259
 
235
- It only shapes the UI. A module that must refuse the invitation itself does so from `Hook.INVITE_BEING_CREATED` and `Hook.MEMBER_BEING_ADDED`. The registration is lifted when the registering module stops; the returned function removes it earlier.
260
+ The resolver only shapes the UI. A module that must refuse the invitation itself does so from `Hook.INVITE_BEING_CREATED` and `Hook.MEMBER_BEING_ADDED`. The registration is lifted when the registering module stops, and the returned function removes it earlier.
236
261
 
237
- ## Next Steps
262
+ ## Next steps
238
263
 
239
264
  [Hooks](/docs/interfaces/core/hooks) covers the invite and membership events these functions fire, and how to react to them.