@knkcs/contenthub-ui 0.0.0-stage → 0.1.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 +30 -0
- package/LICENSE +30 -0
- package/README.md +25 -2
- package/dist/branch-content-fields-WBpviLQg.js +86 -0
- package/dist/branch-content-fields-WBpviLQg.js.map +1 -0
- package/dist/branch-form-kit-BIZbBl1B.js +11 -0
- package/dist/branch-form-kit-BIZbBl1B.js.map +1 -0
- package/dist/content-data-fields-CGJTea3s.js +19 -0
- package/dist/content-data-fields-CGJTea3s.js.map +1 -0
- package/dist/content-library-B2eauvHt.js +2494 -0
- package/dist/content-library-B2eauvHt.js.map +1 -0
- package/dist/heads-Brd2Gtjm.js +124 -0
- package/dist/heads-Brd2Gtjm.js.map +1 -0
- package/dist/index.d.ts +5729 -0
- package/dist/index.js +7180 -0
- package/dist/index.js.map +1 -0
- package/dist/testing.d.ts +1555 -0
- package/dist/testing.js +1801 -0
- package/dist/testing.js.map +1 -0
- package/package.json +100 -4
|
@@ -0,0 +1,1555 @@
|
|
|
1
|
+
import { HostIdentity } from '@knkcs/anker/host';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One of a workspace's own reasons a Content may be blocked, such as "being
|
|
5
|
+
* revised by the author" (CONTEXT.md, Block Reason). Configuration, not
|
|
6
|
+
* versioned.
|
|
7
|
+
*/
|
|
8
|
+
declare interface BlockReason {
|
|
9
|
+
id: string;
|
|
10
|
+
name: string;
|
|
11
|
+
/** ISO 8601. */
|
|
12
|
+
createTime: string;
|
|
13
|
+
/** ISO 8601. */
|
|
14
|
+
updateTime: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** A content Blueprint, as the `BlueprintSource` port names it. */
|
|
18
|
+
declare interface BlueprintInfo {
|
|
19
|
+
id: string;
|
|
20
|
+
/** What editors call it. */
|
|
21
|
+
name: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** One page of `BlueprintSource.searchBlueprints`. */
|
|
25
|
+
declare interface BlueprintPage {
|
|
26
|
+
blueprints: BlueprintInfo[];
|
|
27
|
+
/** Empty on the last page. */
|
|
28
|
+
nextPageToken: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** A Release of a content Blueprint: what a new Content pins. */
|
|
32
|
+
declare interface BlueprintReleaseInfo {
|
|
33
|
+
id: string;
|
|
34
|
+
blueprintId: string;
|
|
35
|
+
/** The name given when it was cut, such as "2026-10". */
|
|
36
|
+
name: string;
|
|
37
|
+
/** ISO 8601: when it was cut. */
|
|
38
|
+
releaseTime: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The port a host fills with blueprinthub (ADR 0020): the workspace's
|
|
43
|
+
* content Blueprints and their Releases, for New Content and the Library's
|
|
44
|
+
* Blueprint filter. contenthub-ui depends on no blueprinthub package. A host
|
|
45
|
+
* without blueprinthub leaves the port empty: the Library then names
|
|
46
|
+
* Blueprints by id, offers no Blueprint filter and cannot create Content.
|
|
47
|
+
*/
|
|
48
|
+
declare interface BlueprintSource {
|
|
49
|
+
/**
|
|
50
|
+
* Unarchived content Blueprints whose name holds `query` (every one for
|
|
51
|
+
* ""), by name. `signal` aborts a search the user has moved on from.
|
|
52
|
+
*/
|
|
53
|
+
searchBlueprints(input: {
|
|
54
|
+
query: string;
|
|
55
|
+
pageToken?: string;
|
|
56
|
+
signal?: AbortSignal;
|
|
57
|
+
}): Promise<BlueprintPage>;
|
|
58
|
+
/** The Blueprints of these ids, archived ones too; an unknown id is left out. */
|
|
59
|
+
getBlueprints(ids: string[]): Promise<BlueprintInfo[]>;
|
|
60
|
+
/** Every Release of a Blueprint, newest first; empty while none has been cut. */
|
|
61
|
+
listReleases(blueprintId: string): Promise<BlueprintReleaseInfo[]>;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** What a Branch is for: one an editor works on, or a Carry-forward link. */
|
|
65
|
+
declare type BranchKind = "editorial" | "carry_forward";
|
|
66
|
+
|
|
67
|
+
/** What a Chain on Dated Content, effective on a date, would be and meet (PreviewChain). */
|
|
68
|
+
declare interface ChainPreview {
|
|
69
|
+
/** The Release it would fork from; "" in a gap. */
|
|
70
|
+
forkReleaseId: string;
|
|
71
|
+
/** The later Releases it would carry forward through. */
|
|
72
|
+
carryForwardReleaseIds: string[];
|
|
73
|
+
/** Whether a final link would merge Main's head. */
|
|
74
|
+
mergesMain: boolean;
|
|
75
|
+
/** The Releases the period cuts into. */
|
|
76
|
+
cutIntoReleaseIds: string[];
|
|
77
|
+
/** The Releases the period covers entirely: planning it as it is would be refused. */
|
|
78
|
+
coveredReleaseIds: string[];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** A Change Set as editors see it (CONTEXT.md, Change Set). */
|
|
82
|
+
declare interface ChangeSet {
|
|
83
|
+
id: string;
|
|
84
|
+
name: string;
|
|
85
|
+
/** Absent when it records none, as a one-off correction does. */
|
|
86
|
+
source?: ChangeSetSource;
|
|
87
|
+
state: ChangeSetState;
|
|
88
|
+
/** Who opened it: an odon user id. */
|
|
89
|
+
createdBy: string;
|
|
90
|
+
/** ISO 8601. */
|
|
91
|
+
createTime: string;
|
|
92
|
+
/** ISO 8601; absent while it is open. */
|
|
93
|
+
closeTime?: string;
|
|
94
|
+
/** In the order they were started. Empty in a list. */
|
|
95
|
+
chains: ChangeSetChain[];
|
|
96
|
+
/** The Change Sets it depends on, whatever their state. Empty in a list. */
|
|
97
|
+
dependsOnChangeSetIds: string[];
|
|
98
|
+
/**
|
|
99
|
+
* The slug of its status in statushub's `contenthub/change_set`
|
|
100
|
+
* catalogue; "" for an unknown status, which it has until someone first
|
|
101
|
+
* sets one. Frozen once it is closed.
|
|
102
|
+
*/
|
|
103
|
+
status: string;
|
|
104
|
+
/** Who is working on it now: odon user ids, in the order they were set. */
|
|
105
|
+
assigneeIds: string[];
|
|
106
|
+
/**
|
|
107
|
+
* Its Planned Releases, proposed ones included, in the order they were
|
|
108
|
+
* planned. Empty in a list.
|
|
109
|
+
*/
|
|
110
|
+
plannedReleases: PlannedRelease[];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** One Branch of a Chain, with the head a save on it names. */
|
|
114
|
+
declare interface ChangeSetBranch {
|
|
115
|
+
id: string;
|
|
116
|
+
/** Its place in its Chain, from 0. */
|
|
117
|
+
position: number;
|
|
118
|
+
kind: BranchKind;
|
|
119
|
+
headRevisionId: string;
|
|
120
|
+
/**
|
|
121
|
+
* On a Chain on Dated Content, the date its change takes effect
|
|
122
|
+
* (YYYY-MM-DD): an editorial Branch's own, or the first day of the
|
|
123
|
+
* Release a Carry-forward link carries. Absent or "" otherwise.
|
|
124
|
+
*/
|
|
125
|
+
effectiveOn?: string;
|
|
126
|
+
/**
|
|
127
|
+
* The Release it carries: the first Branch's fork Release, or the later
|
|
128
|
+
* Release a Carry-forward link carries. Absent or "" where it carries
|
|
129
|
+
* Main's head or nothing.
|
|
130
|
+
*/
|
|
131
|
+
carriedReleaseId?: string;
|
|
132
|
+
/** Whether a Pending Merge is stored on it, which `getPendingMerge` reads. */
|
|
133
|
+
hasPendingMerge?: boolean;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** The ordered Branches of one Content inside a Change Set. */
|
|
137
|
+
declare interface ChangeSetChain {
|
|
138
|
+
id: string;
|
|
139
|
+
contentId: string;
|
|
140
|
+
/** Born in this Change Set: it has no Main Branch until it is published. */
|
|
141
|
+
born: boolean;
|
|
142
|
+
/** By position. */
|
|
143
|
+
branches: ChangeSetBranch[];
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/** One page of `listChangeSets`. */
|
|
147
|
+
declare interface ChangeSetList {
|
|
148
|
+
changeSets: ChangeSet[];
|
|
149
|
+
/** Empty on the last page. */
|
|
150
|
+
nextPageToken: string;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* The publication that triggered a Change Set (CONTEXT.md, Source), such as
|
|
155
|
+
* 2026-09-20, "BGBl. 2026 I Nr. 270".
|
|
156
|
+
*/
|
|
157
|
+
declare interface ChangeSetSource {
|
|
158
|
+
/** The day it was published, as YYYY-MM-DD. */
|
|
159
|
+
date: string;
|
|
160
|
+
/** How it is cited: one line, at most 500 characters. */
|
|
161
|
+
reference: string;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/** Where a Change Set is in its life: open, then published or discarded for good. */
|
|
165
|
+
declare type ChangeSetState = "open" | "published" | "discarded";
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* A status of statushub's `contenthub/change_set` catalogue, as a label to
|
|
169
|
+
* show: what the `StatusSource` port answers.
|
|
170
|
+
*/
|
|
171
|
+
declare interface ChangeSetStatusInfo {
|
|
172
|
+
slug: string;
|
|
173
|
+
/** Its display name, in the workspace's words. */
|
|
174
|
+
name: string;
|
|
175
|
+
/** Its colour as statushub holds it (a CSS colour); absent for none. */
|
|
176
|
+
color?: string;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/** What `updateChangeSet` changes of a Change Set. */
|
|
180
|
+
declare type ChangeSetUpdateField = "name" | "source";
|
|
181
|
+
|
|
182
|
+
/** What a Check Result says. */
|
|
183
|
+
declare type CheckOutcome = "passed" | "failed" | "waived";
|
|
184
|
+
|
|
185
|
+
/** One recorded outcome of a Required Check, against the heads it saw. */
|
|
186
|
+
declare interface CheckResult {
|
|
187
|
+
id: string;
|
|
188
|
+
requiredCheckId: string;
|
|
189
|
+
heads: Record<string, string>;
|
|
190
|
+
outcome: CheckOutcome;
|
|
191
|
+
/** Why, for a waiver; optional otherwise. */
|
|
192
|
+
note: string;
|
|
193
|
+
/** Who recorded it: a person, or a flow's Run-as user. */
|
|
194
|
+
recordedBy: string;
|
|
195
|
+
/** ISO 8601. */
|
|
196
|
+
recordTime: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Whether a Required Check gates each Branch, or the Change Set once (ADR 0014). */
|
|
200
|
+
declare type CheckScope = "branch" | "change_set";
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Where one Required Check stands on one thing it applies to: a Branch or a
|
|
204
|
+
* Branch-less Planned Release for Branch scope, the whole Change Set for
|
|
205
|
+
* Change Set scope.
|
|
206
|
+
*/
|
|
207
|
+
declare interface CheckStanding {
|
|
208
|
+
check: RequiredCheck;
|
|
209
|
+
/** For Branch scope, its Content; "" for Change Set scope. */
|
|
210
|
+
contentId: string;
|
|
211
|
+
/** For Branch scope, the Branch, or the Branch-less Planned Release; "" otherwise. */
|
|
212
|
+
branchId: string;
|
|
213
|
+
releaseId: string;
|
|
214
|
+
/** What a result recorded now names. */
|
|
215
|
+
heads: Record<string, string>;
|
|
216
|
+
/** Newest first: the first is the latest, the one that counts. */
|
|
217
|
+
results: CheckResult[];
|
|
218
|
+
/** The latest result names other heads: a save since made it count for nothing. */
|
|
219
|
+
stale: boolean;
|
|
220
|
+
/** The latest result is passed or waived, and not stale. */
|
|
221
|
+
cleared: boolean;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* A node of the workspace's tree for filing Content (CONTEXT.md,
|
|
226
|
+
* Collection). Filing is not a save and is not versioned.
|
|
227
|
+
*/
|
|
228
|
+
declare interface Collection {
|
|
229
|
+
id: string;
|
|
230
|
+
name: string;
|
|
231
|
+
/** The Collection it sits in; "" at the root. */
|
|
232
|
+
parentId: string;
|
|
233
|
+
/** A Restricted Collection, visible only to those granted on it (ADR 0017). */
|
|
234
|
+
restricted: boolean;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* A level of access to a Restricted Collection (ADR 0017): `viewer` sees the
|
|
239
|
+
* Content filed in it, `editor` also saves and files it, and `owner`, given to
|
|
240
|
+
* whoever restricted it and never granted, also manages the grants.
|
|
241
|
+
*/
|
|
242
|
+
declare type CollectionAccessLevel = "viewer" | "editor" | "owner";
|
|
243
|
+
|
|
244
|
+
/** One person's access to a Restricted Collection. */
|
|
245
|
+
declare interface CollectionGrant {
|
|
246
|
+
userId: string;
|
|
247
|
+
level: CollectionAccessLevel;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** What a Revision is compared against. */
|
|
251
|
+
declare type CompareBase = {
|
|
252
|
+
kind: "revision";
|
|
253
|
+
revisionId: string;
|
|
254
|
+
} | {
|
|
255
|
+
kind: "fork";
|
|
256
|
+
branchId: string;
|
|
257
|
+
} | {
|
|
258
|
+
kind: "main_head";
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
/** One Content as a read found it: at a Main head, a Branch head or a Release. */
|
|
262
|
+
declare interface Content {
|
|
263
|
+
id: string;
|
|
264
|
+
/** The Blueprint, and the Blueprint Release its Revision pins. */
|
|
265
|
+
blueprintId: string;
|
|
266
|
+
blueprintReleaseId: string;
|
|
267
|
+
/** The Revision read. */
|
|
268
|
+
revisionId: string;
|
|
269
|
+
/** Its data, keyed by field accessor. */
|
|
270
|
+
data: Record<string, unknown>;
|
|
271
|
+
/**
|
|
272
|
+
* The Change Set and Branch it was read on; "" when read on Main or at a
|
|
273
|
+
* Release. A search on Main finds Branch heads too, so a Main list can
|
|
274
|
+
* hold rows read in a Change Set.
|
|
275
|
+
*/
|
|
276
|
+
changeSetId: string;
|
|
277
|
+
branchId: string;
|
|
278
|
+
/** ISO 8601: when the Revision was written. */
|
|
279
|
+
revisionCreateTime: string;
|
|
280
|
+
/** The Release it was read at, in the In Force view; "" elsewhere. */
|
|
281
|
+
releaseId: string;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* A Content's unversioned attributes (ADR 0015): the same wherever it is
|
|
286
|
+
* read, and never part of a Revision or a Release.
|
|
287
|
+
*/
|
|
288
|
+
declare interface ContentAttributes {
|
|
289
|
+
/** The Collections it is filed in, by id. */
|
|
290
|
+
collectionIds: string[];
|
|
291
|
+
/** Who maintains it: odon user ids, in the order they were set. */
|
|
292
|
+
assigneeIds: string[];
|
|
293
|
+
/** Absent while it is not blocked. */
|
|
294
|
+
block?: ContentBlock;
|
|
295
|
+
/** When it was archived, ISO 8601; absent while it is not Archived. */
|
|
296
|
+
archiveTime?: string;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* A Content's Block (CONTEXT.md, Block): editing is closed to all but
|
|
301
|
+
* `allowedUserIds` until it is lifted. A Block controls editing, not seeing.
|
|
302
|
+
*/
|
|
303
|
+
declare interface ContentBlock {
|
|
304
|
+
blockReasonId: string;
|
|
305
|
+
/** Who may still edit it: odon user ids; empty is nobody. */
|
|
306
|
+
allowedUserIds: string[];
|
|
307
|
+
/** The odon user who set it. */
|
|
308
|
+
blockedBy: string;
|
|
309
|
+
/** ISO 8601. */
|
|
310
|
+
blockTime: string;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/** One Content as `getContent` reads it, with its Blueprint Release and attributes. */
|
|
314
|
+
declare interface ContentDetail {
|
|
315
|
+
content: Content;
|
|
316
|
+
/** Absent when this build can't read the Resolved Release. */
|
|
317
|
+
blueprintRelease?: ResolvedBlueprintRelease;
|
|
318
|
+
attributes: ContentAttributes;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Everything contenthub-ui's screens ask contenthub, and nothing else: the
|
|
323
|
+
* port a host fills (ADR 0020). `createConnectContenthubClient` is the
|
|
324
|
+
* production implementation; `@knkcs/contenthub-ui/testing` has a stub over
|
|
325
|
+
* an in-memory workspace.
|
|
326
|
+
*
|
|
327
|
+
* Errors the screens act on arrive as the typed errors below, never as a
|
|
328
|
+
* ConnectError the screen would have to pick details out of. Anything else
|
|
329
|
+
* (no permission, the service down) arrives as it came.
|
|
330
|
+
*
|
|
331
|
+
* The workspace is never an argument: contenthub reads it from the caller's
|
|
332
|
+
* token (contenthub ADR 0017), so a host cannot ask about another workspace by
|
|
333
|
+
* mistake.
|
|
334
|
+
*/
|
|
335
|
+
declare interface ContenthubClient {
|
|
336
|
+
/** The workspace's Block Reasons, by name. */
|
|
337
|
+
listBlockReasons(): Promise<BlockReason[]>;
|
|
338
|
+
/**
|
|
339
|
+
* Adds a Block Reason. Rejects with `BlockReasonNameTakenError` when the
|
|
340
|
+
* workspace already has one of that name, and `InvalidInputError` for a
|
|
341
|
+
* name the service refuses (blank, too long, more than one line).
|
|
342
|
+
*/
|
|
343
|
+
createBlockReason(input: {
|
|
344
|
+
name: string;
|
|
345
|
+
}): Promise<BlockReason>;
|
|
346
|
+
/** Renames a Block Reason; its id stays. Rejects as `createBlockReason` does. */
|
|
347
|
+
renameBlockReason(input: {
|
|
348
|
+
id: string;
|
|
349
|
+
name: string;
|
|
350
|
+
}): Promise<BlockReason>;
|
|
351
|
+
/** Removes a Block Reason. */
|
|
352
|
+
deleteBlockReason(input: {
|
|
353
|
+
id: string;
|
|
354
|
+
}): Promise<void>;
|
|
355
|
+
/**
|
|
356
|
+
* Change Sets, newest first, without their Chains, dependencies or
|
|
357
|
+
* Planned Releases. Each filter given must hold.
|
|
358
|
+
*/
|
|
359
|
+
listChangeSets(input?: {
|
|
360
|
+
state?: ChangeSetState;
|
|
361
|
+
/** Only those this odon user is assigned to. */
|
|
362
|
+
assigneeId?: string;
|
|
363
|
+
/** Only those with a Chain on this Content. */
|
|
364
|
+
contentId?: string;
|
|
365
|
+
/** At most 200; 50 when absent. */
|
|
366
|
+
pageSize?: number;
|
|
367
|
+
pageToken?: string;
|
|
368
|
+
}): Promise<ChangeSetList>;
|
|
369
|
+
/**
|
|
370
|
+
* Opens a Change Set. Rejects with `InvalidInputError` for a name or
|
|
371
|
+
* Source the service refuses.
|
|
372
|
+
*/
|
|
373
|
+
createChangeSet(input: {
|
|
374
|
+
name: string;
|
|
375
|
+
source?: ChangeSetSource;
|
|
376
|
+
}): Promise<ChangeSet>;
|
|
377
|
+
/** A Change Set with its Chains, their Branches' heads and its dependencies. */
|
|
378
|
+
getChangeSet(id: string): Promise<ChangeSet>;
|
|
379
|
+
/**
|
|
380
|
+
* Renames an open Change Set and corrects its Source, as `updateMask`
|
|
381
|
+
* says: a field it doesn't name is left as it is, and a masked `source`
|
|
382
|
+
* that is absent clears the Source. Rejects with `InvalidInputError` for
|
|
383
|
+
* a name or Source the service refuses, and `ChangeSetClosedError` once
|
|
384
|
+
* it is published or discarded: the Source freezes at Publish.
|
|
385
|
+
*/
|
|
386
|
+
updateChangeSet(input: {
|
|
387
|
+
id: string;
|
|
388
|
+
updateMask: ChangeSetUpdateField[];
|
|
389
|
+
name?: string;
|
|
390
|
+
source?: ChangeSetSource;
|
|
391
|
+
/** Makes a retry safe (CONTEXT.md, Idempotency Key). */
|
|
392
|
+
idempotencyKey?: string;
|
|
393
|
+
}): Promise<ChangeSet>;
|
|
394
|
+
/**
|
|
395
|
+
* Moves the status label from `expectedStatus` (the status the caller
|
|
396
|
+
* saw, "" for none) to `status`. Rejects with
|
|
397
|
+
* `StatusTransitionRefusedError` when statushub refuses the move,
|
|
398
|
+
* `StaleStatusError` when the status moved meanwhile,
|
|
399
|
+
* `ChangeSetClosedError` when the Change Set is published or discarded,
|
|
400
|
+
* and `ServiceUnavailableError` while statushub can't be reached.
|
|
401
|
+
*/
|
|
402
|
+
setChangeSetStatus(input: {
|
|
403
|
+
id: string;
|
|
404
|
+
expectedStatus: string;
|
|
405
|
+
status: string;
|
|
406
|
+
}): Promise<ChangeSet>;
|
|
407
|
+
/** Replaces who is working on it: the whole new set of odon user ids. */
|
|
408
|
+
setChangeSetAssignees(input: {
|
|
409
|
+
id: string;
|
|
410
|
+
assigneeIds: string[];
|
|
411
|
+
}): Promise<ChangeSet>;
|
|
412
|
+
/**
|
|
413
|
+
* Makes the Change Set depend on another open one. Rejects with
|
|
414
|
+
* `InvalidInputError` for one that would close a cycle or is closed, and
|
|
415
|
+
* `ChangeSetClosedError` when this Change Set itself is closed.
|
|
416
|
+
*/
|
|
417
|
+
addDependency(input: {
|
|
418
|
+
id: string;
|
|
419
|
+
dependsOnId: string;
|
|
420
|
+
}): Promise<ChangeSet>;
|
|
421
|
+
/** Undoes `addDependency` while the Change Set is open. */
|
|
422
|
+
removeDependency(input: {
|
|
423
|
+
id: string;
|
|
424
|
+
dependsOnId: string;
|
|
425
|
+
}): Promise<ChangeSet>;
|
|
426
|
+
/**
|
|
427
|
+
* Publish's dry run with `reviewedHeads` (Branch id to head Revision id):
|
|
428
|
+
* every blocker a Publish with them would be refused with now, and the
|
|
429
|
+
* Releases it would cut. Writes nothing. Rejects with `WithheldWorkError`
|
|
430
|
+
* when Publish would, for a caller who can't see all of the Change Set.
|
|
431
|
+
*/
|
|
432
|
+
validatePublish(input: {
|
|
433
|
+
id: string;
|
|
434
|
+
reviewedHeads: Record<string, string>;
|
|
435
|
+
}): Promise<PublishReview>;
|
|
436
|
+
/**
|
|
437
|
+
* Publishes the Change Set with exactly `reviewedHeads`: every Branch at
|
|
438
|
+
* the head the caller reviewed. Rejects with `PublishRefusedError`
|
|
439
|
+
* carrying every blocker when it is refused, `ChangeSetClosedError`
|
|
440
|
+
* when it is closed (published with other heads, or discarded), and
|
|
441
|
+
* `WithheldWorkError` when it holds work the caller can't see.
|
|
442
|
+
*/
|
|
443
|
+
publish(input: {
|
|
444
|
+
id: string;
|
|
445
|
+
reviewedHeads: Record<string, string>;
|
|
446
|
+
}): Promise<PublishOutcome>;
|
|
447
|
+
/**
|
|
448
|
+
* Merges what Main (and each dependency) gained since into every Chain
|
|
449
|
+
* of the Change Set. A Branch whose merge has Conflicts, or fails its
|
|
450
|
+
* Blueprint Release, is left with a Pending Merge, which the Branch
|
|
451
|
+
* editor resolves. Rejects with `ChangeSetClosedError` when it is closed,
|
|
452
|
+
* and, without `chainId`, `WithheldWorkError` when it holds work the
|
|
453
|
+
* caller can't see.
|
|
454
|
+
*/
|
|
455
|
+
updateFromMain(input: {
|
|
456
|
+
id: string;
|
|
457
|
+
/** One of its Chains to update alone; every Chain when absent. */
|
|
458
|
+
chainId?: string;
|
|
459
|
+
/** Makes a retry safe (CONTEXT.md, Idempotency Key). */
|
|
460
|
+
idempotencyKey?: string;
|
|
461
|
+
}): Promise<UpdateFromMainOutcome>;
|
|
462
|
+
/**
|
|
463
|
+
* Closes the Change Set for good without publishing it. Rejects with
|
|
464
|
+
* `ChangeSetClosedError` when it is closed already, and
|
|
465
|
+
* `WithheldWorkError` when it holds work the caller can't see.
|
|
466
|
+
*/
|
|
467
|
+
discardChangeSet(id: string): Promise<ChangeSet>;
|
|
468
|
+
/**
|
|
469
|
+
* Where every Required Check that applies to the Change Set stands: the
|
|
470
|
+
* heads a result recorded now names, its results newest first, and
|
|
471
|
+
* whether the latest is stale or clears it.
|
|
472
|
+
*/
|
|
473
|
+
listCheckResults(changeSetId: string): Promise<CheckStanding[]>;
|
|
474
|
+
/**
|
|
475
|
+
* Records a Check Result against `heads`, the heads the recorder saw.
|
|
476
|
+
* Rejects with `StaleHeadError` when one of them moved,
|
|
477
|
+
* `CheckResultDeniedError` when the caller may not record it (an
|
|
478
|
+
* independent check's passed or waived from an author of what it
|
|
479
|
+
* covers), `InvalidInputError` for what
|
|
480
|
+
* the service refuses (a waiver without a note), and
|
|
481
|
+
* `ChangeSetClosedError` when the Change Set is closed.
|
|
482
|
+
*/
|
|
483
|
+
recordCheckResult(input: {
|
|
484
|
+
changeSetId: string;
|
|
485
|
+
requiredCheckId: string;
|
|
486
|
+
heads: Record<string, string>;
|
|
487
|
+
outcome: CheckOutcome;
|
|
488
|
+
note: string;
|
|
489
|
+
}): Promise<CheckResult>;
|
|
490
|
+
/** The workspace's Required Checks, by name. */
|
|
491
|
+
listRequiredChecks(): Promise<RequiredCheck[]>;
|
|
492
|
+
/**
|
|
493
|
+
* Declares a Required Check; it gates every open Change Set at once.
|
|
494
|
+
* Rejects with `NameTakenError` when another check has the name, and
|
|
495
|
+
* `InvalidInputError` for anything else the service refuses.
|
|
496
|
+
*/
|
|
497
|
+
createRequiredCheck(input: RequiredCheckInput): Promise<RequiredCheck>;
|
|
498
|
+
/** Replaces every field of a Required Check; its id stays. Rejects as create does. */
|
|
499
|
+
updateRequiredCheck(input: RequiredCheckInput & {
|
|
500
|
+
id: string;
|
|
501
|
+
}): Promise<RequiredCheck>;
|
|
502
|
+
/**
|
|
503
|
+
* Removes a Required Check: it stops gating. Its results are kept and
|
|
504
|
+
* count for nothing; its recorders' grants go with it. Rejects with
|
|
505
|
+
* `ServiceUnavailableError` while Guardian doesn't take that, and nothing
|
|
506
|
+
* is removed.
|
|
507
|
+
*/
|
|
508
|
+
deleteRequiredCheck(input: {
|
|
509
|
+
id: string;
|
|
510
|
+
}): Promise<void>;
|
|
511
|
+
/**
|
|
512
|
+
* Who records a Required Check: every member until an admin narrows it
|
|
513
|
+
* (ADR 0017's 2026-10-03 amendment). Admin only: rejects with
|
|
514
|
+
* `AccessDeniedError` otherwise, and with `GuardianModeRequiredError` in
|
|
515
|
+
* `authz.mode: workspace`, where every member records every check and
|
|
516
|
+
* nothing narrows it.
|
|
517
|
+
*/
|
|
518
|
+
listRequiredCheckRecorders(requiredCheckId: string): Promise<RequiredCheckRecorders>;
|
|
519
|
+
/**
|
|
520
|
+
* Makes a member, or every member, a recorder of a Required Check. The
|
|
521
|
+
* caller may grant themselves: an admin records a check only when
|
|
522
|
+
* granted (break-glass, announced like any grant). Rejects as
|
|
523
|
+
* `listRequiredCheckRecorders` does, with `InvalidInputError` for a
|
|
524
|
+
* grantee who is not a member, and `ServiceUnavailableError` while
|
|
525
|
+
* Guardian doesn't take the grant.
|
|
526
|
+
*/
|
|
527
|
+
grantRequiredCheckRecorder(input: {
|
|
528
|
+
requiredCheckId: string;
|
|
529
|
+
recorder: RecorderGrant;
|
|
530
|
+
}): Promise<void>;
|
|
531
|
+
/**
|
|
532
|
+
* Takes recorder from a person, or from every member, which narrows the
|
|
533
|
+
* check to the people granted by name. Rejects as grant does.
|
|
534
|
+
*/
|
|
535
|
+
revokeRequiredCheckRecorder(input: {
|
|
536
|
+
requiredCheckId: string;
|
|
537
|
+
recorder: RecorderGrant;
|
|
538
|
+
}): Promise<void>;
|
|
539
|
+
/** Every Collection of the workspace, by name, then id: a tree by `parentId`. */
|
|
540
|
+
listCollections(): Promise<Collection[]>;
|
|
541
|
+
/**
|
|
542
|
+
* Creates a Collection at the root or under `parentId`. Rejects with
|
|
543
|
+
* `NameTakenError` for a sibling of the same name, `InvalidInputError` for
|
|
544
|
+
* a name the service refuses, and `RestrictionUnavailableError` for a
|
|
545
|
+
* restricted one in workspace mode.
|
|
546
|
+
*/
|
|
547
|
+
createCollection(input: {
|
|
548
|
+
name: string;
|
|
549
|
+
parentId?: string;
|
|
550
|
+
restricted?: boolean;
|
|
551
|
+
}): Promise<Collection>;
|
|
552
|
+
/** Renames a Collection, keeping its place and filing. Rejects as create does. */
|
|
553
|
+
renameCollection(input: {
|
|
554
|
+
id: string;
|
|
555
|
+
name: string;
|
|
556
|
+
}): Promise<Collection>;
|
|
557
|
+
/**
|
|
558
|
+
* Moves a Collection, with everything under it, under `parentId` ("" for
|
|
559
|
+
* the root). Rejects with `InvalidInputError` for a move under itself, and
|
|
560
|
+
* `NameTakenError` for a sibling of the same name there, whose
|
|
561
|
+
* `takenName` is "": the request carries no name.
|
|
562
|
+
*/
|
|
563
|
+
moveCollection(input: {
|
|
564
|
+
id: string;
|
|
565
|
+
parentId: string;
|
|
566
|
+
}): Promise<Collection>;
|
|
567
|
+
/**
|
|
568
|
+
* Removes a Collection and unfiles its Content, answering the Content it
|
|
569
|
+
* unfiled. Rejects with `InvalidInputError` while Collections sit under it.
|
|
570
|
+
*/
|
|
571
|
+
removeCollection(input: {
|
|
572
|
+
id: string;
|
|
573
|
+
}): Promise<string[]>;
|
|
574
|
+
/**
|
|
575
|
+
* Restricts a Collection (the caller becomes its owner), or opens it
|
|
576
|
+
* again, which discloses its Content to every viewer and so needs
|
|
577
|
+
* `acknowledgeDisclosure`; opening it clears its grants. Rejects with
|
|
578
|
+
* `RestrictionUnavailableError` in workspace mode, and
|
|
579
|
+
* `InvalidInputError` for an unacknowledged disclosure.
|
|
580
|
+
*/
|
|
581
|
+
setCollectionRestricted(input: {
|
|
582
|
+
id: string;
|
|
583
|
+
restricted: boolean;
|
|
584
|
+
acknowledgeDisclosure?: boolean;
|
|
585
|
+
}): Promise<Collection>;
|
|
586
|
+
/**
|
|
587
|
+
* Who is granted on a Restricted Collection, its owner included. Rejects
|
|
588
|
+
* with `AccessDeniedError` unless the caller is its owner or an admin, and
|
|
589
|
+
* `RestrictionUnavailableError` in workspace mode.
|
|
590
|
+
*/
|
|
591
|
+
listCollectionGrants(collectionId: string): Promise<CollectionGrant[]>;
|
|
592
|
+
/**
|
|
593
|
+
* Grants a member viewer or editor on a Restricted Collection, replacing
|
|
594
|
+
* what they held. The caller may grant themselves (break-glass, announced
|
|
595
|
+
* like any grant). Rejects as `listCollectionGrants` does, and with
|
|
596
|
+
* `InvalidInputError` for a grantee who is not a member or an open
|
|
597
|
+
* Collection.
|
|
598
|
+
*/
|
|
599
|
+
grantCollectionAccess(input: {
|
|
600
|
+
collectionId: string;
|
|
601
|
+
userId: string;
|
|
602
|
+
level: "viewer" | "editor";
|
|
603
|
+
}): Promise<void>;
|
|
604
|
+
/** Takes a person's grant on a Restricted Collection. Rejects as grant does. */
|
|
605
|
+
revokeCollectionAccess(input: {
|
|
606
|
+
collectionId: string;
|
|
607
|
+
userId: string;
|
|
608
|
+
}): Promise<void>;
|
|
609
|
+
/**
|
|
610
|
+
* Content in one view, ordered by id (then Branch, for a search), each
|
|
611
|
+
* filter given holding. Rejects with `InvalidInputError` for a search in
|
|
612
|
+
* the In Force view, which Editor Search never covers (ADR 0019), and for
|
|
613
|
+
* a search the service refuses.
|
|
614
|
+
*/
|
|
615
|
+
listContents(input?: {
|
|
616
|
+
/** Main when absent. */
|
|
617
|
+
view?: ContentView;
|
|
618
|
+
/**
|
|
619
|
+
* Only Content filed directly in this Collection, not in Collections
|
|
620
|
+
* under it.
|
|
621
|
+
*/
|
|
622
|
+
collectionId?: string;
|
|
623
|
+
/** Editor Search: a name, number or phrase, letter for letter but ignoring case. */
|
|
624
|
+
search?: string;
|
|
625
|
+
/**
|
|
626
|
+
* Only Content of one of these Blueprints, filtered by the service so
|
|
627
|
+
* that every page but the last is full; empty or absent for every
|
|
628
|
+
* Blueprint. At most 100.
|
|
629
|
+
*/
|
|
630
|
+
blueprintIds?: string[];
|
|
631
|
+
/** Only Content this user maintains: one of its assignees. */
|
|
632
|
+
assigneeId?: string;
|
|
633
|
+
/** At most 200; 50 when absent. */
|
|
634
|
+
pageSize?: number;
|
|
635
|
+
pageToken?: string;
|
|
636
|
+
}): Promise<ContentList>;
|
|
637
|
+
/**
|
|
638
|
+
* Creates a Content in an open Change Set, pinning a Blueprint Release,
|
|
639
|
+
* with empty data: its one Chain has one Branch, opened in the Branch
|
|
640
|
+
* editor. Rejects with `ChangeSetClosedError` for a closed Change Set,
|
|
641
|
+
* `ContentRefusedError` for a Release contenthub can't load or empty data
|
|
642
|
+
* the Release refuses (a required field), and `InvalidInputError` for
|
|
643
|
+
* anything else the service refuses.
|
|
644
|
+
*/
|
|
645
|
+
createContent(input: {
|
|
646
|
+
changeSetId: string;
|
|
647
|
+
/** May be "" with `copyFrom`, to pin what the source pins. */
|
|
648
|
+
blueprintReleaseId: string;
|
|
649
|
+
/** Duplicate: the new Content's first Revision takes this source's data. */
|
|
650
|
+
copyFrom?: CopyFrom;
|
|
651
|
+
}): Promise<Content>;
|
|
652
|
+
/**
|
|
653
|
+
* Saves a new Revision on a Branch of an open Change Set, on top of
|
|
654
|
+
* `expectedHeadId`, the head the editor loaded (ADR 0003). With
|
|
655
|
+
* `fieldMask` the save is partial: each top-level field it names takes
|
|
656
|
+
* its value in `data`, or is removed when `data` doesn't hold it, and
|
|
657
|
+
* every other field is carried over from the head. Answers the Content
|
|
658
|
+
* as read in the Change Set afterwards.
|
|
659
|
+
*
|
|
660
|
+
* Rejects with `StaleHeadError` when the head moved (nothing is written,
|
|
661
|
+
* and nothing is merged: ADR 0020), `ContentRefusedError` with one reason
|
|
662
|
+
* per Violation the data breaks, `ContentBlockedError` or
|
|
663
|
+
* `ContentArchivedError` for Content closed to the caller,
|
|
664
|
+
* `ChangeSetClosedError` for a closed Change Set, and `InvalidInputError`
|
|
665
|
+
* for anything else the service refuses.
|
|
666
|
+
*/
|
|
667
|
+
saveRevision(input: {
|
|
668
|
+
/** The Branch's Change Set, which a closed refusal names. */
|
|
669
|
+
changeSetId: string;
|
|
670
|
+
branchId: string;
|
|
671
|
+
expectedHeadId: string;
|
|
672
|
+
data: Record<string, unknown>;
|
|
673
|
+
/** Top-level field accessors; absent saves `data` as the whole Revision. */
|
|
674
|
+
fieldMask?: string[];
|
|
675
|
+
/**
|
|
676
|
+
* Makes a retry safe (CONTEXT.md, Idempotency Key): sent again with
|
|
677
|
+
* the same request, it answers the first save and writes nothing.
|
|
678
|
+
*/
|
|
679
|
+
idempotencyKey?: string;
|
|
680
|
+
}): Promise<Content>;
|
|
681
|
+
/**
|
|
682
|
+
* One Content with its Blueprint Release and attributes: on Main, or
|
|
683
|
+
* inside `changeSetId`. Content born in an open Change Set exists only
|
|
684
|
+
* there, so read anywhere else it is a NotFound ConnectError.
|
|
685
|
+
*/
|
|
686
|
+
getContent(input: {
|
|
687
|
+
id: string;
|
|
688
|
+
changeSetId?: string;
|
|
689
|
+
}): Promise<ContentDetail>;
|
|
690
|
+
/** Its Timeline, with the Planned Releases of open Change Sets beside it. */
|
|
691
|
+
getTimeline(contentId: string): Promise<ContentTimeline>;
|
|
692
|
+
/**
|
|
693
|
+
* Revisions, newest first: every one of a published Content, or those of
|
|
694
|
+
* one Branch (the only way to list those of Content born in an open
|
|
695
|
+
* Change Set).
|
|
696
|
+
*/
|
|
697
|
+
listRevisions(input: {
|
|
698
|
+
target: {
|
|
699
|
+
contentId: string;
|
|
700
|
+
} | {
|
|
701
|
+
branchId: string;
|
|
702
|
+
};
|
|
703
|
+
pageSize?: number;
|
|
704
|
+
pageToken?: string;
|
|
705
|
+
}): Promise<RevisionList>;
|
|
706
|
+
/** How `revisionId` differs from a base, field by field. */
|
|
707
|
+
compare(input: {
|
|
708
|
+
revisionId: string;
|
|
709
|
+
base: CompareBase;
|
|
710
|
+
}): Promise<RevisionComparison>;
|
|
711
|
+
/** The outgoing edges of one Revision, its own only. */
|
|
712
|
+
listReferences(input: {
|
|
713
|
+
contentId: string;
|
|
714
|
+
revisionId: string;
|
|
715
|
+
}): Promise<Edge[]>;
|
|
716
|
+
/**
|
|
717
|
+
* One page of the edges pointing at a Content from Releases In Force
|
|
718
|
+
* today and, asked, open Branch heads: Releases first, then Change Sets.
|
|
719
|
+
*/
|
|
720
|
+
listReferrers(input: {
|
|
721
|
+
contentId: string;
|
|
722
|
+
includeOpenChangeSets?: boolean;
|
|
723
|
+
/** 100 when absent; above 1000 reads as 1000. */
|
|
724
|
+
pageSize?: number;
|
|
725
|
+
pageToken?: string;
|
|
726
|
+
}): Promise<ReferrerList>;
|
|
727
|
+
/** The pinned edges of a Branch head or a Revision that are outdated today. */
|
|
728
|
+
listOutdatedPins(input: {
|
|
729
|
+
branchId: string;
|
|
730
|
+
} | {
|
|
731
|
+
revisionId: string;
|
|
732
|
+
}): Promise<OutdatedPin[]>;
|
|
733
|
+
/** Files a Content in exactly these Collections: no save, no Revision (ADR 0015). Answers its Collections. */
|
|
734
|
+
setContentCollections(input: {
|
|
735
|
+
contentId: string;
|
|
736
|
+
collectionIds: string[];
|
|
737
|
+
}): Promise<string[]>;
|
|
738
|
+
/** Replaces who maintains a Content: no save, no Revision. */
|
|
739
|
+
setContentAssignees(input: {
|
|
740
|
+
contentId: string;
|
|
741
|
+
assigneeIds: string[];
|
|
742
|
+
}): Promise<ContentAttributes>;
|
|
743
|
+
/** Blocks a Content, replacing any Block it has. */
|
|
744
|
+
blockContent(input: {
|
|
745
|
+
contentId: string;
|
|
746
|
+
blockReasonId: string;
|
|
747
|
+
allowedUserIds: string[];
|
|
748
|
+
}): Promise<ContentAttributes>;
|
|
749
|
+
unblockContent(contentId: string): Promise<ContentAttributes>;
|
|
750
|
+
/**
|
|
751
|
+
* Archives a published Content with no Release In Force today or later.
|
|
752
|
+
* Rejects with `InvalidInputError` for any other, with the service's reason.
|
|
753
|
+
*/
|
|
754
|
+
archiveContent(contentId: string): Promise<ContentAttributes>;
|
|
755
|
+
unarchiveContent(contentId: string): Promise<ContentAttributes>;
|
|
756
|
+
/**
|
|
757
|
+
* Starts a Chain on a published Content, in `changeSetId` or in a new
|
|
758
|
+
* Change Set named `changeSetName` (after the Content when empty).
|
|
759
|
+
* Answers the Change Set and the Content as read on the Branch to edit.
|
|
760
|
+
* Rejects with `ContentBlockedError`, `ContentArchivedError`,
|
|
761
|
+
* `ChangeSetClosedError`, and `InvalidInputError` for anything else the
|
|
762
|
+
* service refuses (a missing or needless effective date).
|
|
763
|
+
*/
|
|
764
|
+
startEditing(input: {
|
|
765
|
+
contentId: string;
|
|
766
|
+
changeSetId?: string;
|
|
767
|
+
/** YYYY-MM-DD: required for Dated Content, refused for undated. */
|
|
768
|
+
effectiveOn?: string;
|
|
769
|
+
changeSetName?: string;
|
|
770
|
+
}): Promise<{
|
|
771
|
+
changeSet: ChangeSet;
|
|
772
|
+
content: Content;
|
|
773
|
+
}>;
|
|
774
|
+
/** What a Chain on Dated Content, effective on a date, would fork from and meet. */
|
|
775
|
+
previewChain(input: {
|
|
776
|
+
changeSetId: string;
|
|
777
|
+
contentId: string;
|
|
778
|
+
effectiveOn: string;
|
|
779
|
+
/** The period to meet the Content's Releases with; from `effectiveOn`, open, when absent. */
|
|
780
|
+
validityPeriod?: ValidityPeriod;
|
|
781
|
+
}): Promise<ChainPreview>;
|
|
782
|
+
/**
|
|
783
|
+
* Plans the Release Publish will cut of an editorial Branch's head, with
|
|
784
|
+
* its Validity Period (required for Dated Content, refused for undated)
|
|
785
|
+
* and Release Spec values. Rejects with `ContentRefusedError` for Release
|
|
786
|
+
* Spec values the Blueprint Release refuses, `CoversReleaseError` when
|
|
787
|
+
* the period would cover a Release entirely, and as any edit does.
|
|
788
|
+
*/
|
|
789
|
+
planRelease(input: {
|
|
790
|
+
changeSetId: string;
|
|
791
|
+
branchId: string;
|
|
792
|
+
validityPeriod?: ValidityPeriod;
|
|
793
|
+
releaseSpec?: Record<string, unknown>;
|
|
794
|
+
supersedesReleaseIds?: string[];
|
|
795
|
+
idempotencyKey?: string;
|
|
796
|
+
}): Promise<PlannedRelease>;
|
|
797
|
+
/**
|
|
798
|
+
* Changes a Planned Release: each part given replaces what it had, each
|
|
799
|
+
* absent keeps it. The Change Set's proposals are derived again. Rejects
|
|
800
|
+
* as `planRelease` does, and with `InvalidInputError` for a proposal.
|
|
801
|
+
*/
|
|
802
|
+
updatePlannedRelease(input: {
|
|
803
|
+
changeSetId: string;
|
|
804
|
+
plannedReleaseId: string;
|
|
805
|
+
validityPeriod?: ValidityPeriod;
|
|
806
|
+
releaseSpec?: Record<string, unknown>;
|
|
807
|
+
supersedesReleaseIds?: string[];
|
|
808
|
+
idempotencyKey?: string;
|
|
809
|
+
}): Promise<PlannedRelease>;
|
|
810
|
+
/**
|
|
811
|
+
* Adds an editorial Branch to a Chain on Dated Content, for a later
|
|
812
|
+
* date. Answers the Change Set and the new Branch's id. Rejects with
|
|
813
|
+
* `InvalidInputError` for a date not after the Chain's last editorial
|
|
814
|
+
* Branch's, or a Chain without dates.
|
|
815
|
+
*/
|
|
816
|
+
appendBranch(input: {
|
|
817
|
+
changeSetId: string;
|
|
818
|
+
chainId: string;
|
|
819
|
+
effectiveOn: string;
|
|
820
|
+
idempotencyKey?: string;
|
|
821
|
+
}): Promise<{
|
|
822
|
+
changeSet: ChangeSet;
|
|
823
|
+
branchId: string;
|
|
824
|
+
}>;
|
|
825
|
+
/**
|
|
826
|
+
* Removes a Chain from an open Change Set with its Planned Releases; its
|
|
827
|
+
* Revisions stay in history. Rejects with `InvalidInputError` for the
|
|
828
|
+
* Chain of Content born in the Change Set.
|
|
829
|
+
*/
|
|
830
|
+
dropChain(input: {
|
|
831
|
+
changeSetId: string;
|
|
832
|
+
chainId: string;
|
|
833
|
+
idempotencyKey?: string;
|
|
834
|
+
}): Promise<ChangeSet>;
|
|
835
|
+
/** The Pending Merge on a Branch, with what its resolution decides; null for none. */
|
|
836
|
+
getPendingMerge(branchId: string): Promise<PendingMerge | null>;
|
|
837
|
+
/**
|
|
838
|
+
* Resolves the Pending Merge on a Branch field by field, as a merge
|
|
839
|
+
* Revision that becomes its head. Rejects with `StaleHeadError` when the
|
|
840
|
+
* head moved, `ContentRefusedError` when the result fails the Blueprint
|
|
841
|
+
* Release, and `InvalidInputError` for a field undecided or a Branch
|
|
842
|
+
* without a Pending Merge.
|
|
843
|
+
*/
|
|
844
|
+
resolveMerge(input: {
|
|
845
|
+
changeSetId: string;
|
|
846
|
+
branchId: string;
|
|
847
|
+
expectedHeadId: string;
|
|
848
|
+
resolutions: FieldResolution[];
|
|
849
|
+
idempotencyKey?: string;
|
|
850
|
+
}): Promise<Content>;
|
|
851
|
+
/** Drops the Pending Merge on a Branch, which stays behind its base. */
|
|
852
|
+
abortMerge(input: {
|
|
853
|
+
changeSetId: string;
|
|
854
|
+
branchId: string;
|
|
855
|
+
idempotencyKey?: string;
|
|
856
|
+
}): Promise<void>;
|
|
857
|
+
/**
|
|
858
|
+
* Preview: the Content as In Force on `validOn` (today when absent) if
|
|
859
|
+
* the open Change Set were published now (ReleaseService's
|
|
860
|
+
* preview_change_set); null when nothing is In Force then.
|
|
861
|
+
*/
|
|
862
|
+
previewInForce(input: {
|
|
863
|
+
contentId: string;
|
|
864
|
+
changeSetId: string;
|
|
865
|
+
validOn?: string;
|
|
866
|
+
}): Promise<PreviewedContent | null>;
|
|
867
|
+
/** Plans a Repeal of Dated Content ending on `lastDay`. */
|
|
868
|
+
planRepeal(input: {
|
|
869
|
+
changeSetId: string;
|
|
870
|
+
contentId: string;
|
|
871
|
+
lastDay: string;
|
|
872
|
+
}): Promise<PlannedEnd>;
|
|
873
|
+
/** Plans a Withdrawal of undated Content. */
|
|
874
|
+
planWithdrawal(input: {
|
|
875
|
+
changeSetId: string;
|
|
876
|
+
contentId: string;
|
|
877
|
+
}): Promise<PlannedEnd>;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
/** One page of `listContents`. */
|
|
881
|
+
declare interface ContentList {
|
|
882
|
+
contents: Content[];
|
|
883
|
+
/** Empty on the last page. */
|
|
884
|
+
nextPageToken: string;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
/** A Content's Timeline, with what open Change Sets plan to add to it. */
|
|
888
|
+
declare interface ContentTimeline {
|
|
889
|
+
entries: TimelineEntry[];
|
|
890
|
+
/** By Change Set, in the order they were planned. */
|
|
891
|
+
plannedReleases: {
|
|
892
|
+
changeSetId: string;
|
|
893
|
+
plannedRelease: PlannedRelease;
|
|
894
|
+
}[];
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
/**
|
|
898
|
+
* Where the Content Library reads each Content: on Main (what has been
|
|
899
|
+
* published, at its Main head), at its Release In Force today, or inside one
|
|
900
|
+
* Change Set (at the head of its Chain's last Branch).
|
|
901
|
+
*/
|
|
902
|
+
declare type ContentView = {
|
|
903
|
+
kind: "main";
|
|
904
|
+
} | {
|
|
905
|
+
kind: "in_force";
|
|
906
|
+
} | {
|
|
907
|
+
kind: "change_set";
|
|
908
|
+
changeSetId: string;
|
|
909
|
+
};
|
|
910
|
+
|
|
911
|
+
/** What a new Content copies (`createContent`'s copy_from). */
|
|
912
|
+
declare type CopyFrom = {
|
|
913
|
+
revisionId: string;
|
|
914
|
+
} | {
|
|
915
|
+
releaseId: string;
|
|
916
|
+
};
|
|
917
|
+
|
|
918
|
+
export declare function createStubBlueprintSource(blueprints?: BlueprintInfo[], releases?: BlueprintReleaseInfo[]): BlueprintSource;
|
|
919
|
+
|
|
920
|
+
export declare function createStubContenthubClient(options?: StubContenthubClientOptions): ContenthubClient;
|
|
921
|
+
|
|
922
|
+
export declare function createStubStatusSource(statuses?: ChangeSetStatusInfo[]): StatusSource;
|
|
923
|
+
|
|
924
|
+
/** One edge of one Revision. */
|
|
925
|
+
declare interface Edge {
|
|
926
|
+
sourceContentId: string;
|
|
927
|
+
sourceRevisionId: string;
|
|
928
|
+
/** fieldkit's Path of the value it comes from; "" for the Blueprint edge. */
|
|
929
|
+
path: string;
|
|
930
|
+
kind: EdgeKind;
|
|
931
|
+
/** Exactly one of the three targets is set. */
|
|
932
|
+
targetContentId: string;
|
|
933
|
+
targetAssetId: string;
|
|
934
|
+
targetBlueprintReleaseId: string;
|
|
935
|
+
/** The Release the edge is pinned to; "" when it follows the Release In Force. */
|
|
936
|
+
pinReleaseId: string;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
/** What kind of edge of the Content Graph (ADR 0009). */
|
|
940
|
+
declare type EdgeKind = "reference" | "toc" | "include" | "exclude" | "replace" | "annotate" | "link" | "footnote" | "anchor" | "media" | "blueprint" | "unspecified";
|
|
941
|
+
|
|
942
|
+
/** One field that differs between two Revisions. */
|
|
943
|
+
declare interface FieldChange {
|
|
944
|
+
/** "/" and the field's accessor. */
|
|
945
|
+
path: string;
|
|
946
|
+
kind: "added" | "removed" | "changed";
|
|
947
|
+
/** Absent on the side that doesn't hold the field. */
|
|
948
|
+
before?: unknown;
|
|
949
|
+
after?: unknown;
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
/** One decision of a merge resolution: a side's value, or the editor's own. */
|
|
953
|
+
declare type FieldResolution = {
|
|
954
|
+
path: string;
|
|
955
|
+
side: "ours" | "theirs";
|
|
956
|
+
} | {
|
|
957
|
+
path: string;
|
|
958
|
+
value: unknown;
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
/** An unpinned edge a Repeal or Withdrawal will leave pointing at a gap. */
|
|
962
|
+
declare interface GapReferrer {
|
|
963
|
+
edge: Edge;
|
|
964
|
+
/** The Release holding the edge. */
|
|
965
|
+
releaseId: string;
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/** One field a merge resolution must decide, with each side's value. */
|
|
969
|
+
declare interface MergeField {
|
|
970
|
+
/** "/" and the field's accessor, as a Violation spells it. */
|
|
971
|
+
path: string;
|
|
972
|
+
/** Where within the field it stopped. */
|
|
973
|
+
conflictPaths: string[];
|
|
974
|
+
/** The field's value in base, ours (the Branch's head) and theirs; absent on a side without it. */
|
|
975
|
+
base?: unknown;
|
|
976
|
+
ours?: unknown;
|
|
977
|
+
theirs?: unknown;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/** A pinned edge whose Release is superseded, or is not the one In Force today. */
|
|
981
|
+
declare interface OutdatedPin {
|
|
982
|
+
edge: Edge;
|
|
983
|
+
/** "" if none. */
|
|
984
|
+
supersededByReleaseId: string;
|
|
985
|
+
/** The target's Release In Force today; "" in a gap. */
|
|
986
|
+
inForceReleaseId: string;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
/**
|
|
990
|
+
* A merge on a Branch that stopped (CONTEXT.md, Conflict), with what its
|
|
991
|
+
* resolution decides: saves on the Branch and Publish wait until it is
|
|
992
|
+
* resolved or aborted.
|
|
993
|
+
*/
|
|
994
|
+
declare interface PendingMerge {
|
|
995
|
+
branchId: string;
|
|
996
|
+
contentId: string;
|
|
997
|
+
reason: PendingMergeReason;
|
|
998
|
+
/** The Branch's head, which a resolution names as the head it built on. */
|
|
999
|
+
oursRevisionId: string;
|
|
1000
|
+
/** What the Branch was merging. */
|
|
1001
|
+
theirsRevisionId: string;
|
|
1002
|
+
/** Whether theirs is what a Carry-forward link carries rather than Main's head. */
|
|
1003
|
+
carried: boolean;
|
|
1004
|
+
/** The fields a resolution must decide, by path. */
|
|
1005
|
+
fields: MergeField[];
|
|
1006
|
+
/** Every other field, merged. */
|
|
1007
|
+
merged: Record<string, unknown>;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
/** Why Update from Main stopped a merge: Conflicts, or merged data the Blueprint Release refuses. */
|
|
1011
|
+
declare type PendingMergeReason = "conflict" | "invalid";
|
|
1012
|
+
|
|
1013
|
+
/** Which Branch holds a Pending Merge: the Branch editor shows the merge itself. */
|
|
1014
|
+
declare interface PendingMergeRef {
|
|
1015
|
+
branchId: string;
|
|
1016
|
+
contentId: string;
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
/** A Repeal or Withdrawal planned, and the referrers it will leave with a gap. */
|
|
1020
|
+
declare interface PlannedEnd {
|
|
1021
|
+
plannedRelease: PlannedRelease;
|
|
1022
|
+
/** A warning, never a refusal (ADR 0009). */
|
|
1023
|
+
gapReferrers: GapReferrer[];
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
/**
|
|
1027
|
+
* A Release a Change Set will cut when it is published (CONTEXT.md, Planned
|
|
1028
|
+
* Release). Its id is the Release's id from the moment it is planned.
|
|
1029
|
+
*/
|
|
1030
|
+
declare interface PlannedRelease {
|
|
1031
|
+
id: string;
|
|
1032
|
+
contentId: string;
|
|
1033
|
+
kind: ReleaseKind;
|
|
1034
|
+
/** The editorial Branch whose head at Publish it pins; "" for a Branch-less kind. */
|
|
1035
|
+
branchId: string;
|
|
1036
|
+
/** The Revision a Branch-less kind re-pins; "" for a Branch's Release. */
|
|
1037
|
+
revisionId: string;
|
|
1038
|
+
/** Absent for undated Content. */
|
|
1039
|
+
validityPeriod?: ValidityPeriod;
|
|
1040
|
+
/** Its Release Spec values, keyed by the Release Spec Field's accessor; absent for none. */
|
|
1041
|
+
releaseSpec?: Record<string, unknown>;
|
|
1042
|
+
/** The Releases it will Supersede. */
|
|
1043
|
+
supersedesReleaseIds: string[];
|
|
1044
|
+
/**
|
|
1045
|
+
* Proposed by the Change Set, to end `proposedForReleaseId`, a Release a
|
|
1046
|
+
* planned Validity Period cuts into: recomputed from the plans, never
|
|
1047
|
+
* edited by hand.
|
|
1048
|
+
*/
|
|
1049
|
+
proposed: boolean;
|
|
1050
|
+
proposedForReleaseId: string;
|
|
1051
|
+
/** For a proposed tail, the Release whose wording it resumes; "" otherwise. */
|
|
1052
|
+
splitFromReleaseId: string;
|
|
1053
|
+
/**
|
|
1054
|
+
* For a Carry-forward link's proposal, whether a plan supersedes the
|
|
1055
|
+
* Release it carries, so that Publish doesn't cut it.
|
|
1056
|
+
*/
|
|
1057
|
+
withheld: boolean;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
/**
|
|
1061
|
+
* One Content as a Preview reads it (ReleaseService with a Change Set
|
|
1062
|
+
* previewed): its Release In Force on a day as if the Change Set were
|
|
1063
|
+
* published now.
|
|
1064
|
+
*/
|
|
1065
|
+
declare interface PreviewedContent {
|
|
1066
|
+
/** The Release read, or the Planned Release the Change Set would cut. */
|
|
1067
|
+
releaseId: string;
|
|
1068
|
+
revisionId: string;
|
|
1069
|
+
/** Whether it is one of the previewed Change Set's Planned Releases. */
|
|
1070
|
+
planned: boolean;
|
|
1071
|
+
/** Restricted Content the caller isn't granted on: the Preview's change is withheld. */
|
|
1072
|
+
withheld: boolean;
|
|
1073
|
+
/** Absent for undated Content. */
|
|
1074
|
+
validityPeriod?: ValidityPeriod;
|
|
1075
|
+
data: Record<string, unknown>;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
/**
|
|
1079
|
+
* One reason a Publish is refused, or would be (ADR 0015). Which ids are set
|
|
1080
|
+
* depends on `code`; an id that doesn't apply is "".
|
|
1081
|
+
*/
|
|
1082
|
+
declare interface PublishBlocker {
|
|
1083
|
+
/**
|
|
1084
|
+
* versionkit's (moved_head, unplanned_branch, several_branches,
|
|
1085
|
+
* behind_base, superseded_release, overlapping_periods, covers_release,
|
|
1086
|
+
* pending_merge, nothing_in_force, withdrawal_with_chain, dated_changed,
|
|
1087
|
+
* unpublished_dependency, discarded_dependency), the Content Graph's
|
|
1088
|
+
* (dangling_pin, second_toc_parent, missing_asset), mediahub's
|
|
1089
|
+
* (media_unavailable: it refused the caller's token), Required Checks'
|
|
1090
|
+
* (outstanding_check) or the values' (missing_required_field: a required
|
|
1091
|
+
* field `revisionId` leaves empty, at `path`). A code this build doesn't
|
|
1092
|
+
* know shows as its code.
|
|
1093
|
+
*/
|
|
1094
|
+
code: string;
|
|
1095
|
+
contentId: string;
|
|
1096
|
+
branchId: string;
|
|
1097
|
+
expectedHeadId: string;
|
|
1098
|
+
currentHeadId: string;
|
|
1099
|
+
releaseId: string;
|
|
1100
|
+
overlapsReleaseId: string;
|
|
1101
|
+
dependencyChangeSetId: string;
|
|
1102
|
+
path: string;
|
|
1103
|
+
targetContentId: string;
|
|
1104
|
+
assetId: string;
|
|
1105
|
+
parentContentIds: string[];
|
|
1106
|
+
requiredCheckId: string;
|
|
1107
|
+
coveredReleaseId: string;
|
|
1108
|
+
revisionId: string;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
/** What a Publish did. */
|
|
1112
|
+
declare interface PublishOutcome {
|
|
1113
|
+
changeSet: ChangeSet;
|
|
1114
|
+
/** ISO 8601: the Publish Time every Release carries. */
|
|
1115
|
+
publishTime: string;
|
|
1116
|
+
releases: Release[];
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
/**
|
|
1120
|
+
* Publish's dry run: what a Publish with the same reviewed heads would be
|
|
1121
|
+
* refused with now, and what it would cut.
|
|
1122
|
+
*/
|
|
1123
|
+
declare interface PublishReview {
|
|
1124
|
+
/** None means a Publish with these heads would succeed now. */
|
|
1125
|
+
blockers: PublishBlocker[];
|
|
1126
|
+
releases: Release[];
|
|
1127
|
+
/** Published already with these heads: Publish would return its stored outcome. */
|
|
1128
|
+
published: boolean;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
/** One recorder grant: a member by name, or every member of the workspace. */
|
|
1132
|
+
declare type RecorderGrant = {
|
|
1133
|
+
userId: string;
|
|
1134
|
+
} | {
|
|
1135
|
+
everyMember: true;
|
|
1136
|
+
};
|
|
1137
|
+
|
|
1138
|
+
/** An incoming edge, and where it was found: a Release In Force, or an open Change Set's Branch. */
|
|
1139
|
+
declare interface Referrer {
|
|
1140
|
+
edge: Edge;
|
|
1141
|
+
/** "" when found in a Change Set. */
|
|
1142
|
+
releaseId: string;
|
|
1143
|
+
/** "" when found in a Release. */
|
|
1144
|
+
changeSetId: string;
|
|
1145
|
+
branchId: string;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
/** One page of `listReferrers`. */
|
|
1149
|
+
declare interface ReferrerList {
|
|
1150
|
+
referrers: Referrer[];
|
|
1151
|
+
/** Empty on the last page. */
|
|
1152
|
+
nextPageToken: string;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/** A Release a Publish cut, or would cut. */
|
|
1156
|
+
declare interface Release {
|
|
1157
|
+
id: string;
|
|
1158
|
+
contentId: string;
|
|
1159
|
+
kind: ReleaseKind;
|
|
1160
|
+
branchId: string;
|
|
1161
|
+
revisionId: string;
|
|
1162
|
+
/** The Content's first Release: the moment it exists outside its Change Set. */
|
|
1163
|
+
first: boolean;
|
|
1164
|
+
supersedesReleaseIds: string[];
|
|
1165
|
+
/** Absent for undated Content. */
|
|
1166
|
+
validityPeriod?: ValidityPeriod;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
/** How a Release comes to be (contenthub ADR 0016). */
|
|
1170
|
+
declare type ReleaseKind = "revision" | "date_only" | "repeal" | "withdrawal";
|
|
1171
|
+
|
|
1172
|
+
/** A condition the workspace requires before Publish (CONTEXT.md, Required Check). */
|
|
1173
|
+
declare interface RequiredCheck {
|
|
1174
|
+
id: string;
|
|
1175
|
+
name: string;
|
|
1176
|
+
scope: CheckScope;
|
|
1177
|
+
/** The Blueprints whose Content it applies to; empty for every one. */
|
|
1178
|
+
blueprintAccessors: string[];
|
|
1179
|
+
/** Passed and waived are refused from whoever authored what it covers. */
|
|
1180
|
+
independent: boolean;
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
/** What a Required Check is declared with, on create and on update alike. */
|
|
1184
|
+
declare interface RequiredCheckInput {
|
|
1185
|
+
name: string;
|
|
1186
|
+
scope: CheckScope;
|
|
1187
|
+
/** Blueprint accessors; empty for every Blueprint. */
|
|
1188
|
+
blueprintAccessors: string[];
|
|
1189
|
+
independent: boolean;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
/**
|
|
1193
|
+
* Who records a Required Check's results (ADR 0017's 2026-10-03 amendment):
|
|
1194
|
+
* every member of the workspace, the people granted by name, or both while
|
|
1195
|
+
* an admin narrows it.
|
|
1196
|
+
*/
|
|
1197
|
+
declare interface RequiredCheckRecorders {
|
|
1198
|
+
everyMember: boolean;
|
|
1199
|
+
/** Sorted odon user ids. */
|
|
1200
|
+
userIds: string[];
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
/**
|
|
1204
|
+
* The Blueprint Release a Content's Revision pins, as contenthub validated
|
|
1205
|
+
* and cached it (blueprinthub's Resolved Release): what its form is drawn
|
|
1206
|
+
* from.
|
|
1207
|
+
*/
|
|
1208
|
+
declare interface ResolvedBlueprintRelease {
|
|
1209
|
+
/** The Blueprint's name, as the released Revision holds it; "" if it holds none. */
|
|
1210
|
+
displayName: string;
|
|
1211
|
+
/** Whether its Content is Dated: its Releases carry a Validity Period. */
|
|
1212
|
+
dated: boolean;
|
|
1213
|
+
/** fieldkit's Resolved Spec fields, in Blueprint order. */
|
|
1214
|
+
fields: ResolvedField[];
|
|
1215
|
+
/**
|
|
1216
|
+
* Its Release Spec: the fields every Release of its Content carries
|
|
1217
|
+
* values for, which a Planned Release sets. Absent or empty for none.
|
|
1218
|
+
*/
|
|
1219
|
+
releaseSpec?: ResolvedField[];
|
|
1220
|
+
/** The opaque parts the fields pin (fieldkit ADR-0020), by kind and Release id. */
|
|
1221
|
+
parts: Record<string, Record<string, unknown>>;
|
|
1222
|
+
}
|
|
1223
|
+
|
|
1224
|
+
/**
|
|
1225
|
+
* One field of a Blueprint Release, as its Resolved Release declares it:
|
|
1226
|
+
* fieldkit's Field. The screens read its name and accessor and hand the
|
|
1227
|
+
* rest to fieldkit untouched.
|
|
1228
|
+
*/
|
|
1229
|
+
declare interface ResolvedField {
|
|
1230
|
+
field_type: string;
|
|
1231
|
+
config: {
|
|
1232
|
+
name: string;
|
|
1233
|
+
api_accessor: string;
|
|
1234
|
+
hidden?: boolean;
|
|
1235
|
+
} & Record<string, unknown>;
|
|
1236
|
+
children?: ResolvedField[];
|
|
1237
|
+
[key: string]: unknown;
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
/** One immutable Revision of a Content, without its data. */
|
|
1241
|
+
declare interface Revision {
|
|
1242
|
+
id: string;
|
|
1243
|
+
contentId: string;
|
|
1244
|
+
/** The Revision it was built on; "" for the Content's first. */
|
|
1245
|
+
parentId: string;
|
|
1246
|
+
/** The other side of a merge Revision; "" otherwise. */
|
|
1247
|
+
secondParentId: string;
|
|
1248
|
+
blueprintReleaseId: string;
|
|
1249
|
+
/** ISO 8601. */
|
|
1250
|
+
createTime: string;
|
|
1251
|
+
/** The odon user who wrote it. */
|
|
1252
|
+
author: string;
|
|
1253
|
+
cause: RevisionCause;
|
|
1254
|
+
/** The Branch it was written on, and that Branch's Change Set. */
|
|
1255
|
+
branchId: string;
|
|
1256
|
+
changeSetId: string;
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
/** Why a Revision was written. */
|
|
1260
|
+
declare type RevisionCause = "create" | "save" | "merge" | "resolve" | "upgrade" | "unspecified";
|
|
1261
|
+
|
|
1262
|
+
/** How one Revision differs from a base, field by field. */
|
|
1263
|
+
declare interface RevisionComparison {
|
|
1264
|
+
base: Revision;
|
|
1265
|
+
revision: Revision;
|
|
1266
|
+
changes: FieldChange[];
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
/** One page of `listRevisions`, newest first. */
|
|
1270
|
+
declare interface RevisionList {
|
|
1271
|
+
revisions: Revision[];
|
|
1272
|
+
/** Empty on the last page. */
|
|
1273
|
+
nextPageToken: string;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
/**
|
|
1277
|
+
* The port a host fills with statushub (ADR 0020): the workspace's Change Set
|
|
1278
|
+
* statuses, for their display names and colours. contenthub-ui depends on no
|
|
1279
|
+
* statushub package. A host without statushub leaves the port empty, and the
|
|
1280
|
+
* screens then show the bare slug and offer no status picker.
|
|
1281
|
+
*/
|
|
1282
|
+
declare interface StatusSource {
|
|
1283
|
+
/** Every status of the workspace's `contenthub/change_set` catalogue, in its order. */
|
|
1284
|
+
listChangeSetStatuses(): Promise<ChangeSetStatusInfo[]>;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
export declare const STUB_NOW = "2026-10-01T09:00:00.000Z";
|
|
1288
|
+
|
|
1289
|
+
/** A second member of the stub workspace, to assign and filter by. */
|
|
1290
|
+
export declare const STUB_OTHER_USER_ID = "user_ben";
|
|
1291
|
+
|
|
1292
|
+
export declare const STUB_USER_ID = "user_stub";
|
|
1293
|
+
|
|
1294
|
+
export declare const STUB_WORKSPACE_ID = "ws_stub";
|
|
1295
|
+
|
|
1296
|
+
/** A blocker naming only what `fields` sets; every other id "", as on the wire. */
|
|
1297
|
+
export declare function stubBlocker(code: string, fields?: Partial<PublishBlocker>): PublishBlocker;
|
|
1298
|
+
|
|
1299
|
+
/** A legal publisher's Block Reasons, in the service's order (by name). */
|
|
1300
|
+
export declare function stubBlockReasons(): BlockReason[];
|
|
1301
|
+
|
|
1302
|
+
/** Their Releases, newest first per Blueprint. */
|
|
1303
|
+
export declare function stubBlueprintReleases(): BlueprintReleaseInfo[];
|
|
1304
|
+
|
|
1305
|
+
/**
|
|
1306
|
+
* The workspace's content Blueprints, as the `BlueprintSource` port answers,
|
|
1307
|
+
* by name. Commentary has had no Release cut yet.
|
|
1308
|
+
*/
|
|
1309
|
+
export declare function stubBlueprints(): BlueprintInfo[];
|
|
1310
|
+
|
|
1311
|
+
/**
|
|
1312
|
+
* A gazette's Change Sets: one open with two Chains (§ 1 amended twice, so
|
|
1313
|
+
* two Branches, and a paragraph born in it), one open with nothing in it yet,
|
|
1314
|
+
* and one published correction. Newest first, as the service lists them.
|
|
1315
|
+
*/
|
|
1316
|
+
export declare function stubChangeSets(): ChangeSet[];
|
|
1317
|
+
|
|
1318
|
+
/**
|
|
1319
|
+
* statushub's seed catalogue for `contenthub/change_set` (spec #56, story 9),
|
|
1320
|
+
* as the `StatusSource` port answers it. Colours are CSS names: statushub
|
|
1321
|
+
* holds whatever CSS colour an admin chose.
|
|
1322
|
+
*/
|
|
1323
|
+
export declare function stubChangeSetStatuses(): ChangeSetStatusInfo[];
|
|
1324
|
+
|
|
1325
|
+
/**
|
|
1326
|
+
* A legal publisher's Collection tree, by name as the service lists it:
|
|
1327
|
+
* Laws holding BGB and StGB, and Commentary beside it.
|
|
1328
|
+
*/
|
|
1329
|
+
export declare function stubCollections(): Collection[];
|
|
1330
|
+
|
|
1331
|
+
/** A merge an Update from Main would stop on (see `conflicts`). */
|
|
1332
|
+
export declare interface StubConflict {
|
|
1333
|
+
theirsRevisionId: string;
|
|
1334
|
+
fields: MergeField[];
|
|
1335
|
+
/** Every field but `fields`, merged. */
|
|
1336
|
+
merged: Record<string, unknown>;
|
|
1337
|
+
reason?: "conflict" | "invalid";
|
|
1338
|
+
/** Already stored on the Branch, as an earlier Update from Main left it. */
|
|
1339
|
+
pending?: boolean;
|
|
1340
|
+
}
|
|
1341
|
+
|
|
1342
|
+
/**
|
|
1343
|
+
* A Content of the stub workspace, every way the screens can read it. Not a
|
|
1344
|
+
* service type: it is what the stub keeps to answer its reads.
|
|
1345
|
+
*/
|
|
1346
|
+
export declare interface StubContent {
|
|
1347
|
+
id: string;
|
|
1348
|
+
blueprintId: string;
|
|
1349
|
+
blueprintReleaseId: string;
|
|
1350
|
+
/** The Collections it is filed in, directly. */
|
|
1351
|
+
collectionIds: string[];
|
|
1352
|
+
/** Who maintains it; none when absent. */
|
|
1353
|
+
assigneeIds?: string[];
|
|
1354
|
+
/** Its Block; absent while it is not blocked. */
|
|
1355
|
+
block?: ContentBlock;
|
|
1356
|
+
/** When it was archived, ISO 8601; absent while it is not Archived. */
|
|
1357
|
+
archiveTime?: string;
|
|
1358
|
+
/** Its Main head; absent while it was born in an open Change Set. */
|
|
1359
|
+
main?: StubHead;
|
|
1360
|
+
/** The Release In Force today, and the head it pins; absent for none. */
|
|
1361
|
+
inForce?: StubHead & {
|
|
1362
|
+
releaseId: string;
|
|
1363
|
+
};
|
|
1364
|
+
/** The head of its Chain's last Branch in each Change Set it is in, by Change Set id. */
|
|
1365
|
+
branches: Record<string, StubHead & {
|
|
1366
|
+
branchId: string;
|
|
1367
|
+
}>;
|
|
1368
|
+
/** Its Timeline as known now; none when absent. */
|
|
1369
|
+
timeline?: TimelineEntry[];
|
|
1370
|
+
/** What open (or since closed) Change Sets plan for it, in the order planned. */
|
|
1371
|
+
plannedReleases?: {
|
|
1372
|
+
changeSetId: string;
|
|
1373
|
+
plannedRelease: PlannedRelease;
|
|
1374
|
+
}[];
|
|
1375
|
+
/** Its Revisions, newest first, beyond what its heads imply; none when absent. */
|
|
1376
|
+
revisions?: (Revision & {
|
|
1377
|
+
data?: Record<string, unknown>;
|
|
1378
|
+
})[];
|
|
1379
|
+
/** The outgoing edges of its Revisions, each naming the Revision holding it. */
|
|
1380
|
+
edges?: Edge[];
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
export declare interface StubContenthubClientOptions {
|
|
1384
|
+
/** The workspace's Block Reasons to start from; the fixtures' by default. */
|
|
1385
|
+
blockReasons?: BlockReason[];
|
|
1386
|
+
/** The workspace's Change Sets to start from, newest first; the fixtures' by default. */
|
|
1387
|
+
changeSets?: ChangeSet[];
|
|
1388
|
+
/**
|
|
1389
|
+
* statushub's `contenthub/change_set` catalogue the stub checks status
|
|
1390
|
+
* moves against; the fixtures' by default.
|
|
1391
|
+
*/
|
|
1392
|
+
statuses?: ChangeSetStatusInfo[];
|
|
1393
|
+
/** The moves statushub allows, from slug to slugs; the fixtures' by default. */
|
|
1394
|
+
statusTransitions?: Record<string, string[]>;
|
|
1395
|
+
/** The workspace's Collections, by name; the fixtures' by default. */
|
|
1396
|
+
collections?: Collection[];
|
|
1397
|
+
/** The workspace's Content, every way it can be read; the fixtures' by default. */
|
|
1398
|
+
contents?: StubContent[];
|
|
1399
|
+
/**
|
|
1400
|
+
* The Blueprint Releases contenthub can load, which `createContent`
|
|
1401
|
+
* accepts; the fixtures' by default.
|
|
1402
|
+
*/
|
|
1403
|
+
blueprintReleases?: {
|
|
1404
|
+
id: string;
|
|
1405
|
+
blueprintId: string;
|
|
1406
|
+
}[];
|
|
1407
|
+
/** The Resolved Releases `getContent` answers with, by Blueprint Release id; the fixtures' by default. */
|
|
1408
|
+
resolvedReleases?: Record<string, ResolvedBlueprintRelease>;
|
|
1409
|
+
/**
|
|
1410
|
+
* The workspace's Required Checks; the fixtures' by default. The stub
|
|
1411
|
+
* reads `blueprintAccessors` as Blueprint ids, the one name its Content
|
|
1412
|
+
* carries.
|
|
1413
|
+
*/
|
|
1414
|
+
requiredChecks?: RequiredCheck[];
|
|
1415
|
+
/** Check Results recorded before, in the order they were recorded. */
|
|
1416
|
+
checkResults?: (CheckResult & {
|
|
1417
|
+
changeSetId: string;
|
|
1418
|
+
})[];
|
|
1419
|
+
/**
|
|
1420
|
+
* Blockers the stub can't derive itself (versionkit's and the Content
|
|
1421
|
+
* Graph's, such as covers_release or dangling_pin), by Change Set id:
|
|
1422
|
+
* `validatePublish` and `publish` report them beside the ones it does
|
|
1423
|
+
* derive (moved_head, the dependencies', outstanding_check).
|
|
1424
|
+
*/
|
|
1425
|
+
publishBlockers?: Record<string, PublishBlocker[]>;
|
|
1426
|
+
/** The Pending Merges `updateFromMain` leaves, by Change Set id; none by default. */
|
|
1427
|
+
pendingMerges?: Record<string, PendingMergeRef[]>;
|
|
1428
|
+
/**
|
|
1429
|
+
* What an Update from Main would meet on a Branch, by Branch id: the
|
|
1430
|
+
* fields it can't merge and the rest merged. `updateFromMain` stores it
|
|
1431
|
+
* on the Branch as a Pending Merge; `pending` stores it from the start.
|
|
1432
|
+
*/
|
|
1433
|
+
conflicts?: Record<string, StubConflict>;
|
|
1434
|
+
/**
|
|
1435
|
+
* contenthub's `authz.mode`: "guardian" by default. In "workspace" every
|
|
1436
|
+
* restriction and grant is refused, as contenthub refuses them, and
|
|
1437
|
+
* opening a Restricted Collection again is still allowed.
|
|
1438
|
+
*/
|
|
1439
|
+
authzMode?: "workspace" | "guardian";
|
|
1440
|
+
/** Grants on Restricted Collections, by Collection id, the owner's included. */
|
|
1441
|
+
collectionGrants?: Record<string, CollectionGrant[]>;
|
|
1442
|
+
/**
|
|
1443
|
+
* The Change Sets, by id, holding work the caller can't see (Restricted
|
|
1444
|
+
* Content, ADR 0017): `validatePublish`, `publish`, `discardChangeSet`
|
|
1445
|
+
* and an `updateFromMain` without `chainId` refuse them with
|
|
1446
|
+
* `WithheldWorkError`, as contenthub does.
|
|
1447
|
+
*/
|
|
1448
|
+
withheld?: string[];
|
|
1449
|
+
/**
|
|
1450
|
+
* Who records each Required Check, by check id; a check not named here,
|
|
1451
|
+
* and every new one, is recorded by every member. In guardian mode
|
|
1452
|
+
* `recordCheckResult` refuses a caller who is no recorder, as contenthub
|
|
1453
|
+
* does; in workspace mode every member records, and the recorder calls
|
|
1454
|
+
* are refused.
|
|
1455
|
+
*/
|
|
1456
|
+
recorders?: Record<string, RequiredCheckRecorders>;
|
|
1457
|
+
/** The workspace's members, whom a grant may name; the stub identity's two by default. */
|
|
1458
|
+
memberIds?: string[];
|
|
1459
|
+
/**
|
|
1460
|
+
* Whether the caller is a workspace admin, who manages every Restricted
|
|
1461
|
+
* Collection's grants; true by default. Otherwise only an owner does.
|
|
1462
|
+
*/
|
|
1463
|
+
admin?: boolean;
|
|
1464
|
+
/** Who the token names: the creator of a new Change Set. STUB_USER_ID by default. */
|
|
1465
|
+
userId?: string;
|
|
1466
|
+
/** The time every write stamps; STUB_NOW by default. */
|
|
1467
|
+
now?: () => string;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1470
|
+
/**
|
|
1471
|
+
* The Content behind the fixtures' Change Sets: § 1 BGB, amended in
|
|
1472
|
+
* BGBl. 2026 I Nr. 270; § 2 BGB; § 4a BGB, born in that Change Set; § 211
|
|
1473
|
+
* StGB; and a footnote filed nowhere, published but with no Release In Force
|
|
1474
|
+
* yet (dated to start next year).
|
|
1475
|
+
*/
|
|
1476
|
+
export declare function stubContents(): StubContent[];
|
|
1477
|
+
|
|
1478
|
+
/** One head of a Content: its Revision, data and when it was written. */
|
|
1479
|
+
export declare interface StubHead {
|
|
1480
|
+
revisionId: string;
|
|
1481
|
+
data: Record<string, unknown>;
|
|
1482
|
+
/** ISO 8601. */
|
|
1483
|
+
revisionCreateTime: string;
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1486
|
+
/** Who is looking, for anker's `TestHost` or `<HostProvider identity>`. */
|
|
1487
|
+
export declare function stubIdentity(): HostIdentity;
|
|
1488
|
+
|
|
1489
|
+
/**
|
|
1490
|
+
* § 3 BGB, repealed at the end of 2001: published, filed in BGB, with
|
|
1491
|
+
* nothing In Force today or later, so it may be archived. Not among
|
|
1492
|
+
* `stubContents()`, so the Library's fixtures stay as they are; pass it in
|
|
1493
|
+
* with `contents` to a stub that needs it.
|
|
1494
|
+
*/
|
|
1495
|
+
export declare function stubRepealedContent(): StubContent;
|
|
1496
|
+
|
|
1497
|
+
/**
|
|
1498
|
+
* A legal publisher's Required Checks, by name: a print round trip once per
|
|
1499
|
+
* Change Set, and a lawyer's review of each Branch, by someone who wrote
|
|
1500
|
+
* none of it. Both apply to every Blueprint.
|
|
1501
|
+
*/
|
|
1502
|
+
export declare function stubRequiredChecks(): RequiredCheck[];
|
|
1503
|
+
|
|
1504
|
+
/**
|
|
1505
|
+
* The Resolved Releases contenthub holds for the fixtures' Blueprint
|
|
1506
|
+
* Releases, by id, as `getContent` decodes them: a paragraph has a number
|
|
1507
|
+
* and a heading, a footnote a text. Both are Dated.
|
|
1508
|
+
*/
|
|
1509
|
+
export declare function stubResolvedReleases(): Record<string, ResolvedBlueprintRelease>;
|
|
1510
|
+
|
|
1511
|
+
/**
|
|
1512
|
+
* The moves the stub's statushub allows, from slug to slugs. Anything else is
|
|
1513
|
+
* refused with a reason, as statushub refuses it; a move away from an unknown
|
|
1514
|
+
* status is never checked (contenthub ADR 0014).
|
|
1515
|
+
*/
|
|
1516
|
+
export declare function stubStatusTransitions(): Record<string, string[]>;
|
|
1517
|
+
|
|
1518
|
+
/** One Release of a Content's Timeline (CONTEXT.md, Timeline), without its data. */
|
|
1519
|
+
declare interface TimelineEntry {
|
|
1520
|
+
/** Its place in the Timeline, from 1. */
|
|
1521
|
+
ordinal: number;
|
|
1522
|
+
releaseId: string;
|
|
1523
|
+
kind: ReleaseKind;
|
|
1524
|
+
revisionId: string;
|
|
1525
|
+
blueprintReleaseId: string;
|
|
1526
|
+
/** Absent for undated Content. */
|
|
1527
|
+
validityPeriod?: ValidityPeriod;
|
|
1528
|
+
/** ISO 8601. */
|
|
1529
|
+
publishTime: string;
|
|
1530
|
+
first: boolean;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
/** What Update from Main did to a Change Set. */
|
|
1534
|
+
declare interface UpdateFromMainOutcome {
|
|
1535
|
+
changeSet: ChangeSet;
|
|
1536
|
+
/** The Branches whose heads moved to a merge Revision. */
|
|
1537
|
+
mergedBranchIds: string[];
|
|
1538
|
+
/** The Branches this update left with a Pending Merge. */
|
|
1539
|
+
conflicted: PendingMergeRef[];
|
|
1540
|
+
/** Branches with a Pending Merge from before, which it left alone. */
|
|
1541
|
+
pending: PendingMergeRef[];
|
|
1542
|
+
/** Carry-forward links taken out of their Chains. */
|
|
1543
|
+
endedBranchIds: string[];
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
/**
|
|
1547
|
+
* The calendar days a Release of Dated Content is In Force, both included,
|
|
1548
|
+
* as YYYY-MM-DD; `lastDay` is "" for an open end.
|
|
1549
|
+
*/
|
|
1550
|
+
declare interface ValidityPeriod {
|
|
1551
|
+
firstDay: string;
|
|
1552
|
+
lastDay: string;
|
|
1553
|
+
}
|
|
1554
|
+
|
|
1555
|
+
export { }
|