lunibee 0.3.1 → 0.3.3

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 (81) hide show
  1. package/dist/builders/attachment.d.ts +1 -0
  2. package/dist/builders/clone.d.ts +10 -0
  3. package/dist/builders/commands.d.ts +1 -1
  4. package/dist/builders/components.d.ts +24 -5
  5. package/dist/builders/index.js +64 -17
  6. package/dist/builders/index.js.map +10 -9
  7. package/dist/collection/index.d.ts +1 -0
  8. package/dist/collection/index.js +297 -19
  9. package/dist/collection/index.js.map +5 -4
  10. package/dist/collection/redis.d.ts +98 -0
  11. package/dist/core/collector.d.ts +8 -0
  12. package/dist/core/events.d.ts +1 -0
  13. package/dist/core/index.d.ts +3 -0
  14. package/dist/core/index.js +6242 -4733
  15. package/dist/core/index.js.map +47 -40
  16. package/dist/core/permissions.d.ts +3 -402
  17. package/dist/core/redis-cache.d.ts +85 -0
  18. package/dist/formatters/index.d.ts +5 -1
  19. package/dist/formatters/index.js +7 -3
  20. package/dist/formatters/index.js.map +3 -3
  21. package/dist/handlers/index.js +11 -2
  22. package/dist/handlers/index.js.map +3 -3
  23. package/dist/index.js +8688 -6136
  24. package/dist/index.js.map +67 -59
  25. package/dist/managers/application.d.ts +10 -6
  26. package/dist/managers/base.d.ts +11 -1
  27. package/dist/managers/guild.d.ts +3 -1
  28. package/dist/managers/index.d.ts +6 -1
  29. package/dist/managers/index.js +383 -109
  30. package/dist/managers/index.js.map +20 -23
  31. package/dist/managers/member.d.ts +3 -1
  32. package/dist/managers/message.d.ts +13 -4
  33. package/dist/managers/thread.d.ts +3 -3
  34. package/dist/rest/decoder.d.ts +2 -0
  35. package/dist/rest/errors.d.ts +5 -2
  36. package/dist/rest/headers.d.ts +31 -0
  37. package/dist/rest/identity.d.ts +31 -0
  38. package/dist/rest/index.d.ts +97 -6
  39. package/dist/rest/index.js +1355 -220
  40. package/dist/rest/index.js.map +16 -13
  41. package/dist/rest/limiter.d.ts +75 -10
  42. package/dist/rest/redis.d.ts +103 -22
  43. package/dist/rest/scheduler.d.ts +13 -0
  44. package/dist/rest/store.d.ts +135 -12
  45. package/dist/rest/telemetry.d.ts +151 -0
  46. package/dist/rest/webhook.d.ts +18 -6
  47. package/dist/sharding/bus.d.ts +4 -2
  48. package/dist/sharding/cluster.d.ts +29 -1
  49. package/dist/sharding/health.d.ts +1 -1
  50. package/dist/sharding/host.d.ts +13 -2
  51. package/dist/sharding/identify.d.ts +2 -0
  52. package/dist/sharding/index.d.ts +8 -0
  53. package/dist/sharding/index.js +579 -65
  54. package/dist/sharding/index.js.map +17 -15
  55. package/dist/sharding/leader.d.ts +34 -0
  56. package/dist/sharding/remote.d.ts +36 -2
  57. package/dist/sharding/supervisor.d.ts +1 -1
  58. package/dist/sharding/thread.d.ts +30 -0
  59. package/dist/sharding/transport.d.ts +6 -5
  60. package/dist/sharding/worker.d.ts +11 -1
  61. package/dist/structures/base.d.ts +16 -5
  62. package/dist/structures/index.d.ts +1 -1
  63. package/dist/structures/index.js +57 -91
  64. package/dist/structures/index.js.map +10 -18
  65. package/dist/structures/options.d.ts +3 -2
  66. package/dist/structures/permissions.d.ts +409 -0
  67. package/dist/structures/resources.d.ts +4 -1
  68. package/dist/types/gateway.d.ts +4 -0
  69. package/dist/types/index.d.ts +14 -4
  70. package/dist/types/index.js.map +3 -3
  71. package/dist/utils/args.d.ts +3 -1
  72. package/dist/utils/index.d.ts +6 -1
  73. package/dist/utils/index.js +17 -10
  74. package/dist/utils/index.js.map +4 -4
  75. package/dist/voice/index.d.ts +7 -1
  76. package/dist/voice/index.js +33 -10
  77. package/dist/voice/index.js.map +3 -3
  78. package/dist/ws/index.d.ts +2 -0
  79. package/dist/ws/index.js +32 -4
  80. package/dist/ws/index.js.map +5 -5
  81. package/package.json +21 -17
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Leadership between several coordinators, so a standby `ClusterManager` can
3
+ * take over when the active one dies. Only the holder of the lock runs
4
+ * clusters; see `ClusterManagerOptions.leader`.
5
+ */
6
+ export interface LeaderLock {
7
+ /**
8
+ * Takes the lock for `ttlMs`, or extends it when this process already
9
+ * holds it. Resolves `true` while this process is the leader, `false` when
10
+ * another one holds it. A rejection counts as "unknown".
11
+ */
12
+ acquire(ttlMs: number): Promise<boolean>;
13
+ /** Gives the lock up if this process holds it. */
14
+ release(): Promise<void>;
15
+ }
16
+ /** The part of a Redis client the lock uses. `Bun.RedisClient` works as it is; for ioredis pass `{ send: (c, a) => redis.call(c, ...a) }`. */
17
+ export interface LeaderRedisClient {
18
+ send(command: string, args: string[]): Promise<unknown>;
19
+ }
20
+ /** Options for {@link RedisLeaderLock}. */
21
+ export interface RedisLeaderLockOptions {
22
+ client: LeaderRedisClient;
23
+ /** The key every coordinator of one deployment shares. Default `lunibee:cluster:leader`. */
24
+ key?: string;
25
+ /** This coordinator's identity in the key. Default: a random UUID. Must differ between coordinators. */
26
+ token?: string;
27
+ }
28
+ /** A {@link LeaderLock} on one Redis key, with an expiry so a dead leader's lock lapses on its own. */
29
+ export declare class RedisLeaderLock implements LeaderLock {
30
+ #private;
31
+ constructor(options: RedisLeaderLockOptions);
32
+ acquire(ttlMs: number): Promise<boolean>;
33
+ release(): Promise<void>;
34
+ }
@@ -40,12 +40,36 @@ export interface RemoteOptions {
40
40
  * a shard never runs in two places. Default 15,000.
41
41
  */
42
42
  lease?: number;
43
- /** Milliseconds a new connection has to authenticate before it is closed. Default 10,000. */
43
+ /** Milliseconds a new connection has to authenticate before it is closed. Default 3,000. */
44
44
  helloTimeout?: number;
45
- /** Most connections that may be waiting to authenticate at once; more are closed. Default 16. */
45
+ /**
46
+ * Most connections that may be waiting to authenticate at once. When full,
47
+ * the one that has waited longest is closed to make room: a host answers
48
+ * the challenge within a round trip, a connection that holds a slot idle
49
+ * does not. Default 16.
50
+ */
46
51
  maxUnauthenticated?: number;
52
+ /** The same limit for one client address (see `clientAddress`). Default 4. */
53
+ maxUnauthenticatedPerAddress?: number;
54
+ /** New connections one client address may open per second; more are refused. Default 10. */
55
+ connectionsPerSecond?: number;
56
+ /**
57
+ * The client address the per-address limits count by. Default: the peer
58
+ * address of the TCP connection. Behind a TLS proxy every peer is the
59
+ * proxy, so return the client address the proxy forwards (only from a
60
+ * header your proxy sets and overwrites).
61
+ */
62
+ clientAddress?: (request: Request, peer: string | undefined) => string;
47
63
  /** Also run clusters on the coordinator's own machine. Default false: clusters run on the hosts only. */
48
64
  local?: boolean;
65
+ /**
66
+ * When a host is lost, restart its clusters on the connected host (or
67
+ * `local`) running the fewest, once the lost host has certainly fenced
68
+ * itself (two leases after the coordinator dropped it). They stay there
69
+ * when the host comes back. Default true; `false` restarts them on the
70
+ * same host only, so they wait for it.
71
+ */
72
+ moveClusters?: boolean;
49
73
  }
