@antelopejs/dms-saas 0.0.1

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 (687) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +658 -0
  3. package/dist/auth/index.d.ts +3 -0
  4. package/dist/auth/index.js +20 -0
  5. package/dist/auth/index.js.map +1 -0
  6. package/dist/auth/oauth-entry.d.ts +5 -0
  7. package/dist/auth/oauth-entry.js +10 -0
  8. package/dist/auth/oauth-entry.js.map +1 -0
  9. package/dist/auth/plan-permissions-resolver.d.ts +1 -0
  10. package/dist/auth/plan-permissions-resolver.js +44 -0
  11. package/dist/auth/plan-permissions-resolver.js.map +1 -0
  12. package/dist/auth/subscription-access-gate.d.ts +8 -0
  13. package/dist/auth/subscription-access-gate.js +38 -0
  14. package/dist/auth/subscription-access-gate.js.map +1 -0
  15. package/dist/automation/index.d.ts +44 -0
  16. package/dist/automation/index.js +209 -0
  17. package/dist/automation/index.js.map +1 -0
  18. package/dist/billing-state/index.d.ts +5 -0
  19. package/dist/billing-state/index.js +58 -0
  20. package/dist/billing-state/index.js.map +1 -0
  21. package/dist/billing-state/recovery.d.ts +22 -0
  22. package/dist/billing-state/recovery.js +81 -0
  23. package/dist/billing-state/recovery.js.map +1 -0
  24. package/dist/config/dev-mode.d.ts +3 -0
  25. package/dist/config/dev-mode.js +27 -0
  26. package/dist/config/dev-mode.js.map +1 -0
  27. package/dist/config/index.d.ts +2 -0
  28. package/dist/config/index.js +19 -0
  29. package/dist/config/index.js.map +1 -0
  30. package/dist/config/runtime.d.ts +6 -0
  31. package/dist/config/runtime.js +54 -0
  32. package/dist/config/runtime.js.map +1 -0
  33. package/dist/crons/auto-suspend-past-due.d.ts +2 -0
  34. package/dist/crons/auto-suspend-past-due.js +43 -0
  35. package/dist/crons/auto-suspend-past-due.js.map +1 -0
  36. package/dist/crons/cleanup-stripe-webhook-events.d.ts +2 -0
  37. package/dist/crons/cleanup-stripe-webhook-events.js +27 -0
  38. package/dist/crons/cleanup-stripe-webhook-events.js.map +1 -0
  39. package/dist/crons/expire-free-workspaces.d.ts +2 -0
  40. package/dist/crons/expire-free-workspaces.js +36 -0
  41. package/dist/crons/expire-free-workspaces.js.map +1 -0
  42. package/dist/crons/hard-delete-cancelled.d.ts +2 -0
  43. package/dist/crons/hard-delete-cancelled.js +55 -0
  44. package/dist/crons/hard-delete-cancelled.js.map +1 -0
  45. package/dist/crons/index.d.ts +8 -0
  46. package/dist/crons/index.js +25 -0
  47. package/dist/crons/index.js.map +1 -0
  48. package/dist/crons/notify-free-workspaces-ending-soon.d.ts +2 -0
  49. package/dist/crons/notify-free-workspaces-ending-soon.js +69 -0
  50. package/dist/crons/notify-free-workspaces-ending-soon.js.map +1 -0
  51. package/dist/crons/recompute-billing-state.d.ts +2 -0
  52. package/dist/crons/recompute-billing-state.js +19 -0
  53. package/dist/crons/recompute-billing-state.js.map +1 -0
  54. package/dist/crons/recompute-segments.d.ts +2 -0
  55. package/dist/crons/recompute-segments.js +19 -0
  56. package/dist/crons/recompute-segments.js.map +1 -0
  57. package/dist/crons/reconcile-workspace-lifecycle.d.ts +2 -0
  58. package/dist/crons/reconcile-workspace-lifecycle.js +19 -0
  59. package/dist/crons/reconcile-workspace-lifecycle.js.map +1 -0
  60. package/dist/crons/register.d.ts +2 -0
  61. package/dist/crons/register.js +24 -0
  62. package/dist/crons/register.js.map +1 -0
  63. package/dist/crons/subscription-notifications.d.ts +2 -0
  64. package/dist/crons/subscription-notifications.js +55 -0
  65. package/dist/crons/subscription-notifications.js.map +1 -0
  66. package/dist/data-api/index.d.ts +2 -0
  67. package/dist/data-api/index.js +19 -0
  68. package/dist/data-api/index.js.map +1 -0
  69. package/dist/data-api/platformOwner/admin-user-invoices.d.ts +27 -0
  70. package/dist/data-api/platformOwner/admin-user-invoices.js +158 -0
  71. package/dist/data-api/platformOwner/admin-user-invoices.js.map +1 -0
  72. package/dist/data-api/platformOwner/admin-user-workspaces.d.ts +22 -0
  73. package/dist/data-api/platformOwner/admin-user-workspaces.js +97 -0
  74. package/dist/data-api/platformOwner/admin-user-workspaces.js.map +1 -0
  75. package/dist/data-api/platformOwner/credit-notes.d.ts +24 -0
  76. package/dist/data-api/platformOwner/credit-notes.js +133 -0
  77. package/dist/data-api/platformOwner/credit-notes.js.map +1 -0
  78. package/dist/data-api/platformOwner/features.d.ts +30 -0
  79. package/dist/data-api/platformOwner/features.js +141 -0
  80. package/dist/data-api/platformOwner/features.js.map +1 -0
  81. package/dist/data-api/platformOwner/hidden-filter.d.ts +1 -0
  82. package/dist/data-api/platformOwner/hidden-filter.js +18 -0
  83. package/dist/data-api/platformOwner/hidden-filter.js.map +1 -0
  84. package/dist/data-api/platformOwner/index.d.ts +12 -0
  85. package/dist/data-api/platformOwner/index.js +29 -0
  86. package/dist/data-api/platformOwner/index.js.map +1 -0
  87. package/dist/data-api/platformOwner/invoice-options.d.ts +7 -0
  88. package/dist/data-api/platformOwner/invoice-options.js +14 -0
  89. package/dist/data-api/platformOwner/invoice-options.js.map +1 -0
  90. package/dist/data-api/platformOwner/invoices.d.ts +26 -0
  91. package/dist/data-api/platformOwner/invoices.js +147 -0
  92. package/dist/data-api/platformOwner/invoices.js.map +1 -0
  93. package/dist/data-api/platformOwner/members.d.ts +24 -0
  94. package/dist/data-api/platformOwner/members.js +125 -0
  95. package/dist/data-api/platformOwner/members.js.map +1 -0
  96. package/dist/data-api/platformOwner/plan-migrations.d.ts +24 -0
  97. package/dist/data-api/platformOwner/plan-migrations.js +138 -0
  98. package/dist/data-api/platformOwner/plan-migrations.js.map +1 -0
  99. package/dist/data-api/platformOwner/plans.d.ts +30 -0
  100. package/dist/data-api/platformOwner/plans.js +228 -0
  101. package/dist/data-api/platformOwner/plans.js.map +1 -0
  102. package/dist/data-api/platformOwner/segments.d.ts +29 -0
  103. package/dist/data-api/platformOwner/segments.js +223 -0
  104. package/dist/data-api/platformOwner/segments.js.map +1 -0
  105. package/dist/data-api/platformOwner/support.d.ts +58 -0
  106. package/dist/data-api/platformOwner/support.js +111 -0
  107. package/dist/data-api/platformOwner/support.js.map +1 -0
  108. package/dist/data-api/platformOwner/users.d.ts +22 -0
  109. package/dist/data-api/platformOwner/users.js +128 -0
  110. package/dist/data-api/platformOwner/users.js.map +1 -0
  111. package/dist/data-api/platformOwner/workspaces.d.ts +22 -0
  112. package/dist/data-api/platformOwner/workspaces.js +153 -0
  113. package/dist/data-api/platformOwner/workspaces.js.map +1 -0
  114. package/dist/data-api/support-fields.d.ts +49 -0
  115. package/dist/data-api/support-fields.js +166 -0
  116. package/dist/data-api/support-fields.js.map +1 -0
  117. package/dist/data-api/support-routes.d.ts +10 -0
  118. package/dist/data-api/support-routes.js +71 -0
  119. package/dist/data-api/support-routes.js.map +1 -0
  120. package/dist/data-api/tenant/index.d.ts +2 -0
  121. package/dist/data-api/tenant/index.js +19 -0
  122. package/dist/data-api/tenant/index.js.map +1 -0
  123. package/dist/data-api/tenant/support.d.ts +39 -0
  124. package/dist/data-api/tenant/support.js +53 -0
  125. package/dist/data-api/tenant/support.js.map +1 -0
  126. package/dist/data-api/tenant/tenant-invoices.d.ts +37 -0
  127. package/dist/data-api/tenant/tenant-invoices.js +242 -0
  128. package/dist/data-api/tenant/tenant-invoices.js.map +1 -0
  129. package/dist/db/index.d.ts +1 -0
  130. package/dist/db/index.js +18 -0
  131. package/dist/db/index.js.map +1 -0
  132. package/dist/hooks/index.d.ts +3 -0
  133. package/dist/hooks/index.js +20 -0
  134. package/dist/hooks/index.js.map +1 -0
  135. package/dist/hooks/register.d.ts +1 -0
  136. package/dist/hooks/register.js +57 -0
  137. package/dist/hooks/register.js.map +1 -0
  138. package/dist/hooks/tenant-export.d.ts +2 -0
  139. package/dist/hooks/tenant-export.js +64 -0
  140. package/dist/hooks/tenant-export.js.map +1 -0
  141. package/dist/hooks/tenant-provisioning.d.ts +3 -0
  142. package/dist/hooks/tenant-provisioning.js +12 -0
  143. package/dist/hooks/tenant-provisioning.js.map +1 -0
  144. package/dist/implementations/dms-saas/billing.d.ts +2 -0
  145. package/dist/implementations/dms-saas/billing.js +49 -0
  146. package/dist/implementations/dms-saas/billing.js.map +1 -0
  147. package/dist/implementations/dms-saas/invoice-line-items.d.ts +11 -0
  148. package/dist/implementations/dms-saas/invoice-line-items.js +24 -0
  149. package/dist/implementations/dms-saas/invoice-line-items.js.map +1 -0
  150. package/dist/implementations/dms-saas/pages.d.ts +3 -0
  151. package/dist/implementations/dms-saas/pages.js +12 -0
  152. package/dist/implementations/dms-saas/pages.js.map +1 -0
  153. package/dist/implementations/dms-saas/workspace-lifecycle.d.ts +2 -0
  154. package/dist/implementations/dms-saas/workspace-lifecycle.js +23 -0
  155. package/dist/implementations/dms-saas/workspace-lifecycle.js.map +1 -0
  156. package/dist/index.d.ts +8 -0
  157. package/dist/index.js +107 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/invoice-line-items/billing-window.d.ts +3 -0
  160. package/dist/invoice-line-items/billing-window.js +19 -0
  161. package/dist/invoice-line-items/billing-window.js.map +1 -0
  162. package/dist/invoice-line-items/index.d.ts +1 -0
  163. package/dist/invoice-line-items/index.js +18 -0
  164. package/dist/invoice-line-items/index.js.map +1 -0
  165. package/dist/invoice-line-items/injection.d.ts +2 -0
  166. package/dist/invoice-line-items/injection.js +171 -0
  167. package/dist/invoice-line-items/injection.js.map +1 -0
  168. package/dist/notifications/index.d.ts +2 -0
  169. package/dist/notifications/index.js +19 -0
  170. package/dist/notifications/index.js.map +1 -0
  171. package/dist/notifications/recipients.d.ts +14 -0
  172. package/dist/notifications/recipients.js +87 -0
  173. package/dist/notifications/recipients.js.map +1 -0
  174. package/dist/notifications/subjects.d.ts +21 -0
  175. package/dist/notifications/subjects.js +121 -0
  176. package/dist/notifications/subjects.js.map +1 -0
  177. package/dist/operator-actions/commands.d.ts +41 -0
  178. package/dist/operator-actions/commands.js +233 -0
  179. package/dist/operator-actions/commands.js.map +1 -0
  180. package/dist/operator-actions/db/index.d.ts +4 -0
  181. package/dist/operator-actions/db/index.js +21 -0
  182. package/dist/operator-actions/db/index.js.map +1 -0
  183. package/dist/operator-actions/db/lifecycle-delivery.model.d.ts +29 -0
  184. package/dist/operator-actions/db/lifecycle-delivery.model.js +85 -0
  185. package/dist/operator-actions/db/lifecycle-delivery.model.js.map +1 -0
  186. package/dist/operator-actions/db/lifecycle-delivery.table.d.ts +26 -0
  187. package/dist/operator-actions/db/lifecycle-delivery.table.js +107 -0
  188. package/dist/operator-actions/db/lifecycle-delivery.table.js.map +1 -0
  189. package/dist/operator-actions/db/operator-action.model.d.ts +33 -0
  190. package/dist/operator-actions/db/operator-action.model.js +63 -0
  191. package/dist/operator-actions/db/operator-action.model.js.map +1 -0
  192. package/dist/operator-actions/db/operator-action.table.d.ts +21 -0
  193. package/dist/operator-actions/db/operator-action.table.js +95 -0
  194. package/dist/operator-actions/db/operator-action.table.js.map +1 -0
  195. package/dist/operator-actions/index.d.ts +3 -0
  196. package/dist/operator-actions/index.js +20 -0
  197. package/dist/operator-actions/index.js.map +1 -0
  198. package/dist/operator-actions/journal.d.ts +22 -0
  199. package/dist/operator-actions/journal.js +183 -0
  200. package/dist/operator-actions/journal.js.map +1 -0
  201. package/dist/operator-actions/lifecycle-consumers.d.ts +12 -0
  202. package/dist/operator-actions/lifecycle-consumers.js +28 -0
  203. package/dist/operator-actions/lifecycle-consumers.js.map +1 -0
  204. package/dist/operator-actions/lifecycle-outbox.d.ts +19 -0
  205. package/dist/operator-actions/lifecycle-outbox.js +229 -0
  206. package/dist/operator-actions/lifecycle-outbox.js.map +1 -0
  207. package/dist/operator-actions/types.d.ts +11 -0
  208. package/dist/operator-actions/types.js +3 -0
  209. package/dist/operator-actions/types.js.map +1 -0
  210. package/dist/pages/definitions.d.ts +1 -0
  211. package/dist/pages/definitions.js +18 -0
  212. package/dist/pages/definitions.js.map +1 -0
  213. package/dist/pages/index.d.ts +4 -0
  214. package/dist/pages/index.js +21 -0
  215. package/dist/pages/index.js.map +1 -0
  216. package/dist/pages/module.d.ts +5 -0
  217. package/dist/pages/module.js +15 -0
  218. package/dist/pages/module.js.map +1 -0
  219. package/dist/pages/platform/categories.d.ts +6 -0
  220. package/dist/pages/platform/categories.js +48 -0
  221. package/dist/pages/platform/categories.js.map +1 -0
  222. package/dist/pages/platform/credit-notes.d.ts +9 -0
  223. package/dist/pages/platform/credit-notes.js +40 -0
  224. package/dist/pages/platform/credit-notes.js.map +1 -0
  225. package/dist/pages/platform/dashboard.d.ts +10 -0
  226. package/dist/pages/platform/dashboard.js +95 -0
  227. package/dist/pages/platform/dashboard.js.map +1 -0
  228. package/dist/pages/platform/features.d.ts +9 -0
  229. package/dist/pages/platform/features.js +42 -0
  230. package/dist/pages/platform/features.js.map +1 -0
  231. package/dist/pages/platform/index.d.ts +15 -0
  232. package/dist/pages/platform/index.js +32 -0
  233. package/dist/pages/platform/index.js.map +1 -0
  234. package/dist/pages/platform/invoices.d.ts +9 -0
  235. package/dist/pages/platform/invoices.js +63 -0
  236. package/dist/pages/platform/invoices.js.map +1 -0
  237. package/dist/pages/platform/plans/edit.d.ts +17 -0
  238. package/dist/pages/platform/plans/edit.js +213 -0
  239. package/dist/pages/platform/plans/edit.js.map +1 -0
  240. package/dist/pages/platform/plans/index.d.ts +9 -0
  241. package/dist/pages/platform/plans/index.js +99 -0
  242. package/dist/pages/platform/plans/index.js.map +1 -0
  243. package/dist/pages/platform/plans/migrations.d.ts +9 -0
  244. package/dist/pages/platform/plans/migrations.js +38 -0
  245. package/dist/pages/platform/plans/migrations.js.map +1 -0
  246. package/dist/pages/platform/segments/index.d.ts +9 -0
  247. package/dist/pages/platform/segments/index.js +59 -0
  248. package/dist/pages/platform/segments/index.js.map +1 -0
  249. package/dist/pages/platform/settings.d.ts +9 -0
  250. package/dist/pages/platform/settings.js +147 -0
  251. package/dist/pages/platform/settings.js.map +1 -0
  252. package/dist/pages/platform/support.d.ts +9 -0
  253. package/dist/pages/platform/support.js +29 -0
  254. package/dist/pages/platform/support.js.map +1 -0
  255. package/dist/pages/platform/users/detail.d.ts +9 -0
  256. package/dist/pages/platform/users/detail.js +78 -0
  257. package/dist/pages/platform/users/detail.js.map +1 -0
  258. package/dist/pages/platform/users/index.d.ts +9 -0
  259. package/dist/pages/platform/users/index.js +77 -0
  260. package/dist/pages/platform/users/index.js.map +1 -0
  261. package/dist/pages/platform/workspaces/detail.d.ts +9 -0
  262. package/dist/pages/platform/workspaces/detail.js +120 -0
  263. package/dist/pages/platform/workspaces/detail.js.map +1 -0
  264. package/dist/pages/platform/workspaces/index.d.ts +35 -0
  265. package/dist/pages/platform/workspaces/index.js +300 -0
  266. package/dist/pages/platform/workspaces/index.js.map +1 -0
  267. package/dist/pages/public/auth/index.d.ts +1 -0
  268. package/dist/pages/public/auth/index.js +18 -0
  269. package/dist/pages/public/auth/index.js.map +1 -0
  270. package/dist/pages/public/auth/no-workspace.d.ts +9 -0
  271. package/dist/pages/public/auth/no-workspace.js +26 -0
  272. package/dist/pages/public/auth/no-workspace.js.map +1 -0
  273. package/dist/pages/public/index.d.ts +3 -0
  274. package/dist/pages/public/index.js +20 -0
  275. package/dist/pages/public/index.js.map +1 -0
  276. package/dist/pages/public/legal/index.d.ts +3 -0
  277. package/dist/pages/public/legal/index.js +20 -0
  278. package/dist/pages/public/legal/index.js.map +1 -0
  279. package/dist/pages/public/legal/privacy-policy.d.ts +9 -0
  280. package/dist/pages/public/legal/privacy-policy.js +29 -0
  281. package/dist/pages/public/legal/privacy-policy.js.map +1 -0
  282. package/dist/pages/public/legal/terms-and-conditions.d.ts +9 -0
  283. package/dist/pages/public/legal/terms-and-conditions.js +29 -0
  284. package/dist/pages/public/legal/terms-and-conditions.js.map +1 -0
  285. package/dist/pages/public/legal/terms-of-use.d.ts +9 -0
  286. package/dist/pages/public/legal/terms-of-use.js +29 -0
  287. package/dist/pages/public/legal/terms-of-use.js.map +1 -0
  288. package/dist/pages/public/register.d.ts +9 -0
  289. package/dist/pages/public/register.js +29 -0
  290. package/dist/pages/public/register.js.map +1 -0
  291. package/dist/pages/public/screens.d.ts +3 -0
  292. package/dist/pages/public/screens.js +50 -0
  293. package/dist/pages/public/screens.js.map +1 -0
  294. package/dist/pages/tenant/billing.d.ts +15 -0
  295. package/dist/pages/tenant/billing.js +87 -0
  296. package/dist/pages/tenant/billing.js.map +1 -0
  297. package/dist/pages/tenant/data-export.d.ts +10 -0
  298. package/dist/pages/tenant/data-export.js +32 -0
  299. package/dist/pages/tenant/data-export.js.map +1 -0
  300. package/dist/pages/tenant/general.d.ts +10 -0
  301. package/dist/pages/tenant/general.js +33 -0
  302. package/dist/pages/tenant/general.js.map +1 -0
  303. package/dist/pages/tenant/index.d.ts +6 -0
  304. package/dist/pages/tenant/index.js +23 -0
  305. package/dist/pages/tenant/index.js.map +1 -0
  306. package/dist/pages/tenant/members-seat-quota.d.ts +3 -0
  307. package/dist/pages/tenant/members-seat-quota.js +25 -0
  308. package/dist/pages/tenant/members-seat-quota.js.map +1 -0
  309. package/dist/pages/tenant/support.d.ts +9 -0
  310. package/dist/pages/tenant/support.js +27 -0
  311. package/dist/pages/tenant/support.js.map +1 -0
  312. package/dist/pages/tenant/workspace-suspended.d.ts +9 -0
  313. package/dist/pages/tenant/workspace-suspended.js +26 -0
  314. package/dist/pages/tenant/workspace-suspended.js.map +1 -0
  315. package/dist/plan-changes/deferred.d.ts +18 -0
  316. package/dist/plan-changes/deferred.js +225 -0
  317. package/dist/plan-changes/deferred.js.map +1 -0
  318. package/dist/plan-changes/index.d.ts +1 -0
  319. package/dist/plan-changes/index.js +18 -0
  320. package/dist/plan-changes/index.js.map +1 -0
  321. package/dist/plans/index.d.ts +4 -0
  322. package/dist/plans/index.js +21 -0
  323. package/dist/plans/index.js.map +1 -0
  324. package/dist/plans/seat-capacity.d.ts +9 -0
  325. package/dist/plans/seat-capacity.js +38 -0
  326. package/dist/plans/seat-capacity.js.map +1 -0
  327. package/dist/plans/seat-hooks.d.ts +1 -0
  328. package/dist/plans/seat-hooks.js +80 -0
  329. package/dist/plans/seat-hooks.js.map +1 -0
  330. package/dist/plans/seat-sync.d.ts +10 -0
  331. package/dist/plans/seat-sync.js +23 -0
  332. package/dist/plans/seat-sync.js.map +1 -0
  333. package/dist/routes/index.d.ts +3 -0
  334. package/dist/routes/index.js +20 -0
  335. package/dist/routes/index.js.map +1 -0
  336. package/dist/routes/platformOwner/billing-settings.d.ts +20 -0
  337. package/dist/routes/platformOwner/billing-settings.js +98 -0
  338. package/dist/routes/platformOwner/billing-settings.js.map +1 -0
  339. package/dist/routes/platformOwner/credit-notes-issue.d.ts +16 -0
  340. package/dist/routes/platformOwner/credit-notes-issue.js +56 -0
  341. package/dist/routes/platformOwner/credit-notes-issue.js.map +1 -0
  342. package/dist/routes/platformOwner/dashboard.d.ts +62 -0
  343. package/dist/routes/platformOwner/dashboard.js +310 -0
  344. package/dist/routes/platformOwner/dashboard.js.map +1 -0
  345. package/dist/routes/platformOwner/index.d.ts +12 -0
  346. package/dist/routes/platformOwner/index.js +29 -0
  347. package/dist/routes/platformOwner/index.js.map +1 -0
  348. package/dist/routes/platformOwner/plan-deletion.d.ts +30 -0
  349. package/dist/routes/platformOwner/plan-deletion.js +156 -0
  350. package/dist/routes/platformOwner/plan-deletion.js.map +1 -0
  351. package/dist/routes/platformOwner/plans.d.ts +99 -0
  352. package/dist/routes/platformOwner/plans.js +376 -0
  353. package/dist/routes/platformOwner/plans.js.map +1 -0
  354. package/dist/routes/platformOwner/platform-notes.d.ts +36 -0
  355. package/dist/routes/platformOwner/platform-notes.js +149 -0
  356. package/dist/routes/platformOwner/platform-notes.js.map +1 -0
  357. package/dist/routes/platformOwner/platform-owners.d.ts +12 -0
  358. package/dist/routes/platformOwner/platform-owners.js +77 -0
  359. package/dist/routes/platformOwner/platform-owners.js.map +1 -0
  360. package/dist/routes/platformOwner/segments.d.ts +24 -0
  361. package/dist/routes/platformOwner/segments.js +174 -0
  362. package/dist/routes/platformOwner/segments.js.map +1 -0
  363. package/dist/routes/platformOwner/support.d.ts +21 -0
  364. package/dist/routes/platformOwner/support.js +180 -0
  365. package/dist/routes/platformOwner/support.js.map +1 -0
  366. package/dist/routes/platformOwner/users-detail.d.ts +26 -0
  367. package/dist/routes/platformOwner/users-detail.js +82 -0
  368. package/dist/routes/platformOwner/users-detail.js.map +1 -0
  369. package/dist/routes/platformOwner/workspace-operator-actions.d.ts +34 -0
  370. package/dist/routes/platformOwner/workspace-operator-actions.js +183 -0
  371. package/dist/routes/platformOwner/workspace-operator-actions.js.map +1 -0
  372. package/dist/routes/platformOwner/workspaces-admin.d.ts +27 -0
  373. package/dist/routes/platformOwner/workspaces-admin.js +140 -0
  374. package/dist/routes/platformOwner/workspaces-admin.js.map +1 -0
  375. package/dist/routes/public/index.d.ts +3 -0
  376. package/dist/routes/public/index.js +20 -0
  377. package/dist/routes/public/index.js.map +1 -0
  378. package/dist/routes/public/legal-documents.d.ts +15 -0
  379. package/dist/routes/public/legal-documents.js +72 -0
  380. package/dist/routes/public/legal-documents.js.map +1 -0
  381. package/dist/routes/public/register.d.ts +48 -0
  382. package/dist/routes/public/register.js +193 -0
  383. package/dist/routes/public/register.js.map +1 -0
  384. package/dist/routes/public/webhooks/index.d.ts +1 -0
  385. package/dist/routes/public/webhooks/index.js +18 -0
  386. package/dist/routes/public/webhooks/index.js.map +1 -0
  387. package/dist/routes/public/webhooks/stripe.d.ts +7 -0
  388. package/dist/routes/public/webhooks/stripe.js +41 -0
  389. package/dist/routes/public/webhooks/stripe.js.map +1 -0
  390. package/dist/routes/tenant/billing-portal.d.ts +31 -0
  391. package/dist/routes/tenant/billing-portal.js +117 -0
  392. package/dist/routes/tenant/billing-portal.js.map +1 -0
  393. package/dist/routes/tenant/billing-self-refund.d.ts +18 -0
  394. package/dist/routes/tenant/billing-self-refund.js +199 -0
  395. package/dist/routes/tenant/billing-self-refund.js.map +1 -0
  396. package/dist/routes/tenant/data-export.d.ts +16 -0
  397. package/dist/routes/tenant/data-export.js +102 -0
  398. package/dist/routes/tenant/data-export.js.map +1 -0
  399. package/dist/routes/tenant/index.d.ts +9 -0
  400. package/dist/routes/tenant/index.js +26 -0
  401. package/dist/routes/tenant/index.js.map +1 -0
  402. package/dist/routes/tenant/support.d.ts +27 -0
  403. package/dist/routes/tenant/support.js +185 -0
  404. package/dist/routes/tenant/support.js.map +1 -0
  405. package/dist/routes/tenant/tenant-billing.d.ts +26 -0
  406. package/dist/routes/tenant/tenant-billing.js +148 -0
  407. package/dist/routes/tenant/tenant-billing.js.map +1 -0
  408. package/dist/routes/tenant/tenant-plan-ops.d.ts +57 -0
  409. package/dist/routes/tenant/tenant-plan-ops.js +244 -0
  410. package/dist/routes/tenant/tenant-plan-ops.js.map +1 -0
  411. package/dist/routes/tenant/tenant-plan.d.ts +19 -0
  412. package/dist/routes/tenant/tenant-plan.js +172 -0
  413. package/dist/routes/tenant/tenant-plan.js.map +1 -0
  414. package/dist/routes/tenant/tenant-seats.d.ts +17 -0
  415. package/dist/routes/tenant/tenant-seats.js +58 -0
  416. package/dist/routes/tenant/tenant-seats.js.map +1 -0
  417. package/dist/routes/tenant/workspaces.d.ts +78 -0
  418. package/dist/routes/tenant/workspaces.js +301 -0
  419. package/dist/routes/tenant/workspaces.js.map +1 -0
  420. package/dist/stripe/client.d.ts +6 -0
  421. package/dist/stripe/client.js +44 -0
  422. package/dist/stripe/client.js.map +1 -0
  423. package/dist/stripe/customer-balance.d.ts +12 -0
  424. package/dist/stripe/customer-balance.js +16 -0
  425. package/dist/stripe/customer-balance.js.map +1 -0
  426. package/dist/stripe/customer-billing.d.ts +33 -0
  427. package/dist/stripe/customer-billing.js +140 -0
  428. package/dist/stripe/customer-billing.js.map +1 -0
  429. package/dist/stripe/index.d.ts +11 -0
  430. package/dist/stripe/index.js +28 -0
  431. package/dist/stripe/index.js.map +1 -0
  432. package/dist/stripe/plan-schedule.d.ts +9 -0
  433. package/dist/stripe/plan-schedule.js +83 -0
  434. package/dist/stripe/plan-schedule.js.map +1 -0
  435. package/dist/stripe/proration.d.ts +2 -0
  436. package/dist/stripe/proration.js +19 -0
  437. package/dist/stripe/proration.js.map +1 -0
  438. package/dist/stripe/sync-plan.d.ts +2 -0
  439. package/dist/stripe/sync-plan.js +66 -0
  440. package/dist/stripe/sync-plan.js.map +1 -0
  441. package/dist/stripe/webhook-checkout.d.ts +3 -0
  442. package/dist/stripe/webhook-checkout.js +157 -0
  443. package/dist/stripe/webhook-checkout.js.map +1 -0
  444. package/dist/stripe/webhook-credit-notes.d.ts +3 -0
  445. package/dist/stripe/webhook-credit-notes.js +192 -0
  446. package/dist/stripe/webhook-credit-notes.js.map +1 -0
  447. package/dist/stripe/webhook-dispatch.d.ts +2 -0
  448. package/dist/stripe/webhook-dispatch.js +45 -0
  449. package/dist/stripe/webhook-dispatch.js.map +1 -0
  450. package/dist/stripe/webhook-handlers.d.ts +11 -0
  451. package/dist/stripe/webhook-handlers.js +318 -0
  452. package/dist/stripe/webhook-handlers.js.map +1 -0
  453. package/dist/stripe/webhook-shared.d.ts +28 -0
  454. package/dist/stripe/webhook-shared.js +126 -0
  455. package/dist/stripe/webhook-shared.js.map +1 -0
  456. package/dist/stripe/workspace-checkout.d.ts +29 -0
  457. package/dist/stripe/workspace-checkout.js +106 -0
  458. package/dist/stripe/workspace-checkout.js.map +1 -0
  459. package/dist/support/admissions.d.ts +36 -0
  460. package/dist/support/admissions.js +136 -0
  461. package/dist/support/admissions.js.map +1 -0
  462. package/dist/support/attachments.d.ts +12 -0
  463. package/dist/support/attachments.js +56 -0
  464. package/dist/support/attachments.js.map +1 -0
  465. package/dist/support/config.d.ts +19 -0
  466. package/dist/support/config.js +75 -0
  467. package/dist/support/config.js.map +1 -0
  468. package/dist/support/index.d.ts +6 -0
  469. package/dist/support/index.js +23 -0
  470. package/dist/support/index.js.map +1 -0
  471. package/dist/support/operations.d.ts +51 -0
  472. package/dist/support/operations.js +109 -0
  473. package/dist/support/operations.js.map +1 -0
  474. package/dist/support/plans.d.ts +6 -0
  475. package/dist/support/plans.js +130 -0
  476. package/dist/support/plans.js.map +1 -0
  477. package/dist/support/publications.d.ts +8 -0
  478. package/dist/support/publications.js +106 -0
  479. package/dist/support/publications.js.map +1 -0
  480. package/dist/support/recovery.d.ts +7 -0
  481. package/dist/support/recovery.js +43 -0
  482. package/dist/support/recovery.js.map +1 -0
  483. package/dist/support/service.d.ts +51 -0
  484. package/dist/support/service.js +143 -0
  485. package/dist/support/service.js.map +1 -0
  486. package/dist/support/transitions.d.ts +4 -0
  487. package/dist/support/transitions.js +29 -0
  488. package/dist/support/transitions.js.map +1 -0
  489. package/dist/support/uploads.d.ts +39 -0
  490. package/dist/support/uploads.js +115 -0
  491. package/dist/support/uploads.js.map +1 -0
  492. package/dist/support/validation.d.ts +15 -0
  493. package/dist/support/validation.js +54 -0
  494. package/dist/support/validation.js.map +1 -0
  495. package/dist/types/config.d.ts +16 -0
  496. package/dist/types/config.js +3 -0
  497. package/dist/types/config.js.map +1 -0
  498. package/dist/types/index.d.ts +1 -0
  499. package/dist/types/index.js +18 -0
  500. package/dist/types/index.js.map +1 -0
  501. package/dist/utils/billing-document-type.d.ts +3 -0
  502. package/dist/utils/billing-document-type.js +18 -0
  503. package/dist/utils/billing-document-type.js.map +1 -0
  504. package/dist/utils/billing-period-type.d.ts +3 -0
  505. package/dist/utils/billing-period-type.js +18 -0
  506. package/dist/utils/billing-period-type.js.map +1 -0
  507. package/dist/utils/email-hash.d.ts +1 -0
  508. package/dist/utils/email-hash.js +8 -0
  509. package/dist/utils/email-hash.js.map +1 -0
  510. package/dist/utils/export-dataset-stream.d.ts +19 -0
  511. package/dist/utils/export-dataset-stream.js +40 -0
  512. package/dist/utils/export-dataset-stream.js.map +1 -0
  513. package/dist/utils/index.d.ts +15 -0
  514. package/dist/utils/index.js +32 -0
  515. package/dist/utils/index.js.map +1 -0
  516. package/dist/utils/invoice-lines-type.d.ts +27 -0
  517. package/dist/utils/invoice-lines-type.js +34 -0
  518. package/dist/utils/invoice-lines-type.js.map +1 -0
  519. package/dist/utils/money-cents-type.d.ts +3 -0
  520. package/dist/utils/money-cents-type.js +18 -0
  521. package/dist/utils/money-cents-type.js.map +1 -0
  522. package/dist/utils/pagination.d.ts +22 -0
  523. package/dist/utils/pagination.js +35 -0
  524. package/dist/utils/pagination.js.map +1 -0
  525. package/dist/utils/parse-future-date.d.ts +1 -0
  526. package/dist/utils/parse-future-date.js +15 -0
  527. package/dist/utils/parse-future-date.js.map +1 -0
  528. package/dist/utils/row-instance.d.ts +1 -0
  529. package/dist/utils/row-instance.js +8 -0
  530. package/dist/utils/row-instance.js.map +1 -0
  531. package/dist/utils/segment-conditions-type.d.ts +33 -0
  532. package/dist/utils/segment-conditions-type.js +86 -0
  533. package/dist/utils/segment-conditions-type.js.map +1 -0
  534. package/dist/utils/segment-evaluator.d.ts +3 -0
  535. package/dist/utils/segment-evaluator.js +117 -0
  536. package/dist/utils/segment-evaluator.js.map +1 -0
  537. package/dist/utils/segment-fields.d.ts +19 -0
  538. package/dist/utils/segment-fields.js +212 -0
  539. package/dist/utils/segment-fields.js.map +1 -0
  540. package/dist/utils/segment-matching.d.ts +56 -0
  541. package/dist/utils/segment-matching.js +200 -0
  542. package/dist/utils/segment-matching.js.map +1 -0
  543. package/dist/utils/segment-name-cache.d.ts +2 -0
  544. package/dist/utils/segment-name-cache.js +22 -0
  545. package/dist/utils/segment-name-cache.js.map +1 -0
  546. package/dist/utils/time.d.ts +3 -0
  547. package/dist/utils/time.js +10 -0
  548. package/dist/utils/time.js.map +1 -0
  549. package/dist/workers/index.d.ts +1 -0
  550. package/dist/workers/index.js +18 -0
  551. package/dist/workers/index.js.map +1 -0
  552. package/dist/workers/plan-migration.d.ts +4 -0
  553. package/dist/workers/plan-migration.js +206 -0
  554. package/dist/workers/plan-migration.js.map +1 -0
  555. package/dist/workspaces/billing-profile.d.ts +3 -0
  556. package/dist/workspaces/billing-profile.js +55 -0
  557. package/dist/workspaces/billing-profile.js.map +1 -0
  558. package/dist/workspaces/complimentary.d.ts +7 -0
  559. package/dist/workspaces/complimentary.js +47 -0
  560. package/dist/workspaces/complimentary.js.map +1 -0
  561. package/dist/workspaces/db/card-capacity.model.d.ts +30 -0
  562. package/dist/workspaces/db/card-capacity.model.js +98 -0
  563. package/dist/workspaces/db/card-capacity.model.js.map +1 -0
  564. package/dist/workspaces/db/card-capacity.table.d.ts +11 -0
  565. package/dist/workspaces/db/card-capacity.table.js +34 -0
  566. package/dist/workspaces/db/card-capacity.table.js.map +1 -0
  567. package/dist/workspaces/db/provisioning-attempt.model.d.ts +24 -0
  568. package/dist/workspaces/db/provisioning-attempt.model.js +33 -0
  569. package/dist/workspaces/db/provisioning-attempt.model.js.map +1 -0
  570. package/dist/workspaces/db/provisioning-attempt.table.d.ts +18 -0
  571. package/dist/workspaces/db/provisioning-attempt.table.js +77 -0
  572. package/dist/workspaces/db/provisioning-attempt.table.js.map +1 -0
  573. package/dist/workspaces/db/trial-identity.model.d.ts +25 -0
  574. package/dist/workspaces/db/trial-identity.model.js +62 -0
  575. package/dist/workspaces/db/trial-identity.model.js.map +1 -0
  576. package/dist/workspaces/db/trial-identity.table.d.ts +7 -0
  577. package/dist/workspaces/db/trial-identity.table.js +34 -0
  578. package/dist/workspaces/db/trial-identity.table.js.map +1 -0
  579. package/dist/workspaces/deletion.d.ts +8 -0
  580. package/dist/workspaces/deletion.js +75 -0
  581. package/dist/workspaces/deletion.js.map +1 -0
  582. package/dist/workspaces/free-workspace-guard.d.ts +11 -0
  583. package/dist/workspaces/free-workspace-guard.js +96 -0
  584. package/dist/workspaces/free-workspace-guard.js.map +1 -0
  585. package/dist/workspaces/index.d.ts +6 -0
  586. package/dist/workspaces/index.js +23 -0
  587. package/dist/workspaces/index.js.map +1 -0
  588. package/dist/workspaces/provisioning-rollback.d.ts +2 -0
  589. package/dist/workspaces/provisioning-rollback.js +78 -0
  590. package/dist/workspaces/provisioning-rollback.js.map +1 -0
  591. package/dist/workspaces/provisioning-state.d.ts +6 -0
  592. package/dist/workspaces/provisioning-state.js +91 -0
  593. package/dist/workspaces/provisioning-state.js.map +1 -0
  594. package/dist/workspaces/provisioning.d.ts +49 -0
  595. package/dist/workspaces/provisioning.js +263 -0
  596. package/dist/workspaces/provisioning.js.map +1 -0
  597. package/dist/workspaces/registration-extras.d.ts +1 -0
  598. package/dist/workspaces/registration-extras.js +50 -0
  599. package/dist/workspaces/registration-extras.js.map +1 -0
  600. package/dist/workspaces/suspension.d.ts +13 -0
  601. package/dist/workspaces/suspension.js +124 -0
  602. package/dist/workspaces/suspension.js.map +1 -0
  603. package/frontend-vue/.editorconfig +12 -0
  604. package/frontend-vue/.prettierrc +11 -0
  605. package/frontend-vue/app/build/.gitkeep +0 -0
  606. package/frontend-vue/app/components/CardGrid.vue +77 -0
  607. package/frontend-vue/app/components/CustomerPortalButton.vue +45 -0
  608. package/frontend-vue/app/components/DataExport.vue +300 -0
  609. package/frontend-vue/app/components/DeletePlanModal.vue +223 -0
  610. package/frontend-vue/app/components/FreeAccessBanner.vue +70 -0
  611. package/frontend-vue/app/components/InvoiceLines.vue +57 -0
  612. package/frontend-vue/app/components/IssueCreditNoteModal.vue +128 -0
  613. package/frontend-vue/app/components/LegalLayout.vue +63 -0
  614. package/frontend-vue/app/components/LoadFailure.vue +25 -0
  615. package/frontend-vue/app/components/PastDueAlert.vue +96 -0
  616. package/frontend-vue/app/components/PaymentMethodCard.vue +86 -0
  617. package/frontend-vue/app/components/PlanCard.vue +294 -0
  618. package/frontend-vue/app/components/PlanCardPublic.vue +59 -0
  619. package/frontend-vue/app/components/PlanCardsDisplay.vue +127 -0
  620. package/frontend-vue/app/components/PlanComparisonModal.vue +213 -0
  621. package/frontend-vue/app/components/PlanInheritancePicker.vue +329 -0
  622. package/frontend-vue/app/components/PlatformNotes.vue +281 -0
  623. package/frontend-vue/app/components/PlatformSupport.vue +461 -0
  624. package/frontend-vue/app/components/RecentActivity.vue +72 -0
  625. package/frontend-vue/app/components/RefundButton.vue +126 -0
  626. package/frontend-vue/app/components/Register.vue +174 -0
  627. package/frontend-vue/app/components/RegistrationClosed.vue +15 -0
  628. package/frontend-vue/app/components/SeatQuotaBanner.vue +78 -0
  629. package/frontend-vue/app/components/SegmentConditionsBuilder.vue +176 -0
  630. package/frontend-vue/app/components/SegmentConditionsGroup.vue +494 -0
  631. package/frontend-vue/app/components/SupportAttachmentUpload.vue +140 -0
  632. package/frontend-vue/app/components/SupportThreadHistory.vue +139 -0
  633. package/frontend-vue/app/components/TenantBillingForm.vue +208 -0
  634. package/frontend-vue/app/components/TenantPlanCard.vue +223 -0
  635. package/frontend-vue/app/components/TenantSupport.vue +415 -0
  636. package/frontend-vue/app/components/UserSummaryCard.vue +166 -0
  637. package/frontend-vue/app/components/WorkspaceBillingInfo.vue +68 -0
  638. package/frontend-vue/app/components/WorkspaceCompAccessButton.vue +198 -0
  639. package/frontend-vue/app/components/WorkspaceCreateModal.vue +256 -0
  640. package/frontend-vue/app/components/WorkspaceDangerZone.vue +146 -0
  641. package/frontend-vue/app/components/WorkspaceDetailHeader.vue +24 -0
  642. package/frontend-vue/app/components/WorkspaceIdentity.vue +99 -0
  643. package/frontend-vue/app/components/WorkspaceJoinButton.vue +50 -0
  644. package/frontend-vue/app/components/WorkspaceOperatorActions.vue +340 -0
  645. package/frontend-vue/app/components/WorkspaceSummaryCard.vue +161 -0
  646. package/frontend-vue/app/components/WorkspaceSuspendButton.vue +167 -0
  647. package/frontend-vue/app/components/WorkspaceSuspended.vue +164 -0
  648. package/frontend-vue/app/components/WorkspaceSwitcherWidget.vue +247 -0
  649. package/frontend-vue/app/composables/useApiErrorMessage.ts +35 -0
  650. package/frontend-vue/app/composables/useBillingCountries.ts +54 -0
  651. package/frontend-vue/app/composables/useBillingDocumentType.ts +7 -0
  652. package/frontend-vue/app/composables/useBillingStatus.ts +39 -0
  653. package/frontend-vue/app/composables/useCurrentWorkspace.ts +43 -0
  654. package/frontend-vue/app/composables/useDetailRefresh.ts +17 -0
  655. package/frontend-vue/app/composables/useExportHistory.ts +143 -0
  656. package/frontend-vue/app/composables/useInvoiceLines.ts +22 -0
  657. package/frontend-vue/app/composables/useMoneyFormat.ts +49 -0
  658. package/frontend-vue/app/composables/useMyWorkspaces.ts +47 -0
  659. package/frontend-vue/app/composables/usePlanFeatureFormat.ts +60 -0
  660. package/frontend-vue/app/composables/usePlanIntervalLabel.ts +30 -0
  661. package/frontend-vue/app/composables/useSaasRegistration.ts +522 -0
  662. package/frontend-vue/app/composables/useSeatQuota.ts +18 -0
  663. package/frontend-vue/app/composables/useSharedRequest.ts +54 -0
  664. package/frontend-vue/app/composables/useStripePaymentElement.ts +74 -0
  665. package/frontend-vue/app/composables/useSubscriptionAccess.ts +12 -0
  666. package/frontend-vue/app/composables/useSupportRequest.ts +74 -0
  667. package/frontend-vue/app/composables/useTenantPlan.ts +95 -0
  668. package/frontend-vue/app/composables/useTenantSwitch.ts +22 -0
  669. package/frontend-vue/app/composables/useWorkspaceAccessCache.ts +25 -0
  670. package/frontend-vue/app/custom-pages/auth/no-workspace.vue +495 -0
  671. package/frontend-vue/app/middleware/workspace-suspended.global.ts +56 -0
  672. package/frontend-vue/app/plugins/auth-links.ts +24 -0
  673. package/frontend-vue/app/plugins/billing-data-types.ts +62 -0
  674. package/frontend-vue/app/plugins/footer-links.ts +36 -0
  675. package/frontend-vue/app/plugins/plan-cards-display.client.ts +16 -0
  676. package/frontend-vue/app/plugins/segment-conditions-data-type.client.ts +122 -0
  677. package/frontend-vue/app/plugins/sidebar-widgets.ts +13 -0
  678. package/frontend-vue/app/types/support.ts +123 -0
  679. package/frontend-vue/dms.frontend.ts +68 -0
  680. package/frontend-vue/eslint.config.mjs +13 -0
  681. package/frontend-vue/i18n/locales/saas-en-GB.json +1285 -0
  682. package/frontend-vue/i18n/locales/saas-fr-FR.json +1285 -0
  683. package/frontend-vue/package.json +27 -0
  684. package/frontend-vue/pnpm-lock.yaml +4948 -0
  685. package/frontend-vue/pnpm-workspace.yaml +2 -0
  686. package/frontend-vue/server/routes/auth/finalize-workspace.post.ts +61 -0
  687. package/package.json +91 -0
