@stapel/workspaces-react 0.7.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/dist/api/generated/schema.d.ts +497 -5
- package/dist/api/generated/schema.d.ts.map +1 -1
- package/dist/api/types.d.ts +91 -2
- package/dist/api/types.d.ts.map +1 -1
- package/dist/api/workspacesApi.d.ts +35 -1
- package/dist/api/workspacesApi.d.ts.map +1 -1
- package/dist/api/workspacesApi.js +20 -0
- package/dist/api/workspacesApi.js.map +1 -1
- package/dist/default/MembersManager.js +2 -2
- package/dist/i18n/generated/errors.gen.d.ts +6 -0
- package/dist/i18n/generated/errors.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.gen.js +3 -0
- package/dist/i18n/generated/errors.gen.js.map +1 -1
- package/dist/i18n/generated/errors.ru.gen.d.ts.map +1 -1
- package/dist/i18n/generated/errors.ru.gen.js +1 -0
- package/dist/i18n/generated/errors.ru.gen.js.map +1 -1
- package/dist/index.d.ts +7 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/model/mutations.d.ts +86 -2
- package/dist/model/mutations.d.ts.map +1 -1
- package/dist/model/mutations.js +152 -1
- package/dist/model/mutations.js.map +1 -1
- package/dist/model/queries.d.ts +90 -2
- package/dist/model/queries.d.ts.map +1 -1
- package/dist/model/queries.js +115 -1
- package/dist/model/queries.js.map +1 -1
- package/dist/model/queryKeys.d.ts +11 -1
- package/dist/model/queryKeys.d.ts.map +1 -1
- package/dist/model/queryKeys.js +21 -1
- package/dist/model/queryKeys.js.map +1 -1
- package/dist/model/stepUp.d.ts +25 -0
- package/dist/model/stepUp.d.ts.map +1 -0
- package/dist/model/stepUp.js +79 -0
- package/dist/model/stepUp.js.map +1 -0
- package/llms.txt +15 -3
- package/manifest.json +147 -2
- package/package.json +4 -4
- package/src/analytics/generated/events.json +1 -1
- package/src/api/generated/schema.ts +497 -5
- package/src/api/types.ts +101 -2
- package/src/api/workspacesApi.ts +93 -0
- package/src/default/MembersManager.tsx +2 -2
- package/src/i18n/generated/errors.gen.ts +3 -0
- package/src/i18n/generated/errors.json +9 -0
- package/src/i18n/generated/errors.ru.gen.ts +1 -0
- package/src/index.ts +30 -2
- package/src/model/mutations.ts +193 -1
- package/src/model/queries.ts +162 -2
- package/src/model/queryKeys.ts +38 -2
- package/src/model/stepUp.ts +96 -0
package/dist/model/queryKeys.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Namespaced TanStack Query keys (frontend-standard §2 —
|
|
2
|
+
* Namespaced TanStack Query keys (frontend-standard §2 — namespaced keys).
|
|
3
3
|
* Everything under the `"workspaces"` root so a host can invalidate the whole
|
|
4
4
|
* module or match a single resource. Persist scope is per-user via core's query
|
|
5
5
|
* runtime (`setPersistUser`). Explicit tuple return types satisfy
|
|
@@ -14,7 +14,27 @@ 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
|
+
// Same prefix trick as `members`: the bare 3-tuple invalidates every page
|
|
18
|
+
// (and the infinite list, which keys on it) after a revoke / resend.
|
|
19
|
+
invitations: (workspaceId) => [ROOT, "invitations", workspaceId],
|
|
20
|
+
invitationsPage: (workspaceId, params) => [
|
|
21
|
+
ROOT,
|
|
22
|
+
"invitations",
|
|
23
|
+
workspaceId,
|
|
24
|
+
params,
|
|
25
|
+
],
|
|
26
|
+
// The infinite list carries its own marker segment: its cached value is an
|
|
27
|
+
// `InfiniteData` envelope, not a page, so it must never collide with a
|
|
28
|
+
// single-page key that happens to hold the same filters.
|
|
29
|
+
invitationsInfinite: (workspaceId, filters) => [
|
|
30
|
+
ROOT,
|
|
31
|
+
"invitations",
|
|
32
|
+
workspaceId,
|
|
33
|
+
"infinite",
|
|
34
|
+
filters,
|
|
35
|
+
],
|
|
17
36
|
roles: () => [ROOT, "roles"],
|
|
37
|
+
instance: () => [ROOT, "instance"],
|
|
18
38
|
// NOTE: the key carries the invite TOKEN (a secret). Core's query persist
|
|
19
39
|
// scope is per-user and the preview response is already public-by-design
|
|
20
40
|
// (masked email only) — but hosts logging query keys should treat this one
|
|
@@ -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,
|
|
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,GA6B5B;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,0EAA0E;IAC1E,qEAAqE;IACrE,WAAW,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,CAAC;IAChE,eAAe,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,EAAE,CAAC;QACxC,IAAI;QACJ,aAAa;QACb,WAAW;QACX,MAAM;KACP;IACD,2EAA2E;IAC3E,uEAAuE;IACvE,yDAAyD;IACzD,mBAAmB,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,IAAI;QACJ,aAAa;QACb,WAAW;QACX,UAAU;QACV,OAAO;KACR;IACD,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC;IAClC,0EAA0E;IAC1E,yEAAyE;IACzE,2EAA2E;IAC3E,gBAAgB;IAChB,iBAAiB,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,oBAAoB,EAAE,KAAK,CAAC;CAClE,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** The verification scope every `high` workspace capability is gated under. */
|
|
2
|
+
export declare const SENSITIVE_SCOPE = "sensitive";
|
|
3
|
+
/** Step-up level of a capability. */
|
|
4
|
+
export type CapabilityLevel = "standard" | "high";
|
|
5
|
+
/** PORT of `BUILTIN_CAPABILITY_LEVELS` — everything unlisted is `standard`. */
|
|
6
|
+
export declare const BUILTIN_CAPABILITY_LEVELS: Readonly<Record<string, "high">>;
|
|
7
|
+
/** The declared step-up level of one capability string. */
|
|
8
|
+
export declare function capabilityLevel(capability: string): CapabilityLevel;
|
|
9
|
+
/**
|
|
10
|
+
* The 403 ENROLLMENT envelope: the caller must first enroll one of `factors`
|
|
11
|
+
* — there is no challenge to complete, so core cannot drive it.
|
|
12
|
+
*/
|
|
13
|
+
export interface VerificationEnrollment {
|
|
14
|
+
/** What the demand protects — `"sensitive"` for every `high` capability. */
|
|
15
|
+
readonly scope: string;
|
|
16
|
+
/** Interchangeable factors, any ONE of which unblocks the operation. */
|
|
17
|
+
readonly factors: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Read the enrollment demand out of a rejected request, or `null` when the
|
|
21
|
+
* error is anything else (including a step-up CHALLENGE, which carries a
|
|
22
|
+
* `challenge_id` and is core's business, not the consumer's).
|
|
23
|
+
*/
|
|
24
|
+
export declare function readVerificationEnrollment(error: unknown): VerificationEnrollment | null;
|
|
25
|
+
//# sourceMappingURL=stepUp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepUp.d.ts","sourceRoot":"","sources":["../../src/model/stepUp.ts"],"names":[],"mappings":"AAiCA,+EAA+E;AAC/E,eAAO,MAAM,eAAe,cAAc,CAAC;AAE3C,qCAAqC;AACrC,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,MAAM,CAAC;AAElD,+EAA+E;AAC/E,eAAO,MAAM,yBAAyB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAItE,CAAC;AAEF,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,CAEnE;AAED;;;GAGG;AACH,MAAM,WAAW,sBAAsB;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,wEAAwE;IACxE,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAQD;;;;GAIG;AACH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,sBAAsB,GAAG,IAAI,CAoB/B"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Step-up ahead of the button, not behind it (org-program §A3).
|
|
3
|
+
*
|
|
4
|
+
* Some workspace operations are declared **high**: the backend gates them
|
|
5
|
+
* with `stapel_core`'s `@requires_verification(scope="sensitive")` on top of
|
|
6
|
+
* the capability check, so an ambient cookie is never enough. A client that
|
|
7
|
+
* only learns this from the 403 shows the admin a button, a spinner and a
|
|
8
|
+
* refusal; this module lets it know BEFORE the click.
|
|
9
|
+
*
|
|
10
|
+
* Two things travel from the backend, and they are not the same thing:
|
|
11
|
+
*
|
|
12
|
+
* 1. **A step-up CHALLENGE** — `verification.challenge_id` is present. This
|
|
13
|
+
* one nobody has to handle here: `@stapel/core`'s client intercepts it,
|
|
14
|
+
* hands it to the app's verification controller (auth-react's factor
|
|
15
|
+
* machines) and replays the original request with
|
|
16
|
+
* `X-Verification-Token`. It is a detour, not a failure.
|
|
17
|
+
* 2. **An ENROLLMENT demand** — `verification.enroll === true` and there is
|
|
18
|
+
* NO challenge id, because the user holds no factor that could be
|
|
19
|
+
* challenged. Core deliberately does not intercept this one (there is
|
|
20
|
+
* nothing to drive), so it surfaces as a plain 403 and the app must send
|
|
21
|
+
* the user to factor enrollment first. {@link readVerificationEnrollment}
|
|
22
|
+
* is how a hook says "this is that, and these are the factors".
|
|
23
|
+
*
|
|
24
|
+
* KEEP IN SYNC with stapel-workspaces `capabilities.BUILTIN_CAPABILITY_LEVELS`
|
|
25
|
+
* — a PORT for the same reason `capabilityMatches` is one: `GET /roles`
|
|
26
|
+
* publishes each role's capabilities but not their levels, so the level map
|
|
27
|
+
* cannot be read off the wire. A deployment may raise further capabilities via
|
|
28
|
+
* `STAPEL_WORKSPACES["CAPABILITY_LEVELS"]`; those are additive, so treating an
|
|
29
|
+
* unlisted capability as `standard` can only ever under-promise (the backend
|
|
30
|
+
* still challenges, and core still drives it).
|
|
31
|
+
*/
|
|
32
|
+
import { isStapelApiError } from "@stapel/core";
|
|
33
|
+
/** The verification scope every `high` workspace capability is gated under. */
|
|
34
|
+
export const SENSITIVE_SCOPE = "sensitive";
|
|
35
|
+
/** PORT of `BUILTIN_CAPABILITY_LEVELS` — everything unlisted is `standard`. */
|
|
36
|
+
export const BUILTIN_CAPABILITY_LEVELS = {
|
|
37
|
+
"members.provision": "high",
|
|
38
|
+
"members.password.reset": "high",
|
|
39
|
+
"workspace.security.manage": "high",
|
|
40
|
+
};
|
|
41
|
+
/** The declared step-up level of one capability string. */
|
|
42
|
+
export function capabilityLevel(capability) {
|
|
43
|
+
return BUILTIN_CAPABILITY_LEVELS[capability] ?? "standard";
|
|
44
|
+
}
|
|
45
|
+
function asRecord(value) {
|
|
46
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
47
|
+
? value
|
|
48
|
+
: null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Read the enrollment demand out of a rejected request, or `null` when the
|
|
52
|
+
* error is anything else (including a step-up CHALLENGE, which carries a
|
|
53
|
+
* `challenge_id` and is core's business, not the consumer's).
|
|
54
|
+
*/
|
|
55
|
+
export function readVerificationEnrollment(error) {
|
|
56
|
+
// Both dialects, narrowed through the imported predicate (never through a
|
|
57
|
+
// shape this call site invented): the typed error carries the parsed body,
|
|
58
|
+
// a rethrown raw envelope IS the body.
|
|
59
|
+
const body = asRecord(isStapelApiError(error) ? error.body : error);
|
|
60
|
+
if (body === null)
|
|
61
|
+
return null;
|
|
62
|
+
const verification = asRecord(body["verification"]);
|
|
63
|
+
if (verification === null)
|
|
64
|
+
return null;
|
|
65
|
+
if (verification["enroll"] !== true)
|
|
66
|
+
return null;
|
|
67
|
+
if (typeof verification["challenge_id"] === "string")
|
|
68
|
+
return null;
|
|
69
|
+
const factors = verification["factors"];
|
|
70
|
+
return {
|
|
71
|
+
scope: typeof verification["scope"] === "string"
|
|
72
|
+
? verification["scope"]
|
|
73
|
+
: SENSITIVE_SCOPE,
|
|
74
|
+
factors: Array.isArray(factors)
|
|
75
|
+
? factors.filter((f) => typeof f === "string")
|
|
76
|
+
: [],
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=stepUp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stepUp.js","sourceRoot":"","sources":["../../src/model/stepUp.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC;AAK3C,+EAA+E;AAC/E,MAAM,CAAC,MAAM,yBAAyB,GAAqC;IACzE,mBAAmB,EAAE,MAAM;IAC3B,wBAAwB,EAAE,MAAM;IAChC,2BAA2B,EAAE,MAAM;CACpC,CAAC;AAEF,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,UAAkB;IAChD,OAAO,yBAAyB,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;AAC7D,CAAC;AAaD,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,IAAI,CAAC;AACX,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,0BAA0B,CACxC,KAAc;IAEd,0EAA0E;IAC1E,2EAA2E;IAC3E,uCAAuC;IACvC,MAAM,IAAI,GAAG,QAAQ,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;IACpE,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IACpD,IAAI,YAAY,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,YAAY,CAAC,QAAQ,CAAC,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjD,IAAI,OAAO,YAAY,CAAC,cAAc,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IAClE,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IACxC,OAAO;QACL,KAAK,EACH,OAAO,YAAY,CAAC,OAAO,CAAC,KAAK,QAAQ;YACvC,CAAC,CAAC,YAAY,CAAC,OAAO,CAAC;YACvB,CAAC,CAAC,eAAe;QACrB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;YAC7B,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YAC3D,CAAC,CAAC,EAAE;KACP,CAAC;AACJ,CAAC"}
|
package/llms.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# @stapel/workspaces-react 0.
|
|
1
|
+
# @stapel/workspaces-react 0.9.0
|
|
2
2
|
|
|
3
|
-
Headless React flow pair for stapel-workspaces (contract >=0.
|
|
3
|
+
Headless React flow pair for stapel-workspaces (contract >=0.18 <0.19) — business + state, zero visual opinion.
|
|
4
4
|
Built on @stapel/core: typed client + StapelApiError envelope, auth token refresh,
|
|
5
5
|
verification-403 interception, i18n engine, analytics facade, TanStack Query layer.
|
|
6
6
|
|
|
@@ -26,16 +26,21 @@ Request/response schema names are in manifest.json + the generated types.
|
|
|
26
26
|
Paths are relative to `/workspaces/api/v1/`.
|
|
27
27
|
- workspaces_api_v1_create: POST /
|
|
28
28
|
- workspaces_api_v1_destroy: DELETE /{workspace_id}
|
|
29
|
+
- workspaces_api_v1_instance_retrieve: GET /instance
|
|
29
30
|
- workspaces_api_v1_internal_members_retrieve: GET /internal/{workspace_id}/members/{user_id}
|
|
30
31
|
- workspaces_api_v1_internal_users_personal_create: POST /internal/users/{user_id}/personal
|
|
31
32
|
- workspaces_api_v1_invitations_accept_create: POST /invitations/accept
|
|
32
33
|
- workspaces_api_v1_invitations_claim_create: POST /invitations/{token}/claim
|
|
33
34
|
- workspaces_api_v1_invitations_decline_create: POST /invitations/{token}/decline
|
|
35
|
+
- workspaces_api_v1_invitations_list: GET /{workspace_id}/invitations
|
|
36
|
+
- workspaces_api_v1_invitations_resend_create: POST /{workspace_id}/invitations/{invitation_id}/resend
|
|
34
37
|
- workspaces_api_v1_invitations_retrieve: GET /invitations/{token}
|
|
38
|
+
- workspaces_api_v1_invitations_revoke_create: POST /{workspace_id}/invitations/{invitation_id}/revoke
|
|
35
39
|
- workspaces_api_v1_members_destroy: DELETE /{workspace_id}/members/{user_id}
|
|
36
40
|
- workspaces_api_v1_members_invite_create: POST /{workspace_id}/members/invite
|
|
37
41
|
- workspaces_api_v1_members_list: GET /{workspace_id}/members
|
|
38
42
|
- workspaces_api_v1_members_partial_update: PATCH /{workspace_id}/members/{user_id}
|
|
43
|
+
- workspaces_api_v1_members_password_reset_create: POST /{workspace_id}/members/{user_id}/password/reset
|
|
39
44
|
- workspaces_api_v1_members_provision_create: POST /{workspace_id}/members/provision
|
|
40
45
|
- workspaces_api_v1_partial_update: PATCH /{workspace_id}
|
|
41
46
|
- workspaces_api_v1_retrieve: GET /
|
|
@@ -48,18 +53,24 @@ Paths are relative to `/workspaces/api/v1/`.
|
|
|
48
53
|
- useCreateWorkspace (mutation) → createWorkspace
|
|
49
54
|
- useDeclineInvitation (mutation) → declineInvitation
|
|
50
55
|
- useDeleteWorkspace (mutation) → deleteWorkspace
|
|
56
|
+
- useInstanceShape (query) → getInstanceShape
|
|
51
57
|
- useInvitationPreview (query) → getInvitationPreview
|
|
58
|
+
- useInvitations (query) → listInvitations
|
|
52
59
|
- useInviteMembers (mutation) → inviteMembers
|
|
53
60
|
- useMembers (query) → listMembers
|
|
54
61
|
- useRemoveMember (mutation) → removeMember
|
|
62
|
+
- useResendInvitation (mutation) → resendInvitation
|
|
63
|
+
- useResetMemberPassword (mutation) → resetMemberPassword
|
|
64
|
+
- useRevokeInvitation (mutation) → revokeInvitation
|
|
55
65
|
- useRoles (query) → listRoles
|
|
56
66
|
- useUpdateMemberRole (mutation) → updateMemberRole
|
|
67
|
+
- useUpdateSecuritySettings (mutation) → getWorkspace+updateWorkspace
|
|
57
68
|
- useUpdateWorkspace (mutation) → updateWorkspace
|
|
58
69
|
- useWorkspace (query) → getWorkspace
|
|
59
70
|
- useWorkspaces (query) → listWorkspaces
|
|
60
71
|
|
|
61
72
|
## Errors (render t(code, params); UX from remediation)
|
|
62
|
-
|
|
73
|
+
61 keys (full catalog: manifest.json §errors). By remediation: fix_input 29 · retry 12 · contact_support 7 · wait_and_retry 6 · verify 5 · reauthenticate 2.
|
|
63
74
|
Param-bearing keys (interpolation slots matter):
|
|
64
75
|
- error.400.field.blank [400] → fix_input {field}
|
|
65
76
|
- error.400.field.does_not_exist [400] → fix_input {field}
|
|
@@ -75,6 +86,7 @@ Param-bearing keys (interpolation slots matter):
|
|
|
75
86
|
- error.402.member_limit_reached [402] → fix_input {limit}
|
|
76
87
|
- error.403.membership_suspended [403] → fix_input {reason}
|
|
77
88
|
- error.403.missing_capability [403] → contact_support {capability}
|
|
89
|
+
- error.403.role_exceeds_inviter_rank [403] → fix_input {role}
|
|
78
90
|
- error.429.rate_limit [429] → wait_and_retry {retry_after_minutes}
|
|
79
91
|
|
|
80
92
|
## Analytics events (typed; defineEvent → events.json, drift-gated)
|
package/manifest.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$generated": "by scripts/gen-manifest.mjs — do not edit; drift-gated (pnpm gen:manifest:check)",
|
|
3
3
|
"package": "@stapel/workspaces-react",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.9.0",
|
|
5
5
|
"backend": {
|
|
6
6
|
"module": "stapel-workspaces",
|
|
7
|
-
"contract": ">=0.
|
|
7
|
+
"contract": ">=0.18 <0.19"
|
|
8
8
|
},
|
|
9
9
|
"layers": [
|
|
10
10
|
"api",
|
|
@@ -32,6 +32,13 @@
|
|
|
32
32
|
"request": null,
|
|
33
33
|
"response": null
|
|
34
34
|
},
|
|
35
|
+
"workspaces_api_v1_instance_retrieve": {
|
|
36
|
+
"method": "GET",
|
|
37
|
+
"path": "/workspaces/api/v1/instance",
|
|
38
|
+
"tag": "Workspaces",
|
|
39
|
+
"request": null,
|
|
40
|
+
"response": "InstanceShapeResponse"
|
|
41
|
+
},
|
|
35
42
|
"workspaces_api_v1_internal_members_retrieve": {
|
|
36
43
|
"method": "GET",
|
|
37
44
|
"path": "/workspaces/api/v1/internal/{workspace_id}/members/{user_id}",
|
|
@@ -67,6 +74,20 @@
|
|
|
67
74
|
"request": null,
|
|
68
75
|
"response": null
|
|
69
76
|
},
|
|
77
|
+
"workspaces_api_v1_invitations_list": {
|
|
78
|
+
"method": "GET",
|
|
79
|
+
"path": "/workspaces/api/v1/{workspace_id}/invitations",
|
|
80
|
+
"tag": "Members",
|
|
81
|
+
"request": null,
|
|
82
|
+
"response": "PaginatedInvitationResponseList"
|
|
83
|
+
},
|
|
84
|
+
"workspaces_api_v1_invitations_resend_create": {
|
|
85
|
+
"method": "POST",
|
|
86
|
+
"path": "/workspaces/api/v1/{workspace_id}/invitations/{invitation_id}/resend",
|
|
87
|
+
"tag": "Members",
|
|
88
|
+
"request": null,
|
|
89
|
+
"response": "InvitationResponse"
|
|
90
|
+
},
|
|
70
91
|
"workspaces_api_v1_invitations_retrieve": {
|
|
71
92
|
"method": "GET",
|
|
72
93
|
"path": "/workspaces/api/v1/invitations/{token}",
|
|
@@ -74,6 +95,13 @@
|
|
|
74
95
|
"request": null,
|
|
75
96
|
"response": "InvitationPreviewResponse"
|
|
76
97
|
},
|
|
98
|
+
"workspaces_api_v1_invitations_revoke_create": {
|
|
99
|
+
"method": "POST",
|
|
100
|
+
"path": "/workspaces/api/v1/{workspace_id}/invitations/{invitation_id}/revoke",
|
|
101
|
+
"tag": "Members",
|
|
102
|
+
"request": null,
|
|
103
|
+
"response": "InvitationResponse"
|
|
104
|
+
},
|
|
77
105
|
"workspaces_api_v1_members_destroy": {
|
|
78
106
|
"method": "DELETE",
|
|
79
107
|
"path": "/workspaces/api/v1/{workspace_id}/members/{user_id}",
|
|
@@ -102,6 +130,13 @@
|
|
|
102
130
|
"request": "PatchedMemberUpdateRequest",
|
|
103
131
|
"response": "MemberResponse"
|
|
104
132
|
},
|
|
133
|
+
"workspaces_api_v1_members_password_reset_create": {
|
|
134
|
+
"method": "POST",
|
|
135
|
+
"path": "/workspaces/api/v1/{workspace_id}/members/{user_id}/password/reset",
|
|
136
|
+
"tag": "Members",
|
|
137
|
+
"request": "MemberPasswordResetRequest",
|
|
138
|
+
"response": "MemberPasswordResetResponse"
|
|
139
|
+
},
|
|
105
140
|
"workspaces_api_v1_members_provision_create": {
|
|
106
141
|
"method": "POST",
|
|
107
142
|
"path": "/workspaces/api/v1/{workspace_id}/members/provision",
|
|
@@ -194,6 +229,14 @@
|
|
|
194
229
|
]
|
|
195
230
|
]
|
|
196
231
|
},
|
|
232
|
+
"useInstanceShape": {
|
|
233
|
+
"kind": "query",
|
|
234
|
+
"operation": "getInstanceShape",
|
|
235
|
+
"queryKey": [
|
|
236
|
+
"workspaces",
|
|
237
|
+
"instance"
|
|
238
|
+
]
|
|
239
|
+
},
|
|
197
240
|
"useInvitationPreview": {
|
|
198
241
|
"kind": "query",
|
|
199
242
|
"operation": "getInvitationPreview",
|
|
@@ -203,6 +246,16 @@
|
|
|
203
246
|
"{token}"
|
|
204
247
|
]
|
|
205
248
|
},
|
|
249
|
+
"useInvitations": {
|
|
250
|
+
"kind": "query",
|
|
251
|
+
"operation": "listInvitations",
|
|
252
|
+
"queryKey": [
|
|
253
|
+
"workspaces",
|
|
254
|
+
"invitations",
|
|
255
|
+
"{workspaceId}",
|
|
256
|
+
"{params}"
|
|
257
|
+
]
|
|
258
|
+
},
|
|
206
259
|
"useInviteMembers": {
|
|
207
260
|
"kind": "mutation",
|
|
208
261
|
"operation": "inviteMembers",
|
|
@@ -235,6 +288,44 @@
|
|
|
235
288
|
]
|
|
236
289
|
]
|
|
237
290
|
},
|
|
291
|
+
"useResendInvitation": {
|
|
292
|
+
"kind": "mutation",
|
|
293
|
+
"operation": "resendInvitation",
|
|
294
|
+
"invalidates": [
|
|
295
|
+
[
|
|
296
|
+
"workspaces",
|
|
297
|
+
"invitations",
|
|
298
|
+
"{workspaceId}"
|
|
299
|
+
]
|
|
300
|
+
]
|
|
301
|
+
},
|
|
302
|
+
"useResetMemberPassword": {
|
|
303
|
+
"kind": "mutation",
|
|
304
|
+
"operation": "resetMemberPassword",
|
|
305
|
+
"invalidates": [
|
|
306
|
+
[
|
|
307
|
+
"workspaces",
|
|
308
|
+
"members",
|
|
309
|
+
"{workspaceId}"
|
|
310
|
+
]
|
|
311
|
+
]
|
|
312
|
+
},
|
|
313
|
+
"useRevokeInvitation": {
|
|
314
|
+
"kind": "mutation",
|
|
315
|
+
"operation": "revokeInvitation",
|
|
316
|
+
"invalidates": [
|
|
317
|
+
[
|
|
318
|
+
"workspaces",
|
|
319
|
+
"invitations",
|
|
320
|
+
"{workspaceId}"
|
|
321
|
+
],
|
|
322
|
+
[
|
|
323
|
+
"workspaces",
|
|
324
|
+
"members",
|
|
325
|
+
"{workspaceId}"
|
|
326
|
+
]
|
|
327
|
+
]
|
|
328
|
+
},
|
|
238
329
|
"useRoles": {
|
|
239
330
|
"kind": "query",
|
|
240
331
|
"operation": "listRoles",
|
|
@@ -254,6 +345,29 @@
|
|
|
254
345
|
]
|
|
255
346
|
]
|
|
256
347
|
},
|
|
348
|
+
"useUpdateSecuritySettings": {
|
|
349
|
+
"kind": "mutation",
|
|
350
|
+
"operations": [
|
|
351
|
+
"getWorkspace",
|
|
352
|
+
"updateWorkspace"
|
|
353
|
+
],
|
|
354
|
+
"invalidates": [
|
|
355
|
+
[
|
|
356
|
+
"workspaces",
|
|
357
|
+
"detail",
|
|
358
|
+
"{workspaceId}"
|
|
359
|
+
],
|
|
360
|
+
[
|
|
361
|
+
"workspaces",
|
|
362
|
+
"list"
|
|
363
|
+
],
|
|
364
|
+
[
|
|
365
|
+
"workspaces",
|
|
366
|
+
"members",
|
|
367
|
+
"{workspaceId}"
|
|
368
|
+
]
|
|
369
|
+
]
|
|
370
|
+
},
|
|
257
371
|
"useUpdateWorkspace": {
|
|
258
372
|
"kind": "mutation",
|
|
259
373
|
"operation": "updateWorkspace",
|
|
@@ -505,6 +619,13 @@
|
|
|
505
619
|
"params": [],
|
|
506
620
|
"remediation": "contact_support"
|
|
507
621
|
},
|
|
622
|
+
"error.403.role_exceeds_inviter_rank": {
|
|
623
|
+
"status": 403,
|
|
624
|
+
"params": [
|
|
625
|
+
"role"
|
|
626
|
+
],
|
|
627
|
+
"remediation": "fix_input"
|
|
628
|
+
},
|
|
508
629
|
"error.403.verification_enrollment_required": {
|
|
509
630
|
"status": 403,
|
|
510
631
|
"params": [],
|
|
@@ -764,6 +885,7 @@
|
|
|
764
885
|
"error.403.membership_suspended",
|
|
765
886
|
"error.403.missing_capability",
|
|
766
887
|
"error.403.network_blocked",
|
|
888
|
+
"error.403.role_exceeds_inviter_rank",
|
|
767
889
|
"error.403.verification_enrollment_required",
|
|
768
890
|
"error.403.verification_required",
|
|
769
891
|
"error.404.ad_not_found",
|
|
@@ -853,10 +975,12 @@
|
|
|
853
975
|
"exports": {
|
|
854
976
|
"runtime": [
|
|
855
977
|
"AcceptInvitation",
|
|
978
|
+
"BUILTIN_CAPABILITY_LEVELS",
|
|
856
979
|
"Can",
|
|
857
980
|
"InviteAcceptFlow",
|
|
858
981
|
"Members",
|
|
859
982
|
"RoleSelect",
|
|
983
|
+
"SENSITIVE_SCOPE",
|
|
860
984
|
"WORKSPACES_ERRORS",
|
|
861
985
|
"WORKSPACES_ERROR_CODES",
|
|
862
986
|
"WORKSPACES_FLOWS",
|
|
@@ -864,6 +988,7 @@
|
|
|
864
988
|
"WorkspaceList",
|
|
865
989
|
"WorkspacesProvider",
|
|
866
990
|
"WorkspacesRuntimeContext",
|
|
991
|
+
"capabilityLevel",
|
|
867
992
|
"capabilityMatches",
|
|
868
993
|
"createFlowMachine",
|
|
869
994
|
"createInviteAcceptFlow",
|
|
@@ -875,21 +1000,30 @@
|
|
|
875
1000
|
"hasCapability",
|
|
876
1001
|
"isErrorCode",
|
|
877
1002
|
"maskEmail",
|
|
1003
|
+
"readVerificationEnrollment",
|
|
878
1004
|
"registerWorkspacesI18n",
|
|
879
1005
|
"toFlowError",
|
|
880
1006
|
"useAcceptInvitation",
|
|
881
1007
|
"useCapabilities",
|
|
1008
|
+
"useCapabilityGate",
|
|
882
1009
|
"useClaimInvitation",
|
|
883
1010
|
"useCreateWorkspace",
|
|
884
1011
|
"useDeclineInvitation",
|
|
885
1012
|
"useDeleteWorkspace",
|
|
886
1013
|
"useFlow",
|
|
1014
|
+
"useInfiniteInvitations",
|
|
1015
|
+
"useInstanceShape",
|
|
887
1016
|
"useInvitationPreview",
|
|
1017
|
+
"useInvitations",
|
|
888
1018
|
"useInviteMembers",
|
|
889
1019
|
"useMembers",
|
|
890
1020
|
"useRemoveMember",
|
|
1021
|
+
"useResendInvitation",
|
|
1022
|
+
"useResetMemberPassword",
|
|
1023
|
+
"useRevokeInvitation",
|
|
891
1024
|
"useRoles",
|
|
892
1025
|
"useUpdateMemberRole",
|
|
1026
|
+
"useUpdateSecuritySettings",
|
|
893
1027
|
"useUpdateWorkspace",
|
|
894
1028
|
"useWorkspace",
|
|
895
1029
|
"useWorkspaces",
|
|
@@ -904,6 +1038,8 @@
|
|
|
904
1038
|
"AcceptInvitationBag",
|
|
905
1039
|
"CanBag",
|
|
906
1040
|
"CapabilitiesResult",
|
|
1041
|
+
"CapabilityGate",
|
|
1042
|
+
"CapabilityLevel",
|
|
907
1043
|
"CreateWorkspacesRuntimeOptions",
|
|
908
1044
|
"FlowEndpoint",
|
|
909
1045
|
"FlowError",
|
|
@@ -913,7 +1049,10 @@
|
|
|
913
1049
|
"Invitation",
|
|
914
1050
|
"InvitationAccept",
|
|
915
1051
|
"InvitationClaim",
|
|
1052
|
+
"InvitationListData",
|
|
916
1053
|
"InvitationPreview",
|
|
1054
|
+
"InvitationStatusFilter",
|
|
1055
|
+
"InvitationsParams",
|
|
917
1056
|
"InviteAcceptFlowBag",
|
|
918
1057
|
"InviteAcceptFlowController",
|
|
919
1058
|
"InviteAcceptFlowDeps",
|
|
@@ -922,21 +1061,27 @@
|
|
|
922
1061
|
"MemberInvite",
|
|
923
1062
|
"MemberInviteResult",
|
|
924
1063
|
"MemberListData",
|
|
1064
|
+
"MemberPasswordReset",
|
|
1065
|
+
"MemberPasswordResetResult",
|
|
1066
|
+
"MemberPasswordResetVars",
|
|
925
1067
|
"MemberRoleChange",
|
|
926
1068
|
"MemberRoleUpdate",
|
|
927
1069
|
"MembersBag",
|
|
928
1070
|
"MembersParams",
|
|
1071
|
+
"ProvisionedUserPolicy",
|
|
929
1072
|
"Remediation",
|
|
930
1073
|
"RoleInfo",
|
|
931
1074
|
"RoleList",
|
|
932
1075
|
"RoleSelectBag",
|
|
933
1076
|
"Schemas",
|
|
1077
|
+
"VerificationEnrollment",
|
|
934
1078
|
"WorkspaceCreate",
|
|
935
1079
|
"WorkspaceData",
|
|
936
1080
|
"WorkspaceKind",
|
|
937
1081
|
"WorkspaceListBag",
|
|
938
1082
|
"WorkspaceListData",
|
|
939
1083
|
"WorkspaceRole",
|
|
1084
|
+
"WorkspaceSecuritySettings",
|
|
940
1085
|
"WorkspaceUpdate",
|
|
941
1086
|
"WorkspacesApi",
|
|
942
1087
|
"WorkspacesErrorCode",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stapel/workspaces-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "Headless React flow pair for stapel-workspaces: typed API client, TanStack Query hooks, flow machines, headless components, and i18n keys. Zero visual opinion.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -82,9 +82,9 @@
|
|
|
82
82
|
"size-limit": "^11.2.0",
|
|
83
83
|
"typescript": "^5.8.3",
|
|
84
84
|
"vitest": "^3.2.4",
|
|
85
|
-
"@stapel/core": "^0.
|
|
86
|
-
"@stapel/
|
|
87
|
-
"@stapel/
|
|
85
|
+
"@stapel/core": "^0.10.0",
|
|
86
|
+
"@stapel/showcase": "^0.2.0",
|
|
87
|
+
"@stapel/tokens": "^0.5.0"
|
|
88
88
|
},
|
|
89
89
|
"engines": {
|
|
90
90
|
"node": ">=22"
|