@unbound-app/api 0.11.0 → 1.1.1

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 (72) hide show
  1. package/ambient/image-modules.d.ts +58 -0
  2. package/package.json +27 -4
  3. package/src/_internal.d.ts +2775 -139
  4. package/src/{utils.d.ts → _types.d.ts} +10 -0
  5. package/src/assets.d.ts +64 -26
  6. package/src/builtins.d.ts +17 -0
  7. package/src/commands.d.ts +101 -25
  8. package/src/dialogs.d.ts +90 -25
  9. package/src/flux.d.ts +317 -0
  10. package/src/fonts.d.ts +51 -0
  11. package/src/fs.d.ts +15 -24
  12. package/src/global.d.ts +173 -11
  13. package/src/i18n.d.ts +33 -31
  14. package/src/iconPacks.d.ts +43 -0
  15. package/src/index.d.ts +14 -0
  16. package/src/marketplace.d.ts +50 -0
  17. package/src/metro/api.d.ts +8 -0
  18. package/src/metro/common.d.ts +34 -5
  19. package/src/metro/components.d.ts +34 -25
  20. package/src/metro/filters.d.ts +31 -16
  21. package/src/metro/index.d.ts +26079 -83
  22. package/src/metro/stores.d.ts +5 -0
  23. package/src/native.d.ts +77 -5
  24. package/src/patcher.d.ts +214 -57
  25. package/src/plugins.d.ts +55 -0
  26. package/src/settings.d.ts +8 -16
  27. package/src/shims.d.ts +5 -0
  28. package/src/storage.d.ts +80 -224
  29. package/src/sync.d.ts +51 -0
  30. package/src/themes.d.ts +43 -0
  31. package/src/toasts.d.ts +62 -9
  32. package/src/ui.d.ts +650 -0
  33. package/src/updates.d.ts +25 -0
  34. package/src/utils/index.d.ts +53 -0
  35. package/src/utils/react/index.d.ts +82 -0
  36. package/testing/fake-api.ts +256 -0
  37. package/testing/fake-components.ts +183 -0
  38. package/testing/fake-feedback.ts +258 -0
  39. package/testing/fake-fs.ts +54 -0
  40. package/testing/fake-java.ts +513 -0
  41. package/testing/fake-locales.ts +85 -0
  42. package/testing/fake-metro.ts +346 -0
  43. package/testing/fake-native-bridge.ts +98 -0
  44. package/testing/fake-native.ts +211 -0
  45. package/testing/fake-objc.ts +388 -0
  46. package/testing/fake-plugins.ts +176 -0
  47. package/testing/fake-react-native-modules.ts +362 -0
  48. package/testing/fake-react-native.ts +180 -0
  49. package/testing/fake-react.ts +54 -0
  50. package/testing/fake-settings-panel.ts +173 -0
  51. package/testing/fake-settings.ts +428 -0
  52. package/testing/fake-timers.ts +74 -0
  53. package/testing/fake-utils.ts +216 -0
  54. package/testing/icu-format.ts +132 -0
  55. package/testing/icu-parse.ts +277 -0
  56. package/testing/index.ts +42 -0
  57. package/testing/install-addon-globals.ts +260 -0
  58. package/testing/listener-registry.ts +39 -0
  59. package/testing/memory-storage.ts +149 -0
  60. package/testing/plugin-files.ts +155 -0
  61. package/testing/plugin-lifecycle.ts +149 -0
  62. package/testing/plugin-types.ts +34 -0
  63. package/testing/preset.ts +263 -0
  64. package/testing/react-patcher.ts +154 -0
  65. package/testing/react-value.ts +3 -0
  66. package/testing/recorders.ts +183 -0
  67. package/testing/recording-patcher.ts +173 -0
  68. package/testing/render.ts +84 -0
  69. package/testing/session.ts +77 -0
  70. package/testing/test-node.ts +163 -0
  71. package/testing/test-renderer.ts +753 -0
  72. package/testing/unfrozen-elements.ts +49 -0
@@ -1,8 +1,8 @@
1
1
  // Auto-generated by generate-plugin-sdk.ts - DO NOT EDIT
2
2
 
3
- import type { LiteralUnion } from './utils';
3
+ import type { LiteralUnion } from './_types';
4
4
  import * as React$1 from 'react';
5
- import { ComponentType, ReactNode } from 'react';
5
+ import { ComponentType, FunctionComponent, ReactElement, ReactNode } from 'react';
6
6
  import * as RN from 'react-native';
7
7
  import { ImageSourcePropType, ImageStyle, TextStyle, ViewStyle } from 'react-native';
8
8
 
@@ -15,10 +15,32 @@ declare const THEME_FLAG_KEYS: readonly [
15
15
  ];
16
16
  declare const TRANSITION_STATE_KEYS: readonly ['MOUNTED', 'ENTERED', 'YEETED'];
17
17
  declare const nativeHandle: unique symbol;
18
- /** The kinds of addon a manifest can declare. */
19
- export declare const ADDON_TYPES: readonly ['plugin', 'theme', 'icon-pack', 'font'];
18
+ declare const nativeJavaCallPlan: unique symbol;
19
+ declare const nativeObjCCallPlan: unique symbol;
20
+ /** The kinds of addon, as a manifest's `type` declares them. One manager governs each, in this start order. */
21
+ export declare const ADDON_KINDS: readonly ['plugin', 'theme', 'icon-pack', 'font'];
22
+ /**
23
+ * The globals a plugin bundle is evaluated with, in parameter order. Bytecode compiled against an earlier
24
+ * list receives them by position, so new globals are only ever appended.
25
+ */
26
+ export declare const ADDON_SCOPE_GLOBALS: readonly [
27
+ 'React',
28
+ 'unbound',
29
+ 'addon',
30
+ 'patcher',
31
+ 'logger',
32
+ 'setTimeout',
33
+ 'setInterval',
34
+ 'clearTimeout',
35
+ 'clearInterval',
36
+ 'commands',
37
+ ];
38
+ /** The core settings store; each addon's settings store is named after the addon id. */
39
+ export declare const CORE_SETTINGS_STORE = 'unbound';
20
40
  /** The components of Discord's design module, each of which Unbound can stand in for when Discord drops it. */