50
74
  /** A host as the coordinator sees it. */
51
75
  export interface HostStatus {
@@ -99,6 +123,16 @@ export declare class RemoteHosts {
99
123
  get port(): number | undefined;
100
124
  /** Host IDs that are connected now, sorted. */
101
125
  connected(): string[];
126
+ /** Whether `hostId` is connected now. */
127
+ isConnected(hostId: string): boolean;
128
+ /**
129
+ * When workers that ran on a lost host are certainly gone (epoch ms), or 0
130
+ * for a host that is connected or was never dropped. The host fences
131
+ * itself one lease after it last heard from the coordinator, checking
132
+ * every third of a lease; the coordinator sends nothing after the drop,
133
+ * and two leases leave room for the kill itself.
134
+ */
135
+ fencedAt(hostId: string): number;
102
136
  /** Opens the listener. Safe to call twice. */
103
137
  start(): void;
104
138
  /** Closes the listener and every host connection. */
@@ -4,7 +4,7 @@ export interface SupervisorOptions {
4
4
  restartDelay?: number;
5
5
  /** Each further crash in the window multiplies the delay by this (default 1: a fixed delay). */
6
6
  backoff?: number;
7
- /** The longest delay (default 5 minutes). */
7
+ /** The longest delay, jitter included (default 5 minutes). */
8
8
  maxDelay?: number;
9
9
  /** Random spread added to each delay, as a fraction of it (0-1, default 0). */
10
10
  jitter?: number;
@@ -0,0 +1,30 @@
1
+ import type { ChildProcess } from "node:child_process";
2
+ import { type ResourceLimits } from "node:worker_threads";
3
+ /** Options for {@link threadFork}. */
4
+ export interface ThreadForkOptions {
5
+ /** Heap limits for each cluster thread (`worker_threads` `resourceLimits`). */
6
+ resourceLimits?: ResourceLimits;
7
+ }
8
+ /**
9
+ * Runs each cluster as a worker thread of the manager's process instead of a
10
+ * forked process: pass it as `ClusterManager`'s `fork`. Threads start faster
11
+ * and use less memory; a crash that takes the process down (an out-of-memory
12
+ * abort, a native fault) takes every cluster with it. The worker script is the
13
+ * same: `ShardManager`, `ShardBus` and `ClusterWorker` find the parent through
14
+ * `parentPort`.
15
+ */
16
+ export declare function threadFork(options?: ThreadForkOptions): (script: string, env: Record<string, string | undefined>) => ChildProcess;
17
+ /** The parent link of a cluster thread: the part of `process` a worker uses. */
18
+ export interface ThreadEndpoint {
19
+ send(message: unknown): boolean;
20
+ on(event: string, listener: (...args: never[]) => void): ThreadEndpoint;
21
+ off(event: string, listener: (...args: never[]) => void): ThreadEndpoint;
22
+ }
23
+ /** The parent link when this code runs in a cluster thread started by {@link threadFork}, otherwise `undefined`. */
24
+ export declare function threadEndpoint(): ThreadEndpoint | undefined;
25
+ /** Wraps a message port as a worker endpoint. @internal */
26
+ export declare function portEndpoint(port: {
27
+ postMessage(message: unknown): void;
28
+ on(event: "message", listener: (frame: unknown) => void): unknown;
29
+ off(event: "message", listener: (frame: unknown) => void): unknown;
30
+ }): ThreadEndpoint;
@@ -28,14 +28,15 @@ export interface IpcEndpoint {
28
28
  on(event: "message", listener: (message: unknown) => void): unknown;
29
29
  off(event: "message", listener: (message: unknown) => void): unknown;
30
30
  }
31
- /**
32
- * Forked clusters: a worker `send()`s to its parent, and the parent
33
- * ({@link ClusterManager}) relays to every other worker. Selected
34
- * automatically in a worker forked by `ClusterManager`.
35
- */
36
31
  export declare class IpcTransport implements ShardBusTransport {
37
32
  #private;
38
33
  constructor(endpoint?: IpcEndpoint);
34
+ /**
35
+ * Sends to the parent, which relays to other clusters, and delivers to the
36
+ * other buses in this process: the parent never sends a message back to the
37
+ * cluster it came from, so without this a shard could not reach a shard in
38
+ * its own worker. Each bus drops what is not addressed to it.
39
+ */
39
40
  post(message: ShardMessage): void;
40
41
  onMessage(listener: (message: ShardMessage) => void): void;
41
42
  onPeerDown(listener: (shardIds: readonly number[]) => void): void;
@@ -27,7 +27,17 @@ export declare class ClusterWorker {
27
27
  /** Forgets the process-wide worker (tests). */
28
28
  static reset(): void;
29
29
  readonly context: ClusterContext;
30
- constructor(context: ClusterContext, endpoint?: WorkerEndpoint);
30
+ constructor(context: ClusterContext, endpoint?: WorkerEndpoint, options?: {
31
+ /**
32
+ * Exit when the parent's IPC channel closes. Without a parent
33
+ * nothing coordinates IDENTIFY or fences this process, and its
34
+ * Gateway sessions would keep running beside a replacement.
35
+ * Default: true for the real process, false for an injected endpoint.
36
+ */
37
+ exitOnParentLoss?: boolean;
38
+ /** Replaces `process.exit`; for tests. */
39
+ exit?: (code: number) => void;
40
+ });
31
41
  /** The gate to use when the parent coordinates IDENTIFY, otherwise `undefined`. */
32
42
  get identifyGate(): IdentifyGate | undefined;
33
43
  /** Tells the parent every shard of this process finished its handshake. */
@@ -11,6 +11,7 @@ export declare class BaseStructure {
11
11
  /** Returns the timestamp this snowflake was created at. */
12
12
  get createdAt(): Date;
13
13
  }
14
+ /** What a structure uses to act on Discord (send, edit, fetch, compute permissions). `Client` supplies it; tests can supply their own. */
14
15
  export interface ResourceContext {
15
16
  sendMessage(channelId: string, options: MessageCreateOptions): Promise<import("./index.js").Message>;
16
17
  editMessage(channelId: string, messageId: string, options: MessageEditOptions): Promise<import("./index.js").Message>;
@@ -29,7 +30,9 @@ export interface ResourceContext {
29
30
  * (with overwrites) when a channel ID is given. Null when the guild (or
30
31
  * channel) is not cached.
31
32
  */
32
- memberPermissions?(guildId: string, memberId: string, roleIds: readonly string[], channelId?: string, timedOutUntil?: Date | null): import("@lunibee/core").PermissionSet | null;
33
+ /** The cached channel, when the client has a complete one (not a partial placeholder). */
34
+ cachedChannel?(channelId: string): Channel | undefined;
35
+ memberPermissions?(guildId: string, memberId: string, roleIds: readonly string[], channelId?: string, timedOutUntil?: Date | null): import("./permissions.js").PermissionSet | null;
33
36
  kickMember?(guildId: string, userId: string, reason?: string): Promise<void>;
34
37
  banMember?(guildId: string, userId: string, options?: {
35
38
  reason?: string;
@@ -49,7 +52,7 @@ export interface ResourceContext {
49
52
  * Permissions to change on one overwrite: `true` allows, `false` denies,
50
53
  * `null` goes back to inheriting. Permissions not named keep their state.
51
54
  */
52
- export type PermissionOverwriteChanges = Partial<Record<import("@lunibee/core").PermissionName, boolean | null>>;
55
+ export type PermissionOverwriteChanges = Partial<Record<import("./permissions.js").PermissionName, boolean | null>>;
53
56
  export declare const CDN_BASE = "https://cdn.discordapp.com";
54
57
  /** Options for CDN image URLs. */
55
58
  export interface ImageURLOptions {
@@ -94,8 +97,16 @@ export declare class Channel extends BaseStructure {
94
97
  position?: number;
95
98
  /** Role and member permission overwrites (empty for DMs and when not provided). */
96
99
  permissionOverwrites: import("@lunibee/types").APIOverwrite[];
97
- /** Creates a channel structure from Discord channel data. */
98
- constructor(data: import("@lunibee/types").APIChannel, context?: ResourceContext);
100
+ /**
101
+ * A placeholder built from a message's `channel_id`, not from channel
102
+ * data: its `type`, `name`, `parentId` and `permissionOverwrites` are not
103
+ * the real channel's, so nothing may decide access from them.
104
+ */
105
+ partial: boolean;
106
+ /** Creates a channel structure from Discord channel data. `options.partial` marks a placeholder. */
107
+ constructor(data: import("@lunibee/types").APIChannel, context?: ResourceContext, options?: {
108
+ partial?: boolean;
109
+ });
99
110
  /** Sends a message to this channel. @param options Message payload. @returns The created message. @throws {Error} If the channel is not attached to a client. */
100
111
  send(options: MessageCreateOptions): Promise<import("./index.js").Message>;
101
112
  /** Edits this channel. @param options Channel fields to change. @returns The updated channel. @throws {Error} If the channel is not attached to a client. */
@@ -125,7 +136,7 @@ export declare class Channel extends BaseStructure {
125
136
  get kind(): ChannelKind | UnknownChannelKind;
126
137
  /**
127
138
  * Whether this channel is one of `kinds`, narrowing its type to match.
128
- * @example if (channel.is("text", "announcement")) await channel.send("hi");
139
+ * @example if (channel.is("text", "announcement")) await channel.send({ content: "hi" });
129
140
  */
130
141
  is<K extends ChannelKind | UnknownChannelKind>(...kinds: K[]): this is ChannelOfKind<K>;
131
142
  /**
@@ -116,4 +116,4 @@ export * from "./interactions.js";
116
116
  export { Embed } from "./embed.js";
117
117
  export { AuditLog, AuditLogEntry, type AuditLogAutoModInfo, type AuditLogInfo, type AuditLogInfoByType, type AuditLogOverwriteInfo, type AuditLogQuery, } from "./audit-log.js";
118
118
  export { Sticker, stickerURL } from "./sticker.js";
119
- export { PermissionsBitField } from "@lunibee/core";
119
+ export { Permission, Permissions, PermissionFlagsBits, PermissionSet, PermissionsBitField, PermissionOverwriteEnum, computePermissions, type PermissionContext, type PermissionOverwrite, type PermissionRole, type PermissionName, type PermissionResolvable, } from "./permissions.js";
@@ -162,8 +162,9 @@ class Channel extends BaseStructure {
162
162
  rateLimitPerUser;
163
163
  position;
164
164
  permissionOverwrites;
165
+ partial;
165
166
  #context;
166
- constructor(data, context) {
167
+ constructor(data, context, options) {
167
168
  super(data.id);
168
169
  if (!Number.isInteger(data.type) || data.type < 0)
169
170
  throw new RangeError("A Discord channel requires a valid channel type.");
@@ -176,6 +177,7 @@ class Channel extends BaseStructure {
176
177
  this.rateLimitPerUser = data.rate_limit_per_user;
177
178
  this.position = data.position;
178
179
  this.permissionOverwrites = (data.permission_overwrites ?? []).map((overwrite) => ({ ...overwrite }));
180
+ this.partial = options?.partial ?? false;
179
181
  this.#context = context;
180
182
  }
181
183
  send(options) {
@@ -366,7 +368,12 @@ class Guild extends BaseStructure {
366
368
  }
367
369
  }
368
370
 
369
- // packages/core/src/permissions.ts
371
+ // packages/structures/src/permissions.ts
372
+ var PermissionOverwriteEnum;
373
+ ((PermissionOverwriteEnum) => {
374
+ PermissionOverwriteEnum[PermissionOverwriteEnum["Role"] = 0] = "Role";
375
+ PermissionOverwriteEnum[PermissionOverwriteEnum["Member"] = 1] = "Member";
376
+ })(PermissionOverwriteEnum ||= {});
370
377
  var Permission = {
371
378
  createInstantInvite: 1n << 0n,
372
379
  kickMembers: 1n << 1n,
@@ -648,6 +655,15 @@ class PermissionSet {
648
655
  get useExternalApps() {
649
656
  return (this.bitfield & Permission.useExternalApps) === Permission.useExternalApps;
650
657
  }
658
+ get setVoiceChannelStatus() {
659
+ return (this.bitfield & Permission.setVoiceChannelStatus) === Permission.setVoiceChannelStatus;
660
+ }
661
+ get pinMessages() {
662
+ return (this.bitfield & Permission.pinMessages) === Permission.pinMessages;
663
+ }
664
+ get bypassSlowmode() {
665
+ return (this.bitfield & Permission.bypassSlowmode) === Permission.bypassSlowmode;
666
+ }
651
667
  has(...permissions) {
652
668
  if (permissions.length === 1) {
653
669
  const p = permissions[0];
@@ -750,94 +766,38 @@ class PermissionsBitField extends PermissionSet {
750
766
  }
751
767
  }
752
768
  var ALL_PERMISSIONS = Object.values(Permission).reduce((bits, bit) => bits | bit, 0n);
753
- // packages/builders/src/components.ts
754
- var IS_COMPONENTS_V2 = 1 << 15;
755
- // packages/builders/src/commands.ts
756
- var MAX_SAFE = Number.MAX_SAFE_INTEGER;
757
- // packages/utils/src/args.ts
758
- var TRUE_WORDS = new Set([
759
- "true",
760
- "yes",
761
- "y",
762
- "on",
763
- "1",
764
- "enable",
765
- "enabled"
766
- ]);
767
- var FALSE_WORDS = new Set([
768
- "false",
769
- "no",
770
- "n",
771
- "off",
772
- "0",
773
- "disable",
774
- "disabled"
775
- ]);
776
- // packages/collection/src/index.ts
777
- var mapGet = Map.prototype.get;
778
- var mapHas = Map.prototype.has;
779
- // packages/rest/package.json
780
- var package_default = {
781
- name: "@lunibee/rest",
782
- version: "0.3.1",
783
- type: "module",
784
- module: "./src/index.ts",
785
- types: "./src/index.ts",
786
- exports: {
787
- ".": "./src/index.ts"
788
- },
789
- dependencies: {
790
- "@lunibee/types": "workspace:*"
791
- }
792
- };
793
-
794
- // packages/rest/src/index.ts
795
- var LIBRARY_VERSION = package_default.version;
796
- var LIBRARY_URL = "https://github.com/Ekretos/lunibee";
797
- var USER_AGENT = `DiscordBot (${LIBRARY_URL}, ${LIBRARY_VERSION})`;
798
- var REQUEST_DATA_KEYS = new Set([
799
- "body",
800
- "files",
801
- "query",
802
- "headers",
803
- "reason",
804
- "auth",
805
- "signal"
806
- ]);
807
- // packages/managers/src/index.ts
808
- var BULK_DELETE_MAX_AGE_MS = 14 * 24 * 60 * 60000;
809
-
810
- // packages/ws/src/close-codes.ts
811
- var GatewayCloseCodes = {
812
- UnknownError: 4000,
813
- UnknownOpcode: 4001,
814
- DecodeError: 4002,
815
- NotAuthenticated: 4003,
816
- AuthenticationFailed: 4004,
817
- AlreadyAuthenticated: 4005,
818
- InvalidSeq: 4007,
819
- RateLimited: 4008,
820
- SessionTimedOut: 4009,
821
- InvalidShard: 4010,
822
- ShardingRequired: 4011,
823
- InvalidAPIVersion: 4012,
824
- InvalidIntents: 4013,
825
- DisallowedIntents: 4014
826
- };
769
+ var bits = (value) => new PermissionSet(value).bitfield;
770
+ function computePermissions(context) {
771
+ if (context.ownerId !== undefined && context.ownerId === context.memberId)
772
+ return new PermissionSet(ALL_PERMISSIONS);
773
+ const roles = new Map(context.roles.map((role) => [role.id, role]));
774
+ let base = bits(roles.get(context.guildId)?.permissions ?? 0n);
775
+ for (const id of context.memberRoleIds)
776
+ base |= bits(roles.get(id)?.permissions ?? 0n);
777
+ if (base & Permission.administrator)
778
+ return new PermissionSet(ALL_PERMISSIONS);
779
+ const overwrites = context.overwrites ?? [];
780
+ const everyone = overwrites.find((o) => o.id === context.guildId);
781
+ if (everyone)
782
+ base = base & ~bits(everyone.deny) | bits(everyone.allow);
783
+ const memberRoles = new Set(context.memberRoleIds);
784
+ let allow = 0n;
785
+ let deny = 0n;
786
+ for (const overwrite of overwrites)
787
+ if (overwrite.type === 0 /* Role */ && overwrite.id !== context.guildId && memberRoles.has(overwrite.id)) {
788
+ allow |= bits(overwrite.allow);
789
+ deny |= bits(overwrite.deny);
790
+ }
791
+ base = base & ~deny | allow;
792
+ const member = overwrites.find((o) => o.type === 1 /* Member */ && o.id === context.memberId);
793
+ if (member)
794
+ base = base & ~bits(member.deny) | bits(member.allow);
795
+ const until = context.timedOutUntil instanceof Date ? context.timedOutUntil.getTime() : context.timedOutUntil ?? 0;
796
+ if (until > Date.now())
797
+ base &= Permission.viewChannel | Permission.readMessageHistory;
798
+ return new PermissionSet(base);
799
+ }
827
800
 
828
- // packages/ws/src/reconnect.ts
829
- var FATAL_CLOSE_CODES = [
830
- GatewayCloseCodes.AuthenticationFailed,
831
- GatewayCloseCodes.InvalidShard,
832
- GatewayCloseCodes.ShardingRequired,
833
- GatewayCloseCodes.InvalidAPIVersion,
834
- GatewayCloseCodes.InvalidIntents,
835
- GatewayCloseCodes.DisallowedIntents
836
- ];
837
- var IDENTIFY_CLOSE_CODES = [
838
- GatewayCloseCodes.InvalidSeq,
839
- GatewayCloseCodes.SessionTimedOut
840
- ];
841
801
  // packages/structures/src/resources.ts
842
802
  function toDateOrNull(value) {
843
803
  if (!value)
@@ -2243,7 +2203,7 @@ class Message extends BaseStructure {
2243
2203
  user: data.member.user ?? data.author,
2244
2204
  guild_id: data.guild_id
2245
2205
  }, context) : null;
2246
- this.channel = new Channel({ id: data.channel_id, type: 0, guild_id: data.guild_id }, context);
2206
+ this.channel = context?.cachedChannel?.(data.channel_id) ?? new Channel({ id: data.channel_id, type: 0, guild_id: data.guild_id }, context, { partial: true });
2247
2207
  }
2248
2208
  get embedsSuppressed() {
2249
2209
  return (this.flags & 4) !== 0;
@@ -2400,6 +2360,11 @@ export {
2400
2360
  NewsChannel,
2401
2361
  OnboardingPrompt,
2402
2362
  OnboardingPromptOption,
2363
+ Permission,
2364
+ PermissionFlagsBits,
2365
+ PermissionOverwriteEnum,
2366
+ PermissionSet,
2367
+ Permissions,
2403
2368
  PermissionsBitField,
2404
2369
  Role,
2405
2370
  StageChannel,
@@ -2412,9 +2377,10 @@ export {
2412
2377
  WebhookEnum,
2413
2378
  WelcomeScreenChannel,
2414
2379
  cdnURL,
2380
+ computePermissions,
2415
2381
  createChannel,
2416
2382
  createInteraction,
2417
2383
  stickerURL
2418
2384
  };
2419
2385
 
2420
- //# debugId=1F2A9DC9E180B64C64756E2164756E21
2386
+ //# debugId=AAE5FFB306F1F13364756E2164756E21