@company-semantics/contracts 39.6.0 → 39.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.
- package/package.json +1 -1
- package/src/api/generated-spec-hash.ts +2 -2
- package/src/api/generated.ts +2 -0
- package/src/index.ts +2 -0
- package/src/notifications/__tests__/__snapshots__/registry.test.ts.snap +1 -0
- package/src/notifications/__tests__/fixtures.ts +7 -0
- package/src/notifications/kinds/company-md-access-requested.ts +32 -2
- package/src/notifications/payloads.ts +6 -0
- package/src/permissions/access-request.ts +15 -0
package/package.json
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
// AUTO-GENERATED — do not edit. Run pnpm generate:spec-hash to regenerate.
|
|
2
|
-
export const SPEC_HASH = '
|
|
3
|
-
export const SPEC_HASH_FULL = '
|
|
2
|
+
export const SPEC_HASH = 'e8cf36a33d43' as const;
|
|
3
|
+
export const SPEC_HASH_FULL = 'e8cf36a33d43bec5e4383c8edbfbdccd37fe8d081a5ddd02e96c83cb5e7bd21a' as const;
|
package/src/api/generated.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -452,6 +452,8 @@ export {
|
|
|
452
452
|
COMPANY_MD_COLLAB_MAX_UPDATE_B64_CHARS,
|
|
453
453
|
COMPANY_MD_COLLAB_MAX_DOC_TEXT_BYTES,
|
|
454
454
|
COMPANY_MD_COLLAB_MAX_PRESENCE_POSITION_CHARS,
|
|
455
|
+
COMPANY_MD_COLLAB_PRESENCE_TTL_MS,
|
|
456
|
+
COMPANY_MD_COLLAB_PRESENCE_HEARTBEAT_MS,
|
|
455
457
|
CompanyMdCollabSyncLimitsSchema,
|
|
456
458
|
CompanyMdCollabSyncResponseSchema,
|
|
457
459
|
CompanyMdCollabUpdateAcceptedSchema,
|
|
@@ -15,6 +15,7 @@ exports[`NOTIFICATION_DEFINITIONS > titles every kind 1`] = `
|
|
|
15
15
|
"companyMd.access_request_denied · No reason": "Your access request was reviewed",
|
|
16
16
|
"companyMd.access_request_denied · With reason": "Your access request was reviewed",
|
|
17
17
|
"companyMd.access_requested · No message": "Someone requested access to a document",
|
|
18
|
+
"companyMd.access_requested · Requested editor": "Someone requested access to a document",
|
|
18
19
|
"companyMd.access_requested · With message": "Someone requested access to a document",
|
|
19
20
|
"org.invite · Admin": "You've been invited to join Acme Corp on Company Semantics",
|
|
20
21
|
"org.invite · Member": "You've been invited to join Acme Corp on Company Semantics",
|
|
@@ -198,6 +198,13 @@ add("companyMd.access_requested", "No message", {
|
|
|
198
198
|
docTitle: "Engineering Handbook",
|
|
199
199
|
reviewUrl: `${APP}/doc/handbook?request=req_456`,
|
|
200
200
|
});
|
|
201
|
+
add("companyMd.access_requested", "Requested editor", {
|
|
202
|
+
requesterName: "Sam Chen",
|
|
203
|
+
docTitle: "Engineering Handbook",
|
|
204
|
+
message: "I maintain this section day to day — may I edit it directly?",
|
|
205
|
+
requestedAccessLevel: "editor",
|
|
206
|
+
reviewUrl: `${APP}/doc/handbook?request=req_789`,
|
|
207
|
+
});
|
|
201
208
|
|
|
202
209
|
add("companyMd.access_request_approved", "Editor", {
|
|
203
210
|
approverName: "Jordan Lee",
|
|
@@ -8,11 +8,28 @@
|
|
|
8
8
|
|
|
9
9
|
import type { NotificationDefinition } from "../definition";
|
|
10
10
|
|
|
11
|
+
/**
|
|
12
|
+
* How each requestable band reads in prose ("requested edit access") and in the
|
|
13
|
+
* key-value table ("Editor"). Absent band ⇒ band-neutral copy, so senders that
|
|
14
|
+
* predate `requestedAccessLevel` (ADR-CONTRACTS-098) render exactly as before.
|
|
15
|
+
*/
|
|
16
|
+
const LEVEL_PHRASE = {
|
|
17
|
+
viewer: "view",
|
|
18
|
+
commenter: "comment",
|
|
19
|
+
editor: "edit",
|
|
20
|
+
} as const;
|
|
21
|
+
const LEVEL_LABEL = {
|
|
22
|
+
viewer: "Viewer",
|
|
23
|
+
commenter: "Commenter",
|
|
24
|
+
editor: "Editor",
|
|
25
|
+
} as const;
|
|
26
|
+
|
|
11
27
|
export const accessRequestedDefinition: NotificationDefinition<"companyMd.access_requested"> =
|
|
12
28
|
{
|
|
13
29
|
kind: "companyMd.access_requested",
|
|
14
30
|
compose: (payload, context) => {
|
|
15
|
-
const { requesterName, docTitle, message, reviewUrl } =
|
|
31
|
+
const { requesterName, docTitle, message, requestedAccessLevel, reviewUrl } =
|
|
32
|
+
payload;
|
|
16
33
|
|
|
17
34
|
return {
|
|
18
35
|
metadata: {
|
|
@@ -23,7 +40,12 @@ export const accessRequestedDefinition: NotificationDefinition<"companyMd.access
|
|
|
23
40
|
{
|
|
24
41
|
elements: [
|
|
25
42
|
{ type: "greeting" },
|
|
26
|
-
{
|
|
43
|
+
{
|
|
44
|
+
type: "body",
|
|
45
|
+
text: requestedAccessLevel
|
|
46
|
+
? `Someone requested ${LEVEL_PHRASE[requestedAccessLevel]} access to a document.`
|
|
47
|
+
: "Someone requested document access.",
|
|
48
|
+
},
|
|
27
49
|
{
|
|
28
50
|
type: "chatUnit",
|
|
29
51
|
items: [
|
|
@@ -47,6 +69,14 @@ export const accessRequestedDefinition: NotificationDefinition<"companyMd.access
|
|
|
47
69
|
rows: [
|
|
48
70
|
{ label: "From", value: requesterName },
|
|
49
71
|
{ label: "Document", value: `"${docTitle}"` },
|
|
72
|
+
...(requestedAccessLevel
|
|
73
|
+
? [
|
|
74
|
+
{
|
|
75
|
+
label: "Requested",
|
|
76
|
+
value: LEVEL_LABEL[requestedAccessLevel],
|
|
77
|
+
},
|
|
78
|
+
]
|
|
79
|
+
: []),
|
|
50
80
|
],
|
|
51
81
|
},
|
|
52
82
|
{
|
|
@@ -132,6 +132,12 @@ export interface NotificationPayloads {
|
|
|
132
132
|
docTitle: string;
|
|
133
133
|
/** Optional message from the requester (notification only) */
|
|
134
134
|
message?: string;
|
|
135
|
+
/**
|
|
136
|
+
* The band the requester asked for (ADR-CONTRACTS-098): names the intent
|
|
137
|
+
* in the owner's email ("requested edit access"). Absent = unspecified
|
|
138
|
+
* (older senders / clients) — the copy stays band-neutral.
|
|
139
|
+
*/
|
|
140
|
+
requestedAccessLevel?: "viewer" | "commenter" | "editor";
|
|
135
141
|
/** Deep-link that opens the doc's ShareDialog scrolled to the pending request */
|
|
136
142
|
reviewUrl: string;
|
|
137
143
|
};
|
|
@@ -28,6 +28,15 @@ export type AccessRequestStatus = z.infer<typeof AccessRequestStatusSchema>;
|
|
|
28
28
|
export const AccessRequestCreateSchema = z.object({
|
|
29
29
|
/** Optional context the requester sends to the owner(s). */
|
|
30
30
|
message: z.string().max(2000).optional(),
|
|
31
|
+
/**
|
|
32
|
+
* The band the requester is asking for (ADR-CONTRACTS-098 / ADR-BE-454):
|
|
33
|
+
* `viewer` from the locked preview, `editor` from the view-only Editor tab
|
|
34
|
+
* (elevation, ADR-BE-453). A REQUEST, not a claim — the owner still chooses
|
|
35
|
+
* the granted band on approval; this only seeds their picker. Optional so
|
|
36
|
+
* older clients keep working (absent ⇒ unspecified, owners default to
|
|
37
|
+
* viewer).
|
|
38
|
+
*/
|
|
39
|
+
requestedAccessLevel: GrantableAccessLevelSchema.optional(),
|
|
31
40
|
});
|
|
32
41
|
export type AccessRequestCreate = z.infer<typeof AccessRequestCreateSchema>;
|
|
33
42
|
|
|
@@ -45,6 +54,12 @@ export const AccessRequestSchema = z.object({
|
|
|
45
54
|
docId: z.string(),
|
|
46
55
|
status: AccessRequestStatusSchema,
|
|
47
56
|
message: z.string().nullable(),
|
|
57
|
+
/**
|
|
58
|
+
* The band the requester asked for (ADR-CONTRACTS-098) — seeds the owner
|
|
59
|
+
* inbox's approval picker. Null for requests filed before the field existed
|
|
60
|
+
* or by clients that did not specify one.
|
|
61
|
+
*/
|
|
62
|
+
requestedAccessLevel: GrantableAccessLevelSchema.nullable(),
|
|
48
63
|
createdAt: z.string(),
|
|
49
64
|
resolvedAt: z.string().nullable(),
|
|
50
65
|
});
|