21
41
  export declare const DESIGN_COMPONENTS: readonly [
42
+ 'SearchBar',
43
+ 'Badge',
22
44
  'Text',
23
45
  'Heading',
24
46
  'TableRow',
@@ -55,6 +77,7 @@ export declare const DESIGN_COMPONENTS: readonly [
55
77
  'ActionSheetRow',
56
78
  'ContextMenu',
57
79
  ];
80
+ /** Every capability name a manifest may declare; an unknown name fails manifest validation. */
58
81
  export declare const NATIVE_PLUGIN_CAPABILITIES: readonly [
59
82
  'native.objc.classes',
60
83
  'native.objc.invoke',
@@ -80,6 +103,83 @@ export declare const NATIVE_PLUGIN_CAPABILITIES: readonly [
80
103
  'native.debug.evaluations',
81
104
  'native.debug.environment',
82
105
  ];
106
+ /** The Capability each native bridge method needs. */
107
+ export declare const NATIVE_PLUGIN_METHOD_CAPABILITIES: {
108
+ readonly 'objc.getClass': 'native.objc.classes';
109
+ readonly 'objc.alloc': 'native.objc.classes';
110
+ readonly 'objc.create': 'native.objc.invoke';
111
+ readonly 'objc.className': 'native.objc.classes';
112
+ readonly 'objc.respondsTo': 'native.objc.classes';
113
+ readonly 'objc.call': 'native.objc.invoke';
114
+ readonly 'objc.callSuper': 'native.objc.invoke';
115
+ readonly 'objc.invoke': 'native.objc.invoke';
116
+ readonly 'objc.prepare': 'native.objc.invoke';
117
+ readonly 'objc.invokePrepared': 'native.objc.invoke';
118
+ readonly 'objc.disposePlan': 'native.objc.invoke';
119
+ readonly 'objc.invokeAsync': 'native.objc.invokeAsync';
120
+ readonly 'objc.invokePreparedAsync': 'native.objc.invokeAsync';
121
+ readonly 'objc.batch': 'native.objc.batch';
122
+ readonly 'objc.snapshot': 'native.objc.snapshot';
123
+ readonly 'objc.findViews': 'native.objc.snapshot';
124
+ readonly 'objc.invokeSuper': 'native.objc.invoke';
125
+ readonly 'objc.invokeSuperAsync': 'native.objc.invokeAsync';
126
+ readonly 'objc.getIvar': 'native.objc.ivars';
127
+ readonly 'objc.setIvar': 'native.objc.ivars';
128
+ readonly 'objc.createAssociationKey': 'native.objc.associations';
129
+ readonly 'objc.getAssociatedObject': 'native.objc.associations';
130
+ readonly 'objc.setAssociatedObject': 'native.objc.associations';
131
+ readonly 'objc.struct': 'native.objc.classes';
132
+ readonly 'objc.array': 'native.objc.classes';
133
+ readonly 'objc.data': 'native.objc.classes';
134
+ readonly 'objc.hook': 'native.objc.hooks';
135
+ readonly 'ffi.symbol': 'native.ffi.symbols';
136
+ readonly 'ffi.call': 'native.ffi.call';
137
+ readonly 'fabric.mount': 'native.fabric.mount';
138
+ readonly 'fabric.update': 'native.fabric.mount';
139
+ readonly 'fabric.setSize': 'native.fabric.mount';
140
+ readonly 'fabric.setFrame': 'native.fabric.mount';
141
+ readonly 'fabric.measure': 'native.fabric.mount';
142
+ readonly 'fabric.unmount': 'native.fabric.mount';
143
+ readonly 'fabric.releaseIdle': 'native.fabric.mount';
144
+ readonly 'fabric.mountAsync': 'native.fabric.async';
145
+ readonly 'fabric.updateAsync': 'native.fabric.async';
146
+ readonly 'fabric.setSizeAsync': 'native.fabric.async';
147
+ readonly 'fabric.setFrameAsync': 'native.fabric.async';
148
+ readonly 'fabric.measureAsync': 'native.fabric.async';
149
+ readonly 'fabric.unmountAsync': 'native.fabric.async';
150
+ readonly 'fabric.releaseIdleAsync': 'native.fabric.async';
151
+ readonly 'runtime.subscribe': 'native.runtime.events';
152
+ readonly 'java.getClass': 'native.java.classes';
153
+ readonly 'java.className': 'native.java.classes';
154
+ readonly 'java.describe': 'native.java.classes';
155
+ readonly 'java.construct': 'native.java.construct';
156
+ readonly 'java.respondsTo': 'native.java.classes';
157
+ readonly 'java.invoke': 'native.java.invoke';
158
+ readonly 'java.invokeAsync': 'native.java.invokeAsync';
159
+ readonly 'java.prepare': 'native.java.invoke';
160
+ readonly 'java.invokePrepared': 'native.java.invoke';
161
+ readonly 'java.invokePreparedAsync': 'native.java.invokeAsync';
162
+ readonly 'java.disposePlan': 'native.java.invoke';
163
+ readonly 'java.getField': 'native.java.fields';
164
+ readonly 'java.setField': 'native.java.fields';
165
+ readonly 'java.release': 'native.java.classes';
166
+ readonly 'java.batch': 'native.java.batch';
167
+ readonly 'java.batchAsync': 'native.java.batch';
168
+ readonly 'java.findViews': 'native.java.invoke';
169
+ readonly 'java.createAssociationKey': 'native.java.associations';
170
+ readonly 'java.getAssociatedObject': 'native.java.associations';
171
+ readonly 'java.setAssociatedObject': 'native.java.associations';
172
+ readonly 'debug.recordEvaluation': 'native.debug.evaluations';
173
+ readonly 'debug.environment': 'native.debug.environment';
174
+ readonly 'hooks.hook': 'native.java.hooks';
175
+ readonly 'hooks.setReturnValue': 'native.java.hooks';
176
+ readonly 'hooks.removeReturnValue': 'native.java.hooks';
177
+ readonly 'hooks.clearReturnValues': 'native.java.hooks';
178
+ readonly 'hooks.remove': 'native.java.hooks';
179
+ };
180
+ /** The host platforms a native bridge runs on. */
181
+ export declare const NATIVE_PLUGIN_PLATFORMS: readonly ['ios', 'android'];
182
+ /** The capabilities each platform's loader offers; Objective-C ones are iOS only and Java ones Android only. */
83
183
  export declare const NATIVE_PLUGIN_PLATFORM_CAPABILITIES: {
84
184
  readonly android: readonly [
85
185
  'native.java.classes',
@@ -115,6 +215,8 @@ export declare const NATIVE_PLUGIN_PLATFORM_CAPABILITIES: {
115
215
  'native.runtime.events',
116
216
  ];
117
217
  };
218
+ /** The design components Discord added after the build the generated types describe; see {@link NewerDesignComponents}. */
219
+ export declare const NEWER_DESIGN_COMPONENTS: readonly ['SearchBar', 'Badge'];
118
220
  /**
119
221
  * Props of `AIGlyphText` (function). Exports: AIGlyphText.
120
222
  * @see design/visual-identities/ai/AIGlyphText.native.tsx
@@ -311,69 +413,83 @@ export type ActionSheetSwitchRowComponent = React$1.ComponentType<
311
413
  * @see design/components/Sheet/native/ActionSheetRow.native.tsx
312
414
  */
313
415
  export type ActionSheetSwitchRowProps = TableSwitchRowProps;
314
- /** A loaded addon entity: its runtime state, instance, source bundle, and {@link AddonManifest}. */
315
- export type Addon = {
316
- started: boolean;
317
- /** What the bundle evaluated to. Every addon kind may implement the {@link Plugin} lifecycle hooks. */
318
- instance: Plugin$1 | null;
319
- context?: PluginContext;
320
- id: string;
321
- failed: boolean;
322
- data: AddonManifest;
323
- bundle: string;
416
+ /** One image a plugin ships beside its bundle, as `ubd build` lists it in the manifest. */
417
+ export type AddonAsset = {
418
+ /** The file type. */
419
+ type: 'png' | 'jpg' | 'webp' | 'gif';
420
+ /** Width in points at scale 1. */
421
+ width: number;
422
+ /** Height in points at scale 1. */
423
+ height: number;
424
+ /** The SHA-256 of the file at each pixel density it ships at; the file is `assets/<sha256>.<type>` beside the bundle. */
425
+ scales: Partial<Record<'1' | '2' | '3', string>>;
324
426
  };
325
427
  /** The author of an addon: a display name and a numeric user id. */
326
428
  export type AddonAuthor = {
429
+ /** The name shown for the author. */
327
430
  name: string;
431
+ /** The author's Discord user id, as a string of digits. */
328
432
  id: `${number}`;
329
433
  };
330
- /** The manifest describing an addon's metadata, entry point, and source. */
331
- export type AddonManifest = {
332
- id: string;
333
- /** The addon kind this manifest describes; used to validate installs. */
334
- type?: AddonType;
335
- name: string;
336
- description: string;
337
- authors: AddonAuthor[];
338
- icon:
339
- | (string & {})
340
- | {
341
- uri: string;
342
- };
343
- updates: string;
344
- main: string;
345
- version: string;
346
- folder: string;
347
- path: string;
348
- url: string;
349
- platforms?: NativePluginPlatform[];
350
- capabilities?: NativePluginCapability[];
351
- platformCapabilities?: Partial<Record<NativePluginPlatform, NativePluginCapability[]>>;
352
- minNativePluginApi?: string;
353
- /** The Ed25519 signature the Unbound team's publish pipeline puts on first-party plugins. */
354
- signature?: {
355
- version: 1;
356
- ed25519: string;
357
- };
358
- /** Marks a plugin other plugins build on, which the plugin list hides by default. */
359
- library?: boolean;
360
- /** The addons this one needs, by id, each with the semver range it accepts, such as `^1.2.0`. */
361
- dependencies?: Record<string, string>;
362
- /** The SHA-512 of each bundle compiled to Hermes bytecode, by bytecode version; covered by `signature`. */
363
- bytecode?: Record<string, string>;
434
+ /**
435
+ * A loaded plugin, theme or icon pack its manager governs: its manifest and state, and what its manager
436
+ * does to it. Stringifies to its {@link AddonManifest}.
437
+ */
438
+ export type AddonHandle = {
439
+ /** The manifest's `id`. */
440
+ readonly id: string;
441
+ /** The manifest's display `name`. */
442
+ readonly name: string;
443
+ /** The manifest's `version`. */
444
+ readonly version: string;
445
+ /** The manifest's `authors`. */
446
+ readonly authors: AddonAuthor[];
447
+ /** The loaded manifest, including what the loader and installer recorded. */
448
+ readonly manifest: AddonManifest;
449
+ /** Whether the addon is running. */
450
+ readonly started: boolean;
451
+ /** Whether the addon failed to start. */
452
+ readonly failed: boolean;
453
+ /** Whether the user has the addon enabled, as its manager records it. */
454
+ isEnabled(): boolean;
455
+ /** Whether the plugin manager governs this addon. */
456
+ isPlugin(): boolean;
457
+ /** Asks the addon's manager to enable it. */
458
+ enable(): void | Promise<void>;
459
+ /** Asks the addon's manager to disable it. */
460
+ disable(): void;
461
+ /** Restarts the addon on its current bundle if it is running; settles once it is running again. */
462
+ reload(): Promise<void>;
463
+ /** Returns the manifest, so serializing the addon never leaks its bundle or instance. */
464
+ toJSON(): AddonManifest;
465
+ };
466
+ /** One addon kind, such as `plugin` or `icon-pack`; each has its own manager. */
467
+ export type AddonKind = (typeof ADDON_KINDS)[number];
468
+ /** The `logger` global a plugin runs with: console levels prefixed with the plugin's name. */
469
+ export type AddonLogger = Record<
470
+ 'log' | 'info' | 'success' | 'warn' | 'error' | 'debug',
471
+ (...args: unknown[]) => void
472
+ >;
473
+ /** A loaded addon's manifest: the {@link AuthoredAddonManifest} plus what the loader and installer record. */
474
+ export type AddonManifest = AuthoredAddonManifest & {
475
+ /** Set by the loader for an addon it read from disk: the addon's folder name. */
476
+ folder?: string;
477
+ /** Set by the loader for an addon it read from disk: the addon's absolute directory. */
478
+ path?: string;
364
479
  /** Set by the loader and installer: whether the bundle carries a valid Unbound signature. */
365
480
  trust?: AddonTrust;
366
- /** Requirements on the Unbound client running the addon. */
367
- unbound?: {
368
- /** The minimum Unbound client version (semver) the addon supports. */
369
- min?: string;
370
- };
371
481
  };
372
- /** An addon referenced either by its id string or the {@link Addon} entity itself. */
373
- export type AddonResolveable = string | Addon;
482
+ /** What an addon declares for one platform it runs on: the capabilities that platform provides which it needs. */
483
+ export type AddonPlatform<P extends NativePluginPlatform = NativePluginPlatform> = {
484
+ /** Capabilities needed on this platform only, added to the manifest's top-level `capabilities`. */
485
+ capabilities?: NativePluginPlatformCapability<P>[];
486
+ };
487
+ /** The platforms an addon runs on, keyed by platform. */
488
+ export type AddonPlatforms = {
489
+ [P in NativePluginPlatform]?: AddonPlatform<P>;
490
+ };
374
491
  /** Whether an addon's bundle carries a valid Unbound signature. */
375
492
  export type AddonTrust = 'signed' | 'unsigned';
376
- export type AddonType = (typeof ADDON_TYPES)[number];
377
493
  export type AlertActionButtonComponent = React$1.ComponentType<
378
494
  AlertActionButtonProps & Record<string, unknown>
379
495
  >;
@@ -410,11 +526,73 @@ export type AlertModalProps = {
410
526
  header?: StackProps['children'];
411
527
  title?: DesignTextProps['children'];
412
528
  };
529
+ /**
530
+ * An asset name of file type `T`: the names Discord's generated build registers as suggestions, and any other
531
+ * string, since a build may register names the generator never saw.
532
+ */
533
+ export type AssetName<T extends string = DiscordAssetType> = LiteralUnion<
534
+ DiscordAssetName<Extract<T, DiscordAssetType>>
535
+ >;
536
+ /** A file type the asset lookups take: Discord's types as suggestions, and any other string. */
537
+ export type AssetType = LiteralUnion<DiscordAssetType>;
413
538
  /** The native module used to register and resolve {@link DiscordAsset}s by id. */
414
539
  export type AssetsModule = {
540
+ /** Adds an asset to the registry and returns its new asset id. */
415
541
  registerAsset: (asset: DiscordAsset) => number;
542
+ /** Returns the asset registered under `id`; `null` or `undefined` when there is none. */
416
543
  getAssetByID: (id: number) => DiscordAsset | null;
417
544
  };
545
+ /** The manifest an author ships in an addon's `manifest.json`: its metadata and entry point. */
546
+ export type AuthoredAddonManifest = {
547
+ /** The unique id: alphanumeric runs joined by single `.`, `_` or `-`, at most 100 characters. */
548
+ id: string;
549
+ /** The addon kind this manifest describes; used to validate installs. */
550
+ type?: AddonKind;
551
+ /** The display name; must not be empty. */
552
+ name: string;
553
+ /** A short summary shown with the addon; may be empty. */
554
+ description: string;
555
+ /** Who made the addon; a published manifest lists at least one. */
556
+ authors: AddonAuthor[];
557
+ /** An image for the addon, as a URL or an `{ uri }` image source. */
558
+ icon?:
559
+ | string
560
+ | {
561
+ uri: string;
562
+ };
563
+ /** The bundle's path relative to the manifest, such as `index.js`; it may not leave the addon's directory. */
564
+ main: string;
565
+ /** The addon's version, in strict SemVer 2.0.0 with no `v` prefix. */
566
+ version: string;
567
+ /** The platforms the addon runs on, each with the capabilities it needs there; absent means every platform. */
568
+ platforms?: AddonPlatforms;
569
+ /** Capabilities the addon needs on every platform it runs on. */
570
+ capabilities?: NativePluginCapability[];
571
+ /** The lowest native plugin API version the addon supports; an older native bridge fails its start. */
572
+ minNativePluginApi?: string;
573
+ /** The Ed25519 signature the Unbound team's publish pipeline puts on first-party plugins. */
574
+ signature?: {
575
+ version: 1;
576
+ ed25519: string;
577
+ };
578
+ /** Marks a plugin other plugins build on, which the plugin list hides by default. */
579
+ library?: boolean;
580
+ /** Starts the plugin once Discord has drawn its first frame, for one that changes nothing on the first screen. */
581
+ startAfterFirstFrame?: boolean;
582
+ /** The addons this one needs, by id, each with the semver range it accepts, such as `^1.2.0`. */
583
+ dependencies?: Record<string, string>;
584
+ /** The SHA-512 of each bundle compiled to Hermes bytecode, by bytecode version; covered by `signature`. */
585
+ bytecode?: Record<string, string>;
586
+ /** The SHA-256 of each locale file beside the bundle (`i18n/<code>.json`), by locale code; en-US is in the bundle. */
587
+ locales?: Record<string, string>;
588
+ /** The images `ubd build` emits beside the bundle, by asset name, such as `icons/star`. */
589
+ assets?: Record<string, AddonAsset>;
590
+ /** Requirements on the Unbound client running the addon. */
591
+ unbound?: {
592
+ /** The minimum Unbound client version (semver) the addon supports. */
593
+ min?: string;
594
+ };
595
+ };
418
596
  export type AvatarDuoPileComponent = React$1.ComponentType<
419
597
  AvatarDuoPileProps & Record<string, unknown>
420
598
  >;
@@ -504,6 +682,34 @@ export type BackgroundBlurViewComponentProps = Omit<
504
682
  ref?: React$1.Ref<any>;
505
683
  style?: React$1.ComponentProps<typeof RN.View>['style'];
506
684
  };
685
+ /** The props of Discord's `Badge`, read from Discord 352's `design/components/Badge/native/Badge.native.tsx`. */
686
+ export type BadgeProps = {
687
+ /** A built-in label, or `{ text }` for custom text. */
688
+ type:
689
+ | 'new'
690
+ | 'beta'
691
+ | 'early_access'
692
+ | 'free_trial'
693
+ | {
694
+ text: string;
695
+ };
696
+ /** The badge's colour scheme. */
697
+ variant?: BadgeVariant;
698
+ /** A leading icon component, such as `StarIcon`, drawn at `xxs`. */
699
+ icon?: React$1.ComponentType<DiscordIconProps>;
700
+ };
701
+ /** The colours of Discord's `Badge`; with none, it is grey. `primary` is the brand colour. */
702
+ export type BadgeVariant =
703
+ | 'primary'
704
+ | 'secondary'
705
+ | 'expressive'
706
+ | 'premium'
707
+ | 'inverted'
708
+ | 'notification'
709
+ | 'rarity-common'
710
+ | 'rarity-rare'
711
+ | 'rarity-epic'
712
+ | 'rarity-mythic';
507
713
  /**
508
714
  * Props of `BaseIconButton` (function). Exports: BaseIconButton.
509
715
  * @see design/components/Button/native/BaseIconButton.native.tsx
@@ -810,6 +1016,14 @@ export type ButtonIconButtonProps = Omit<
810
1016
  export type ButtonPillProps = Omit<LoadingButtonPillProps, 'loading'> & {
811
1017
  loading?: boolean;
812
1018
  };
1019
+ /** A button row: it stores nothing, and calls the export `action` of the plugin's `src/actions.ts`. */
1020
+ export type ButtonSchema = SettingCommon & {
1021
+ kind: 'button';
1022
+ displayAs: 'button' | 'danger';
1023
+ action: string;
1024
+ /** The message key of a confirmation asked before `run`. */
1025
+ confirm?: string;
1026
+ };
813
1027
  /**
814
1028
  * Props of `ButtonShine` (function). Exports: ButtonShine.
815
1029
  * @see design/components/Button/native/ButtonShine.native.tsx
@@ -817,6 +1031,8 @@ export type ButtonPillProps = Omit<LoadingButtonPillProps, 'loading'> & {
817
1031
  export type ButtonShineProps = {
818
1032
  variant?: 'primary' | 'secondary' | 'tertiary' | (string & {});
819
1033
  };
1034
+ /** A callback the generator typed: kept as is, since its parameters and arity are what a caller relies on. */
1035
+ export type Callback = (...args: never[]) => unknown;
820
1036
  export type CameraLottieComponent = React$1.ComponentType<
821
1037
  CameraLottieProps & Record<string, unknown>
822
1038
  >;
@@ -827,6 +1043,17 @@ export type CameraLottieComponent = React$1.ComponentType<
827
1043
  export type CameraLottieProps = Omit<LottieIconProps, 'ref'> & {
828
1044
  ref?: LottieIconProps['ref'];
829
1045
  };
1046
+ /** A choice setting: one of its options' keys. */
1047
+ export type ChoiceSettingSchema = {
1048
+ /** Marks a setting that stores one of a fixed set of options. */
1049
+ kind: 'choice';
1050
+ /** Draws the options as a radio group, a picker sheet or a segmented control. */
1051
+ displayAs: 'radio' | 'picker' | 'segmented';
1052
+ /** The `const` of the option picked before the user changes it. */
1053
+ default: string;
1054
+ /** The options, in the order they are drawn. */
1055
+ options: SettingChoice[];
1056
+ };
830
1057
  export type CoachmarkComponent = React$1.ComponentType<CoachmarkProps>;
831
1058
  /**
832
1059
  * Props of `Coachmark` (function). Exports: Coachmark.
@@ -1107,28 +1334,50 @@ export type DesignCheckboxProps = {
1107
1334
  onToggle: (...args: any[]) => unknown;
1108
1335
  required?: unknown;
1109
1336
  };
1337
+ /** The name of one component in {@link DESIGN_COMPONENTS}. */
1110
1338
  export type DesignComponentName = (typeof DESIGN_COMPONENTS)[number];
1111
- /** Every component the `design/native.tsx` barrel exports, typed only by `bun run generate-discord-types`. */
1112
- export type DesignComponents = DesignBarrelComponents;
1339
+ /**
1340
+ * Every component the `design/native.tsx` barrel exports, typed by `bun run generate-discord-types` and made
1341
+ * {@link LooseModule | loose}: known props optional and checked where concrete, unknown props allowed.
1342
+ */
1343
+ export type DesignComponents = LooseModule<DesignBarrelComponents & NewerDesignComponents>;
1113
1344
  /** The design module's non-component exports (hooks, functions, constants), which the generator does not type. */
1114
1345
  export type DesignHelpers = {
1346
+ /** Discord's theme-aware style factory; see {@link CreateStyles}. */
1115
1347
  createStyles: CreateStyles;
1348
+ /** The text style Discord uses for each typography variant. */
1116
1349
  TextStyleSheet: Record<TextVariant, TextStyle>;
1350
+ /** Hook that resolves a semantic colour token, such as `Theme.colors.TEXT_DEFAULT`, to a colour for the current theme. */
1117
1351
  useToken: (token: SemanticColorToken) => string;
1352
+ /** Hook that builds the state a `SegmentedControl` and its `SegmentedControlPages` share. */
1118
1353
  useSegmentedControlState: (options: SegmentedControlStateOptions) => SegmentedControlState;
1354
+ /** Opens an alert as `openAlert(key, element)`; pass the same key to `dismissAlert` to close it. */
1119
1355
  openAlert: DiscordFunction<void>;
1356
+ /** Closes the alert opened under `key`. */
1120
1357
  dismissAlert: (key: string) => void;
1358
+ /** Closes every open alert. */
1121
1359
  dismissAlerts: DiscordFunction<void>;
1360
+ /** Shows a confirm modal from `{ title, content, confirmText, cancelText, onConfirm }`. */
1122
1361
  showConfirmModal: DiscordFunction;
1362
+ /** Shows an action sheet from `{ key, header: { title }, options: [{ label, icon, onPress }] }`. */
1123
1363
  showSimpleActionSheet: DiscordFunction;
1364
+ /** Closes the open context menu, such as after a plugin's menu item runs. */
1124
1365
  hideContextMenu: DiscordFunction<void>;
1366
+ /** Hook that returns the navigation of the screen the calling component renders in. */
1125
1367
  useNavigation: <T = any>() => Navigation<T>;
1368
+ /** Returns `color` with its opacity set to `opacity`. */
1126
1369
  setColorOpacity: (color: string, opacity: number) => string;
1370
+ /** Returns `color` darkened by `amount`. */
1127
1371
  darkenColor: (color: string, amount: number) => string;
1372
+ /** Returns `color` brightened by `amount`. */
1128
1373
  brightenColor: (color: string, amount: number) => string;
1374
+ /** Returns a colour that contrasts with `color`, for content drawn on it. */
1129
1375
  getContrastingColor: (color: string) => string;
1376
+ /** Discord's transition state enum; see {@link TransitionState}. */
1130
1377
  TransitionStates: EnumLike<typeof TRANSITION_STATE_KEYS>;
1378
+ /** Discord's theme flag enum: gradient themes, reduced or increased contrast, and reduced saturation. */
1131
1379
  ThemeContextFlags: EnumLike<typeof THEME_FLAG_KEYS>;
1380
+ /** The minimum WCAG contrast ratios Discord applies to non-text, text and high-contrast text. */
1132
1381
  WCAGContrastRatios: Record<'NonText' | 'Text' | 'HighContrastText', number>;
1133
1382
  };
1134
1383
  export type DesignModalComponent = React$1.ComponentType<
@@ -1318,17 +1567,1458 @@ export type DisableCustomThemeProps = {
1318
1567
  };
1319
1568
  /** An asset registered with Discord's packager (its metadata and dimensions). */
1320
1569
  export type DiscordAsset = {
1570
+ /** `true` on assets the React Native packager generated. */
1321
1571
  __packager_asset?: boolean;
1572
+ /** The file name without extension, such as `ic_close`; `assets.getByName` matches on it. */
1322
1573
  name: string;
1574
+ /** The asset's directory in the bundle, such as `/assets/images`. */
1323
1575
  httpServerLocation: string;
1576
+ /** Width in points at scale 1. */
1324
1577
  width: number;
1578
+ /** Height in points at scale 1. */
1325
1579
  height: number;
1580
+ /** The pixel densities the bundle ships the file at, such as `[1, 2, 3]`. */
1326
1581
  scales: number[];
1582
+ /** The packager's content hash of the file. */
1327
1583
  hash: string;
1584
+ /** The file extension, such as `png` or `svg`. */
1328
1585
  type: string;
1329
1586
  };
1587
+ /** The name of an asset Discord registers, of the given file types. */
1588
+ export type DiscordAssetName<T extends DiscordAssetType = DiscordAssetType> = DiscordAssetNames[T];
1589
+ /** The names of the assets Discord discord-350 registers, by file type, as `assets.getIdByName` takes them. */
1590
+ export type DiscordAssetNames = {
1591
+ jpg: 'background-splash-dev';
1592
+ lottie:
1593
+ | 'Camera'
1594
+ | 'MessageRequest'
1595
+ | 'MessagesTab'
1596
+ | 'Microphone'
1597
+ | 'NitroGem1'
1598
+ | 'NitroGem12'
1599
+ | 'NitroGem15'
1600
+ | 'NitroGem18'
1601
+ | 'NitroGem2'
1602
+ | 'NitroGem24'
1603
+ | 'NitroGem3'
1604
+ | 'NitroGem6'
1605
+ | 'NitroGem9'
1606
+ | 'NotificationsTab'
1607
+ | 'ServerTab'
1608
+ | 'SpendEarnOrbs'
1609
+ | 'SpendEarnOrbsLightTheme'
1610
+ | 'YouTab';
1611
+ png:
1612
+ | 'AccessibilityIcon'
1613
+ | 'AchievementsIcon'
1614
+ | 'ActivitiesIcon'
1615
+ | 'AnalyticsIcon'
1616
+ | 'AngryIcon'
1617
+ | 'AnnouncementsIcon'
1618
+ | 'AnnouncementsLockIcon'
1619
+ | 'AnnouncementsSpoilerIcon'
1620
+ | 'AnnouncementsWarningIcon'
1621
+ | 'AppIcon'
1622
+ | 'AppleNeutralIcon'
1623
+ | 'AppsIcon'
1624
+ | 'AppsLockIcon'
1625
+ | 'AppsSpoilerIcon'
1626
+ | 'AppsWarningIcon'
1627
+ | 'ArrowAngleLeftUpIcon'
1628
+ | 'ArrowAngleRightUpIcon'
1629
+ | 'ArrowLargeDownIcon'
1630
+ | 'ArrowLargeLeftIcon'
1631
+ | 'ArrowLargeRightIcon'
1632
+ | 'ArrowLargeUpIcon'
1633
+ | 'ArrowSmallDownIcon'
1634
+ | 'ArrowSmallLeftIcon'
1635
+ | 'ArrowSmallRightIcon'
1636
+ | 'ArrowSmallUpIcon'
1637
+ | 'ArrowsLeftRightIcon'
1638
+ | 'ArrowsUpDownIcon'
1639
+ | 'AtIcon'
1640
+ | 'AttachmentIcon'
1641
+ | 'BackspaceIcon'
1642
+ | 'BattlenetNeutralIcon'
1643
+ | 'BeakerIcon'
1644
+ | 'BeanieIcon'
1645
+ | 'BellIcon'
1646
+ | 'BellSlashIcon'
1647
+ | 'BellZIcon'
1648
+ | 'BicycleIcon'
1649
+ | 'BillIcon'
1650
+ | 'BlueskyNeutralIcon'
1651
+ | 'BlurBackgroundIcon'
1652
+ | 'BlurpleTwilightIcon'
1653
+ | 'BlushIcon'
1654
+ | 'BookCheckIcon'
1655
+ | 'BookmarkIcon'
1656
+ | 'BookmarkOutlineIcon'
1657
+ | 'BoostGemIcon'
1658
+ | 'BoostGemOutlineIcon'
1659
+ | 'BoostGemSlashIcon'
1660
+ | 'BoostTier1Icon'
1661
+ | 'BoostTier2Icon'
1662
+ | 'BoostTier3Icon'
1663
+ | 'BrandDarkIcon'
1664
+ | 'BrandInvertedIcon'
1665
+ | 'BugIcon'
1666
+ | 'BurgerIcon'
1667
+ | 'CalendarIcon'
1668
+ | 'CalendarMinusIcon'
1669
+ | 'CalendarPlusIcon'
1670
+ | 'CameraIcon'
1671
+ | 'CamoIcon'
1672
+ | 'CarIcon'
1673
+ | 'ChannelListIcon'
1674
+ | 'ChannelListMagnifyingGlassIcon'
1675
+ | 'ChannelListPlusIcon'
1676
+ | 'ChannelNotificationIcon'
1677
+ | 'ChannelsFollowedIcon'
1678
+ | 'ChatArrowRightIcon'
1679
+ | 'ChatCheckIcon'
1680
+ | 'ChatDotsIcon'
1681
+ | 'ChatIcon'
1682
+ | 'ChatMarkUnreadIcon'
1683
+ | 'ChatPlusIcon'
1684
+ | 'ChatShieldIcon'
1685
+ | 'ChatSmileIcon'
1686
+ | 'ChatWarningIcon'
1687
+ | 'ChatXIcon'
1688
+ | 'Check'
1689
+ | 'CheckmarkLargeBoldIcon'
1690
+ | 'CheckmarkLargeIcon'
1691
+ | 'CheckmarkSmallBoldIcon'
1692
+ | 'CheckmarkSmallIcon'
1693
+ | 'CherryBlossomIcon'
1694
+ | 'ChevronLargeDownIcon'
1695
+ | 'ChevronLargeLeftIcon'
1696
+ | 'ChevronLargeRightIcon'
1697
+ | 'ChevronLargeUpIcon'
1698
+ | 'ChevronSmallDownIcon'
1699
+ | 'ChevronSmallRightIcon'
1700
+ | 'ChevronSmallUpIcon'
1701
+ | 'CircleCheckIcon'
1702
+ | 'CircleCheckIcon-primary'
1703
+ | 'CircleCheckIcon-secondary'
1704
+ | 'CircleErrorIcon'
1705
+ | 'CircleErrorIcon-primary'
1706
+ | 'CircleErrorIcon-secondary'
1707
+ | 'CircleInformationIcon'
1708
+ | 'CircleInformationIcon-primary'
1709
+ | 'CircleInformationIcon-secondary'
1710
+ | 'CircleMinusIcon-primary'
1711
+ | 'CircleMinusIcon-secondary'
1712
+ | 'CirclePlayIcon-primary'
1713
+ | 'CirclePlayIcon-secondary'
1714
+ | 'CirclePlusIcon-primary'
1715
+ | 'CirclePlusIcon-secondary'
1716
+ | 'CircleQuestionIcon'
1717
+ | 'CircleQuestionIcon-primary'
1718
+ | 'CircleQuestionIcon-secondary'
1719
+ | 'CircleXIcon'
1720
+ | 'CircleXIcon-primary'
1721
+ | 'CircleXIcon-secondary'
1722
+ | 'CircuitIcon'
1723
+ | 'ClipboardCheckIcon'
1724
+ | 'ClipboardListIcon'
1725
+ | 'ClipsIcon'
1726
+ | 'ClockIcon'
1727
+ | 'ClockWarningIcon'
1728
+ | 'ClockXIcon'
1729
+ | 'ClosedCaptionsOutlineIcon'
1730
+ | 'CloudDownloadIcon'
1731
+ | 'CloudIcon'
1732
+ | 'ClydeIcon'
1733
+ | 'ColorWaveIcon'
1734
+ | 'CompassIcon'
1735
+ | 'ConnectionAverageIcon'
1736
+ | 'ConnectionBadIcon'
1737
+ | 'ConnectionFineIcon'
1738
+ | 'ConnectionUnknownIcon'
1739
+ | 'ControllerIcon'
1740
+ | 'CopyIcon'
1741
+ | 'CreditCardIcon'
1742
+ | 'CrownIcon'
1743
+ | 'CrunchyrollNeutralIcon'
1744
+ | 'DenyIcon'
1745
+ | 'DiceIcon'
1746
+ | 'Discord'
1747
+ | 'DoorExitIcon'
1748
+ | 'DoubleCheckmarkIcon'
1749
+ | 'DoubleChevronSmallRightIcon'
1750
+ | 'DownloadIcon'
1751
+ | 'DragIcon'
1752
+ | 'EducationIcon'
1753
+ | 'EmbedIcon'
1754
+ | 'EmojiAngryFaceWithHornsIcon'
1755
+ | 'EmojiColdFaceIcon'
1756
+ | 'EmojiCowboyHatFaceIcon'
1757
+ | 'EmojiCryingFaceIcon'
1758
+ | 'EmojiDisguisedFaceIcon'
1759
+ | 'EmojiFaceVomitingIcon'
1760
+ | 'EmojiFaceWithMonocleIcon'
1761
+ | 'EmojiFaceWithSpiralEyesIcon'
1762
+ | 'EmojiMeltingFaceIcon'
1763
+ | 'EmojiMoneyMouthFaceIcon'
1764
+ | 'EmojiNerdFaceIcon'
1765
+ | 'EmojiPartyingFaceIcon'
1766
+ | 'EmojiRollingOnTheFloorLaughingIcon'
1767
+ | 'EmojiSalutingFaceIcon'
1768
+ | 'EmojiSkullIcon'
1769
+ | 'EmojiSmilingFaceWithHeartsIcon'
1770
+ | 'EmojiSmilingFaceWithHornsIcon'
1771
+ | 'EmojiSmilingFaceWithSunglassesIcon'
1772
+ | 'EmojiSquintingFaceWithTongueIcon'
1773
+ | 'EmojiUpsideDownFaceIcon'
1774
+ | 'EmojiWoozyFaceIcon'
1775
+ | 'EmojiZanyFaceIcon'
1776
+ | 'EnvelopeIcon'
1777
+ | 'EpicGamesNeutralIcon'
1778
+ | 'ExampleSketchheadsActivity'
1779
+ | 'ExampleVoiceChatActivity'
1780
+ | 'ExperimentalCommonIcon'
1781
+ | 'ExperimentalDirectSelectIcon'
1782
+ | 'ExperimentalEpicIcon'
1783
+ | 'ExperimentalGameControllerLinkIcon'
1784
+ | 'ExperimentalLfgIcon'
1785
+ | 'ExperimentalLfgLockIcon'
1786
+ | 'ExperimentalMythicIcon'
1787
+ | 'ExperimentalRareIcon'
1788
+ | 'EyeDropperIcon'
1789
+ | 'EyeIcon'
1790
+ | 'EyeSlashIcon'
1791
+ | 'FacebookNeutralIcon'
1792
+ | 'FileIcon'
1793
+ | 'FileUpIcon'
1794
+ | 'FileWarningIcon'
1795
+ | 'FiltersHorizontalIcon'
1796
+ | 'FireIcon'
1797
+ | 'FlagIcon'
1798
+ | 'FlashIcon'
1799
+ | 'FolderIcon'
1800
+ | 'FolderPlusIcon'
1801
+ | 'FoodIcon'
1802
+ | 'ForumIcon'
1803
+ | 'ForumLockIcon'
1804
+ | 'ForumSpoilerIcon'
1805
+ | 'ForumWarningIcon'
1806
+ | 'FriendsIcon'
1807
+ | 'FullscreenEnterIcon'
1808
+ | 'GalaxyIcon'
1809
+ | 'GameControllerIcon'
1810
+ | 'GamingIcon'
1811
+ | 'GifIcon'
1812
+ | 'GiftIcon'
1813
+ | 'GlobeEarthIcon'
1814
+ | 'Glow'
1815
+ | 'GoogleNeutralIcon'
1816
+ | 'GridSquareIcon'
1817
+ | 'GroupArrowDownIcon'
1818
+ | 'GroupIcon'
1819
+ | 'GroupPlusIcon'
1820
+ | 'HammerIcon'
1821
+ | 'HandRequestDenyIcon'
1822
+ | 'HandRequestSpeakIcon'
1823
+ | 'HandRequestSpeakListIcon'
1824
+ | 'HashmarkIcon'
1825
+ | 'HeadphonesDenyIcon'
1826
+ | 'HeadphonesIcon'
1827
+ | 'HeadphonesSlashIcon'
1828
+ | 'HeartIcon'
1829
+ | 'HeartOutlineIcon'
1830
+ | 'HoloWavesIcon'
1831
+ | 'HomeIcon'
1832
+ | 'HourglassIcon'
1833
+ | 'HubIcon'
1834
+ | 'IAP_feature_education'
1835
+ | 'IdCardIcon'
1836
+ | 'IdIcon'
1837
+ | 'ImageBrokenIcon'
1838
+ | 'ImageFileIcon'
1839
+ | 'ImageIcon'
1840
+ | 'ImageLockIcon'
1841
+ | 'ImagePlusIcon'
1842
+ | 'ImageSparkleIcon'
1843
+ | 'ImageTextIcon'
1844
+ | 'ImageWarningIcon'
1845
+ | 'ImagesIcon'
1846
+ | 'InRainbowsIcon'
1847
+ | 'InboxIcon'
1848
+ | 'InstagramNeutralIcon'
1849
+ | 'InventoryIcon'
1850
+ | 'KeyIcon'
1851
+ | 'KeyboardIcon'
1852
+ | 'LanguageIcon'
1853
+ | 'LaptopPhoneIcon'
1854
+ | 'LettersIcon'
1855
+ | 'LightbulbIcon'
1856
+ | 'LinkExternalMediumIcon'
1857
+ | 'LinkExternalSmallIcon'
1858
+ | 'LinkIcon'
1859
+ | 'LinkPlusIcon'
1860
+ | 'ListBulletsIcon'
1861
+ | 'ListNumberedIcon'
1862
+ | 'ListViewIcon'
1863
+ | 'LocationIcon'
1864
+ | 'LockIcon'
1865
+ | 'LockUnlockedIcon'
1866
+ | 'MagicDoorIcon'
1867
+ | 'MagicWandIcon'
1868
+ | 'MagnifyingGlassIcon'
1869
+ | 'MangaIcon'
1870
+ | 'MatteDarkIcon'
1871
+ | 'MatteLightIcon'
1872
+ | 'MaximizeIcon'
1873
+ | 'MedalIcon'
1874
+ | 'MenuIcon'
1875
+ | 'MicrophoneArrowRightIcon'
1876
+ | 'MicrophoneDenyIcon'
1877
+ | 'MicrophoneIcon'
1878
+ | 'MicrophoneSlashIcon'
1879
+ | 'MidnightPrismIcon'
1880
+ | 'MinecraftNeutralIcon-primary'
1881
+ | 'MinecraftNeutralIcon-secondary'
1882
+ | 'MinecraftNeutralIcon-tertiary'
1883
+ | 'MobilePhoneDenyIcon'
1884
+ | 'MobilePhoneIcon'
1885
+ | 'MobilePhoneSettingsIcon'
1886
+ | 'MobilePhoneShareIcon'
1887
+ | 'ModerationIcon'
1888
+ | 'MoreHorizontalIcon'
1889
+ | 'MoreVerticalIcon'
1890
+ | 'MushroomIcon'
1891
+ | 'MusicIcon'
1892
+ | 'MusicSlashIcon'
1893
+ | 'NatureIcon'
1894
+ | 'NewUserIcon'
1895
+ | 'NewUserSimpleIcon'
1896
+ | 'NintendoSwitchNeutralIcon'
1897
+ | 'NitroWheelIcon'
1898
+ | 'NitroWheelIconWithGradient'
1899
+ | 'NotificationCenter'
1900
+ | 'ObjectIcon'
1901
+ | 'OrbsIcon'
1902
+ | 'PaintPaletteIcon'
1903
+ | 'PaintbrushThinIcon'
1904
+ | 'PaperIcon'
1905
+ | 'PaperPlusIcon'
1906
+ | 'PastelIcon'
1907
+ | 'PauseIcon'
1908
+ | 'PawPrintIcon'
1909
+ | 'PencilIcon'
1910
+ | 'PencilSparkleIcon'
1911
+ | 'PhoneCallIcon'
1912
+ | 'PhoneHangUpIcon'
1913
+ | 'PhoneIcon'
1914
+ | 'PiggyBankIcon'
1915
+ | 'PinIcon'
1916
+ | 'PirateIcon'
1917
+ | 'PlayIcon'
1918
+ | 'PlaystationNeutralIcon'
1919
+ | 'PlusLargeIcon'
1920
+ | 'PlusMediumIcon'
1921
+ | 'PlusSmallIcon'
1922
+ | 'PollsIcon'
1923
+ | 'PremiumGroupEmbedImage'
1924
+ | 'PuzzlePieceIcon'
1925
+ | 'QrCodeIcon'
1926
+ | 'QuestsIcon'
1927
+ | 'QuoteIcon'
1928
+ | 'ReactionIcon'
1929
+ | 'RecordPlayerIcon'
1930
+ | 'RedditNeutralIcon'
1931
+ | 'RedoIcon'
1932
+ | 'RefreshIcon'
1933
+ | 'RemixIcon'
1934
+ | 'RetryIcon'
1935
+ | 'RibbonIcon'
1936
+ | 'RiotGamesNeutralIcon'
1937
+ | 'RobloxNeutralIcon'
1938
+ | 'RobotIcon'
1939
+ | 'SaveIcon'
1940
+ | 'ScienceIcon'
1941
+ | 'ScreenArrowIcon'
1942
+ | 'ScreenIcon'
1943
+ | 'ScreenStreamIcon'
1944
+ | 'ScreenXIcon'
1945
+ | 'SendMessageIcon'
1946
+ | 'ServerGridIcon'
1947
+ | 'ServerIcon'
1948
+ | 'SettingsIcon'
1949
+ | 'SettingsInfoIcon'
1950
+ | 'Share'
1951
+ | 'ShareIcon'
1952
+ | 'ShieldIcon'
1953
+ | 'ShieldLockIcon'
1954
+ | 'ShieldUserIcon'
1955
+ | 'ShopIcon'
1956
+ | 'SignPostIcon'
1957
+ | 'SlashBoxIcon'
1958
+ | 'SlashIcon'
1959
+ | 'Small'
1960
+ | 'SoundboardIcon'
1961
+ | 'SoundboardSlashIcon'
1962
+ | 'SparklesIcon'
1963
+ | 'SpeedometerIcon'
1964
+ | 'SpoilerIcon'
1965
+ | 'SpotifyNeutralIcon'
1966
+ | 'StaffBadgeIcon'
1967
+ | 'StageIcon'
1968
+ | 'StageLockIcon'
1969
+ | 'StampIcon'
1970
+ | 'StampXIcon'
1971
+ | 'StarIcon'
1972
+ | 'StarOutlineIcon'
1973
+ | 'StatusDND'
1974
+ | 'StatusIdle'
1975
+ | 'StatusMobileOnline'
1976
+ | 'StatusOffline'
1977
+ | 'StatusOnline'
1978
+ | 'StatusStreaming'
1979
+ | 'StatusVROnline'
1980
+ | 'SteamNeutralIcon'
1981
+ | 'StickerIcon'
1982
+ | 'StickerPlusIcon'
1983
+ | 'StopIcon'
1984
+ | 'SubscriptionIcon'
1985
+ | 'SunsetIcon'
1986
+ | 'SuperReactionIcon'
1987
+ | 'TagIcon'
1988
+ | 'TagsIcon'
1989
+ | 'TeacupIcon'
1990
+ | 'TextControllerIcon'
1991
+ | 'TextIcon'
1992
+ | 'TextLockIcon'
1993
+ | 'TextSpoilerIcon'
1994
+ | 'TextWarningIcon'
1995
+ | 'ThemeDarkIcon'
1996
+ | 'ThemeGrayIcon'
1997
+ | 'ThemeLightIcon'
1998
+ | 'ThemeMidnightIcon'
1999
+ | 'ThreadIcon'
2000
+ | 'ThreadLockIcon'
2001
+ | 'ThreadMinusIcon'
2002
+ | 'ThreadPlusIcon'
2003
+ | 'ThumbsDownIcon'
2004
+ | 'ThumbsUpIcon'
2005
+ | 'TicketIcon'
2006
+ | 'TiktokNeutralIcon'
2007
+ | 'TimerIcon'
2008
+ | 'TopicsIcon'
2009
+ | 'TrainIcon'
2010
+ | 'TranscriptOutlineIcon'
2011
+ | 'TrashIcon'
2012
+ | 'TreehouseIcon'
2013
+ | 'TrophyIcon'
2014
+ | 'TvIcon'
2015
+ | 'TwitchNeutralIcon'
2016
+ | 'TwitterNeutralIcon'
2017
+ | 'UndoIcon'
2018
+ | 'UnknownGameIcon'
2019
+ | 'UnsendIcon'
2020
+ | 'UploadIcon'
2021
+ | 'UserCheckIcon'
2022
+ | 'UserCircleIcon'
2023
+ | 'UserClockIcon'
2024
+ | 'UserIcon'
2025
+ | 'UserMinusIcon'
2026
+ | 'UserPlatformIcon'
2027
+ | 'UserPlusIcon'
2028
+ | 'UserSquareIcon'
2029
+ | 'VideoDenyIcon'
2030
+ | 'VideoIcon'
2031
+ | 'VideoSelfieIcon'
2032
+ | 'VideoSlashIcon'
2033
+ | 'VoiceLockIcon'
2034
+ | 'VoiceNormalIcon'
2035
+ | 'VoiceNormalSpoilerIcon'
2036
+ | 'VoiceWarningIcon'
2037
+ | 'VoiceXIcon'
2038
+ | 'VrHeadsetIcon'
2039
+ | 'WarningIcon'
2040
+ | 'WaveformIcon'
2041
+ | 'WebhookIcon'
2042
+ | 'WebhookPlusIcon'
2043
+ | 'WidgetsIcon'
2044
+ | 'WindowLaunchIcon'
2045
+ | 'WrenchIcon'
2046
+ | 'XLargeBoldIcon'
2047
+ | 'XLargeIcon'
2048
+ | 'XNeutralIcon'
2049
+ | 'XSmallBoldIcon'
2050
+ | 'XSmallIcon'
2051
+ | 'XboxNeutralIcon'
2052
+ | 'Y2KIcon'
2053
+ | 'YoutubeNeutralIcon'
2054
+ | 'add'
2055
+ | 'add_friend_32px'
2056
+ | 'add_server'
2057
+ | 'add_white'
2058
+ | 'airplay'
2059
+ | 'alert'
2060
+ | 'amanda_1'
2061
+ | 'amanda_2'
2062
+ | 'announcement_birb'
2063
+ | 'app_dock_no_permissions_dark'
2064
+ | 'app_dock_no_permissions_light'
2065
+ | 'app_dock_not_found_dark'
2066
+ | 'app_dock_not_found_light'
2067
+ | 'app_icon_marketing'
2068
+ | 'app_icons_upsell'
2069
+ | 'app_installed_check'
2070
+ | 'arrow'
2071
+ | 'arrow-right'
2072
+ | 'arrow-sm-down'
2073
+ | 'asset_blurred_media_post_preview'
2074
+ | 'asset_bronze_badge_small'
2075
+ | 'asset_diamond_badge_small'
2076
+ | 'asset_emerald_badge_small'
2077
+ | 'asset_gold_badge_small'
2078
+ | 'asset_gradient'
2079
+ | 'asset_nitro_ticket'
2080
+ | 'asset_opal_badge_small'
2081
+ | 'asset_platinum_badge_small'
2082
+ | 'asset_role_subscription_earnings'
2083
+ | 'asset_role_subscription_exclusive_perks'
2084
+ | 'asset_role_subscription_megaphone'
2085
+ | 'asset_ruby_badge_small'
2086
+ | 'asset_silver_badge_small'
2087
+ | 'audience_welcome'
2088
+ | 'audio'
2089
+ | 'auto_moderation_avatar'
2090
+ | 'avatar_placeholder'
2091
+ | 'back-icon'
2092
+ | 'back-icon-mask'
2093
+ | 'background'
2094
+ | 'background-splash-mobile'
2095
+ | 'badconnection'
2096
+ | 'badge'
2097
+ | 'badge_2'
2098
+ | 'bg'
2099
+ | 'blocked-purchases-dark'
2100
+ | 'blocked-purchases-light'
2101
+ | 'blocked_dark'
2102
+ | 'blocked_darker'
2103
+ | 'blocked_light'
2104
+ | 'blue-pointer-hand'
2105
+ | 'boost'
2106
+ | 'box_idle'
2107
+ | 'breaddog_1'
2108
+ | 'cactus'
2109
+ | 'cake_idle'
2110
+ | 'camera'
2111
+ | 'camera-swap'
2112
+ | 'camera_swap'
2113
+ | 'camera_upload'
2114
+ | 'camera_upload_light'
2115
+ | 'cap_2'
2116
+ | 'channel-following-backdrop-dark'
2117
+ | 'channel-following-backdrop-light'
2118
+ | 'channel_following_success_1'
2119
+ | 'channel_following_success_2'
2120
+ | 'channel_following_success_3'
2121
+ | 'channel_settings_grid_view_example_post'
2122
+ | 'channel_settings_list_view_example_post'
2123
+ | 'channel_setup'
2124
+ | 'channel_setup_darker'
2125
+ | 'channel_setup_light'
2126
+ | 'channels-empty'
2127
+ | 'check-with-stars'
2128
+ | 'chest_idle'
2129
+ | 'clear-icon'
2130
+ | 'client_theme'
2131
+ | 'client_themes_upsell'
2132
+ | 'close'
2133
+ | 'close-icon'
2134
+ | 'clouds_background'
2135
+ | 'clouds_light_background'
2136
+ | 'clyde-avatar'
2137
+ | 'code-illustration-dark'
2138
+ | 'code-illustration-light'
2139
+ | 'coffee_idle'
2140
+ | 'confetti'
2141
+ | 'conjure_activity_dark'
2142
+ | 'conjure_activity_light'
2143
+ | 'connections-profile-steam-dota2'
2144
+ | 'connections-profile-steam-tf2'
2145
+ | 'conversation'
2146
+ | 'copy'
2147
+ | 'crunchyroll_connect'
2148
+ | 'crunchyroll_link_intro'
2149
+ | 'crunchyroll_link_success'
2150
+ | 'cs'
2151
+ | 'cta'
2152
+ | 'custom_icons'
2153
+ | 'custom_profile'
2154
+ | 'custom_sounds'
2155
+ | 'customize_empty'
2156
+ | 'customize_empty_light'
2157
+ | 'da'
2158
+ | 'dark_home_header_placeholder'
2159
+ | 'de'
2160
+ | 'deafen'
2161
+ | 'debug'
2162
+ | 'default_avatar_0'
2163
+ | 'default_avatar_0_small'
2164
+ | 'default_avatar_1'
2165
+ | 'default_avatar_1_small'
2166
+ | 'default_avatar_2'
2167
+ | 'default_avatar_2_small'
2168
+ | 'default_avatar_3'
2169
+ | 'default_avatar_3_small'
2170
+ | 'default_avatar_4'
2171
+ | 'default_avatar_4_small'
2172
+ | 'default_avatar_5'
2173
+ | 'default_avatar_5_small'
2174
+ | 'default_provisional_avatar_0'
2175
+ | 'default_provisional_avatar_1'
2176
+ | 'default_provisional_avatar_2'
2177
+ | 'default_provisional_avatar_3'
2178
+ | 'default_provisional_avatar_4'
2179
+ | 'default_provisional_avatar_5'
2180
+ | 'devices_not_found'
2181
+ | 'discoverability-header'
2182
+ | 'early_access'
2183
+ | 'el'
2184
+ | 'emoji'
2185
+ | 'emoji-negative'
2186
+ | 'emoji-neutral'
2187
+ | 'emoji-positive'
2188
+ | 'empty'
2189
+ | 'empty-suggestions-header'
2190
+ | 'empty_castle'
2191
+ | 'empty_permission'
2192
+ | 'empty_photos'
2193
+ | 'empty_quest_home'
2194
+ | 'empty_quick_switcher'
2195
+ | 'empty_server_settings_audit_log_dark'
2196
+ | 'empty_server_settings_audit_log_darker'
2197
+ | 'empty_server_settings_audit_log_light'
2198
+ | 'empty_server_settings_emoji_dark'
2199
+ | 'empty_server_settings_emoji_darker'
2200
+ | 'empty_server_settings_emoji_light'
2201
+ | 'empty_voice_channel'
2202
+ | 'en-GB'
2203
+ | 'en-US'
2204
+ | 'entrace_sounds'
2205
+ | 'es-419'
2206
+ | 'es-ES'
2207
+ | 'failure-header'
2208
+ | 'family_center_activity_banner_image_parent'
2209
+ | 'family_center_activity_banner_image_teen'
2210
+ | 'family_center_activity_checklist_image'
2211
+ | 'family_center_chat_check_icon'
2212
+ | 'featured_page_footer_dark'
2213
+ | 'featured_page_footer_light'
2214
+ | 'feedback-modal-happy'
2215
+ | 'feedback-modal-happy-desaturated'
2216
+ | 'feedback-modal-happy-desaturated_darker'
2217
+ | 'feedback-modal-neutral'
2218
+ | 'feedback-modal-neutral-desaturated'
2219
+ | 'feedback-modal-neutral-desaturated_darker'
2220
+ | 'feedback-modal-sad'
2221
+ | 'feedback-modal-sad-desaturated'
2222
+ | 'feedback-modal-sad-desaturated_darker'
2223
+ | 'fi'
2224
+ | 'finishing_touches'
2225
+ | 'finishing_touches_light'
2226
+ | 'fist_bump'
2227
+ | 'flash'
2228
+ | 'fr'
2229
+ | 'fullscreen'
2230
+ | 'game-empty-state'
2231
+ | 'game-empty-state-controller'
2232
+ | 'game_icon_placeholder'
2233
+ | 'gif'
2234
+ | 'gift_box'
2235
+ | 'gift_cake'
2236
+ | 'gift_chest'
2237
+ | 'gift_coffee'
2238
+ | 'gmail'
2239
+ | 'googleauth-logo'
2240
+ | 'graggle_2'
2241
+ | 'grey_badge'
2242
+ | 'grey_server_boosts'
2243
+ | 'grid'
2244
+ | 'guild_identity_education_dark'
2245
+ | 'guild_identity_education_light'
2246
+ | 'guild_subscription_no_guilds_dark'
2247
+ | 'guild_subscription_no_guilds_darker'
2248
+ | 'guild_subscription_no_guilds_light'
2249
+ | 'guild_subscription_removal_dark'
2250
+ | 'guild_subscription_removal_darker'
2251
+ | 'guild_subscription_removal_light'
2252
+ | 'hd_video'
2253
+ | 'header-art-onboarding'
2254
+ | 'header_arrow_right'
2255
+ | 'hero-orbs'
2256
+ | 'hi'
2257
+ | 'history'
2258
+ | 'hr'
2259
+ | 'hu'
2260
+ | 'hub-header'
2261
+ | 'hub_header'
2262
+ | 'ic-application-rejected'
2263
+ | 'ic-application-required'
2264
+ | 'ic-application-submitted'
2265
+ | 'ic-customize'
2266
+ | 'ic-location'
2267
+ | 'ic_add_18px'
2268
+ | 'ic_add_24px'
2269
+ | 'ic_add_circle'
2270
+ | 'ic_add_perk_24px'
2271
+ | 'ic_add_reaction_v2'
2272
+ | 'ic_add_super_reaction'
2273
+ | 'ic_add_tier_40px'
2274
+ | 'ic_alert'
2275
+ | 'ic_application_command_24px'
2276
+ | 'ic_application_command_built_in'
2277
+ | 'ic_archived_thread_embed_16px'
2278
+ | 'ic_arrow'
2279
+ | 'ic_arrow_back_24px'
2280
+ | 'ic_arrow_down'
2281
+ | 'ic_arrow_forward_24px'
2282
+ | 'ic_arrow_right'
2283
+ | 'ic_audit_create_24px'
2284
+ | 'ic_audit_delete_24px'
2285
+ | 'ic_audit_update_24px'
2286
+ | 'ic_auto_moderation_shield'
2287
+ | 'ic_badge_nitro'
2288
+ | 'ic_badge_staff'
2289
+ | 'ic_bell_on'
2290
+ | 'ic_block'
2291
+ | 'ic_blocked_chat_bubble_icon'
2292
+ | 'ic_browse_channel'
2293
+ | 'ic_caret_24px'
2294
+ | 'ic_category_16px'
2295
+ | 'ic_channel_arrow'
2296
+ | 'ic_channel_arrow_collapsed_24px'
2297
+ | 'ic_chat_bubble_32px'
2298
+ | 'ic_check_18px'
2299
+ | 'ic_check_24px'
2300
+ | 'ic_checkmark'
2301
+ | 'ic_clock'
2302
+ | 'ic_close'
2303
+ | 'ic_close_16px'
2304
+ | 'ic_close_18px'
2305
+ | 'ic_close_24px'
2306
+ | 'ic_close_circle'
2307
+ | 'ic_close_circle_24px'
2308
+ | 'ic_closed_lock'
2309
+ | 'ic_community_guild_badge_dark_24px'
2310
+ | 'ic_community_guild_badge_light_24px'
2311
+ | 'ic_community_guild_badge_premium_24px'
2312
+ | 'ic_controller_24px'
2313
+ | 'ic_crown_16px'
2314
+ | 'ic_discoverable_guild_badge_dark_24px'
2315
+ | 'ic_discoverable_guild_badge_light_24px'
2316
+ | 'ic_discoverable_guild_badge_premium_24px'
2317
+ | 'ic_download_24px'
2318
+ | 'ic_drag_icon_24px'
2319
+ | 'ic_emoji_picker_20px'
2320
+ | 'ic_emoji_recent_color_24px'
2321
+ | 'ic_emoji_zipper_24px'
2322
+ | 'ic_event_calendar'
2323
+ | 'ic_expand_more_24px'
2324
+ | 'ic_eye'
2325
+ | 'ic_eye_hidden'
2326
+ | 'ic_feed_more'
2327
+ | 'ic_feedback'
2328
+ | 'ic_feedback_dark'
2329
+ | 'ic_file_small_acrobat'
2330
+ | 'ic_file_small_ae'
2331
+ | 'ic_file_small_ai'
2332
+ | 'ic_file_small_archive'
2333
+ | 'ic_file_small_audio'
2334
+ | 'ic_file_small_code'
2335
+ | 'ic_file_small_document'
2336
+ | 'ic_file_small_image'
2337
+ | 'ic_file_small_ps'
2338
+ | 'ic_file_small_sketch'
2339
+ | 'ic_file_small_spreadsheet'
2340
+ | 'ic_file_small_unknown'
2341
+ | 'ic_file_small_video'
2342
+ | 'ic_file_small_webcode'
2343
+ | 'ic_flower_star_18px'
2344
+ | 'ic_flower_star_24px'
2345
+ | 'ic_forward_chevron'
2346
+ | 'ic_friend_wave_24px'
2347
+ | 'ic_full_server_gating_24px'
2348
+ | 'ic_gear'
2349
+ | 'ic_gift'
2350
+ | 'ic_group'
2351
+ | 'ic_group_dm'
2352
+ | 'ic_guild_grid_24px'
2353
+ | 'ic_guild_template'
2354
+ | 'ic_guild_video_24px'
2355
+ | 'ic_guild_voice_24px'
2356
+ | 'ic_header_members_24px'
2357
+ | 'ic_headset_deafened_24px'
2358
+ | 'ic_headset_deafened_dark_24px'
2359
+ | 'ic_headset_neutral'
2360
+ | 'ic_hide_24px'
2361
+ | 'ic_highlight'
2362
+ | 'ic_home'
2363
+ | 'ic_icon_upload'
2364
+ | 'ic_image'
2365
+ | 'ic_image_upload'
2366
+ | 'ic_information_24px'
2367
+ | 'ic_information_filled_24px'
2368
+ | 'ic_input_clear_24px'
2369
+ | 'ic_invite'
2370
+ | 'ic_invites_disabled'
2371
+ | 'ic_launch'
2372
+ | 'ic_leave_24px'
2373
+ | 'ic_leave_stage'
2374
+ | 'ic_link_24px'
2375
+ | 'ic_loading_emoji_dark'
2376
+ | 'ic_loading_emoji_light'
2377
+ | 'ic_lock'
2378
+ | 'ic_lock_short_16px'
2379
+ | 'ic_mail'
2380
+ | 'ic_media_post_share_prompt'
2381
+ | 'ic_members'
2382
+ | 'ic_members_24px'
2383
+ | 'ic_mention_24px'
2384
+ | 'ic_message'
2385
+ | 'ic_mic_24px'
2386
+ | 'ic_mic_muted_24px'
2387
+ | 'ic_mic_muted_dark_24px'
2388
+ | 'ic_mic_muted_light_24px'
2389
+ | 'ic_mic_neutral'
2390
+ | 'ic_minimize'
2391
+ | 'ic_mobile_device'
2392
+ | 'ic_moderator'
2393
+ | 'ic_money_emoji_24px'
2394
+ | 'ic_monitor'
2395
+ | 'ic_more_24px'
2396
+ | 'ic_move_to_audience'
2397
+ | 'ic_move_to_speaker'
2398
+ | 'ic_mute_channel_24px'
2399
+ | 'ic_nitro_basic_wheel_gradient'
2400
+ | 'ic_nitro_wheel'
2401
+ | 'ic_nitro_wheel_gradient_purple'
2402
+ | 'ic_notif'
2403
+ | 'ic_notif_off'
2404
+ | 'ic_overflow_android'
2405
+ | 'ic_paperclip_24px'
2406
+ | 'ic_partnered_guild_icon_black_24px'
2407
+ | 'ic_partnered_guild_icon_blurple_24px'
2408
+ | 'ic_person_shield'
2409
+ | 'ic_person_waving'
2410
+ | 'ic_pins'
2411
+ | 'ic_play'
2412
+ | 'ic_play_dark'
2413
+ | 'ic_playstation_24px'
2414
+ | 'ic_playstation_device_ps5_32px'
2415
+ | 'ic_polls'
2416
+ | 'ic_premium_channel_16px'
2417
+ | 'ic_premium_info_24px'
2418
+ | 'ic_premium_overview_24px'
2419
+ | 'ic_premium_perk_money_24px'
2420
+ | 'ic_premium_tiers_24px'
2421
+ | 'ic_profile_badge_active_developer'
2422
+ | 'ic_public'
2423
+ | 'ic_qr_code_24px'
2424
+ | 'ic_radio_circle'
2425
+ | 'ic_radio_circle_checked'
2426
+ | 'ic_radio_circle_checked_green'
2427
+ | 'ic_radio_square_24px'
2428
+ | 'ic_radio_square_checked_24px'
2429
+ | 'ic_raised_hand'
2430
+ | 'ic_raised_hand_list'
2431
+ | 'ic_report_message'
2432
+ | 'ic_rulebook'
2433
+ | 'ic_rulebook_16px'
2434
+ | 'ic_select_all_24px'
2435
+ | 'ic_select_manually_24px'
2436
+ | 'ic_selection_checked_24px'
2437
+ | 'ic_selection_none_24px'
2438
+ | 'ic_send'
2439
+ | 'ic_settings'
2440
+ | 'ic_settings_grey_24px'
2441
+ | 'ic_settings_white_24px'
2442
+ | 'ic_share_android'
2443
+ | 'ic_share_ios'
2444
+ | 'ic_shield_24px'
2445
+ | 'ic_show_password'
2446
+ | 'ic_sparkle'
2447
+ | 'ic_sparkle2'
2448
+ | 'ic_spotify_white_16px'
2449
+ | 'ic_stage_channel_24px'
2450
+ | 'ic_stage_channel_32px'
2451
+ | 'ic_stage_music'
2452
+ | 'ic_stage_music_disabled'
2453
+ | 'ic_star_filled'
2454
+ | 'ic_sticker_24px'
2455
+ | 'ic_stop_stream_24px'
2456
+ | 'ic_swipe_reply_24px'
2457
+ | 'ic_sync_24px'
2458
+ | 'ic_table_arrow_right'
2459
+ | 'ic_text_channel_16px'
2460
+ | 'ic_text_in_voice_24px'
2461
+ | 'ic_thread_normal_24px'
2462
+ | 'ic_thumbsdown'
2463
+ | 'ic_thumbsup'
2464
+ | 'ic_trash_24px'
2465
+ | 'ic_trash_filled_16px'
2466
+ | 'ic_unmute_channel_24px'
2467
+ | 'ic_update_profile'
2468
+ | 'ic_upload'
2469
+ | 'ic_upload_image_40px'
2470
+ | 'ic_verified_check_18px'
2471
+ | 'ic_verified_check_24px'
2472
+ | 'ic_verified_guild_icon_black_24px'
2473
+ | 'ic_verified_guild_icon_green_24px'
2474
+ | 'ic_verified_icon_white_16px'
2475
+ | 'ic_video'
2476
+ | 'ic_video_disabled_dark'
2477
+ | 'ic_video_disabled_white'
2478
+ | 'ic_voice_channel_16px'
2479
+ | 'ic_voice_channel_24px'
2480
+ | 'ic_volume'
2481
+ | 'ic_volume_locked'
2482
+ | 'ic_volume_mute'
2483
+ | 'ic_vr_headset_24px'
2484
+ | 'ic_wand'
2485
+ | 'ic_warning_24px'
2486
+ | 'ic_wreath'
2487
+ | 'ic_xbox_24px'
2488
+ | 'icon-afk'
2489
+ | 'icon-call'
2490
+ | 'icon-group'
2491
+ | 'icon-new-group'
2492
+ | 'icon-search'
2493
+ | 'icon-server-muted'
2494
+ | 'icon-settings'
2495
+ | 'icon0'
2496
+ | 'icon1'
2497
+ | 'icon2'
2498
+ | 'icon3'
2499
+ | 'icon4'
2500
+ | 'icon5'
2501
+ | 'icon6'
2502
+ | 'icon7'
2503
+ | 'image_role_subscription_badge'
2504
+ | 'image_role_subscription_lanyard'
2505
+ | 'image_role_subscription_purchase_card_bg'
2506
+ | 'img-auth-qrcode-overlay'
2507
+ | 'img_account_sync_battlenet_light_and_dark'
2508
+ | 'img_account_sync_battlenet_white'
2509
+ | 'img_account_sync_bluesky_light_and_dark'
2510
+ | 'img_account_sync_bluesky_white'
2511
+ | 'img_account_sync_crunchyroll_light_and_dark'
2512
+ | 'img_account_sync_ebay_light_and_dark'
2513
+ | 'img_account_sync_ebay_white'
2514
+ | 'img_account_sync_epic_dark_and_white'
2515
+ | 'img_account_sync_epic_light'
2516
+ | 'img_account_sync_facebook_light_and_dark'
2517
+ | 'img_account_sync_facebook_white'
2518
+ | 'img_account_sync_github_light'
2519
+ | 'img_account_sync_github_white'
2520
+ | 'img_account_sync_instagram_light_and_dark'
2521
+ | 'img_account_sync_instagram_white'
2522
+ | 'img_account_sync_league_of_legends_light_and_dark'
2523
+ | 'img_account_sync_league_of_legends_white'
2524
+ | 'img_account_sync_mastodon_light_and_dark'
2525
+ | 'img_account_sync_mastodon_white'
2526
+ | 'img_account_sync_paypal_light_and_dark'
2527
+ | 'img_account_sync_paypal_white'
2528
+ | 'img_account_sync_playstation_light'
2529
+ | 'img_account_sync_playstation_white'
2530
+ | 'img_account_sync_reddit_light_and_dark'
2531
+ | 'img_account_sync_reddit_white'
2532
+ | 'img_account_sync_riot_light_and_dark'
2533
+ | 'img_account_sync_riot_white'
2534
+ | 'img_account_sync_samsung_light_and_dark'
2535
+ | 'img_account_sync_samsung_white'
2536
+ | 'img_account_sync_skype_light_and_dark'
2537
+ | 'img_account_sync_skype_white'
2538
+ | 'img_account_sync_spotify_light_and_dark'
2539
+ | 'img_account_sync_spotify_white'
2540
+ | 'img_account_sync_steam_light'
2541
+ | 'img_account_sync_steam_white'
2542
+ | 'img_account_sync_tiktok_dark'
2543
+ | 'img_account_sync_tiktok_light'
2544
+ | 'img_account_sync_twitch_light_and_dark'
2545
+ | 'img_account_sync_twitch_white'
2546
+ | 'img_account_sync_twitter_light_and_dark'
2547
+ | 'img_account_sync_twitter_white'
2548
+ | 'img_account_sync_x_dark'
2549
+ | 'img_account_sync_x_light'
2550
+ | 'img_account_sync_x_white'
2551
+ | 'img_account_sync_xbox_custom'
2552
+ | 'img_account_sync_xbox_light'
2553
+ | 'img_account_sync_xbox_white'
2554
+ | 'img_account_sync_youtube_light_and_dark'
2555
+ | 'img_account_sync_youtube_white'
2556
+ | 'img_amazon_music'
2557
+ | 'img_app_crash_dark'
2558
+ | 'img_app_crash_darker'
2559
+ | 'img_app_crash_light'
2560
+ | 'img_artists_creators'
2561
+ | 'img_ban'
2562
+ | 'img_bans_empty_dark'
2563
+ | 'img_bans_empty_darker'
2564
+ | 'img_bans_empty_light'
2565
+ | 'img_boost'
2566
+ | 'img_boost_activated_border'
2567
+ | 'img_boost_error_mobile'
2568
+ | 'img_boost_hands'
2569
+ | 'img_boost_mobile'
2570
+ | 'img_boost_resubscribe_mobile'
2571
+ | 'img_boost_subheader_error_mobile'
2572
+ | 'img_boost_subheader_mobile'
2573
+ | 'img_boost_subheader_resub_mobile'
2574
+ | 'img_bundle_banner'
2575
+ | 'img_bundle_mobile'
2576
+ | 'img_bundle_subheader_mobile'
2577
+ | 'img_bungie_dark'
2578
+ | 'img_bungie_light'
2579
+ | 'img_bungie_white'
2580
+ | 'img_classic_error_mobile'
2581
+ | 'img_classic_mobile'
2582
+ | 'img_classic_resubscribe_mobile'
2583
+ | 'img_classic_subheader_mobile'
2584
+ | 'img_clouds_header_tier_0'
2585
+ | 'img_clouds_header_tier_2'
2586
+ | 'img_clubs'
2587
+ | 'img_collectibles_shop'
2588
+ | 'img_create_my_own'
2589
+ | 'img_custom_app_icons'
2590
+ | 'img_discord_nitro_logo_centered_dark'
2591
+ | 'img_discord_nitro_logo_centered_light'
2592
+ | 'img_discord_nitro_logo_left'
2593
+ | 'img_discord_nitro_logo_left_light'
2594
+ | 'img_domain_dark'
2595
+ | 'img_domain_light'
2596
+ | 'img_forum_empty_state_dark'
2597
+ | 'img_forum_empty_state_light'
2598
+ | 'img_friends'
2599
+ | 'img_gaming'
2600
+ | 'img_gifting_empty'
2601
+ | 'img_group_dm_illustration'
2602
+ | 'img_guild_cap_upsell_dark'
2603
+ | 'img_guild_cap_upsell_light'
2604
+ | 'img_guild_folder'
2605
+ | 'img_invalid_link_dark'
2606
+ | 'img_invalid_link_darker'
2607
+ | 'img_invalid_link_light'
2608
+ | 'img_invite_empty_dark'
2609
+ | 'img_invite_empty_darker'
2610
+ | 'img_invite_empty_light'
2611
+ | 'img_keychain'
2612
+ | 'img_kick_member'
2613
+ | 'img_local_community'
2614
+ | 'img_logo_basic_small_dark'
2615
+ | 'img_logo_basic_small_light'
2616
+ | 'img_logo_boost'
2617
+ | 'img_logo_bundle_horizontal'
2618
+ | 'img_logo_bundle_horizontal_black'
2619
+ | 'img_logo_discord'
2620
+ | 'img_logo_nitro_basic_stacked'
2621
+ | 'img_logo_nitro_classic'
2622
+ | 'img_logo_nitro_classic_horizontal'
2623
+ | 'img_logo_nitro_classic_horizontal_light'
2624
+ | 'img_logo_nitro_classic_stacked'
2625
+ | 'img_logo_nitro_dark'
2626
+ | 'img_logo_nitro_small_dark'
2627
+ | 'img_logo_nitro_small_light'
2628
+ | 'img_logo_nitro_tier_0'
2629
+ | 'img_logo_nitro_tier_0_horizontal_dark'
2630
+ | 'img_logo_nitro_tier_0_light'
2631
+ | 'img_logo_nitro_tier_2_horizontal_dark'
2632
+ | 'img_logo_plus_boost'
2633
+ | 'img_logo_premium_tier_0_full'
2634
+ | 'img_logo_premium_tier_1_full'
2635
+ | 'img_marketing_frog'
2636
+ | 'img_marketing_profiles'
2637
+ | 'img_marketing_uploads_light_border'
2638
+ | 'img_meta_quest_dark'
2639
+ | 'img_meta_quest_light'
2640
+ | 'img_meta_quest_white'
2641
+ | 'img_nitro_animated_avatar'
2642
+ | 'img_nitro_animated_emoji'
2643
+ | 'img_nitro_badge'
2644
+ | 'img_nitro_classic_icon_80px'
2645
+ | 'img_nitro_classic_icon_white_80px'
2646
+ | 'img_nitro_file_upload'
2647
+ | 'img_nitro_global_emoji'
2648
+ | 'img_nitro_icon_80px'
2649
+ | 'img_nitro_icon_filled'
2650
+ | 'img_nitro_longer_message_upsell_dark'
2651
+ | 'img_nitro_longer_message_upsell_light'
2652
+ | 'img_nitro_misc_perks_20px'
2653
+ | 'img_nitro_premium_guilds_20px'
2654
+ | 'img_nitro_sticker_yellow_24px'
2655
+ | 'img_nitro_subheader_mobile'
2656
+ | 'img_nitro_ticket_bg'
2657
+ | 'img_nitro_tier_0_activated_dark'
2658
+ | 'img_nitro_tier_0_activated_light'
2659
+ | 'img_nitro_tier_0_icon_80px'
2660
+ | 'img_nitro_tier_1_activated_dark'
2661
+ | 'img_nitro_tier_1_activated_light'
2662
+ | 'img_nitro_tier_2_activated_dark'
2663
+ | 'img_nitro_tier_2_activated_light'
2664
+ | 'img_no_results'
2665
+ | 'img_no_results_alt_darker'
2666
+ | 'img_no_results_dark'
2667
+ | 'img_no_results_dark_theme'
2668
+ | 'img_no_results_darker'
2669
+ | 'img_no_results_light'
2670
+ | 'img_none'
2671
+ | 'img_outbound_promotion_error'
2672
+ | 'img_outbound_promotion_redemption'
2673
+ | 'img_plan_activated'
2674
+ | 'img_plan_activated_light'
2675
+ | 'img_poop_dark'
2676
+ | 'img_poop_light'
2677
+ | 'img_premium_basic_icon'
2678
+ | 'img_premium_canvas_mobile'
2679
+ | 'img_premium_classic_icon_80px'
2680
+ | 'img_premium_embed_background_dark'
2681
+ | 'img_premium_embed_background_light'
2682
+ | 'img_premium_error_mobile'
2683
+ | 'img_premium_icon_80px'
2684
+ | 'img_premium_resubscribe_mobile'
2685
+ | 'img_preview_not_available_dark'
2686
+ | 'img_preview_not_available_light'
2687
+ | 'img_profile_upsell'
2688
+ | 'img_register_header'
2689
+ | 'img_roblox_dark'
2690
+ | 'img_roblox_light'
2691
+ | 'img_roblox_white'
2692
+ | 'img_search_empty_dark'
2693
+ | 'img_search_empty_darker'
2694
+ | 'img_search_empty_light'
2695
+ | 'img_security'
2696
+ | 'img_stream_ended_dark'
2697
+ | 'img_stream_ended_darker'
2698
+ | 'img_stream_full'
2699
+ | 'img_study'
2700
+ | 'img_subheader_error_mobile'
2701
+ | 'img_subheader_error_mobile_v2'
2702
+ | 'img_subheader_error_mobile_v2_light'
2703
+ | 'img_subheader_resub_mobile'
2704
+ | 'img_subscription_activated_dark'
2705
+ | 'img_subscription_activated_light'
2706
+ | 'img_tier_0_clouds'
2707
+ | 'img_tier_0_clouds_bigger'
2708
+ | 'img_tier_0_error_mobile'
2709
+ | 'img_tier_0_marketing_boosting'
2710
+ | 'img_tier_0_marketing_emojis'
2711
+ | 'img_tier_0_mobile'
2712
+ | 'img_tier_0_resubscribe_mobile'
2713
+ | 'img_tier_0_subheader_mobile'
2714
+ | 'img_tier_2_clouds'
2715
+ | 'img_tier_2_clouds_bigger'
2716
+ | 'img_top_pattern_dark'
2717
+ | 'img_top_pattern_darker'
2718
+ | 'img_top_pattern_light'
2719
+ | 'img_transfer_arrow'
2720
+ | 'img_vanity_urls'
2721
+ | 'img_verify_email_sent'
2722
+ | 'img_verify_phone_dark_theme'
2723
+ | 'img_verify_phone_darker'
2724
+ | 'img_verify_phone_light_theme'
2725
+ | 'img_what_you_lose_boost'
2726
+ | 'img_what_you_lose_emojis'
2727
+ | 'img_what_you_lose_hd_video'
2728
+ | 'img_what_you_lose_profile'
2729
+ | 'img_what_you_lose_profile_tier1_dark'
2730
+ | 'img_what_you_lose_profile_tier1_darker'
2731
+ | 'img_what_you_lose_profile_tier1_light'
2732
+ | 'img_what_you_lose_uploads'
2733
+ | 'img_wump_trash_dark'
2734
+ | 'img_wump_trash_darker'
2735
+ | 'img_wumpus_lightro'
2736
+ | 'img_wumpus_nitro'
2737
+ | 'img_wumpus_nitro_boost'
2738
+ | 'img_wumpus_nitro_classic'
2739
+ | 'img_wumpus_nitro_classic_boost'
2740
+ | 'img_wumpus_nitro_rev'
2741
+ | 'img_wumpus_nitro_tier_0'
2742
+ | 'intro_header_dark'
2743
+ | 'intro_header_darker'
2744
+ | 'intro_header_light'
2745
+ | 'invite'
2746
+ | 'invite-bg'
2747
+ | 'it'
2748
+ | 'ja'
2749
+ | 'ko'
2750
+ | 'krisp_logo_dark'
2751
+ | 'krisp_logo_light'
2752
+ | 'large_uploads'
2753
+ | 'light_home_header_placeholder'
2754
+ | 'line'
2755
+ | 'link_expired'
2756
+ | 'link_expired_light'
2757
+ | 'link_failure'
2758
+ | 'load-issue-dark'
2759
+ | 'load-issue-light'
2760
+ | 'lock'
2761
+ | 'locke_2'
2762
+ | 'logo'
2763
+ | 'lt'
2764
+ | 'mac_2'
2765
+ | 'mail'
2766
+ | 'mallow_1'
2767
+ | 'maximize'
2768
+ | 'member_list_badge_16px'
2769
+ | 'member_list_icon'
2770
+ | 'member_pricing'
2771
+ | 'messages'
2772
+ | 'messenger'
2773
+ | 'mfa-server'
2774
+ | 'mobile-empty-state'
2775
+ | 'money_birb_placeholder_dark'
2776
+ | 'money_birb_placeholder_light'
2777
+ | 'nameplate_avatar_placeholder_dark_mode'
2778
+ | 'nameplate_avatar_placeholder_light_mode'
2779
+ | 'nav_header_disconnect'
2780
+ | 'nelly_1'
2781
+ | 'nitro_home_banner'
2782
+ | 'nitro_modal_header_background'
2783
+ | 'nitro_wumpus_avatar'
2784
+ | 'nl'
2785
+ | 'no'
2786
+ | 'no-app-icon'
2787
+ | 'no_mutual_friends_dark'
2788
+ | 'no_mutual_friends_darker'
2789
+ | 'no_mutual_friends_light'
2790
+ | 'no_mutual_servers_dark'
2791
+ | 'no_mutual_servers_darker'
2792
+ | 'no_mutual_servers_light'
2793
+ | 'notification_upsell'
2794
+ | 'nsfw_gate'
2795
+ | 'nsfw_gate_unavailable'
2796
+ | 'nux'
2797
+ | 'onboarding_v2_upsell'
2798
+ | 'partner_icon'
2799
+ | 'partying_face'
2800
+ | 'pending-alert'
2801
+ | 'pending_dark'
2802
+ | 'pending_darker'
2803
+ | 'pending_light'
2804
+ | 'personalize_32px'
2805
+ | 'phibi_1'
2806
+ | 'pl'
2807
+ | 'poop_dark_large'
2808
+ | 'poop_light_large'
2809
+ | 'premium_gift_plan_selection_header'
2810
+ | 'premium_role_unavailable'
2811
+ | 'progress-setup'
2812
+ | 'ps_relink_upsell'
2813
+ | 'pt-BR'
2814
+ | 'quests_embed_mobile_missing'
2815
+ | 'redesign_email_header'
2816
+ | 'register-background-dark'
2817
+ | 'register-background-light'
2818
+ | 'rejected-alert'
2819
+ | 'report'
2820
+ | 'resubscribed_alert_header'
2821
+ | 'ro'
2822
+ | 'role'
2823
+ | 'role_2'
2824
+ | 'role_subscription_benefit_avatar_1'
2825
+ | 'role_subscription_benefit_bunny_avatar'
2826
+ | 'role_subscription_benefit_nelly_avatar'
2827
+ | 'role_subscription_benefit_wise_avatar'
2828
+ | 'role_subscription_earning_illo'
2829
+ | 'role_subscription_earning_metric_avatar'
2830
+ | 'role_subscription_lanyard_illo'
2831
+ | 'role_subscription_settings_hero'
2832
+ | 'role_subscription_social'
2833
+ | 'ru'
2834
+ | 'safety_check'
2835
+ | 'safety_check_light'
2836
+ | 'safety_shield'
2837
+ | 'sample_banner'
2838
+ | 'screenshare'
2839
+ | 'screenshare_end'
2840
+ | 'screenshare_splash'
2841
+ | 'scrubber'
2842
+ | 'search-icon'
2843
+ | 'search_empty_state'
2844
+ | 'search_empty_state_dark'
2845
+ | 'search_empty_state_light'
2846
+ | 'send_message_32px'
2847
+ | 'server-error'
2848
+ | 'server-invite-envelope'
2849
+ | 'server_boost_logo_dark'
2850
+ | 'server_boost_logo_light'
2851
+ | 'server_boosts'
2852
+ | 'settings'
2853
+ | 'share'
2854
+ | 'sparkle_star_elongated'
2855
+ | 'sparkle_star_pointed'
2856
+ | 'speaker'
2857
+ | 'spectator'
2858
+ | 'stack-nav-back'
2859
+ | 'stack-nav-close'
2860
+ | 'stage-channel-upsell'
2861
+ | 'stage-sparkles'
2862
+ | 'stamp-wave'
2863
+ | 'star'
2864
+ | 'sticker'
2865
+ | 'sticker_search_empty'
2866
+ | 'stream'
2867
+ | 'study'
2868
+ | 'subscribe_confirm'
2869
+ | 'subscription_placeholder_pattern_dark'
2870
+ | 'subscription_placeholder_pattern_darker'
2871
+ | 'subscription_placeholder_pattern_light'
2872
+ | 'success-header'
2873
+ | 'summary_indicator_end'
2874
+ | 'summary_indicator_start'
2875
+ | 'sunbeam_gradient_mobile'
2876
+ | 'super_reaction'
2877
+ | 'support'
2878
+ | 'sv-SE'
2879
+ | 'system-user-avatar'
2880
+ | 'telegram'
2881
+ | 'th'
2882
+ | 'tier_0_24px'
2883
+ | 'tier_0_48px_dark'
2884
+ | 'tier_0_48px_darker'
2885
+ | 'tier_0_48px_light'
2886
+ | 'tier_1_24px'
2887
+ | 'tier_1_32px'
2888
+ | 'tier_2_24px'
2889
+ | 'tier_2_32px'
2890
+ | 'tier_3_24px'
2891
+ | 'tier_3_32px'
2892
+ | 'tiny-bronco-spot'
2893
+ | 'top_perk_streaming_quality'
2894
+ | 'top_perk_vanity_url'
2895
+ | 'tr'
2896
+ | 'twitter'
2897
+ | 'uk'
2898
+ | 'updateAppIcon'
2899
+ | 'upload'
2900
+ | 'verify-email'
2901
+ | 'vi'
2902
+ | 'vibing_wumpus_rings'
2903
+ | 'video'
2904
+ | 'video_dark'
2905
+ | 'video_light'
2906
+ | 'voice_bar_bluetooth'
2907
+ | 'voice_bar_deafen_off'
2908
+ | 'voice_bar_deafen_on'
2909
+ | 'voice_bar_mute_off'
2910
+ | 'voice_bar_mute_on'
2911
+ | 'voice_bar_phone'
2912
+ | 'voice_bar_speaker_new'
2913
+ | 'voice_channels'
2914
+ | 'vr'
2915
+ | 'watch'
2916
+ | 'webhook_empty_dark'
2917
+ | 'webhook_empty_darker'
2918
+ | 'webhook_empty_light'
2919
+ | 'welcome-bg'
2920
+ | 'whatsapp'
2921
+ | 'wreath_dark'
2922
+ | 'wreath_light'
2923
+ | 'wumpus-ash'
2924
+ | 'wumpus-link'
2925
+ | 'wumpus-luigi'
2926
+ | 'wumpus-mario'
2927
+ | 'wumpus-pikachu'
2928
+ | 'wumpus-wizard'
2929
+ | 'wumpus-wump'
2930
+ | 'wumpus_1'
2931
+ | 'wumpus_box_premium120'
2932
+ | 'wumpus_cup_premium120'
2933
+ | 'wumpus_snowglobe_premium120'
2934
+ | 'wumpus_wave'
2935
+ | 'xbox'
2936
+ | 'xbox_app_phone'
2937
+ | 'xbox_upsell'
2938
+ | 'yearly_upsell_wumpus'
2939
+ | 'yellow-alert'
2940
+ | 'youtube_icon'
2941
+ | 'zh-CN'
2942
+ | 'zh-TW';
2943
+ svg:
2944
+ | 'img_account_sync_battlenet_light_and_dark'
2945
+ | 'img_account_sync_battlenet_white'
2946
+ | 'img_account_sync_bluesky_light_and_dark'
2947
+ | 'img_account_sync_bluesky_white'
2948
+ | 'img_account_sync_crunchyroll_light_and_dark'
2949
+ | 'img_account_sync_crunchyroll_white'
2950
+ | 'img_account_sync_ebay_light_and_dark'
2951
+ | 'img_account_sync_ebay_white'
2952
+ | 'img_account_sync_epic_dark_and_white'
2953
+ | 'img_account_sync_epic_light'
2954
+ | 'img_account_sync_facebook_light_and_dark'
2955
+ | 'img_account_sync_facebook_white'
2956
+ | 'img_account_sync_github_light'
2957
+ | 'img_account_sync_github_white'
2958
+ | 'img_account_sync_instagram_light_and_dark'
2959
+ | 'img_account_sync_instagram_white'
2960
+ | 'img_account_sync_league_of_legends_light_and_dark'
2961
+ | 'img_account_sync_league_of_legends_white'
2962
+ | 'img_account_sync_mastodon_light_and_dark'
2963
+ | 'img_account_sync_mastodon_white'
2964
+ | 'img_account_sync_paypal_light_and_dark'
2965
+ | 'img_account_sync_paypal_white'
2966
+ | 'img_account_sync_playstation_light'
2967
+ | 'img_account_sync_playstation_white'
2968
+ | 'img_account_sync_reddit_light_and_dark'
2969
+ | 'img_account_sync_reddit_white'
2970
+ | 'img_account_sync_riot_black'
2971
+ | 'img_account_sync_riot_light_and_dark'
2972
+ | 'img_account_sync_riot_white'
2973
+ | 'img_account_sync_samsung_light_and_dark'
2974
+ | 'img_account_sync_samsung_white'
2975
+ | 'img_account_sync_skype_light_and_dark'
2976
+ | 'img_account_sync_skype_white'
2977
+ | 'img_account_sync_spotify_light_and_dark'
2978
+ | 'img_account_sync_spotify_white'
2979
+ | 'img_account_sync_steam_light'
2980
+ | 'img_account_sync_steam_white'
2981
+ | 'img_account_sync_tiktok_dark'
2982
+ | 'img_account_sync_tiktok_light'
2983
+ | 'img_account_sync_twitch_light_and_dark'
2984
+ | 'img_account_sync_twitch_white'
2985
+ | 'img_account_sync_twitter_light_and_dark'
2986
+ | 'img_account_sync_twitter_white'
2987
+ | 'img_account_sync_x_dark'
2988
+ | 'img_account_sync_x_light'
2989
+ | 'img_account_sync_x_white'
2990
+ | 'img_account_sync_xbox_light'
2991
+ | 'img_account_sync_xbox_white'
2992
+ | 'img_account_sync_youtube_light_and_dark'
2993
+ | 'img_account_sync_youtube_white'
2994
+ | 'img_amazon_music'
2995
+ | 'img_bungie_dark'
2996
+ | 'img_bungie_light'
2997
+ | 'img_bungie_white'
2998
+ | 'img_domain_dark'
2999
+ | 'img_domain_light'
3000
+ | 'img_meta_quest'
3001
+ | 'img_meta_quest_light'
3002
+ | 'img_roblox_dark'
3003
+ | 'img_roblox_light'
3004
+ | 'img_roblox_white';
3005
+ webm: 'halloween_loading_dark' | 'halloween_loading_light';
3006
+ };
3007
+ /** A file type Discord registers assets of. */
3008
+ export type DiscordAssetType = keyof DiscordAssetNames;
1330
3009
  /** A function exported by a Discord module, whose signature Discord does not document. */
1331
3010
  export type DiscordFunction<T = any> = (...args: any[]) => T;
3011
+ /** The props Discord passes its `*Icon` components, such as `WrenchIcon`, and an imported SVG takes. */
3012
+ export type DiscordIconProps = {
3013
+ /** A size on Discord's scale, or points. Defaults to `'md'` (24). */
3014
+ size?: DiscordIconSize | number;
3015
+ /** A theme token or a colour. Defaults to the theme's interactive icon colour. */
3016
+ color?: SemanticColorToken | string;
3017
+ };
3018
+ /** The sizes of Discord's icons, from 12 points (`xxs`) to 32 (`lg`); `custom` leaves the size to `style`. */
3019
+ export type DiscordIconSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg' | 'custom' | 'refresh_sm';
3020
+ /** A duration's units, smallest first. */
3021
+ export type DurationUnit = 'ms' | 's' | 'm' | 'h' | 'd';
1332
3022
  /**
1333
3023
  * Props of `EllipsisCircle` (function). Exports: none.
1334
3024
  * @see design/components/Button/native/ButtonEllipsis.native.tsx
@@ -1338,6 +3028,8 @@ export type EllipsisCircleProps = {
1338
3028
  size?: unknown;
1339
3029
  variant?: unknown;
1340
3030
  };
3031
+ /** The displays of a `string` setting that pick a Discord entity by its id. */
3032
+ export type EntityDisplay = 'user' | 'channel' | 'guild' | 'role';
1341
3033
  /** Discord ships numeric enums as bidirectional maps; this models both directions. */
1342
3034
  export type EnumLike<K extends readonly string[]> = {
1343
3035
  [P in K[number]]: number;
@@ -1393,14 +3085,8 @@ export type FloatingActionButtonProps = Omit<
1393
3085
  /** @default 16 */
1394
3086
  positionRight?: number;
1395
3087
  };
1396
- /** A custom font the native loader has registered, as injected on `window.UNBOUND_FONTS`. */
1397
- export type FontDescriptor = {
1398
- name: string;
1399
- file: string;
1400
- path: string;
1401
- };
1402
- /** A font managed by the Fonts manager: currently identical to its {@link FontDescriptor}. */
1403
- export type FontEntity = FontDescriptor;
3088
+ /** A font face managed by the Fonts manager, as `UnboundNative.fonts.list()` returns it. */
3089
+ export type FontEntity = UnboundInstalledFont;
1404
3090
  /**
1405
3091
  * Props of `FormLabel` (function). Exports: default.
1406
3092
  * @see design/void/Form/native/FormLabel.tsx
@@ -1592,9 +3278,13 @@ export type HeaderSubmittingIndicatorComponent =
1592
3278
  * @see design/components/Navigator/native/NavigatorHeader.native.tsx
1593
3279
  */
1594
3280
  export type HeaderSubmittingIndicatorProps = {};
3281
+ /** An icon a row or toast draws: an asset id, an element such as `<Star />`, or an icon component such as `Star`. */
3282
+ export type IconInput = number | React$1.ReactElement | React$1.ComponentType<DiscordIconProps>;
1595
3283
  /** A loaded icon pack: its bundle marker and {@link IconPackManifest}. */
1596
3284
  export type IconPack = {
3285
+ /** The name the pack was loaded under: its manifest `name`, or `Default` for Discord's own icons. */
1597
3286
  bundle: string;
3287
+ /** The pack's manifest. */
1598
3288
  manifest: IconPackManifest;
1599
3289
  };
1600
3290
  /** An icon pack's manifest: an {@link AddonManifest} tagged with its source kind. */
@@ -1711,6 +3401,8 @@ export type LayerScopeProps = {
1711
3401
  children?: React$1.ReactNode;
1712
3402
  zIndex?: number;
1713
3403
  };
3404
+ /** The `objc` namespace the loader publishes, before the client adds `create` and scopes it to a plugin. */
3405
+ export type LoaderObjCBridge = Omit<NativeObjCBridge, 'create'> & NativeUIScopeFactory;
1714
3406
  /**
1715
3407
  * Props of `LoadingButtonPill` (function). Exports: LoadingButtonPill.
1716
3408
  * @see design/components/Button/native/ButtonPill.native.tsx
@@ -1729,6 +3421,31 @@ export type LoadingButtonPillProps = {
1729
3421
  /** @default 'primary' */
1730
3422
  variant?: PillWrapperProps['variant'];
1731
3423
  };
3424
+ /** A generated component that also accepts {@link LooseProps}, keeping its statics such as `TableRow.Icon`. */
3425
+ export type LooseComponent<C> =
3426
+ C extends React$1.ComponentType<infer P> ? C & React$1.FunctionComponent<LooseProps<P>> : C;
3427
+ /** Each export of a generated module with {@link LooseComponent} applied. */
3428
+ export type LooseModule<M> = {
3429
+ [K in keyof M]: LooseComponent<M[K]>;
3430
+ };
3431
+ /**
3432
+ * The value type a loose prop accepts: a primitive, literal union or callback stays checked; anything else the
3433
+ * generator inferred (`any`, objects, React nodes, wide unions) is {@link UncertainValue}.
3434
+ */
3435
+ export type LoosePropValue<T> = 0 extends 1 & T
3436
+ ? UncertainValue
3437
+ : [NonNullable<T>] extends [Primitive]
3438
+ ? T
3439
+ : [NonNullable<T>] extends [Callback]
3440
+ ? T
3441
+ : UncertainValue;
3442
+ /**
3443
+ * Generated component props made safe to pass: every known prop is optional and checked only where its type is
3444
+ * concrete, and any other prop is allowed, since the generator can miss props or mark a defaulted one required.
3445
+ */
3446
+ export type LooseProps<P> = {
3447
+ [K in keyof P]?: LoosePropValue<P[K]>;
3448
+ } & Record<string, unknown>;
1732
3449
  /**
1733
3450
  * Props of `LottieIcon` (function). Exports: LottieIcon.
1734
3451
  * @see design/components/LottieIcon/native/LottieIcon.tsx
@@ -1762,6 +3479,63 @@ export type ManaContextProviderProps = {
1762
3479
  children?: React$1.ReactNode;
1763
3480
  value?: unknown;
1764
3481
  };
3482
+ /** Parses nested Markdown, as a rule's `parse` receives it. */
3483
+ export type MarkdownNestedParse = (source: string, state: MarkdownState) => MarkdownNode[];
3484
+ /** One node of a parsed Markdown tree; `type` names the rule that parsed it. */
3485
+ export type MarkdownNode = {
3486
+ /** The name of the rule that parsed the node, such as `text` or `strong`. */
3487
+ type: string;
3488
+ /** The node's children, or its text for a leaf rule; absent when a rule stores its data elsewhere. */
3489
+ content?: MarkdownNode[] | string;
3490
+ };
3491
+ /** Renders a node or a list of nodes, as a rule's `react` receives it. */
3492
+ export type MarkdownOutput = (
3493
+ node: MarkdownNode | MarkdownNode[],
3494
+ state: MarkdownState,
3495
+ ) => React$1.ReactNode;
3496
+ /** Discord's Markdown module (`MarkupUtils`), found by `parse`, `parseToAST` and `reactParserFor`. */
3497
+ export type MarkdownParserModule = {
3498
+ /** The rules Discord renders messages with. */
3499
+ defaultRules: MarkdownRules;
3500
+ /** Builds a renderer from a rule set, such as `defaultRules` plus your own rules. */
3501
+ reactParserFor(rules: MarkdownRules): MarkdownReactParser;
3502
+ /** Renders Markdown with `defaultRules`, as Discord renders message content. */
3503
+ parse: MarkdownReactParser;
3504
+ /** Parses Markdown with `defaultRules` into nodes without rendering them; `inline` defaults to `true`. */
3505
+ parseToAST(source?: string, inline?: boolean, state?: MarkdownState): MarkdownNode[];
3506
+ };
3507
+ /** Renders Markdown source to React Native elements; `inline` defaults to `true`. */
3508
+ export type MarkdownReactParser = (
3509
+ source?: string,
3510
+ inline?: boolean,
3511
+ state?: MarkdownState,
3512
+ ) => React$1.ReactNode;
3513
+ /** A simple-markdown rule: `match` finds it at the start of the source, `parse` builds its node, `react` renders it. */
3514
+ export type MarkdownRule<TNode extends MarkdownNode = MarkdownNode> = {
3515
+ /** Discord 349 ships `highlight`, `guild` and `channel` without one; the parser never calls those. */
3516
+ order?: number;
3517
+ /** Matches the rule at the start of `source`; `previous` is the text already consumed. `null` means no match. */
3518
+ match(source: string, state: MarkdownState, previous: string): RegExpExecArray | null;
3519
+ /** Builds the node from `match`'s capture; call `parse` to parse nested Markdown. */
3520
+ parse(capture: RegExpExecArray, parse: MarkdownNestedParse, state: MarkdownState): TNode;
3521
+ /** Renders the node; call `output` to render its children. */
3522
+ react?(node: TNode, output: MarkdownOutput, state: MarkdownState): React$1.ReactNode;
3523
+ };
3524
+ /** A rule set by rule name, the shape `reactParserFor` takes. */
3525
+ export type MarkdownRules = Record<string, MarkdownRule>;
3526
+ /** The parse state Discord's rules read; the `allow*` flags turn links, headings and lists on. */
3527
+ export type MarkdownState = {
3528
+ /** The React key the output function sets before calling a rule's `react`. */
3529
+ key?: string | number;
3530
+ /** Whether the parser is inside inline content; inline-only rules such as `strong` match only then. */
3531
+ inline?: boolean;
3532
+ /** Renders links as links instead of plain text. */
3533
+ allowLinks?: boolean;
3534
+ /** Parses `#` headings. */
3535
+ allowHeading?: boolean;
3536
+ /** Parses `-` and `1.` lists. */
3537
+ allowList?: boolean;
3538
+ };
1765
3539
  export type MenuComponent = React$1.ComponentType<MenuProps>;
1766
3540
  export type MenuGroupComponent = React$1.ComponentType<MenuGroupProps>;
1767
3541
  /**
@@ -1941,25 +3715,85 @@ export type ModalStepIndicatorProps = {
1941
3715
  };
1942
3716
  /** The outcome of checking an addon's signature against the keys compiled into the loader. */
1943
3717
  export type NativeAddonVerification = {
3718
+ /** `signed` when a trusted key signed the bundle, `unsigned` when there is no signature, `invalid` when it fails. */
1944
3719
  readonly status: 'signed' | 'unsigned' | 'invalid';
3720
+ /** Who signed the addon; set only when `status` is `signed`. */
1945
3721
  readonly signer?: string;
3722
+ /** Why verification did not succeed, when the loader can say. */
1946
3723
  readonly problem?: string;
1947
3724
  };
3725
+ /** Where a running install is: `confirming` waits on the system prompt; `failed` carries `error`. */
3726
+ export type NativeAndroidInstallPhase =
3727
+ | 'idle'
3728
+ | 'downloading'
3729
+ | 'installing'
3730
+ | 'confirming'
3731
+ | 'failed';
3732
+ /** How far the running install is. */
3733
+ export type NativeAndroidInstallProgress = {
3734
+ /** What the installer is doing now. */
3735
+ readonly phase: NativeAndroidInstallPhase;
3736
+ /** Gzipped bytes downloaded so far, of `total`. */
3737
+ readonly downloaded: number;
3738
+ /** Gzipped bytes the install downloads in all. */
3739
+ readonly total: number;
3740
+ /** Why the last install failed, or `null`. */
3741
+ readonly error: string | null;
3742
+ };
3743
+ /** One gzipped split APK of a build to install. */
3744
+ export type NativeAndroidInstallSplit = {
3745
+ /** The split's name: `base` or a config split such as `config.arm64_v8a`. */
3746
+ readonly name: string;
3747
+ /** Where the gzipped APK downloads from. */
3748
+ readonly url: string;
3749
+ /** SHA-256 of the APK after it is gunzipped. */
3750
+ readonly sha256: string;
3751
+ /** Size of the APK in bytes. */
3752
+ readonly size: number;
3753
+ /** Size of the gzipped download in bytes. */
3754
+ readonly compressedSize: number;
3755
+ };
3756
+ /** Whether Discord can install another patched build of itself: not patched with LSPatch, patched before in-app installs, waiting on the "Install unknown apps" permission, or ready. */
3757
+ export type NativeAndroidInstallerAvailability =
3758
+ | 'unpatched'
3759
+ | 'unsupported'
3760
+ | 'needs-permission'
3761
+ | 'ready';
3762
+ /** The Discord install the installer would replace. */
3763
+ export type NativeAndroidInstallerStatus = {
3764
+ /** Whether in-app installs work, or what blocks them. */
3765
+ readonly availability: NativeAndroidInstallerAvailability;
3766
+ /** Discord's version name, such as `352.17 - Stable`. */
3767
+ readonly versionName: string;
3768
+ /** The installed split names, `base` first. */
3769
+ readonly splits: string[];
3770
+ };
3771
+ /** A key from `objc.createAssociationKey` that names one associated object. */
1948
3772
  export type NativeAssociationKey = NativeHandle;
3773
+ /** Refers to an earlier step's result inside `objc.batch`, as a target or an argument. */
1949
3774
  export type NativeBatchReference = {
3775
+ /** The zero-based index of the earlier step whose result to use. */
1950
3776
  readonly $nativeBatchResult: number;
1951
3777
  };
3778
+ /** One Objective-C call in `objc.batch`; a batch takes up to 64 steps. */
1952
3779
  export type NativeBatchStep = {
3780
+ /** The object to call, or an earlier step's result. */
1953
3781
  target: NativeObjectHandle | NativeBatchReference;
3782
+ /** The selector to send, at most 256 characters. */
1954
3783
  selector: string;
3784
+ /** The call's arguments, at most 16; each may be an earlier step's result. */
1955
3785
  args: unknown[];
1956
3786
  };
3787
+ /** Options for a synchronous Objective-C call. */
1957
3788
  export type NativeCallOptions = {
3789
+ /** The thread to run on. Defaults to `current`. */
1958
3790
  thread?: NativeThreadPolicy;
1959
3791
  };
3792
+ /** A promise for native work; `cancel` drops it, and stopping the plugin cancels every pending one. */
1960
3793
  export type NativeCancelablePromise<T> = Promise<T> & {
1961
3794
  cancel(): void;
1962
3795
  };
3796
+ /** A handle to an Objective-C class, from `objc.getClass`. */
1963
3797
  export type NativeClassHandle = NativeHandle;
1964
3798
  /** A plugin bundle the loader evaluated from bytecode: it takes the scoped React and returns the plugin module. */
1965
3799
  export type NativeCompiledPlugin = (react: typeof React$1) =>
@@ -1967,45 +3801,85 @@ export type NativeCompiledPlugin = (react: typeof React$1) =>
1967
3801
  | {
1968
3802
  default: Plugin$1;
1969
3803
  };
3804
+ /** What an addon was doing when the loader blamed it: `starting` or `running` for a crash, `frozen` for a freeze. */
1970
3805
  export type NativeCrashPhase = 'starting' | 'running' | 'frozen';
3806
+ /** An addon the loader disabled because Discord crashed or froze in it on consecutive launches. */
1971
3807
  export type NativeCrashedAddon = {
3808
+ /** The addon's crash guard key, `<bucket>:<addon id>`. */
1972
3809
  readonly id: string;
3810
+ /** The addon's display name. */
1973
3811
  readonly name: string;
1974
- readonly phase?: NativeCrashPhase;
3812
+ /** What the addon was doing. */
3813
+ readonly phase: NativeCrashPhase;
1975
3814
  };
3815
+ /** Debugger support for plugins. */
1976
3816
  export type NativeDebugBridge = {
3817
+ /** Logs an evaluation and adds it to the loader's history; false when the record is malformed. Needs `native.debug.evaluations`. */
1977
3818
  recordEvaluation(record: NativeDebugEvaluation): boolean;
1978
- environment(): NativeDebugEnvironment;
3819
+ /** Reads the debug environment, optionally collecting garbage or resetting counters first. Needs `native.debug.environment`. */
3820
+ environment(options?: NativeDebugEnvironmentOptions): NativeDebugEnvironment;
1979
3821
  };
3822
+ /** Facts about the device a debugger session needs. */
1980
3823
  export type NativeDebugEnvironment = {
3824
+ /** Whether Discord runs in a simulator, emulator or virtual machine. */
1981
3825
  isVirtualDevice: boolean;
3826
+ /** The address of the machine hosting the virtual device, or `null` on a physical one. */
1982
3827
  hostAddress: string | null;
1983
- resources?: NativeResourceCounts;
1984
- };
3828
+ /** The loader's resource counts. */
3829
+ resources: NativeResourceCounts;
3830
+ /** Present when the read collected garbage first. */
3831
+ garbageCollection?: NativeGarbageCollection;
3832
+ };
3833
+ /** What reading the debug environment may do first. */
3834
+ export type NativeDebugEnvironmentOptions = {
3835
+ /** Collects garbage on the calling runtime and the UI runtime before counting. */
3836
+ collectGarbage?: boolean;
3837
+ /** Zeroes the main-thread counters after reading them. */
3838
+ resetCounters?: boolean;
3839
+ };
3840
+ /** One debugger evaluation, which the loader logs and keeps in its evaluation history. */
1985
3841
  export type NativeDebugEvaluation = {
1986
3842
  id: string;
1987
3843
  code: string;
1988
- ok: boolean;
1989
- value?: string;
1990
- error?: string;
1991
- logs?: {
1992
- level: 1 | 2 | 3;
1993
- message: string;
1994
- }[];
3844
+ logs?: NativeDebugEvaluationLog[];
3845
+ } & (
3846
+ | {
3847
+ ok: true;
3848
+ value?: string;
3849
+ }
3850
+ | {
3851
+ ok: false;
3852
+ error?: string;
3853
+ }
3854
+ );
3855
+ /** One console line an evaluation printed. */
3856
+ export type NativeDebugEvaluationLog = {
3857
+ /** 1 for log, 2 for warn, 3 for error. */
3858
+ level: 1 | 2 | 3;
3859
+ /** The printed text. */
3860
+ message: string;
1995
3861
  };
3862
+ /** Calls C functions in images Discord already loaded. An unsigned plugin needs the user's consent to use it. */
1996
3863
  export type NativeFFIBridge = {
3864
+ /** Resolves a symbol in a loaded image, or in every loaded image when `image` is omitted; `null` when not found. */
1997
3865
  symbol(name: string, image?: string): NativePointer | null;
3866
+ /** Calls a symbol from `symbol` with an explicit signature. */
1998
3867
  call(pointer: NativePointer, signature: NativeFFISignature, ...args: unknown[]): unknown;
1999
3868
  };
3869
+ /** A non-variadic C function signature for `ffi.call`. */
2000
3870
  export type NativeFFISignature = {
3871
+ /** The result type; `i64` and `u64` results come back as `BigInt`. */
2001
3872
  returnType: NativeFFIType;
3873
+ /** The argument types, at most 16 and none `void`. */
2002
3874
  args: NativeFFIType[];
2003
3875
  };
3876
+ /** An FFI type: a scalar or pointer name, or a registered struct by name, such as `{ struct: 'CGRect' }`. */
2004
3877
  export type NativeFFIType =
2005
3878
  | NativeFFITypeName
2006
3879
  | {
2007
3880
  struct: string;
2008
3881
  };
3882
+ /** A C type in an FFI signature; `object`, `class` and `selector` exist only on iOS. */
2009
3883
  export type NativeFFITypeName =
2010
3884
  | 'void'
2011
3885
  | 'bool'
@@ -2024,188 +3898,371 @@ export type NativeFFITypeName =
2024
3898
  | 'object'
2025
3899
  | 'class'
2026
3900
  | 'selector';
3901
+ /** Mounts registered React Native components inside existing native views. Sync methods are iOS only. */
2027
3902
  export type NativeFabricBridge = {
3903
+ /** Starts a surface for a registered component inside a container view. Needs `native.fabric.mount`. */
2028
3904
  mount(
2029
3905
  container: NativeObjectHandle,
2030
3906
  moduleName: string,
2031
3907
  properties?: NativeSerializableObject,
3908
+ options?: NativeFabricMountOptions,
2032
3909
  ): NativeFabricSurface;
3910
+ /** Like `mount`, on the main thread. Needs `native.fabric.async`. */
2033
3911
  mountAsync(
2034
3912
  container: NativeObjectHandle,
2035
3913
  moduleName: string,
2036
3914
  properties?: NativeSerializableObject,
3915
+ options?: NativeFabricMountOptions,
2037
3916
  ): NativeCancelablePromise<NativeFabricSurface>;
3917
+ /** Sends new properties to a surface. */
2038
3918
  update(surface: NativeFabricSurface, properties: NativeSerializableObject): void;
3919
+ /** Like `update`, on the main thread. */
2039
3920
  updateAsync(
2040
3921
  surface: NativeFabricSurface,
2041
3922
  properties: NativeSerializableObject,
2042
3923
  ): NativeCancelablePromise<void>;
3924
+ /** Sets the smallest and largest size the surface may lay out at. */
2043
3925
  setSize(
2044
3926
  surface: NativeFabricSurface,
2045
3927
  minimumSize: NativeFabricSize,
2046
3928
  maximumSize: NativeFabricSize,
2047
3929
  ): void;
3930
+ /** Like `setSize`, on the main thread. */
2048
3931
  setSizeAsync(
2049
3932
  surface: NativeFabricSurface,
2050
3933
  minimumSize: NativeFabricSize,
2051
3934
  maximumSize: NativeFabricSize,
2052
3935
  ): NativeCancelablePromise<void>;
3936
+ /** Positions the surface's view in its container. */
2053
3937
  setFrame(surface: NativeFabricSurface, frame: NativeFabricFrame): void;
3938
+ /** Like `setFrame`, on the main thread. */
2054
3939
  setFrameAsync(
2055
3940
  surface: NativeFabricSurface,
2056
3941
  frame: NativeFabricFrame,
2057
3942
  ): NativeCancelablePromise<void>;
3943
+ /** Reads a view's frame. */
2058
3944
  measure(view: NativeObjectHandle): NativeFabricFrame;
3945
+ /** Like `measure`, on the main thread. */
2059
3946
  measureAsync(view: NativeObjectHandle): NativeCancelablePromise<NativeFabricFrame>;
3947
+ /** Stops a surface and removes its view. */
2060
3948
  unmount(surface: NativeFabricSurface): void;
3949
+ /** Like `unmount`, on the main thread. */
2061
3950
  unmountAsync(surface: NativeFabricSurface): NativeCancelablePromise<void>;
3951
+ /** Destroys the idle surfaces this plugin left for reuse. */
3952
+ releaseIdle?(): void;
3953
+ /** Like `releaseIdle`, on the main thread; the plugin scope calls it when the plugin stops. */
3954
+ releaseIdleAsync(): NativeCancelablePromise<void>;
2062
3955
  };
3956
+ /** A view's frame in its container, in points on iOS and dp on Android. */
2063
3957
  export type NativeFabricFrame = {
3958
+ /** The left edge, between -100,000 and 100,000. */
2064
3959
  x: number;
3960
+ /** The top edge, between -100,000 and 100,000. */
2065
3961
  y: number;
3962
+ /** Width, between 0 and 32,768. */
2066
3963
  width: number;
3964
+ /** Height, between 0 and 32,768. */
2067
3965
  height: number;
2068
3966
  };
3967
+ /** Options for mounting a Fabric surface. */
3968
+ export type NativeFabricMountOptions = {
3969
+ /** Reuses an idle surface of the same component this plugin unmounted, re-hosted in the new container with the new properties, instead of starting one. Only for components whose state follows their properties. */
3970
+ reuse?: boolean;
3971
+ };
3972
+ /** A Fabric surface size, in points on iOS and dp on Android, between 0 and 32,768. */
2069
3973
  export type NativeFabricSize = {
3974
+ /** Width, in points on iOS and dp on Android. */
2070
3975
  width: number;
3976
+ /** Height, in points on iOS and dp on Android. */
2071
3977
  height: number;
2072
3978
  };
3979
+ /** A mounted Fabric surface; the plugin scope unmounts it on dispose. */
2073
3980
  export type NativeFabricSurface = NativeHandle;
3981
+ /** One font the loader can apply. */
2074
3982
  export type NativeFontEntry = {
3983
+ /** The font's PostScript name, falling back to its full or file name; unique in the list. */
2075
3984
  readonly name: string;
3985
+ /** The font's full name, or `name` when the file has none. */
2076
3986
  readonly displayName: string;
3987
+ /** The family name, when the font file declares one. */
2077
3988
  readonly family?: string;
3989
+ /** The style name, such as `Bold`, when the font file declares one. */
2078
3990
  readonly style?: string;
3991
+ /** The font file's path; missing for system fonts the loader lists by name only. */
2079
3992
  readonly path?: string;
3993
+ /** Where the font comes from. */
2080
3994
  readonly source: NativeFontSource;
2081
3995
  };
3996
+ /** Where a font comes from: bundled with Discord, installed on the system, or a font addon. */
2082
3997
  export type NativeFontSource = 'app' | 'system' | 'custom';
3998
+ /** Which runtimes a debug garbage collection reached. */
3999
+ export type NativeGarbageCollection = {
4000
+ /** Whether garbage was collected on the runtime that made the call. */
4001
+ runtime: boolean;
4002
+ /** Whether garbage was collected on the UI runtime; false when no UI runtime is registered or collection failed. */
4003
+ uiRuntime: boolean;
4004
+ };
2083
4005
  /** An opaque reference to a native object. Only the bridge creates handles; plugins pass them back. */
2084
4006
  export type NativeHandle = {
4007
+ /** A type-only brand, absent at runtime, so plain objects cannot pass as handles. */
2085
4008
  readonly [nativeHandle]: true;
2086
4009
  };
2087
- export type NativeHookContext = {
2088
- self: NativeObjectHandle;
4010
+ /** What an Objective-C hook handler receives for one call of the hooked method. */
4011
+ export type NativeHookContext<Receiver extends boolean = true> = {
4012
+ /** The receiver, borrowed until the handler returns. */
4013
+ self: Receiver extends true ? NativeObjectHandle : undefined;
4014
+ /** The hooked selector's name. */
2089
4015
  selector: string;
4016
+ /** The method's explicit arguments, without `self` and `_cmd`, borrowed until the handler returns. */
2090
4017
  args: unknown[];
2091
- original: (...args: unknown[]) => unknown;
4018
+ /** The method argument index each entry of `args` came from, as trimmed by `payload.arguments`. */
4019
+ argumentIndexes: number[];
4020
+ /** Which handler is running. */
4021
+ phase: 'before' | 'after' | 'replace';
4022
+ /** Runs the original implementation; it works only synchronously on the hook's thread. */
4023
+ original: (...args: unknown[]) => NativeObjCResult;
4024
+ /** Swaps the object argument at an index of `args` before the original runs; only during a synchronous handler. */
2092
4025
  replaceObjectArgument(index: number, value: NativeObjectHandle | null): void;
2093
4026
  };
2094
- export type NativeHookHandlers = {
2095
- before?: (context: NativeHookContext) => void | Promise<void>;
2096
- after?: (context: NativeHookContext) => void | Promise<void>;
2097
- replace?: (context: NativeHookContext) => unknown;
2098
- };
2099
- export type NativeHookOptions = {
4027
+ /** The handlers an Objective-C hook runs around each call; it needs at least one, unless `cacheOnly` is set. */
4028
+ export type NativeHookHandlers<Receiver extends boolean = true> = {
4029
+ /** Runs before the original implementation. */
4030
+ before?: (context: NativeHookContext<Receiver>) => void | Promise<void>;
4031
+ /** Runs after the original implementation. */
4032
+ after?: (context: NativeHookContext<Receiver>) => void | Promise<void>;
4033
+ /** Runs instead of the original; what it returns becomes the method's result. */
4034
+ replace?: (context: NativeHookContext<Receiver>) => NativeObjCResult;
4035
+ };
4036
+ /** Options for `objc.hook`. */
4037
+ export type NativeHookOptions<Receiver extends boolean = boolean> = {
4038
+ /** Runs no JavaScript and returns values set with `setReturnValue`; needs a scalar or struct return type. */
2100
4039
  cacheOnly?: boolean;
4040
+ coalesce?: 'receiver';
4041
+ /** Hooks calls on this object only. */
2101
4042
  instance?: NativeObjectHandle;
4043
+ /** Removes the hook after its first call. */
2102
4044
  once?: boolean;
4045
+ payload?: NativeHookPayload<Receiver>;
2103
4046
  } & NativeCallOptions;
4047
+ /** Trims what a hook sends to JavaScript per call, to cut crossing cost on hot methods. */
4048
+ export type NativeHookPayload<Receiver extends boolean = boolean> = {
4049
+ /** Whether handlers receive `self`. Defaults to true. */
4050
+ receiver?: Receiver;
4051
+ /** The zero-based indexes of the arguments to send; every argument when omitted. */
4052
+ arguments?: number[];
4053
+ /** Sends only the `before` or only the `after` call; both when omitted. */
4054
+ phase?: 'before' | 'after';
4055
+ };
4056
+ /** An installed Objective-C hook; the plugin scope removes it on dispose. */
2104
4057
  export type NativeHookToken = {
4058
+ /** False once the hook is removed. */
2105
4059
  readonly active: boolean;
2106
- setReturnValue(self: NativeObjectHandle, args: unknown[], value: unknown): void;
4060
+ /** Sets the result a `cacheOnly` hook returns for calls with this receiver and these arguments. */
4061
+ setReturnValue(self: NativeObjectHandle, args: unknown[], value: NativeObjCResult): void;
4062
+ /** Removes the result set for this receiver and these arguments. */
2107
4063
  removeReturnValue(self: NativeObjectHandle, args: unknown[]): void;
4064
+ /** Removes every result set on this hook. */
2108
4065
  clearReturnValues(): void;
4066
+ /** Removes the hook; calling it again does nothing. */
2109
4067
  remove(): void;
2110
4068
  };
4069
+ /** An argument to a Java call: a tagged value or a handle. */
2111
4070
  export type NativeJavaArgument = NativeJavaValue | NativeJavaHandle;
4071
+ /** A key from `java.createAssociationKey` that names one associated value. */
2112
4072
  export type NativeJavaAssociationKey = NativeHandle;
4073
+ /** One independent operation in a Java `batch` or `batchAsync`. */
2113
4074
  export type NativeJavaBatchOperation = {
4075
+ /** What to do with `handle`. */
2114
4076
  op: 'invoke' | 'getField' | 'setField' | 'respondsTo';
4077
+ /** The object to act on. */
2115
4078
  handle: NativeJavaReference;
4079
+ /** The method or field name. */
2116
4080
  name: string;
4081
+ /** The method's arguments, for `invoke` and `respondsTo`. */
2117
4082
  args?: NativeJavaArgument[];
4083
+ /** The value to write, for `setField`. */
2118
4084
  value?: NativeJavaArgument;
2119
4085
  };
4086
+ /** The Android bridge to Java through reflection. Sync calls run on the JavaScript thread, so touch views only asynchronously. */
2120
4087
  export type NativeJavaBridge = {
4088
+ /** Looks up a class by fully qualified name and returns a handle the scope holds until released. */
2121
4089
  getClass(name: string): NativeJavaHandle;
4090
+ /** Lists a class's constructors, methods and fields. */
2122
4091
  describe(name: string): NativeJavaClassDescription;
4092
+ /** Runs independent operations in one call on the JavaScript thread and returns every result in order. */
2123
4093
  batch(operations: NativeJavaBatchOperation[]): NativeJavaValue[];
4094
+ /** Runs the operations like `batch`, on the main thread, so views can be read safely. */
4095
+ batchAsync(operations: NativeJavaBatchOperation[]): NativeCancelablePromise<NativeJavaValue[]>;
4096
+ /** Finds the views of a class under or above a view, on the main thread, like `objc.findViews`. */
4097
+ findViews(
4098
+ root: NativeJavaReference,
4099
+ className: string,
4100
+ options?: NativeViewSearchOptions,
4101
+ ): NativeCancelablePromise<NativeJavaValue[]>;
4102
+ /** Creates a key for attaching a value to objects with `setAssociatedObject`. */
2124
4103
  createAssociationKey(): NativeJavaAssociationKey;
4104
+ /** Reads the value attached to an object under a key. */
2125
4105
  getAssociatedObject(
2126
4106
  handle: NativeJavaReference,
2127
4107
  key: NativeJavaAssociationKey,
2128
4108
  ): NativeJavaValue;
4109
+ /** Attaches a value to an object under a key. */
2129
4110
  setAssociatedObject(
2130
4111
  handle: NativeJavaReference,
2131
4112
  key: NativeJavaAssociationKey,
2132
4113
  value: NativeJavaArgument,
2133
4114
  ): void;
4115
+ /** Reads an object's class name, as a string value. */
2134
4116
  className(handle: NativeJavaReference): NativeJavaValue;
4117
+ /** Calls the constructor matching `args` and returns a handle the scope holds until released. */
2135
4118
  construct(name: string, args?: NativeJavaArgument[]): NativeJavaHandle;
4119
+ /** Checks whether the object has a method `name` callable with `args`, as a boolean value. */
2136
4120
  respondsTo(
2137
4121
  handle: NativeJavaReference,
2138
4122
  name: string,
2139
4123
  args?: NativeJavaArgument[],
2140
4124
  ): NativeJavaValue;
4125
+ /** Calls a method on the JavaScript thread. */
2141
4126
  invoke(handle: NativeJavaReference, name: string, args?: NativeJavaArgument[]): NativeJavaValue;
4127
+ /** Resolves a method by name and parameter types once, for repeated calls through `invokePrepared`. */
4128
+ prepare(
4129
+ target: NativeJavaReference,
4130
+ name: string,
4131
+ parameterTypes: readonly string[],
4132
+ ): NativeJavaCallPlan;
4133
+ /** Calls a prepared method on the JavaScript thread, like `invoke`. */
4134
+ invokePrepared(
4135
+ plan: NativeJavaCallPlan,
4136
+ target: NativeJavaReference,
4137
+ args?: NativeJavaArgument[],
4138
+ ): NativeJavaValue;
4139
+ /** Calls a prepared method on the main thread and resolves with its result, like `invokeAsync`. */
4140
+ invokePreparedAsync(
4141
+ plan: NativeJavaCallPlan,
4142
+ target: NativeJavaReference,
4143
+ args?: NativeJavaArgument[],
4144
+ ): NativeCancelablePromise<NativeJavaValue>;
4145
+ /** Frees a call plan; using it afterwards throws. */
4146
+ disposePlan(plan: NativeJavaCallPlan): void;
4147
+ /** Calls a method on the main thread and resolves with its result. Needs `native.java.invokeAsync`. */
2142
4148
  invokeAsync(
2143
4149
  handle: NativeJavaReference,
2144
4150
  name: string,
2145
4151
  args?: NativeJavaArgument[],
2146
4152
  ): NativeCancelablePromise<NativeJavaValue>;
4153
+ /** Reads a field by name. */
2147
4154
  getField(handle: NativeJavaReference, name: string): NativeJavaValue;
4155
+ /** Writes a field by name. */
2148
4156
  setField(handle: NativeJavaReference, name: string, value: NativeJavaArgument): void;
4157
+ /** Drops the plugin's hold on a handle so the loader can free the object. */
2149
4158
  release(handle: NativeJavaReference): void;
2150
4159
  };
4160
+ /** A method resolved once by `java.prepare`, for calling many times without the lookup. */
4161
+ export type NativeJavaCallPlan = NativeJavaHandle & {
4162
+ readonly [nativeJavaCallPlan]: true;
4163
+ };
4164
+ /** A Java class's shape, read by reflection with `java.describe`. */
2151
4165
  export type NativeJavaClassDescription = {
4166
+ /** The fully qualified class name. */
2152
4167
  name: string;
4168
+ /** The superclass name, or `null` when there is none. */
2153
4169
  superclass: string | null;
4170
+ /** The names of the interfaces the class implements. */
2154
4171
  interfaces: string[];
4172
+ /** Each constructor's parameter class names. */
2155
4173
  constructors: string[][];
4174
+ /** The methods the class declares. */
2156
4175
  methods: NativeJavaMethodDescription[];
4176
+ /** The fields the class declares. */
2157
4177
  fields: NativeJavaFieldDescription[];
2158
4178
  };
4179
+ /** One field a Java class declares, from `java.describe`. */
2159
4180
  export type NativeJavaFieldDescription = {
4181
+ /** The field name. */
2160
4182
  name: string;
4183
+ /** The field type's class name. */
2161
4184
  type: string;
4185
+ /** Whether the field is static. */
2162
4186
  static: boolean;
2163
4187
  };
4188
+ /** A handle to a Java object or class; the plugin scope releases it on dispose. */
2164
4189
  export type NativeJavaHandle = NativeHandle;
4190
+ /** A Java object reference the bridge returns inside a result. */
2165
4191
  export type NativeJavaHandleValue = {
4192
+ /** Marks the value as an object reference. */
2166
4193
  type: 'handle';
4194
+ /** The id the loader issued for the object. */
2167
4195
  value: string;
2168
4196
  };
2169
- export type NativeJavaHookEvent = {
2170
- self: NativeJavaValue;
4197
+ /** What a Java hook listener receives for one call of the hooked method. */
4198
+ export type NativeJavaHookEvent<Receiver extends boolean = true> = {
4199
+ /** The object the hooked method was called on. */
4200
+ self: Receiver extends true ? NativeJavaValue : undefined;
4201
+ /** The call's arguments. */
2171
4202
  args: NativeJavaValue[];
2172
- };
2173
- export type NativeJavaHookOptions = {
4203
+ /** The method argument index each entry of `args` came from, as trimmed by `payload.arguments`. */
4204
+ argumentIndexes: number[];
4205
+ /** Whether the listener heard the call before or after the method ran. */
4206
+ phase: 'before' | 'after';
4207
+ };
4208
+ /** Options for `hooks.hook`. */
4209
+ export type NativeJavaHookOptions<Receiver extends boolean = boolean> = {
4210
+ /** Collapses queued `after` events for the same receiver into one; needs a non-static method and an `after` payload. */
4211
+ coalesce?: 'receiver';
4212
+ /** Returns a value set with `setReturnValue` for a matching call instead of running the method. Defaults to false. */
2174
4213
  replace?: boolean;
2175
- notify?: boolean;
4214
+ /** Whether the listener hears calls: before the method by default, `after` once it has run, `false` never. */
4215
+ notify?: boolean | 'after';
4216
+ /** Trims the receiver, arguments and phase each event sends, to cut crossing cost on hot methods. */
4217
+ payload?: NativeHookPayload<Receiver>;
2176
4218
  };
4219
+ /** An installed Java hook; the plugin scope removes it on dispose. */
2177
4220
  export type NativeJavaHookToken = {
4221
+ /** The id the loader issued, such as `hook-1`. */
2178
4222
  readonly id: string;
2179
4223
  };
4224
+ /** The Android bridge for hooking Java methods. Needs `native.java.hooks`. */
2180
4225
  export type NativeJavaHooksBridge = {
2181
- hook(
4226
+ /** Hooks the method whose parameter class names match `parameterTypes`, and sends each call to `listener`. */
4227
+ hook<Receiver extends boolean = true>(
2182
4228
  className: string,
2183
4229
  methodName: string,
2184
4230
  parameterTypes: string[],
2185
- options?: NativeJavaHookOptions,
2186
- listener?: (event: NativeJavaHookEvent) => void,
4231
+ options?: NativeJavaHookOptions<Receiver>,
4232
+ listener?: (event: NativeJavaHookEvent<Receiver>) => void,
2187
4233
  ): NativeJavaHookToken;
4234
+ /** Sets the result a `replace` hook returns for calls with this receiver and these arguments. */
2188
4235
  setReturnValue(
2189
4236
  token: NativeJavaHookToken,
2190
4237
  self: NativeJavaValue,
2191
4238
  args: NativeJavaValue[],
2192
4239
  value: NativeJavaValue,
2193
4240
  ): void;
4241
+ /** Removes the result set for this receiver and these arguments. */
2194
4242
  removeReturnValue(
2195
4243
  token: NativeJavaHookToken,
2196
4244
  self: NativeJavaValue,
2197
4245
  args: NativeJavaValue[],
2198
4246
  ): void;
4247
+ /** Removes every result set on a hook. */
2199
4248
  clearReturnValues(token: NativeJavaHookToken): void;
4249
+ /** Removes a hook. */
2200
4250
  remove(token: NativeJavaHookToken): void;
2201
4251
  };
4252
+ /** One method a Java class declares, from `java.describe`. */
2202
4253
  export type NativeJavaMethodDescription = {
4254
+ /** The method name. */
2203
4255
  name: string;
4256
+ /** The parameters' class names, in order, as `hooks.hook` takes them. */
2204
4257
  parameters: string[];
4258
+ /** The return type's class name. */
2205
4259
  returnType: string;
4260
+ /** Whether the method is static. */
2206
4261
  static: boolean;
2207
4262
  };
4263
+ /** A Java object, as a handle or as a tagged handle value from a result. */
2208
4264
  export type NativeJavaReference = NativeJavaHandle | NativeJavaHandleValue;
4265
+ /** A Java value tagged with its type, as the Java bridge returns and accepts it. */
2209
4266
  export type NativeJavaValue =
2210
4267
  | {
2211
4268
  type: 'null';
@@ -2237,171 +4294,414 @@ export type NativeJavaValue =
2237
4294
  componentType: string;
2238
4295
  value: (NativeJavaValue | NativeJavaHandle | string | number | boolean)[];
2239
4296
  };
4297
+ /** How long main-thread crossings for one addon, kind and call label waited and ran. */
4298
+ export type NativeMainWaitCounts = {
4299
+ /** The id of the addon that made the crossings. */
4300
+ addon: string;
4301
+ /** How the caller crossed: blocking (`sync`), fire-and-forget (`posted`) or awaiting a promise (`async`). */
4302
+ kind: 'sync' | 'posted' | 'async' | 'unknown';
4303
+ /** The call label the crossings ran under, `(other)` once the table is full. */
4304
+ label: string;
4305
+ /** Crossings queued for the main thread. */
4306
+ posted: number;
4307
+ /** Crossings that began running on the main thread. */
4308
+ started: number;
4309
+ /** Crossings that finished running on the main thread. */
4310
+ finished: number;
4311
+ /** Crossings that timed out or were refused before they started. */
4312
+ expired: number;
4313
+ /** Total time between posting and starting on the main thread. */
4314
+ queuedMs: number;
4315
+ /** The longest wait between posting and starting. */
4316
+ maxQueuedMs: number;
4317
+ /** Total time spent running on the main thread. */
4318
+ runMs: number;
4319
+ /** The longest single run on the main thread. */
4320
+ maxRunMs: number;
4321
+ };
4322
+ /** Main-thread drains since launch or the last counter reset. */
4323
+ export type NativeMainWorkCounts = {
4324
+ /** Times the loader drained its main-thread queue. */
4325
+ drains: number;
4326
+ /** Work items run across every drain. */
4327
+ items: number;
4328
+ /** Total time spent draining. */
4329
+ drainMs: number;
4330
+ /** The longest single drain. */
4331
+ maxDrainMs: number;
4332
+ /** The most items one drain ran. */
4333
+ maxDrainItems: number;
4334
+ };
4335
+ /** The iOS bridge to the Objective-C runtime, scoped to the plugin's capabilities. */
2240
4336
  export type NativeObjCBridge = {
4337
+ /** Looks up a class by name, or returns `null` when none is registered. */
2241
4338
  getClass(name: string): NativeClassHandle | null;
4339
+ /** Allocates an instance and initializes it with `init`, UIKit classes on the main thread; use `create` for any other initializer. */
2242
4340
  alloc(classOrName: string | NativeClassHandle): NativeObjectHandle;
4341
+ /** Allocates an uninitialized instance, UIKit classes on the main thread unless `options.thread` says otherwise, and returns what `initSelector` initializes; throws when that is nil. */
4342
+ create(
4343
+ classOrName: string | NativeClassHandle,
4344
+ initSelector: string,
4345
+ args?: unknown[],
4346
+ options?: NativeCallOptions,
4347
+ ): NativeObjectHandle;
4348
+ /** Returns the class name of the object a handle refers to, or `null`. */
2243
4349
  className(handle: NativeHandle): string | null;
4350
+ /** Checks whether the object responds to a selector. */
2244
4351
  respondsTo(handle: NativeHandle, selector: string): boolean;
2245
- call(handle: NativeHandle, selector: string, ...args: unknown[]): unknown;
4352
+ /** Sends a selector with its arguments on the current runtime thread. */
4353
+ call(handle: NativeHandle, selector: string, ...args: unknown[]): NativeObjCResult;
4354
+ /** Runs the implementation `currentClass`'s superclass provides, like `super` in Objective-C. */
2246
4355
  callSuper(
2247
4356
  handle: NativeObjectHandle,
2248
4357
  currentClass: NativeClassHandle | string,
2249
4358
  selector: string,
2250
4359
  ...args: unknown[]
2251
- ): unknown;
4360
+ ): NativeObjCResult;
4361
+ /** Sends a selector on the thread `options.thread` names; `main` blocks, `main-post` queues `void` methods, so prefer `invokeAsync` or `main-post` for UI work. Ownership follows Cocoa naming: an `alloc`, `new`, `copy`, `mutableCopy` or `init` result is owned by its handle without an extra reference, and the receiver of an `init` selector stays valid. */
2252
4362
  invoke(
2253
4363
  handle: NativeObjectHandle,
2254
4364
  selector: string,
2255
4365
  args: unknown[],
2256
4366
  options?: NativeCallOptions,
2257
- ): unknown;
4367
+ ): NativeObjCResult;
4368
+ /** Sends a selector on the main thread and resolves with its result. Needs `native.objc.invokeAsync`. */
2258
4369
  invokeAsync(
2259
4370
  handle: NativeObjectHandle,
2260
4371
  selector: string,
2261
4372
  args: unknown[],
2262
- ): NativeCancelablePromise<unknown>;
2263
- batch(steps: readonly NativeBatchStep[]): NativeCancelablePromise<unknown[]>;
4373
+ ): NativeCancelablePromise<NativeObjCResult>;
4374
+ /** Resolves a selector's method signature on an object once, for repeated calls through `invokePrepared`. */
4375
+ prepare(handle: NativeHandle, selector: string): NativeObjCCallPlan;
4376
+ /** Calls a prepared selector on an object, on the thread `options.thread` names, like `invoke`. */
4377
+ invokePrepared(
4378
+ plan: NativeObjCCallPlan,
4379
+ handle: NativeHandle,
4380
+ args: unknown[],
4381
+ options?: NativeCallOptions,
4382
+ ): NativeObjCResult;
4383
+ /** Calls a prepared selector on the main thread and resolves with its result, like `invokeAsync`. */
4384
+ invokePreparedAsync(
4385
+ plan: NativeObjCCallPlan,
4386
+ handle: NativeHandle,
4387
+ args: unknown[],
4388
+ ): NativeCancelablePromise<NativeObjCResult>;
4389
+ /** Frees a call plan; using it afterwards throws. */
4390
+ disposePlan(plan: NativeObjCCallPlan): void;
4391
+ /** Runs dependent calls in one main-thread pass; a failed step rejects it without undoing earlier steps. */
4392
+ batch(steps: readonly NativeBatchStep[]): NativeCancelablePromise<NativeObjCResult[]>;
4393
+ /** Reads a `UIView` subtree in one main-thread pass, as a point-in-time list. Needs `native.objc.snapshot`. */
2264
4394
  snapshot(
2265
4395
  root: NativeObjectHandle,
2266
4396
  options?: NativeViewSnapshotOptions,
2267
4397
  ): NativeCancelablePromise<NativeViewSnapshotNode[]>;
4398
+ /** Finds the views of a class under or above a view on the main thread. Needs `native.objc.snapshot`. */
2268
4399
  findViews(
2269
4400
  root: NativeObjectHandle,
2270
4401
  className: string,
2271
4402
  options?: NativeViewSearchOptions,
2272
4403
  ): NativeCancelablePromise<NativeObjectHandle[]>;
4404
+ /** Like `callSuper` with a thread policy; it cannot cross to the main thread synchronously. */
2273
4405
  invokeSuper(
2274
4406
  handle: NativeObjectHandle,
2275
4407
  currentClass: NativeClassHandle | string,
2276
4408
  selector: string,
2277
4409
  args: unknown[],
2278
4410
  options?: NativeCallOptions,
2279
- ): unknown;
4411
+ ): NativeObjCResult;
4412
+ /** Runs the superclass implementation on the main thread and resolves with its result. */
2280
4413
  invokeSuperAsync(
2281
4414
  handle: NativeObjectHandle,
2282
4415
  currentClass: NativeClassHandle | string,
2283
4416
  selector: string,
2284
4417
  args: unknown[],
2285
- ): NativeCancelablePromise<unknown>;
2286
- getIvar(handle: NativeObjectHandle, name: string): unknown;
2287
- setIvar(handle: NativeObjectHandle, name: string, value: unknown): void;
4418
+ ): NativeCancelablePromise<NativeObjCResult>;
4419
+ /** Reads an instance variable by name, such as `_viewModel`. */
4420
+ getIvar(handle: NativeObjectHandle, name: string): NativeObjCResult;
4421
+ /** Writes an instance variable by name. */
4422
+ setIvar(handle: NativeObjectHandle, name: string, value: NativeObjCResult): void;
4423
+ /** Creates a key for attaching a value to objects with `setAssociatedObject`. */
2288
4424
  createAssociationKey(): NativeAssociationKey;
2289
- getAssociatedObject(handle: NativeObjectHandle, key: NativeAssociationKey): unknown;
4425
+ /** Reads the value attached to an object under a key. */
4426
+ getAssociatedObject(handle: NativeObjectHandle, key: NativeAssociationKey): NativeObjCResult;
4427
+ /** Attaches a value to an object; `null` clears it. `policy` is `assign`, `retain`, `copy`, `retainNonatomic` or `copyNonatomic`. */
2290
4428
  setAssociatedObject(
2291
4429
  handle: NativeObjectHandle,
2292
4430
  key: NativeAssociationKey,
2293
- value: unknown,
4431
+ value: NativeObjCResult,
2294
4432
  policy?: string,
2295
4433
  ): void;
4434
+ /** Builds a registered struct, such as `CGRect` or `UIEdgeInsets`, to pass to native calls. */
2296
4435
  struct<T extends NativeStructFields = NativeStructFields>(
2297
4436
  name: string,
2298
4437
  fields: T,
2299
4438
  ): NativeStruct<T>;
2300
- array(handle: NativeObjectHandle): unknown[];
4439
+ /** Converts an `NSArray` handle to a JavaScript array. */
4440
+ array(handle: NativeObjectHandle): NativeObjCResult[];
4441
+ /** Copies bytes into a new `NSData` object. */
2301
4442
  data(value: ArrayBuffer | Uint8Array): NativeObjectHandle;
2302
- hook(
4443
+ /** Hooks a method by class and selector; handlers run in registration order, and the scope removes the hook on dispose. */
4444
+ hook<Receiver extends boolean = true>(
2303
4445
  className: string,
2304
4446
  selector: string,
2305
- handlers: NativeHookHandlers,
2306
- options?: NativeHookOptions,
4447
+ handlers: NativeHookHandlers<Receiver>,
4448
+ options?: NativeHookOptions<Receiver>,
2307
4449
  ): NativeHookToken;
2308
4450
  };
4451
+ /** A selector and method signature resolved once by `objc.prepare`, for calling many times without the lookup. */
4452
+ export type NativeObjCCallPlan = NativeHandle & {
4453
+ readonly [nativeObjCCallPlan]: true;
4454
+ };
4455
+ /** What an Objective-C call returns: a plain value, a handle to an object, a 64-bit integer, or nothing for `void`. */
4456
+ export type NativeObjCResult = NativeSerializable | NativeHandle | bigint | undefined;
4457
+ /** A retained handle to an Objective-C object. */
2309
4458
  export type NativeObjectHandle = NativeHandle;
4459
+ /** Loader helpers for verifying and loading installed addons. */
2310
4460
  export type NativePlatformAddons = {
2311
4461
  /** Checks a manifest's `signature` against its bundle. */
2312
4462
  verify(manifest: string, bundle: string): NativeAddonVerification;
2313
4463
  /** Evaluates an installed plugin's bundle compiled for this bytecode version, if its digest matches the manifest. */
2314
- evaluateBytecode?(folder: string, bytecodeVersion: number): NativeCompiledPlugin | undefined;
2315
- };
4464
+ evaluateBytecode(folder: string, bytecodeVersion: number): NativeCompiledPlugin | undefined;
4465
+ /** Reads an installed plugin's source, for one the loader handed over without it, if its signature still holds. */
4466
+ readSource(folder: string): string | undefined;
4467
+ };
4468
+ /** Android-only helpers; missing on iOS. */
4469
+ export type NativePlatformAndroidBridge = {
4470
+ /** Installs patched Discord builds over this one. */
4471
+ readonly installer: NativePlatformAndroidInstaller;
4472
+ };
4473
+ /** Installs another patched Discord build over this one, upgrade or downgrade, downloading only the splits that differ. */
4474
+ export type NativePlatformAndroidInstaller = {
4475
+ /** Reads whether in-app installs work and which Discord is installed. */
4476
+ status(): NativeAndroidInstallerStatus;
4477
+ /** Opens the system's "Install unknown apps" screen for Discord. */
4478
+ requestPermission(): boolean;
4479
+ /** SHA-256 of each installed split APK, `null` where it cannot be read. */
4480
+ installedSplits(): Promise<Record<string, string | null>>;
4481
+ /** Starts installing a build in the background; false when an install is already running. Poll `progress`. */
4482
+ install(splits: readonly NativeAndroidInstallSplit[]): boolean;
4483
+ /** Reads how far the running install is. */
4484
+ progress(): NativeAndroidInstallProgress;
4485
+ /** Stops a running download or abandons the install session. */
4486
+ cancel(): boolean;
4487
+ };
4488
+ /** Facts about the Discord install the loader runs in. */
2316
4489
  export type NativePlatformApp = {
4490
+ /** Where Discord was installed from, such as `App Store` or `Google Play`. */
2317
4491
  getAppSource(): string;
2318
- /** True for the first caller in this process; a reloaded runtime sees false. Missing on older loaders. */
2319
- claimLaunchURL?(): boolean;
4492
+ /** The framework that injected the loader, such as Vector or LSPosed on Android and ElleKit on iOS, or an empty string. */
4493
+ getFramework(): string;
4494
+ /** Whether the loader's embedded attestation verified against Unbound's pinned key. False for development builds. */
4495
+ isVerifiedBuild(): boolean;
4496
+ /** True for the first caller in this process; a reloaded runtime sees false. */
4497
+ claimLaunchURL(): boolean;
2320
4498
  };
4499
+ /** Platform-wide helpers the loader publishes as `globalThis.NativePlatform`, not scoped to a plugin. */
2321
4500
  export type NativePlatformBridge = {
4501
+ /** The host platform. */
2322
4502
  readonly platform: NativePluginPlatform;
4503
+ /** Evaluates Hermes bytecode in the current runtime; `tag` names it in errors. Throws on invalid bytecode. */
2323
4504
  evaluateBytecode(bytecode: ArrayBuffer, tag?: string): unknown;
4505
+ /** Facts about the device. */
2324
4506
  readonly device: NativePlatformDevice;
4507
+ /** Facts about the Discord install. */
2325
4508
  readonly app: NativePlatformApp;
4509
+ /** File removal in the Unbound folder; missing when the loader has no documents directory. */
2326
4510
  readonly files?: NativePlatformFiles;
4511
+ /** Crash and freeze attribution for addons; missing when the loader has no documents directory. */
2327
4512
  readonly crashGuard?: NativePlatformCrashGuard;
4513
+ /** The native settings file; missing when the loader does not manage settings. */
2328
4514
  readonly settings?: NativePlatformSettings;
4515
+ /** The font list; missing when the loader cannot list fonts. */
2329
4516
  readonly fonts?: NativePlatformFonts;
2330
- readonly addons?: NativePlatformAddons;
4517
+ /** Addon verification and bytecode loading. */
4518
+ readonly addons: NativePlatformAddons;
4519
+ /** Hermes' sampling profiler. */
4520
+ readonly profiler: NativePlatformProfiler;
4521
+ /** iOS-only helpers; missing on Android. */
2331
4522
  readonly ios?: NativePlatformIOSBridge;
4523
+ /** Android-only helpers; missing on iOS and on loaders without the in-app installer. */
4524
+ readonly android?: NativePlatformAndroidBridge;
2332
4525
  };
4526
+ /** The loader's record of which addon was starting or running when Discord crashed, kept across launches. */
2333
4527
  export type NativePlatformCrashGuard = {
4528
+ /** Marks an addon as starting, by crash guard key and display name, so a crash during its start is blamed on it. */
2334
4529
  begin(id: string, name: string): boolean;
4530
+ /** Clears the start marker once the addon's start has returned. */
2335
4531
  end(id: string): boolean;
4532
+ /** Lists the addons the loader disabled after crashes on consecutive launches. */
2336
4533
  disabled(): NativeCrashedAddon[];
2337
- register?(id: string, name: string): number;
2338
- activity?(): ArrayBuffer | undefined;
4534
+ /** Registers an addon for crash attribution and returns its slot, or 0 when the loader cannot attribute crashes. */
4535
+ register(id: string, name: string): number;
4536
+ /** Returns a 4-byte buffer shared with the loader that holds the running addon's slot, or `undefined` when unavailable. */
4537
+ activity(): ArrayBuffer | undefined;
2339
4538
  };
4539
+ /** Facts about the device Discord runs on. */
2340
4540
  export type NativePlatformDevice = {
4541
+ /** The host platform. */
2341
4542
  readonly platform: NativePluginPlatform;
4543
+ /** The device's model name. */
2342
4544
  getDeviceModel(): string;
4545
+ /** The operating system's version. */
2343
4546
  getOSVersionString(): string;
4547
+ /** Whether the device is jailbroken on iOS or has an `su` binary on Android. */
2344
4548
  isRooted(): boolean;
4549
+ /** The active iOS jailbreak's name, such as `Dopamine 2.4`, or an empty string on Android and when none is found; older loaders lack it. */
4550
+ getJailbreak?(): string;
4551
+ /** Whether Discord is installed as a system app. */
2345
4552
  isSystemApp(): boolean;
4553
+ /** Whether Discord runs in a simulator, emulator or virtual machine. */
2346
4554
  isVirtualDevice(): boolean;
2347
4555
  };
4556
+ /** File operations inside the Unbound folder in Discord's documents directory. */
2348
4557
  export type NativePlatformFiles = {
4558
+ /** Removes a file or folder tree, by path relative to the Unbound folder; returns whether anything was removed. */
2349
4559
  remove(path: string): boolean;
4560
+ /** Reads a text file, by path relative to the Unbound folder; `undefined` when it is missing. Older loaders lack it. */
4561
+ read?(path: string): string | undefined;
4562
+ /** Replaces a text file atomically, by path relative to the Unbound folder; returns whether it was written. Older loaders lack it. */
4563
+ write?(path: string, text: string): boolean;
2350
4564
  };
4565
+ /** The fonts the loader can apply. */
2351
4566
  export type NativePlatformFonts = {
4567
+ /** Lists font addons first, then app and system fonts, without duplicate names. */
2352
4568
  list(): NativeFontEntry[];
2353
4569
  };
4570
+ /** iOS-only facts about Discord's code signature. */
2354
4571
  export type NativePlatformIOSBridge = {
2355
- isVerifiedBuild(): boolean;
4572
+ /** Discord's code-signing entitlements, as an object. */
2356
4573
  getEntitlements(): NativeSerializableObject;
4574
+ /** Discord's code-signing entitlements, as plist text. */
2357
4575
  getEntitlementsAsPlist(): string;
2358
4576
  };
4577
+ /** Hermes' sampling profiler, shared with the loader's freeze watchdog. */
4578
+ export type NativePlatformProfiler = {
4579
+ /** Starts sampling; `false` when the profiler is missing or already running. */
4580
+ start(): boolean;
4581
+ /** Stops sampling and returns the Chrome trace it recorded, or `undefined` when it was not running. */
4582
+ stop(): string | undefined;
4583
+ };
4584
+ /** The loader's native settings file, which holds every Bucket. */
2359
4585
  export type NativePlatformSettings = {
4586
+ /** Applies changes and writes the file at once; false when the changes are malformed or the write failed. */
2360
4587
  apply(changes: readonly NativeSettingsChange[]): boolean;
2361
- };
4588
+ /** Applies changes in memory, to be written by `flush`. */
4589
+ stage(changes: readonly NativeSettingsChange[]): boolean;
4590
+ /** Writes staged changes to the file, if any. */
4591
+ flush(): boolean;
4592
+ /** Reads every Bucket with no arguments, one Bucket with `store`, or one dot-path `key`; `undefined` when unset. */
4593
+ get(store?: string, key?: string): NativeSerializable | undefined;
4594
+ };
4595
+ /** The native bridge a plugin reaches through `context.native`, gated by the capabilities it declares. */
2362
4596
  export type NativePluginBridge = {
4597
+ /** The version of the JavaScript API plugins use, compared with a manifest's `minNativePluginApi`. */
2363
4598
  readonly apiVersion: string;
4599
+ /** The version of the native ABI the loader implements. */
2364
4600
  readonly abiVersion: string;
4601
+ /** Every capability this loader build provides, not only the ones the plugin declares. */
2365
4602
  readonly capabilities: readonly NativePluginCapability[];
4603
+ /** The Objective-C runtime; iOS only. */
2366
4604
  readonly objc: NativeObjCBridge;
4605
+ /** Raw calls to C functions. */
2367
4606
  readonly ffi: NativeFFIBridge;
4607
+ /** React Native surfaces mounted in native views. */
2368
4608
  readonly fabric: NativeFabricBridge;
4609
+ /** Subscriptions to Discord activity. */
2369
4610
  readonly runtime: NativeRuntimeBridge;
4611
+ /** Java reflection; Android only. */
2370
4612
  readonly java: NativeJavaBridge;
4613
+ /** Java method hooks; Android only. */
2371
4614
  readonly hooks: NativeJavaHooksBridge;
4615
+ /** Debugger support. */
2372
4616
  readonly debug: NativeDebugBridge;
4617
+ /** Worklets on the UI runtime. */
4618
+ readonly ui: NativeUIBridge;
2373
4619
  };
