@stapel/workspaces-react 0.5.0 → 0.7.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 (100) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/api/generated/schema.d.ts +384 -4
  3. package/dist/api/generated/schema.d.ts.map +1 -1
  4. package/dist/api/types.d.ts +20 -5
  5. package/dist/api/types.d.ts.map +1 -1
  6. package/dist/api/workspacesApi.d.ts +23 -1
  7. package/dist/api/workspacesApi.d.ts.map +1 -1
  8. package/dist/api/workspacesApi.js +4 -0
  9. package/dist/api/workspacesApi.js.map +1 -1
  10. package/dist/default/InviteAcceptPage.d.ts +28 -0
  11. package/dist/default/InviteAcceptPage.d.ts.map +1 -0
  12. package/dist/default/InviteAcceptPage.js +141 -0
  13. package/dist/default/InviteAcceptPage.js.map +1 -0
  14. package/dist/default/MembersManager.d.ts +4 -4
  15. package/dist/default/MembersManager.d.ts.map +1 -1
  16. package/dist/default/MembersManager.js +61 -56
  17. package/dist/default/MembersManager.js.map +1 -1
  18. package/dist/default/index.d.ts +2 -0
  19. package/dist/default/index.d.ts.map +1 -1
  20. package/dist/default/index.js +1 -0
  21. package/dist/default/index.js.map +1 -1
  22. package/dist/flows/inviteAcceptFlow.d.ts +155 -0
  23. package/dist/flows/inviteAcceptFlow.d.ts.map +1 -0
  24. package/dist/flows/inviteAcceptFlow.js +126 -0
  25. package/dist/flows/inviteAcceptFlow.js.map +1 -0
  26. package/dist/headless/Can.d.ts +40 -0
  27. package/dist/headless/Can.d.ts.map +1 -0
  28. package/dist/headless/Can.js +30 -0
  29. package/dist/headless/Can.js.map +1 -0
  30. package/dist/headless/InviteAcceptFlow.d.ts +44 -0
  31. package/dist/headless/InviteAcceptFlow.d.ts.map +1 -0
  32. package/dist/headless/InviteAcceptFlow.js +67 -0
  33. package/dist/headless/InviteAcceptFlow.js.map +1 -0
  34. package/dist/headless/RoleSelect.d.ts +41 -0
  35. package/dist/headless/RoleSelect.d.ts.map +1 -0
  36. package/dist/headless/RoleSelect.js +34 -0
  37. package/dist/headless/RoleSelect.js.map +1 -0
  38. package/dist/i18n/generated/errors.gen.d.ts +48 -0
  39. package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
  40. package/dist/i18n/generated/errors.gen.js +24 -0
  41. package/dist/i18n/generated/errors.gen.js.map +1 -1
  42. package/dist/i18n/generated/errors.ru.gen.d.ts.map +1 -1
  43. package/dist/i18n/generated/errors.ru.gen.js +8 -0
  44. package/dist/i18n/generated/errors.ru.gen.js.map +1 -1
  45. package/dist/i18n/keys.d.ts +28 -0
  46. package/dist/i18n/keys.d.ts.map +1 -1
  47. package/dist/i18n/keys.js +64 -0
  48. package/dist/i18n/keys.js.map +1 -1
  49. package/dist/i18n/ru.d.ts.map +1 -1
  50. package/dist/i18n/ru.js +30 -0
  51. package/dist/i18n/ru.js.map +1 -1
  52. package/dist/index.d.ts +14 -3
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +9 -2
  55. package/dist/index.js.map +1 -1
  56. package/dist/model/capabilities.d.ts +21 -0
  57. package/dist/model/capabilities.d.ts.map +1 -0
  58. package/dist/model/capabilities.js +32 -0
  59. package/dist/model/capabilities.js.map +1 -0
  60. package/dist/model/emailMask.d.ts +22 -0
  61. package/dist/model/emailMask.d.ts.map +1 -0
  62. package/dist/model/emailMask.js +36 -0
  63. package/dist/model/emailMask.js.map +1 -0
  64. package/dist/model/mutations.d.ts +23 -3
  65. package/dist/model/mutations.d.ts.map +1 -1
  66. package/dist/model/mutations.js +39 -1
  67. package/dist/model/mutations.js.map +1 -1
  68. package/dist/model/queries.d.ts +56 -6
  69. package/dist/model/queries.d.ts.map +1 -1
  70. package/dist/model/queries.js +75 -7
  71. package/dist/model/queries.js.map +1 -1
  72. package/dist/model/queryKeys.d.ts +2 -0
  73. package/dist/model/queryKeys.d.ts.map +1 -1
  74. package/dist/model/queryKeys.js +6 -0
  75. package/dist/model/queryKeys.js.map +1 -1
  76. package/llms.txt +40 -15
  77. package/manifest.json +225 -3
  78. package/package.json +5 -5
  79. package/src/analytics/generated/events.json +1 -1
  80. package/src/api/generated/schema.ts +384 -4
  81. package/src/api/types.ts +20 -5
  82. package/src/api/workspacesApi.ts +50 -0
  83. package/src/default/InviteAcceptPage.tsx +373 -0
  84. package/src/default/MembersManager.tsx +155 -145
  85. package/src/default/index.ts +2 -0
  86. package/src/flows/inviteAcceptFlow.ts +289 -0
  87. package/src/headless/Can.tsx +49 -0
  88. package/src/headless/InviteAcceptFlow.tsx +105 -0
  89. package/src/headless/RoleSelect.tsx +58 -0
  90. package/src/i18n/generated/errors.gen.ts +24 -0
  91. package/src/i18n/generated/errors.json +62 -0
  92. package/src/i18n/generated/errors.ru.gen.ts +8 -0
  93. package/src/i18n/keys.ts +68 -0
  94. package/src/i18n/ru.ts +34 -0
  95. package/src/index.ts +26 -0
  96. package/src/model/capabilities.ts +37 -0
  97. package/src/model/emailMask.ts +37 -0
  98. package/src/model/mutations.ts +56 -4
  99. package/src/model/queries.ts +99 -7
  100. package/src/model/queryKeys.ts +10 -0
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAI7D,gFAAgF;AAChF,4EAA4E;AAC5E,4EAA4E;AAC5E,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOvE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOtE,gFAAgF;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAK7D,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,YAAY,EACZ,UAAU,GACX,MAAM,oBAAoB,CAAC;AAE5B,gFAAgF;AAChF,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAqB9B,gFAAgF;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAGlE,gFAAgF;AAChF,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAGxB,gFAAgF;AAChF,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,gFAAgF;AAChF,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAI7D,gFAAgF;AAChF,4EAA4E;AAC5E,4EAA4E;AAC5E,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAOvE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAMrE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAOtE,gFAAgF;AAChF,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAK7D,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,gFAAgF;AAChF,OAAO,EACL,aAAa,EACb,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,gFAAgF;AAChF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEnE,gFAAgF;AAChF,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,sBAAsB,CAAC;AAyB9B,gFAAgF;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEhD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAElE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AAGlE,gFAAgF;AAChF,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAGxB,gFAAgF;AAChF,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Client-side capability matcher (org-program §A1/§A2) — a PORT of
3
+ * stapel-workspaces' `capabilities.capability_matches` (which is itself
4
+ * mirrored by the consumer helper in `stapel_core.django.workspaces`).
5
+ * KEEP SEMANTICS IN SYNC with the backend: capability strings are namespaced
6
+ * `"<domain>.<action>"`, free-form for the client (`meetings.spotlight`,
7
+ * `records.view`, …); a granted string may be the exact capability, the
8
+ * global wildcard `"*"`, or a prefix wildcard like `"members.*"` (which
9
+ * matches `members.remove` AND deeper `members.role.change`).
10
+ *
11
+ * The client-side check is a UI convenience (hide/disable affordances) —
12
+ * NEVER an access decision: the backend re-checks every capability on every
13
+ * operation (`has_capability` in-service, `workspaces.check_capability`
14
+ * cross-service).
15
+ */
16
+ /** Match one granted capability string against the requested one. */
17
+ export declare function capabilityMatches(capability: string, granted: string): boolean;
18
+ /** True if any of `granted` (verbatim registry strings, wildcards included)
19
+ * matches `capability`. Empty/absent grants deny — deny-by-default. */
20
+ export declare function hasCapability(granted: readonly string[] | null | undefined, capability: string): boolean;
21
+ //# sourceMappingURL=capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/model/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,qEAAqE;AACrE,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAMT;AAED;uEACuE;AACvE,wBAAgB,aAAa,CAC3B,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,EAC7C,UAAU,EAAE,MAAM,GACjB,OAAO,CAGT"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Client-side capability matcher (org-program §A1/§A2) — a PORT of
3
+ * stapel-workspaces' `capabilities.capability_matches` (which is itself
4
+ * mirrored by the consumer helper in `stapel_core.django.workspaces`).
5
+ * KEEP SEMANTICS IN SYNC with the backend: capability strings are namespaced
6
+ * `"<domain>.<action>"`, free-form for the client (`meetings.spotlight`,
7
+ * `records.view`, …); a granted string may be the exact capability, the
8
+ * global wildcard `"*"`, or a prefix wildcard like `"members.*"` (which
9
+ * matches `members.remove` AND deeper `members.role.change`).
10
+ *
11
+ * The client-side check is a UI convenience (hide/disable affordances) —
12
+ * NEVER an access decision: the backend re-checks every capability on every
13
+ * operation (`has_capability` in-service, `workspaces.check_capability`
14
+ * cross-service).
15
+ */
16
+ /** Match one granted capability string against the requested one. */
17
+ export function capabilityMatches(capability, granted) {
18
+ if (granted === "*" || granted === capability)
19
+ return true;
20
+ if (granted.endsWith(".*")) {
21
+ return capability.startsWith(granted.slice(0, -1));
22
+ }
23
+ return false;
24
+ }
25
+ /** True if any of `granted` (verbatim registry strings, wildcards included)
26
+ * matches `capability`. Empty/absent grants deny — deny-by-default. */
27
+ export function hasCapability(granted, capability) {
28
+ if (!granted)
29
+ return false;
30
+ return granted.some((g) => capabilityMatches(capability, g));
31
+ }
32
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/model/capabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,qEAAqE;AACrE,MAAM,UAAU,iBAAiB,CAC/B,UAAkB,EAClB,OAAe;IAEf,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IAC3D,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;uEACuE;AACvE,MAAM,UAAU,aAAa,CAC3B,OAA6C,EAC7C,UAAkB;IAElB,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Email masking — a PORT of stapel-workspaces' `views._mask_email` (the
3
+ * function that produces `InvitationPreviewResponse.email_masked`). KEEP IN
4
+ * SYNC with the backend: first character of the local part and of the domain
5
+ * name survive, the TLD stays readable — `m***@e***.com`.
6
+ *
7
+ * Why the client re-implements it: the public invitation preview deliberately
8
+ * carries only the MASKED email (harvest-proof, org-program §B2), yet the
9
+ * §B4 flow must route "session & email match" vs "wrong account" BEFORE
10
+ * attempting the accept. Masking the signed-in account's own (fully known)
11
+ * email with the same algorithm and comparing the two masks is the exact
12
+ * decision the backend would make — without ever exposing the invitee's
13
+ * address. A mask collision (two addresses masking identically) merely shows
14
+ * the accept prompt; the backend's real email-match on accept remains the
15
+ * enforcement point.
16
+ */
17
+ /** Mask an email exactly like the backend's invitation preview does. */
18
+ export declare function maskEmail(email: string): string;
19
+ /** Whether `email`, masked by the backend's algorithm, equals `emailMasked`
20
+ * (case-insensitive on the email, as the backend matches `iexact`). */
21
+ export declare function emailMatchesMask(email: string, emailMasked: string): boolean;
22
+ //# sourceMappingURL=emailMask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emailMask.d.ts","sourceRoot":"","sources":["../../src/model/emailMask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAY/C;AAED;uEACuE;AACvE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAE5E"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Email masking — a PORT of stapel-workspaces' `views._mask_email` (the
3
+ * function that produces `InvitationPreviewResponse.email_masked`). KEEP IN
4
+ * SYNC with the backend: first character of the local part and of the domain
5
+ * name survive, the TLD stays readable — `m***@e***.com`.
6
+ *
7
+ * Why the client re-implements it: the public invitation preview deliberately
8
+ * carries only the MASKED email (harvest-proof, org-program §B2), yet the
9
+ * §B4 flow must route "session & email match" vs "wrong account" BEFORE
10
+ * attempting the accept. Masking the signed-in account's own (fully known)
11
+ * email with the same algorithm and comparing the two masks is the exact
12
+ * decision the backend would make — without ever exposing the invitee's
13
+ * address. A mask collision (two addresses masking identically) merely shows
14
+ * the accept prompt; the backend's real email-match on accept remains the
15
+ * enforcement point.
16
+ */
17
+ /** Mask an email exactly like the backend's invitation preview does. */
18
+ export function maskEmail(email) {
19
+ const at = email.indexOf("@");
20
+ const local = at === -1 ? email : email.slice(0, at);
21
+ const domain = at === -1 ? "" : email.slice(at + 1);
22
+ const dot = domain.lastIndexOf(".");
23
+ const maskedLocal = `${local.slice(0, 1) || "*"}***`;
24
+ if (dot !== -1) {
25
+ const domainName = domain.slice(0, dot);
26
+ const tld = domain.slice(dot + 1);
27
+ return `${maskedLocal}@${domainName.slice(0, 1) || "*"}***.${tld}`;
28
+ }
29
+ return `${maskedLocal}@${domain.slice(0, 1) || "*"}***`;
30
+ }
31
+ /** Whether `email`, masked by the backend's algorithm, equals `emailMasked`
32
+ * (case-insensitive on the email, as the backend matches `iexact`). */
33
+ export function emailMatchesMask(email, emailMasked) {
34
+ return maskEmail(email.trim().toLowerCase()) === emailMasked.toLowerCase();
35
+ }
36
+ //# sourceMappingURL=emailMask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emailMask.js","sourceRoot":"","sources":["../../src/model/emailMask.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,wEAAwE;AACxE,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACpC,MAAM,WAAW,GAAG,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC;IACrD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QACxC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QAClC,OAAO,GAAG,WAAW,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,OAAO,GAAG,EAAE,CAAC;IACrE,CAAC;IACD,OAAO,GAAG,WAAW,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC;AAC1D,CAAC;AAED;uEACuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,WAAmB;IACjE,OAAO,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,WAAW,CAAC,WAAW,EAAE,CAAC;AAC7E,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { UseMutationResult } from "@tanstack/react-query";
2
2
  import type { StapelApiError } from "@stapel/core";
