@knkcs/contenthub-ui 0.4.0 → 0.6.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/dist/testing.d.ts CHANGED
@@ -21,15 +21,27 @@ declare interface BlueprintEditingOverride {
21
21
  editingMode: EditingMode | null;
22
22
  /** null follows the workspace's. */
23
23
  editingBlock: boolean | null;
24
+ /** The people beside the admins; null follows the workspace's, [] is the admins alone. */
25
+ forceGroup: string[] | null;
24
26
  /** What applies to the Blueprint's Content: this override over the workspace's. */
25
27
  effective: EditingSettings;
26
28
  }
27
29
 
28
- /** A content Blueprint, as the `BlueprintSource` port names it. */
30
+ /** A Blueprint, as the `BlueprintSource` port names it. */
29
31
  declare interface BlueprintInfo {
30
32
  id: string;
31
33
  /** What editors call it. */
32
34
  name: string;
35
+ /**
36
+ * Its accessor, unique in the workspace for good: what workspace
37
+ * configuration names it by (ADR 0023).
38
+ */
39
+ accessor: string;
40
+ /**
41
+ * Whether it is archived. Search never offers an archived Blueprint;
42
+ * naming one by id or accessor does, marked. Absent means not archived.
43
+ */
44
+ archived?: boolean;
33
45
  }
34
46
 
35
47
  /** One page of `BlueprintSource.searchBlueprints`. */
@@ -57,8 +69,8 @@ declare interface BlueprintReleaseInfo {
57
69
  }
58
70
 
59
71
  /**
60
- * The workspace's content Blueprints and their Releases, for New Content and
61
- * the Library's Blueprint filter. contenthub serves them itself
72
+ * The workspace's content Blueprints and their Releases, for New Content, the
73
+ * Library's Blueprint filter and the configuration that names Blueprints. contenthub serves them itself
62
74
  * (`BlueprintCatalogService`, #238): blueprinthub is its direct dependency,
63
75
  * not a port a host fills (ADR 0020 as amended), so every screen builds this
64
76
  * from its `ContenthubClient` unless a host passes its own, which only tests
@@ -66,16 +78,24 @@ declare interface BlueprintReleaseInfo {
66
78
  */
67
79
  declare interface BlueprintSource {
68
80
  /**
69
- * Unarchived content Blueprints whose name holds `query` (every one for
70
- * ""), by name. `signal` aborts a search the user has moved on from.
81
+ * Unarchived content Blueprints with a Release whose name holds `query`
82
+ * (every one for ""), by name; with `includeWithoutRelease`, those
83
+ * without a Release too. `signal` aborts a search the user has moved on
84
+ * from.
71
85
  */
72
86
  searchBlueprints(input: {
73
87
  query: string;
74
88
  pageToken?: string;
89
+ includeWithoutRelease?: boolean;
75
90
  signal?: AbortSignal;
76
91
  }): Promise<BlueprintPage>;
77
92
  /** The Blueprints of these ids, archived ones too; an unknown id is left out. */
78
93
  getBlueprints(ids: string[]): Promise<BlueprintInfo[]>;
94
+ /**
95
+ * The Blueprints of these accessors, archived ones too; an accessor of no
96
+ * Blueprint is left out.
97
+ */
98
+ getBlueprintsByAccessor(accessors: string[]): Promise<BlueprintInfo[]>;
79
99
  /** Every Release of a Blueprint, newest first; empty while none has been cut. */
80
100
  listReleases(blueprintId: string): Promise<BlueprintReleaseInfo[]>;
81
101
  }