4620
+ /** A named permission to use one part of the native bridge, declared in an addon's manifest. */
2374
4621
  export type NativePluginCapability = (typeof NATIVE_PLUGIN_CAPABILITIES)[number];
4622
+ /** The shape of an error the native bridge or its plugin scope throws. */
2375
4623
  export type NativePluginError = {
4624
+ /** Which failure it is; native failures without their own code use `NATIVE_BRIDGE_ERROR`. */
2376
4625
  code: NativePluginErrorCode;
4626
+ /** A human-readable description. */
2377
4627
  message: string;
4628
+ /** The capability the plugin lacks, for `NATIVE_PLUGIN_CAPABILITY_DENIED`. */
2378
4629
  capability?: NativePluginCapability;
2379
4630
  };
4631
+ /** The stable `code` on an error the native bridge or its plugin scope throws. */
2380
4632
  export type NativePluginErrorCode =
2381
4633
  | 'NATIVE_BRIDGE_ERROR'
2382
4634
  | 'NATIVE_PLUGIN_API_VERSION_UNSUPPORTED'
4635
+ | 'NATIVE_PLUGIN_CALL_CANCELLED'
4636
+ | 'NATIVE_PLUGIN_CALL_TIMEOUT'
2383
4637
  | 'NATIVE_PLUGIN_CAPABILITY_DENIED'