3
- import type { Member, MemberInvite, MemberInviteResult, InvitationAccept, Workspace, WorkspaceCreate, WorkspaceRole, WorkspaceUpdate } from "../api/types.js";
3
+ import type { Member, MemberInvite, MemberInviteResult, InvitationAccept, InvitationClaim, Workspace, WorkspaceCreate, WorkspaceUpdate } from "../api/types.js";
4
4
  /**
5
5
  * Write hooks (frontend-standard §2 — "мутации с инвалидацией"). Each mutation
6
6
  * invalidates exactly the server state it can move. Membership and ownership are
@@ -29,10 +29,14 @@ export declare function useDeleteWorkspace(): UseMutationResult<void, StapelApiE
29
29
  * there).
30
30
  */
31
31
  export declare function useInviteMembers(workspaceId: string): UseMutationResult<MemberInviteResult, StapelApiError, MemberInvite>;
32
- /** The variable for {@link useUpdateMemberRole}: which member, which new role. */
32
+ /** The variable for {@link useUpdateMemberRole}: which member, which new role.
33
+ * `role` is an open string since stapel-workspaces 0.6.0 (org-program §A1):
34
+ * the effective registry is settings-extensible, so any key of GET /roles is
35
+ * valid — the backend validates against the registry. {@link WorkspaceRole}
36
+ * still names the builtin four for literals. */
33
37
  export interface MemberRoleChange {
34
38
  readonly userId: string;
35
- readonly role: WorkspaceRole;
39
+ readonly role: string;
36
40
  }
