initiative-plugin-sdk 7.1.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.
- package/README.md +385 -51
- package/dist/build.d.ts +1 -1
- package/dist/build.js +32 -22
- package/dist/build.js.map +1 -1
- package/dist/client.d.ts +17 -6
- package/dist/client.js +12 -8
- package/dist/client.js.map +1 -1
- package/dist/contract.d.ts +452 -80
- package/dist/contract.js +22 -6
- package/dist/contract.js.map +1 -1
- package/dist/define.d.ts +78 -31
- package/dist/define.js +27 -9
- package/dist/define.js.map +1 -1
- package/dist/manifest.d.ts +1 -1
- package/dist/manifest.js.map +1 -1
- package/dist/plugin-api.generated.d.ts +97 -5
- package/dist/plugin-api.generated.js +15 -2
- package/dist/plugin-api.generated.js.map +1 -1
- package/dist/server.d.ts +1 -0
- package/dist/server.js +21 -5
- package/dist/server.js.map +1 -1
- package/dist/statements.d.ts +111 -0
- package/dist/statements.js +205 -0
- package/dist/statements.js.map +1 -0
- package/dist/testing.d.ts +132 -21
- package/dist/testing.js +273 -51
- package/dist/testing.js.map +1 -1
- package/dist/validate.d.ts +13 -4
- package/dist/validate.js +240 -48
- package/dist/validate.js.map +1 -1
- package/manifest.contract.json +514 -23
- package/package.json +1 -1
- package/schemas/plugin-api.json +462 -33
- package/schemas/plugin-manifest.json +553 -22
package/dist/contract.d.ts
CHANGED
|
@@ -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:
|
|
603
|
-
*
|
|
604
|
-
*
|
|
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
|
-
*
|
|
664
|
-
*
|
|
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.
|
|
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
|
|
685
|
-
*
|
|
686
|
-
*
|
|
687
|
-
* plug-in
|
|
688
|
-
*
|
|
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
|
-
*
|
|
853
|
-
*
|
|
854
|
-
*
|
|
855
|
-
*
|
|
856
|
-
* the plug-in.
|
|
857
|
-
*
|
|
858
|
-
*
|
|
859
|
-
*
|
|
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
|
|
1018
|
-
* menu
|
|
1019
|
-
*
|
|
1020
|
-
*
|
|
1021
|
-
*
|
|
1022
|
-
*
|
|
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
|
-
*
|
|
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
|
-
|
|
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;
|
|
1125
|
-
*
|
|
1126
|
-
*
|
|
1127
|
-
*
|
|
1128
|
-
*
|
|
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:
|
|
1184
|
-
*
|
|
1185
|
-
*
|
|
1186
|
-
*
|
|
1187
|
-
*
|
|
1188
|
-
*
|
|
1189
|
-
|
|
1190
|
-
|
|
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
|
-
*
|
|
1370
|
-
*
|
|
1371
|
-
*
|
|
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
|
|
1715
|
+
emit?: NamespacedId;
|
|
1382
1716
|
/**
|
|
1383
1717
|
* The event's payload: an object of that endpoint's declared returns.
|
|
1384
1718
|
*/
|
|
1385
|
-
map
|
|
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
|
|
1409
|
-
* events Initiative runs itself from the requests and
|
|
1410
|
-
* written here
|
|
1411
|
-
* the
|
|
1412
|
-
*
|
|
1413
|
-
*
|
|
1414
|
-
*
|
|
1415
|
-
*
|
|
1416
|
-
*
|
|
1417
|
-
*
|
|
1418
|
-
*
|
|
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
|
|
1422
|
-
*
|
|
1423
|
-
* and
|
|
1424
|
-
*
|
|
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
|
|
1447
|
-
*
|
|
1448
|
-
*
|
|
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
|
|
1496
|
-
*
|
|
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
|
|
1519
|
-
*
|
|
1520
|
-
*
|
|
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.
|
|
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
|
|
1531
|
-
*
|
|
1532
|
-
*
|
|
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
|
}
|