2384
4638
  | 'NATIVE_PLUGIN_SCOPE_DISPOSED'
2385
4639
  | 'NATIVE_PLUGIN_UNAVAILABLE';
2386
- export type NativePluginPlatform = 'ios' | 'android';
4640
+ /** A native bridge method by the path a plugin calls it through, such as `objc.invoke`. */
4641
+ export type NativePluginMethod = {
4642
+ [N in NativePluginNamespace]: `${N}.${keyof NativePluginBridge[N] & string}`;
4643
+ }[NativePluginNamespace];
4644
+ /** A {@link NativePluginBridge} namespace whose methods a plugin calls, such as `objc` or `java`. */
4645
+ export type NativePluginNamespace = Exclude<
4646
+ keyof NativePluginBridge,
4647
+ 'apiVersion' | 'abiVersion' | 'capabilities' | 'ui'
4648
+ >;
4649
+ /** A host platform the loader reports, `ios` or `android`. */
4650
+ export type NativePluginPlatform = (typeof NATIVE_PLUGIN_PLATFORMS)[number];
4651
+ /** A capability the native bridge on platform `P` provides. */
4652
+ export type NativePluginPlatformCapability<P extends NativePluginPlatform> =
4653
+ (typeof NATIVE_PLUGIN_PLATFORM_CAPABILITIES)[P][number];
4654
+ /** The raw bridge the loader publishes as `globalThis.NativePlugin`; `objc` exists only on iOS, `java` and `hooks` only on Android. */
2387
4655
  export type NativePluginRuntimeBridge = Pick<