37
41
  /**
38
42
  * Change a member's role (admin+; the backend guards owner grants and the
@@ -52,4 +56,20 @@ export declare function useRemoveMember(workspaceId: string): UseMutationResult<
52
56
  * Refreshes the workspace list (the new membership appears there).
53
57
  */
54
58
  export declare function useAcceptInvitation(): UseMutationResult<Member, StapelApiError, InvitationAccept>;
59
+ /**
60
+ * Mint a login grant for a NOT-yet-registered invitee (POST
61
+ * /invitations/{token}/claim, AllowAny — org-program §B2/§B3). The variable
62
+ * is the invite token; the result carries the single-use `grant_token` to
63
+ * exchange at AUTH's `POST /grant/exchange/` (the auth-react api — this pair
64
+ * deliberately does not call it; see `InviteAcceptFlow`'s `onLoginGrant`
65
+ * seam). 409 `email_already_registered` → switch to login. The invitation is
66
+ * NOT consumed here. The grant token is a credential: never log it.
67
+ */
68
+ export declare function useClaimInvitation(): UseMutationResult<InvitationClaim, StapelApiError, string>;
69
+ /**
70
+ * Decline an invitation (POST /invitations/{token}/decline, authenticated +
71
+ * email-match — org-program §B2). The variable is the invite token. Decline ≠
72
+ * revoke — the preview's `status` becomes `declined`.
73
+ */
74
+ export declare function useDeclineInvitation(): UseMutationResult<void, StapelApiError, string>;
55
75
  //# sourceMappingURL=mutations.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../../src/model/mutations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,eAAe,EACf,aAAa,EACb,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAIzB;;;;;;;;;;;GAWG;AAEH,wEAAwE;AACxE,wBAAgB,kBAAkB,IAAI,iBAAiB,CACrD,SAAS,EACT,cAAc,EACd,eAAe,CAChB,CAaA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAAC,SAAS,EAAE,cAAc,EAAE,eAAe,CAAC,CAiB/D;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,IAAI,iBAAiB,CACrD,IAAI,EACJ,cAAc,EACd,MAAM,CACP,CAeA;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAAC,kBAAkB,EAAE,cAAc,EAAE,YAAY,CAAC,CAgBrE;AAED,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAa7D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,CAAC,CAYjD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,iBAAiB,CACtD,MAAM,EACN,cAAc,EACd,gBAAgB,CACjB,CAYA"}
