@openbrf/plugin-sdk 1.0.0 → 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.
Files changed (100) hide show
  1. package/README.md +95 -0
  2. package/dist/abort-signal.d.ts +23 -0
  3. package/dist/abort-signal.d.ts.map +1 -0
  4. package/dist/abort-signal.js +2 -0
  5. package/dist/abort-signal.js.map +1 -0
  6. package/dist/action-refusal.d.ts +101 -0
  7. package/dist/action-refusal.d.ts.map +1 -0
  8. package/dist/action-refusal.js +96 -0
  9. package/dist/action-refusal.js.map +1 -0
  10. package/dist/action-schema.d.ts.map +1 -1
  11. package/dist/action-schema.js +4 -1
  12. package/dist/action-schema.js.map +1 -1
  13. package/dist/actions.d.ts +94 -6
  14. package/dist/actions.d.ts.map +1 -1
  15. package/dist/actions.js.map +1 -1
  16. package/dist/blocks.d.ts +310 -0
  17. package/dist/blocks.d.ts.map +1 -0
  18. package/dist/blocks.js +185 -0
  19. package/dist/blocks.js.map +1 -0
  20. package/dist/catalog.d.ts +399 -7
  21. package/dist/catalog.d.ts.map +1 -1
  22. package/dist/catalog.js +373 -9
  23. package/dist/catalog.js.map +1 -1
  24. package/dist/entitlements.d.ts +117 -0
  25. package/dist/entitlements.d.ts.map +1 -0
  26. package/dist/entitlements.js +62 -0
  27. package/dist/entitlements.js.map +1 -0
  28. package/dist/extensions.d.ts +183 -0
  29. package/dist/extensions.d.ts.map +1 -0
  30. package/dist/extensions.js +67 -0
  31. package/dist/extensions.js.map +1 -0
  32. package/dist/finances.d.ts +294 -0
  33. package/dist/finances.d.ts.map +1 -0
  34. package/dist/finances.js +56 -0
  35. package/dist/finances.js.map +1 -0
  36. package/dist/findings.d.ts +90 -1
  37. package/dist/findings.d.ts.map +1 -1
  38. package/dist/findings.js +89 -0
  39. package/dist/findings.js.map +1 -1
  40. package/dist/host.d.ts +621 -2
  41. package/dist/host.d.ts.map +1 -1
  42. package/dist/host.js +39 -0
  43. package/dist/host.js.map +1 -1
  44. package/dist/imports.d.ts +104 -0
  45. package/dist/imports.d.ts.map +1 -0
  46. package/dist/imports.js +70 -0
  47. package/dist/imports.js.map +1 -0
  48. package/dist/index.d.ts +17 -7
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +15 -6
  51. package/dist/index.js.map +1 -1
  52. package/dist/localized-text.d.ts +18 -0
  53. package/dist/localized-text.d.ts.map +1 -0
  54. package/dist/localized-text.js +17 -0
  55. package/dist/localized-text.js.map +1 -0
  56. package/dist/manifest.d.ts +730 -0
  57. package/dist/manifest.d.ts.map +1 -1
  58. package/dist/manifest.js +805 -11
  59. package/dist/manifest.js.map +1 -1
  60. package/dist/permissions.d.ts +170 -11
  61. package/dist/permissions.d.ts.map +1 -1
  62. package/dist/permissions.js +210 -2
  63. package/dist/permissions.js.map +1 -1
  64. package/dist/recipients.d.ts +139 -0
  65. package/dist/recipients.d.ts.map +1 -0
  66. package/dist/recipients.js +223 -0
  67. package/dist/recipients.js.map +1 -0
  68. package/dist/records.d.ts +130 -0
  69. package/dist/records.d.ts.map +1 -0
  70. package/dist/records.js +85 -0
  71. package/dist/records.js.map +1 -0
  72. package/dist/require-capability.d.ts +37 -0
  73. package/dist/require-capability.d.ts.map +1 -0
  74. package/dist/require-capability.js +88 -0
  75. package/dist/require-capability.js.map +1 -0
  76. package/dist/settings-schema.d.ts +35 -0
  77. package/dist/settings-schema.d.ts.map +1 -1
  78. package/dist/settings-schema.js +55 -2
  79. package/dist/settings-schema.js.map +1 -1
  80. package/package.json +4 -4
  81. package/src/abort-signal.ts +22 -0
  82. package/src/action-refusal.ts +178 -0
  83. package/src/action-schema.ts +4 -1
  84. package/src/actions.ts +103 -6
  85. package/src/blocks.ts +289 -0
  86. package/src/catalog.ts +500 -57
  87. package/src/entitlements.ts +150 -0
  88. package/src/extensions.ts +212 -0
  89. package/src/finances.ts +317 -0
  90. package/src/findings.ts +92 -0
  91. package/src/host.ts +656 -2
  92. package/src/imports.ts +135 -0
  93. package/src/index.ts +193 -0
  94. package/src/localized-text.ts +19 -0
  95. package/src/manifest.ts +1039 -12
  96. package/src/permissions.ts +223 -3
  97. package/src/recipients.ts +294 -0
  98. package/src/records.ts +172 -0
  99. package/src/require-capability.ts +106 -0
  100. package/src/settings-schema.ts +64 -2