2388
4656
  NativePluginBridge,
2389
- 'apiVersion' | 'abiVersion' | 'capabilities'
4657
+ 'apiVersion' | 'abiVersion' | 'capabilities' | 'ffi' | 'fabric' | 'debug'
2390
4658
  > &
2391
- Partial<Omit<NativePluginBridge, 'apiVersion' | 'abiVersion' | 'capabilities'>>;
4659
+ Partial<Pick<NativePluginBridge, 'hooks'>> & {
4660
+ readonly objc?: LoaderObjCBridge;
4661
+ readonly java?: NativeJavaBridge & NativeUIScopeFactory;
4662
+ };
4663
+ /** A handle to a native symbol's address, from `ffi.symbol`; `ffi.call` accepts only these. */
2392
4664
  export type NativePointer = NativeHandle;
4665
+ /** How many native resources the loader holds across every plugin. */
2393
4666
  export type NativeResourceCounts = {
4667
+ /** Installed hooks. */
2394
4668
  hooks: number;
4669
+ /** Mounted Fabric surfaces. */
2395
4670
  surfaces: number;
4671
+ /** Hook return values set with `setReturnValue`. */
2396
4672
  cachedReturns: number;
4673
+ /** Handles still referenced from JavaScript: leases plus the platform's own handle count. */
2397
4674
  handles: number;
2398
- };
4675
+ /** Handle leases JavaScript still holds. */
4676
+ leases: number;
4677
+ /** Live Objective-C value handles; iOS only, 0 elsewhere. */
4678
+ objcHandles: number;
4679
+ /** Prepared Objective-C call plans; iOS only, 0 elsewhere. */
4680
+ objcPlans: number;
4681
+ /** Objective-C objects the loader retains internally; iOS only, 0 elsewhere. */
4682
+ objcRetains: number;
4683
+ /** Java objects with a live handle; Android only, 0 elsewhere. */
4684
+ javaHandles: number;
4685
+ /** Pooled Fabric surfaces waiting to be reused. */
4686
+ idleSurfaces: number;
4687
+ /** Fabric surfaces created since launch. */
4688
+ createdSurfaces: number;
4689
+ /** Fabric surfaces reused from the pool since launch. */
4690
+ reusedSurfaces: number;
4691
+ /** Batches of main-thread work the loader drained. */
4692
+ mainWork: NativeMainWorkCounts;
4693
+ /** Main-thread crossings per addon, kind and call label, busiest first. */
4694
+ mainWaits: NativeMainWaitCounts[];
4695
+ };
4696
+ /** Delivers Discord activity to plugins. Needs `native.runtime.events`. */
2399
4697
  export type NativeRuntimeBridge = {
4698
+ /** Calls `listener` with a serializable payload each time the event happens. */
2400
4699
  subscribe(
2401
4700
  event: NativeRuntimeEventName,
2402
4701
  listener: (payload: NativeSerializableObject) => void,
2403
4702
  ): NativeRuntimeEventToken;
2404
4703
  };
