@rocketman-streamkit/types 1.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.
Files changed (3) hide show
  1. package/README.md +182 -0
  2. package/addon.d.ts +1123 -0
  3. package/package.json +23 -0
package/README.md ADDED
@@ -0,0 +1,182 @@
1
+ # @rocketman-streamkit/types
2
+
3
+ TypeScript declarations for the **StreamKit+** integration addon sandbox API.
4
+
5
+ Use this package when developing worker addons outside the StreamKit+ repository. It provides global typings for `network`, `events`, `permissions`, `dashboard`, `GenerateConfig`, and the rest of the VM sandbox surface — the same declarations that StreamKit+ generates from its internal API source.
6
+
7
+ > **Version sync:** package version matches the StreamKit+ app release it was built from. Install a version that corresponds to the StreamKit+ build your addon targets.
8
+
9
+ ---
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install --save-dev @rocketman-streamkit/types
15
+ ```
16
+
17
+ Or with yarn / pnpm:
18
+
19
+ ```bash
20
+ yarn add -D @rocketman-streamkit/types
21
+ pnpm add -D @rocketman-streamkit/types
22
+ ```
23
+
24
+ ---
25
+
26
+ ## Setup
27
+
28
+ Addon worker code runs inside a VM with **global** sandbox APIs — no `import` of the SDK at runtime. TypeScript only needs the declaration file for editor checks and `tsc --noEmit`.
29
+
30
+ ### Recommended `tsconfig.json`
31
+
32
+ ```json
33
+ {
34
+ "compilerOptions": {
35
+ "types": [],
36
+ "lib": ["ES2020"],
37
+ "noEmit": true,
38
+ "strict": true,
39
+ "skipLibCheck": true
40
+ },
41
+ "include": ["./**/*.ts", "./node_modules/@rocketman-streamkit/types/addon.d.ts"]
42
+ }
43
+ ```
44
+
45
+ Alternatively, reference the package types field directly:
46
+
47
+ ```json
48
+ {
49
+ "compilerOptions": {
50
+ "types": ["@rocketman-streamkit/types"],
51
+ "lib": ["ES2020"],
52
+ "noEmit": true,
53
+ "strict": true,
54
+ "skipLibCheck": true
55
+ },
56
+ "include": ["./**/*.ts"]
57
+ }
58
+ ```
59
+
60
+ Do **not** add `@types/node` — addon workers are not Node.js processes.
61
+
62
+ ---
63
+
64
+ ## Examples
65
+
66
+ ### HTTP endpoint
67
+
68
+ Register a POST handler exposed at `http://localhost:{port}/addon/{yourAddonId}/hook`:
69
+
70
+ ```typescript
71
+ network.endpoints.create('hook', 'POST', 'onHook');
72
+
73
+ events.On('onHook', ({ body, query, params }) => {
74
+ console.log('Incoming webhook', body);
75
+ return { ok: true };
76
+ });
77
+ ```
78
+
79
+ ### Settings schema
80
+
81
+ Call `GenerateConfig` once at addon load to register settings fields shown in the StreamKit+ UI:
82
+
83
+ ```typescript
84
+ await GenerateConfig([
85
+ {
86
+ key: 'channel_id',
87
+ type: 'text',
88
+ default: '',
89
+ editor: {
90
+ label: { en: 'Channel ID', ru: 'ID канала' },
91
+ required: true,
92
+ },
93
+ },
94
+ {
95
+ key: 'enabled',
96
+ type: 'boolean',
97
+ default: true,
98
+ editor: { label: { en: 'Enabled' } },
99
+ },
100
+ ]);
101
+
102
+ const params = await api.config.getParams<{ channel_id: string; enabled: boolean }>();
103
+ ```
104
+
105
+ ### Outbound HTTP request
106
+
107
+ Requires `NETWORK_REQUEST` permission in `manifest.json`:
108
+
109
+ ```typescript
110
+ const response = await network.request.get('https://api.example.com/status');
111
+ console.log(response.status, response.body);
112
+ ```
113
+
114
+ ### Dashboard events
115
+
116
+ Requires `DASHBOARD_EVENTS` permission:
117
+
118
+ ```typescript
119
+ dashboard.registerPlatform({ id: 'my_platform', name: { en: 'My Platform' } });
120
+
121
+ dashboard.addRecord(
122
+ {
123
+ type: 'follow',
124
+ platform: 'my_platform',
125
+ message: { en: 'New follower!' },
126
+ },
127
+ { id: 'user_1', name: 'ViewerName' }
128
+ );
129
+ ```
130
+
131
+ ### Addon-to-addon RPC
132
+
133
+ Request data from another enabled addon:
134
+
135
+ ```typescript
136
+ // In addon A
137
+ addons.onRequest('getChannelId', () => ({ channelId: '12345' }));
138
+
139
+ // In addon B
140
+ const { channelId } = await addons.request<{ channelId: string }>(
141
+ 'addon_a',
142
+ 'getChannelId'
143
+ );
144
+ ```
145
+
146
+ ---
147
+
148
+ ## `manifest.json` permissions
149
+
150
+ Declared permissions must match sandbox API usage. Common values:
151
+
152
+ | Permission | Used for |
153
+ | --- | --- |
154
+ | `WEB_END_POINTS` | `network.endpoints.create` |
155
+ | `NETWORK_REQUEST` | `network.request.*` |
156
+ | `NETWORK_WEBSOCKET` | `network.websocket.connect` |
157
+ | `DASHBOARD_EVENTS` | `dashboard.addRecord`, `dashboard.registerTriggers` |
158
+ | `DASHBOARD_CHAT` | `dashboard.addChatMessage`, chat badges |
159
+ | `WEB_CONTENT` | Static web page served at `/addon_static/{id}/` |
160
+ | `STATUS` | `status.Update`, `status.OnClick` |
161
+ | `NOTIFY` | `notify.Send` |
162
+
163
+ See the `AddonsPermission` union in the declaration file for the full list.
164
+
165
+ ---
166
+
167
+ ## What's included
168
+
169
+ The published `addon.d.ts` is a `declare global` module:
170
+
171
+ - Sandbox globals: `network`, `events`, `permissions`, `api`, `dashboard`, `addons`, `data`, `status`, `notify`, `game`, `storage`, `crypto`, timers, etc.
172
+ - `GenerateConfig` and settings schema types
173
+ - `AddonsPermission` enum-as-union
174
+ - Supporting types (`DashboardLocalizedText`, config field types, …)
175
+
176
+ Runtime behaviour (timeouts, host blocklists, permission gates) is enforced by StreamKit+ — typings describe the API surface only.
177
+
178
+ ---
179
+
180
+ ## Support
181
+
182
+ This package tracks the StreamKit+ sandbox API. If typings are missing or outdated for your app version, install the matching `@rocketman-streamkit/types` release or report an issue to the StreamKit+ maintainers.
package/addon.d.ts ADDED
@@ -0,0 +1,1123 @@
1
+ // AUTO-GENERATED — do not edit manually
2
+ // Source: backend/addons/list/integrations/index.ts -> GenerateContext()
3
+
4
+ declare global {
5
+ type URLSearchParamsInit = | string
6
+ | Record<string, string>
7
+ | Iterable<[string, string]>
8
+ | ReadonlyArray<[string, string]>
9
+ | URLSearchParams;
10
+
11
+ declare class URLSearchParams {
12
+ constructor(init?: URLSearchParamsInit);
13
+ static from(native: URLSearchParams): URLSearchParams;
14
+ append(name: string, value: string): void;
15
+ delete(name: string, value?: string): void;
16
+ get(name: string): string | null;
17
+ getAll(name: string): string[];
18
+ has(name: string, value?: string): boolean;
19
+ set(name: string, value: string): void;
20
+ sort(): void;
21
+ toString(): string;
22
+ keys(): IterableIterator<string>;
23
+ values(): IterableIterator<string>;
24
+ entries(): IterableIterator<[string, string]>;
25
+ forEach(callback: (value: string, key: string, parent: URLSearchParams) => void, thisArg: unknown): void;
26
+ [Symbol.iterator](): IterableIterator<[string, string]>;
27
+ size: number;
28
+ }
29
+
30
+ declare class UrlCustom {
31
+ constructor(url: string | UrlCustom, base?: string | UrlCustom);
32
+ static canParse(url: string, base?: string | UrlCustom): boolean;
33
+ static parse(url: string, base?: string | UrlCustom): UrlCustom | null;
34
+ toString(): string;
35
+ toJSON(): string;
36
+ href: string;
37
+ origin: string;
38
+ protocol: string;
39
+ username: string;
40
+ password: string;
41
+ host: string;
42
+ hostname: string;
43
+ port: string;
44
+ pathname: string;
45
+ search: string;
46
+ searchParams: URLSearchParams;
47
+ hash: string;
48
+ }
49
+
50
+ type AddonStatusState = 'offline' | 'connecting' | 'online' | 'error';
51
+
52
+ type LangData = string;
53
+
54
+ type AddonConfigLang = 'en' | 'ru' | 'uk';
55
+
56
+ /**
57
+ * Per-language text; `en` is required, other locales are optional.
58
+ */
59
+ type DashboardLocalizedText = { en: string } & Partial<
60
+ Record<Exclude<AddonConfigLang, 'en'>, string>
61
+ >;
62
+
63
+ type DashboardLocalizedString = | string
64
+ | [LangData, ...(string | number)[]]
65
+ | DashboardLocalizedText;
66
+
67
+ type DashboardChatEmote = {
68
+ /** Exact text token as it appears in chat (case-sensitive). */
69
+ word: string;
70
+ /** Image URL (ideally minimal size). */
71
+ url: string;
72
+ };
73
+
74
+ type DashboardChatMessageValue = {
75
+ id: string;
76
+ content: DashboardLocalizedString;
77
+ platform: string;
78
+ from?: string;
79
+ /**
80
+ * Emotes extracted from message payload (e.g. Twitch fragments).
81
+ * Used by the chat UI to render emote images even without registration.
82
+ */
83
+ emotes?: DashboardChatEmote[];
84
+ };
85
+
86
+ /**
87
+ * Payload delivered to addons subscribed via `dashboard.onChatMessage`.
88
+ */
89
+ type DashboardChatIncomingPayload = {
90
+ id: string;
91
+ created: number;
92
+ updated: number;
93
+ message: DashboardChatMessageValue;
94
+ user?: {
95
+ id: string;
96
+ name: string;
97
+ avatar: string;
98
+ platform: string;
99
+ color?: string;
100
+ icons?: string[];
101
+ };
102
+ sourceAddonId?: string;
103
+ };
104
+
105
+ type AddonConfigFieldType = | 'text'
106
+ | 'color'
107
+ | 'number'
108
+ | 'boolean'
109
+ | 'array'
110
+ | 'object'
111
+ | 'button'
112
+ | 'select'
113
+ | 'folder'
114
+ | 'file';
115
+
116
+ type AddonLocalizedString = Partial<Record<AddonConfigLang, string>>;
117
+
118
+ /**
119
+ * Options for folder/file picker fields in `GenerateConfig`.
120
+ */
121
+ type AddonConfigPathPicker = {
122
+ /** Native open-dialog title override. */
123
+ title?: AddonLocalizedString;
124
+ /**
125
+ * Electron dialog filters (`extensions` without a leading dot).
126
+ * Used by `file` fields only.
127
+ */
128
+ filters?: Array<{ name: string; extensions: string[] }>;
129
+ /**
130
+ * Require the selected file basename to match (case-insensitive on Windows).
131
+ * Example: `GTAV.exe`.
132
+ */
133
+ filename?: string;
134
+ };
135
+
136
+ type AddonConfigArrayItemType = 'text' | 'number';
137
+
138
+ type AddonConfigFieldValidation = {
139
+ required?: boolean;
140
+ pattern?: string;
141
+ min?: number;
142
+ max?: number;
143
+ minLength?: number;
144
+ maxLength?: number;
145
+ };
146
+
147
+ type AddonConfigFieldEditor = {
148
+ label?: AddonLocalizedString;
149
+ description?: AddonLocalizedString;
150
+ required?: boolean;
151
+ placeholder?: AddonLocalizedString;
152
+ validation?: AddonConfigFieldValidation;
153
+ };
154
+
155
+ type AddonConfigSelectOption = {
156
+ value: string;
157
+ label?: AddonLocalizedString;
158
+ };
159
+
160
+ type AddonConfigField = {
161
+ key: string;
162
+ type: AddonConfigFieldType;
163
+ default?: unknown;
164
+ editor?: AddonConfigFieldEditor;
165
+ /** Item type when `type` is `array`. */
166
+ items?: AddonConfigArrayItemType;
167
+ /** Select options when `type` is `select`. */
168
+ options?: AddonConfigSelectOption[];
169
+ /** Nested fields when `type` is `object`. */
170
+ fields?: AddonConfigField[];
171
+ /** Picker options when `type` is `folder` or `file`. */
172
+ pathPicker?: AddonConfigPathPicker;
173
+ /**
174
+ * Addon event name triggered when a `button` field is clicked in the
175
+ * settings UI. Must match the name passed to `events.On(name, ...)`.
176
+ * Required for `button` fields; ignored for all other types.
177
+ */
178
+ event?: string;
179
+ };
180
+
181
+ /**
182
+ * One settings field or a group of fields rendered on the same row in the UI.
183
+ */
184
+ type AddonConfigSchemaEntry = AddonConfigField | AddonConfigField[];
185
+
186
+ type AddonConfigSchema = AddonConfigSchemaEntry[];
187
+
188
+ /**
189
+ * The port of the local web server.
190
+ * @example const port = WEB_SERVER_PORT;
191
+ console.log(port);
192
+ */
193
+ var WEB_SERVER_PORT: number;
194
+ /**
195
+ * Check if developer mode is enabled
196
+ Can be used for additional logging and debugging, or advanced configuration.
197
+ * @example if (isDeveloperMode) {
198
+ console.log('Developer mode is enabled');
199
+ }
200
+ */
201
+ var isDeveloperMode: boolean;
202
+ /**
203
+ * Requires a module.
204
+ * @param name Module name.
205
+ * @returns Module.
206
+ * @example const fs = require('fs');
207
+ console.log(fs.readFileSync('package.json', 'utf8'));
208
+ Allows only with ROOT permission.
209
+ * @example const fs = require('fs');
210
+ console.log(fs.readFileSync('package.json', 'utf8'));
211
+ Allows only with ROOT permission.
212
+ * @example const fs = require('fs');
213
+ console.log(fs.readFileSync('package.json', 'utf8'));
214
+ Allows only with ROOT permission.
215
+ */
216
+ var require: (name: string) => any;
217
+ var URL: typeof UrlCustom;
218
+ var URLSearchParams: typeof URLSearchParams;
219
+ /**
220
+ * Private per-addon file storage in the addon install directory.
221
+ Persists a single JSON blob at `{data.path}/storage_data.json` across worker restarts.
222
+ Synchronous read/write in the integration worker — no IPC and no manifest permission required.
223
+ * @remarks - Not the same as {@link api.config.getParams } / {@link api.config.updateParams }: `storage` is
224
+ addon-internal runtime state (caches, counters, session maps) and is never shown in settings UI.
225
+ - {@link storage.Write } replaces the entire file; merge with a prior {@link storage.Read } when
226
+ updating part of the blob.
227
+ - Values must be JSON-serializable (objects, arrays, strings, numbers, booleans, `null`).
228
+ - The file is removed on uninstall; call {@link storage.Clear } to reset state without uninstalling.
229
+ * @example type CacheState = { lastSync: number; emoteIds: string[] };
230
+ const cached = storage.Read<CacheState>();
231
+ if (!cached) {
232
+ storage.Write<CacheState>({ lastSync: 0, emoteIds: [] });
233
+ }
234
+ * @example // Increment a counter persisted between restarts:
235
+ const count = storage.Read<{ n: number }>()?.n ?? 0;
236
+ storage.Write({ n: count + 1 });
237
+ */
238
+ var storage: {
239
+ /**
240
+ * Reads the persisted JSON blob for this addon.
241
+ * @template T Expected shape of the stored object (for TypeScript addons).
242
+ * @returns Parsed data cast to `T`, or `undefined` when `storage_data.json` does not exist yet.
243
+ * @example const state = storage.Read<{ offset: number }>();
244
+ const offset = state?.offset ?? 0;
245
+ * @example // First run — initialize defaults:
246
+ if (!storage.Read()) {
247
+ storage.Write({ seenIds: [] as string[] });
248
+ }
249
+ */
250
+ Read: <T>() => T | undefined;
251
+ /**
252
+ * Replaces the entire persisted JSON blob for this addon.
253
+ * @template T Shape of the object being stored.
254
+ * @param data JSON-serializable value written to `storage_data.json` (pretty-printed).
255
+ * @example storage.Write({ lastEventId: 'abc', processedAt: Date.now() });
256
+ * @example // Partial update — read, merge, write back:
257
+ const prev = storage.Read<{ tokens: string[] }>() ?? { tokens: [] };
258
+ storage.Write({ tokens: [...prev.tokens, newToken] });
259
+ */
260
+ Write: <T>(data: T) => void;
261
+ /**
262
+ * Deletes the persisted storage file for this addon.
263
+ No-op when `storage_data.json` is already missing.
264
+ * @example storage.Clear();
265
+ storage.Write({ fresh: true });
266
+ */
267
+ Clear: () => void;
268
+ };
269
+ /**
270
+ * Connection status shown in the main window status bar.
271
+ * @requires AddonsPermission.STATUS
272
+ * @example status.Update({ current: 'connecting', message: undefined });
273
+ status.OnClick(() => api.openUrl('https://twitch.tv'));
274
+ status.Update({
275
+ current: 'online',
276
+ message: { en: 'Twitch', ru: 'Twitch', uk: 'Twitch' },
277
+ });
278
+ */
279
+ var status: {
280
+ /**
281
+ * Current status payload mirrored to the main window.
282
+ */
283
+ data: {
284
+ current: AddonStatusState;
285
+ /**
286
+ * Tooltip text in the status bar (per-locale strings).
287
+ */
288
+ message: { en?: string | undefined; ru?: string | undefined; uk?: string | undefined; } | undefined;
289
+ /**
290
+ * Timestamp of the last status change.
291
+ */
292
+ timestamp: number | undefined;
293
+ };
294
+ /**
295
+ * Pushes status to the main window status bar.
296
+ * @requires AddonsPermission.STATUS
297
+ */
298
+ Update: (data: { current: AddonStatusState; message?: { en?: string | undefined; ru?: string | undefined; uk?: string | undefined; } | undefined; }) => void;
299
+ /**
300
+ * Registers a click handler for the status bar entry.
301
+ * @requires AddonsPermission.STATUS
302
+ */
303
+ OnClick: (handler: () => void) => void;
304
+ };
305
+ /**
306
+ * In-app notifications shown in the title-bar notification center.
307
+ * @requires AddonsPermission.NOTIFY
308
+ * @example notify.Send({
309
+ id: `${data.id}_status`,
310
+ type: 'success',
311
+ title: { en: 'Twitch' },
312
+ message: { en: 'Connected', ru: 'Подключено', uk: 'Підключено' },
313
+ temp: true,
314
+ });
315
+ */
316
+ var notify: {
317
+ /**
318
+ * Creates or replaces a notification record.
319
+ When `id` is provided, any previous record with the same id is removed first.
320
+ * @requires AddonsPermission.NOTIFY
321
+ */
322
+ Send: (payload: { id?: string | undefined; type?: "error" | "success" | "info" | "warning" | undefined; title?: DashboardLocalizedString | undefined; message: DashboardLocalizedString; temp?: boolean | undefined; }) => void;
323
+ };
324
+ /**
325
+ * Permission helpers for the running addon instance.
326
+ Values come from `manifest.json` and are fixed for the lifetime of the worker process.
327
+ * @example if (!permissions.has(AddonsPermission.NETWORK_REQUEST)) {
328
+ console.warn('Network is disabled for this addon');
329
+ return;
330
+ }
331
+ */
332
+ var permissions: {
333
+ /**
334
+ * Permissions granted to this addon (from manifest).
335
+ Treat as read-only; changing this array does not update the manifest or main process.
336
+ * @example console.log('Granted:', permissions.list.join(', '));
337
+ */
338
+ list: AddonsPermission[];
339
+ /**
340
+ * Returns whether the addon may use a capability.
341
+ Logs a warning to the worker console when access is denied.
342
+ * @param permission Capability to check (see global `AddonsPermission` enum in generated typings).
343
+ * @returns `true` if `permission` is listed or if `ROOT` is granted; otherwise `false`.
344
+ * @example if (permissions.has(AddonsPermission.CONFIG_WRITE)) {
345
+ await api.config.setConfig({ theme: 'dark' });
346
+ }
347
+ * @example // ROOT bypasses every individual check:
348
+ permissions.has(AddonsPermission.NETWORK_REQUEST); // true when list includes ROOT
349
+ */
350
+ has: (permission: AddonsPermission) => boolean;
351
+ };
352
+ /**
353
+ * In-addon event bus. Used mainly to handle HTTP endpoint callbacks registered via `network.endpoints.create`.
354
+ Handlers run in the integration worker when the main process forwards `customEvent` messages.
355
+ * @example events.On('onDonation', payload => {
356
+ console.log('Donation', payload.body);
357
+ return { ok: true };
358
+ });
359
+ */
360
+ var events: {
361
+ /**
362
+ * Internal registry of active handlers. Prefer `events.On` / subscription `Destroy` for lifecycle control.
363
+ */
364
+ list: { id: string; name: string; handle: (data: any) => any; }[];
365
+ /**
366
+ * Registers a named handler. The name must match `callbackName` passed to `network.endpoints.create`.
367
+ * @param name Event identifier (callback name).
368
+ * @param handler Receives `{ query, params, body }` from Express for HTTP endpoints; return value is sent as the HTTP response body.
369
+ * @returns Subscription with `id` and `Destroy()` to unregister.
370
+ * @example network.endpoints.create('/hook', 'POST', 'onHook');
371
+ const sub = events.On('onHook', ({ body }) => {
372
+ console.log(body);
373
+ return 'received';
374
+ });
375
+ // later: sub.Destroy();
376
+ */
377
+ On: (name: string, handler: (data: any) => any) => { id: string; Destroy(): void; };
378
+ };
379
+ /**
380
+ * Outbound HTTP and inbound HTTP endpoint helpers (worker-side).
381
+ Outbound calls are subject to DNS/IP filtering, concurrency limits, and permission checks.
382
+ */
383
+ var network: {
384
+ /**
385
+ * Registers HTTP routes on the main-process web server under `/addon/{addonId}/...`.
386
+ */
387
+ endpoints: {
388
+ /**
389
+ * Creates a route and binds it to an `events.On` handler by name.
390
+ * @requires AddonsPermission.WEB_END_POINTS
391
+ * @param path Suffix appended after `/addon/{id}/` (leading slash optional).
392
+ * @param type HTTP method exposed by the backend server.
393
+ * @param callbackName Must match the first argument of `events.On`.
394
+ * @returns Promise resolving to `{ success: true }` or `{ success: false, message: string }`.
395
+ * @example await network.endpoints.create('alerts', 'POST', 'handleAlert');
396
+ events.On('handleAlert', ({ body }) => ({ received: body }));
397
+ // POST http://localhost:{WEB_SERVER_PORT}/addon/twitch/alerts
398
+ */
399
+ create: (path: string, type: "GET" | "POST", callbackName: string) => Promise<unknown>;
400
+ };
401
+ /**
402
+ * Registers Socket.IO namespaces on the main-process web server.
403
+ Clients connect with path `/addon/socket.io` and namespace `/addon/{addonId}/{path}`.
404
+ */
405
+ socketEndpoints: {
406
+ /**
407
+ * Creates a Socket.IO namespace and binds lifecycle/events to an `events.On` handler.
408
+ * @requires AddonsPermission.SOCKET_END_POINTS
409
+ * @param path Suffix appended after `/addon/{id}/` (leading slash optional).
410
+ * @param callbackName Must match the first argument of `events.On`.
411
+ * @returns Promise resolving to `{ success: true }` or `{ success: false, message: string }`.
412
+ * @remarks Handler receives `{ type: 'connect' | 'disconnect' | 'event', socketId, ... }`.
413
+ For `type: 'event'`, a non-undefined return value is emitted back to the client as `reply`.
414
+ * @example await network.socketEndpoints.create('live', 'onSocket');
415
+ events.On('onSocket', payload => {
416
+ if (payload.type === 'event' && payload.event === 'ping') {
417
+ return { pong: true };
418
+ }
419
+ });
420
+ // Client: io('http://localhost:3000/addon/mywidget/live', { path: '/addon/socket.io' })
421
+ */
422
+ create: (path: string, callbackName: string) => Promise<unknown>;
423
+ /**
424
+ * Emits an event to connected Socket.IO clients on a registered namespace.
425
+ * @requires AddonsPermission.SOCKET_END_POINTS
426
+ * @param path Namespace suffix passed to `create` (e.g. `'live'`).
427
+ * @param event Event name clients listen for.
428
+ * @param data JSON-serializable payload.
429
+ * @param socketId Optional socket id — omit to broadcast to all clients.
430
+ * @returns `{ success: true }` or `{ success: false, message: string }`.
431
+ * @example await network.socketEndpoints.emit('live', 'chat:message', { text: 'Hello' });
432
+ */
433
+ emit: (path: string, event: string, data: unknown, socketId: string | undefined) => Promise<unknown>;
434
+ };
435
+ /**
436
+ * Outbound HTTP client (worker process). Responses are always plain text (`response.text()`).
437
+ * @remarks Max 5 concurrent requests; 10s timeout; redirects are not followed; private/local networks are blocked.
438
+ */
439
+ request: {
440
+ /**
441
+ * Performs a GET request.
442
+ * @requires AddonsPermission.NETWORK_REQUEST
443
+ * @param url Absolute URL (http/https). Blocked if host resolves to loopback or RFC1918 ranges.
444
+ * @param headers Optional request headers.
445
+ * @returns Response body as string.
446
+ * @example const html = await network.request.get('https://api.example.com/status');
447
+ */
448
+ get: (url: string, headers?: Record<string, string>) => Promise<string>;
449
+ /**
450
+ * Performs a POST request with JSON body (`Content-Type: application/json`).
451
+ * @requires AddonsPermission.NETWORK_REQUEST
452
+ * @param url Target URL.
453
+ * @param body Serializable object; sent as `JSON.stringify(body)`.
454
+ * @param headers Extra headers merged with the default content type.
455
+ * @returns Response body as string.
456
+ * @example const res = await network.request.post('https://api.example.com/hook', { live: true });
457
+ */
458
+ post: (url: string, body: any, headers?: Record<string, string>) => Promise<string>;
459
+ /**
460
+ * Performs a PUT request with JSON body.
461
+ * @requires AddonsPermission.NETWORK_REQUEST
462
+ * @param url Target URL.
463
+ * @param body Request payload object.
464
+ * @param headers Optional extra headers.
465
+ * @returns Response body as string.
466
+ */
467
+ put: (url: string, body: any, headers?: Record<string, string>) => Promise<string>;
468
+ /**
469
+ * Performs a DELETE request.
470
+ * @requires AddonsPermission.NETWORK_REQUEST
471
+ * @param url Target URL.
472
+ * @param headers Optional request headers.
473
+ * @returns Response body as string.
474
+ */
475
+ delete: (url: string, headers?: Record<string, string>) => Promise<string>;
476
+ /**
477
+ * Performs a POST request with `application/x-www-form-urlencoded` body.
478
+ * @requires AddonsPermission.NETWORK_REQUEST
479
+ * @param url Target URL.
480
+ * @param fields Form fields encoded as URLSearchParams.
481
+ * @param headers Optional extra headers.
482
+ * @returns Response body as string.
483
+ */
484
+ postForm: (url: string, fields: Record<string, string>, headers?: Record<string, string>) => Promise<string>;
485
+ };
486
+ /**
487
+ * Outbound WebSocket client (worker process).
488
+ * @remarks Max 5 concurrent connections; private/local networks are blocked.
489
+ */
490
+ websocket: {
491
+ /**
492
+ * Opens a WebSocket connection to an external host.
493
+ * @requires AddonsPermission.NETWORK_WEBSOCKET
494
+ * @param url Absolute `ws://` or `wss://` URL. Blocked if host resolves to loopback or RFC1918 ranges.
495
+ * @param options Optional subprotocols and handshake headers.
496
+ * @returns Connection handle with event subscriptions and `Send` / `Close` / `Destroy`.
497
+ * @example const ws = await network.websocket.connect('wss://example.com/socket', {
498
+ headers: { Authorization: 'Bearer token' },
499
+ });
500
+ ws.On('open', () => ws.Send({ type: 'ping' }));
501
+ ws.On('message', data => console.log(data));
502
+ ws.On('close', ({ code, reason }) => console.log(code, reason));
503
+ */
504
+ connect: (url: string, options?: { headers?: Record<string, string> | undefined; protocols?: string | string[] | undefined; }) => Promise<{ readonly state: 0 | 1 | 2 | 3; On(event: "error" | "open" | "message" | "close", handler: (() => void) | ((data: string) => void) | ((data: { code: number; reason: string; }) => void) | ((error: Error) => void)): { id: string; Destroy(): void; }; Send(data: string | number | boolean | Record<string, unknown>): void; Close(code?: number, reason?: string): void; Destroy(): void; }>;
505
+ };
506
+ };
507
+ /**
508
+ * Metadata for the integration instance loaded into this worker.
509
+ Populated from main process before `vm.runInContext` executes addon code.
510
+ * @example console.log(`Running addon: ${data.id}`);
511
+ console.log(`Frontend token: ${data.token}`);
512
+ events.On('onParams', ({ query }) => {
513
+ if (query.token !== data.token) {
514
+ return { success: false, message: 'Unauthorized' };
515
+ }
516
+ return api.config.getParams();
517
+ });
518
+ */
519
+ var data: {
520
+ id: string;
521
+ permissions: AddonsPermission[];
522
+ /**
523
+ * Recorded addon install folder path (used for frontend access token derivation).
524
+ */
525
+ path: string;
526
+ /**
527
+ * Stable frontend access token for this addon instance (`?token=` on web pages).
528
+ */
529
+ token: string;
530
+ };
531
+ /**
532
+ * Logging helpers prefixed with `[Addon {id}]` for easier filtering in worker logs.
533
+ */
534
+ var console: {
535
+ /**
536
+ * Writes an informational log line.
537
+ */
538
+ log: (...args: any[]) => void;
539
+ /**
540
+ * Writes an error log line.
541
+ */
542
+ error: (...args: any[]) => void;
543
+ /**
544
+ * Writes a warning log line.
545
+ */
546
+ warn: (...args: any[]) => void;
547
+ /**
548
+ * Writes an info log line.
549
+ */
550
+ info: (...args: any[]) => void;
551
+ };
552
+ /**
553
+ * Schedules a one-shot callback. Errors inside `fn` are caught and logged; they do not crash the worker.
554
+ * @param fn Callback executed after the delay.
555
+ * @param delay Milliseconds to wait (clamped to max 60_000).
556
+ * @param args Optional arguments forwarded to `fn`.
557
+ * @returns Timer handle compatible with `clearTimeout`.
558
+ * @example setTimeout(() => console.log('ready'), 500);
559
+ */
560
+ var setTimeout: (fn: any, delay?: number, ...args: any[]) => number;
561
+ /**
562
+ * Cancels a timer created by `setTimeout`.
563
+ * @param id Handle returned from `setTimeout`.
564
+ */
565
+ var clearTimeout: (id: any) => void;
566
+ /**
567
+ * Schedules a repeating callback. Interval is clamped between 50 ms and 60_000 ms.
568
+ * @param fn Callback invoked on each tick.
569
+ * @param interval Period in milliseconds (default 1000).
570
+ * @param args Optional arguments forwarded to `fn`.
571
+ * @returns Timer handle compatible with `clearInterval`.
572
+ */
573
+ var setInterval: (fn: any, interval?: number, ...args: any[]) => number;
574
+ /**
575
+ * Cancels a timer created by `setInterval`.
576
+ * @param id Handle returned from `setInterval`.
577
+ */
578
+ var clearInterval: (id: any) => void;
579
+ /**
580
+ * Resolves after a delay (max 60_000 ms). Useful for simple polling/backoff in addon code.
581
+ * @param ms Milliseconds to wait.
582
+ * @returns Promise that resolves with no value.
583
+ * @example await sleep(1000);
584
+ */
585
+ var sleep: (ms: number) => Promise<unknown>;
586
+ /**
587
+ * Non-cryptographic random helpers for IDs and UI sampling inside addons.
588
+ */
589
+ var random: {
590
+ /**
591
+ * Inclusive integer in `[min, max]`.
592
+ * @param min Lower bound (default 0).
593
+ * @param max Upper bound (default 1).
594
+ * @example const dice = random.number(1, 6);
595
+ */
596
+ number: (min?: number, max?: number) => number;
597
+ /**
598
+ * Short alphanumeric string suitable for correlation IDs (not UUID-strength).
599
+ * @example const eventId = random.id();
600
+ */
601
+ id: () => string;
602
+ };
603
+ /**
604
+ * Cryptographic helpers executed in the worker (not inside addon VM imports).
605
+ */
606
+ var crypto: {
607
+ /**
608
+ * Creates a PKCE verifier/challenge pair for OAuth 2.1 (S256).
609
+ */
610
+ createPkce: () => { verifier: string; challenge: string; };
611
+ /**
612
+ * Verifies an RSA-SHA256 PKCS#1 v1.5 signature (e.g. Kick webhooks).
613
+ */
614
+ verifyRsaSha256: (publicKeyPem: string, message: string, signatureBase64: string) => boolean;
615
+ };
616
+ /**
617
+ * RPC-style access to main-process services (config, persistence).
618
+ All methods are async and cross the worker IPC boundary.
619
+ */
620
+ var api: {
621
+ /**
622
+ * Opens a URL in the default browser
623
+ * @param url URL to open
624
+ * @example api.openUrl('https://www.google.com');
625
+ */
626
+ openUrl: (url: string) => void;
627
+ /**
628
+ * Fully restarts this addon worker process.
629
+ */
630
+ restart: () => void;
631
+ /**
632
+ * Application and per-addon configuration stored in the main process.
633
+ */
634
+ config: {
635
+ /**
636
+ * Reads persisted settings for this addon (`Config.data.addonsParams[id]`).
637
+ * @returns Stored parameter object (empty object if none saved yet).
638
+ * @example const params = await api.config.getParams<{ token: string }>();
639
+ console.log(params.token);
640
+ */
641
+ getParams: <T extends Record<string, any>>() => Promise<T>;
642
+ /**
643
+ * Replaces this addon's parameter blob in app config.
644
+ Size limit: 10_000 bytes JSON unless `INCREASE_CONFIG_SIZE` is granted (then 1_000_000).
645
+ * @param data New parameters object.
646
+ * @returns `{ success: true, params }` or `{ success: false, message }`.
647
+ * @example await api.config.updateParams({ lastSync: Date.now() });
648
+ */
649
+ updateParams: <T extends Record<string, any>>(data: T) => Promise<unknown>;
650
+ /**
651
+ * Reads the full application config from the main process.
652
+ * @requires AddonsPermission.CONFIG_READ
653
+ * @returns Full config object, or `null` when permission is missing.
654
+ * @example const cfg = await api.config.getConfig();
655
+ */
656
+ getConfig: <T extends Record<string, any>>() => Promise<T>;
657
+ /**
658
+ * Patches global application config via `Config.Update`.
659
+ * @requires AddonsPermission.CONFIG_WRITE
660
+ * @param data Partial config fields accepted by main-process storage.
661
+ * @returns `{ success: true }` or `{ success: false, message }`.
662
+ */
663
+ setConfig: <T extends Record<string, any>>(data: T) => Promise<unknown>;
664
+ /**
665
+ * Reads persisted settings of another installed addon.
666
+ * @requires AddonsPermission.ADDON_CONFIG_READ
667
+ * @param addonId Target addon identifier.
668
+ * @returns `{ success, params }` or `{ success: false, message }`.
669
+ * @example const twitch = await api.config.getAddonParams<{ access_token?: string }>('twitch');
670
+ */
671
+ getAddonParams: <T extends Record<string, any>>(addonId: string) => Promise<{ success: true; params: T; } | { success: false; message: string; }>;
672
+ };
673
+ };
674
+ /**
675
+ * Addon-to-addon request/response API (separate from `events`).
676
+ Use {@link addons.request } to call another addon and {@link addons.onRequest }
677
+ to expose handlers in the current addon.
678
+ */
679
+ var addons: {
680
+ /**
681
+ * Sends a request to another enabled addon and waits for its response.
682
+ * @param targetAddonId Receiver addon id.
683
+ * @param method Handler method name registered via `addons.onRequest`.
684
+ * @param params Optional payload for the receiver.
685
+ * @returns Receiver response or an error when routing fails.
686
+ * @example const channel = await addons.request('twitch', 'getChannelId');
687
+ */
688
+ request: (targetAddonId: string, method: string, params: unknown) => Promise<{ success: true; result?: unknown; } | { success: false; message?: string | undefined; }>;
689
+ /**
690
+ * Registers a request handler exposed to other addons.
691
+ The handler receives the sender addon id and request params.
692
+ * @param method Unique method name within this addon.
693
+ * @param handler Async callback that returns the response payload.
694
+ * @example addons.onRequest('getChannelId', async ({ fromAddonId }) => {
695
+ console.log('Request from', fromAddonId);
696
+ return { channelId: '123' };
697
+ });
698
+ */
699
+ onRequest: (method: string, handler: (payload: { fromAddonId: string; params?: unknown; }) => unknown) => void;
700
+ /**
701
+ * Removes a previously registered addon request handler.
702
+ * @param method Handler method name passed to `addons.onRequest`.
703
+ */
704
+ offRequest: (method: string) => void;
705
+ };
706
+ /**
707
+ * Built-in UI helpers for addon web flows (OAuth callbacks, etc.).
708
+ */
709
+ var ui: {
710
+ /**
711
+ * OAuth authorization result pages served by the local web server.
712
+ Return `{ redirect: ui.auth.generateSuccess() }` from an endpoint handler
713
+ to send the user to the styled success page.
714
+ */
715
+ auth: {
716
+ /**
717
+ * Builds a redirect URL for the OAuth success page.
718
+ * @param message Optional custom message shown via `?message=`.
719
+ * @returns Absolute URL on the local web server.
720
+ * @example return { redirect: ui.auth.generateSuccess('Twitch connected') };
721
+ */
722
+ generateSuccess: (message: string | undefined) => string;
723
+ /**
724
+ * Builds a redirect URL for the OAuth failure page.
725
+ * @param message Optional custom message shown via `?message=`.
726
+ * @returns Absolute URL on the local web server.
727
+ * @example return { redirect: ui.auth.generateFail('Invalid OAuth state') };
728
+ */
729
+ generateFail: (message: string | undefined) => string;
730
+ };
731
+ };
732
+ /**
733
+ * Dashboard feed: latest events widget and chat window.
734
+ User profiles are shared via `upsertUser` and referenced by `from` on records/messages.
735
+ */
736
+ var dashboard: {
737
+ /**
738
+ * Registers a platform identifier for dashboard events and chat.
739
+ The `id` must match the `platform` field on records and messages.
740
+ Icon is taken from the addon manifest when present.
741
+ Re-registering the same id from the same addon is allowed.
742
+ * @requires AddonsPermission.DASHBOARD_EVENTS or AddonsPermission.DASHBOARD_CHAT
743
+ * @example await dashboard.registerPlatform({
744
+ id: 'twitch',
745
+ name: { en: 'Twitch', ru: 'Twitch', uk: 'Twitch' },
746
+ });
747
+ */
748
+ registerPlatform: (platform: { id: string; name: Partial<Record<"en" | "ru" | "uk", string>>; }) => Promise<unknown>;
749
+ /**
750
+ * Registers chat badge images so the chat UI can resolve
751
+ `DashboardRecordUserValue.icons` identifiers to image URLs.
752
+
753
+ Re-registering badges is allowed and updates the mapping on the fly.
754
+ * @requires AddonsPermission.DASHBOARD_EVENTS or AddonsPermission.DASHBOARD_CHAT
755
+ */
756
+ registerChatBadges: (badges: { id: string; url: string; title?: string | undefined; }[]) => Promise<unknown>;
757
+ /**
758
+ * Returns chat badge images registered by platform addons (id → url/title).
759
+ * @requires AddonsPermission.DASHBOARD_CHAT or AddonsPermission.DASHBOARD_CHAT_INCOMING
760
+ */
761
+ listChatBadges: () => Promise<unknown>;
762
+ /**
763
+ * Returns chat emotes registered by platform addons (platform → word → url).
764
+ * @requires AddonsPermission.DASHBOARD_CHAT or AddonsPermission.DASHBOARD_CHAT_INCOMING
765
+ */
766
+ listChatEmotes: () => Promise<unknown>;
767
+ /**
768
+ * Returns streaming platforms registered by addons (id, name, iconUrl).
769
+ * @requires AddonsPermission.DASHBOARD_CHAT or AddonsPermission.DASHBOARD_CHAT_INCOMING
770
+ */
771
+ listPlatforms: () => Promise<unknown>;
772
+ /**
773
+ * Registers emote images so the chat UI can replace tokens in messages.
774
+
775
+ Several addons may register emotes for the same platform; re-registering
776
+ is allowed and updates mapping on the fly.
777
+ * @requires AddonsPermission.DASHBOARD_EVENTS or AddonsPermission.DASHBOARD_CHAT
778
+ */
779
+ registerChatEmotes: (payload: { platforms: string[]; emotes: { word: string; url: string; }[]; }) => Promise<unknown>;
780
+ /**
781
+ * Creates or updates a user shown in chat and event rows.
782
+ * @requires AddonsPermission.DASHBOARD_EVENTS or AddonsPermission.DASHBOARD_CHAT
783
+ */
784
+ upsertUser: (user: { id: string; name: string; avatar?: string | undefined; platform: string; color?: string | undefined; icons?: string[] | undefined; }) => Promise<unknown>;
785
+ /**
786
+ * Registers overlay trigger options shown in overlay addon settings.
787
+
788
+ Call once at addon load (before or after auth). Each entry describes one
789
+ event type the user can bind to an overlay in **Settings → Overlay → Triggers**.
790
+ When your addon pushes a dashboard event, pass a matching `{ trigger }` in
791
+ `dashboard.addRecord(..., user, { trigger })` so the overlay matcher can
792
+ find configured rules (`addonId` + `type` + optional `key` + `value`).
793
+ * @requires AddonsPermission.DASHBOARD_EVENTS
794
+ * @param options Array of trigger option descriptors (see fields below).
795
+
796
+ **Option fields**
797
+
798
+ | Field | Description |
799
+ | --- | --- |
800
+ | `type` | Event kind: `donation`, `subscribe`, `subgift`, `follow`, or `custom`. Must match `trigger.type` you pass to `addRecord`. |
801
+ | `key` | Fixed discriminator when one `type` has several variants. Examples: `bits`, `kicks`, `redeems`. Stored in saved trigger `key` and compared to `trigger.key` on incoming events. Do **not** set when using `keyOptions` (user picks the key in settings). |
802
+ | `label` | Localized name shown in the event dropdown (`en` required; `ru`, `uk` optional). |
803
+ | `valueType` | How the value field is rendered: `text`, `number`, `select`, or `dynamic`. Omit for triggers without a value (e.g. `follow`). |
804
+ | `valueOptions` | For `valueType: 'select'`. `{ value, label }[]` — `value` is matched against incoming events; `label` is shown in UI. |
805
+ | `valueProvider` | For `valueType: 'dynamic'`. Provider id; handle `overlayTriggerValue:{provider}:list\|create\|release` events in this addon. |
806
+ | `valueGenerateLabel` | For `dynamic`: label of the “generate new value” option in the dropdown. |
807
+ | `requireValue` | Extra input before `create` (e.g. reward cost). Sent as `context[key]` on create. Fields: `key`, `type`, `label`, `default`, `min`. |
808
+ | `valueHint` | Label/hint for `text` / `number` value fields (e.g. “Donation amount”). |
809
+ | `keyOptions` | User-selectable keys (e.g. currency codes). Renders a second dropdown; chosen value is stored in saved trigger `key`. |
810
+ | `keyLabel` | Label for the `keyOptions` dropdown (e.g. “Currency”). |
811
+ | `valueMatch` | Numeric matching mode. Default: `exact` (incoming === configured). Use `minimum` for “at or above” thresholds (bits, KICKs, sub gift count). |
812
+
813
+ **Matching rules**
814
+
815
+ - Saved overlay rule: `{ targetId, addonId, type, key?, value }`.
816
+ - Incoming event: `{ type, key?, value? }` from `addRecord` options.
817
+ - `addonId` and `type` must match; `key` must match when both sides have it.
818
+ - `value`: compared per `valueMatch` for numbers; strings use strict equality.
819
+
820
+ **Dynamic provider contract**
821
+
822
+ - `overlayTriggerValue:{provider}:list` → `{ success, items?: [{ id, label, meta? }] }`
823
+ - `overlayTriggerValue:{provider}:create` → `{ success, valueId?, label?, meta? }`
824
+ (payload includes `title`, `overlayId`, `context` from `requireValue`)
825
+ - `overlayTriggerValue:{provider}:release` → `{ success }` (payload: `valueId`;
826
+ called on settings save when the value is no longer referenced)
827
+ * @example // Follow — no value field
828
+ await dashboard.registerTriggers([
829
+ { type: 'follow', label: { en: 'New follower', ru: 'Новый фолловер' } },
830
+ ]);
831
+ * @example // Custom numeric trigger with minimum threshold (bits)
832
+ await dashboard.registerTriggers([
833
+ {
834
+ type: 'custom',
835
+ key: 'bits',
836
+ label: { en: 'Cheer (bits)', ru: 'Cheer (битсы)' },
837
+ valueType: 'number',
838
+ valueMatch: 'minimum',
839
+ valueHint: { en: 'Minimum bits', ru: 'Минимум битсов' },
840
+ },
841
+ ]);
842
+ // Fire: { trigger: { type: 'custom', key: 'bits', value: 100 } }
843
+ // Matches configured value 100 when viewer cheers 100+ bits.
844
+ * @example // Donation with currency picker and exact amount (default valueMatch)
845
+ await dashboard.registerTriggers([
846
+ {
847
+ type: 'donation',
848
+ label: { en: 'Donation', ru: 'Донат' },
849
+ valueType: 'number',
850
+ keyOptions: [
851
+ { value: 'RUB', label: { en: 'RUB' } },
852
+ { value: 'USD', label: { en: 'USD' } },
853
+ ],
854
+ keyLabel: { en: 'Currency', ru: 'Валюта' },
855
+ valueHint: { en: 'Donation amount', ru: 'Сумма доната' },
856
+ },
857
+ ]);
858
+ // Fire: { trigger: { type: 'donation', key: 'RUB', value: 500 } }
859
+ * @example // Select: separate UI label and match value (sub tier)
860
+ await dashboard.registerTriggers([
861
+ {
862
+ type: 'subscribe',
863
+ label: { en: 'Subscription', ru: 'Подписка' },
864
+ valueType: 'select',
865
+ valueOptions: [
866
+ { value: '1000', label: { en: 'Tier 1', ru: 'Тир 1' } },
867
+ { value: '2000', label: { en: 'Tier 2', ru: 'Тир 2' } },
868
+ ],
869
+ },
870
+ ]);
871
+ * @example // Dynamic: list / generate / release via events.On in this addon
872
+ await dashboard.registerTriggers([
873
+ {
874
+ type: 'custom',
875
+ key: 'redeems',
876
+ label: { en: 'Channel point reward', ru: 'Награда за баллы' },
877
+ valueType: 'dynamic',
878
+ valueProvider: 'rewards',
879
+ valueGenerateLabel: { en: 'Generate reward', ru: 'Сгенерировать' },
880
+ requireValue: {
881
+ key: 'cost',
882
+ type: 'number',
883
+ label: { en: 'Reward cost', ru: 'Стоимость' },
884
+ default: 100,
885
+ min: 1,
886
+ },
887
+ },
888
+ ]);
889
+ events.On('overlayTriggerValue:rewards:list', async () => ({
890
+ success: true,
891
+ items: [{ id: 'abc', label: 'My reward', meta: '100' }],
892
+ }));
893
+ * @example // Pass matching trigger when pushing dashboard events
894
+ await dashboard.addRecord(
895
+ { id: random.id(), type: 'custom', platform: 'twitch', message: '100 bits!' },
896
+ user,
897
+ { trigger: { type: 'custom', key: 'bits', value: 100 } },
898
+ );
899
+ */
900
+ registerTriggers: (options: { type: "donation" | "subscribe" | "subgift" | "follow" | "custom"; key?: string | undefined; label?: Partial<Record<"en" | "ru" | "uk", string>> | undefined; valueType?: "number" | "text" | "select" | "dynamic" | undefined; valueOptions?: { value: string | number; label: Partial<Record<"en" | "ru" | "uk", string>>; }[] | undefined; valueProvider?: string | undefined; valueGenerateLabel?: Partial<Record<"en" | "ru" | "uk", string>> | undefined; requireValue?: { key?: string | undefined; type?: "number" | "text" | undefined; label?: Partial<Record<"en" | "ru" | "uk", string>> | undefined; default?: string | number | undefined; min?: number | undefined; } | undefined; valueHint?: Partial<Record<"en" | "ru" | "uk", string>> | undefined; keyOptions?: { value: string | number; label: Partial<Record<"en" | "ru" | "uk", string>>; }[] | undefined; keyLabel?: Partial<Record<"en" | "ru" | "uk", string>> | undefined; valueMatch?: "exact" | "minimum" | undefined; }[]) => Promise<unknown>;
901
+ /**
902
+ * Pushes an event into the latest-events widget.
903
+ * @requires AddonsPermission.DASHBOARD_EVENTS
904
+ `message` accepts a plain string, a `[LangData, ...args]` tuple (app
905
+ translation key with placeholders), or `{ en, ru?, uk? }` per-language
906
+ text (`en` required; missing locale falls back to `en` in the UI).
907
+ Optional `trigger` is used by the overlay system to match configured rules.
908
+ * @example await dashboard.addRecord({
909
+ id: random.id(),
910
+ type: 'donation',
911
+ platform: 'twitch',
912
+ amount: [5, 'USD'],
913
+ message: { en: 'Thanks!', ru: 'Спасибо!' },
914
+ from: 'user-1',
915
+ }, { id: 'user-1', name: 'Viewer', avatar: '', platform: 'twitch', color: '#7fff00' }, {
916
+ trigger: { type: 'donation', key: 'USD', value: 5 },
917
+ });
918
+ */
919
+ addRecord: (record: { id?: string | undefined; type: "donation" | "subscribe" | "follow" | "custom" | "timer"; amount?: [number, string] | undefined; platform: string; message?: DashboardLocalizedString | undefined; from?: string | undefined; attach?: { type: string; value: string; }[] | undefined; }, user: { id: string; name: string; avatar?: string | undefined; platform: string; color?: string | undefined; icons?: string[] | undefined; } | undefined, options: { trigger?: { type: "donation" | "subscribe" | "subgift" | "follow" | "custom"; key?: string | undefined; value?: string | number | boolean | undefined; } | undefined; triggers?: { type: "donation" | "subscribe" | "subgift" | "follow" | "custom"; key?: string | undefined; value?: string | number | boolean | undefined; }[] | undefined; } | undefined) => Promise<unknown>;
920
+ /**
921
+ * Pushes a chat line into the chat dashboard window.
922
+ `content` accepts the same formats as `addRecord` `message`: plain
923
+ string, `[LangData, ...args]` tuple, or `{ en, ru?, uk? }` object.
924
+ * @requires AddonsPermission.DASHBOARD_CHAT
925
+ */
926
+ addChatMessage: (message: { id?: string | undefined; content: DashboardLocalizedString; platform: string; from?: string | undefined; emotes?: { word: string; url: string; }[] | undefined; }, user: { id: string; name: string; avatar?: string | undefined; platform: string; color?: string | undefined; icons?: string[] | undefined; } | undefined) => Promise<unknown>;
927
+ /**
928
+ * Subscribes to outgoing messages from the chat window input.
929
+ The handler receives `{ text }` when the user sends a message and this
930
+ addon is selected as a target.
931
+ * @requires AddonsPermission.DASHBOARD_CHAT
932
+ * @example dashboard.onChatSend(async ({ text }) => {
933
+ console.log('User sent:', text);
934
+ });
935
+ */
936
+ onChatSend: (handler: (payload: { text: string; }) => void | Promise<void>) => Promise<unknown>;
937
+ /**
938
+ * Unsubscribes from outgoing chat window messages.
939
+ * @requires AddonsPermission.DASHBOARD_CHAT
940
+ */
941
+ offChatSend: () => Promise<unknown>;
942
+ /**
943
+ * Subscribes to new chat messages shown in the chat dashboard window.
944
+ The handler receives a detailed payload with message metadata, author info,
945
+ and the addon id that pushed the message (if any).
946
+ * @requires AddonsPermission.DASHBOARD_CHAT_INCOMING
947
+ * @example dashboard.onChatMessage(msg => {
948
+ console.log(msg.message.content, msg.user?.name, msg.sourceAddonId);
949
+ });
950
+ */
951
+ onChatMessage: (handler: (payload: DashboardChatIncomingPayload) => void | Promise<void>) => Promise<unknown>;
952
+ /**
953
+ * Unsubscribes from incoming chat dashboard messages.
954
+ * @requires AddonsPermission.DASHBOARD_CHAT_INCOMING
955
+ */
956
+ offChatMessage: () => Promise<unknown>;
957
+ };
958
+ /**
959
+ * Game integration API for `manifest.type: "game"` addons.
960
+ Register in-game actions the user can bind to dashboard events in
961
+ **Settings → Game integrations**.
962
+ */
963
+ var game: {
964
+ /**
965
+ * Registers input triggers (in-game actions) for this game addon.
966
+ Call once at addon load. The user binds dashboard events to each action
967
+ in the addon settings UI. Handle invocations with
968
+ `events.On('gameInputTrigger', payload => { ... })`.
969
+
970
+ Game addons may also call `dashboard.registerTriggers()` (requires
971
+ `DASHBOARD_EVENTS`) so overlays and other modules can react to game events.
972
+ * @param options Registered actions (`id` must be unique within this addon).
973
+ * @example await game.registerInputTriggers([
974
+ { id: 'spawn_car', label: { en: 'Spawn car', ru: 'Заспавнить машину' } },
975
+ { id: 'explosion', label: { en: 'Explosion', ru: 'Взрыв' } },
976
+ ]);
977
+ events.On('gameInputTrigger', ({ actionId, trigger, record, user }) => {
978
+ if (actionId === 'spawn_car') { ... }
979
+ });
980
+ */
981
+ registerInputTriggers: (options: { id: string; label?: Partial<Record<"en" | "ru" | "uk", string>> | undefined; description?: Partial<Record<"en" | "ru" | "uk", string>> | undefined; }[]) => Promise<unknown>;
982
+ };
983
+ /**
984
+ * Declares addon settings schema for the settings UI and initializes default params.
985
+ Fields without `editor` are stored but not shown in the settings form.
986
+ A `button` field stores no value: it renders a button in the settings UI and,
987
+ when clicked, triggers the addon event named by its `event` property
988
+ (handle it with `events.On(event, ...)`).
989
+ * @param schema Declarative list of config keys, types, defaults, and optional editor metadata.
990
+ Nested arrays place multiple fields on one settings row.
991
+ * @returns Main-process response `{ success, params?, message? }`.
992
+ * @example GenerateConfig([
993
+ {
994
+ key: 'theme',
995
+ type: 'select',
996
+ default: 'dark',
997
+ options: [
998
+ { value: 'dark', label: { en: 'Dark', ru: 'Тёмная', uk: 'Темна' } },
999
+ { value: 'light', label: { en: 'Light', ru: 'Светлая', uk: 'Світла' } },
1000
+ ],
1001
+ editor: { label: { en: 'Theme', ru: 'Тема', uk: 'Тема' } },
1002
+ },
1003
+ [
1004
+ {
1005
+ key: 'width',
1006
+ type: 'number',
1007
+ default: 1920,
1008
+ editor: { label: { en: 'Width', ru: 'Ширина', uk: 'Ширина' } },
1009
+ },
1010
+ {
1011
+ key: 'height',
1012
+ type: 'number',
1013
+ default: 1080,
1014
+ editor: { label: { en: 'Height', ru: 'Высота', uk: 'Висота' } },
1015
+ },
1016
+ ],
1017
+ {
1018
+ key: 'oauth',
1019
+ type: 'text',
1020
+ default: '',
1021
+ editor: {
1022
+ label: { en: 'OAuth token', ru: 'OAuth токен', uk: 'OAuth токен' },
1023
+ required: true,
1024
+ validation: { pattern: '^[a-zA-Z0-9]+$' },
1025
+ },
1026
+ },
1027
+ { key: 'last_update', type: 'number', default: 0 },
1028
+ {
1029
+ key: 'reconnect',
1030
+ type: 'button',
1031
+ event: 'onReconnect',
1032
+ editor: { label: { en: 'Reconnect', ru: 'Переподключиться' } },
1033
+ },
1034
+ {
1035
+ key: 'game_dir',
1036
+ type: 'folder',
1037
+ default: '',
1038
+ pathPicker: { title: { en: 'Game folder', ru: 'Папка с игрой' } },
1039
+ editor: { label: { en: 'Install folder', ru: 'Папка установки' } },
1040
+ },
1041
+ {
1042
+ key: 'game_exe',
1043
+ type: 'file',
1044
+ default: '',
1045
+ pathPicker: {
1046
+ title: { en: 'Game executable', ru: 'Исполняемый файл игры' },
1047
+ filename: 'GTAV.exe',
1048
+ filters: [{ name: 'Executable', extensions: ['exe'] }],
1049
+ },
1050
+ editor: { label: { en: 'GTA V executable', ru: 'Файл GTAV.exe' }, required: true },
1051
+ },
1052
+ ]);
1053
+ // events.On('onReconnect', () => { ... });
1054
+ */
1055
+ var GenerateConfig: (schema: AddonConfigSchema) => Promise<unknown>;
1056
+
1057
+ /**
1058
+ * Addons permissions
1059
+ */
1060
+ type AddonsPermission =
1061
+ /**
1062
+ * Global access for all features
1063
+ */
1064
+ | 'ROOT'
1065
+ /**
1066
+ * Access to the storage module with a limit of 1MB
1067
+ */
1068
+ | 'INCREASE_CONFIG_SIZE'
1069
+ /**
1070
+ * Read full config file
1071
+ */
1072
+ | 'CONFIG_READ'
1073
+ /**
1074
+ * Read configuration parameters of other addons
1075
+ */
1076
+ | 'ADDON_CONFIG_READ'
1077
+ /**
1078
+ * Write full config file
1079
+ */
1080
+ | 'CONFIG_WRITE'
1081
+ /**
1082
+ * Perform network requests (GET, POST, PUT, DELETE)
1083
+ */
1084
+ | 'NETWORK_REQUEST'
1085
+ /**
1086
+ * Open outbound WebSocket connections
1087
+ */
1088
+ | 'NETWORK_WEBSOCKET'
1089
+ /**
1090
+ * Ability to create web endpoints
1091
+ */
1092
+ | 'WEB_END_POINTS'
1093
+ /**
1094
+ * Serve manifest-declared web page and static files for overlay
1095
+ */
1096
+ | 'WEB_CONTENT'
1097
+ /**
1098
+ * Display connection status in the main window status bar
1099
+ */
1100
+ | 'STATUS'
1101
+ /**
1102
+ * Push in-app notifications to the title-bar notification center
1103
+ */
1104
+ | 'NOTIFY'
1105
+ /**
1106
+ * Push events to the latest-events dashboard widget
1107
+ */
1108
+ | 'DASHBOARD_EVENTS'
1109
+ /**
1110
+ * Push messages to the chat dashboard window
1111
+ */
1112
+ | 'DASHBOARD_CHAT'
1113
+ /**
1114
+ * Receive new chat messages from the chat dashboard window
1115
+ */
1116
+ | 'DASHBOARD_CHAT_INCOMING'
1117
+ /**
1118
+ * Create Socket.IO namespaces for addon web pages and external clients
1119
+ */
1120
+ | 'SOCKET_END_POINTS';
1121
+ }
1122
+
1123
+ export {};
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@rocketman-streamkit/types",
3
+ "version": "1.0.0",
4
+ "description": "TypeScript declarations for the StreamKit+ integration addon sandbox API",
5
+ "types": "addon.d.ts",
6
+ "files": [
7
+ "addon.d.ts",
8
+ "README.md"
9
+ ],
10
+ "keywords": [
11
+ "streamkit",
12
+ "streamkitplus",
13
+ "addon",
14
+ "integration",
15
+ "typescript",
16
+ "types"
17
+ ],
18
+ "author": "XXanderWP",
19
+ "license": "ISC",
20
+ "publishConfig": {
21
+ "access": "public"
22
+ }
23
+ }