@@ -83,6 +103,13 @@ declare interface BlueprintSource {
83
103
  /** What a Branch is for: one an editor works on, or a Carry-forward link. */
84
104
  declare type BranchKind = "editorial" | "carry_forward";
85
105
 
106
+ /** Whether a Direct Edit's change carries forward into one later wording (#270). */
107
+ declare interface CarryForwardAnswer {
108
+ /** The later wording: the Release a Carry-forward link carries. */
109
+ releaseId: string;
110
+ carry: boolean;
111
+ }
112
+
86
113
  /** What a Chain on Dated Content, effective on a date, would be and meet (PreviewChain). */
87
114
  declare interface ChainPreview {
88
115
  /** The Release it would fork from; "" in a gap. */
@@ -328,6 +355,8 @@ declare interface ContentAttributes {
328
355
  block?: ContentBlock;
329
356
  /** When it was archived, ISO 8601; absent while it is not Archived. */
330
357
  archiveTime?: string;
358
+ /** Its Editing Block; absent while no open Direct Edit holds one. */
359
+ editingBlock?: EditingBlock;
331
360
  }
332
361
 
333
362
  /**
@@ -552,11 +581,18 @@ declare interface ContenthubClient {
552
581
  listRequiredChecks(): Promise<RequiredCheck[]>;
553
582
  /**
554
583
  * Declares a Required Check; it gates every open Change Set at once.
555
- * Rejects with `NameTakenError` when another check has the name, and
556
- * `InvalidInputError` for anything else the service refuses.
584
+ * Rejects with `NameTakenError` when another check has the name,
585
+ * `BlueprintAccessorsRefusedError` for accessors naming no content
586
+ * Blueprint taking new work, `ServiceUnavailableError` while they can't
587
+ * be checked, and `InvalidInputError` for anything else the service
588
+ * refuses.
557
589
  */
558
590
  createRequiredCheck(input: RequiredCheckInput): Promise<RequiredCheck>;
559
- /** Replaces every field of a Required Check; its id stays. Rejects as create does. */
591
+ /**
592
+ * Replaces every field of a Required Check; its id stays. Rejects as
593
+ * create does, checking only the accessors it adds: one the check names
594
+ * already passes whatever its Blueprint's state now.
595
+ */
560
596
  updateRequiredCheck(input: RequiredCheckInput & {
561
597
  id: string;
562
598
  }): Promise<RequiredCheck>;
@@ -619,12 +655,17 @@ declare interface ContenthubClient {
619
655
  /**
620
656
  * Replaces one Blueprint's override; admin only. A null field follows the
621
657
  * workspace's, and at least one must be set. Rejects as
622
- * `setEditingSettings` does.
658
+ * `setEditingSettings` does, and adding an override with
659
+ * `BlueprintAccessorsRefusedError` for an accessor naming no content
660
+ * Blueprint taking new work, `ServiceUnavailableError` while it can't be
661
+ * checked.
623
662
  */
624
663
  setBlueprintEditingOverride(input: {
625
664
  blueprintAccessor: string;
626
665
  editingMode: EditingMode | null;
627
666
  editingBlock: boolean | null;
667
+ /** null follows the workspace's; [] is the admins alone. */
668
+ forceGroup: string[] | null;
628
669
  }): Promise<BlueprintEditingOverride>;
629
670
  /** Removes one Blueprint's override, so it follows the workspace's; admin only. */
630
671
  deleteBlueprintEditingOverride(input: {
@@ -731,12 +772,16 @@ declare interface ContenthubClient {
731
772
  /**
732
773
  * A page of the workspace's content Blueprints Content can be made from:
733
774
  * not archived, with at least one Release, whose accessor or name holds
734
- * `query`. contenthub asks blueprinthub as the caller (#238). Rejects
735
- * with `ServiceUnavailableError` while blueprinthub gives no answer.
775
+ * `query`. With `includeWithoutRelease`, those without a Release too, for
776
+ * configuration that names a Blueprint before its first Release (ADR
777
+ * 0023); never an archived one. contenthub asks blueprinthub as the
778
+ * caller (#238). Rejects with `ServiceUnavailableError` while blueprinthub
779
+ * gives no answer.
736
780
  */
737
781
  searchBlueprints(input: {
738
782
  query: string;
739
783
  pageToken?: string;
784
+ includeWithoutRelease?: boolean;
740
785
  signal?: AbortSignal;
741
786
  }): Promise<BlueprintPage>;
742
787
  /**
@@ -754,6 +799,14 @@ declare interface ContenthubClient {
754
799
  * `ServiceUnavailableError` while blueprinthub gives no answer.
755
800
  */
756
801
  getBlueprints(ids: string[]): Promise<BlueprintInfo[]>;
802
+ /**
803
+ * Names the Blueprints of these accessors, as workspace configuration
804
+ * names them (ADR 0023): archived ones and ones without a Release
805
+ * included. An accessor of no Blueprint, or of one of another workspace,
806
+ * is left out. At most `MAX_BLUEPRINT_IDS`. Rejects with
807
+ * `ServiceUnavailableError` while blueprinthub gives no answer.
808
+ */
809
+ getBlueprintsByAccessor(accessors: string[]): Promise<BlueprintInfo[]>;
757
810
  /**
758
811
  * Creates a Content in an open Change Set, pinning a Blueprint Release,
759
812
  * with empty data: its one Chain has one Branch, opened in the Branch
@@ -889,11 +942,20 @@ declare interface ContenthubClient {
889
942
  * or answers the one the caller has open on it, with `reopened`. Answers
890
943
  * the Direct Edit and the Content as read on its Branch. Rejects with
891
944
  * `EditingModeRefusedError` where the Editing Mode is "Change Sets only",
892
- * `DirectEditRefusedError` where the Content is Dated, `ContentBlockedError`, `ContentArchivedError`,
893
- * and `InvalidInputError` for anything else the service refuses.
945
+ * `DirectEditRefusedError` where another editor's Direct Edit holds its
946
+ * Editing Block (naming them), `ContentBlockedError`, `ContentArchivedError`,
947
+ * and `InvalidInputError` for anything else the service refuses (a day
948
+ * for undated Content among it).
894
949
  */
895
950
  openDirectEdit(input: {
896
951
  contentId: string;
952
+ /**
953
+ * Dated Content only (#270): the day the change takes effect, as
954
+ * YYYY-MM-DD; absent is today. Its Branch forks from the Release In
955
+ * Force that day: on today it corrects that Release, on a later day
956
+ * it is a new wording.
957
+ */
958
+ effectiveOn?: string;
897
959
  /** Makes a retry safe (CONTEXT.md, Idempotency Key). */
898
960
  idempotencyKey?: string;
899
961
  }): Promise<{
@@ -901,17 +963,63 @@ declare interface ContenthubClient {
901
963
  content: Content;
902
964
  reopened: boolean;
903
965
  }>;
966
+ /**
967
+ * What a Direct Edit's Publish of Dated Content would plan (#270): its
968
+ * Release's Validity Period with `validityLastDay` as Publish takes it,
969
+ * the Release it corrects, the date-only Releases contenthub derives and
970
+ * the later wordings Publish asks about. Writes nothing. Rejects with
971
+ * `CoversReleaseError` (`changeSetRequired`) when the period would cover
972
+ * a Release entirely.
973
+ */
974
+ previewDirectEditPublish(input: {
975
+ id: string;
976
+ validityLastDay?: string;
977
+ }): Promise<DirectEditPublishPreview>;
904
978
  /**
905
979
  * Publishes a Direct Edit at `expectedHeadId`, the head of its Branch the
906
- * editor saw: one Release, In Force from its Publish. Rejects as
907
- * `publish` does, and with `DirectEditRefusedError` for a Change Set that
908
- * is not a Direct Edit.
980
+ * editor saw: one Release, In Force from its Publish, carrying
981
+ * `releaseSpec`. Rejects as `publish` does, with `ContentRefusedError`
982
+ * for Release Spec values the Blueprint Release refuses (a required one
983
+ * missing among them), and with `DirectEditRefusedError` for a Change
984
+ * Set that is not a Direct Edit. On Dated Content (#270) it takes the
985
+ * Validity Period's last day and one carry-forward answer per later
986
+ * wording, and rejects with `CoversReleaseError` (`changeSetRequired`)
987
+ * when the period would cover a Release entirely.
909
988
  */
910
989
  publishDirectEdit(input: {
911
990
  id: string;
912
991
  expectedHeadId: string;
992
+ /** The Release's Release Spec values; absent is none. */
993
+ releaseSpec?: Record<string, unknown>;
994
+ /** Dated Content: the period's last day, "" for an open end; absent keeps the default. */
995
+ validityLastDay?: string;
996
+ /** Dated Content: whether the change carries into each later wording. */
997
+ carryForward?: CarryForwardAnswer[];
913
998
  idempotencyKey?: string;
914
999
  }): Promise<PublishOutcome>;
1000
+ /**
1001
+ * Saves on a Direct Edit's Branch on top of `expectedHeadId`, as
1002
+ * `saveRevision` does, and publishes the Revision saved, as
1003
+ * `publishDirectEdit` does, in one request (ADR 0022). Refused as a
1004
+ * whole, with nothing saved: rejects as either does (`StaleHeadError`,
1005
+ * `ContentRefusedError` for the data or the Release Spec values,
1006
+ * `PublishRefusedError` with every blocker).
1007
+ */
1008
+ saveAndPublishDirectEdit(input: {
1009
+ id: string;
1010
+ expectedHeadId: string;
1011
+ data: Record<string, unknown>;
1012
+ /** Top-level field accessors; absent saves `data` as the whole Revision. */
1013
+ fieldMask?: string[];
1014
+ releaseSpec?: Record<string, unknown>;
1015
+ /** As `publishDirectEdit`'s. */
1016
+ validityLastDay?: string;
1017
+ carryForward?: CarryForwardAnswer[];
1018
+ idempotencyKey?: string;
1019
+ }): Promise<{
1020
+ content: Content;
1021
+ outcome: PublishOutcome;
1022
+ }>;
915
1023
  /**
916
1024
  * Discards a Direct Edit: its work is dropped, Main and the Releases stay.
917
1025
  * Rejects as `discardChangeSet` does, and with `DirectEditRefusedError`
@@ -921,6 +1029,23 @@ declare interface ContenthubClient {
921
1029
  id: string;
922
1030
  idempotencyKey?: string;
923
1031
  }): Promise<ChangeSet>;
1032
+ /**
1033
+ * Forces an Editing Block (ADR 0022): hands the Direct Edit `id` holding
1034
+ * it, with its work and its Editing Block, to the caller. Answers it with
1035
+ * the caller as its editor, the Content as read on its Branch, and who
1036
+ * edited it until now. Rejects with `AccessDeniedError` outside the
1037
+ * Force Group, `DirectEditRefusedError` where the caller has a Direct
1038
+ * Edit of the Content of their own or it holds no Editing Block any more,
1039
+ * and as `discardDirectEdit` does otherwise.
1040
+ */
1041
+ forceDirectEdit(input: {
1042
+ id: string;
1043
+ idempotencyKey?: string;
1044
+ }): Promise<{
1045
+ changeSet: ChangeSet;
1046
+ content: Content;
1047
+ previousEditorId: string;
1048
+ }>;
924
1049
  startEditing(input: {
925
1050
  contentId: string;
926
1051
  changeSetId?: string;
@@ -1081,6 +1206,21 @@ export declare function createStubContenthubClient(options?: StubContenthubClien
1081
1206
 
1082
1207
  export declare function createStubStatusSource(statuses?: ChangeSetStatusInfo[]): StatusSource;
1083
1208
 
1209
+ /**
1210
+ * What a Direct Edit's Publish of Dated Content would plan (#270), for its
1211
+ * Publish dialog: nothing of it is written.
1212
+ */
1213
+ declare interface DirectEditPublishPreview {
1214
+ /** Its Release's Validity Period; an empty last day is an open end. */
1215
+ validityPeriod?: ValidityPeriod;
1216
+ /** The Release it corrects and Supersedes; "" for a new wording. */
1217
+ correctsReleaseId: string;
1218
+ /** The date-only Releases contenthub derives, read-only. */
1219
+ dateOnlyReleases: PlannedRelease[];
1220
+ /** The later wordings Publish asks about, by first day. */
1221
+ laterWordings: LaterWording[];
1222
+ }
1223
+
1084
1224
  /** One edge of one Revision. */
1085
1225
  declare interface Edge {
1086
1226
  sourceContentId: string;
@@ -1099,6 +1239,21 @@ declare interface Edge {
1099
1239
  /** What kind of edge of the Content Graph (ADR 0009). */
1100
1240
  declare type EdgeKind = "reference" | "toc" | "include" | "exclude" | "replace" | "annotate" | "link" | "footnote" | "anchor" | "media" | "blueprint" | "unspecified";
1101
1241
 
1242
+ /**
1243
+ * The Block a Direct Edit sets on its Content (CONTEXT.md, Editing Block):
1244
+ * "being edited by" its editor. It keeps out only other editors' Direct
1245
+ * Edits, ends with its Direct Edit's Publish or Discard, and can't be
1246
+ * lifted. It is independent of `block`: a Content can hold both.
1247
+ */
1248
+ declare interface EditingBlock {
1249
+ /** The Direct Edit's editor, an odon user id. */
1250
+ editorId: string;
1251
+ /** The Direct Edit holding it. */
1252
+ changeSetId: string;
1253
+ /** ISO 8601. */
1254
+ blockTime: string;
1255
+ }
1256
+
1102
1257
  /**
1103
1258
  * Which ways of changing a Blueprint's Content the workspace offers (ADR
1104
1259
  * 0022, CONTEXT.md Editing Mode): Direct Edits only, Change Sets only, or
@@ -1112,6 +1267,12 @@ declare interface EditingSettings {
1112
1267
  editingMode: EditingMode;
1113
1268
  /** Whether opening a Direct Edit sets an Editing Block on its Content. */
1114
1269
  editingBlock: boolean;
1270
+ /**
1271
+ * The Force Group: who may force an Editing Block (ADR 0022). The
1272
+ * workspace's admins always may; these are the people beside them, by
1273
+ * odon user id, sorted. Empty is the admins alone.
1274
+ */
1275
+ forceGroup: string[];
1115
1276
  }
1116
1277
 
1117
1278
  /** The editing settings in effect for one Blueprint, and which its override decides. */
@@ -1119,6 +1280,13 @@ declare interface EffectiveEditingSettings {
1119
1280
  effective: EditingSettings;
1120
1281
  editingModeOverridden: boolean;
1121
1282
  editingBlockOverridden: boolean;
1283
+ forceGroupOverridden: boolean;
1284
+ /**
1285
+ * Whether the caller is in the effective Force Group: an admin, or named
1286
+ * by it. It is how a screen knows to offer Force (#269); the service
1287
+ * asks the same when it is used.
1288
+ */
1289
+ callerInForceGroup: boolean;
1122
1290
  }
1123
1291
 
1124
1292
  /** One field that differs between two Revisions. */
@@ -1147,6 +1315,12 @@ declare interface GapReferrer {
1147
1315
  releaseId: string;
1148
1316
  }
1149
1317
 
1318
+ /** A later wording a Direct Edit's change may carry into (#270). */
1319
+ declare interface LaterWording {
1320
+ releaseId: string;
1321
+ validityPeriod?: ValidityPeriod;
1322
+ }
1323
+
1150
1324
  /** One field a merge resolution must decide, with each side's value. */
1151
1325
  declare interface MergeField {
1152
1326
  /** "/" and the field's accessor, as a Violation spells it. */
@@ -1376,8 +1550,18 @@ declare interface RequiredCheck {
1376
1550
  declare interface RequiredCheckInput {
1377
1551
  name: string;
1378
1552
  scope: CheckScope;
1379
- /** Blueprint accessors; empty for every Blueprint. */
1553
+ /**
1554
+ * Blueprint accessors, empty exactly when `everyBlueprint` is set. Each
1555
+ * one the write adds must name a content Blueprint of the workspace that
1556
+ * is not archived (ADR 0023).
1557
+ */
1380
1558
  blueprintAccessors: string[];
1559
+ /**
1560
+ * Applies the check to every Blueprint. A switch of its own: no accessors
1561
+ * without it is refused, so clearing the last Blueprint never widens a
1562
+ * check to every Publish.
1563
+ */
1564
+ everyBlueprint: boolean;
1381
1565
  independent: boolean;
1382
1566
  }
1383
1567
 
@@ -1552,6 +1736,8 @@ export declare interface StubContent {
1552
1736
  assigneeIds?: string[];
1553
1737
  /** Its Block; absent while it is not blocked. */
1554
1738
  block?: ContentBlock;
1739
+ /** Its Editing Block; absent while no open Direct Edit holds one. */
1740
+ editingBlock?: EditingBlock;
1555
1741
  /** When it was archived, ISO 8601; absent while it is not Archived. */
1556
1742
  archiveTime?: string;
1557
1743
  /** Its Main head; absent while it was born in an open Change Set. */
@@ -1596,13 +1782,13 @@ export declare interface StubContenthubClientOptions {
1596
1782
  /** The workspace's Content, every way it can be read; the fixtures' by default. */
1597
1783
  contents?: StubContent[];
1598
1784
  /**
1599
- * The workspace's content Blueprints, as `getBlueprints` names them;
1600
- * the fixtures' by default. `searchBlueprints` lists those Content can
1601
- * be made from: not `archived`, with a Release.
1785
+ * The workspace's content Blueprints, as `getBlueprints` and
1786
+ * `getBlueprintsByAccessor` name them; the fixtures' by default.
1787
+ * `searchBlueprints` lists those Content can be made from: not
1788
+ * `archived`, with a Release — or, with `includeWithoutRelease`, any not
1789
+ * `archived`.
1602
1790
  */
1603
- blueprints?: (BlueprintInfo & {
1604
- archived?: boolean;
1605
- })[];
1791
+ blueprints?: BlueprintInfo[];
1606
1792
  /**
1607
1793
  * The Blueprint Releases, newest first per Blueprint, as
1608
1794
  * `listBlueprintReleases` lists them; the fixtures' by default.
@@ -1613,9 +1799,9 @@ export declare interface StubContenthubClientOptions {
1613
1799
  /** The Resolved Releases `getContent` answers with, by Blueprint Release id; the fixtures' by default. */
1614
1800
  resolvedReleases?: Record<string, ResolvedBlueprintRelease>;
1615
1801
  /**
1616
- * The workspace's Required Checks; the fixtures' by default. The stub
1617
- * reads `blueprintAccessors` as Blueprint ids, the one name its Content
1618
- * carries.
1802
+ * The workspace's Required Checks; the fixtures' by default. A check
1803
+ * covers a Content whose Blueprint (in `blueprints`) has one of its
1804
+ * `blueprintAccessors`.
1619
1805
  */
1620
1806
  requiredChecks?: RequiredCheck[];
1621
1807
  /** Check Results recorded before, in the order they were recorded. */
@@ -1629,6 +1815,13 @@ export declare interface StubContenthubClientOptions {
1629
1815
  * derive (moved_head, the dependencies', outstanding_check).
1630
1816
  */
1631
1817
  publishBlockers?: Record<string, PublishBlocker[]>;
1818
+ /**
1819
+ * The Branches behind their base, by id, as a Change Set published past
1820
+ * them leaves them (#268): `validatePublish` and `publish` report
1821
+ * behind_base for each until `updateFromMain` merges it or a resolution
1822
+ * of its Pending Merge does. An aborted merge leaves it behind.
1823
+ */
1824
+ behind?: string[];
1632
1825
  /** The Pending Merges `updateFromMain` leaves, by Change Set id; none by default. */
1633
1826
  pendingMerges?: Record<string, PendingMergeRef[]>;
1634
1827
  /**
@@ -1673,9 +1866,12 @@ export declare interface StubContenthubClientOptions {
1673
1866
  now?: () => string;
1674
1867
  /**
1675
1868
  * The workspace's own editing settings; "Change Sets only" without an
1676
- * Editing Block by default, as for a workspace that never set them.
1869
+ * Editing Block by default, as for a workspace that never set them. A
1870
+ * Force Group left out is the admins alone.
1677
1871
  */
1678
- editingSettings?: EditingSettings;
1872
+ editingSettings?: Omit<EditingSettings, "forceGroup"> & {
1873
+ forceGroup?: string[];
1874
+ };
1679
1875
  /** The per-Blueprint overrides of the editing settings; none by default. */
1680
1876
  editingOverrides?: StubEditingOverride[];
1681
1877
  }
@@ -1693,6 +1889,8 @@ export declare interface StubEditingOverride {
1693
1889
  blueprintAccessor: string;
1694
1890
  editingMode: EditingMode | null;
1695
1891
  editingBlock: boolean | null;
1892
+ /** The people beside the admins; null follows the workspace's. Absent is null. */
1893
+ forceGroup?: string[] | null;
1696
1894
  }
1697
1895
 
1698
1896
  /** One head of a Content: its Revision, data and when it was written. */