4704
+ /** A Discord activity a plugin can subscribe to; the client derives each from Flux actions, such as `MESSAGE_CREATE`. */
2405
4705
  export type NativeRuntimeEventName =
2406
4706
  | 'message.created'
2407
4707
  | 'message.updated'
@@ -2410,8 +4710,11 @@ export type NativeRuntimeEventName =
2410
4710
  | 'channel.changed'
2411
4711
  | 'composer.changed'
2412
4712
  | 'ui.changed';
4713
+ /** A runtime event subscription; the plugin scope removes it on dispose. */
2413
4714
  export type NativeRuntimeEventToken = {
4715
+ /** False once the subscription is removed. */
2414
4716
  readonly active: boolean;
4717
+ /** Stops the listener receiving events. */
2415
4718
  remove(): void;
2416
4719
  };
2417
4720
  /** A value the bridge serializes by structure, such as Fabric surface props or a plist. */
@@ -2422,9 +4725,11 @@ export type NativeSerializable =
2422
4725
  | null
2423
4726
  | NativeSerializable[]
2424
4727
  | NativeSerializableObject;
4728
+ /** A plain object of serializable values, such as a runtime event payload. */
2425
4729
  export type NativeSerializableObject = {
2426
4730
  [key: string]: NativeSerializable;
2427
4731
  };