1
+ {"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../../src/model/mutations.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EACV,MAAM,EACN,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,eAAe,EACf,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAIzB;;;;;;;;;;;GAWG;AAEH,wEAAwE;AACxE,wBAAgB,kBAAkB,IAAI,iBAAiB,CACrD,SAAS,EACT,cAAc,EACd,eAAe,CAChB,CAaA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAAC,SAAS,EAAE,cAAc,EAAE,eAAe,CAAC,CAiB/D;AAED,0FAA0F;AAC1F,wBAAgB,kBAAkB,IAAI,iBAAiB,CACrD,IAAI,EACJ,cAAc,EACd,MAAM,CACP,CAeA;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAAC,kBAAkB,EAAE,cAAc,EAAE,YAAY,CAAC,CAgBrE;AAED;;;;gDAIgD;AAChD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAAC,MAAM,EAAE,cAAc,EAAE,gBAAgB,CAAC,CAa7D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,MAAM,GAClB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,CAAC,CAYjD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,iBAAiB,CACtD,MAAM,EACN,cAAc,EACd,gBAAgB,CACjB,CAgBA;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,IAAI,iBAAiB,CACrD,eAAe,EACf,cAAc,EACd,MAAM,CACP,CAMA;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,iBAAiB,CACvD,IAAI,EACJ,cAAc,EACd,MAAM,CACP,CAYA"}
@@ -127,10 +127,48 @@ export function useAcceptInvitation() {
127
127
  const queryClient = useQueryClient();
128
128
  const options = {
129
129
  mutationFn: (body) => api.acceptInvitation(body),
130
- onSuccess: () => {
130
+ onSuccess: (_member, body) => {
131
131
  void queryClient.invalidateQueries({
132
132
  queryKey: workspacesQueryKeys.list(),
133
133
  });
134
+ // The preview's `status` moved pending → accepted.
135
+ void queryClient.invalidateQueries({
136
+ queryKey: workspacesQueryKeys.invitationPreview(body.token),
137
+ });
138
+ },
139
+ };
140
+ return useMutation(options);
141
+ }
142
+ /**
143
+ * Mint a login grant for a NOT-yet-registered invitee (POST
144
+ * /invitations/{token}/claim, AllowAny — org-program §B2/§B3). The variable
145
+ * is the invite token; the result carries the single-use `grant_token` to
146
+ * exchange at AUTH's `POST /grant/exchange/` (the auth-react api — this pair
147
+ * deliberately does not call it; see `InviteAcceptFlow`'s `onLoginGrant`
148
+ * seam). 409 `email_already_registered` → switch to login. The invitation is
149
+ * NOT consumed here. The grant token is a credential: never log it.
150
+ */
151
+ export function useClaimInvitation() {
152
+ const api = useWorkspacesApi();
153
+ const options = {
154
+ mutationFn: (token) => api.claimInvitation(token),
155
+ };
156
+ return useMutation(options);
157
+ }
158
+ /**
159
+ * Decline an invitation (POST /invitations/{token}/decline, authenticated +
160
+ * email-match — org-program §B2). The variable is the invite token. Decline ≠
161
+ * revoke — the preview's `status` becomes `declined`.
162
+ */
163
+ export function useDeclineInvitation() {
164
+ const api = useWorkspacesApi();
165
+ const queryClient = useQueryClient();
166
+ const options = {
167
+ mutationFn: (token) => api.declineInvitation(token),
168
+ onSuccess: (_result, token) => {
169
+ void queryClient.invalidateQueries({
170
+ queryKey: workspacesQueryKeys.invitationPreview(token),
171
+ });
134
172
  },
135
173
  };
136
174
  return useMutation(options);
@@ -1 +1 @@
1
- {"version":3,"file":"mutations.js","sourceRoot":"","sources":["../../src/model/mutations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mutations.js","sourceRoot":"","sources":["../../src/model/mutations.ts"],"names":[],"mappings":"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"}
@@ -1,23 +1,73 @@
1
1
  import type { UseQueryResult } from "@tanstack/react-query";
2
2
  import type { StapelApiError } from "@stapel/core";
3
- import type { MemberPage, MembersParams, Workspace, WorkspaceList } from "../api/types.js";
3
+ import type { InvitationPreview, MemberPage, MembersParams, RoleInfo, Workspace, WorkspaceList } from "../api/types.js";
4
4
  /**
5
5
  * Read hooks over the workspaces API. Staleness follows core's query defaults;
6
6
  * override per call site via a page that needs fresher data. Keys are
7
7
  * namespaced (see `workspacesQueryKeys`).
8
8
  */
9
- /** The caller's workspaces — their accepted memberships (GET /). */
9
+ /**
10
+ * The caller's workspaces — their accepted memberships (GET /).
11
+ *
12
+ * Gated on {@link useActiveSessionReady} (owner-diagnosed live incident,
13
+ * 2026-07-17): unlike {@link useWorkspace}/{@link useMembers} below (both
14
+ * naturally disabled until a `workspaceId` is picked), this is the top-level
15
+ * list hook with nothing else to gate it — it fires the instant a component
16
+ * mounts. Without the session ready-gate this is exactly the shape of hook
17
+ * that raced a session still bootstrapping (e.g. right after a QR
18
+ * `session_share` scan set fresh cookies this JS runtime hadn't caught up
19
+ * to yet) and read a live session as "expired" before it had a chance to
20
+ * resolve — zero manual `enabled` wiring needed at each call site by design.
21
+ */
10
22
  export declare function useWorkspaces(): UseQueryResult<WorkspaceList, StapelApiError>;
11
23
  /**
12
24
  * A single workspace by id (GET /{id}). Disabled until a `workspaceId` is
13
- * given, so a detail hook can mount before a selection exists.
25
+ * given, so a detail hook can mount before a selection exists — AND until
26
+ * the session is ready (a `workspaceId` can be known synchronously, e.g.
27
+ * from a URL param, before the session has finished bootstrapping).
14
28
  */
15
29
  export declare function useWorkspace(workspaceId: string | null): UseQueryResult<Workspace, StapelApiError>;
16
30
  /**
17
31
  * A page of a workspace's members (GET /{id}/members, anchor-paginated).
18
- * Disabled until a `workspaceId` is given. Pass `{ anchor, direction, limit,
19
- * search }` to jump to a specific page or filter; omit for the newest page
20
- * (default limit 100).
32
+ * Disabled until a `workspaceId` is given (and the session is ready — see
33
+ * {@link useWorkspace}). Pass `{ anchor, direction, limit, search }` to jump
34
+ * to a specific page or filter; omit for the newest page (default limit 100).
21
35
  */
22
36
  export declare function useMembers(workspaceId: string | null, params?: MembersParams): UseQueryResult<MemberPage, StapelApiError>;
37
+ /**
38
+ * The effective role registry (GET /roles, org-program §A2): builtin four +
39
+ * the deployment's `STAPEL_WORKSPACES["ROLES"]` overlay, capability strings
40
+ * verbatim, rank-descending. Deployment-static data — role UI (RoleSelect)
41
+ * reads this instead of hardcoding the builtin four. Session-ready-gated like
42
+ * {@link useWorkspaces} (IsAuthenticated endpoint, mounts at screen top).
43
+ */
44
+ export declare function useRoles(): UseQueryResult<readonly RoleInfo[], StapelApiError>;
45
+ /**
46
+ * Public invitation preview (GET /invitations/{token}, AllowAny — org-program
47
+ * §B2): what the `/invite/{token}` page renders BEFORE any auth decision.
48
+ * Deliberately NOT session-gated — the whole point is that the invitee may
49
+ * have no session at all; the token in the URL is the bearer secret.
50
+ */
51
+ export declare function useInvitationPreview(token: string | null): UseQueryResult<InvitationPreview, StapelApiError>;
52
+ /** What {@link useCapabilities} returns: the caller's granted capability
53
+ * strings in one workspace plus the wildcard-aware `can()` check. */
54
+ export interface CapabilitiesResult {
55
+ /** Verbatim registry strings of the caller's role (wildcards included);
56
+ * empty while loading or when the caller is not a member. */
57
+ readonly capabilities: readonly string[];
58
+ /** Wildcard-aware check (`*` / `prefix.*` — the backend matcher, ported).
59
+ * UI convenience only: the backend re-checks on every operation. */
60
+ can(capability: string): boolean;
61
+ readonly isLoading: boolean;
62
+ readonly isError: boolean;
63
+ readonly error: StapelApiError | null;
64
+ }
65
+ /**
66
+ * The caller's capabilities in one workspace (org-program §A2): reads
67
+ * `my_capabilities` off the workspace detail (`WorkspaceResponse`, additive
68
+ * field since stapel-workspaces 0.6.0) and exposes the ported wildcard
69
+ * matcher. Deny-by-default: `can()` is false while loading, on error, or when
70
+ * the backend predates the field.
71
+ */
72
+ export declare function useCapabilities(workspaceId: string | null): CapabilitiesResult;
23
73
  //# sourceMappingURL=queries.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/model/queries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EACV,UAAU,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACd,MAAM,iBAAiB,CAAC;AAIzB;;;;GAIG;AAEH,oEAAoE;AACpE,wBAAgB,aAAa,IAAI,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,CAM7E;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,cAAc,CAAC,SAAS,EAAE,cAAc,CAAC,CAO3C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,MAAM,CAAC,EAAE,aAAa,GACrB,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,CAQ5C"}
1
+ {"version":3,"file":"queries.d.ts","sourceRoot":"","sources":["../../src/model/queries.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,QAAQ,EACR,SAAS,EACT,aAAa,EACd,MAAM,iBAAiB,CAAC;AAKzB;;;;GAIG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,IAAI,cAAc,CAAC,aAAa,EAAE,cAAc,CAAC,CAQ7E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,cAAc,CAAC,SAAS,EAAE,cAAc,CAAC,CAQ3C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,MAAM,CAAC,EAAE,aAAa,GACrB,cAAc,CAAC,UAAU,EAAE,cAAc,CAAC,CAS5C;AAED;;;;;;GAMG;AACH,wBAAgB,QAAQ,IAAI,cAAc,CACxC,SAAS,QAAQ,EAAE,EACnB,cAAc,CACf,CAQA;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,cAAc,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAOnD;AAED;qEACqE;AACrE,MAAM,WAAW,kBAAkB;IACjC;iEAC6D;IAC7D,QAAQ,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC;wEACoE;IACpE,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;CACvC;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,kBAAkB,CAU9E"}
@@ -1,44 +1,112 @@
1
1
  import { useQuery } from "@tanstack/react-query";
2
+ import { useActiveSessionReady } from "@stapel/core";
2
3
  import { useWorkspacesApi } from "./context.js";
3
4
  import { workspacesQueryKeys } from "./queryKeys.js";
5
+ import { hasCapability } from "./capabilities.js";
4
6
  /**
5
7
  * Read hooks over the workspaces API. Staleness follows core's query defaults;
6
8
  * override per call site via a page that needs fresher data. Keys are
7
9
  * namespaced (see `workspacesQueryKeys`).
8
10
  */
9
- /** The caller's workspaces — their accepted memberships (GET /). */
11
+ /**
12
+ * The caller's workspaces — their accepted memberships (GET /).
13
+ *
14
+ * Gated on {@link useActiveSessionReady} (owner-diagnosed live incident,
15
+ * 2026-07-17): unlike {@link useWorkspace}/{@link useMembers} below (both
16
+ * naturally disabled until a `workspaceId` is picked), this is the top-level
17
+ * list hook with nothing else to gate it — it fires the instant a component
18
+ * mounts. Without the session ready-gate this is exactly the shape of hook
19
+ * that raced a session still bootstrapping (e.g. right after a QR
20
+ * `session_share` scan set fresh cookies this JS runtime hadn't caught up
21
+ * to yet) and read a live session as "expired" before it had a chance to
22
+ * resolve — zero manual `enabled` wiring needed at each call site by design.
23
+ */
10
24
  export function useWorkspaces() {
11
25
  const api = useWorkspacesApi();
26
+ const sessionReady = useActiveSessionReady();
12
27
  return useQuery({
13
28
  queryKey: workspacesQueryKeys.list(),
14
29
  queryFn: () => api.listWorkspaces(),
30
+ enabled: sessionReady,
15
31
  });
16
32
  }
17
33
  /**
18
34
  * A single workspace by id (GET /{id}). Disabled until a `workspaceId` is
19
- * given, so a detail hook can mount before a selection exists.
35
+ * given, so a detail hook can mount before a selection exists — AND until
36
+ * the session is ready (a `workspaceId` can be known synchronously, e.g.
37
+ * from a URL param, before the session has finished bootstrapping).
20
38
  */
21
39
  export function useWorkspace(workspaceId) {
22
40
  const api = useWorkspacesApi();
41
+ const sessionReady = useActiveSessionReady();
23
42
  return useQuery({
24
43
  queryKey: workspacesQueryKeys.detail(workspaceId ?? ""),
25
44
  queryFn: () => api.getWorkspace(workspaceId),
26
- enabled: workspaceId !== null && workspaceId !== "",
45
+ enabled: sessionReady && workspaceId !== null && workspaceId !== "",
27
46
  });
28
47
  }
29
48
  /**
30
49
  * A page of a workspace's members (GET /{id}/members, anchor-paginated).
31
- * Disabled until a `workspaceId` is given. Pass `{ anchor, direction, limit,
32
- * search }` to jump to a specific page or filter; omit for the newest page
33
- * (default limit 100).
50
+ * Disabled until a `workspaceId` is given (and the session is ready — see
51
+ * {@link useWorkspace}). Pass `{ anchor, direction, limit, search }` to jump
52
+ * to a specific page or filter; omit for the newest page (default limit 100).
34
53
  */
35
54
  export function useMembers(workspaceId, params) {
36
55
  const api = useWorkspacesApi();
56
+ const sessionReady = useActiveSessionReady();
37
57
  const p = params ?? {};
38
58
  return useQuery({
39
59
  queryKey: workspacesQueryKeys.membersPage(workspaceId ?? "", p),
40
60
  queryFn: () => api.listMembers(workspaceId, p),
41
- enabled: workspaceId !== null && workspaceId !== "",
61
+ enabled: sessionReady && workspaceId !== null && workspaceId !== "",
42
62
  });
43
63
  }
64
+ /**
65
+ * The effective role registry (GET /roles, org-program §A2): builtin four +
66
+ * the deployment's `STAPEL_WORKSPACES["ROLES"]` overlay, capability strings
67
+ * verbatim, rank-descending. Deployment-static data — role UI (RoleSelect)
68
+ * reads this instead of hardcoding the builtin four. Session-ready-gated like
69
+ * {@link useWorkspaces} (IsAuthenticated endpoint, mounts at screen top).
70
+ */
71
+ export function useRoles() {
72
+ const api = useWorkspacesApi();
73
+ const sessionReady = useActiveSessionReady();
74
+ return useQuery({
75
+ queryKey: workspacesQueryKeys.roles(),
76
+ queryFn: async () => (await api.listRoles()).roles ?? [],
77
+ enabled: sessionReady,
78
+ });
79
+ }
80
+ /**
81
+ * Public invitation preview (GET /invitations/{token}, AllowAny — org-program
82
+ * §B2): what the `/invite/{token}` page renders BEFORE any auth decision.
83
+ * Deliberately NOT session-gated — the whole point is that the invitee may
84
+ * have no session at all; the token in the URL is the bearer secret.
85
+ */
86
+ export function useInvitationPreview(token) {
87
+ const api = useWorkspacesApi();
88
+ return useQuery({
89
+ queryKey: workspacesQueryKeys.invitationPreview(token ?? ""),
90
+ queryFn: () => api.getInvitationPreview(token),
91
+ enabled: token !== null && token !== "",
92
+ });
93
+ }
94
+ /**
95
+ * The caller's capabilities in one workspace (org-program §A2): reads
96
+ * `my_capabilities` off the workspace detail (`WorkspaceResponse`, additive
97
+ * field since stapel-workspaces 0.6.0) and exposes the ported wildcard
98
+ * matcher. Deny-by-default: `can()` is false while loading, on error, or when
99
+ * the backend predates the field.
100
+ */
101
+ export function useCapabilities(workspaceId) {
102
+ const query = useWorkspace(workspaceId);
103
+ const capabilities = query.data?.my_capabilities ?? [];
104
+ return {
105
+ capabilities,
106
+ can: (capability) => hasCapability(capabilities, capability),
107
+ isLoading: query.isLoading,
108
+ isError: query.isError,
109
+ error: query.error ?? null,
110
+ };
111
+ }
44
112
  //# sourceMappingURL=queries.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/model/queries.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AASjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAErD;;;;GAIG;AAEH,oEAAoE;AACpE,MAAM,UAAU,aAAa;IAC3B,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAC/B,OAAO,QAAQ,CAAC;QACd,QAAQ,EAAE,mBAAmB,CAAC,IAAI,EAAE;QACpC,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,cAAc,EAAE;KACpC,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,WAA0B;IAE1B,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAC/B,OAAO,QAAQ,CAAC;QACd,QAAQ,EAAE,mBAAmB,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC;QACvD,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,CAAC,WAAqB,CAAC;QACtD,OAAO,EAAE,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,EAAE;KACpD,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CACxB,WAA0B,EAC1B,MAAsB;IAEtB,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAC;IAC/B,MAAM,CAAC,GAAG,MAAM,IAAI,EAAE,CAAC;IACvB,OAAO,QAAQ,CAAC;QACd,QAAQ,EAAE,mBAAmB,CAAC,WAAW,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/D,OAAO,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC,WAAqB,EAAE,CAAC,CAAC;QACxD,OAAO,EAAE,WAAW,KAAK,IAAI,IAAI,WAAW,KAAK,EAAE;KACpD,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/model/queries.ts"],"names":[],"mappings":"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"}
@@ -5,5 +5,7 @@ export declare const workspacesQueryKeys: {
5
5
  detail(workspaceId: string): readonly ["workspaces", "detail", string];
6
6
  members(workspaceId: string): readonly ["workspaces", "members", string];
7
7
  membersPage(workspaceId: string, params: MembersParams): readonly ["workspaces", "members", string, MembersParams];
8
+ roles(): readonly ["workspaces", "roles"];
9
+ invitationPreview(token: string): readonly ["workspaces", "invitation-preview", string];
8
10
  };
9
11
  //# sourceMappingURL=queryKeys.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryKeys.d.ts","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAWrD,eAAO,MAAM,mBAAmB,EAAE;IAChC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACtC,IAAI,IAAI,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvE,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACzE,WAAW,CACT,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,GACpB,SAAS,CAAC,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;CAS9D,CAAC"}
1
+ {"version":3,"file":"queryKeys.d.ts","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAWrD,eAAO,MAAM,mBAAmB,EAAE;IAChC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,YAAY,CAAC,CAAC;IACtC,IAAI,IAAI,SAAS,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;IACvE,OAAO,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC,YAAY,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IACzE,WAAW,CACT,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,aAAa,GACpB,SAAS,CAAC,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7D,KAAK,IAAI,SAAS,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;IAC1C,iBAAiB,CACf,KAAK,EAAE,MAAM,GACZ,SAAS,CAAC,YAAY,EAAE,oBAAoB,EAAE,MAAM,CAAC,CAAC;CAe1D,CAAC"}
@@ -14,5 +14,11 @@ export const workspacesQueryKeys = {
14
14
  // invalidating `members(workspaceId)` (mutations.ts) drops every page.
15
15
  members: (workspaceId) => [ROOT, "members", workspaceId],
16
16
  membersPage: (workspaceId, params) => [ROOT, "members", workspaceId, params],
17
+ roles: () => [ROOT, "roles"],
18
+ // NOTE: the key carries the invite TOKEN (a secret). Core's query persist
19
+ // scope is per-user and the preview response is already public-by-design
20
+ // (masked email only) — but hosts logging query keys should treat this one
21
+ // as sensitive.
22
+ invitationPreview: (token) => [ROOT, "invitation-preview", token],
17
23
  };
18
24
  //# sourceMappingURL=queryKeys.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,IAAI,GAAG,YAAqB,CAAC;AAEnC,MAAM,CAAC,MAAM,mBAAmB,GAS5B;IACF,GAAG,EAAE,CAAC,IAAI,CAAC;IACX,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC;IACtD,kEAAkE;IAClE,uEAAuE;IACvE,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC;IACxD,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC;CAC7E,CAAC"}
1
+ {"version":3,"file":"queryKeys.js","sourceRoot":"","sources":["../../src/model/queryKeys.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,IAAI,GAAG,YAAqB,CAAC;AAEnC,MAAM,CAAC,MAAM,mBAAmB,GAa5B;IACF,GAAG,EAAE,CAAC,IAAI,CAAC;IACX,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC;IACtD,kEAAkE;IAClE,uEAAuE;IACvE,OAAO,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,CAAC;IACxD,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC;IAC5E,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC;IAC5B,0EAA0E;IAC1E,yEAAyE;IACzE,2EAA2E;IAC3E,gBAAgB;IAChB,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,CAAC;CAClE,CAAC"}