@openbrf/plugin-sdk 0.0.0-stage → 1.2.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/LICENSE +661 -0
- package/LICENSE-EXCEPTION.md +28 -0
- package/README.md +94 -2
- package/dist/abort-signal.d.ts +23 -0
- package/dist/abort-signal.d.ts.map +1 -0
- package/dist/abort-signal.js +2 -0
- package/dist/abort-signal.js.map +1 -0
- package/dist/action-refusal.d.ts +101 -0
- package/dist/action-refusal.d.ts.map +1 -0
- package/dist/action-refusal.js +96 -0
- package/dist/action-refusal.js.map +1 -0
- package/dist/action-schema.d.ts +42 -0
- package/dist/action-schema.d.ts.map +1 -0
- package/dist/action-schema.js +67 -0
- package/dist/action-schema.js.map +1 -0
- package/dist/actions.d.ts +287 -0
- package/dist/actions.d.ts.map +1 -0
- package/dist/actions.js +68 -0
- package/dist/actions.js.map +1 -0
- package/dist/api-version.d.ts +23 -0
- package/dist/api-version.d.ts.map +1 -0
- package/dist/api-version.js +27 -0
- package/dist/api-version.js.map +1 -0
- package/dist/blocks.d.ts +310 -0
- package/dist/blocks.d.ts.map +1 -0
- package/dist/blocks.js +185 -0
- package/dist/blocks.js.map +1 -0
- package/dist/catalog.d.ts +707 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +567 -0
- package/dist/catalog.js.map +1 -0
- package/dist/define-plugin.d.ts +14 -0
- package/dist/define-plugin.d.ts.map +1 -0
- package/dist/define-plugin.js +15 -0
- package/dist/define-plugin.js.map +1 -0
- package/dist/entitlements.d.ts +117 -0
- package/dist/entitlements.d.ts.map +1 -0
- package/dist/entitlements.js +62 -0
- package/dist/entitlements.js.map +1 -0
- package/dist/extensions.d.ts +183 -0
- package/dist/extensions.d.ts.map +1 -0
- package/dist/extensions.js +67 -0
- package/dist/extensions.js.map +1 -0
- package/dist/finances.d.ts +294 -0
- package/dist/finances.d.ts.map +1 -0
- package/dist/finances.js +56 -0
- package/dist/finances.js.map +1 -0
- package/dist/findings.d.ts +156 -0
- package/dist/findings.d.ts.map +1 -0
- package/dist/findings.js +146 -0
- package/dist/findings.js.map +1 -0
- package/dist/host.d.ts +827 -0
- package/dist/host.d.ts.map +1 -0
- package/dist/host.js +80 -0
- package/dist/host.js.map +1 -0
- package/dist/imports.d.ts +104 -0
- package/dist/imports.d.ts.map +1 -0
- package/dist/imports.js +70 -0
- package/dist/imports.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/integrity.d.ts +38 -0
- package/dist/integrity.d.ts.map +1 -0
- package/dist/integrity.js +105 -0
- package/dist/integrity.js.map +1 -0
- package/dist/localized-text.d.ts +18 -0
- package/dist/localized-text.d.ts.map +1 -0
- package/dist/localized-text.js +17 -0
- package/dist/localized-text.js.map +1 -0
- package/dist/manifest.d.ts +1122 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +1118 -0
- package/dist/manifest.js.map +1 -0
- package/dist/module.d.ts +35 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +2 -0
- package/dist/module.js.map +1 -0
- package/dist/package-check.d.ts +66 -0
- package/dist/package-check.d.ts.map +1 -0
- package/dist/package-check.js +755 -0
- package/dist/package-check.js.map +1 -0
- package/dist/permissions.d.ts +224 -0
- package/dist/permissions.d.ts.map +1 -0
- package/dist/permissions.js +277 -0
- package/dist/permissions.js.map +1 -0
- package/dist/recipients.d.ts +139 -0
- package/dist/recipients.d.ts.map +1 -0
- package/dist/recipients.js +223 -0
- package/dist/recipients.js.map +1 -0
- package/dist/records.d.ts +130 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +85 -0
- package/dist/records.js.map +1 -0
- package/dist/require-capability.d.ts +37 -0
- package/dist/require-capability.d.ts.map +1 -0
- package/dist/require-capability.js +88 -0
- package/dist/require-capability.js.map +1 -0
- package/dist/settings-schema.d.ts +130 -0
- package/dist/settings-schema.d.ts.map +1 -0
- package/dist/settings-schema.js +272 -0
- package/dist/settings-schema.js.map +1 -0
- package/dist/standard-schema.d.ts +43 -0
- package/dist/standard-schema.d.ts.map +1 -0
- package/dist/standard-schema.js +2 -0
- package/dist/standard-schema.js.map +1 -0
- package/package.json +55 -3
- package/src/abort-signal.ts +22 -0
- package/src/action-refusal.ts +178 -0
- package/src/action-schema.ts +89 -0
- package/src/actions.ts +344 -0
- package/src/api-version.ts +28 -0
- package/src/blocks.ts +289 -0
- package/src/catalog.ts +679 -0
- package/src/define-plugin.ts +18 -0
- package/src/entitlements.ts +150 -0
- package/src/extensions.ts +212 -0
- package/src/finances.ts +317 -0
- package/src/findings.ts +163 -0
- package/src/host.ts +894 -0
- package/src/imports.ts +135 -0
- package/src/index.ts +316 -0
- package/src/integrity.ts +125 -0
- package/src/localized-text.ts +19 -0
- package/src/manifest.ts +1412 -0
- package/src/module.ts +38 -0
- package/src/package-check.ts +894 -0
- package/src/permissions.ts +295 -0
- package/src/recipients.ts +294 -0
- package/src/records.ts +172 -0
- package/src/require-capability.ts +106 -0
- package/src/settings-schema.ts +334 -0
- package/src/standard-schema.ts +39 -0
|
@@ -0,0 +1,1122 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type PluginManifestRule } from "./findings.ts";
|
|
3
|
+
/**
|
|
4
|
+
* The plugin manifest.
|
|
5
|
+
*
|
|
6
|
+
* It lives in the `openbrf` field of the plugin's own package.json rather
|
|
7
|
+
* than in a separate file: npm already installs package.json, already
|
|
8
|
+
* validates its name and version, and already refuses to install a package
|
|
9
|
+
* without one. A second manifest file could go missing, disagree with the
|
|
10
|
+
* package it sits in, or be left behind by a partial extraction, and the
|
|
11
|
+
* loader would have to decide which of the two to believe.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* A plugin id.
|
|
15
|
+
*
|
|
16
|
+
* Used as a URL segment (`/api/plugin/<id>/...`), an i18n namespace
|
|
17
|
+
* (`plugin-<id>`), a database key and a directory name, so it is restricted to
|
|
18
|
+
* what is safe in all four. In particular it may not contain a dot or a
|
|
19
|
+
* slash: a plugin id is resolved against paths, and `..` must not be
|
|
20
|
+
* expressible.
|
|
21
|
+
*/
|
|
22
|
+
export declare const pluginIdSchema: z.ZodString;
|
|
23
|
+
export declare const pluginEntrySchema: z.ZodObject<{
|
|
24
|
+
server: z.ZodOptional<z.ZodString>;
|
|
25
|
+
client: z.ZodOptional<z.ZodString>;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
/**
|
|
28
|
+
* One action the plugin proposes.
|
|
29
|
+
*
|
|
30
|
+
* Declared in the manifest rather than at registration, because the board reads
|
|
31
|
+
* it on the install consent screen before anything has been downloaded, and
|
|
32
|
+
* nothing that can refuse a plugin may run after the code that executes it. The
|
|
33
|
+
* plugin's bundle supplies the schemas and the handler; what it may ask for is
|
|
34
|
+
* settled here.
|
|
35
|
+
*
|
|
36
|
+
* `capability` is a free string because this package cannot import the core
|
|
37
|
+
* capability union - it is published to plugin authors and the union is the
|
|
38
|
+
* instance's. It is resolved against the real list at the boot gate, which also
|
|
39
|
+
* refuses the ones no action of any kind may hold.
|
|
40
|
+
*/
|
|
41
|
+
export declare const pluginActionSchema: z.ZodObject<{
|
|
42
|
+
id: z.ZodString;
|
|
43
|
+
capability: z.ZodString;
|
|
44
|
+
effect: z.ZodEnum<{
|
|
45
|
+
delete: "delete";
|
|
46
|
+
read: "read";
|
|
47
|
+
write: "write";
|
|
48
|
+
}>;
|
|
49
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
50
|
+
account: "account";
|
|
51
|
+
apartment: "apartment";
|
|
52
|
+
auditTrail: "auditTrail";
|
|
53
|
+
email: "email";
|
|
54
|
+
financial: "financial";
|
|
55
|
+
freeText: "freeText";
|
|
56
|
+
health: "health";
|
|
57
|
+
name: "name";
|
|
58
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
59
|
+
phone: "phone";
|
|
60
|
+
photograph: "photograph";
|
|
61
|
+
postalAddress: "postalAddress";
|
|
62
|
+
protected: "protected";
|
|
63
|
+
residency: "residency";
|
|
64
|
+
}>>>;
|
|
65
|
+
surfaces: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
66
|
+
ai: "ai";
|
|
67
|
+
mcp: "mcp";
|
|
68
|
+
ui: "ui";
|
|
69
|
+
}>>>;
|
|
70
|
+
}, z.core.$strip>;
|
|
71
|
+
/**
|
|
72
|
+
* The declared actions, as every boundary that reads them must read them.
|
|
73
|
+
*
|
|
74
|
+
* One schema rather than the same array written twice, because the invariant
|
|
75
|
+
* below has to hold at both: the catalog entry the consent screen renders from,
|
|
76
|
+
* and the manifest the loader enforces against it.
|
|
77
|
+
*
|
|
78
|
+
* An id appears once. Two declarations sharing one id are not a redundancy that
|
|
79
|
+
* sorts itself out - each of the three places that reads them resolves the
|
|
80
|
+
* collision differently. The binder takes the LAST, through a Map; consent
|
|
81
|
+
* compares canonical strings as a SET, so reordering the pair leaves the
|
|
82
|
+
* comparison equal and asks the board nothing; and arming stores the bare id,
|
|
83
|
+
* which names both. A republished version that only swapped the order of a
|
|
84
|
+
* duplicated pair would therefore keep its arming and go live at the OTHER
|
|
85
|
+
* declaration's capability, personal data and surfaces, with nobody having
|
|
86
|
+
* decided that. An action is one operation with one capability; two of them
|
|
87
|
+
* wearing one id is not a declaration this can read.
|
|
88
|
+
*
|
|
89
|
+
* Undefaulted, so each use site says for itself whether an absent list means
|
|
90
|
+
* "none declared" or "you did not answer". A manifest and a catalog entry mean
|
|
91
|
+
* the first and add `.default([])`; the install request means the second, since
|
|
92
|
+
* a board's echo that silently became an empty list would read as consent to no
|
|
93
|
+
* action at all - and a plugin that declares one would then be refused with a
|
|
94
|
+
* mismatch nothing the board could do would satisfy.
|
|
95
|
+
*/
|
|
96
|
+
export declare const pluginActionsSchema: z.ZodArray<z.ZodObject<{
|
|
97
|
+
id: z.ZodString;
|
|
98
|
+
capability: z.ZodString;
|
|
99
|
+
effect: z.ZodEnum<{
|
|
100
|
+
delete: "delete";
|
|
101
|
+
read: "read";
|
|
102
|
+
write: "write";
|
|
103
|
+
}>;
|
|
104
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
105
|
+
account: "account";
|
|
106
|
+
apartment: "apartment";
|
|
107
|
+
auditTrail: "auditTrail";
|
|
108
|
+
email: "email";
|
|
109
|
+
financial: "financial";
|
|
110
|
+
freeText: "freeText";
|
|
111
|
+
health: "health";
|
|
112
|
+
name: "name";
|
|
113
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
114
|
+
phone: "phone";
|
|
115
|
+
photograph: "photograph";
|
|
116
|
+
postalAddress: "postalAddress";
|
|
117
|
+
protected: "protected";
|
|
118
|
+
residency: "residency";
|
|
119
|
+
}>>>;
|
|
120
|
+
surfaces: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
121
|
+
ai: "ai";
|
|
122
|
+
mcp: "mcp";
|
|
123
|
+
ui: "ui";
|
|
124
|
+
}>>>;
|
|
125
|
+
}, z.core.$strip>>;
|
|
126
|
+
/**
|
|
127
|
+
* The declared actions over a given reading of one action.
|
|
128
|
+
*
|
|
129
|
+
* The manifest reads an action as `pluginActionSchema` does; the catalog index
|
|
130
|
+
* reads the same fields strictly, because the index refuses a field its
|
|
131
|
+
* version does not define. Both keep the rule above, which is why the list is
|
|
132
|
+
* built here rather than written again.
|
|
133
|
+
*/
|
|
134
|
+
export declare function declaredActionsSchema<T extends z.ZodType<{
|
|
135
|
+
id: string;
|
|
136
|
+
}>>(action: T): z.ZodArray<T>;
|
|
137
|
+
/**
|
|
138
|
+
* The public name a declared action is offered under.
|
|
139
|
+
*
|
|
140
|
+
* The plugin's id with dashes folded to underscores, then the action's id. The
|
|
141
|
+
* folding has a consequence worth knowing: a plugin `a-b` declaring `c` and a
|
|
142
|
+
* plugin `a` declaring `b_c` compose the same name, so the registry refuses the
|
|
143
|
+
* second one to arrive and docs/plugin-contract.md says so.
|
|
144
|
+
*/
|
|
145
|
+
export declare function composedActionName(pluginId: string, actionId: string): string;
|
|
146
|
+
/**
|
|
147
|
+
* The sections of the application's navigation a plugin's view may stand in.
|
|
148
|
+
*
|
|
149
|
+
* The application's own four, in the order its band shows them: the
|
|
150
|
+
* association and its life, the building and the apartments in it, the board's
|
|
151
|
+
* own desk, and the settings. A plugin names one of them rather than a section
|
|
152
|
+
* of its own, so a view is found where a destination of its kind already is.
|
|
153
|
+
*/
|
|
154
|
+
export declare const PLUGIN_VIEW_SECTIONS: readonly ["association", "building", "board", "settings"];
|
|
155
|
+
export type PluginViewSection = (typeof PLUGIN_VIEW_SECTIONS)[number];
|
|
156
|
+
export declare const pluginViewSchema: z.ZodObject<{
|
|
157
|
+
module: z.ZodDefault<z.ZodString>;
|
|
158
|
+
titleKey: z.ZodString;
|
|
159
|
+
section: z.ZodOptional<z.ZodEnum<{
|
|
160
|
+
association: "association";
|
|
161
|
+
board: "board";
|
|
162
|
+
building: "building";
|
|
163
|
+
settings: "settings";
|
|
164
|
+
}>>;
|
|
165
|
+
}, z.core.$strip>;
|
|
166
|
+
/** The id of an extension point, unique within the plugin that declares it. */
|
|
167
|
+
export declare const extensionPointIdSchema: z.ZodString;
|
|
168
|
+
/**
|
|
169
|
+
* One extension point the plugin offers other plugins (ADR 0030).
|
|
170
|
+
*
|
|
171
|
+
* Declared here rather than at registration for the reason an action is: the
|
|
172
|
+
* board reads what the point accepts on the consent screen before anything is
|
|
173
|
+
* downloaded. The bundle supplies the schemas; what may cross is settled here.
|
|
174
|
+
*/
|
|
175
|
+
export declare const pluginExtensionPointSchema: z.ZodObject<{
|
|
176
|
+
id: z.ZodString;
|
|
177
|
+
version: z.ZodInt;
|
|
178
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
179
|
+
account: "account";
|
|
180
|
+
apartment: "apartment";
|
|
181
|
+
auditTrail: "auditTrail";
|
|
182
|
+
email: "email";
|
|
183
|
+
financial: "financial";
|
|
184
|
+
freeText: "freeText";
|
|
185
|
+
health: "health";
|
|
186
|
+
name: "name";
|
|
187
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
188
|
+
phone: "phone";
|
|
189
|
+
photograph: "photograph";
|
|
190
|
+
postalAddress: "postalAddress";
|
|
191
|
+
protected: "protected";
|
|
192
|
+
residency: "residency";
|
|
193
|
+
}>>>;
|
|
194
|
+
}, z.core.$strip>;
|
|
195
|
+
/** One extension point of another plugin that this plugin extends. */
|
|
196
|
+
export declare const pluginExtensionSchema: z.ZodObject<{
|
|
197
|
+
plugin: z.ZodString;
|
|
198
|
+
point: z.ZodString;
|
|
199
|
+
version: z.ZodInt;
|
|
200
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
201
|
+
account: "account";
|
|
202
|
+
apartment: "apartment";
|
|
203
|
+
auditTrail: "auditTrail";
|
|
204
|
+
email: "email";
|
|
205
|
+
financial: "financial";
|
|
206
|
+
freeText: "freeText";
|
|
207
|
+
health: "health";
|
|
208
|
+
name: "name";
|
|
209
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
210
|
+
phone: "phone";
|
|
211
|
+
photograph: "photograph";
|
|
212
|
+
postalAddress: "postalAddress";
|
|
213
|
+
protected: "protected";
|
|
214
|
+
residency: "residency";
|
|
215
|
+
}>>>;
|
|
216
|
+
}, z.core.$strip>;
|
|
217
|
+
/**
|
|
218
|
+
* The declared extension points over a given reading of one point.
|
|
219
|
+
*
|
|
220
|
+
* The manifest reads a point as `pluginExtensionPointSchema` does; the catalog
|
|
221
|
+
* index reads it strictly and with the curator's title and description. Both
|
|
222
|
+
* keep the rule that an id appears once, which is why the list is built here.
|
|
223
|
+
*/
|
|
224
|
+
export declare function declaredExtensionPointsSchema<T extends z.ZodType<{
|
|
225
|
+
id: string;
|
|
226
|
+
}>>(point: T): z.ZodArray<T>;
|
|
227
|
+
/**
|
|
228
|
+
* The declared extensions over a given reading of one, each pair of plugin and
|
|
229
|
+
* point once: an addon contributes once to each point it extends.
|
|
230
|
+
*/
|
|
231
|
+
export declare function declaredExtensionsSchema<T extends z.ZodType<{
|
|
232
|
+
plugin: string;
|
|
233
|
+
point: string;
|
|
234
|
+
}>>(extension: T): z.ZodArray<T>;
|
|
235
|
+
/** What the rules between a plugin's extension declarations read. */
|
|
236
|
+
export interface ExtensionDeclarations {
|
|
237
|
+
readonly id: string;
|
|
238
|
+
readonly permissions: readonly string[];
|
|
239
|
+
readonly personalData: readonly string[];
|
|
240
|
+
readonly extensionPoints: readonly {
|
|
241
|
+
readonly personalData: readonly string[];
|
|
242
|
+
}[];
|
|
243
|
+
readonly extends: readonly {
|
|
244
|
+
readonly plugin: string;
|
|
245
|
+
readonly personalData: readonly string[];
|
|
246
|
+
}[];
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* The rules between a plugin's extension declarations and the rest of its
|
|
250
|
+
* declaration (ADR 0030), as issues with the path each one is at.
|
|
251
|
+
*
|
|
252
|
+
* One function for the manifest and the catalog entry, so an entry the loader
|
|
253
|
+
* would refuse is never offered for consent.
|
|
254
|
+
*/
|
|
255
|
+
export declare function extensionRuleIssues(declaration: ExtensionDeclarations): {
|
|
256
|
+
path: (string | number)[];
|
|
257
|
+
message: string;
|
|
258
|
+
}[];
|
|
259
|
+
/**
|
|
260
|
+
* The permissions that keep an addon and the plugin it extends apart, or an
|
|
261
|
+
* empty list when there are none (ADR 0030): those of whichever of the two
|
|
262
|
+
* does not ask for `site:blocks` that read the register or propose an import,
|
|
263
|
+
* when the other does.
|
|
264
|
+
*
|
|
265
|
+
* A plugin that asks for `site:blocks` reads nothing in the register and holds
|
|
266
|
+
* no member list, so what it publishes cannot name a resident. An extension is
|
|
267
|
+
* a path between two plugins in both directions: the host hands the addon the
|
|
268
|
+
* point's input, and the addon hands the host its output. A website host's
|
|
269
|
+
* points accept no personal data, but an addon that reads the register, or
|
|
270
|
+
* holds the member list it proposes, could still return a name in a field the
|
|
271
|
+
* point types as text, and only the addon's own `personalData` would say it
|
|
272
|
+
* does not. A website addon extending such a host could be handed names as the
|
|
273
|
+
* point's input, keep them, and render them in a block. So the rule reads what
|
|
274
|
+
* each side can reach, from the two manifests, rather than what either
|
|
275
|
+
* declares it hands over. Like the rule on a single plugin, it holds an honest
|
|
276
|
+
* pair to the website's argument rather than a hostile one.
|
|
277
|
+
*/
|
|
278
|
+
export declare function extensionPermissionsRefused(addon: {
|
|
279
|
+
readonly permissions: readonly string[];
|
|
280
|
+
}, host: {
|
|
281
|
+
readonly permissions: readonly string[];
|
|
282
|
+
}): string[];
|
|
283
|
+
/**
|
|
284
|
+
* The personal data a plugin handles that keeps an addon asking for
|
|
285
|
+
* `site:blocks` off it, or an empty list when there is none (ADR 0030): the
|
|
286
|
+
* host plugin's own `personalData`, when the addon asks for `site:blocks`.
|
|
287
|
+
*
|
|
288
|
+
* The point's input is the one thing that crosses an extension and that no
|
|
289
|
+
* manifest declares. A host plugin that reads nothing in the register can
|
|
290
|
+
* still be handed names by another of its addons, and then hand them on as a
|
|
291
|
+
* point's input. A host plugin that handles no personal data has none to hand
|
|
292
|
+
* on, so a website addon extends only such a plugin.
|
|
293
|
+
*/
|
|
294
|
+
export declare function extensionHostPersonalDataRefused(addon: {
|
|
295
|
+
readonly permissions: readonly string[];
|
|
296
|
+
}, host: {
|
|
297
|
+
readonly personalData: readonly string[];
|
|
298
|
+
}): string[];
|
|
299
|
+
/** Why a plugin's point cannot serve an addon's extension of it. */
|
|
300
|
+
export type ExtensionPointRefusal = {
|
|
301
|
+
readonly reason: "extension-point-unknown";
|
|
302
|
+
} | {
|
|
303
|
+
readonly reason: "extension-version-unsupported";
|
|
304
|
+
readonly supported: number;
|
|
305
|
+
} | {
|
|
306
|
+
readonly reason: "extension-personal-data-refused";
|
|
307
|
+
readonly categories: string[];
|
|
308
|
+
};
|
|
309
|
+
/**
|
|
310
|
+
* Why the host plugin's points cannot serve an addon's extension, or null when
|
|
311
|
+
* they can (ADR 0030): the host declares no such point, declares it at another
|
|
312
|
+
* major version, or the point does not accept a personal-data category the
|
|
313
|
+
* addon hands over.
|
|
314
|
+
*
|
|
315
|
+
* Both the loader and the catalog read this, so an index that lists an addon
|
|
316
|
+
* beside the plugin it extends is refused for the three refusals the loader
|
|
317
|
+
* would give those two declarations. What the installed packages declare is
|
|
318
|
+
* the loader's to read.
|
|
319
|
+
*/
|
|
320
|
+
export declare function extensionPointRefusal(extension: {
|
|
321
|
+
readonly point: string;
|
|
322
|
+
readonly version: number;
|
|
323
|
+
readonly personalData: readonly string[];
|
|
324
|
+
}, hostPoints: readonly {
|
|
325
|
+
readonly id: string;
|
|
326
|
+
readonly version: number;
|
|
327
|
+
readonly personalData: readonly string[];
|
|
328
|
+
}[]): ExtensionPointRefusal | null;
|
|
329
|
+
/** What the rule on a group of plugins joined by extensions reads. */
|
|
330
|
+
export interface ExtensionGroupMember {
|
|
331
|
+
readonly id: string;
|
|
332
|
+
readonly permissions: readonly string[];
|
|
333
|
+
readonly extends: readonly {
|
|
334
|
+
readonly plugin: string;
|
|
335
|
+
}[];
|
|
336
|
+
}
|
|
337
|
+
/** Why an addon's group keeps it from serving. */
|
|
338
|
+
export interface ExtensionGroupRefusal {
|
|
339
|
+
/** The plugins in its group that ask for `site:blocks`. */
|
|
340
|
+
readonly website: string[];
|
|
341
|
+
/**
|
|
342
|
+
* The plugins in its group that read the register or propose an import,
|
|
343
|
+
* and so reach the members' details.
|
|
344
|
+
*/
|
|
345
|
+
readonly register: string[];
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* The addons refused because the plugins joined to them by extensions hold
|
|
349
|
+
* both a plugin that asks for `site:blocks` and one that reads the register or
|
|
350
|
+
* proposes an import, by id (ADR 0030).
|
|
351
|
+
*
|
|
352
|
+
* The rule between an addon and its host plugin reads two manifests. Data
|
|
353
|
+
* also crosses between two addons of one host plugin, and further: an addon
|
|
354
|
+
* that reads the register, or holds the member list it proposes, hands the
|
|
355
|
+
* host plugin a name while declaring nothing, the host plugin hands it to a
|
|
356
|
+
* website addon as a point's input, and the website addon renders it. Neither manifest of any one pair says so.
|
|
357
|
+
* So the plugins joined by extensions, through one host plugin or several,
|
|
358
|
+
* are read as one group, and a group never holds both kinds.
|
|
359
|
+
*
|
|
360
|
+
* The answer depends only on the set of members, never on their order, so it
|
|
361
|
+
* is the same whichever order the loader finds the packages in. Addons give
|
|
362
|
+
* way in the order of `GROUP_YIELDS`, which keeps the plugin that reads the
|
|
363
|
+
* register or proposes an import serving and refuses the website addon beside
|
|
364
|
+
* it.
|
|
365
|
+
*/
|
|
366
|
+
export declare function extensionGroupRefusals(members: readonly ExtensionGroupMember[]): Map<string, ExtensionGroupRefusal>;
|
|
367
|
+
/**
|
|
368
|
+
* One device route: a path under the plugin's own mount that answers to a
|
|
369
|
+
* device token and to nothing else (ADR 0031).
|
|
370
|
+
*
|
|
371
|
+
* Declared in the manifest because the board reads it on the install consent
|
|
372
|
+
* screen, and because the guard has to know which paths take no session cookie
|
|
373
|
+
* before any of the plugin's code has run.
|
|
374
|
+
*/
|
|
375
|
+
export declare const pluginDeviceRouteSchema: z.ZodObject<{
|
|
376
|
+
id: z.ZodString;
|
|
377
|
+
path: z.ZodString;
|
|
378
|
+
}, z.core.$strip>;
|
|
379
|
+
/** At most this many device routes per plugin. */
|
|
380
|
+
export declare const MAX_DEVICE_ROUTES = 4;
|
|
381
|
+
/**
|
|
382
|
+
* Whether one route path is the other or lies below it, segment by segment.
|
|
383
|
+
*
|
|
384
|
+
* `screen` and `screen/pictures` overlap; `screen` and `screens` do not.
|
|
385
|
+
*/
|
|
386
|
+
export declare function routePathsOverlap(left: string, right: string): boolean;
|
|
387
|
+
/**
|
|
388
|
+
* The declared device routes, as every boundary that reads them must read
|
|
389
|
+
* them: the manifest and the catalog entry the consent screen renders from.
|
|
390
|
+
*
|
|
391
|
+
* An id names one route, and no two routes overlap. A token is issued for one
|
|
392
|
+
* route by its id, and a request is matched to one route by its path, so a
|
|
393
|
+
* duplicated id or a path inside another route's would leave the guard two
|
|
394
|
+
* answers to choose from.
|
|
395
|
+
*/
|
|
396
|
+
export declare function declaredDeviceRoutesSchema<T extends z.ZodType<{
|
|
397
|
+
id: string;
|
|
398
|
+
path: string;
|
|
399
|
+
}>>(route: T): z.ZodArray<T>;
|
|
400
|
+
export declare const pluginDeviceRoutesSchema: z.ZodArray<z.ZodObject<{
|
|
401
|
+
id: z.ZodString;
|
|
402
|
+
path: z.ZodString;
|
|
403
|
+
}, z.core.$strip>>;
|
|
404
|
+
/**
|
|
405
|
+
* The rules a declaration of device routes has to keep beside the rest of the
|
|
406
|
+
* manifest, for the manifest and the catalog entry alike.
|
|
407
|
+
*
|
|
408
|
+
* A device route may not overlap the OAuth protected resource, which takes a
|
|
409
|
+
* different token on its own branch of the guard, and a plugin with a device
|
|
410
|
+
* route reads nothing from the register: a device is a screen on a wall that
|
|
411
|
+
* anyone passing reads (ADR 0031).
|
|
412
|
+
*/
|
|
413
|
+
export declare function deviceRouteRuleIssues(declaration: {
|
|
414
|
+
deviceRoutes: readonly {
|
|
415
|
+
id: string;
|
|
416
|
+
path: string;
|
|
417
|
+
}[];
|
|
418
|
+
oauthProtectedResource?: string | undefined;
|
|
419
|
+
permissions: readonly string[];
|
|
420
|
+
}): {
|
|
421
|
+
path: (string | number)[];
|
|
422
|
+
message: string;
|
|
423
|
+
rule: PluginManifestRule;
|
|
424
|
+
}[];
|
|
425
|
+
/**
|
|
426
|
+
* What a plugin that proposes an import declares about the data it carries,
|
|
427
|
+
* for the manifest and the catalog entry alike (ADR 0043).
|
|
428
|
+
*
|
|
429
|
+
* The file is the association's member list, and the plugin carries it
|
|
430
|
+
* whole: every name, contact detail and personal identity number, and rows
|
|
431
|
+
* about persons with protected personal data, which the file does not mark.
|
|
432
|
+
* So the board is told so on the consent screen. And no other plugin can reach
|
|
433
|
+
* an identity number or a protected person, so for any other plugin either
|
|
434
|
+
* category would describe something that cannot happen.
|
|
435
|
+
*/
|
|
436
|
+
export declare function proposeImportPersonalDataIssues(declaration: {
|
|
437
|
+
permissions: readonly string[];
|
|
438
|
+
personalData: readonly string[];
|
|
439
|
+
}): {
|
|
440
|
+
message: string;
|
|
441
|
+
}[];
|
|
442
|
+
/**
|
|
443
|
+
* A calendar date written `YYYY-MM-DD`, and a real one: `2027-02-30` is
|
|
444
|
+
* refused rather than rolled over into March.
|
|
445
|
+
*/
|
|
446
|
+
export declare function isCalendarDay(text: string): boolean;
|
|
447
|
+
/**
|
|
448
|
+
* Which of an issuer's keys signed a licence (ADR 0042).
|
|
449
|
+
*
|
|
450
|
+
* It selects the keys to try and asserts nothing: two plugins may declare one
|
|
451
|
+
* key id with different keys, and a key is known by its fingerprint.
|
|
452
|
+
*/
|
|
453
|
+
export declare const licenceKeyIdSchema: z.ZodString;
|
|
454
|
+
/**
|
|
455
|
+
* An Ed25519 public key: the base64 of its 32 raw bytes, padded, and in the
|
|
456
|
+
* one spelling that decodes to them. The last character before the padding
|
|
457
|
+
* carries two bits no key has, which is what the class of letters it may be
|
|
458
|
+
* from says.
|
|
459
|
+
*/
|
|
460
|
+
export declare const licencePublicKeySchema: z.ZodString;
|
|
461
|
+
/**
|
|
462
|
+
* A service a plugin may present the instance's licence to: an `https` origin
|
|
463
|
+
* as the WHATWG URL standard serialises one, so it compares exactly.
|
|
464
|
+
*
|
|
465
|
+
* A lower-case domain in punycode, a port only when it is not 443, and no
|
|
466
|
+
* userinfo, path, query or fragment. A host whose last label is a number is
|
|
467
|
+
* an IPv4 address to that standard, which serialises it otherwise, so it is
|
|
468
|
+
* refused rather than compared in a form no browser would print. Plain `http`
|
|
469
|
+
* is refused too: a presentation sent in the clear could be replayed before
|
|
470
|
+
* the service saw its nonce.
|
|
471
|
+
*/
|
|
472
|
+
export declare const licenceAudienceSchema: z.ZodString;
|
|
473
|
+
/**
|
|
474
|
+
* The licence a paid plugin reads (ADR 0042), and whom it trusts to issue it.
|
|
475
|
+
*
|
|
476
|
+
* The keys sit here rather than in the core, so the core holds no vendor's
|
|
477
|
+
* key and anyone who sells a plugin can issue licences for it in the same
|
|
478
|
+
* format. The host verifies; a plugin reads the result through
|
|
479
|
+
* `host.entitlements`.
|
|
480
|
+
*
|
|
481
|
+
* Strict, because what it grants is consented to: a misspelled field read as
|
|
482
|
+
* absent would be a declaration the board never saw.
|
|
483
|
+
*/
|
|
484
|
+
export declare const pluginLicenceSchema: z.ZodObject<{
|
|
485
|
+
entitlement: z.ZodString;
|
|
486
|
+
issuer: z.ZodObject<{
|
|
487
|
+
name: z.ZodString;
|
|
488
|
+
url: z.ZodString;
|
|
489
|
+
}, z.core.$strict>;
|
|
490
|
+
keys: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
491
|
+
audiences: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
492
|
+
}, z.core.$strict>;
|
|
493
|
+
export type PluginLicenceDeclaration = z.infer<typeof pluginLicenceSchema>;
|
|
494
|
+
export declare const pluginManifestSchema: z.ZodObject<{
|
|
495
|
+
apiVersion: z.ZodInt;
|
|
496
|
+
id: z.ZodString;
|
|
497
|
+
entry: z.ZodObject<{
|
|
498
|
+
server: z.ZodOptional<z.ZodString>;
|
|
499
|
+
client: z.ZodOptional<z.ZodString>;
|
|
500
|
+
}, z.core.$strip>;
|
|
501
|
+
permissions: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
502
|
+
"addressBook:proposeImport": "addressBook:proposeImport";
|
|
503
|
+
"addressBook:read": "addressBook:read";
|
|
504
|
+
"addressBook:readContact": "addressBook:readContact";
|
|
505
|
+
"addresses:read": "addresses:read";
|
|
506
|
+
"bookings:readAvailability": "bookings:readAvailability";
|
|
507
|
+
"calendar:read": "calendar:read";
|
|
508
|
+
"finances:read": "finances:read";
|
|
509
|
+
"finances:recordDelivery": "finances:recordDelivery";
|
|
510
|
+
"jobs:schedule": "jobs:schedule";
|
|
511
|
+
"mail:send": "mail:send";
|
|
512
|
+
"media:read": "media:read";
|
|
513
|
+
"news:read": "news:read";
|
|
514
|
+
"site:blocks": "site:blocks";
|
|
515
|
+
"sms:send": "sms:send";
|
|
516
|
+
"themes:install": "themes:install";
|
|
517
|
+
}>>>;
|
|
518
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
519
|
+
account: "account";
|
|
520
|
+
apartment: "apartment";
|
|
521
|
+
auditTrail: "auditTrail";
|
|
522
|
+
email: "email";
|
|
523
|
+
financial: "financial";
|
|
524
|
+
freeText: "freeText";
|
|
525
|
+
health: "health";
|
|
526
|
+
name: "name";
|
|
527
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
528
|
+
phone: "phone";
|
|
529
|
+
photograph: "photograph";
|
|
530
|
+
postalAddress: "postalAddress";
|
|
531
|
+
protected: "protected";
|
|
532
|
+
residency: "residency";
|
|
533
|
+
}>>>;
|
|
534
|
+
settingsSchema: z.ZodOptional<z.ZodObject<{
|
|
535
|
+
fields: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
536
|
+
key: z.ZodString;
|
|
537
|
+
labelKey: z.ZodString;
|
|
538
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
539
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
540
|
+
type: z.ZodLiteral<"text">;
|
|
541
|
+
default: z.ZodOptional<z.ZodString>;
|
|
542
|
+
minLength: z.ZodOptional<z.ZodInt>;
|
|
543
|
+
maxLength: z.ZodOptional<z.ZodInt>;
|
|
544
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
545
|
+
key: z.ZodString;
|
|
546
|
+
labelKey: z.ZodString;
|
|
547
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
548
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
549
|
+
type: z.ZodLiteral<"number">;
|
|
550
|
+
default: z.ZodOptional<z.ZodNumber>;
|
|
551
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
552
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
553
|
+
integer: z.ZodDefault<z.ZodBoolean>;
|
|
554
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
555
|
+
key: z.ZodString;
|
|
556
|
+
labelKey: z.ZodString;
|
|
557
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
558
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
559
|
+
type: z.ZodLiteral<"boolean">;
|
|
560
|
+
default: z.ZodOptional<z.ZodBoolean>;
|
|
561
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
562
|
+
key: z.ZodString;
|
|
563
|
+
labelKey: z.ZodString;
|
|
564
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
565
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
566
|
+
type: z.ZodLiteral<"select">;
|
|
567
|
+
default: z.ZodOptional<z.ZodString>;
|
|
568
|
+
options: z.ZodArray<z.ZodObject<{
|
|
569
|
+
value: z.ZodString;
|
|
570
|
+
labelKey: z.ZodString;
|
|
571
|
+
}, z.core.$strip>>;
|
|
572
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
573
|
+
key: z.ZodString;
|
|
574
|
+
labelKey: z.ZodString;
|
|
575
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
576
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
577
|
+
type: z.ZodLiteral<"secret">;
|
|
578
|
+
minLength: z.ZodOptional<z.ZodInt>;
|
|
579
|
+
maxLength: z.ZodOptional<z.ZodInt>;
|
|
580
|
+
}, z.core.$strip>], "type">>;
|
|
581
|
+
}, z.core.$strip>>;
|
|
582
|
+
view: z.ZodOptional<z.ZodObject<{
|
|
583
|
+
module: z.ZodDefault<z.ZodString>;
|
|
584
|
+
titleKey: z.ZodString;
|
|
585
|
+
section: z.ZodOptional<z.ZodEnum<{
|
|
586
|
+
association: "association";
|
|
587
|
+
board: "board";
|
|
588
|
+
building: "building";
|
|
589
|
+
settings: "settings";
|
|
590
|
+
}>>;
|
|
591
|
+
}, z.core.$strip>>;
|
|
592
|
+
actions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
593
|
+
id: z.ZodString;
|
|
594
|
+
capability: z.ZodString;
|
|
595
|
+
effect: z.ZodEnum<{
|
|
596
|
+
delete: "delete";
|
|
597
|
+
read: "read";
|
|
598
|
+
write: "write";
|
|
599
|
+
}>;
|
|
600
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
601
|
+
account: "account";
|
|
602
|
+
apartment: "apartment";
|
|
603
|
+
auditTrail: "auditTrail";
|
|
604
|
+
email: "email";
|
|
605
|
+
financial: "financial";
|
|
606
|
+
freeText: "freeText";
|
|
607
|
+
health: "health";
|
|
608
|
+
name: "name";
|
|
609
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
610
|
+
phone: "phone";
|
|
611
|
+
photograph: "photograph";
|
|
612
|
+
postalAddress: "postalAddress";
|
|
613
|
+
protected: "protected";
|
|
614
|
+
residency: "residency";
|
|
615
|
+
}>>>;
|
|
616
|
+
surfaces: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
617
|
+
ai: "ai";
|
|
618
|
+
mcp: "mcp";
|
|
619
|
+
ui: "ui";
|
|
620
|
+
}>>>;
|
|
621
|
+
}, z.core.$strip>>>;
|
|
622
|
+
oauthProtectedResource: z.ZodOptional<z.ZodString>;
|
|
623
|
+
deviceRoutes: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
624
|
+
id: z.ZodString;
|
|
625
|
+
path: z.ZodString;
|
|
626
|
+
}, z.core.$strip>>>;
|
|
627
|
+
ai: z.ZodDefault<z.ZodBoolean>;
|
|
628
|
+
blocks: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
629
|
+
name: z.ZodString;
|
|
630
|
+
labelKey: z.ZodString;
|
|
631
|
+
icon: z.ZodDefault<z.ZodEnum<{
|
|
632
|
+
calendar: "calendar";
|
|
633
|
+
contact: "contact";
|
|
634
|
+
documents: "documents";
|
|
635
|
+
facts: "facts";
|
|
636
|
+
form: "form";
|
|
637
|
+
heading: "heading";
|
|
638
|
+
image: "image";
|
|
639
|
+
news: "news";
|
|
640
|
+
paragraph: "paragraph";
|
|
641
|
+
people: "people";
|
|
642
|
+
plugin: "plugin";
|
|
643
|
+
questions: "questions";
|
|
644
|
+
}>>;
|
|
645
|
+
category: z.ZodDefault<z.ZodEnum<{
|
|
646
|
+
association: "association";
|
|
647
|
+
media: "media";
|
|
648
|
+
text: "text";
|
|
649
|
+
}>>;
|
|
650
|
+
settingsSchema: z.ZodDefault<z.ZodObject<{
|
|
651
|
+
fields: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
652
|
+
key: z.ZodString;
|
|
653
|
+
labelKey: z.ZodString;
|
|
654
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
655
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
656
|
+
type: z.ZodLiteral<"text">;
|
|
657
|
+
default: z.ZodOptional<z.ZodString>;
|
|
658
|
+
minLength: z.ZodOptional<z.ZodInt>;
|
|
659
|
+
maxLength: z.ZodOptional<z.ZodInt>;
|
|
660
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
661
|
+
key: z.ZodString;
|
|
662
|
+
labelKey: z.ZodString;
|
|
663
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
664
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
665
|
+
type: z.ZodLiteral<"number">;
|
|
666
|
+
default: z.ZodOptional<z.ZodNumber>;
|
|
667
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
668
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
669
|
+
integer: z.ZodDefault<z.ZodBoolean>;
|
|
670
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
671
|
+
key: z.ZodString;
|
|
672
|
+
labelKey: z.ZodString;
|
|
673
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
674
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
675
|
+
type: z.ZodLiteral<"boolean">;
|
|
676
|
+
default: z.ZodOptional<z.ZodBoolean>;
|
|
677
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
678
|
+
key: z.ZodString;
|
|
679
|
+
labelKey: z.ZodString;
|
|
680
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
681
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
682
|
+
type: z.ZodLiteral<"select">;
|
|
683
|
+
default: z.ZodOptional<z.ZodString>;
|
|
684
|
+
options: z.ZodArray<z.ZodObject<{
|
|
685
|
+
value: z.ZodString;
|
|
686
|
+
labelKey: z.ZodString;
|
|
687
|
+
}, z.core.$strip>>;
|
|
688
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
689
|
+
key: z.ZodString;
|
|
690
|
+
labelKey: z.ZodString;
|
|
691
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
692
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
693
|
+
type: z.ZodLiteral<"secret">;
|
|
694
|
+
minLength: z.ZodOptional<z.ZodInt>;
|
|
695
|
+
maxLength: z.ZodOptional<z.ZodInt>;
|
|
696
|
+
}, z.core.$strip>], "type">>;
|
|
697
|
+
}, z.core.$strip>>;
|
|
698
|
+
}, z.core.$strict>>>;
|
|
699
|
+
extensionPoints: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
700
|
+
id: z.ZodString;
|
|
701
|
+
version: z.ZodInt;
|
|
702
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
703
|
+
account: "account";
|
|
704
|
+
apartment: "apartment";
|
|
705
|
+
auditTrail: "auditTrail";
|
|
706
|
+
email: "email";
|
|
707
|
+
financial: "financial";
|
|
708
|
+
freeText: "freeText";
|
|
709
|
+
health: "health";
|
|
710
|
+
name: "name";
|
|
711
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
712
|
+
phone: "phone";
|
|
713
|
+
photograph: "photograph";
|
|
714
|
+
postalAddress: "postalAddress";
|
|
715
|
+
protected: "protected";
|
|
716
|
+
residency: "residency";
|
|
717
|
+
}>>>;
|
|
718
|
+
}, z.core.$strip>>>;
|
|
719
|
+
extends: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
720
|
+
plugin: z.ZodString;
|
|
721
|
+
point: z.ZodString;
|
|
722
|
+
version: z.ZodInt;
|
|
723
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
724
|
+
account: "account";
|
|
725
|
+
apartment: "apartment";
|
|
726
|
+
auditTrail: "auditTrail";
|
|
727
|
+
email: "email";
|
|
728
|
+
financial: "financial";
|
|
729
|
+
freeText: "freeText";
|
|
730
|
+
health: "health";
|
|
731
|
+
name: "name";
|
|
732
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
733
|
+
phone: "phone";
|
|
734
|
+
photograph: "photograph";
|
|
735
|
+
postalAddress: "postalAddress";
|
|
736
|
+
protected: "protected";
|
|
737
|
+
residency: "residency";
|
|
738
|
+
}>>>;
|
|
739
|
+
}, z.core.$strip>>>;
|
|
740
|
+
recipients: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
741
|
+
id: z.ZodString;
|
|
742
|
+
origin: z.ZodString;
|
|
743
|
+
purpose: z.ZodObject<{
|
|
744
|
+
sv: z.ZodString;
|
|
745
|
+
en: z.ZodString;
|
|
746
|
+
}, z.core.$strict>;
|
|
747
|
+
personalData: z.ZodArray<z.ZodEnum<{
|
|
748
|
+
account: "account";
|
|
749
|
+
apartment: "apartment";
|
|
750
|
+
auditTrail: "auditTrail";
|
|
751
|
+
email: "email";
|
|
752
|
+
financial: "financial";
|
|
753
|
+
freeText: "freeText";
|
|
754
|
+
health: "health";
|
|
755
|
+
name: "name";
|
|
756
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
757
|
+
phone: "phone";
|
|
758
|
+
photograph: "photograph";
|
|
759
|
+
postalAddress: "postalAddress";
|
|
760
|
+
protected: "protected";
|
|
761
|
+
residency: "residency";
|
|
762
|
+
}>>;
|
|
763
|
+
}, z.core.$strip>>>;
|
|
764
|
+
licence: z.ZodOptional<z.ZodObject<{
|
|
765
|
+
entitlement: z.ZodString;
|
|
766
|
+
issuer: z.ZodObject<{
|
|
767
|
+
name: z.ZodString;
|
|
768
|
+
url: z.ZodString;
|
|
769
|
+
}, z.core.$strict>;
|
|
770
|
+
keys: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
771
|
+
audiences: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
772
|
+
}, z.core.$strict>>;
|
|
773
|
+
released: z.ZodOptional<z.ZodString>;
|
|
774
|
+
}, z.core.$strip>;
|
|
775
|
+
export type PluginManifest = z.infer<typeof pluginManifestSchema>;
|
|
776
|
+
export type PluginActionDeclaration = z.infer<typeof pluginActionSchema>;
|
|
777
|
+
export type PluginEntry = z.infer<typeof pluginEntrySchema>;
|
|
778
|
+
export type PluginView = z.infer<typeof pluginViewSchema>;
|
|
779
|
+
export type PluginExtensionPointDeclaration = z.infer<typeof pluginExtensionPointSchema>;
|
|
780
|
+
export type PluginExtensionDeclaration = z.infer<typeof pluginExtensionSchema>;
|
|
781
|
+
export type PluginDeviceRoute = z.infer<typeof pluginDeviceRouteSchema>;
|
|
782
|
+
/**
|
|
783
|
+
* Dependency fields npm installs at install time.
|
|
784
|
+
*
|
|
785
|
+
* The installer omits peer, dev and optional dependencies and runs no scripts,
|
|
786
|
+
* but it still hands npm the package: anything listed here would send that npm
|
|
787
|
+
* to a registry, which an instance never contacts. optionalDependencies is
|
|
788
|
+
* listed although it is omitted, because a package relying on one being
|
|
789
|
+
* present works in development and quietly not on an instance.
|
|
790
|
+
*/
|
|
791
|
+
export declare const RUNTIME_DEPENDENCY_FIELDS: readonly ["dependencies", "optionalDependencies", "bundleDependencies", "bundledDependencies"];
|
|
792
|
+
/** Package names in a dependency field, whether a map or npm's bundle list. */
|
|
793
|
+
export declare function dependencyNames(value: unknown): string[];
|
|
794
|
+
/** Whether a dependency field is an empty map or an empty list. */
|
|
795
|
+
export declare function isEmptyDependencyField(value: unknown): boolean;
|
|
796
|
+
/**
|
|
797
|
+
* The subset of package.json the loader reads. Everything else in the file is
|
|
798
|
+
* npm's business, apart from the dependency fields, which must name nothing.
|
|
799
|
+
*/
|
|
800
|
+
export declare const pluginPackageSchema: z.ZodObject<{
|
|
801
|
+
name: z.ZodString;
|
|
802
|
+
version: z.ZodString;
|
|
803
|
+
openbrf: z.ZodObject<{
|
|
804
|
+
apiVersion: z.ZodInt;
|
|
805
|
+
id: z.ZodString;
|
|
806
|
+
entry: z.ZodObject<{
|
|
807
|
+
server: z.ZodOptional<z.ZodString>;
|
|
808
|
+
client: z.ZodOptional<z.ZodString>;
|
|
809
|
+
}, z.core.$strip>;
|
|
810
|
+
permissions: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
811
|
+
"addressBook:proposeImport": "addressBook:proposeImport";
|
|
812
|
+
"addressBook:read": "addressBook:read";
|
|
813
|
+
"addressBook:readContact": "addressBook:readContact";
|
|
814
|
+
"addresses:read": "addresses:read";
|
|
815
|
+
"bookings:readAvailability": "bookings:readAvailability";
|
|
816
|
+
"calendar:read": "calendar:read";
|
|
817
|
+
"finances:read": "finances:read";
|
|
818
|
+
"finances:recordDelivery": "finances:recordDelivery";
|
|
819
|
+
"jobs:schedule": "jobs:schedule";
|
|
820
|
+
"mail:send": "mail:send";
|
|
821
|
+
"media:read": "media:read";
|
|
822
|
+
"news:read": "news:read";
|
|
823
|
+
"site:blocks": "site:blocks";
|
|
824
|
+
"sms:send": "sms:send";
|
|
825
|
+
"themes:install": "themes:install";
|
|
826
|
+
}>>>;
|
|
827
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
828
|
+
account: "account";
|
|
829
|
+
apartment: "apartment";
|
|
830
|
+
auditTrail: "auditTrail";
|
|
831
|
+
email: "email";
|
|
832
|
+
financial: "financial";
|
|
833
|
+
freeText: "freeText";
|
|
834
|
+
health: "health";
|
|
835
|
+
name: "name";
|
|
836
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
837
|
+
phone: "phone";
|
|
838
|
+
photograph: "photograph";
|
|
839
|
+
postalAddress: "postalAddress";
|
|
840
|
+
protected: "protected";
|
|
841
|
+
residency: "residency";
|
|
842
|
+
}>>>;
|
|
843
|
+
settingsSchema: z.ZodOptional<z.ZodObject<{
|
|
844
|
+
fields: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
845
|
+
key: z.ZodString;
|
|
846
|
+
labelKey: z.ZodString;
|
|
847
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
848
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
849
|
+
type: z.ZodLiteral<"text">;
|
|
850
|
+
default: z.ZodOptional<z.ZodString>;
|
|
851
|
+
minLength: z.ZodOptional<z.ZodInt>;
|
|
852
|
+
maxLength: z.ZodOptional<z.ZodInt>;
|
|
853
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
854
|
+
key: z.ZodString;
|
|
855
|
+
labelKey: z.ZodString;
|
|
856
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
857
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
858
|
+
type: z.ZodLiteral<"number">;
|
|
859
|
+
default: z.ZodOptional<z.ZodNumber>;
|
|
860
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
861
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
862
|
+
integer: z.ZodDefault<z.ZodBoolean>;
|
|
863
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
864
|
+
key: z.ZodString;
|
|
865
|
+
labelKey: z.ZodString;
|
|
866
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
867
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
868
|
+
type: z.ZodLiteral<"boolean">;
|
|
869
|
+
default: z.ZodOptional<z.ZodBoolean>;
|
|
870
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
871
|
+
key: z.ZodString;
|
|
872
|
+
labelKey: z.ZodString;
|
|
873
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
874
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
875
|
+
type: z.ZodLiteral<"select">;
|
|
876
|
+
default: z.ZodOptional<z.ZodString>;
|
|
877
|
+
options: z.ZodArray<z.ZodObject<{
|
|
878
|
+
value: z.ZodString;
|
|
879
|
+
labelKey: z.ZodString;
|
|
880
|
+
}, z.core.$strip>>;
|
|
881
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
882
|
+
key: z.ZodString;
|
|
883
|
+
labelKey: z.ZodString;
|
|
884
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
885
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
886
|
+
type: z.ZodLiteral<"secret">;
|
|
887
|
+
minLength: z.ZodOptional<z.ZodInt>;
|
|
888
|
+
maxLength: z.ZodOptional<z.ZodInt>;
|
|
889
|
+
}, z.core.$strip>], "type">>;
|
|
890
|
+
}, z.core.$strip>>;
|
|
891
|
+
view: z.ZodOptional<z.ZodObject<{
|
|
892
|
+
module: z.ZodDefault<z.ZodString>;
|
|
893
|
+
titleKey: z.ZodString;
|
|
894
|
+
section: z.ZodOptional<z.ZodEnum<{
|
|
895
|
+
association: "association";
|
|
896
|
+
board: "board";
|
|
897
|
+
building: "building";
|
|
898
|
+
settings: "settings";
|
|
899
|
+
}>>;
|
|
900
|
+
}, z.core.$strip>>;
|
|
901
|
+
actions: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
902
|
+
id: z.ZodString;
|
|
903
|
+
capability: z.ZodString;
|
|
904
|
+
effect: z.ZodEnum<{
|
|
905
|
+
delete: "delete";
|
|
906
|
+
read: "read";
|
|
907
|
+
write: "write";
|
|
908
|
+
}>;
|
|
909
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
910
|
+
account: "account";
|
|
911
|
+
apartment: "apartment";
|
|
912
|
+
auditTrail: "auditTrail";
|
|
913
|
+
email: "email";
|
|
914
|
+
financial: "financial";
|
|
915
|
+
freeText: "freeText";
|
|
916
|
+
health: "health";
|
|
917
|
+
name: "name";
|
|
918
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
919
|
+
phone: "phone";
|
|
920
|
+
photograph: "photograph";
|
|
921
|
+
postalAddress: "postalAddress";
|
|
922
|
+
protected: "protected";
|
|
923
|
+
residency: "residency";
|
|
924
|
+
}>>>;
|
|
925
|
+
surfaces: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
926
|
+
ai: "ai";
|
|
927
|
+
mcp: "mcp";
|
|
928
|
+
ui: "ui";
|
|
929
|
+
}>>>;
|
|
930
|
+
}, z.core.$strip>>>;
|
|
931
|
+
oauthProtectedResource: z.ZodOptional<z.ZodString>;
|
|
932
|
+
deviceRoutes: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
933
|
+
id: z.ZodString;
|
|
934
|
+
path: z.ZodString;
|
|
935
|
+
}, z.core.$strip>>>;
|
|
936
|
+
ai: z.ZodDefault<z.ZodBoolean>;
|
|
937
|
+
blocks: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
938
|
+
name: z.ZodString;
|
|
939
|
+
labelKey: z.ZodString;
|
|
940
|
+
icon: z.ZodDefault<z.ZodEnum<{
|
|
941
|
+
calendar: "calendar";
|
|
942
|
+
contact: "contact";
|
|
943
|
+
documents: "documents";
|
|
944
|
+
facts: "facts";
|
|
945
|
+
form: "form";
|
|
946
|
+
heading: "heading";
|
|
947
|
+
image: "image";
|
|
948
|
+
news: "news";
|
|
949
|
+
paragraph: "paragraph";
|
|
950
|
+
people: "people";
|
|
951
|
+
plugin: "plugin";
|
|
952
|
+
questions: "questions";
|
|
953
|
+
}>>;
|
|
954
|
+
category: z.ZodDefault<z.ZodEnum<{
|
|
955
|
+
association: "association";
|
|
956
|
+
media: "media";
|
|
957
|
+
text: "text";
|
|
958
|
+
}>>;
|
|
959
|
+
settingsSchema: z.ZodDefault<z.ZodObject<{
|
|
960
|
+
fields: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
961
|
+
key: z.ZodString;
|
|
962
|
+
labelKey: z.ZodString;
|
|
963
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
964
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
965
|
+
type: z.ZodLiteral<"text">;
|
|
966
|
+
default: z.ZodOptional<z.ZodString>;
|
|
967
|
+
minLength: z.ZodOptional<z.ZodInt>;
|
|
968
|
+
maxLength: z.ZodOptional<z.ZodInt>;
|
|
969
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
970
|
+
key: z.ZodString;
|
|
971
|
+
labelKey: z.ZodString;
|
|
972
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
973
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
974
|
+
type: z.ZodLiteral<"number">;
|
|
975
|
+
default: z.ZodOptional<z.ZodNumber>;
|
|
976
|
+
min: z.ZodOptional<z.ZodNumber>;
|
|
977
|
+
max: z.ZodOptional<z.ZodNumber>;
|
|
978
|
+
integer: z.ZodDefault<z.ZodBoolean>;
|
|
979
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
980
|
+
key: z.ZodString;
|
|
981
|
+
labelKey: z.ZodString;
|
|
982
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
983
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
984
|
+
type: z.ZodLiteral<"boolean">;
|
|
985
|
+
default: z.ZodOptional<z.ZodBoolean>;
|
|
986
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
987
|
+
key: z.ZodString;
|
|
988
|
+
labelKey: z.ZodString;
|
|
989
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
990
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
991
|
+
type: z.ZodLiteral<"select">;
|
|
992
|
+
default: z.ZodOptional<z.ZodString>;
|
|
993
|
+
options: z.ZodArray<z.ZodObject<{
|
|
994
|
+
value: z.ZodString;
|
|
995
|
+
labelKey: z.ZodString;
|
|
996
|
+
}, z.core.$strip>>;
|
|
997
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
998
|
+
key: z.ZodString;
|
|
999
|
+
labelKey: z.ZodString;
|
|
1000
|
+
hintKey: z.ZodOptional<z.ZodString>;
|
|
1001
|
+
required: z.ZodDefault<z.ZodBoolean>;
|
|
1002
|
+
type: z.ZodLiteral<"secret">;
|
|
1003
|
+
minLength: z.ZodOptional<z.ZodInt>;
|
|
1004
|
+
maxLength: z.ZodOptional<z.ZodInt>;
|
|
1005
|
+
}, z.core.$strip>], "type">>;
|
|
1006
|
+
}, z.core.$strip>>;
|
|
1007
|
+
}, z.core.$strict>>>;
|
|
1008
|
+
extensionPoints: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1009
|
+
id: z.ZodString;
|
|
1010
|
+
version: z.ZodInt;
|
|
1011
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
1012
|
+
account: "account";
|
|
1013
|
+
apartment: "apartment";
|
|
1014
|
+
auditTrail: "auditTrail";
|
|
1015
|
+
email: "email";
|
|
1016
|
+
financial: "financial";
|
|
1017
|
+
freeText: "freeText";
|
|
1018
|
+
health: "health";
|
|
1019
|
+
name: "name";
|
|
1020
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
1021
|
+
phone: "phone";
|
|
1022
|
+
photograph: "photograph";
|
|
1023
|
+
postalAddress: "postalAddress";
|
|
1024
|
+
protected: "protected";
|
|
1025
|
+
residency: "residency";
|
|
1026
|
+
}>>>;
|
|
1027
|
+
}, z.core.$strip>>>;
|
|
1028
|
+
extends: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1029
|
+
plugin: z.ZodString;
|
|
1030
|
+
point: z.ZodString;
|
|
1031
|
+
version: z.ZodInt;
|
|
1032
|
+
personalData: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
1033
|
+
account: "account";
|
|
1034
|
+
apartment: "apartment";
|
|
1035
|
+
auditTrail: "auditTrail";
|
|
1036
|
+
email: "email";
|
|
1037
|
+
financial: "financial";
|
|
1038
|
+
freeText: "freeText";
|
|
1039
|
+
health: "health";
|
|
1040
|
+
name: "name";
|
|
1041
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
1042
|
+
phone: "phone";
|
|
1043
|
+
photograph: "photograph";
|
|
1044
|
+
postalAddress: "postalAddress";
|
|
1045
|
+
protected: "protected";
|
|
1046
|
+
residency: "residency";
|
|
1047
|
+
}>>>;
|
|
1048
|
+
}, z.core.$strip>>>;
|
|
1049
|
+
recipients: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
1050
|
+
id: z.ZodString;
|
|
1051
|
+
origin: z.ZodString;
|
|
1052
|
+
purpose: z.ZodObject<{
|
|
1053
|
+
sv: z.ZodString;
|
|
1054
|
+
en: z.ZodString;
|
|
1055
|
+
}, z.core.$strict>;
|
|
1056
|
+
personalData: z.ZodArray<z.ZodEnum<{
|
|
1057
|
+
account: "account";
|
|
1058
|
+
apartment: "apartment";
|
|
1059
|
+
auditTrail: "auditTrail";
|
|
1060
|
+
email: "email";
|
|
1061
|
+
financial: "financial";
|
|
1062
|
+
freeText: "freeText";
|
|
1063
|
+
health: "health";
|
|
1064
|
+
name: "name";
|
|
1065
|
+
personalIdentityNumber: "personalIdentityNumber";
|
|
1066
|
+
phone: "phone";
|
|
1067
|
+
photograph: "photograph";
|
|
1068
|
+
postalAddress: "postalAddress";
|
|
1069
|
+
protected: "protected";
|
|
1070
|
+
residency: "residency";
|
|
1071
|
+
}>>;
|
|
1072
|
+
}, z.core.$strip>>>;
|
|
1073
|
+
licence: z.ZodOptional<z.ZodObject<{
|
|
1074
|
+
entitlement: z.ZodString;
|
|
1075
|
+
issuer: z.ZodObject<{
|
|
1076
|
+
name: z.ZodString;
|
|
1077
|
+
url: z.ZodString;
|
|
1078
|
+
}, z.core.$strict>;
|
|
1079
|
+
keys: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
1080
|
+
audiences: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
1081
|
+
}, z.core.$strict>>;
|
|
1082
|
+
released: z.ZodOptional<z.ZodString>;
|
|
1083
|
+
}, z.core.$strip>;
|
|
1084
|
+
dependencies: z.ZodOptional<z.ZodUnknown>;
|
|
1085
|
+
optionalDependencies: z.ZodOptional<z.ZodUnknown>;
|
|
1086
|
+
bundleDependencies: z.ZodOptional<z.ZodUnknown>;
|
|
1087
|
+
bundledDependencies: z.ZodOptional<z.ZodUnknown>;
|
|
1088
|
+
}, z.core.$strip>;
|
|
1089
|
+
export type PluginPackage = z.infer<typeof pluginPackageSchema>;
|
|
1090
|
+
export interface ManifestParseFailure {
|
|
1091
|
+
ok: false;
|
|
1092
|
+
/** One line per problem, already naming the field. */
|
|
1093
|
+
issues: string[];
|
|
1094
|
+
/**
|
|
1095
|
+
* The same problems, each with the code of the rule it broke when it broke
|
|
1096
|
+
* one a board reads in its own language (`PLUGIN_MANIFEST_RULES`), and null
|
|
1097
|
+
* when it is a field's own problem.
|
|
1098
|
+
*/
|
|
1099
|
+
diagnostics: {
|
|
1100
|
+
rule: PluginManifestRule | null;
|
|
1101
|
+
issue: string;
|
|
1102
|
+
}[];
|
|
1103
|
+
}
|
|
1104
|
+
export type ManifestParseResult = {
|
|
1105
|
+
ok: true;
|
|
1106
|
+
value: PluginPackage;
|
|
1107
|
+
} | ManifestParseFailure;
|
|
1108
|
+
/**
|
|
1109
|
+
* Parses a plugin's package.json.
|
|
1110
|
+
*
|
|
1111
|
+
* Returns a result rather than throwing, because the only caller that matters
|
|
1112
|
+
* is the boot-time scan, and a malformed plugin directory must be skipped and
|
|
1113
|
+
* reported rather than being allowed to take the register offline (ADR 0003).
|
|
1114
|
+
* A thrown error would make "skip and report" the caller's discipline instead
|
|
1115
|
+
* of the function's contract.
|
|
1116
|
+
*/
|
|
1117
|
+
export declare function parsePluginPackage(input: unknown): ManifestParseResult;
|
|
1118
|
+
/** Convenience for a plugin's own CI: throws with every problem at once. */
|
|
1119
|
+
export declare function assertPluginPackage(input: unknown): PluginPackage;
|
|
1120
|
+
/** The api version a plugin authored against this SDK should declare. */
|
|
1121
|
+
export declare const CURRENT_PLUGIN_API_VERSION = 1;
|
|
1122
|
+
//# sourceMappingURL=manifest.d.ts.map
|