4732
+ /** One change to a Bucket: set a key, remove a key, or clear the whole Bucket. Keys are dot paths. */
2428
4733
  export type NativeSettingsChange =
2429
4734
  | {
2430
4735
  store: string;
@@ -2440,35 +4745,95 @@ export type NativeSettingsChange =
2440
4745
  store: string;
2441
4746
  clear: true;
2442
4747
  };
4748
+ /** A registered C struct, such as `CGRect`, built by `objc.struct` or returned from a native call. */
2443
4749
  export type NativeStruct<T extends NativeStructFields = NativeStructFields> = {
2444
4750
  readonly name: string;
2445
4751
  readonly value?: T;
2446
4752
  } & NativeHandle;
2447
4753
  /** A C struct field: a scalar, a pointer or object, or a nested struct. */
2448
4754
  export type NativeStructField = number | boolean | NativeHandle | NativeStructFields;
4755
+ /** A struct's field values by field name. */
2449
4756
  export type NativeStructFields = {
2450
4757
  [field: string]: NativeStructField;
2451
4758
  };
2452
- export type NativeThreadPolicy = 'current' | 'main';
4759
+ /**
4760
+ * Where a native call runs: `current` is the calling thread; `main` blocks until the main thread runs it;
4761
+ * `main-post` queues a `void` method on main and logs its failure, and blocks like `main` otherwise.
4762
+ */
4763
+ export type NativeThreadPolicy = 'current' | 'main' | 'main-post';
4764
+ /** A value a worklet can take from the JS runtime: a serializable value, a UI scope, which is shared as is, or a callback into the JS thread. */
4765
+ export type NativeUIArgument = NativeSerializable | NativeUIScope | NativeUICallback;
4766
+ /** Runs plugin worklets on the UI runtime, where native views live, so hooks there act before the next frame. */
4767
+ export type NativeUIBridge = {
4768
+ /** Opens a scope with every synchronous method the plugin's capabilities allow; capture it in a worklet. */
4769
+ createScope(): NativeUIScope;
4770
+ /** Runs a worklet on the UI runtime and resolves with what it returns, which must be serializable. */
4771
+ call<A extends NativeUIArgument[], R extends NativeSerializable | void>(
4772
+ worklet: (...args: A) => R,
4773
+ ...args: A
4774
+ ): NativeCancelablePromise<R>;
4775
+ /** Queues a worklet on the UI runtime. */
4776
+ run<A extends NativeUIArgument[]>(worklet: (...args: A) => void, ...args: A): void;
4777
+ /** Wraps a JS-thread listener so a worklet can call it, for example to wake JS only for the hook events that need it; it stops calling the listener once the plugin stops. */
4778
+ callback<A extends NativeSerializable[]>(listener: (...args: A) => void): NativeUICallback<A>;
4779
+ };
4780
+ /** A function a worklet calls on the UI runtime to hand serializable values to a listener on the JS thread, made with `callback`. */
4781
+ export type NativeUICallback<A extends NativeSerializable[] = NativeSerializable[]> = {
4782
+ call(...args: A): void;
4783
+ }['call'];
4784
+ /** The bridge methods a plugin may call from the UI runtime, synchronously and on the main thread. */
4785
+ export type NativeUIScope = {
4786
+ /** The Objective-C methods the scope allows; present on iOS. */
4787
+ readonly objc?: NativeObjCBridge;
4788
+ /** The Java methods the scope allows; present on Android. */
4789
+ readonly java?: NativeJavaBridge;
4790
+ /** The Java hook methods the scope allows; present on Android. Listeners run inline for calls on the main thread. */
4791
+ readonly hooks?: NativeJavaHooksBridge;
4792
+ /** Removes every hook the scope installed. */
4793
+ dispose(): void;
4794
+ };
4795
+ /** The loader's way to open UI-runtime scopes, offered on its raw `objc` namespace on iOS and `java` on Android. */
4796
+ export type NativeUIScopeFactory = {
4797
+ /** Opens a UI-runtime scope allowed only the listed method paths, such as `objc.invoke`. */
4798
+ createUIScope(paths: readonly string[]): NativeUIScope;
4799
+ };
4800
+ /** Limits and direction for a breadth-first `findViews` search; larger limits are clamped. */
2453
4801
  export type NativeViewSearchOptions = {
4802
+ /** How many levels to walk from the root. Defaults to 24, at most 128. */
2454
4803
  maxDepth?: number;
4804
+ /** How many views to visit. Defaults to 512, at most 8,192. */
2455
4805
  maxVisited?: number;
4806
+ /** How many matches to return. Defaults to 64, at most 256. */
2456
4807
  maxResults?: number;
4808
+ /** Matches only views attached to a window. */
2457
4809
  attachedOnly?: boolean;
4810
+ /** Skips the views beneath a match. */
2458
4811
  stopAtMatch?: boolean;
4812
+ /** `ancestors` walks up the superview chain instead of down. Defaults to `descendants`. */
2459
4813
  direction?: 'ancestors' | 'descendants';
2460
4814
  };
4815
+ /** One view in an `objc.snapshot` result, which lists views in breadth-first order. */
2461
4816
  export type NativeViewSnapshotNode = {
4817
+ /** A retained handle to the view; discard it after cell reuse or a channel change. */
2462
4818
  view: NativeObjectHandle;
4819
+ /** The index of the parent node in the result, or -1 for the root. */
2463
4820
  parent: number;
4821
+ /** Levels below the root, which is 0. */
2464
4822
  depth: number;
4823
+ /** The view's Objective-C class name. */
2465
4824
  className: string;
4825
+ /** The view's `frame` in its superview's coordinates, in points. */
2466
4826
  frame: NativeFabricFrame;
4827
+ /** The view's `text` when it has a string one, such as a `UILabel`'s, else `null`. */
2467
4828
  text: string | null;
4829
+ /** Whether the view is not hidden, has a non-zero alpha and is in a window. */
2468
4830
  visible: boolean;
2469
4831
  };
4832
+ /** Limits for `objc.snapshot`; larger values are clamped and non-integers rejected. */
2470
4833
  export type NativeViewSnapshotOptions = {
4834
+ /** How many levels below the root to read. Defaults to 8, at most 12. */
2471
4835
  maxDepth?: number;
4836
+ /** How many views to return. Defaults to 100, at most 256. */
2472
4837
  maxNodes?: number;
2473
4838
  };
2474
4839
  export type NavScrimComponent = React$1.ComponentType<NavScrimProps>;
@@ -2477,12 +4842,19 @@ export type NavScrimComponent = React$1.ComponentType<NavScrimProps>;
2477
4842
  * @see design/components/Navigator/native/NavScrim.ios.tsx
2478
4843
  */
2479
4844
  export type NavScrimProps = {};
4845
+ /** A screen's handle on Discord's React Navigation stack, as `useNavigation` returns it. */
2480
4846
  export type Navigation<T = any> = {
4847
+ /** Pushes a new screen for `route` with `params` onto the stack. */
2481
4848
  push: (route: string, params?: T) => void;
4849
+ /** Removes the top screen from the stack. */
2482
4850
  pop: () => void;
4851
+ /** Goes to `route`, reusing a screen already on the stack for it. */
2483
4852
  navigate: (route: string, params?: T) => void;
4853
+ /** Returns to the previous screen. */
2484
4854
  goBack: () => void;
4855
+ /** Updates the current screen's header options. */
2485
4856
  setOptions: (options: NavigationOptions) => void;
4857
+ /** Subscribes to a navigation event, such as `focus`; returns a function that unsubscribes. */
2486
4858
  addListener: (event: string, callback: DiscordFunction) => DiscordFunction<void>;
2487
4859
  };
2488
4860
  /**
@@ -2510,7 +4882,9 @@ export type NavigationContainerInnerProps = Omit<
2510
4882
  };
2511
4883
  /** The screen options accepted by {@link Navigation.setOptions}. */
2512
4884
  export type NavigationOptions = {
4885
+ /** The header title. */
2513
4886
  title?: string;
4887
+ /** Renders the element shown at the header's right edge. */
2514
4888
  headerRight?: DiscordFunction<React$1.ReactNode>;
2515
4889
  };
2516
4890
  /**
@@ -2597,6 +4971,16 @@ export type NewInlineNoticeProps = {
2597
4971
  title?: DesignTextProps['children'];
2598
4972
  type?: 'info' | 'warning' | (string & {});
2599
4973
  };
4974
+ /**
4975
+ * Design components newer than the Discord build the generated types describe, typed by hand from Discord 352's
4976
+ * sources. Regenerating the types from 352 or later makes these generated; then drop them here.
4977
+ */
4978
+ export type NewerDesignComponents = {
4979
+ /** Discord's search field: a `TextField` with a search icon, clear button and search return key. */
4980
+ SearchBar: DesignBarrelComponents['TextField'];
4981
+ /** Discord's status label, such as New or Beta, or custom text. */
4982
+ Badge: React$1.ComponentType<BadgeProps>;
4983
+ };
2600
4984
  export type NitroGem12LottieComponent = React$1.ComponentType<
2601
4985
  NitroGem12LottieProps & Record<string, unknown>
2602
4986
  >;
@@ -2687,6 +5071,13 @@ export type NitroGem9LottieComponent = React$1.ComponentType<
2687
5071
  export type NitroGem9LottieProps = Omit<LottieIconProps, 'ref'> & {
2688
5072
  ref?: LottieIconProps['ref'];
2689
5073
  };
5074
+ /** A notice row: it stores nothing, and shows `title` and `subtitle` as a message of its `tone`. */
5075
+ export type NoticeSchema = SettingCommon & {
5076
+ kind: 'notice';
5077
+ displayAs: 'notice';
5078
+ /** How the message reads: `info` plain, `warning` cautious, `danger` for something that cannot be undone. */
5079
+ tone: 'info' | 'warning' | 'danger';
5080
+ };
2690
5081
  export type NotificationsTabLottieComponent = React$1.ComponentType<
2691
5082
  NotificationsTabLottieProps & Record<string, unknown>
