lunibee 0.3.0 → 0.3.2

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 (87) 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/embed.d.ts +1 -0
  6. package/dist/builders/index.js +68 -17
  7. package/dist/builders/index.js.map +10 -9
  8. package/dist/collection/index.d.ts +1 -0
  9. package/dist/collection/index.js +297 -19
  10. package/dist/collection/index.js.map +5 -4
  11. package/dist/collection/redis.d.ts +98 -0
  12. package/dist/core/collector.d.ts +8 -0
  13. package/dist/core/events.d.ts +1 -0
  14. package/dist/core/index.d.ts +3 -0
  15. package/dist/core/index.js +6252 -4704
  16. package/dist/core/index.js.map +47 -40
  17. package/dist/core/permissions.d.ts +3 -402
  18. package/dist/core/redis-cache.d.ts +85 -0
  19. package/dist/formatters/index.d.ts +5 -1
  20. package/dist/formatters/index.js +7 -3
  21. package/dist/formatters/index.js.map +3 -3
  22. package/dist/handlers/index.js +11 -2
  23. package/dist/handlers/index.js.map +3 -3
  24. package/dist/index.js +10481 -6148
  25. package/dist/index.js.map +70 -56
  26. package/dist/managers/application.d.ts +10 -6
  27. package/dist/managers/base.d.ts +4 -1
  28. package/dist/managers/guild.d.ts +3 -1
  29. package/dist/managers/index.d.ts +6 -1
  30. package/dist/managers/index.js +365 -103
  31. package/dist/managers/index.js.map +19 -22
  32. package/dist/managers/member.d.ts +3 -1
  33. package/dist/managers/message.d.ts +13 -4
  34. package/dist/managers/thread.d.ts +3 -3
  35. package/dist/rest/decoder.d.ts +2 -0
  36. package/dist/rest/errors.d.ts +13 -2
  37. package/dist/rest/headers.d.ts +31 -0
  38. package/dist/rest/identity.d.ts +31 -0
  39. package/dist/rest/index.d.ts +99 -6
  40. package/dist/rest/index.js +1412 -231
  41. package/dist/rest/index.js.map +16 -13
  42. package/dist/rest/limiter.d.ts +75 -10
  43. package/dist/rest/redis.d.ts +103 -22
  44. package/dist/rest/scheduler.d.ts +13 -0
  45. package/dist/rest/store.d.ts +135 -12
  46. package/dist/rest/telemetry.d.ts +151 -0
  47. package/dist/rest/transport.d.ts +9 -0
  48. package/dist/rest/webhook.d.ts +18 -6
  49. package/dist/sharding/bus.d.ts +12 -2
  50. package/dist/sharding/cluster.d.ts +225 -15
  51. package/dist/sharding/context.d.ts +41 -0
  52. package/dist/sharding/gateway-bot.d.ts +20 -0
  53. package/dist/sharding/health.d.ts +94 -0
  54. package/dist/sharding/host.d.ts +76 -0
  55. package/dist/sharding/identify.d.ts +64 -0
  56. package/dist/sharding/index.d.ts +62 -12
  57. package/dist/sharding/index.js +2459 -202
  58. package/dist/sharding/index.js.map +21 -13
  59. package/dist/sharding/protocol.d.ts +47 -0
  60. package/dist/sharding/remote-protocol.d.ts +100 -0
  61. package/dist/sharding/remote.d.ts +134 -0
  62. package/dist/sharding/requests.d.ts +54 -0
  63. package/dist/sharding/supervisor.d.ts +1 -1
  64. package/dist/sharding/transport.d.ts +6 -5
  65. package/dist/sharding/worker.d.ts +55 -0
  66. package/dist/structures/base.d.ts +16 -5
  67. package/dist/structures/index.d.ts +1 -1
  68. package/dist/structures/index.js +57 -91
  69. package/dist/structures/index.js.map +10 -18
  70. package/dist/structures/options.d.ts +3 -2
  71. package/dist/structures/permissions.d.ts +409 -0
  72. package/dist/structures/resources.d.ts +4 -1
  73. package/dist/types/gateway.d.ts +7 -0
  74. package/dist/types/index.d.ts +14 -4
  75. package/dist/types/index.js.map +3 -3
  76. package/dist/utils/args.d.ts +3 -1
  77. package/dist/utils/index.d.ts +6 -1
  78. package/dist/utils/index.js +17 -10
  79. package/dist/utils/index.js.map +4 -4
  80. package/dist/voice/index.d.ts +7 -1
  81. package/dist/voice/index.js +33 -10
  82. package/dist/voice/index.js.map +3 -3
  83. package/dist/ws/index.d.ts +3 -1
  84. package/dist/ws/index.js +33 -5
  85. package/dist/ws/index.js.map +6 -6
  86. package/dist/ws/send-budget.d.ts +1 -1
  87. package/package.json +22 -17