@@ -0,0 +1,522 @@
1
+ import {
2
+ computed,
3
+ type MaybeRefOrGetter,
4
+ onMounted,
5
+ reactive,
6
+ ref,
7
+ toValue,
8
+ watch,
9
+ } from "vue";
10
+ import { formatMajorUnits } from "./useMoneyFormat";
11
+ import {
12
+ formatPlanIntervalLabel,
13
+ type PlanInterval,
14
+ } from "./usePlanIntervalLabel";
15
+
16
+ /**
17
+ * A plan as the public registration screen sees it.
18
+ */
19
+ export interface RegistrationPlan {
20
+ _id: string;
21
+ name: string;
22
+ description: string;
23
+ price: number;
24
+ currency: string;
25
+ interval: PlanInterval;
26
+ trialDays: number;
27
+ audience: string;
28
+ borderColor: string | null;
29
+ borderLabel: string | null;
30
+ order: number;
31
+ }
32
+
33
+ export interface RegistrationForm {
34
+ customerType: "individual" | "business";
35
+ email: string;
36
+ password: string;
37
+ name: string;
38
+ workspaceName: string;
39
+ companyName: string;
40
+ vatNumber: string;
41
+ country: string;
42
+ addressLine1: string;
43
+ postalCode: string;
44
+ city: string;
45
+ selectedPlanId: string | null;
46
+ hasAcceptedLegal: boolean;
47
+ }
48
+
49
+ /** Everything the submit guard looks at, independent of how it is bound. */
50
+ export interface RegistrationRequirements {
51
+ selectedPlanId: string | null;
52
+ isPaymentReady: boolean;
53
+ hasAcceptedLegal: boolean;
54
+ country: string;
55
+ }
56
+
57
+ export type RegistrationTranslator = (
58
+ key: string,
59
+ params?: Record<string, string>,
60
+ ) => string;
61
+
62
+ export interface UseSaasRegistrationOptions {
63
+ /**
64
+ * In-app route to land on once the workspace is provisioned. Landing on
65
+ * another origin is the consumer's own call to make, from the tenant id
66
+ * `submit()` returns.
67
+ */
68
+ redirectTo?: string;
69
+ /**
70
+ * DOM id the Stripe payment element mounts into. Consumers that render
71
+ * several registration surfaces on one page must give distinct ids.
72
+ */
73
+ paymentElementId?: string;
74
+ /**
75
+ * Whatever the consuming SaaS captures on top of the billing fields, read
76
+ * when the visitor submits. It stays the consumer's data: dms-saas forwards
77
+ * it inside the provisioning transaction, to the consumer's own
78
+ * `TENANT_BEING_PROVISIONED` listener, and neither reads nor stores it. A
79
+ * listener that fails to write it cancels the whole registration.
80
+ *
81
+ * Keep it to what a form captures — the endpoint is public, so the API caps
82
+ * its serialised size, depth and number of keys and answers 400 above them.
83
+ */
84
+ extras?: MaybeRefOrGetter<Record<string, unknown> | undefined>;
85
+ }
86
+
87
+ interface RegistrationRequirement {
88
+ errorKey: string;
89
+ isMet: (requirements: RegistrationRequirements) => boolean;
90
+ }
91
+
92
+ interface RegistrationAddress {
93
+ country: string;
94
+ line1?: string;
95
+ postalCode?: string;
96
+ city?: string;
97
+ }
98
+
99
+ interface RegistrationPayload {
100
+ email: string;
101
+ password: string;
102
+ name: string;
103
+ workspaceName: string;
104
+ planId: string;
105
+ customerType: string;
106
+ companyName?: string;
107
+ vatNumber?: string;
108
+ paymentMethodId: string;
109
+ address: RegistrationAddress;
110
+ extras?: Record<string, unknown>;
111
+ }
112
+
113
+ /** Everything but the card, which only exists once Stripe has confirmed it. */
114
+ type RegistrationSubmission = Omit<RegistrationPayload, "paymentMethodId">;
115
+
116
+ interface RegistrationResult {
117
+ tenantId: string;
118
+ }
119
+
120
+ interface SetupIntentResponse {
121
+ clientSecret: string | null;
122
+ }
123
+
124
+ interface DmsSaasPublicRuntimeConfig {
125
+ stripePublishableKey?: string;
126
+ admissionMode?: "open" | "invitation-only";
127
+ }
128
+
129
+ const PLANS_ENDPOINT = "/api/saas/plans/public";
130
+ const SETUP_INTENT_ENDPOINT = "/api/saas/register/setup-intent";
131
+ const REGISTER_ENDPOINT = "/api/saas/register";
132
+ const DEFAULT_PAYMENT_ELEMENT_ID = "dms-saas-register-payment-element";
133
+ const DEFAULT_REDIRECT = "/auth/login";
134
+ const ANY_AUDIENCE = "any";
135
+ const PLAN_PRICE_KEY = "saas.register.price";
136
+ const NO_PLAN_ERROR_KEY = "saas.register.error.no_plan";
137
+ const NO_PAYMENT_ERROR_KEY = "saas.register.error.no_payment";
138
+ const LOAD_ERROR_KEY = "saas.register.error.load";
139
+ const SUBMIT_ERROR_KEY = "saas.register.error.failed";
140
+
141
+ /**
142
+ * Checked in the order the visitor can act on them, so a missing plan is never
143
+ * reported as a payment failure.
144
+ */
145
+ const REGISTRATION_REQUIREMENTS: RegistrationRequirement[] = [
146
+ {
147
+ errorKey: NO_PLAN_ERROR_KEY,
148
+ isMet: (requirements) => Boolean(requirements.selectedPlanId),
149
+ },
150
+ {
151
+ errorKey: NO_PAYMENT_ERROR_KEY,
152
+ isMet: (requirements) => requirements.isPaymentReady,
153
+ },
154
+ {
155
+ errorKey: "saas.register.error.legal_required",
156
+ isMet: (requirements) => requirements.hasAcceptedLegal,
157
+ },
158
+ {
159
+ errorKey: "saas.register.error.no_country",
160
+ isMet: (requirements) => Boolean(requirements.country),
161
+ },
162
+ ];
163
+
164
+ /**
165
+ * The one guard a consumer cannot get wrong on its own: the first requirement
166
+ * the visitor has not met yet, in the order they can act on them.
167
+ *
168
+ * @param requirements Current state of the registration form
169
+ * @returns Translation key of the first unmet requirement, or null
170
+ */
171
+ export function firstMissingRegistrationRequirement(
172
+ requirements: RegistrationRequirements,
173
+ ): string | null {
174
+ const missing = REGISTRATION_REQUIREMENTS.find(
175
+ (requirement) => !requirement.isMet(requirements),
176
+ );
177
+ return missing?.errorKey ?? null;
178
+ }
179
+
180
+ function planIntervalLabel(
181
+ interval: PlanInterval,
182
+ translate: RegistrationTranslator,
183
+ ): string {
184
+ return formatPlanIntervalLabel(interval, "saas.register.interval", translate);
185
+ }
186
+
187
+ /**
188
+ * Price the way a summary line reads it: amount and cadence as one string, in
189
+ * the visitor's locale, decimals dropped on whole amounts.
190
+ *
191
+ * Takes its locale and translator instead of reading them from the component
192
+ * context, so a consumer can price a plan outside a `setup()` call.
193
+ *
194
+ * @param plan Plan to price
195
+ * @param locale BCP 47 locale the amount is formatted in
196
+ * @param translate Translation function for the price pattern and the cadence
197
+ * @returns Localised price, e.g. `20 €/mois`
198
+ */
199
+ export function formatRegistrationPlanPrice(
200
+ plan: RegistrationPlan,
201
+ locale: string,
202
+ translate: RegistrationTranslator,
203
+ ): string {
204
+ const price = formatMajorUnits(plan.price, plan.currency, locale, {
205
+ hideWholeAmountDecimals: true,
206
+ });
207
+ return translate(PLAN_PRICE_KEY, {
208
+ price,
209
+ interval: planIntervalLabel(plan.interval, translate),
210
+ });
211
+ }
212
+
213
+ /**
214
+ * The offer a customer type is entitled to, in the order it should read.
215
+ *
216
+ * Sorted here because the endpoint returns plans in storage order, and the
217
+ * first plan on offer is the one that ends up pre-selected: it has to be the
218
+ * one the operator ranked first, not the one created first.
219
+ *
220
+ * @param all Every publicly visible plan
221
+ * @param customerType Customer type the visitor declared
222
+ * @returns Plans that customer type may subscribe to
223
+ */
224
+ export function resolveOfferedPlans(
225
+ all: RegistrationPlan[],
226
+ customerType: string,
227
+ ): RegistrationPlan[] {
228
+ return all
229
+ .filter(
230
+ (plan) => plan.audience === ANY_AUDIENCE || plan.audience === customerType,
231
+ )
232
+ .sort((left, right) => left.order - right.order);
233
+ }
234
+
235
+ /**
236
+ * The plan selection to hold on to now that this is the offer.
237
+ *
238
+ * Switching customer type reshuffles the offer: a selection the visitor can no
239
+ * longer subscribe to would travel to the API and come back rejected, so it
240
+ * falls back to the first plan they may actually buy.
241
+ *
242
+ * @param available Plans the current customer type may subscribe to
243
+ * @param current Plan id currently selected, if any
244
+ * @returns Plan id to select, or null when nothing is on offer
245
+ */
246
+ export function resolveSelectedPlanId(
247
+ available: RegistrationPlan[],
248
+ current: string | null,
249
+ ): string | null {
250
+ const isStillOffered = available.some((plan) => plan._id === current);
251
+ return isStillOffered ? current : (available[0]?._id ?? null);
252
+ }
253
+
254
+ function optionalField(value: string): string | undefined {
255
+ return value.trim() || undefined;
256
+ }
257
+
258
+ /**
259
+ * The consumer's capture, detached from the consumer.
260
+ *
261
+ * An empty capture is no capture, and a live one is not a capture at all: the
262
+ * object is frozen as it will be serialised, so a consumer whose own form is
263
+ * still editable while the card is being confirmed cannot change what was
264
+ * submitted — or make it too large to accept once the card has gone through.
265
+ *
266
+ * @param extras Whatever the consumer handed over, possibly reactive
267
+ * @returns A detached copy, or undefined when there is nothing to send
268
+ */
269
+ export function snapshotRegistrationExtras(
270
+ extras: Record<string, unknown> | undefined,
271
+ ): Record<string, unknown> | undefined {
272
+ if (!extras || Object.keys(extras).length === 0) return undefined;
273
+ return JSON.parse(JSON.stringify(extras)) as Record<string, unknown>;
274
+ }
275
+
276
+ /**
277
+ * The public registration flow, without a single line of presentation.
278
+ *
279
+ * dms-saas owns what is dangerous to re-derive — the Stripe setup intent and
280
+ * card confirmation, the order the fields are validated in, the shape of the
281
+ * provisioning call, the mapping from API failures to a message — and hands
282
+ * the consumer plain state to bind and one action to call. Each SaaS then
283
+ * writes the markup its conversion funnel needs: the fields it groups, the way
284
+ * it presents plans, whether it is one page or three steps, its own copy.
285
+ *
286
+ * The screen shipped in this package is one consumer among others: replace it
287
+ * by turning it off (`publicScreens.register: false` in the module config) and
288
+ * registering your own page on the `register` slug, then build the markup you
289
+ * want on this composable rather than forking its logic.
290
+ *
291
+ * @param options Landing route and payment element id
292
+ * @returns Bindable form state, plan data, submission action and status
293
+ */
294
+ export function useSaasRegistration(options: UseSaasRegistrationOptions = {}) {
295
+ const { $authFetch } = useAuthFetch();
296
+ const { resolveApiError } = useApiErrorMessage();
297
+ const { countryItems } = useBillingCountries();
298
+ const { $i18n } = useDmsApp();
299
+ const config = useDmsRuntimeConfig();
300
+
301
+ const translate: RegistrationTranslator = (key, params) =>
302
+ params ? $i18n.t(key, params) : $i18n.t(key);
303
+
304
+ const paymentElementId =
305
+ options.paymentElementId ?? DEFAULT_PAYMENT_ELEMENT_ID;
306
+ const redirectTo = options.redirectTo ?? DEFAULT_REDIRECT;
307
+
308
+ const form = reactive<RegistrationForm>({
309
+ customerType: "individual",
310
+ email: "",
311
+ password: "",
312
+ name: "",
313
+ workspaceName: "",
314
+ companyName: "",
315
+ vatNumber: "",
316
+ country: "",
317
+ addressLine1: "",
318
+ postalCode: "",
319
+ city: "",
320
+ selectedPlanId: null,
321
+ hasAcceptedLegal: false,
322
+ });
323
+
324
+ const allPlans = ref<RegistrationPlan[]>([]);
325
+ const isLoading = ref(true);
326
+ const isSubmitting = ref(false);
327
+ const errorMessage = ref<string | null>(null);
328
+ const stripeHandle = ref<ReturnType<typeof useStripePaymentElement> | null>(
329
+ null,
330
+ );
331
+
332
+ const stripePublishableKey = computed<string>(
333
+ () =>
334
+ (config.public.dmsSaas as DmsSaasPublicRuntimeConfig | undefined)
335
+ ?.stripePublishableKey ?? "",
336
+ );
337
+
338
+ /** Plans the current customer type may subscribe to, in the operator's order. */
339
+ const plans = computed(() =>
340
+ resolveOfferedPlans(allPlans.value, form.customerType),
341
+ );
342
+
343
+ const selectedPlan = computed(
344
+ () => plans.value.find((plan) => plan._id === form.selectedPlanId) ?? null,
345
+ );
346
+
347
+ /**
348
+ * Whether the card field has been wired to Stripe — false as long as the
349
+ * publishable key or the setup intent is missing.
350
+ */
351
+ const isPaymentReady = computed(() => stripeHandle.value !== null);
352
+
353
+ const requirements = computed<RegistrationRequirements>(() => ({
354
+ selectedPlanId: form.selectedPlanId,
355
+ isPaymentReady: isPaymentReady.value,
356
+ hasAcceptedLegal: form.hasAcceptedLegal,
357
+ country: form.country,
358
+ }));
359
+
360
+ const missingRequirement = computed(() =>
361
+ firstMissingRegistrationRequirement(requirements.value),
362
+ );
363
+
364
+ const canSubmit = computed(
365
+ () => !isSubmitting.value && missingRequirement.value === null,
366
+ );
367
+
368
+ function formatPlanPrice(plan: RegistrationPlan): string {
369
+ return formatRegistrationPlanPrice(plan, $i18n.locale.value, translate);
370
+ }
371
+
372
+ // Repaired synchronously, not on the next flush: a consumer that switches
373
+ // customer type and submits in the same tick would otherwise send the plan
374
+ // the visitor can no longer buy.
375
+ watch(
376
+ plans,
377
+ (available) => {
378
+ form.selectedPlanId = resolveSelectedPlanId(
379
+ available,
380
+ form.selectedPlanId,
381
+ );
382
+ },
383
+ { flush: "sync" },
384
+ );
385
+
386
+ async function loadPlans(): Promise<void> {
387
+ allPlans.value = await $authFetch<RegistrationPlan[]>(PLANS_ENDPOINT);
388
+ }
389
+
390
+ async function mountPaymentElement(): Promise<void> {
391
+ if (!stripePublishableKey.value) return;
392
+ const setup = await $authFetch<SetupIntentResponse>(SETUP_INTENT_ENDPOINT);
393
+ if (!setup.clientSecret) return;
394
+ stripeHandle.value = useStripePaymentElement({
395
+ publishableKey: stripePublishableKey.value,
396
+ clientSecret: setup.clientSecret,
397
+ containerId: paymentElementId,
398
+ });
399
+ }
400
+
401
+ async function confirmPaymentMethod(): Promise<string | null> {
402
+ const confirmation = await stripeHandle.value?.confirmAndGetPaymentMethod();
403
+ if (confirmation?.paymentMethodId) return confirmation.paymentMethodId;
404
+ errorMessage.value =
405
+ confirmation?.error?.message ?? translate(NO_PAYMENT_ERROR_KEY);
406
+ return null;
407
+ }
408
+
409
+ /**
410
+ * The form as it stood when the visitor submitted.
411
+ *
412
+ * Taken whole, before the card confirmation: that step can hold a 3-D Secure
413
+ * challenge open for seconds while the fields stay editable, and a payload
414
+ * half read before and half after would pair, say, the plan chosen then with
415
+ * the customer type chosen since — which the API rejects, once the card has
416
+ * already been confirmed.
417
+ */
418
+ function captureSubmission(planId: string): RegistrationSubmission {
419
+ const isBusiness = form.customerType === "business";
420
+ return {
421
+ email: form.email,
422
+ password: form.password,
423
+ name: form.name,
424
+ workspaceName: form.workspaceName,
425
+ planId,
426
+ customerType: form.customerType,
427
+ companyName: isBusiness ? form.companyName : undefined,
428
+ vatNumber: isBusiness ? optionalField(form.vatNumber) : undefined,
429
+ address: {
430
+ country: form.country,
431
+ line1: optionalField(form.addressLine1),
432
+ postalCode: optionalField(form.postalCode),
433
+ city: optionalField(form.city),
434
+ },
435
+ extras: snapshotRegistrationExtras(toValue(options.extras)),
436
+ };
437
+ }
438
+
439
+ /**
440
+ * Confirm the card, provision the workspace, land on the configured route.
441
+ *
442
+ * Everything the caller needs to know travels through `errorMessage`:
443
+ * nothing throws, so a consumer template can bind the action directly.
444
+ *
445
+ * @returns Tenant id when the workspace was provisioned, null otherwise
446
+ */
447
+ async function submit(): Promise<string | null> {
448
+ // A card is confirmed and an account created in here: a second call while
449
+ // the first is in flight would run both again.
450
+ if (isSubmitting.value) return null;
451
+
452
+ const planId = form.selectedPlanId;
453
+ if (missingRequirement.value || !planId) {
454
+ errorMessage.value = translate(
455
+ missingRequirement.value ?? NO_PLAN_ERROR_KEY,
456
+ );
457
+ return null;
458
+ }
459
+
460
+ errorMessage.value = null;
461
+ isSubmitting.value = true;
462
+ let tenantId: string | null = null;
463
+ try {
464
+ // Inside the guard: freezing the capture reads the consumer's object,
465
+ // and a consumer's object is never guaranteed to be serialisable.
466
+ const submission = captureSubmission(planId);
467
+ const paymentMethodId = await confirmPaymentMethod();
468
+ if (!paymentMethodId) return null;
469
+
470
+ const result = await $authFetch<RegistrationResult>(REGISTER_ENDPOINT, {
471
+ method: "POST",
472
+ body: { ...submission, paymentMethodId },
473
+ });
474
+
475
+ tenantId = result.tenantId ?? null;
476
+ if (tenantId) await navigateDms(redirectTo);
477
+ return tenantId;
478
+ } catch (error) {
479
+ // Once the workspace exists, whatever failed after it is a landing
480
+ // problem: calling it a failed registration sends a visitor who has
481
+ // already paid back through a flow that would charge them again.
482
+ if (tenantId) return tenantId;
483
+ errorMessage.value = resolveApiError(error, SUBMIT_ERROR_KEY);
484
+ return null;
485
+ } finally {
486
+ isSubmitting.value = false;
487
+ }
488
+ }
489
+
490
+ onMounted(async () => {
491
+ if (
492
+ (config.public.dmsSaas as DmsSaasPublicRuntimeConfig | undefined)
493
+ ?.admissionMode === "invitation-only"
494
+ ) {
495
+ isLoading.value = false;
496
+ return;
497
+ }
498
+ try {
499
+ await Promise.all([loadPlans(), mountPaymentElement()]);
500
+ } catch (error) {
501
+ errorMessage.value = resolveApiError(error, LOAD_ERROR_KEY);
502
+ } finally {
503
+ isLoading.value = false;
504
+ }
505
+ });
506
+
507
+ return {
508
+ form,
509
+ plans,
510
+ selectedPlan,
511
+ countryItems,
512
+ paymentElementId,
513
+ isPaymentReady,
514
+ isLoading,
515
+ isSubmitting,
516
+ errorMessage,
517
+ missingRequirement,
518
+ canSubmit,
519
+ formatPlanPrice,
520
+ submit,
521
+ };
522
+ }
@@ -0,0 +1,18 @@
1
+ const SEAT_QUOTA_ENDPOINT = "/api/saas/tenant/seats";
2
+ const SEAT_QUOTA_STATE_KEY = "saas-seat-quota";
3
+
4
+ export interface SeatQuotaResponse {
5
+ members: number;
6
+ pendingInvites: number;
7
+ occupied: number;
8
+ /** `null` when no plan is in force, i.e. no seat ceiling to enforce. */
9
+ maxMembers: number | null;
10
+ isTenantOwner: boolean;
11
+ }
12
+
13
+ export function useSeatQuota(): SharedRequest<SeatQuotaResponse> {
14
+ const { $authFetch } = useAuthFetch();
15
+ return useSharedRequest(SEAT_QUOTA_STATE_KEY, () =>
16
+ $authFetch<SeatQuotaResponse>(SEAT_QUOTA_ENDPOINT),
17
+ );
18
+ }
@@ -0,0 +1,54 @@
1
+ import type { Ref } from "vue";
2
+
3
+ export interface SharedRequest<T> {
4
+ data: Ref<T | null>;
5
+ error: Ref<boolean>;
6
+ load: () => Promise<T | null>;
7
+ refresh: () => Promise<T | null>;
8
+ }
9
+
10
+ /**
11
+ * One payload, many blocks. Page-level surfaces are assembled from independent
12
+ * components that mount together, so a plain per-component fetch multiplies
13
+ * the same request. This keeps the response, the failure flag and the
14
+ * in-flight promise in shared state: `load` serves whatever is already there,
15
+ * `refresh` forces a re-fetch. Failures never reject — they set `error` so
16
+ * every consumer can render the shared failure state and offer a retry
17
+ * instead of silently disappearing.
18
+ */
19
+ export function useSharedRequest<T>(
20
+ key: string,
21
+ fetcher: () => Promise<T>,
22
+ ): SharedRequest<T> {
23
+ const data = useDmsState<T | null>(key, () => null);
24
+ const error = useDmsState(`${key}-error`, () => false);
25
+ const inFlight = useDmsState<Promise<T | null> | null>(
26
+ `${key}-request`,
27
+ () => null,
28
+ );
29
+
30
+ function refresh(): Promise<T | null> {
31
+ if (inFlight.value) return inFlight.value;
32
+ const request = fetcher()
33
+ .then((response) => {
34
+ data.value = response;
35
+ error.value = false;
36
+ return response as T | null;
37
+ })
38
+ .catch(() => {
39
+ error.value = true;
40
+ return null;
41
+ })
42
+ .finally(() => {
43
+ inFlight.value = null;
44
+ });
45
+ inFlight.value = request;
46
+ return request;
47
+ }
48
+
49
+ function load(): Promise<T | null> {
50
+ return data.value ? Promise.resolve(data.value) : refresh();
51
+ }
52
+
53
+ return { data, error, load, refresh };
54
+ }
@@ -0,0 +1,74 @@
1
+ import { onUnmounted } from "vue";
2
+
3
+ interface UseStripePaymentElementOptions {
4
+ publishableKey: string;
5
+ clientSecret: string;
6
+ containerId: string;
7
+ }
8
+
9
+ interface ConfirmResult {
10
+ paymentMethodId?: string;
11
+ error?: { message: string };
12
+ }
13
+
14
+ interface StripePaymentElementHandle {
15
+ confirmAndGetPaymentMethod: () => Promise<ConfirmResult>;
16
+ }
17
+
18
+ const ALLOWED_PAYMENT_METHODS = ["card"];
19
+ const ALLOWED_CARD_BRANDS = ["visa", "mastercard"];
20
+
21
+ export function useStripePaymentElement(
22
+ options: UseStripePaymentElementOptions,
23
+ ): StripePaymentElementHandle {
24
+ let stripeInstance: any = null;
25
+ let elementsInstance: any = null;
26
+
27
+ async function init(): Promise<void> {
28
+ const { loadStripe } = await import("@stripe/stripe-js");
29
+ stripeInstance = await loadStripe(options.publishableKey);
30
+ if (!stripeInstance) {
31
+ return;
32
+ }
33
+ elementsInstance = stripeInstance.elements({
34
+ clientSecret: options.clientSecret,
35
+ paymentMethodTypes: ALLOWED_PAYMENT_METHODS,
36
+ });
37
+ const paymentElement = elementsInstance.create("payment", {
38
+ paymentMethodTypes: ALLOWED_PAYMENT_METHODS,
39
+ wallets: { applePay: "never", googlePay: "never" },
40
+ fields: {
41
+ billingDetails: { address: "auto", name: "auto", email: "never" },
42
+ },
43
+ cardBrands: ALLOWED_CARD_BRANDS,
44
+ });
45
+ paymentElement.mount(`#${options.containerId}`);
46
+ }
47
+
48
+ async function confirmAndGetPaymentMethod(): Promise<ConfirmResult> {
49
+ if (!stripeInstance || !elementsInstance) {
50
+ return { error: { message: "Stripe not initialized" } };
51
+ }
52
+ const result = await stripeInstance.confirmSetup({
53
+ elements: elementsInstance,
54
+ redirect: "if_required",
55
+ });
56
+ if (result.error) {
57
+ return { error: { message: result.error.message } };
58
+ }
59
+ const paymentMethodId = result.setupIntent?.payment_method;
60
+ if (typeof paymentMethodId !== "string") {
61
+ return { error: { message: "No payment method returned" } };
62
+ }
63
+ return { paymentMethodId };
64
+ }
65
+
66
+ onUnmounted(() => {
67
+ elementsInstance = null;
68
+ stripeInstance = null;
69
+ });
70
+
71
+ void init();
72
+
73
+ return { confirmAndGetPaymentMethod };
74
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Subscription statuses that close a workspace, mirroring the backend gate's
3
+ * `BLOCKING_STATUSES`. The billing page stays reachable in those states, so its
4
+ * blocks use this to keep the controls the gate still refuses out of the way.
5
+ */
6
+ const BLOCKING_STATUSES = new Set(["pending_payment", "suspended", "cancelled"]);
7
+
8
+ export function isBlockingSubscriptionStatus(
9
+ status: string | null | undefined,
10
+ ): boolean {
11
+ return !!status && BLOCKING_STATUSES.has(status);
12
+ }