package/src/imports.ts ADDED
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Handing a member list to the board (ADR 0043).
3
+ *
4
+ * A plugin that brings the association's member list in from elsewhere - a
5
+ * file mailed to an address, an export fetched from the economic manager's
6
+ * system - hands it to the core here, and the core holds it as an **import
7
+ * proposal**: an import session on the core's own import screen, marked as
8
+ * proposed by the plugin, which a board member previews, decides and applies,
9
+ * or rejects. The plugin never applies anything, and it learns nothing about
10
+ * what the file would do: each of those is a read of the register, and the
11
+ * permission behind this, addressBook:proposeImport, grants none.
12
+ */
13
+
14
+ /** The file a plugin hands over. */
15
+ export interface ImportProposalFile {
16
+ /** Shown to the board beside the proposal. 1 to 255 characters. */
17
+ fileName: string;
18
+ /**
19
+ * The file, CSV or XLSX, which the core parses exactly as it parses an
20
+ * upload, with the same limits. A source that gives JSON is written out as
21
+ * CSV first.
22
+ */
23
+ content: Uint8Array;
24
+ /**
25
+ * Who sent the file, as the source reports it: the address an email came
26
+ * from. Absent for a source that has no sender, such as a fetch from a
27
+ * manager's system. A claim, not a verified identity, and shown to the board
28
+ * as one. At most 320 characters.
29
+ */
30
+ sender?: string;
31
+ }
32
+
33
+ export interface ImportProposalReceipt {
34
+ proposalId: string;
35
+ /** Data rows read from the file, below its column titles. */
36
+ rowCount: number;
37
+ /** ISO 8601. When the proposal expires if nobody decides it. */
38
+ expiresAt: string;
39
+ }
40
+
41
+ /** Where one of the plugin's own proposals stands. */
42
+ export const IMPORT_PROPOSAL_STATES = [
43
+ /** Waiting for the board. */
44
+ "pending",
45
+ /** A board member started the import, and it is being written. */
46
+ "applying",
47
+ "applied",
48
+ /** The import a board member started stopped before the end. */
49
+ "failed",
50
+ "rejected",
51
+ /** A newer proposal from the same plugin replaced it. */
52
+ "superseded",
53
+ /** Nobody decided it in time. */
54
+ "expired",
55
+ /** The plugin took it back. */
56
+ "withdrawn",
57
+ /** Not one of this plugin's proposals, or no longer kept. */
58
+ "unknown",
59
+ ] as const;
60
+
61
+ export type ImportProposalState = (typeof IMPORT_PROPOSAL_STATES)[number];
62
+
63
+ export interface ImportProposalStatus {
64
+ state: ImportProposalState;
65
+ /** ISO 8601. When it reached the state it is in. Null while pending or unknown. */
66
+ decidedAt: string | null;
67
+ }
68
+
69
+ /**
70
+ * Why a file was refused. Nothing was stored for it.
71
+ *
72
+ * The reasons an upload is refused for, and four of a proposal's own:
73
+ * `file-unchanged` when the rows are those of the last file from this plugin
74
+ * the board applied or of the one still pending, `sender-too-long`,
75
+ * `sender-invalid` when the sender is neither text nor left out, and
76
+ * `file-name-invalid`. Treat a reason you do not know as a refusal all the
77
+ * same: a later core may add one.
78
+ */
79
+ export const IMPORT_PROPOSAL_REFUSAL_REASONS = [
80
+ "file-name-invalid",
81
+ "file-empty",
82
+ "header-row-missing",
83
+ "file-too-large",
84
+ "file-unreadable",
85
+ "file-mixed-encoding",
86
+ "too-many-rows",
87
+ "too-many-columns",
88
+ "cell-too-long",
89
+ "unterminated-quote",
90
+ "workbook-too-large",
91
+ "file-unchanged",
92
+ "sender-too-long",
93
+ "sender-invalid",
94
+ ] as const;
95
+
96
+ export type ImportProposalRefusalReason =
97
+ (typeof IMPORT_PROPOSAL_REFUSAL_REASONS)[number];
98
+
99
+ /**
100
+ * `host.imports.propose` refused the file. Carries the reason and nothing from
101
+ * the file, so it can be logged as it is.
102
+ */
103
+ export class ImportProposalRefusedError extends Error {
104
+ constructor(readonly reason: string) {
105
+ super(`The core refused the import proposal: ${reason}.`);
106
+ this.name = "ImportProposalRefusedError";
107
+ }
108
+ }
109
+
110
+ /**
111
+ * Proposing imports. Requires addressBook:proposeImport.
112
+ *
113
+ * A plugin has at most one pending proposal: a new one replaces the one
114
+ * before, which becomes `superseded`. A proposal nobody decides expires after
115
+ * 14 days, and a decided one stays answerable by `status` for 90 days.
116
+ *
117
+ * What the plugin must not keep, which the catalog review checks: the file,
118
+ * or any part of it, is never passed to `host.jobs`, written to the log, the
119
+ * settings, any store the host offers or an error the plugin throws, and the
120
+ * plugin drops its copy once `propose` has answered. The sender likewise.
121
+ */
122
+ export interface PluginImports {
123
+ /**
124
+ * Hands a member list to the core for the board to review. Resolves once the
125
+ * core has parsed the file and stored the proposal, or rejects with
126
+ * ImportProposalRefusedError and stores nothing.
127
+ */
128
+ propose(file: ImportProposalFile): Promise<ImportProposalReceipt>;
129
+
130
+ /** Where one of this plugin's own proposals stands. */
131
+ status(proposalId: string): Promise<ImportProposalStatus>;
132
+
133
+ /** Withdraws this plugin's pending proposal. True when there was one. */
134
+ withdraw(proposalId: string): Promise<boolean>;
135
+ }
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@
8
8
  * a plugin ship as a self-contained bundle (ADR 0003).