@@ -0,0 +1,47 @@
1
+ import type { WorkerReport } from "./health.js";
2
+ /** Marks a cluster control frame on the IPC channel, next to the shard-bus frames. */
3
+ export declare const CLUSTER_FRAME = "__lunibeeCluster";
4
+ /** The `source` and reply `target` of the parent process on the shard bus. */
5
+ export declare const PARENT_ID = -1;
6
+ /** Built-in cluster request: the worker answers with a {@link WorkerReport}. */
7
+ export declare const REQUEST_HEALTH = "__lunibee:health";
8
+ /** Built-in cluster request: the worker starts the given shards (recovery). */
9
+ export declare const REQUEST_ASSIGN = "__lunibee:assign";
10
+ /** Frames a worker sends to the parent. */
11
+ export type ChildFrame = {
12
+ kind: "ready";
13
+ shardIds: number[];
14
+ } | {
15
+ kind: "identify";
16
+ id: number;
17
+ shardId: number;
18
+ } | {
19
+ kind: "identify-done";
20
+ shardId: number;
21
+ } | {
22
+ kind: "reply";
23
+ id: string;
24
+ result?: unknown;
25
+ error?: string;
26
+ } | {
27
+ kind: "health";
28
+ report: WorkerReport;
29
+ };
30
+ /** Frames the parent sends to a worker. */
31
+ export type ParentFrame = {
32
+ kind: "identify-grant";
33
+ id: number;
34
+ } | {
35
+ kind: "identify-deny";
36
+ id: number;
37
+ error: string;
38
+ } | {
39
+ kind: "request";
40
+ id: string;
41
+ type: string;
42
+ data: unknown;
43
+ };
44
+ /** Validates the body of a control frame from a worker; `null` when it is malformed. */
45
+ export declare function parseChildFrame(value: unknown): ChildFrame | null;
46
+ /** Validates the body of a control frame from the parent; `null` when it is malformed. */
47
+ export declare function parseParentFrame(value: unknown): ParentFrame | null;
@@ -0,0 +1,100 @@
1
+ /** Version of the coordinator ↔ host wire protocol. Both sides must agree. */
2
+ export declare const REMOTE_PROTOCOL_VERSION = 1;
3
+ /** Largest text frame either side accepts, in UTF-8 bytes. */
4
+ export declare const MAX_REMOTE_FRAME_BYTES: number;
5
+ /** WebSocket close codes used between a coordinator and a host. */
6
+ export declare const RemoteClose: {
7
+ readonly BadRequest: 4400;
8
+ readonly AuthFailed: 4401;
9
+ readonly HelloTimeout: 4408;
10
+ readonly DuplicateHost: 4409;
11
+ readonly TooManyConnections: 4429;
12
+ readonly UnknownHost: 4410;
13
+ readonly VersionMismatch: 4426;
14
+ readonly HostLost: 4504;
15
+ readonly Shutdown: 4500;
16
+ };
17
+ /**
18
+ * The only environment variables a coordinator may set in a remote worker.
19
+ * Everything else comes from the host's own environment, so a coordinator
20
+ * cannot inject `NODE_OPTIONS`, `LD_PRELOAD` or a token.
21
+ */
22
+ export declare const SPAWN_ENV_KEYS: ReadonlySet<string>;
23
+ /** Signals a coordinator may send to a remote worker. */
24
+ export declare const KILL_SIGNALS: ReadonlySet<string>;
25
+ /** Whether a host name is this machine, where an unencrypted link is acceptable. */
26
+ export declare function isLoopbackHost(hostname: string): boolean;
27
+ /** A host ID: letters, digits, `.`, `_` and `-`, up to 64 characters. */
28
+ export declare const HOST_ID: RegExp;
29
+ /** Frames the coordinator sends to a host. */
30
+ export type ToHost = {
31
+ t: "challenge";
32
+ nonce: string;
33
+ version: number;
34
+ } | {
35
+ t: "welcome";
36
+ leaseMs: number;
37
+ pingMs: number;
38
+ } | {
39
+ t: "ping";
40
+ n: number;
41
+ } | {
42
+ t: "spawn";
43
+ cluster: number;
44
+ epoch: number;
45
+ env: Record<string, string>;
46
+ } | {
47
+ t: "frame";
48
+ cluster: number;
49
+ epoch: number;
50
+ frame: unknown;
51
+ } | {
52
+ t: "kill";
53
+ cluster: number;
54
+ epoch: number;
55
+ signal: string;
56
+ } | {
57
+ t: "bye";
58
+ reason: string;
59
+ };
60
+ /** Frames a host sends to the coordinator. */
61
+ export type ToCoordinator = {
62
+ t: "hello";
63
+ id: string;
64
+ mac: string;
65
+ version: number;
66
+ } | {
67
+ t: "pong";
68
+ n: number;
69
+ } | {
70
+ t: "spawned";
71
+ cluster: number;
72
+ epoch: number;
73
+ pid?: number;
74
+ } | {
75
+ t: "frame";
76
+ cluster: number;
77
+ epoch: number;
78
+ frame: unknown;
79
+ } | {
80
+ t: "exit";
81
+ cluster: number;
82
+ epoch: number;
83
+ code: number | null;
84
+ signal: string | null;
85
+ } | {
86
+ t: "error";
87
+ cluster: number;
88
+ epoch: number;
89
+ message: string;
90
+ };
91
+ /** The size of a string on the wire, in UTF-8 bytes. */
92
+ export declare function utf8Bytes(text: string): number;
93
+ /** The proof a host sends: an HMAC of the coordinator's nonce and the host ID, keyed by the shared secret. The secret itself never travels. */
94
+ export declare function signChallenge(secret: string, nonce: string, hostId: string): string;
95
+ /** Checks a host's proof in constant time. */
96
+ export declare function verifyChallenge(secret: string, nonce: string, hostId: string, mac: unknown): boolean;
97
+ /** Validates a text frame from the coordinator; `null` when malformed. */
98
+ export declare function parseToHost(text: unknown, maxBytes?: number): ToHost | null;
99
+ /** Validates a text frame from a host; `null` when malformed. */
100
+ export declare function parseToCoordinator(text: unknown, maxBytes?: number): ToCoordinator | null;
@@ -0,0 +1,134 @@
1
+ import { EventEmitter } from "node:events";
2
+ import type { ChildProcess } from "node:child_process";
3
+ /** Where, and how, a coordinator listens for hosts. */
4
+ export interface RemoteOptions {
5
+ /** TCP port. `0` picks a free one (read it from `ClusterManager#remotePort`). */
6
+ port: number;
7
+ /**
8
+ * Interface to bind. Default `127.0.0.1`, which only this machine can
9
+ * reach. Any other address needs `tls` or `allowInsecure`.
10
+ */
11
+ hostname?: string;
12
+ /** Shared secret, at least 16 characters. Hosts prove they know it; it never crosses the wire. */
13
+ secret: string;
14
+ /** TLS for `wss://`. Required to listen on a non-loopback address unless `allowInsecure` is set. */
15
+ tls?: {
16
+ cert: string;
17
+ key: string;
18
+ };
19
+ /**
20
+ * Listen on a non-loopback address without TLS: frames (shard messages
21
+ * and worker output) travel unencrypted and unsigned. Only for a network
22
+ * you fully trust, or when a TLS proxy in front terminates the connection.
23
+ * Default false.
24
+ */
25
+ allowInsecure?: boolean;
26
+ /**
27
+ * The host IDs that make up the deployment. Clusters are placed on them in
28
+ * this order, and an unlisted host is refused. Without it, the hosts that
29
+ * have joined when `spawn()` starts are used, sorted by ID.
30
+ */
31
+ hosts?: string[];
32
+ /** How many hosts must join before clusters are placed when `hosts` is not set. Default 1. */
33
+ minHosts?: number;
34
+ /** Milliseconds to wait for the hosts to join before `spawn()` fails. Default 60,000. */
35
+ joinTimeout?: number;
36
+ /**
37
+ * Fencing lease in milliseconds. A host that hears nothing from the
38
+ * coordinator for this long kills its workers; the coordinator waits twice
39
+ * as long before it treats the host as lost and restarts its clusters, so
40
+ * a shard never runs in two places. Default 15,000.
41
+ */
42
+ lease?: number;
43
+ /** Milliseconds a new connection has to authenticate before it is closed. Default 3,000. */
44
+ helloTimeout?: number;
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
+ */
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;
63
+ /** Also run clusters on the coordinator's own machine. Default false: clusters run on the hosts only. */
64
+ local?: boolean;
65
+ }
66
+ /** A host as the coordinator sees it. */
67
+ export interface HostStatus {
68
+ id: string;
69
+ /** Whether its socket is open and answering. */
70
+ connected: boolean;
71
+ /** When it last sent anything (epoch ms). */
72
+ lastSeen: number;
73
+ /** Clusters currently running on it. */
74
+ clusters: number[];
75
+ }
76
+ type Kill = (signal: string) => boolean;
77
+ /** What the coordinator wants to hear about its hosts. */
78
+ export interface RemoteHooks {
79
+ join(id: string): void;
80
+ leave(id: string, reason: string): void;
81
+ error(error: Error): void;
82
+ }
83
+ /**
84
+ * A worker process on another host, shaped like the `ChildProcess` that
85
+ * `ClusterManager` supervises. `send()` and `kill()` travel to the host's
86
+ * agent; its messages and exit travel back, so the manager's restart,
87
+ * IDENTIFY, routing and health logic needs no special case for it.
88
+ */
89
+ export declare class RemoteChild extends EventEmitter {
90
+ #private;
91
+ readonly host: string;
92
+ readonly cluster: number;
93
+ readonly epoch: number;
94
+ pid: number | undefined;
95
+ exitCode: number | null;
96
+ signalCode: NodeJS.Signals | null;
97
+ connected: boolean;
98
+ constructor(host: string, cluster: number, epoch: number, send: (frame: unknown) => boolean, kill: Kill);
99
+ /** Sends an IPC frame to the worker. */
100
+ send(frame: unknown): boolean;
101
+ /** Asks the host to signal the worker; the exit arrives as an event. */
102
+ kill(signal?: string): boolean;
103
+ /** The agent says the worker started. */
104
+ spawned(pid: number | undefined): void;
105
+ /** The worker sent a message. */
106
+ deliver(frame: unknown): void;
107
+ /** The worker exited, or its host was lost. Emits `exit` once. */
108
+ finish(code: number | null, signal: string | null): void;
109
+ }
110
+ /** The coordinator's listener and the hosts that joined it. */
111
+ export declare class RemoteHosts {
112
+ #private;
113
+ constructor(options: RemoteOptions, hooks: RemoteHooks);
114
+ /** The port in use, once started. */
115
+ get port(): number | undefined;
116
+ /** Host IDs that are connected now, sorted. */
117
+ connected(): string[];
118
+ /** Opens the listener. Safe to call twice. */
119
+ start(): void;
120
+ /** Closes the listener and every host connection. */
121
+ stop(): void;
122
+ /** Resolves when the given hosts (or `count` hosts) are connected. @throws {Error} On timeout. */
123
+ waitFor(hosts: readonly string[] | undefined, count: number, timeoutMs: number): Promise<void>;
124
+ /** Fails everything waiting for hosts to join (a shutdown). */
125
+ abortWaits(): void;
126
+ /** Hosts and the clusters running on them. */
127
+ status(declared?: readonly string[]): HostStatus[];
128
+ /**
129
+ * Starts a worker on `hostId`. If the host is not connected the returned
130
+ * child exits at once, which `ClusterManager` handles like a crash.
131
+ */
132
+ createChild(hostId: string, cluster: number, env: Record<string, string>): ChildProcess;
133
+ }
134
+ export {};
@@ -0,0 +1,54 @@
1
+ /** One answer collected for a request. */
2
+ export interface Settled<R = unknown> {
3
+ key: string;
4
+ result?: R;
5
+ error?: string;
6
+ }
7
+ /** What a finished request collected. */
8
+ export interface Collected<R = unknown> {
9
+ /** Answers by key, in arrival order. */
10
+ replies: Settled<R>[];
11
+ /** Keys that never answered (timeout, abort or shutdown). */
12
+ missing: string[];
13
+ }
14
+ /**
15
+ * Pending requests of the parent process. Each request waits for answers from
16
+ * a set of keys (a shard, a cluster, or every shard of the live clusters) and
17
+ * settles when all arrived, the timeout passed, or the caller aborted.
18
+ *
19
+ * Answers are accepted only from the owner of the key, once per key; late,
20
+ * duplicate and unknown answers are ignored. The number of waiting requests is
21
+ * bounded, and a timer per request guarantees the entry is removed.
22
+ */
23
+ export declare class RequestTracker {
24
+ #private;
25
+ constructor(prefix?: string, maxPending?: number);
26
+ /** Requests waiting for answers. */
27
+ get size(): number;
28
+ /**
29
+ * Starts waiting for answers.
30
+ * @param keys Each key that should answer, with the cluster that owns it.
31
+ * @throws {Error} If `maxPending` requests are already waiting.
32
+ */
33
+ begin<R>(options: {
34
+ keys: ReadonlyMap<string, number>;
35
+ timeoutMs: number;
36
+ signal?: AbortSignal;
37
+ }): {
38
+ id: string;
39
+ done: Promise<Collected<R>>;
40
+ };
41
+ /**
42
+ * Records one answer.
43
+ * @param from The cluster the answer came from; it must own `key`.
44
+ * @returns Whether the answer was accepted.
45
+ */
46
+ answer(id: string, key: string, from: number, value: {
47
+ result?: unknown;
48
+ error?: string;
49
+ }): boolean;
50
+ /** A cluster went away: every key it owns that has not answered settles with `error`. */
51
+ failOwner(owner: number, error: string): void;
52
+ /** Settles every waiting request with what it has (shutdown). */
53
+ close(): void;
54
+ }
@@ -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;
@@ -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;
@@ -0,0 +1,55 @@
1
+ import { type ClusterContext } from "./context.js";
2
+ import type { WorkerReport } from "./health.js";
3
+ /** Asks for the right to IDENTIFY, and gives it back. */
4
+ export interface IdentifyGate {
5
+ /** Resolves when `shardId` may IDENTIFY now. Rejects if the parent refuses or goes away. */
6
+ acquire(shardId: number): Promise<void>;
7
+ /** `shardId` has sent its IDENTIFY. */
8
+ release(shardId: number): void;
9
+ }
10
+ /** The part of `process` a worker uses. */
11
+ export interface WorkerEndpoint {
12
+ send?(message: unknown): unknown;
13
+ on(event: string, listener: (...args: never[]) => void): unknown;
14
+ off(event: string, listener: (...args: never[]) => void): unknown;
15
+ }
16
+ type RequestHandler = (data: unknown) => unknown;
17
+ /**
18
+ * The worker side of a cluster. It tells the parent when the process is
19
+ * ready, answers the parent's requests, and asks the parent for IDENTIFY
20
+ * slots. `ShardManager` uses it automatically inside a cluster; use it
21
+ * directly when you run your own Gateways.
22
+ */
23
+ export declare class ClusterWorker {
24
+ #private;
25
+ /** The worker of this process, or `undefined` when it was not forked by a `ClusterManager`. */
26
+ static current(): ClusterWorker | undefined;
27
+ /** Forgets the process-wide worker (tests). */
28
+ static reset(): void;
29
+ readonly context: ClusterContext;
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
+ });
41
+ /** The gate to use when the parent coordinates IDENTIFY, otherwise `undefined`. */
42
+ get identifyGate(): IdentifyGate | undefined;
43
+ /** Tells the parent every shard of this process finished its handshake. */
44
+ ready(shardIds?: readonly number[]): void;
45
+ /** Pushes a health report to the parent without being asked. */
46
+ reportHealth(report: WorkerReport): void;
47
+ /**
48
+ * Answers requests of `type` sent with `ClusterManager.requestCluster()`.
49
+ * The return value (or thrown error) goes back to the caller.
50
+ */
51
+ onRequest(type: string, handler: RequestHandler): this;
52
+ /** Stops listening and rejects pending IDENTIFY requests. */
53
+ close(): void;
54
+ }
55
+ export {};
@@ -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";