2692
5083
  >;
@@ -2748,17 +5139,27 @@ export type PlainTextExperimentProviderProps = {
2748
5139
  children?: React$1.ReactNode;
2749
5140
  enabled?: boolean;
2750
5141
  };
5142
+ /** What the addon manager passes to a plugin's `start`. */
2751
5143
  export type PluginContext = {
5144
+ /** The plugin's manifest. */
2752
5145
  readonly manifest: AddonManifest;
5146
+ /** The plugin's id, from its manifest. */
2753
5147
  readonly id: string;
5148
+ /** The host platform, or `undefined` when the loader reports none. */
2754
5149
  readonly platform?: NativePluginPlatform;
5150
+ /** The capabilities the manifest declares for this platform; `native` allows only these. */
2755
5151
  readonly capabilities: readonly NativePluginCapability[];
5152
+ /** The native bridge, scoped to the plugin's capabilities. */
2756
5153
  readonly native: NativePluginBridge;
5154
+ /** Releases the plugin's hooks, surfaces, handles and subscriptions; the addon manager calls it on stop, unload, reload or a failed start. */
2757
5155
  dispose(): void;
2758
5156
  };
2759
- /** An {@link Addon} whose instance is a {@link Plugin}. */
2760
- export type PluginEntity = Addon & {
2761
- instance: Plugin$1 | null;
5157
+ /** What a plugin's self-test found: whether the plugin works on this device, and why. */
5158
+ export type PluginSelfTestResult = {
5159
+ /** `true` when the plugin works on this device. */
5160
+ ok: boolean;
5161
+ /** A human-readable reason for the result. */
5162
+ detail: string;
2762
5163
  };
2763
5164
  /**
2764
5165
  * Props of `PostponeRender` (function). Exports: PostponeRender.
@@ -2812,6 +5213,8 @@ export type PressableOpacityProps = Omit<PressableBaseProps, 'activeOpacity' | '
2812
5213
  activeOpacity?: PressableBaseProps['activeOpacity'];
2813
5214
  ref?: PressableBaseProps['innerRef'];
2814
5215
  };
5216
+ /** A value that is not an object or a function. */
5217
+ export type Primitive = string | number | boolean | bigint | null | undefined;
2815
5218
  export type PromoSheetComponent = React$1.ComponentType<PromoSheetProps & Record<string, unknown>>;
2816
5219
  /**
2817
5220
  * Props of `PromoSheet` (function). Exports: PromoSheet.
@@ -2828,6 +5231,20 @@ export type PromoSheetProps = Omit<
2828
5231
  illustration?: React$1.ComponentProps<typeof RN.View>['children'];
2829
5232
  title?: DesignTextProps['children'];
2830
5233
  };
5234
+ /**
5235
+ * A manifest pushed by `ubd dev`. The CLI only checks the fields it reads; the device validates the
5236
+ * whole manifest the same way it validates one it loads, so a dev build is never held to the publish rules.
5237
+ */
5238
+ export type PushedManifest = {
5239
+ /** The addon's id, as in {@link AuthoredAddonManifest.id}. */
5240
+ id: string;
5241
+ /** The bundle's path relative to the manifest, as in {@link AuthoredAddonManifest.main}. */
5242
+ main: string;
5243
+ /** The SHA-512 of each bytecode build the push carries, by bytecode version; the CLI fills it in. */
5244
+ bytecode?: Record<string, string>;
5245
+ /** The images the build emitted beside the bundle, as in {@link AuthoredAddonManifest.assets}. */
5246
+ assets?: Record<string, AddonAsset>;
5247
+ };
2831
5248
  /**
2832
5249
  * Props of `RedesignBottomSheetTitleHeaderBase` (function). Exports: none.
2833
5250
  * @see design/components/Sheet/native/BottomSheetTitleHeader.native.tsx
@@ -2916,8 +5333,11 @@ export type SearchFieldProps = Omit<TextFieldProps, 'ref'> & {
2916
5333
  export type SegmentedControlComponent = React$1.ComponentType<SegmentedControlProps>;
2917
5334
  /** A tab of a segmented control, with the page it shows. */
2918
5335
  export type SegmentedControlItem = {
5336
+ /** A key unique among the control's tabs. */
2919
5337
  id: string;
5338
+ /** The text shown on the tab. */
2920
5339
  label: string;
5340
+ /** What `SegmentedControlPages` renders while this tab is selected. */
2921
5341
  page?: React$1.ReactNode;
2922
5342
  };
2923
5343
  /**
@@ -2979,16 +5399,25 @@ export type SegmentedControlProps = {
2979
5399
  };
2980
5400
  /** The state controller `useSegmentedControlState` returns, which drives a `SegmentedControl`. */
2981
5401
  export type SegmentedControlState = {
5402
+ /** The index of the selected tab in `items`. */
2982
5403
  activeIndex: number;
5404
+ /** The tabs, in display order. */
2983
5405
  items: SegmentedControlItem[];
5406
+ /** Selects the tab at `index`. */
2984
5407
  setActiveIndex: (index: number) => void;
2985
5408
  };
2986
5409
  /** The options `useSegmentedControlState` builds a {@link SegmentedControlState} from. */
2987
5410
  export type SegmentedControlStateOptions = {
5411
+ /** The tabs, in display order. */
2988
5412
  items: SegmentedControlItem[];
5413
+ /** The width of one page in points; Unbound passes the window width. */
2989
5414
  pageWidth: number;
5415
+ /** The index of the tab selected first. */
2990
5416
  defaultIndex?: number;
5417
+ /** Called with the new index when the selected page changes. */
2991
5418
  onPageChange?: (index: number) => void;
5419
+ /** Called with the index of the tab the user selects. */
5420
+ onSetActiveIndex?: (index: number) => void;
2992
5421
  };
2993
5422
  /** A semantic colour token from `Theme.colors`, which `useToken` resolves to a colour string. */
2994
5423
  export type SemanticColorToken = Readonly<Record<string, string | number | boolean>>;
@@ -3002,24 +5431,120 @@ export type ServerTabLottieComponent = React$1.ComponentType<
3002
5431
  export type ServerTabLottieProps = Omit<LottieIconProps, 'ref'> & {
3003
5432
  ref?: LottieIconProps['ref'];
3004
5433
  };
5434
+ /** One option of a `choice` setting. */
5435
+ export type SettingChoice = {
5436
+ /** The value stored when the option is picked. */
5437
+ const: string;
5438
+ /** The message key of the option's label. */
5439
+ title: string;
5440
+ /** The message key of the text under the option; only a radio group shows it. */
5441
+ subtitle?: string;
5442
+ };
5443
+ /** What every setting and section carries. Labels are message keys of the plugin's `i18n/en-US.json`. */
5444
+ export type SettingCommon = {
5445
+ /** The message key of the row's label or the section's title; only a hidden setting may omit it. */
5446
+ title?: string;
5447
+ /** The message key of the row's sub-label. */
5448
+ subtitle?: string;
5449
+ /** Stored and typed, but not drawn in the generated panel. */
5450
+ hidden?: boolean;
5451
+ /** Draws the row only while this holds. */
5452
+ visibleWhen?: SettingCondition;
5453
+ /** Draws the row disabled while this holds. */
5454
+ disabledWhen?: SettingCondition;
5455
+ /** Changing the setting shows a hint to restart Discord. */
5456
+ requiresRestart?: boolean;
5457
+ };
5458
+ /**
5459
+ * When a row shows or is enabled: a boolean setting's dot-separated key, or a predicate the build lifted
5460
+ * out of settings.ts into the plugin bundle, where the panel finds it by the setting's key.
5461
+ */
5462
+ export type SettingCondition =
5463
+ | string
5464
+ | {
5465
+ predicate: true;
5466
+ };
5467
+ /** A value one schema-declared setting holds. */
5468
+ export type SettingPrimitive = string | number | boolean;
5469
+ /** One schema-declared setting, by the primitive it stores. */
5470
+ export type SettingSchema = SettingCommon &
5471
+ (
5472
+ | {
5473
+ kind: 'boolean';
5474
+ displayAs: 'switch' | 'checkbox';
5475
+ default: boolean;
5476
+ }
5477
+ | {
5478
+ kind: 'number' | 'integer';
5479
+ displayAs: 'input' | 'slider' | 'stepper' | 'duration';
5480
+ /** A `duration` is in milliseconds. */
5481
+ default: number;
5482
+ minimum?: number;
5483
+ maximum?: number;
5484
+ /** The slider's or stepper's step; values must be a multiple of it. */
5485
+ multipleOf?: number;
5486
+ /** `duration`: the units offered. */
5487
+ units?: DurationUnit[];
5488
+ }
5489
+ | StringSettingSchema
5490
+ | ChoiceSettingSchema
5491
+ | {
5492
+ kind: 'array';
5493
+ displayAs: 'list' | 'checkboxes' | EntityDisplay;
5494
+ default: string[];
5495
+ /** What each item is: a string, or one of a choice's options. */
5496
+ of: Omit<StringSettingSchema, 'default'> | Omit<ChoiceSettingSchema, 'default'>;
5497
+ minItems?: number;
5498
+ maxItems?: number;
5499
+ }
5500
+ );
5501
+ /** A value any schema-declared setting holds. */
5502
+ export type SettingValue = SettingPrimitive | string[];
3005
5503
  /** A registered Unbound settings entry, mirroring Discord's `SETTING_RENDERER_CONFIG` route shape. */
3006
5504
  export type SettingsEntry = {
5505
+ /** Always `'route'`: the entry opens its own screen. */
3007
5506
  type: 'route';
5507
+ /** Unique id of the entry. Registering an existing key replaces that entry and logs a warning. */
3008
5508
  key: string;
5509
+ /** A hook returning the row and screen title. */
3009
5510
  useTitle: () => string;
5511
+ /** A hook returning whether Discord shows the row; omitted, it always shows. */
3010
5512
  usePredicate?: () => boolean;
5513
+ /** The key of the parent entry; `null` for an entry at the top of the settings overview. */
3011
5514
  parent: string | null;
5515
+ /** The label of the overview section the row belongs to; Unbound's own entries use `'Unbound'`. */
3012
5516
  section?: string;
5517
+ /** Keeps the route registered but leaves its row out of the settings overview. */
3013
5518
  excludeFromDisplay?: boolean;
5519
+ /** The icon drawn at the start of the row. */
3014
5520
  IconComponent?: React$1.ComponentType;
5521
+ /** A hook returning what the row shows at its end, such as a count. */
5522
+ useTrailing?: () => React$1.ReactNode;
5523
+ /** The screen the row opens. */
3015
5524
  screen: SettingsScreen;
3016
5525
  };
5526
+ /** A nested object: its settings, drawn as their own section titled by `title`. */
5527
+ export type SettingsGroupSchema = SettingCommon & {
5528
+ kind: 'section';
5529
+ displayAs: 'group' | 'collapsible';
5530
+ properties: Record<string, SettingSchema | StorelessSchema>;
5531
+ };
3017
5532
  /** A settings store, or a nested group of settings within one. */
3018
5533
  export type SettingsObject = {
3019
5534
  [key: string]: SettingsValue;
3020
5535
  };
5536
+ /** A plugin's settings schema, the JSON its settings.ts `defineSettings(...)` evaluates to at build time. */
5537
+ export type SettingsSchema = {
5538
+ /** Marks the schema's root. */
5539
+ kind: 'settings';
5540
+ /** The message key of the title of the section holding the top-level settings. */
5541
+ title?: string;
5542
+ /** The settings, buttons, notices and sections by key, in the order they are drawn. */
5543
+ properties: Record<string, SettingSchema | StorelessSchema | SettingsGroupSchema>;
5544
+ };
3021
5545
  /** The screen descriptor a settings route entry renders. */
3022
5546
  export type SettingsScreen = {
5547
+ /** The navigator route name; Unbound sets it to the entry's `key`. */
3023
5548
  route: string;
3024
5549
  /** Discord's navigator renders the screen with its own route props, so any component fits. */
3025
5550
  getComponent: () => React$1.ComponentType<never>;
@@ -3127,6 +5652,22 @@ export type SimpleActionSheetProps = {
3127
5652
  map?: unknown;
3128
5653
  };
3129
5654
  };
5655
+ /** The `simple-markdown` library Discord bundles, found by `parserFor`, `outputFor` and `defaultRules`. */
5656
+ export type SimpleMarkdownModule = {
5657
+ /** CommonMark-like rules for a whole document, unlike Discord's message rules. */
5658
+ defaultRules: MarkdownRules;
5659
+ /** Builds a parser from a rule set, such as `defaultRules` plus your own; `TNode` names the nodes they parse. */
5660
+ parserFor<TNode extends MarkdownNode = MarkdownNode>(
5661
+ rules: MarkdownRules,
5662
+ ): SimpleMarkdownParser<TNode>;
5663
+ /** Wraps a regex into a `match` that only matches inside inline content. */
5664
+ inlineRegex(regex: RegExp): MarkdownRule['match'];
5665
+ };
5666
+ /** Parses Markdown into nodes; `inline: false` parses blocks such as headings, lists, code and tables. */
5667
+ export type SimpleMarkdownParser<TNode extends MarkdownNode = MarkdownNode> = (
5668
+ source: string,
5669
+ state?: MarkdownState,
5670
+ ) => TNode[];
3130
5671
  export type SliderComponent = React$1.ComponentType<SliderProps & Record<string, unknown>>;
3131
5672
  /**
3132
5673
  * Props of `Slider` (function). Exports: Slider.
@@ -3252,6 +5793,42 @@ export type StickyWrapperProps = {
3252
5793
  pointerEvents?: React$1.ComponentProps<typeof RN.View>['pointerEvents'];
3253
5794
  style?: React$1.ComponentProps<typeof RN.View>['style'];
3254
5795
  };
5796
+ /** A row that stores nothing: a button or a notice. */
5797
+ export type StorelessSchema = ButtonSchema | NoticeSchema;
5798
+ /** How a `string` setting displays; each validates the text its own way. */
5799
+ export type StringDisplay =
5800
+ | 'input'
5801
+ | 'multiline'
5802
+ | 'secret'
5803
+ | 'url'
5804
+ | 'color'
5805
+ | 'image'
5806
+ | 'font'
5807
+ | 'emoji'
5808
+ | EntityDisplay;
5809
+ /** A string setting: the primitive `array` items can be too. */
5810
+ export type StringSettingSchema = {
5811
+ /** Marks a text setting. */
5812
+ kind: 'string';
5813
+ /** The row that edits the text, and the validation it applies. */
5814
+ displayAs: StringDisplay;
5815
+ /** The value before the user changes it. */
5816
+ default: string;
5817
+ /** The fewest characters the text may have. */
5818
+ minLength?: number;
5819
+ /** The most characters the text may have. */
5820
+ maxLength?: number;
5821
+ /** The message key of the text shown while the input is empty. */
5822
+ placeholder?: string;
5823
+ /** `color`: also takes an alpha channel, `#RRGGBBAA`. */
5824
+ alpha?: boolean;
5825
+ /** `color`: colors offered first. */
5826
+ presets?: string[];
5827
+ /** `color`: draws `presets` inline instead of a swatch row. */
5828
+ palette?: boolean;
5829
+ /** `image`: the largest file accepted, in bytes. */
5830
+ maxSize?: number;
5831
+ };
3255
5832
  /** A stylesheet spec: each key maps to a view, text, or image style. */
3256
5833
  export type StyleSheetSpec = Record<string, ViewStyle | TextStyle | ImageStyle>;
3257
5834
  /** A stylesheet spec, or a function producing one (Discord accepts both forms). */
@@ -3683,9 +6260,13 @@ export type TextVariant = LiteralUnion<
3683
6260
  export type TextWeight = 'normal' | 'medium' | 'semibold' | 'bold';
3684
6261
  /** A theme's semantic and raw colour definitions plus optional background. */
3685
6262
  export type Theme = {
6263
+ /** Overrides for Discord's semantic colours, keyed by name such as `BACKGROUND_BASE_LOWER`; malformed entries are dropped. */
3686
6264
  semantic: Record<PropertyKey, ThemeSemanticColor>;
6265
+ /** Overrides for Discord's raw palette colours, keyed by raw colour name. */
3687
6266
  raw: Record<PropertyKey, string>;
3688
- type: 'midnight' | 'darker' | 'light';
6267
+ /** The Discord base theme the bundle builds on: `light`, `dark` (Ash), `darker` (Dark) or `midnight` (Onyx); parsed as `darker` when absent or unknown. */
6268
+ type: 'light' | 'dark' | 'darker' | 'midnight';
6269
+ /** The chat background the theme recommends: an image `url`, a `blur` radius and an `opacity` from 0 to 1; dropped when `url` is not a string. */
3689
6270
  background?: {
3690
6271
  blur?: number;
3691
6272
  opacity?: number;
@@ -3721,11 +6302,6 @@ export type ThemeContextProviderRootThemeContextProviderProps = {
3721
6302
  secondaryColor?: unknown;
3722
6303
  theme?: unknown;
3723
6304
  };
3724
- /** An {@link Addon} whose instance is a {@link Theme}, tracking its registration state. */
3725
- export type ThemeEntity = Addon & {
3726
- registered: boolean;
3727
- instance: Theme | null;
3728
- };
3729
6305
  /**
3730
6306
  * Props of `ThemeProvider` (function). Exports: ThemeProvider.
3731
6307
  * @see module 4804 (no source path)
@@ -3736,8 +6312,11 @@ export type ThemeProviderProps = {
3736
6312
  };
3737
6313
  /** A single semantic colour definition in a {@link Theme}. */
3738
6314
  export type ThemeSemanticColor = {
6315
+ /** `color` uses `value` as is; `raw` names a raw colour, looked up in the theme's `raw` and then Discord's. */
3739
6316
  type: 'color' | 'raw';
6317
+ /** A colour string, or the name of a raw colour when `type` is `raw`. */
3740
6318
  value: string;
6319
+ /** An alpha from 0 to 1, clamped, that replaces a `#rrggbb` or `#rrggbbaa` colour's alpha; other formats ignore it. */
3741
6320
  opacity?: number;
3742
6321
  };
3743
6322
  /**
@@ -3747,11 +6326,17 @@ export type ThemeSemanticColor = {
3747
6326
  export type TitleProps = DesignTextProps;
3748
6327
  /** A button rendered inside a toast. */
3749
6328
  export type ToastButton = {
6329
+ /** The Discord button style. Defaults to `'primary'`. */
3750
6330
  variant?: 'primary' | 'secondary' | 'tertiary';
6331
+ /** The Discord button size. Defaults to `'sm'`. */
3751
6332
  size?: 'sm' | 'md' | 'lg' | 'xl' | '2xl';
6333
+ /** Which side of the label the icon sits on. Defaults to `'start'`. */
3752
6334
  iconPosition?: 'start' | 'end';
6335
+ /** The button's label. */
3753
6336
  content: string;
3754
- icon?: number;
6337
+ /** An asset id, an element such as `<Star />`, or an icon component such as `Star`, drawn beside the label. */
6338
+ icon?: IconInput;
6339
+ /** Runs when the button is tapped. The toast stays open; call `close` on its handle to dismiss it. */
3755
6340
  onPress: () => void;
3756
6341
  };
3757
6342
  export type ToastComponent = React$1.ComponentType<ToastProps>;
@@ -3797,18 +6382,28 @@ export type ToastEntityProps = {
3797
6382
  };
3798
6383
  /** A handle returned when showing a toast, used to update or close it. */
3799
6384
  export type ToastHandle = {
6385
+ /** Merges `options` into the shown toast. Does nothing once the toast is gone. */
3800
6386
  update: (options: Partial<ToastOptions>) => void;
6387
+ /** Plays the toast's exit animation, then removes it. */
3801
6388
  close: () => void;
3802
6389
  };
3803
6390
  /** Options accepted when showing a toast. */
3804
6391
  export type ToastOptions = {
6392
+ /** The bold first line, or a component rendered in its place. */
3805
6393
  title?: string | React$1.ComponentType;
6394
+ /** The body text under the title. */
3806
6395
  content?: string;
6396
+ /** Milliseconds before the toast closes itself; `0` keeps it until dismissed. Omitted, the user's toast duration setting. */
3807
6397
  duration?: number;
6398
+ /** Declared for callers, but the client does not call it yet. */
3808
6399
  onTimeout?: () => void;
3809
- icon?: string | number | ImageSourcePropType;
6400
+ /** An asset name, asset id, image source, element such as `<Star />`, or icon component such as `Star`; a name with no matching asset draws no image. */
6401
+ icon?: string | IconInput | ImageSourcePropType;
6402
+ /** Identifies the toast; showing another toast with the same id replaces it. Omitted, a random id. */
3810
6403
  id?: string;
6404
+ /** Buttons in a row under the content. */
3811
6405
  buttons?: ToastButton[];
6406
+ /** Tints an image icon with the theme's icon colour. Defaults to `true`; set `false` for a coloured image. An element or component draws its own colour. */
3812
6407
  tintedIcon?: boolean;
3813
6408
  };
3814
6409
  /**
@@ -3825,8 +6420,11 @@ export type ToastProps = {
3825
6420
  };
3826
6421
  /** State and actions of the toast store. */
3827
6422
  export type ToastStoreState = {
6423
+ /** Every toast on screen, keyed by toast id, including ones playing their exit animation. */
3828
6424
  toasts: Record<string, InternalToastOptions>;
6425
+ /** Shows a toast, replacing any with the same id, and stamps `date` when unset. */
3829
6426
  addToast: (options: InternalToastOptions) => ToastHandle;
6427
+ /** Merges `options` into the toast `id`. Does nothing when no such toast is on screen. */
3830
6428
  updateToastWithOptions: (id: string, options: Partial<InternalToastOptions>) => void;
3831
6429
  };
3832
6430
  export type ToggleIconButtonComponent = React$1.ComponentType<
@@ -3847,11 +6445,44 @@ export type ToggleIconButtonProps = {
3847
6445
  };
3848
6446
  /** `TransitionStates`: MOUNTED = 0, ENTERED = 1, YEETED = 2. */
3849
6447
  export type TransitionState = 'MOUNTED' | 'ENTERED' | 'YEETED';
3850
- /** A {@link DiscordAsset} extended with Unbound's icon-pack overrides. */
6448
+ /** A home screen icon the loader ships, listed in Discord's app icon picker. */
6449
+ export type UnboundAppIcon = {
6450
+ /** The icon's native id, which the loader switches to. */
6451
+ id: string;
6452
+ /** The picker row it shows as, when it replaces one of Discord's own icons. */
6453
+ pickerId?: string;
6454
+ /** The name shown under it in the picker. */
6455
+ name: string;
6456
+ /** The URI of its preview image. */
6457
+ image: string;
6458
+ };
6459
+ /** A {@link DiscordAsset} extended with Unbound's icon-pack overrides and the files of an asset a plugin registered. */
3851
6460
  export type UnboundAsset = DiscordAsset & {
3852
6461
  iconPackPath?: string;
3853
6462
  iconPackScale?: number;
6463
+ /** The URI of a registered plugin asset at each scale; set while it is registered. */
6464
+ unboundSources?: Record<number, string>;
6465
+ };
6466
+ /**
6467
+ * One installed face in the loader's font store.
6468
+ * @internal
6469
+ */
6470
+ type UnboundInstalledFont = {
6471
+ /** The store id: the face's PostScript name with only `[A-Za-z0-9._-]`. */
6472
+ id: string;
6473
+ family: string;
6474
+ postScriptName: string;
6475
+ fullName: string;
6476
+ weight: number;
6477
+ style: UnboundFontStyle;
6478
+ /** The file, relative to Unbound's `Fonts` folder. */
6479
+ file: string;
6480
+ /** The file's absolute path; `list()` adds it. */
6481
+ path?: string;
6482
+ source: UnboundFontSource;
3854
6483
  };
6484
+ /** A value the generator could not type with confidence, so a loose prop accepts anything for it. */
6485
+ export type UncertainValue = any;
3855
6486
  /**
3856
6487
  * Props of `VisualEffectView` (function). Exports: default.
3857
6488
  * @see modules/visual_effect_view/native/VisualEffectView.tsx
@@ -3937,11 +6568,16 @@ export type YouTabLottieComponent = React$1.ComponentType<
3937
6568
  export type YouTabLottieProps = Omit<LottieIconProps, 'ref'> & {
3938
6569
  ref?: LottieIconProps['ref'];
3939
6570
  };
3940
- /** The lifecycle and settings contract implemented by a plugin. */
6571
+ /** The named exports of a plugin's entry module the client reads: its lifecycle and its settings panel. */
3941
6572
  type Plugin$1 = {
3942
- start?(context?: PluginContext): void;
6573
+ /** Called when the plugin starts, inside its Addon scope, with its native bridge context; a rejected promise is recorded as a start failure. */
6574
+ start?(context?: PluginContext): void | Promise<void>;
6575
+ /** Called when the plugin stops; a returned promise is awaited, and the scope is disposed even if it throws. */
3943
6576
  stop?(): void | Promise<void>;
3944
- getSettingsPanel?(): React$1.ReactNode;
6577
+ /** The plugin's settings panel, rendered as `<SettingsPanel />` only while the plugin is running. */
6578
+ SettingsPanel?: React$1.ComponentType;
6579
+ /** Checks, without side effects, that the running plugin works on this device; the device matrix calls it after a restart. */
6580
+ selfTest?(): PluginSelfTestResult | Promise<PluginSelfTestResult>;
3945
6581
  };
3946
6582
 
3947
6583
  export { Plugin$1 as Plugin };