9
9
  */
10
10
 
11
+ export type { PluginAbortSignal } from "./abort-signal.ts";
11
12
  export {
12
13
  ACTION_CHANNELS,
13
14
  ACTION_EFFECTS,
@@ -23,12 +24,24 @@ export {
23
24
  type ActionPersonalData,
24
25
  type ActionPrincipal,
25
26
  type ActionRequest,
27
+ type ActionRetry,
26
28
  type ActionSummary,
27
29
  type ActionSurface,
30
+ type PendingChangeReceipt,
31
+ type ActionWithSchemas,
28
32
  type PluginActionFilter,
29
33
  type PluginActionRegistration,
30
34
  type PluginActions,
31
35
  } from "./actions.ts";
36
+ export {
37
+ ACTION_ERROR_MCP,
38
+ ACTION_ERROR_REASONS,
39
+ type ActionErrorReason,
40
+ type ActionRefusal,
41
+ type ActionRefusalKind,
42
+ type ActionRefusalTransport,
43
+ isActionRefusal,
44
+ } from "./action-refusal.ts";
32
45
  export {
33
46
  actionInputJsonSchema,
34
47
  actionOutputJsonSchema,
@@ -39,15 +52,44 @@ export {
39
52
  PLUGIN_API_VERSION,
40
53
  SUPPORTED_PLUGIN_API_VERSIONS,
41
54
  } from "./api-version.ts";
55
+ export {
56
+ PLUGIN_BLOCK_ATTRIBUTES,
57
+ PLUGIN_BLOCK_CATEGORIES,
58
+ PLUGIN_BLOCK_ELEMENTS,
59
+ PLUGIN_BLOCK_ICONS,
60
+ PLUGIN_BLOCK_NAME_PATTERN,
61
+ PLUGIN_BLOCK_RENDER_TIMEOUT_MS,
62
+ type PluginBlockAbortSignal,
63
+ type PluginBlockCategory,
64
+ type PluginBlockContent,
65
+ type PluginBlockDeclaration,
66
+ type PluginBlockElement,
67
+ type PluginBlockElementName,
68
+ type PluginBlockIcon,
69
+ type PluginBlockNode,
70
+ type PluginBlockRegistration,
71
+ type PluginBlockRenderContext,
72
+ type PluginBlocks,
73
+ pluginBlockSchema,
74
+ pluginBlocksSchema,
75
+ pluginBlockType,
76
+ } from "./blocks.ts";
42
77
  export {
43
78
  type Catalog,
79
+ CATALOG_INDEX_VERSIONS,
80
+ CATALOG_REFUSALS,
44
81
  type CatalogArtifact,
45
82
  catalogArtifactSchema,
83
+ type CatalogDiagnostic,
46
84
  type CatalogEntry,
47
85
  catalogEntrySchema,
86
+ type CatalogExtensionPoint,
87
+ catalogExtensionPointSchema,
48
88
  type CatalogParseResult,
49
89
  type CatalogPluginEntry,
50
90
  catalogPluginEntrySchema,
91
+ type CatalogRefusal,
92
+ type CatalogRefusalCode,
51
93
  catalogSchema,
52
94
  type CatalogThemeEntry,
53
95
  catalogThemeEntrySchema,
@@ -55,51 +97,174 @@ export {
55
97
  parseCatalogIndex,
56
98
  } from "./catalog.ts";
57
99
  export { definePlugin } from "./define-plugin.ts";
100
+ export {
101
+ createTestEntitlements,
102
+ ENTITLEMENT_STATUSES,
103
+ type EntitlementState,
104
+ type EntitlementStatus,
105
+ LICENCE_FILE_MAX_BYTES,
106
+ LICENCE_FORMAT,
107
+ LICENCE_PRESENTATION_FORMAT,
108
+ LICENCE_PRESENTATION_MAX_BYTES,
109
+ type PluginEntitlements,
110
+ type TestEntitlementsOptions,
111
+ undeclaredAudienceError,
112
+ } from "./entitlements.ts";
113
+ export {
114
+ EXTENSION_MAX_OUTPUT_LENGTH,
115
+ EXTENSION_MAX_TIMEOUT_MS,
116
+ EXTENSION_POINT_ID_PATTERN,
117
+ EXTENSION_RESULT_REASONS,
118
+ EXTENSION_TIMEOUT_MS,
119
+ type ExtensionContext,
120
+ type ExtensionContributionDefinition,
121
+ type ExtensionContributionSummary,
122
+ type ExtensionPointDefinition,
123
+ type ExtensionResult,
124
+ type ExtensionResultReason,
125
+ type ExtensionTarget,
126
+ MAX_EXTENSION_POINTS,
127
+ type PluginExtensions,
128
+ } from "./extensions.ts";
129
+ export {
130
+ PLUGIN_FINANCE_EVENTS,
131
+ PluginDeliveryRefusedError,
132
+ type PluginDeliveryReceipt,
133
+ type PluginDeliveryReceiptInput,
134
+ type PluginDeliveryReference,
135
+ type PluginFeeNotice,
136
+ type PluginFeeNoticeHolders,
137
+ type PluginFeeNotification,
138
+ type PluginFeeNotificationSummary,
139
+ type PluginFinanceEvent,
140
+ type PluginFinanceEvents,
141
+ type PluginFinanceEventType,
142
+ type PluginFinances,
143
+ type PluginMemberCharge,
144
+ type PluginMemberChargeParty,
145
+ type PluginMemberChargeReason,
146
+ } from "./finances.ts";
147
+ export {
148
+ IMPORT_PROPOSAL_REFUSAL_REASONS,
149
+ IMPORT_PROPOSAL_STATES,
150
+ type ImportProposalFile,
151
+ type ImportProposalReceipt,
152
+ type ImportProposalRefusalReason,
153
+ ImportProposalRefusedError,
154
+ type ImportProposalState,
155
+ type ImportProposalStatus,
156
+ type PluginImports,
157
+ } from "./imports.ts";
58
158
  export { formatSha512, IntegrityError, parseSha512 } from "./integrity.ts";
59
159
  export {
60
160
  PLUGIN_FINDING_REASONS,
161
+ PLUGIN_MANIFEST_RULES,
61
162
  type PluginFindingDetail,
62
163
  type PluginFindingReason,
164
+ type PluginManifestRule,
63
165
  } from "./findings.ts";
64
166
  export {
167
+ PLUGIN_RECIPIENT_ERROR_CODES,
168
+ type DeviceTokenSummary,
169
+ type PluginAddress,
65
170
  type PluginAddressBook,
171
+ type PluginAddresses,
66
172
  type PluginApartment,
173
+ type PluginBookableResource,
174
+ type PluginBookings,
175
+ type PluginBusyInterval,
176
+ type PluginCalendar,
177
+ type PluginContentAudience,
178
+ type PluginDevices,
179
+ type PluginDisclosure,
67
180
  type PluginHost,
68
181
  PluginHostUnavailableError,
69
182
  type PluginJobs,
70
183
  type PluginLogger,
71
184
  type PluginMail,
72
185
  type PluginMailMessage,
186
+ type PluginMedia,
187
+ type PluginMediaFile,
188
+ type PluginMediaStream,
189
+ type PluginMeetingNotice,
190
+ type PluginNews,
191
+ type PluginNewsItem,
73
192
  type PluginOccupancySummary,
193
+ type PluginOccurrence,
74
194
  PluginPermissionError,
195
+ PluginRecipientError,
196
+ type PluginRecipientErrorCode,
197
+ type PluginRecipientRequest,
198
+ type PluginRecipientResponse,
199
+ type PluginRecipients,
75
200
  type PluginResident,
76
201
  type PluginSettings,
202
+ type PluginInstalledTheme,
77
203
  type PluginSms,
78
204
  type PluginSmsMessage,
205
+ type PluginThemeInstallOptions,
206
+ type PluginThemeInstallResult,
207
+ type PluginThemeInstallWarning,
208
+ type PluginThemes,
79
209
  } from "./host.ts";
80
210
  export type { PluginModuleFactory } from "./module.ts";
81
211
  export {
82
212
  assertPluginPackage,
83
213
  composedActionName,
84
214
  CURRENT_PLUGIN_API_VERSION,
215
+ declaredExtensionPointsSchema,
216
+ declaredExtensionsSchema,
217
+ extensionGroupRefusals,
218
+ extensionHostPersonalDataRefused,
219
+ extensionPermissionsRefused,
220
+ extensionPointIdSchema,
221
+ extensionPointRefusal,
222
+ type ExtensionPointRefusal,
223
+ extensionRuleIssues,
224
+ MAX_DEVICE_ROUTES,
225
+ isCalendarDay,
226
+ licenceAudienceSchema,
227
+ licenceKeyIdSchema,
228
+ licencePublicKeySchema,
85
229
  type ManifestParseResult,
86
230
  type PluginActionDeclaration,
87
231
  pluginActionSchema,
88
232
  pluginActionsSchema,
233
+ type PluginDeviceRoute,
234
+ pluginDeviceRouteSchema,
235
+ pluginDeviceRoutesSchema,
89
236
  type PluginEntry,
90
237
  pluginEntrySchema,
238
+ type PluginExtensionDeclaration,
239
+ type PluginExtensionPointDeclaration,
240
+ pluginExtensionPointSchema,
241
+ pluginExtensionSchema,
91
242
  pluginIdSchema,
243
+ type PluginLicenceDeclaration,
244
+ pluginLicenceSchema,
92
245
  type PluginManifest,
93
246
  pluginManifestSchema,
94
247
  type PluginPackage,
95
248
  pluginPackageSchema,
249
+ type PluginView,
250
+ pluginViewSchema,
251
+ type PluginViewSection,
252
+ PLUGIN_VIEW_SECTIONS,
96
253
  parsePluginPackage,
254
+ proposeImportPersonalDataIssues,
255
+ routePathsOverlap,
97
256
  } from "./manifest.ts";
98
257
  export {
99
258
  HOST_SHARED_PACKAGES,
100
259
  type PluginPackageContents,
101
260
  pluginPackageProblems,
102
261
  } from "./package-check.ts";
262
+ export {
263
+ PLUGIN_ROUTE_CAPABILITIES,
264
+ type PluginRouteCapability,
265
+ REQUIRED_CAPABILITIES_KEY,
266
+ RequireCapability,
267
+ } from "./require-capability.ts";
103
268
  export type {
104
269
  StandardSchemaIssue,
105
270
  StandardSchemaResult,
@@ -111,7 +276,33 @@ export {
111
276
  PLUGIN_PERSONAL_DATA_CATEGORIES,
112
277
  type PluginPermission,
113
278
  type PluginPersonalDataCategory,
279
+ PROPOSE_IMPORT_ONLY_PERSONAL_DATA,
280
+ PROPOSE_IMPORT_PERSONAL_DATA,
114
281
  } from "./permissions.ts";
282
+ export {
283
+ canonicalRecipient,
284
+ type PluginRecipient,
285
+ pluginRecipientSchema,
286
+ pluginRecipientsSchema,
287
+ RECEIVING_HOSTS_MAX_LENGTH,
288
+ receivingHosts,
289
+ recipientHost,
290
+ recipientOriginSchema,
291
+ recipientsBeyondConsent,
292
+ sameRecipientDeclaration,
293
+ } from "./recipients.ts";
294
+ export {
295
+ type JsonValue,
296
+ PLUGIN_RECORD_COLLECTION_PATTERN,
297
+ PLUGIN_RECORD_KEY_PATTERN,
298
+ PLUGIN_RECORD_LIMITS,
299
+ type PluginRecord,
300
+ PluginRecordConflictError,
301
+ PluginRecordIdentityNumberError,
302
+ type PluginRecordLimit,
303
+ PluginRecordLimitError,
304
+ type PluginRecords,
305
+ } from "./records.ts";
115
306
  export {
116
307
  defaultSettings,
117
308
  type PluginSettingsField,
@@ -119,5 +310,7 @@ export {
119
310
  type PluginSettingsSchema,
120
311
  pluginSettingsSchema,
121
312
  type PluginSettingsValues,
313
+ secretValueValidator,
122
314
  settingsValidator,
315
+ withoutSecretFields,
123
316
  } from "./settings-schema.ts";
@@ -0,0 +1,19 @@
1
+ import { z } from "zod";
2
+
3
+ /**
4
+ * Text written in both languages the interface is offered in.
5
+ *
6
+ * For what the board reads before anything has been downloaded: the catalog's
7
+ * own name and description of an entry, and the parts of a declaration the
8
+ * consent screen shows, such as a recipient's purpose. A plugin's locale files
9
+ * reach the instance with its package, so a key into them would have no words
10
+ * behind it on the screen that decides whether the package is fetched.
11
+ *
12
+ * Strict, so a misspelled language is refused rather than dropped.
13
+ */
14
+ export const localizedTextSchema = z.strictObject({
15
+ sv: z.string().min(1).max(500),
16
+ en: z.string().min(1).max(500),
17
+ });
18
+
19
+ export type LocalizedText = z.infer<typeof localizedTextSchema>;