initiative-plugin-sdk 7.2.0 → 8.0.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.
@@ -54,6 +54,10 @@ export type FieldKind = "text" | "number" | "date" | "datetime" | "link" | "badg
54
54
  export declare const FIELD_KINDS: readonly FieldKind[];
55
55
  export type Tone = "accent" | "positive" | "negative" | "warning" | "neutral" | "muted";
56
56
  export declare const TONES: readonly Tone[];
57
+ export type SettingType = "string";
58
+ export declare const SETTING_TYPES: readonly SettingType[];
59
+ export type SettingAssignment = "community_name";
60
+ export declare const SETTING_ASSIGNMENTS: readonly SettingAssignment[];
57
61
  export type ListingKind = "plugin" | "dashboard";
58
62
  export declare const LISTING_KINDS: readonly ListingKind[];
59
63
  export type HttpMethod = "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
@@ -91,6 +95,8 @@ export declare const CAPS: {
91
95
  readonly actions: 16;
92
96
  readonly partNodes: 50;
93
97
  readonly partDepth: 4;
98
+ readonly facetsPerField: 4;
99
+ readonly valuesPerFacet: 12;
94
100
  readonly metadataKeyLength: 64;
95
101
  readonly metadataValueBytes: 8192;
96
102
  readonly metadataLookupLength: 255;
@@ -98,7 +104,11 @@ export declare const CAPS: {
98
104
  readonly metadataBytesPerObject: 65536;
99
105
  readonly installMetadataKeys: 256;
100
106
  readonly installMetadataBytes: 1048576;
107
+ readonly writeTargets: 100;
101
108
  readonly partsPlacedPerItem: 3;
109
+ readonly settings: 16;
110
+ readonly uniqueSettingValueLength: 16;
111
+ readonly helpLength: 2000;
102
112
  readonly bundledDashboards: 8;
103
113
  readonly dashboardWidgets: 50;
104
114
  readonly dashboardGridColumns: 12;
@@ -167,6 +177,7 @@ export declare const CHARSETS: {
167
177
  readonly artwork: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/._-";
168
178
  readonly queryName: "-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~";
169
179
  readonly metadataKey: "._0123456789abcdefghijklmnopqrstuvwxyz";
180
+ readonly uniqueSettingValue: "0123456789abcdefghijklmnopqrstuvwxyz";
170
181
  };
171
182
  /**
172
183
  * Every field the contract declares, by the object that owns it.
@@ -186,15 +197,17 @@ export declare const FIELDS: {
186
197
  readonly endpointReturn: readonly ["key", "type", "label", "list", "of"];
187
198
  readonly connection: readonly ["id", "scope", "label", "fields", "flow", "token", "access_hint", "health"];
188
199
  readonly connectionFlow: readonly ["type", "authorize_url", "token_url", "client_id", "client_secret", "scopes", "pkce", "authorize_params", "install_url", "after_connect", "revoke", "revoke_url"];
189
- readonly connectionToken: readonly ["type", "exchange_url", "iss", "key", "alg", "lifetime"];
200
+ readonly connectionToken: readonly ["type", "exchange_url", "exchange_body", "iss", "key", "alg", "lifetime"];
190
201
  readonly webhooks: readonly ["verify", "dedup", "route", "events", "status"];
191
202
  readonly webhookVerify: readonly ["scheme", "header", "prefix", "encoding", "secret"];
192
203
  readonly webhookRoute: readonly ["path", "header", "connection", "field"];
193
- readonly schedule: readonly ["id", "every"];
204
+ readonly schedule: readonly ["id", "every", "endpoint", "params", "write"];
194
205
  readonly endpoint: readonly ["id", "label", "description", "returns", "group", "needs_subject", "direction", "params", "actors", "admin_only", "public", "requires", "cache_ttl_seconds", "identity", "unavailable", "request", "steps", "map", "errors"];
195
206
  readonly widget: readonly ["id", "meta", "module_source", "endpoints", "sample_data", "requires"];
196
207
  readonly page: readonly ["id", "path", "name", "scopes", "admin_only", "capabilities", "requires"];
197
- readonly field: readonly ["key", "name", "kind", "on", "description", "tone", "requires"];
208
+ readonly field: readonly ["key", "name", "kind", "list", "on", "description", "tone", "states", "actions", "requires"];
209
+ readonly stateFacet: readonly ["name", "values"];
210
+ readonly stateValue: readonly ["label", "tone"];
198
211
  readonly sectionNode: readonly ["type", "props", "children"];
199
212
  readonly stackNode: readonly ["type", "props", "children"];
200
213
  readonly fieldNode: readonly ["type", "props"];
@@ -202,13 +215,18 @@ export declare const FIELDS: {
202
215
  readonly textNode: readonly ["type", "props"];
203
216
  readonly buttonNode: readonly ["type", "props"];
204
217
  readonly part: readonly ["id", "name", "on", "tree", "description", "requires"];
205
- readonly action: readonly ["id", "name", "endpoint", "on", "confirm", "menu", "requires"];
218
+ readonly action: readonly ["id", "name", "endpoint", "params", "write", "on", "confirm", "menu", "admin_only", "requires"];
219
+ readonly change: readonly ["set", "upsert", "remove"];
220
+ readonly targetedChange: readonly ["target", "set", "upsert", "remove"];
221
+ readonly listElement: readonly ["ref", "value", "url", "text", "tone", "max", "state"];
222
+ readonly setting: readonly ["key", "type", "label", "description", "unique", "assigned"];
206
223
  readonly bundledDashboard: readonly ["uid", "public_id", "name", "description", "layout", "widgets"];
207
224
  readonly bundledDashboardWidget: readonly ["id", "type", "title", "grid", "binding"];
208
225
  readonly endpointIdentity: readonly ["kind", "key"];
209
226
  readonly vendorAuth: readonly ["header", "prefix"];
210
227
  readonly vendorRequest: readonly ["method", "url", "query", "headers", "body", "graphql", "connection", "paging"];
211
228
  readonly graphqlRequest: readonly ["query", "variables"];
229
+ readonly actorConnections: readonly ["member", "installation"];
212
230
  readonly requestStep: readonly ["name", "request"];
213
231
  readonly pageNumberPaging: readonly ["kind", "page_param", "per_page_param", "per_page", "items", "max_pages", "on_limit"];
214
232
  readonly linkHeaderPaging: readonly ["kind", "items", "max_pages", "on_limit"];
@@ -217,9 +235,9 @@ export declare const FIELDS: {
217
235
  readonly afterConnect: readonly ["request", "steps", "map", "refuse_when", "code"];
218
236
  readonly connectionHealth: readonly ["request", "every", "states"];
219
237
  readonly healthState: readonly ["status", "when", "state"];
220
- readonly webhookEvent: readonly ["when", "emit", "map"];
238
+ readonly webhookEvent: readonly ["when", "emit", "map", "write"];
221
239
  readonly webhookStatus: readonly ["when", "connection", "state"];
222
- readonly manifest: readonly ["plugin_kind", "service", "features", "default_name", "minimum_age", "min_plugin_api", "hosts", "auth", "vendor", "connections", "webhooks", "schedules", "endpoints", "community_summary", "widgets", "pages", "dashboards", "fields", "parts", "actions"];
240
+ readonly manifest: readonly ["plugin_kind", "service", "features", "default_name", "minimum_age", "min_plugin_api", "hosts", "auth", "scopes", "vendor", "connections", "webhooks", "schedules", "endpoints", "community_summary", "widgets", "pages", "dashboards", "fields", "parts", "actions", "settings", "help"];
223
241
  };
224
242
  export type Identifier = string;
225
243
  /**
@@ -564,6 +582,18 @@ export interface ConnectionToken {
564
582
  * '{<key>}'.
565
583
  */
566
584
  exchange_url: string;
585
+ /**
586
+ * A JSON body posted with the signed JWT, such as the narrower permissions a
587
+ * token is asked for. Absent: none. A string anywhere in it may name a vendor
588
+ * value as '{vendor.<key>}' and one of this connection's own fields as
589
+ * '{<key>}'. Or an expression answering the body, which reads only
590
+ * 'connection': this connection's own non-secret fields by key, its managed
591
+ * values included, as 'after_connect' stored them. A body that names a vendor
592
+ * value is written as an object. An answer that is not an object fails the
593
+ * token request, so the connection cannot be used until the expression
594
+ * answers one.
595
+ */
596
+ exchange_body?: Record<string, unknown> | Expression;
567
597
  /**
568
598
  * The JWT's issuer, normally '{vendor.app_id}'. May name a vendor value as
569
599
  * '{vendor.<key>}' and one of this connection's own fields as '{<key>}'.
@@ -599,9 +629,10 @@ export interface Webhooks {
599
629
  dedup: string;
600
630
  route: WebhookRoute;
601
631
  /**
602
- * Declarative plug-ins: how a delivery becomes one of this plug-in's events.
603
- * The first row whose 'when' holds emits; a delivery no row matches is
604
- * dropped.
632
+ * Declarative plug-ins: what a delivery does: emit one of this plug-in's
633
+ * events, change the plug-in's values, or both. The first row whose 'when'
634
+ * holds applies, its 'emit' and its 'write' both; a delivery no row matches
635
+ * is dropped.
605
636
  */
606
637
  events?: WebhookEvent[];
607
638
  /**
@@ -660,12 +691,18 @@ export interface WebhookRoute {
660
691
  field: Identifier;
661
692
  }
662
693
  /**
663
- * An interval at which Initiative calls the plug-in's schedule hook, once for
664
- * each community that installed it, with when the call last succeeded there.
694
+ * Something Initiative runs on an interval, once for each community that
695
+ * installed the plug-in, with when it last succeeded there as 'since'. A
696
+ * container plug-in's schedule calls its schedule hook, and names nothing more.
697
+ * A declarative plug-in's makes one of its read endpoints' calls as the
698
+ * installation and changes the plug-in's values from the answer: it names the
699
+ * 'endpoint' and the 'write', and 'params' when the endpoint takes any.
665
700
  */
666
701
  export interface Schedule {
667
702
  /**
668
- * Unique within the manifest. The hook is told which schedule is due by it.
703
+ * Unique within the manifest. A container's hook is told which schedule is
704
+ * due by it. A declarative plug-in's differs from every connection's id:
705
+ * Initiative keys connection health checks by connection id.
669
706
  */
670
707
  id: Identifier;
671
708
  /**
@@ -673,6 +710,27 @@ export interface Schedule {
673
710
  * minutes and at most 1440 minutes.
674
711
  */
675
712
  every: string;
713
+ /**
714
+ * Declarative plug-ins: a read endpoint this manifest declares, whose
715
+ * 'actors' include 'installation': no person is present when a schedule runs.
716
+ */
717
+ endpoint?: NamespacedId;
718
+ /**
719
+ * Declarative plug-ins: the endpoint's params, as one expression answering an
720
+ * object. It reads 'since', when the schedule last succeeded in the community
721
+ * (ISO 8601), or null the first time; 'now'; 'connection', the non-secret
722
+ * fields of the connection the endpoint's first request names; 'settings' and
723
+ * 'aliases'. Absent: none.
724
+ */
725
+ params?: Expression;
726
+ /**
727
+ * Declarative plug-ins: the changes Initiative makes to the plug-in's values
728
+ * from the endpoint's answer, as the install: a list of at most 100 targeted
729
+ * changes ('targetedChange'). It reads 'result', the endpoint's mapped
730
+ * answer, 'since', 'now', 'settings' and 'aliases'. Answering nothing changes
731
+ * nothing.
732
+ */
733
+ write?: Expression;
676
734
  }
677
735
  /**
678
736
  * Namespaced under the plug-in's own service id — 'plugin.<public_id>.<name>'.
@@ -681,11 +739,12 @@ export interface Schedule {
681
739
  export type NamespacedId = string;
682
740
  /**
683
741
  * 'plugins:<public_id>': permission to call another plug-in's public endpoints
684
- * through the deployment, as this community or as one of its members. Not one
685
- * of the fixed scopes: the family is open, one per plug-in, and the public id
686
- * after the prefix is the plug-in being called. The deployment never lets a
687
- * plug-in address another directly; the call goes through it, and the plug-in
688
- * called is handed its own references for whoever the call is for.
742
+ * through the deployment, as this community or as one of its members, and to
743
+ * read the values that plug-in shows on items this one can read. Not one of the
744
+ * fixed scopes: the family is open, one per plug-in, and the public id after
745
+ * the prefix is the plug-in being called. The deployment never lets a plug-in
746
+ * address another directly; the call goes through it, and the plug-in called is
747
+ * handed its own references for whoever the call is for.
689
748
  */
690
749
  export type PluginScope = `plugins:${string}`;
691
750
  export interface Endpoint {
@@ -849,14 +908,17 @@ export interface Page {
849
908
  export type MetadataKey = string;
850
909
  /**
851
910
  * How one of the plug-in's metadata keys is shown on Initiative's items. The
852
- * plug-in keeps the value in Initiative, through its installation token;
853
- * Initiative draws it with its own component for `kind` and computes its plain
854
- * text itself, so a field filters, sorts and exports with no call to the
855
- * plug-in. Which views show it is chosen by the community's managers, never by
856
- * the plug-in. Initiative holds what is kept, and these caps are enforced there
857
- * rather than here: a value of at most 8192 bytes as JSON, with a string of at
858
- * most 255 characters to be found by; at most 32 keys and 65536 bytes on one
859
- * item, and 256 keys and 1048576 bytes on the install.
911
+ * value is kept in Initiative: a container plug-in writes it with its
912
+ * installation token, and for a declarative plug-in Initiative writes it from
913
+ * the plug-in's expressions. Initiative draws it with its own component for
914
+ * `kind` and computes its plain text itself, so a field filters, sorts and
915
+ * exports with no call to the plug-in. Which views show it is chosen by the
916
+ * community's managers, never by the plug-in. Initiative holds what is kept,
917
+ * and these caps are enforced there rather than here: a value of at most 8192
918
+ * bytes as JSON, with a string of at most 255 characters to be found by, and
919
+ * each element of a list a value of its own, found by its 'ref'; at most 32
920
+ * keys and 65536 bytes on one item, and 256 keys and 1048576 bytes on the
921
+ * install.
860
922
  */
861
923
  export interface Field {
862
924
  /**
@@ -875,6 +937,14 @@ export interface Field {
875
937
  * max}; 'checkbox' a boolean.
876
938
  */
877
939
  kind: FieldKind;
940
+ /**
941
+ * Several values rather than one: the value is a list of elements, each one
942
+ * value of 'kind' with a 'ref' that tells it from the others ('listElement').
943
+ * A change gives the whole list in 'set', or adds, replaces and removes
944
+ * elements by 'ref' with 'upsert' and 'remove'. Absent: one value, which a
945
+ * change sets.
946
+ */
947
+ list?: boolean;
878
948
  /**
879
949
  * The item kinds it is offered on.
880
950
  */
@@ -887,8 +957,46 @@ export interface Field {
887
957
  * A badge's tone when its value names none.
888
958
  */
889
959
  tone?: Tone;
960
+ /**
961
+ * What state the value is in, as facets by id, at most 4, each with keys of
962
+ * its own. The value names a key of each facet it is in as 'state',
963
+ * {"<facet>": "<key>"}, and Initiative draws each as a badge, labelled in the
964
+ * reader's language. A list element, and a link, badge or progress value,
965
+ * carries 'state' beside its other properties; a text, number, date, datetime
966
+ * or checkbox value that carries one is written as an element is, without the
967
+ * 'ref': {"value": …, "state": …}.
968
+ */
969
+ states?: Record<string, StateFacet>;
970
+ /**
971
+ * Declarative plug-ins, on a list field: actions offered on each of its
972
+ * elements, by id, each one offered on every item kind this field is. An
973
+ * action run from an element reads that element's 'ref' as 'element'.
974
+ */
975
+ actions?: Identifier[];
890
976
  requires?: Requires;
891
977
  }
978
+ /**
979
+ * One facet of a field's state, such as whether a piece of work is open or what
980
+ * review it has: its name, and the keys a value may name.
981
+ */
982
+ export interface StateFacet {
983
+ /**
984
+ * What the facet is called.
985
+ */
986
+ name: LocalizedText;
987
+ /**
988
+ * The keys a value may name, at most 12, each with its badge's words and
989
+ * tone.
990
+ */
991
+ values: Record<string, StateValue>;
992
+ }
993
+ /**
994
+ * One key of a state facet, as its badge shows it.
995
+ */
996
+ export interface StateValue {
997
+ label: LocalizedText;
998
+ tone?: Tone;
999
+ }
892
1000
  /**
893
1001
  * One node of a part: one of Initiative's own components, told apart by 'type',
894
1002
  * with its props and, for a section or a stack, the nodes inside it.
@@ -964,6 +1072,11 @@ export interface ValueNode {
964
1072
  export interface TextNode {
965
1073
  type: "text";
966
1074
  props: {
1075
+ /**
1076
+ * May name '{item.id}', the item's id, and '{settings.<key>}', one of this
1077
+ * plug-in's settings, which Initiative fills in when it draws the part. Any
1078
+ * other '{…}' is refused.
1079
+ */
967
1080
  text: LocalizedText;
968
1081
  tone?: Tone;
969
1082
  };
@@ -1014,12 +1127,19 @@ export interface Part {
1014
1127
  requires?: Requires;
1015
1128
  }
1016
1129
  /**
1017
- * Something a reader runs on one item, from a part's button or the item's own
1018
- * menu. Initiative only connects: it calls the write endpoint as the
1019
- * installation, with the reader as 'viewer' and the item as 'subject' in the
1020
- * call's token, and the endpoint does the work, usually writing the plug-in's
1021
- * metadata. Initiative then answers the reader with the item's metadata as it
1022
- * stands.
1130
+ * Something a reader runs on one item, from a part's button, the item's own
1131
+ * menu, or an element of a list field that offers it. Initiative first asks the
1132
+ * reader for the 'params' the action names, when it names any. For a container
1133
+ * plug-in, Initiative only connects: it calls the write endpoint as the
1134
+ * installation, with those parameters, the reader as 'viewer' and the item as
1135
+ * 'subject' in the call's token, and the endpoint does the work, usually
1136
+ * writing the plug-in's metadata. For a declarative plug-in, Initiative does
1137
+ * the work: it makes the endpoint's call, when the action names one, with those
1138
+ * parameters, on the credential its 'actors' say, its expressions reading the
1139
+ * item as 'item' and the element it was run from, if any, as 'element'; then it
1140
+ * makes the change 'write' answers, when the action has one, to the plug-in's
1141
+ * values on the item, as the install. Either way Initiative then answers the
1142
+ * reader with the item's metadata as it stands.
1023
1143
  */
1024
1144
  export interface Action {
1025
1145
  /**
@@ -1031,9 +1151,30 @@ export interface Action {
1031
1151
  */
1032
1152
  name: LocalizedText;
1033
1153
  /**
1034
- * A write endpoint this manifest declares.
1154
+ * An endpoint this manifest declares. A container plug-in's action names a
1155
+ * write, which its handler answers. A declarative plug-in's names a read or a
1156
+ * write, a 'write' expression, or both: a read fetches what the 'write'
1157
+ * keeps, a write changes something at the vendor.
1158
+ */
1159
+ endpoint?: NamespacedId;
1160
+ /**
1161
+ * Parameters of the action's endpoint, by key, that Initiative asks the
1162
+ * reader for before it runs the action, in a form drawn from the endpoint's
1163
+ * own declarations of them: each one's type and label, and its 'options' or
1164
+ * 'options_from'. The endpoint is sent these and nothing else, so every
1165
+ * parameter it requires is among them.
1166
+ */
1167
+ params?: Identifier[];
1168
+ /**
1169
+ * Declarative plug-ins: the change Initiative makes to the plug-in's values
1170
+ * on the action's item, as the install: one change ('change'). It reads
1171
+ * 'item', the item ({kind, id, title}); 'held', this install's values on it,
1172
+ * by key; 'result', the endpoint's mapped answer, absent when the action
1173
+ * names no endpoint; 'params', what the reader answered; 'element', the 'ref'
1174
+ * of the list element it was run from, absent when it was not; 'settings',
1175
+ * 'aliases' and 'now'. Answering nothing changes nothing.
1035
1176
  */
1036
- endpoint: NamespacedId;
1177
+ write?: Expression;
1037
1178
  /**
1038
1179
  * The item kinds it is offered on.
1039
1180
  */
@@ -1046,8 +1187,171 @@ export interface Action {
1046
1187
  * Also offered in the item's own menu.
1047
1188
  */
1048
1189
  menu?: boolean;
1190
+ /**
1191
+ * Only the community's admins run this action, whatever roles a placement
1192
+ * allows. Who else may run it is chosen in the community, per initiative and
1193
+ * per role, not declared here.
1194
+ */
1195
+ admin_only?: boolean;
1049
1196
  requires?: Requires;
1050
1197
  }
1198
+ /**
1199
+ * A change to the plug-in's values on one item or on its install, as a
1200
+ * declarative plug-in's 'write' answers it. 'set' writes values by key, as a
1201
+ * container's client.metadata.set does; 'upsert' and 'remove' change a list
1202
+ * field's elements by their 'ref'. A change gives at least one of the three,
1203
+ * and changes each key with only one. Initiative makes it as the install, and
1204
+ * holds what is kept to the caps a field's description gives.
1205
+ */
1206
+ export interface Change {
1207
+ /**
1208
+ * Values by metadata key, each any JSON value of at most 8192 bytes; a null
1209
+ * removes its key. A list field's value is its whole list of elements, each
1210
+ * held to that cap.
1211
+ */
1212
+ set?: Record<string, unknown>;
1213
+ /**
1214
+ * Elements by metadata key ('listElement'): each is added to that key's list,
1215
+ * or merged into the element there with its 'ref': the properties it gives
1216
+ * replace that element's, the ones it leaves out stay, and its 'state' merges
1217
+ * the same way by facet. So a write that knows one fact about an element
1218
+ * changes that fact alone.
1219
+ */
1220
+ upsert?: Record<string, ListElement[]>;
1221
+ /**
1222
+ * Refs by metadata key: the element with each is taken from that key's list.
1223
+ * A ref the list does not hold changes nothing.
1224
+ */
1225
+ remove?: Record<string, ElementRef[]>;
1226
+ }
1227
+ /**
1228
+ * A change and where Initiative makes it. A webhook event's or a schedule's
1229
+ * 'write' answers a list of at most 100, and cannot read what their targets
1230
+ * hold.
1231
+ */
1232
+ export interface TargetedChange {
1233
+ target: ChangeTarget;
1234
+ /**
1235
+ * As a change's: values by metadata key, a null removing its key.
1236
+ */
1237
+ set?: Record<string, unknown>;
1238
+ /**
1239
+ * As a change's: elements by metadata key, each added to its list or merged
1240
+ * into the one with its 'ref', property by property and its 'state' facet by
1241
+ * facet.
1242
+ */
1243
+ upsert?: Record<string, ListElement[]>;
1244
+ /**
1245
+ * As a change's: refs by metadata key, each element with one taken from its
1246
+ * list.
1247
+ */
1248
+ remove?: Record<string, ElementRef[]>;
1249
+ }
1250
+ /**
1251
+ * Where a change is made: {kind, id}, one item; {install: true}, the install
1252
+ * itself; or {holding: {key, value}}, every item on which this install holds
1253
+ * 'value' under 'key', as a container's client.metadata.find finds them.
1254
+ * Initiative keeps each element of a list as a value of its own, so 'holding'
1255
+ * reaches an element by its 'ref'. A target the install cannot read is skipped.
1256
+ */
1257
+ export type ChangeTarget = {
1258
+ kind: ItemKind;
1259
+ id: number;
1260
+ } | {
1261
+ install: true;
1262
+ } | {
1263
+ holding: {
1264
+ key: MetadataKey;
1265
+ /**
1266
+ * A value is found by its text: a string as it is, a number or a boolean as
1267
+ * JSON writes it; a list element by its 'ref'.
1268
+ */
1269
+ value: string;
1270
+ };
1271
+ };
1272
+ /**
1273
+ * One element of a list field's value: one value of the field's 'kind', with a
1274
+ * 'ref' that tells it from the list's others. A text, number, date, datetime or
1275
+ * checkbox element holds its value in 'value'; a link element is {ref, url,
1276
+ * text?}, a badge element {ref, text, tone?} and a progress element {ref,
1277
+ * value, max}. Initiative keeps each element as a value of its own, of at most
1278
+ * 8192 bytes as JSON. An 'upsert' may give only some of an element's
1279
+ * properties: they are merged into the element with its 'ref'.
1280
+ */
1281
+ export interface ListElement {
1282
+ ref: ElementRef;
1283
+ /**
1284
+ * A text, number, date, datetime or checkbox element's value, or a progress
1285
+ * element's figure.
1286
+ */
1287
+ value?: string | number | boolean;
1288
+ /**
1289
+ * A link element's address.
1290
+ */
1291
+ url?: string;
1292
+ /**
1293
+ * A link element's words, or a badge element's.
1294
+ */
1295
+ text?: string;
1296
+ /**
1297
+ * A badge element's tone.
1298
+ */
1299
+ tone?: Tone;
1300
+ /**
1301
+ * A progress element's whole.
1302
+ */
1303
+ max?: number;
1304
+ /**
1305
+ * A key of each of the field's state facets this element is in, by facet id.
1306
+ */
1307
+ state?: Record<string, Identifier>;
1308
+ }
1309
+ /**
1310
+ * What tells a list's element from the others, such as the vendor's own id for
1311
+ * what it shows: unique in its list, and how a change replaces or removes the
1312
+ * element and a 'holding' target finds it.
1313
+ */
1314
+ export type ElementRef = string;
1315
+ /**
1316
+ * A value the community's admins see and may change on the install, which the
1317
+ * plug-in's expressions read as 'settings.<key>' and its parts' text names as
1318
+ * '{settings.<key>}'.
1319
+ */
1320
+ export interface Setting {
1321
+ /**
1322
+ * Unique among this manifest's settings.
1323
+ */
1324
+ key: Identifier;
1325
+ /**
1326
+ * What the value is: 'string', a line of text.
1327
+ */
1328
+ type: SettingType;
1329
+ label: LocalizedText;
1330
+ /**
1331
+ * A line under the label.
1332
+ */
1333
+ description?: LocalizedText;
1334
+ /**
1335
+ * No two communities on a deployment hold the same value for this plug-in,
1336
+ * and the value is a 'uniqueSettingValue'. An admin who renames it keeps the
1337
+ * earlier values, which no other community may take and the plug-in's
1338
+ * expressions read as 'aliases.<key>'.
1339
+ */
1340
+ unique?: boolean;
1341
+ /**
1342
+ * A unique setting's only: Initiative gives it a value when the community
1343
+ * installs the plug-in, which an admin may rename. 'community_name': the
1344
+ * letters and digits of the community's name, in lowercase, with a short
1345
+ * random suffix when another community holds that value.
1346
+ */
1347
+ assigned?: SettingAssignment;
1348
+ }
1349
+ /**
1350
+ * A unique setting's value: a lowercase letter, then lowercase letters and
1351
+ * digits, two to 16 characters in all. It holds no '-', so a reference such as
1352
+ * '<value>-<number>' reads one way.
1353
+ */
1354
+ export type UniqueSettingValue = string;
1051
1355
  export interface BundledDashboard {
1052
1356
  /**
1053
1357
  * This dashboard's own catalog id — publisher-assigned, immutable, never
@@ -1121,11 +1425,16 @@ export interface EndpointIdentity {
1121
1425
  * fields of the connection the request names; 'connections', on an endpoint's
1122
1426
  * requests and map, each connection its 'requires' names that the call has, by
1123
1427
  * its id, holding the same fields; 'now', the time of the call in ISO 8601,
1124
- * which $now() and $millis() also answer; and 'steps', each earlier step's
1125
- * answer by its name. On the way back it also holds 'response', the answer
1126
- * being read: {status, headers, body}, with header names in lowercase. Each
1127
- * evaluation is bounded: at most 1000 milliseconds, 500 levels of nesting and
1128
- * an answer of 1048576 bytes as JSON. An expression that fails or passes a
1428
+ * which $now() and $millis() also answer; 'steps', each earlier step's answer
1429
+ * by its name; and, on the call an action makes, 'item', the item it runs on:
1430
+ * {kind, id, title}, and 'element', the 'ref' of the list element it was run
1431
+ * from, if it was. On the way back it also holds 'response', the answer being
1432
+ * read: {status, headers, body}, with header names in lowercase. Every
1433
+ * expression of a declarative plug-in also reads 'settings', the install's
1434
+ * settings by key, and 'aliases', each unique setting's earlier values by key,
1435
+ * as a list, except a token's 'exchange_body', which reads only its connection.
1436
+ * Each evaluation is bounded: at most 1000 milliseconds, 500 levels of nesting
1437
+ * and an answer of 1048576 bytes as JSON. An expression that fails or passes a
1129
1438
  * bound answers 'unavailable: mapping-failed'.
1130
1439
  */
1131
1440
  export type Expression = string;
@@ -1180,14 +1489,18 @@ export interface VendorRequest {
1180
1489
  body?: Expression;
1181
1490
  graphql?: GraphqlRequest;
1182
1491
  /**
1183
- * Which connection's credential the request carries: a static connection's is
1184
- * the community's, an interactive one's the acting member's. A call made as a
1185
- * member carries a static connection's credential only when the endpoint's
1186
- * 'requires' names that connection, and is refused otherwise. Required on an
1187
- * endpoint's requests. Absent on 'after_connect' and 'health', which carry
1188
- * the credential of the connection they belong to.
1189
- */
1190
- connection?: Identifier;
1492
+ * Which connection's credential the request carries: one connection for every
1493
+ * call, or, on a write endpoint's requests, one per actor
1494
+ * ('actorConnections'), so a call made as the member carries the member's own
1495
+ * credential and one made as the installation the community's. A static
1496
+ * connection's credential is the community's, an interactive one's the acting
1497
+ * member's, which a call made as the installation does not have. A call made
1498
+ * as a member carries a static connection's credential only when the
1499
+ * endpoint's 'requires' names that connection, and is refused otherwise.
1500
+ * Required on an endpoint's requests. Absent on 'after_connect' and 'health',
1501
+ * which carry the credential of the connection they belong to.
1502
+ */
1503
+ connection?: Identifier | ActorConnections;
1191
1504
  paging?: Paging;
1192
1505
  }
1193
1506
  /**
@@ -1203,6 +1516,25 @@ export interface GraphqlRequest {
1203
1516
  */
1204
1517
  variables?: Expression;
1205
1518
  }
1519
+ /**
1520
+ * One connection per actor, on a write endpoint's requests: a call carries the
1521
+ * credential of the connection named for the actor it is made as. Names exactly
1522
+ * the actors the endpoint's 'actors' declare. The member's connection need not
1523
+ * be named in 'requires': a call made as the member requires the connection its
1524
+ * requests name for the member.
1525
+ */
1526
+ export interface ActorConnections {
1527
+ /**
1528
+ * An interactive connection, which a call made as the member carries: the
1529
+ * member's own account.
1530
+ */
1531
+ member?: Identifier;
1532
+ /**
1533
+ * A static connection, which a call made as the installation carries: the
1534
+ * community's own.
1535
+ */
1536
+ installation?: Identifier;
1537
+ }
1206
1538
  export interface RequestStep {
1207
1539
  /**
1208
1540
  * Unique among its steps. Later steps, the map and the predicates beside it
@@ -1366,9 +1698,11 @@ export interface HealthState {
1366
1698
  state: ConnectionState;
1367
1699
  }
1368
1700
  /**
1369
- * One way a delivery becomes an event. Its expressions read 'headers' (names in
1370
- * lowercase), 'payload' (the parsed body), 'connection' (the routed
1371
- * connection's non-secret fields) and 'now'.
1701
+ * What one kind of delivery does: emit an event, change the plug-in's values,
1702
+ * or both. It gives 'emit', 'write' or both, and 'map' exactly when it gives
1703
+ * 'emit'. Its expressions read 'headers' (names in lowercase), 'payload' (the
1704
+ * parsed body), 'connection' (the routed connection's non-secret fields),
1705
+ * 'now', 'settings' and 'aliases'.
1372
1706
  */
1373
1707
  export interface WebhookEvent {
1374
1708
  /**
@@ -1378,11 +1712,17 @@ export interface WebhookEvent {
1378
1712
  /**
1379
1713
  * An emit endpoint this manifest declares.
1380
1714
  */
1381
- emit: NamespacedId;
1715
+ emit?: NamespacedId;
1382
1716
  /**
1383
1717
  * The event's payload: an object of that endpoint's declared returns.
1384
1718
  */
1385
- map: Expression;
1719
+ map?: Expression;
1720
+ /**
1721
+ * The changes Initiative makes to the plug-in's values, as the install: a
1722
+ * list of at most 100 targeted changes ('targetedChange'). Answering nothing
1723
+ * changes nothing.
1724
+ */
1725
+ write?: Expression;
1386
1726
  }
1387
1727
  /**
1388
1728
  * A delivery that says what state a connection is in, read as an event's
@@ -1405,23 +1745,26 @@ export interface WebhookStatus {
1405
1745
  /**
1406
1746
  * What a plug-in declares it can do. A plug-in is a container, which names its
1407
1747
  * `service` and answers Initiative's calls, or declarative, which names its
1408
- * `hosts` and no service, and whose endpoints, connection checks and webhook
1409
- * events Initiative runs itself from the requests and JSONata expressions
1410
- * written here; one plug-in is never both. This is the 'definition' field of
1411
- * the document served at /.well-known/initiative-plugin.json, NOT that whole
1412
- * document: a registrar also requires protocol_version, public_id and kind
1413
- * alongside it, and refuses a definition served bare. Generated from the
1414
- * platform's own validator vocabulary. A manifest that satisfies this schema is
1415
- * well-formed, not necessarily acceptable. Cross-references (the endpoint a
1416
- * widget binds, a requires term's connection, an endpoint's service prefix),
1417
- * the direction-specific rules on an endpoint, the features/blocks cross-check
1418
- * in both directions, UTF-8 byte-size caps, the rules tying a connection's flow
1748
+ * `hosts` and no service, and whose endpoints, connection checks, webhook
1749
+ * events, schedules and actions Initiative runs itself from the requests and
1750
+ * JSONata expressions written here, keeping the values they write on items; one
1751
+ * plug-in is never both. This is the 'definition' field of the document served
1752
+ * at /.well-known/initiative-plugin.json, NOT that whole document: a registrar
1753
+ * also requires protocol_version, public_id and kind alongside it, and refuses
1754
+ * a definition served bare. Generated from the platform's own validator
1755
+ * vocabulary. A manifest that satisfies this schema is well-formed, not
1756
+ * necessarily acceptable. Cross-references (the endpoint a widget binds, a
1757
+ * requires term's connection, an endpoint's service prefix), the
1758
+ * direction-specific rules on an endpoint, the features/blocks cross-check in
1759
+ * both directions, UTF-8 byte-size caps, the rules tying a connection's flow
1419
1760
  * and token to its scope and fields, what a webhooks block names, what a vendor
1420
1761
  * setup writes to, whether every expression parses, what a declarative request
1421
- * and its steps name, the bounds and unique ids of schedules, the unique keys
1422
- * and ids of fields, parts and actions, what a part's nodes and an action name,
1423
- * and a part's size and depth are enforced by the platform on publish and are
1424
- * not expressible here.
1762
+ * and its steps name, the bounds, ids and endpoints of schedules, which terms
1763
+ * each kind's schedules, actions, fields and webhook events take, the unique
1764
+ * keys and ids of fields, parts, actions and settings, what a part's nodes, a
1765
+ * field's element actions and an action's endpoint and params name, the
1766
+ * placeholders in a part's text, and a part's size and depth are enforced by
1767
+ * the platform on publish and are not expressible here.
1425
1768
  */
1426
1769
  export interface Manifest {
1427
1770
  /**
@@ -1443,12 +1786,20 @@ export interface Manifest {
1443
1786
  /**
1444
1787
  * The scopes this plug-in asks a community to grant: what its installation
1445
1788
  * and member tokens act with. The fixed scopes, and 'plugins:<public_id>'
1446
- * for each plug-in this one calls (at most 24 of those). The community
1447
- * grants some or all of them when it installs the plug-in, and a token
1448
- * never carries more than was granted. Writing implies reading. Absent
1449
- * means none.
1789
+ * for each plug-in this one uses, to call its public endpoints and read the
1790
+ * values it shows on items (at most 24 of those). The community grants some
1791
+ * or all of them when it installs the plug-in, and a token never carries
1792
+ * more than was granted. Writing implies reading. Absent means none.
1450
1793
  */
1451
1794
  scopes?: Array<Scope | PluginScope>;
1795
+ /**
1796
+ * This plug-in may act through any plug-in the community lets it use, not
1797
+ * only those its scopes name as 'plugins:<public_id>'. When a community
1798
+ * installs another plug-in, it is asked there whether this one may use it,
1799
+ * which grants 'plugins:<public_id>' for it. Absent: only the plug-ins its
1800
+ * scopes name.
1801
+ */
1802
+ calls_plugins?: boolean;
1452
1803
  };
1453
1804
  /**
1454
1805
  * What this plug-in contributes. Cross-checked against the blocks present in
@@ -1488,12 +1839,21 @@ export interface Manifest {
1488
1839
  * Declarative plug-ins only.
1489
1840
  */
1490
1841
  auth?: VendorAuth;
1842
+ /**
1843
+ * Declarative plug-ins: the scopes this plug-in asks a community to grant,
1844
+ * all of them read scopes ('<resource>:read'). A declarative plug-in keeps
1845
+ * its own values on items it can read and does not call Initiative, and
1846
+ * Initiative keeps them only on items these scopes read. A container plug-in
1847
+ * declares its scopes in its service block.
1848
+ */
1849
+ scopes?: Array<Scope | PluginScope>;
1491
1850
  vendor?: Vendor;
1492
1851
  connections?: Connection[];
1493
1852
  webhooks?: Webhooks;
1494
1853
  /**
1495
- * What Initiative calls the plug-in's schedule hook for, and how often. At
1496
- * most 8.
1854
+ * What Initiative runs on an interval for each community: a container
1855
+ * plug-in's schedule hook, or a declarative plug-in's read and the values it
1856
+ * writes from the answer. At most 8.
1497
1857
  */
1498
1858
  schedules?: Schedule[];
1499
1859
  endpoints?: Endpoint[];
@@ -1515,21 +1875,33 @@ export interface Manifest {
1515
1875
  */
1516
1876
  dashboards?: BundledDashboard[];
1517
1877
  /**
1518
- * How the plug-in's metadata is shown on items. A container plug-in's only: a
1519
- * declarative plug-in holds no installation token, so it keeps no metadata to
1520
- * show.
1878
+ * How the plug-in's values on items are shown there. Any plug-in may keep
1879
+ * values on items: a container writes them with its installation token, and
1880
+ * for a declarative plug-in Initiative writes them from the plug-in's
1881
+ * expressions.
1521
1882
  */
1522
1883
  fields?: Field[];
1523
1884
  /**
1524
1885
  * Pieces of items' pages and views, built from Initiative's components and
1525
- * bound to the plug-in's fields and actions. A container plug-in's only, as
1526
- * fields are.
1886
+ * bound to the plug-in's fields and actions.
1527
1887
  */
1528
1888
  parts?: Part[];
1529
1889
  /**
1530
- * What a reader may run on an item, each one of the plug-in's write
1531
- * endpoints. A container plug-in's only: a declarative plug-in has no handler
1532
- * to do an action's work.
1890
+ * What a reader may run on an item: a container plug-in's write endpoints,
1891
+ * which its handlers answer, or a declarative plug-in's calls and changes to
1892
+ * its values, which Initiative makes.
1533
1893
  */
1534
1894
  actions?: Action[];
1895
+ /**
1896
+ * Values the community's admins set on the install, which the plug-in's
1897
+ * expressions and its parts' text read. At most 16.
1898
+ */
1899
+ settings?: Setting[];
1900
+ /**
1901
+ * Help with the plug-in, keyed by language tag: markdown of at most 2000
1902
+ * characters in each language. Initiative shows it behind a '?' on the
1903
+ * headers of the plug-in's parts and on its settings, in the reader's
1904
+ * language, or failing that in any.
1905
+ */
1906
+ help?: Record<string, string>;
1535
1907
  }