slack.ts 0.0.3 → 0.0.5

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 (67) hide show
  1. package/README.md +14 -0
  2. package/dist/api/index.d.ts +19 -1
  3. package/dist/api/index.d.ts.map +1 -1
  4. package/dist/api/index.js +1 -0
  5. package/dist/api/interactive/block_actions.d.ts +61 -0
  6. package/dist/api/interactive/block_actions.d.ts.map +1 -0
  7. package/dist/api/interactive/block_actions.js +1 -0
  8. package/dist/api/interactive/common.d.ts +23 -0
  9. package/dist/api/interactive/common.d.ts.map +1 -0
  10. package/dist/api/interactive/common.js +1 -0
  11. package/dist/api/interactive/view_submission.d.ts +8 -0
  12. package/dist/api/interactive/view_submission.d.ts.map +1 -0
  13. package/dist/api/interactive/view_submission.js +1 -0
  14. package/dist/api/types/user.d.ts +54 -0
  15. package/dist/api/types/user.d.ts.map +1 -0
  16. package/dist/api/types/user.js +1 -0
  17. package/dist/api/types/value.d.ts +6 -0
  18. package/dist/api/types/value.d.ts.map +1 -0
  19. package/dist/api/types/value.js +1 -0
  20. package/dist/api/types/view.d.ts +26 -0
  21. package/dist/api/types/view.d.ts.map +1 -0
  22. package/dist/api/types/view.js +1 -0
  23. package/dist/api/web/conversations.d.ts +12 -0
  24. package/dist/api/web/conversations.d.ts.map +1 -1
  25. package/dist/api/web/users.d.ts +11 -0
  26. package/dist/api/web/users.d.ts.map +1 -0
  27. package/dist/api/web/users.js +1 -0
  28. package/dist/api/web/views.d.ts +17 -0
  29. package/dist/api/web/views.d.ts.map +1 -0
  30. package/dist/api/web/views.js +1 -0
  31. package/dist/client.d.ts +71 -14
  32. package/dist/client.d.ts.map +1 -1
  33. package/dist/client.js +72 -35
  34. package/dist/error.d.ts +2 -0
  35. package/dist/error.d.ts.map +1 -1
  36. package/dist/error.js +2 -0
  37. package/dist/events/receivers/socket.d.ts.map +1 -1
  38. package/dist/events/receivers/socket.js +11 -2
  39. package/dist/events/types/index.d.ts +8 -0
  40. package/dist/events/types/index.d.ts.map +1 -1
  41. package/dist/resources/action.d.ts +13 -0
  42. package/dist/resources/action.d.ts.map +1 -0
  43. package/dist/resources/action.js +22 -0
  44. package/dist/resources/channel.d.ts +27 -1
  45. package/dist/resources/channel.d.ts.map +1 -1
  46. package/dist/resources/channel.js +19 -0
  47. package/dist/resources/message.d.ts +95 -0
  48. package/dist/resources/message.d.ts.map +1 -1
  49. package/dist/resources/message.js +127 -1
  50. package/dist/resources/modal.d.ts +21 -0
  51. package/dist/resources/modal.d.ts.map +1 -0
  52. package/dist/resources/modal.js +54 -0
  53. package/dist/resources/submission.d.ts +11 -0
  54. package/dist/resources/submission.d.ts.map +1 -0
  55. package/dist/resources/submission.js +14 -0
  56. package/dist/resources/user.d.ts +38 -0
  57. package/dist/resources/user.d.ts.map +1 -0
  58. package/dist/resources/user.js +41 -0
  59. package/dist/utils/paginate.d.ts +10 -0
  60. package/dist/utils/paginate.d.ts.map +1 -0
  61. package/dist/utils/paginate.js +22 -0
  62. package/dist/utils/respond.d.ts +31 -0
  63. package/dist/utils/respond.d.ts.map +1 -0
  64. package/dist/utils/respond.js +71 -0
  65. package/dist/utils/typing.d.ts +3 -0
  66. package/dist/utils/typing.d.ts.map +1 -1
  67. package/package.json +1 -1
@@ -1,7 +1,9 @@
1
- import { SlackError } from "../error.js";
1
+ import { SlackError, SlackTimeoutError } from "../error.js";
2
2
  import { makeProxy } from "../utils/index.js";
3
3
  import { sendMessage, } from "../utils/messaging.js";
4
+ import { paginate } from "../utils/paginate.js";
4
5
  import { ChannelRef } from "./channel.js";
6
+ import { UserRef } from "./user.js";
5
7
  class MessageMixin {
6
8
  client;
7
9
  #channel;
@@ -25,6 +27,13 @@ class MessageMixin {
25
27
  get _threadTs() {
26
28
  return undefined;
27
29
  }
30
+ /**
31
+ * Waits for an event about this message to occur before continuing. To configure the wait object,
32
+ * see its methods (for example, `message.wait.timeout(60000)`).
33
+ */
34
+ get wait() {
35
+ return new MessageWait(this, this.client);
36
+ }
28
37
  async reply(message) {
29
38
  if (typeof message === "string") {
30
39
  message = { text: message };
@@ -38,6 +47,19 @@ class MessageMixin {
38
47
  return new Message(this.client, this.#channel, data.ts, data.message);
39
48
  }
40
49
  }
50
+ /**
51
+ * Fetches replies in the thread of this message. Note that this method may return the root
52
+ * message by default; set `params.root` to `false` to skip it.
53
+ *
54
+ * @param params Options for fetching replies
55
+ * @returns An async iterator of messages, from oldest to newest
56
+ */
57
+ async *replies(params = {}) {
58
+ yield* paginate(this.client, "conversations.replies", { channel: this.#channel, ts: this.#ts, ...params }, (r) => r.messages
59
+ .values()
60
+ .filter((m) => m.ts !== this.#ts || (params.root ?? true))
61
+ .map((m) => new Message(this.client, this.#channel, m.ts, m)));
62
+ }
41
63
  }
42
64
  export class MessageRef extends MessageMixin {
43
65
  then(onfulfilled, onrejected) {
@@ -72,7 +94,111 @@ export class Message extends MessageMixin {
72
94
  get raw() {
73
95
  return this.#data;
74
96
  }
97
+ /**
98
+ * A reference to the user that created the message. Note that for system messages (such as
99
+ * channel join messages), this may not be the user you expect. Read the Slack documentation to
100
+ * find out.
101
+ */
102
+ get author() {
103
+ return new UserRef(this.client, this.#data.user);
104
+ }
75
105
  get _threadTs() {
76
106
  return this.#data.thread_ts;
77
107
  }
78
108
  }
109
+ class MessageWait {
110
+ message;
111
+ client;
112
+ _timeout = 600000;
113
+ constructor(message, client) {
114
+ this.message = message;
115
+ this.client = client;
116
+ }
117
+ /**
118
+ * Sets the timeout of the wait. A `SlackTimeoutError` will be thrown if no matching event occurs
119
+ * after the timeout. Set this to `0` to disable timeouts; i.e., methods will wait forever. (This
120
+ * is dangerous because it creates potential memory leaks!)
121
+ *
122
+ * By default, timeout is set to 10 minutes.
123
+ *
124
+ * @param timeout Timeout in milliseconds
125
+ * @returns `this` for chaining
126
+ */
127
+ timeout(timeout) {
128
+ this._timeout = timeout;
129
+ return this;
130
+ }
131
+ /**
132
+ * Waits for a block action on this message happened (e.g., a button is pressed).
133
+ *
134
+ * The parameters can be any of any of the following:
135
+ *
136
+ * - An action ID; for example, `'place_order'`.
137
+ * - An event type and an action ID joined with a dot (`.`); for example, `'button.place_order'`.
138
+ * The benefit of using this instead of a plain action ID is, if all string parameters have an
139
+ * event type prefix, the return type of this function will be automatically narrowed to only
140
+ * the possible action types.
141
+ * - A function (`async` or not) that takes in an action and returns `false` if this action should
142
+ * be ignored (useful for permission checks).
143
+ *
144
+ * An action is matched if its container is this message, its `action_id` is one of the parameters
145
+ * passed in, and it passes all the function checks.
146
+ *
147
+ * NOTE: You must specify at least one non-function parameter, since the `action_id` of the action
148
+ * must match one of the arguments.
149
+ *
150
+ * @param specifiers An array of specifiers (see above for their format)
151
+ * @returns The action that occurred that matches the specifiers.
152
+ * @throws `SlackTimeoutError` if timed out before a matched event occurred
153
+ */
154
+ async action(...specifiers) {
155
+ return new Promise((resolve, reject) => {
156
+ const predicates = [];
157
+ const cleanup = () => {
158
+ if (timer) {
159
+ clearTimeout(timer);
160
+ }
161
+ for (const name of subscriptions) {
162
+ this.client.off(name, callback);
163
+ }
164
+ };
165
+ const callback = async (action) => {
166
+ const { event } = action;
167
+ if ((event.container.type === "message" || event.container.type === "message_attachment") &&
168
+ event.container.message_ts === this.message.ts &&
169
+ !(await Promise.all(predicates.map((predicate) => predicate(action)))).filter((v) => !v)
170
+ .length) {
171
+ cleanup();
172
+ resolve(action);
173
+ }
174
+ };
175
+ const subscriptions = [];
176
+ for (const specifier of specifiers) {
177
+ if (typeof specifier === "string") {
178
+ this.client.on(`action.${specifier}`, callback);
179
+ subscriptions.push(`action.${specifier}`);
180
+ const index = specifier.indexOf(".");
181
+ if (index >= 0) {
182
+ const type = specifier.substring(0, index);
183
+ const actionId = specifier.substring(index + 1);
184
+ this.client.on(`action:${type}.${actionId}`, callback);
185
+ subscriptions.push(`action:${type}.${actionId}`);
186
+ }
187
+ }
188
+ else {
189
+ predicates.push(specifier);
190
+ }
191
+ }
192
+ if (!subscriptions.length) {
193
+ reject(new SlackError("No action ID specifiers given"));
194
+ return;
195
+ }
196
+ const timer = this._timeout
197
+ ? setTimeout(() => {
198
+ cleanup();
199
+ reject(new SlackTimeoutError(`Timed out waiting for action (${this._timeout} ms)`));
200
+ }, this._timeout)
201
+ : null;
202
+ });
203
+ }
204
+ }
@@ -0,0 +1,21 @@
1
+ import type { ModalView } from "../api/types/view.js";
2
+ import type { App } from "../client.js";
3
+ import { type SubmissionInstance } from "./submission.js";
4
+ export declare class Modal {
5
+ #private;
6
+ protected client: App;
7
+ constructor(client: App, data: ModalView);
8
+ get raw(): ModalView;
9
+ get wait(): ModalWait;
10
+ }
11
+ export type ModalInstance = Modal & ModalView;
12
+ declare class ModalWait {
13
+ private client;
14
+ private modal;
15
+ private _timeout;
16
+ constructor(client: App, modal: ModalInstance);
17
+ timeout(timeout: number): this;
18
+ submit(): Promise<SubmissionInstance>;
19
+ }
20
+ export {};
21
+ //# sourceMappingURL=modal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal.d.ts","sourceRoot":"","sources":["../../src/resources/modal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAGpC,OAAO,EAAc,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAElE,qBAAa,KAAK;;IAIhB,SAAS,CAAC,MAAM,EAAE,GAAG;gBAAX,MAAM,EAAE,GAAG,EACrB,IAAI,EAAE,SAAS;IAMhB,IAAI,GAAG,cAEN;IAED,IAAI,IAAI,cAEP;CACD;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,SAAS,CAAA;AAE7C,cAAM,SAAS;IAIb,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IAJd,OAAO,CAAC,QAAQ,CAAgB;gBAGvB,MAAM,EAAE,GAAG,EACX,KAAK,EAAE,aAAa;IAG7B,OAAO,CAAC,OAAO,EAAE,MAAM;IAKjB,MAAM;CA0BZ"}
@@ -0,0 +1,54 @@
1
+ import { SlackTimeoutError } from "../error.js";
2
+ import { makeProxy } from "../utils/index.js";
3
+ import { Submission } from "./submission.js";
4
+ export class Modal {
5
+ client;
6
+ #data;
7
+ constructor(client, data) {
8
+ this.client = client;
9
+ this.#data = data;
10
+ return makeProxy(this, () => this.#data);
11
+ }
12
+ get raw() {
13
+ return this.#data;
14
+ }
15
+ get wait() {
16
+ return new ModalWait(this.client, makeProxy(this, () => this.#data));
17
+ }
18
+ }
19
+ class ModalWait {
20
+ client;
21
+ modal;
22
+ _timeout = 60000;
23
+ constructor(client, modal) {
24
+ this.client = client;
25
+ this.modal = modal;
26
+ }
27
+ timeout(timeout) {
28
+ this._timeout = timeout;
29
+ return this;
30
+ }
31
+ async submit() {
32
+ return new Promise((resolve, reject) => {
33
+ const cleanup = () => {
34
+ this.client.off(key, callback);
35
+ if (timeout)
36
+ clearTimeout(timeout);
37
+ };
38
+ const callback = (event) => {
39
+ if (event.view.id === this.modal.id) {
40
+ cleanup();
41
+ resolve(new Submission(this.client, event));
42
+ }
43
+ };
44
+ const key = `submit.${this.modal.callback_id}`;
45
+ this.client.on(key, callback);
46
+ const timeout = this._timeout > 0
47
+ ? setTimeout(() => {
48
+ cleanup();
49
+ reject(new SlackTimeoutError(`Timed out waiting for action (${this._timeout} ms)`));
50
+ }, this._timeout)
51
+ : null;
52
+ });
53
+ }
54
+ }
@@ -0,0 +1,11 @@
1
+ import type { ViewSubmission } from "../api/interactive/view_submission.js";
2
+ import type { App } from "../client.js";
3
+ import { type Responder } from "../utils/respond.js";
4
+ export declare class Submission {
5
+ #private;
6
+ protected client: App;
7
+ constructor(client: App, data: ViewSubmission);
8
+ get respond(): Responder;
9
+ }
10
+ export type SubmissionInstance = Submission & ViewSubmission;
11
+ //# sourceMappingURL=submission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submission.d.ts","sourceRoot":"","sources":["../../src/resources/submission.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAEhE,qBAAa,UAAU;;IAIrB,SAAS,CAAC,MAAM,EAAE,GAAG;gBAAX,MAAM,EAAE,GAAG,EACrB,IAAI,EAAE,cAAc;IAMrB,IAAI,OAAO,IAAI,SAAS,CAEvB;CACD;AAED,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,cAAc,CAAA"}
@@ -0,0 +1,14 @@
1
+ import { makeProxy } from "../utils/index.js";
2
+ import { ResponderImpl } from "../utils/respond.js";
3
+ export class Submission {
4
+ client;
5
+ #data;
6
+ constructor(client, data) {
7
+ this.client = client;
8
+ this.#data = data;
9
+ return makeProxy(this, () => this.#data);
10
+ }
11
+ get respond() {
12
+ return new ResponderImpl(this.client, this.#data.response_urls[0], this.#data.trigger_id);
13
+ }
14
+ }
@@ -0,0 +1,38 @@
1
+ import type { NormalMessage } from "../api/types/message.js";
2
+ import type { User as UserData } from "../api/types/user.js";
3
+ import type { App } from "../client.js";
4
+ import { type SendMessageWithFiles, type SendMessageWithoutFiles } from "../utils/messaging.js";
5
+ import type { DistributiveOmit } from "../utils/typing.js";
6
+ import { type MessageInstance } from "./message.js";
7
+ declare class UserMixin {
8
+ #private;
9
+ protected client: App;
10
+ constructor(client: App, id: string);
11
+ /** ID of the channel */
12
+ get id(): string;
13
+ /**
14
+ * Sends a message in DM with the user with files.
15
+ *
16
+ * @param message The message payload to send, including the files to upload. `text` will be
17
+ * ignored if `blocks` are provided.
18
+ */
19
+ send(message: DistributiveOmit<SendMessageWithFiles, "channel">): Promise<undefined>;
20
+ /**
21
+ * Sends a message in DM with the user.
22
+ *
23
+ * @param message The message payload to send, either a mrkdwn-formatted string or an object.
24
+ * @returns The sent message
25
+ */
26
+ send(message: DistributiveOmit<SendMessageWithoutFiles, "channel"> | string): Promise<MessageInstance<NormalMessage>>;
27
+ }
28
+ export declare class UserRef extends UserMixin implements PromiseLike<UserInstance> {
29
+ #private;
30
+ then<TResult1 = UserInstance, TResult2 = never>(onfulfilled?: ((value: UserInstance) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): PromiseLike<TResult1 | TResult2>;
31
+ }
32
+ export declare class User extends UserMixin {
33
+ #private;
34
+ constructor(client: App, id: string, data: UserData);
35
+ }
36
+ export type UserInstance = User & UserData;
37
+ export {};
38
+ //# sourceMappingURL=user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user.d.ts","sourceRoot":"","sources":["../../src/resources/user.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,KAAK,EAAE,IAAI,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AACzD,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AAEpC,OAAO,EAGN,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAW,KAAK,eAAe,EAAE,MAAM,WAAW,CAAA;AAEzD,cAAM,SAAS;;IAIb,SAAS,CAAC,MAAM,EAAE,GAAG;gBAAX,MAAM,EAAE,GAAG,EACrB,EAAE,EAAE,MAAM;IAKX,wBAAwB;IACxB,IAAI,EAAE,WAEL;IAED;;;;;OAKG;IACG,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,oBAAoB,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC;IAE1F;;;;;OAKG;IACG,IAAI,CACT,OAAO,EAAE,gBAAgB,CAAC,uBAAuB,EAAE,SAAS,CAAC,GAAG,MAAM,GACpE,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;CAgB1C;AAED,qBAAa,OAAQ,SAAQ,SAAU,YAAW,WAAW,CAAC,YAAY,CAAC;;IAC1E,IAAI,CAAC,QAAQ,GAAG,YAAY,EAAE,QAAQ,GAAG,KAAK,EAC7C,WAAW,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,YAAY,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAC5F,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,GACjF,WAAW,CAAC,QAAQ,GAAG,QAAQ,CAAC;CAQnC;AAED,qBAAa,IAAK,SAAQ,SAAS;;gBAGtB,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ;CAKnD;AAED,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG,QAAQ,CAAA"}
@@ -0,0 +1,41 @@
1
+ import { makeProxy } from "../utils/index.js";
2
+ import { sendMessage, } from "../utils/messaging.js";
3
+ import { Message } from "./message.js";
4
+ class UserMixin {
5
+ client;
6
+ #id;
7
+ constructor(client, id) {
8
+ this.client = client;
9
+ this.#id = id;
10
+ }
11
+ /** ID of the channel */
12
+ get id() {
13
+ return this.#id;
14
+ }
15
+ async send(message) {
16
+ if (typeof message === "string") {
17
+ message = { text: message };
18
+ }
19
+ const data = await sendMessage(this.client, { ...message, channel: this.id });
20
+ if (data) {
21
+ return new Message(this.client, this.#id, data.ts, data.message);
22
+ }
23
+ }
24
+ }
25
+ export class UserRef extends UserMixin {
26
+ then(onfulfilled, onrejected) {
27
+ return this.#fetch().then(onfulfilled, onrejected);
28
+ }
29
+ async #fetch() {
30
+ const data = await this.client.request("users.info", { user: this.id });
31
+ return new User(this.client, this.id, data.user);
32
+ }
33
+ }
34
+ export class User extends UserMixin {
35
+ #data;
36
+ constructor(client, id, data) {
37
+ super(client, id);
38
+ this.#data = data;
39
+ return makeProxy(this, () => this.#data);
40
+ }
41
+ }
@@ -0,0 +1,10 @@
1
+ import type { SlackAPIParams, SlackAPIResponse, SlackPaginatingAPIMethod } from "../api/index.js";
2
+ import type { App } from "../client.js";
3
+ import type { DistributiveOmit } from "./typing.js";
4
+ export declare function paginate<Method extends SlackPaginatingAPIMethod, T>(client: App, method: Method, params: DistributiveOmit<SlackAPIParams<Method>, "limit" | "cursor"> & {
5
+ limit?: number;
6
+ batch?: number;
7
+ }, converter: (response: SlackAPIResponse<Method> & {
8
+ ok: true;
9
+ }) => Iterable<T> | AsyncIterable<T>): AsyncGenerator<Awaited<T>, void, unknown>;
10
+ //# sourceMappingURL=paginate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paginate.d.ts","sourceRoot":"","sources":["../../src/utils/paginate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,QAAQ,CAAA;AACxF,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAEhD,wBAAuB,QAAQ,CAAC,MAAM,SAAS,wBAAwB,EAAE,CAAC,EACzE,MAAM,EAAE,GAAG,EACX,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,gBAAgB,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC,GAAG;IACtE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACd,EACD,SAAS,EAAE,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,CAAC,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,aAAa,CAAC,CAAC,CAAC,6CAmBhG"}
@@ -0,0 +1,22 @@
1
+ export async function* paginate(client, method, params, converter) {
2
+ let remaining = params.limit ?? Infinity;
3
+ let cursor;
4
+ if (remaining <= 0)
5
+ return;
6
+ while (true) {
7
+ const batch = await client.request(method, {
8
+ ...params,
9
+ cursor,
10
+ limit: params.batch ?? undefined,
11
+ batch: undefined,
12
+ });
13
+ for await (const item of converter(batch)) {
14
+ yield item;
15
+ if (--remaining <= 0)
16
+ return;
17
+ }
18
+ cursor = batch.response_metadata?.next_cursor;
19
+ if (!batch.has_more || !cursor)
20
+ return;
21
+ }
22
+ }
@@ -0,0 +1,31 @@
1
+ import type { KnownBlock } from "@slack/types";
2
+ import type { App } from "../client.js";
3
+ import type { ViewsOpenParams } from "../api/web/views.js";
4
+ import { type ModalInstance } from "../resources/modal.js";
5
+ export declare class ResponderImpl implements Responder {
6
+ private client;
7
+ private response_url;
8
+ private trigger_id;
9
+ constructor(client: App, response_url: string | undefined, trigger_id: string);
10
+ message(message: string | MessageResponseParams): Promise<void>;
11
+ edit(message: string | MessageResponseParams): Promise<void>;
12
+ delete(): Promise<void>;
13
+ modal(view: ViewsOpenParams["view"]): Promise<ModalInstance>;
14
+ }
15
+ export type Responder<HasResponseURL extends boolean = true> = {
16
+ modal(view: ViewsOpenParams["view"]): Promise<ModalInstance>;
17
+ } & (HasResponseURL extends true ? {
18
+ message(message: string | MessageResponseParams): Promise<void>;
19
+ edit(message: string | MessageResponseParams): Promise<void>;
20
+ delete(): Promise<void>;
21
+ } : {});
22
+ export type MessageResponseParams = {
23
+ ephemeral?: boolean;
24
+ text?: string;
25
+ blocks?: KnownBlock[];
26
+ } & ({
27
+ text: string;
28
+ } | {
29
+ blocks: KnownBlock[];
30
+ });
31
+ //# sourceMappingURL=respond.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"respond.d.ts","sourceRoot":"","sources":["../../src/utils/respond.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAA;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAS,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAG9D,qBAAa,aAAc,YAAW,SAAS;IAE7C,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,YAAY;IACpB,OAAO,CAAC,UAAU;gBAFV,MAAM,EAAE,GAAG,EACX,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,UAAU,EAAE,MAAM;IAGrB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB;IAuB/C,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB;IAuB5C,MAAM;IAcN,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC;CAKzC;AAED,MAAM,MAAM,SAAS,CAAC,cAAc,SAAS,OAAO,GAAG,IAAI,IAAI;IAC9D,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;CAC5D,GAAG,CAAC,cAAc,SAAS,IAAI,GAC7B;IACA,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB,GACA,EAAE,CAAC,CAAA;AAEN,MAAM,MAAM,qBAAqB,GAAG;IACnC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,UAAU,EAAE,CAAA;CACrB,GAAG,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,UAAU,EAAE,CAAA;CAAE,CAAC,CAAA"}
@@ -0,0 +1,71 @@
1
+ import { SlackError } from "../error.js";
2
+ import { Modal } from "../resources/modal.js";
3
+ import { randomUUID } from "crypto";
4
+ export class ResponderImpl {
5
+ client;
6
+ response_url;
7
+ trigger_id;
8
+ constructor(client, response_url, trigger_id) {
9
+ this.client = client;
10
+ this.response_url = response_url;
11
+ this.trigger_id = trigger_id;
12
+ }
13
+ async message(message) {
14
+ if (!this.response_url)
15
+ throw new SlackError("Cannot respond to this event with a message");
16
+ if (typeof message === "string")
17
+ message = { text: message };
18
+ const payload = {
19
+ text: message.text,
20
+ blocks: message.blocks,
21
+ response_type: message.ephemeral ? "ephemeral" : "in_channel",
22
+ replace_original: false,
23
+ };
24
+ const resp = await fetch(this.response_url, {
25
+ method: "POST",
26
+ headers: { "Content-Type": "application/json; charset=utf-8" },
27
+ body: JSON.stringify(payload),
28
+ });
29
+ if (!resp.ok) {
30
+ throw new SlackError(`Responding to response_url failed with status code ${resp.status}`);
31
+ }
32
+ }
33
+ async edit(message) {
34
+ if (!this.response_url)
35
+ throw new SlackError("Cannot respond to this event with an edit");
36
+ if (typeof message === "string")
37
+ message = { text: message };
38
+ const payload = {
39
+ text: message.text,
40
+ blocks: message.blocks,
41
+ response_type: message.ephemeral ? "ephemeral" : "in_channel",
42
+ replace_original: true,
43
+ };
44
+ const resp = await fetch(this.response_url, {
45
+ method: "POST",
46
+ headers: { "Content-Type": "application/json; charset=utf-8" },
47
+ body: JSON.stringify(payload),
48
+ });
49
+ if (!resp.ok) {
50
+ throw new SlackError(`Responding to response_url failed with status code ${resp.status}`);
51
+ }
52
+ }
53
+ async delete() {
54
+ if (!this.response_url)
55
+ throw new SlackError("Cannot respond to this event with deletion");
56
+ const resp = await fetch(this.response_url, {
57
+ method: "POST",
58
+ headers: { "Content-Type": "application/json; charset=utf-8" },
59
+ body: JSON.stringify({ delete_original: true }),
60
+ });
61
+ if (!resp.ok) {
62
+ throw new SlackError(`Responding to response_url failed with status code ${resp.status}`);
63
+ }
64
+ }
65
+ async modal(view) {
66
+ if (!view.callback_id)
67
+ view.callback_id = randomUUID();
68
+ const resp = await this.client.request("views.open", { view, trigger_id: this.trigger_id });
69
+ return new Modal(this.client, resp.view);
70
+ }
71
+ }
@@ -1,2 +1,5 @@
1
1
  export type DistributiveOmit<T, Key extends keyof any> = T extends any ? Omit<T, Key> : never;
2
+ export type DistributivePick<T, Key extends keyof T> = T extends any ? Pick<T, Key> : never;
3
+ export type ExtractPrefix<T extends string, PrefixType extends string = string, Sep extends string = ':', IfNotFound = never> = T extends `${infer Prefix extends PrefixType}${Sep}${string}` ? Prefix : IfNotFound;
4
+ export type NotNull<T> = T extends null ? never : T;
2
5
  //# sourceMappingURL=typing.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"typing.d.ts","sourceRoot":"","sources":["../../src/utils/typing.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,GAAG,SAAS,MAAM,GAAG,IAAI,CAAC,SAAS,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAA"}
1
+ {"version":3,"file":"typing.d.ts","sourceRoot":"","sources":["../../src/utils/typing.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,GAAG,SAAS,MAAM,GAAG,IAAI,CAAC,SAAS,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAA;AAE7F,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,GAAG,SAAS,MAAM,CAAC,IAAI,CAAC,SAAS,GAAG,GAAG,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAA;AAE3F,MAAM,MAAM,aAAa,CACxB,CAAC,SAAS,MAAM,EAChB,UAAU,SAAS,MAAM,GAAG,MAAM,EAClC,GAAG,SAAS,MAAM,GAAG,GAAG,EACxB,UAAU,GAAG,KAAK,IACf,CAAC,SAAS,GAAG,MAAM,MAAM,SAAS,UAAU,GAAG,GAAG,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,UAAU,CAAA;AAEvF,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,KAAK,GAAG,CAAC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slack.ts",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "description": "A fully-typed, opinionated Slack API library",
5
5
  "author": "@jollyroger182",
6
6
  "license": "MIT",