@1kbirds/chidori-mock-slack 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +89 -0
- package/dist/api.d.ts +14 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +74 -0
- package/dist/client.d.ts +176 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +34 -0
- package/dist/errors.d.ts +10 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +14 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/seed.d.ts +8 -0
- package/dist/seed.d.ts.map +1 -0
- package/dist/seed.js +133 -0
- package/dist/service.d.ts +110 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +270 -0
- package/dist/state.d.ts +21 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +100 -0
- package/dist/types.d.ts +134 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/dist/ui/SlackMockApp.d.ts +7 -0
- package/dist/ui/SlackMockApp.d.ts.map +1 -0
- package/dist/ui/SlackMockApp.js +73 -0
- package/dist/ui/dev.d.ts +2 -0
- package/dist/ui/dev.d.ts.map +1 -0
- package/dist/ui/dev.js +11 -0
- package/dist/ui/index.d.ts +3 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +1 -0
- package/dist/ui/styles.css +274 -0
- package/package.json +56 -0
- package/src/__tests__/service.test.ts +97 -0
- package/src/api.ts +81 -0
- package/src/client.ts +37 -0
- package/src/errors.ts +17 -0
- package/src/index.ts +12 -0
- package/src/seed.ts +140 -0
- package/src/service.ts +292 -0
- package/src/state.ts +122 -0
- package/src/types.ts +128 -0
- package/src/ui/SlackMockApp.tsx +210 -0
- package/src/ui/dev.tsx +16 -0
- package/src/ui/index.ts +2 -0
- package/src/ui/styles.css +274 -0
package/README.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @1kbirds/chidori-mock-slack
|
|
2
|
+
|
|
3
|
+
In-memory Slack mock for agent testing. The package provides:
|
|
4
|
+
|
|
5
|
+
- A deterministic in-memory workspace service.
|
|
6
|
+
- A Slack Web API-like client facade.
|
|
7
|
+
- A REST-style `/api/...` adapter.
|
|
8
|
+
- A React Slack review UI.
|
|
9
|
+
- Seed data for users, channels, direct messages, threads, reactions, and files.
|
|
10
|
+
|
|
11
|
+
## Supported Surface
|
|
12
|
+
|
|
13
|
+
Client methods:
|
|
14
|
+
|
|
15
|
+
- `auth.test`
|
|
16
|
+
- `users.list`
|
|
17
|
+
- `users.info`
|
|
18
|
+
- `conversations.list`
|
|
19
|
+
- `conversations.info`
|
|
20
|
+
- `conversations.join`
|
|
21
|
+
- `conversations.history`
|
|
22
|
+
- `conversations.replies`
|
|
23
|
+
- `chat.postMessage`
|
|
24
|
+
- `chat.update`
|
|
25
|
+
- `chat.delete`
|
|
26
|
+
- `reactions.add`
|
|
27
|
+
- `reactions.remove`
|
|
28
|
+
- `files.upload`
|
|
29
|
+
- `search.messages`
|
|
30
|
+
|
|
31
|
+
REST-style paths:
|
|
32
|
+
|
|
33
|
+
- `POST|GET /api/auth.test`
|
|
34
|
+
- `POST|GET /api/users.list`
|
|
35
|
+
- `POST|GET /api/users.info`
|
|
36
|
+
- `POST|GET /api/conversations.list`
|
|
37
|
+
- `POST|GET /api/conversations.info`
|
|
38
|
+
- `POST|GET /api/conversations.join`
|
|
39
|
+
- `POST|GET /api/conversations.history`
|
|
40
|
+
- `POST|GET /api/conversations.replies`
|
|
41
|
+
- `POST /api/chat.postMessage`
|
|
42
|
+
- `POST /api/chat.update`
|
|
43
|
+
- `POST /api/chat.delete`
|
|
44
|
+
- `POST /api/reactions.add`
|
|
45
|
+
- `POST /api/reactions.remove`
|
|
46
|
+
- `POST /api/files.upload`
|
|
47
|
+
- `POST|GET /api/search.messages`
|
|
48
|
+
|
|
49
|
+
## Search Support
|
|
50
|
+
|
|
51
|
+
The first implementation supports common search terms:
|
|
52
|
+
|
|
53
|
+
- Plain text across message text, channel name, and user name.
|
|
54
|
+
- `in:channel`
|
|
55
|
+
- `from:user`
|
|
56
|
+
- `has:reaction`
|
|
57
|
+
- `has:file`
|
|
58
|
+
|
|
59
|
+
## Review
|
|
60
|
+
|
|
61
|
+
Run verification:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
npm run build
|
|
65
|
+
npm test
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Start the React review app:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
npm run dev:slack
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Then open `http://127.0.0.1:5176/`.
|
|
75
|
+
|
|
76
|
+
Manual review should confirm:
|
|
77
|
+
|
|
78
|
+
- Seeded users, channels, direct messages, messages, reactions, files, and threads render.
|
|
79
|
+
- Posting a channel message updates history.
|
|
80
|
+
- Posting a thread reply updates thread replies and reply counts.
|
|
81
|
+
- Reactions can be added.
|
|
82
|
+
- Messages can be deleted.
|
|
83
|
+
- Mock file upload creates file metadata and a channel message.
|
|
84
|
+
- Search filters the visible conversation.
|
|
85
|
+
- Reset restores deterministic seeded state.
|
|
86
|
+
|
|
87
|
+
## Fidelity Notes
|
|
88
|
+
|
|
89
|
+
The mock intentionally keeps all state in memory. It focuses on common Slack workflows agents need to rehearse: listing channels/users, reading history, posting/updating/deleting messages, replying in threads, adding reactions, uploading file metadata, and searching messages. OAuth, Events API, Socket Mode, app manifests, granular permissions, enterprise grid, workflow builder, block kit rendering, and full search grammar are deferred.
|
package/dist/api.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type SlackMock } from "./service";
|
|
2
|
+
export interface SlackApiRequest {
|
|
3
|
+
method: "GET" | "POST";
|
|
4
|
+
path: string;
|
|
5
|
+
query?: Record<string, string | number | boolean | string[] | undefined>;
|
|
6
|
+
body?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export interface SlackApiResponse<T = unknown> {
|
|
9
|
+
status: number;
|
|
10
|
+
headers: Record<string, string>;
|
|
11
|
+
body: T;
|
|
12
|
+
}
|
|
13
|
+
export declare function handleSlackApiRequest(mock: SlackMock, request: SlackApiRequest): SlackApiResponse;
|
|
14
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAG5D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,OAAO;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC;CACT;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,eAAe,GAAG,gBAAgB,CAKjG"}
|
package/dist/api.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { asSlackResponse } from "./service";
|
|
2
|
+
export function handleSlackApiRequest(mock, request) {
|
|
3
|
+
const path = new URL(request.path, "https://slack.com").pathname.replace(/\/+$/, "");
|
|
4
|
+
const params = { ...(request.query ?? {}), ...(request.body ?? {}) };
|
|
5
|
+
const body = route(mock, path, params);
|
|
6
|
+
return { status: body && typeof body === "object" && "ok" in body && body.ok === false ? 200 : 200, headers: { "content-type": "application/json" }, body };
|
|
7
|
+
}
|
|
8
|
+
function route(mock, path, params) {
|
|
9
|
+
if (path === "/api/auth.test")
|
|
10
|
+
return asSlackResponse(() => mock.authTest());
|
|
11
|
+
if (path === "/api/users.list")
|
|
12
|
+
return asSlackResponse(() => mock.listUsers());
|
|
13
|
+
if (path === "/api/users.info")
|
|
14
|
+
return asSlackResponse(() => mock.infoUser(String(params.user)));
|
|
15
|
+
if (path === "/api/conversations.list")
|
|
16
|
+
return asSlackResponse(() => mock.listConversations({ types: stringParam(params.types), exclude_archived: boolParam(params.exclude_archived) }));
|
|
17
|
+
if (path === "/api/conversations.info")
|
|
18
|
+
return asSlackResponse(() => mock.infoConversation(String(params.channel)));
|
|
19
|
+
if (path === "/api/conversations.join")
|
|
20
|
+
return asSlackResponse(() => mock.joinConversation(String(params.channel)));
|
|
21
|
+
if (path === "/api/conversations.history")
|
|
22
|
+
return asSlackResponse(() => mock.history({
|
|
23
|
+
channel: String(params.channel),
|
|
24
|
+
latest: stringParam(params.latest),
|
|
25
|
+
oldest: stringParam(params.oldest),
|
|
26
|
+
inclusive: boolParam(params.inclusive),
|
|
27
|
+
limit: numberParam(params.limit),
|
|
28
|
+
}));
|
|
29
|
+
if (path === "/api/conversations.replies")
|
|
30
|
+
return asSlackResponse(() => mock.replies({ channel: String(params.channel), ts: String(params.ts), limit: numberParam(params.limit) }));
|
|
31
|
+
if (path === "/api/chat.postMessage")
|
|
32
|
+
return asSlackResponse(() => mock.postMessage(params));
|
|
33
|
+
if (path === "/api/chat.update")
|
|
34
|
+
return asSlackResponse(() => mock.updateMessage(String(params.channel), String(params.ts), String(params.text)));
|
|
35
|
+
if (path === "/api/chat.delete")
|
|
36
|
+
return asSlackResponse(() => mock.deleteMessage(String(params.channel), String(params.ts)));
|
|
37
|
+
if (path === "/api/reactions.add")
|
|
38
|
+
return asSlackResponse(() => mock.addReaction(String(params.channel), String(params.timestamp), String(params.name)));
|
|
39
|
+
if (path === "/api/reactions.remove")
|
|
40
|
+
return asSlackResponse(() => mock.removeReaction(String(params.channel), String(params.timestamp), String(params.name)));
|
|
41
|
+
if (path === "/api/files.upload")
|
|
42
|
+
return asSlackResponse(() => mock.uploadFile({
|
|
43
|
+
channels: arrayParam(params.channels),
|
|
44
|
+
filename: String(params.filename),
|
|
45
|
+
title: stringParam(params.title),
|
|
46
|
+
content: stringParam(params.content),
|
|
47
|
+
filetype: stringParam(params.filetype),
|
|
48
|
+
mimetype: stringParam(params.mimetype),
|
|
49
|
+
}));
|
|
50
|
+
if (path === "/api/search.messages")
|
|
51
|
+
return asSlackResponse(() => mock.searchMessages(String(params.query)));
|
|
52
|
+
return { ok: false, error: "unknown_method" };
|
|
53
|
+
}
|
|
54
|
+
function stringParam(value) {
|
|
55
|
+
return value === undefined ? undefined : String(value);
|
|
56
|
+
}
|
|
57
|
+
function boolParam(value) {
|
|
58
|
+
if (value === undefined)
|
|
59
|
+
return undefined;
|
|
60
|
+
return value === true || value === "true";
|
|
61
|
+
}
|
|
62
|
+
function numberParam(value) {
|
|
63
|
+
if (value === undefined)
|
|
64
|
+
return undefined;
|
|
65
|
+
const parsed = Number(value);
|
|
66
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
67
|
+
}
|
|
68
|
+
function arrayParam(value) {
|
|
69
|
+
if (Array.isArray(value))
|
|
70
|
+
return value.map(String);
|
|
71
|
+
if (typeof value === "string")
|
|
72
|
+
return value.split(",").map((item) => item.trim()).filter(Boolean);
|
|
73
|
+
return [];
|
|
74
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { type SlackMock } from "./service";
|
|
2
|
+
import type { SlackPostMessageRequest } from "./types";
|
|
3
|
+
export declare function createSlackClient(mock: SlackMock): {
|
|
4
|
+
auth: {
|
|
5
|
+
test: () => Promise<{
|
|
6
|
+
ok: false;
|
|
7
|
+
error: string;
|
|
8
|
+
} | {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
url: string;
|
|
11
|
+
team: string;
|
|
12
|
+
user: string;
|
|
13
|
+
team_id: string;
|
|
14
|
+
user_id: string;
|
|
15
|
+
}>;
|
|
16
|
+
};
|
|
17
|
+
users: {
|
|
18
|
+
list: () => Promise<{
|
|
19
|
+
ok: false;
|
|
20
|
+
error: string;
|
|
21
|
+
} | {
|
|
22
|
+
ok: boolean;
|
|
23
|
+
members: import("./types").SlackUser[];
|
|
24
|
+
}>;
|
|
25
|
+
info: ({ user }: {
|
|
26
|
+
user: string;
|
|
27
|
+
}) => Promise<{
|
|
28
|
+
ok: false;
|
|
29
|
+
error: string;
|
|
30
|
+
} | {
|
|
31
|
+
ok: boolean;
|
|
32
|
+
user: import("./types").SlackUser;
|
|
33
|
+
}>;
|
|
34
|
+
};
|
|
35
|
+
conversations: {
|
|
36
|
+
list: (params?: {
|
|
37
|
+
types?: string;
|
|
38
|
+
exclude_archived?: boolean;
|
|
39
|
+
}) => Promise<{
|
|
40
|
+
ok: false;
|
|
41
|
+
error: string;
|
|
42
|
+
} | {
|
|
43
|
+
ok: boolean;
|
|
44
|
+
channels: import("./types").SlackChannel[];
|
|
45
|
+
}>;
|
|
46
|
+
info: ({ channel }: {
|
|
47
|
+
channel: string;
|
|
48
|
+
}) => Promise<{
|
|
49
|
+
ok: false;
|
|
50
|
+
error: string;
|
|
51
|
+
} | {
|
|
52
|
+
ok: boolean;
|
|
53
|
+
channel: import("./types").SlackChannel;
|
|
54
|
+
}>;
|
|
55
|
+
join: ({ channel }: {
|
|
56
|
+
channel: string;
|
|
57
|
+
}) => Promise<{
|
|
58
|
+
ok: false;
|
|
59
|
+
error: string;
|
|
60
|
+
} | {
|
|
61
|
+
ok: boolean;
|
|
62
|
+
channel: import("./types").SlackChannel;
|
|
63
|
+
}>;
|
|
64
|
+
history: (params: {
|
|
65
|
+
channel: string;
|
|
66
|
+
latest?: string;
|
|
67
|
+
oldest?: string;
|
|
68
|
+
inclusive?: boolean;
|
|
69
|
+
limit?: number;
|
|
70
|
+
}) => Promise<{
|
|
71
|
+
ok: false;
|
|
72
|
+
error: string;
|
|
73
|
+
} | {
|
|
74
|
+
ok: boolean;
|
|
75
|
+
messages: import("./types").SlackMessage[];
|
|
76
|
+
has_more: boolean;
|
|
77
|
+
}>;
|
|
78
|
+
replies: (params: {
|
|
79
|
+
channel: string;
|
|
80
|
+
ts: string;
|
|
81
|
+
limit?: number;
|
|
82
|
+
}) => Promise<{
|
|
83
|
+
ok: false;
|
|
84
|
+
error: string;
|
|
85
|
+
} | {
|
|
86
|
+
ok: boolean;
|
|
87
|
+
messages: import("./types").SlackMessage[];
|
|
88
|
+
has_more: boolean;
|
|
89
|
+
}>;
|
|
90
|
+
};
|
|
91
|
+
chat: {
|
|
92
|
+
postMessage: (params: SlackPostMessageRequest) => Promise<{
|
|
93
|
+
ok: false;
|
|
94
|
+
error: string;
|
|
95
|
+
} | {
|
|
96
|
+
ok: boolean;
|
|
97
|
+
channel: string;
|
|
98
|
+
ts: string;
|
|
99
|
+
message: import("./types").SlackMessage;
|
|
100
|
+
}>;
|
|
101
|
+
update: ({ channel, ts, text }: {
|
|
102
|
+
channel: string;
|
|
103
|
+
ts: string;
|
|
104
|
+
text: string;
|
|
105
|
+
}) => Promise<{
|
|
106
|
+
ok: false;
|
|
107
|
+
error: string;
|
|
108
|
+
} | {
|
|
109
|
+
ok: boolean;
|
|
110
|
+
channel: string;
|
|
111
|
+
ts: string;
|
|
112
|
+
text: string;
|
|
113
|
+
message: import("./types").SlackMessage;
|
|
114
|
+
}>;
|
|
115
|
+
delete: ({ channel, ts }: {
|
|
116
|
+
channel: string;
|
|
117
|
+
ts: string;
|
|
118
|
+
}) => Promise<{
|
|
119
|
+
ok: false;
|
|
120
|
+
error: string;
|
|
121
|
+
} | {
|
|
122
|
+
ok: boolean;
|
|
123
|
+
channel: string;
|
|
124
|
+
ts: string;
|
|
125
|
+
}>;
|
|
126
|
+
};
|
|
127
|
+
reactions: {
|
|
128
|
+
add: ({ channel, timestamp, name }: {
|
|
129
|
+
channel: string;
|
|
130
|
+
timestamp: string;
|
|
131
|
+
name: string;
|
|
132
|
+
}) => Promise<{
|
|
133
|
+
ok: false;
|
|
134
|
+
error: string;
|
|
135
|
+
} | {
|
|
136
|
+
ok: boolean;
|
|
137
|
+
}>;
|
|
138
|
+
remove: ({ channel, timestamp, name }: {
|
|
139
|
+
channel: string;
|
|
140
|
+
timestamp: string;
|
|
141
|
+
name: string;
|
|
142
|
+
}) => Promise<{
|
|
143
|
+
ok: false;
|
|
144
|
+
error: string;
|
|
145
|
+
} | {
|
|
146
|
+
ok: boolean;
|
|
147
|
+
}>;
|
|
148
|
+
};
|
|
149
|
+
files: {
|
|
150
|
+
upload: (params: {
|
|
151
|
+
channels: string[];
|
|
152
|
+
filename: string;
|
|
153
|
+
title?: string;
|
|
154
|
+
content?: string;
|
|
155
|
+
filetype?: string;
|
|
156
|
+
mimetype?: string;
|
|
157
|
+
}) => Promise<{
|
|
158
|
+
ok: false;
|
|
159
|
+
error: string;
|
|
160
|
+
} | {
|
|
161
|
+
ok: boolean;
|
|
162
|
+
file: import("./types").SlackFile;
|
|
163
|
+
}>;
|
|
164
|
+
};
|
|
165
|
+
search: {
|
|
166
|
+
messages: ({ query }: {
|
|
167
|
+
query: string;
|
|
168
|
+
}) => Promise<({
|
|
169
|
+
ok: true;
|
|
170
|
+
} & import("./types").SlackSearchResult) | {
|
|
171
|
+
ok: false;
|
|
172
|
+
error: string;
|
|
173
|
+
}>;
|
|
174
|
+
};
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC5D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEvD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS;;;;;;;;;;;;;;;;;;;;;;yBAOpB;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE;;;;;;;;;wBAGlB;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;SAAE;;;;;;;4BACzC;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE;;;;;;;4BACnB;YAAE,OAAO,EAAE,MAAM,CAAA;SAAE;;;;;;;0BACrB;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,OAAO,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;0BAC1F;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;8BAG3C,uBAAuB;;;;;;;;;wCACb;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;kCACnD;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE;;;;;;;;;;4CAGrB;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE;;;;;;+CACjD;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE;;;;;;;;yBAG1E;YAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;YAAC,QAAQ,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE;;;;;;;;;8BAI3G;YAAE,KAAK,EAAE,MAAM,CAAA;SAAE;;;;;;;EAGlD"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { asSlackResponse } from "./service";
|
|
2
|
+
export function createSlackClient(mock) {
|
|
3
|
+
return {
|
|
4
|
+
auth: {
|
|
5
|
+
test: async () => asSlackResponse(() => mock.authTest()),
|
|
6
|
+
},
|
|
7
|
+
users: {
|
|
8
|
+
list: async () => asSlackResponse(() => mock.listUsers()),
|
|
9
|
+
info: async ({ user }) => asSlackResponse(() => mock.infoUser(user)),
|
|
10
|
+
},
|
|
11
|
+
conversations: {
|
|
12
|
+
list: async (params = {}) => asSlackResponse(() => mock.listConversations(params)),
|
|
13
|
+
info: async ({ channel }) => asSlackResponse(() => mock.infoConversation(channel)),
|
|
14
|
+
join: async ({ channel }) => asSlackResponse(() => mock.joinConversation(channel)),
|
|
15
|
+
history: async (params) => asSlackResponse(() => mock.history(params)),
|
|
16
|
+
replies: async (params) => asSlackResponse(() => mock.replies(params)),
|
|
17
|
+
},
|
|
18
|
+
chat: {
|
|
19
|
+
postMessage: async (params) => asSlackResponse(() => mock.postMessage(params)),
|
|
20
|
+
update: async ({ channel, ts, text }) => asSlackResponse(() => mock.updateMessage(channel, ts, text)),
|
|
21
|
+
delete: async ({ channel, ts }) => asSlackResponse(() => mock.deleteMessage(channel, ts)),
|
|
22
|
+
},
|
|
23
|
+
reactions: {
|
|
24
|
+
add: async ({ channel, timestamp, name }) => asSlackResponse(() => mock.addReaction(channel, timestamp, name)),
|
|
25
|
+
remove: async ({ channel, timestamp, name }) => asSlackResponse(() => mock.removeReaction(channel, timestamp, name)),
|
|
26
|
+
},
|
|
27
|
+
files: {
|
|
28
|
+
upload: async (params) => asSlackResponse(() => mock.uploadFile(params)),
|
|
29
|
+
},
|
|
30
|
+
search: {
|
|
31
|
+
messages: async ({ query }) => asSlackResponse(() => mock.searchMessages(query)),
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class SlackMockError extends Error {
|
|
2
|
+
readonly error: string;
|
|
3
|
+
constructor(error: string, message?: string);
|
|
4
|
+
toResponse(): {
|
|
5
|
+
ok: false;
|
|
6
|
+
error: string;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export declare function slackError(error: string, message?: string): SlackMockError;
|
|
10
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAEX,KAAK,EAAE,MAAM,EAAE,OAAO,SAAQ;IAM1C,UAAU,IAAI;QAAE,EAAE,EAAE,KAAK,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;CAG3C;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,cAAc,CAE1E"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export class SlackMockError extends Error {
|
|
2
|
+
error;
|
|
3
|
+
constructor(error, message = error) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "SlackMockError";
|
|
6
|
+
this.error = error;
|
|
7
|
+
}
|
|
8
|
+
toResponse() {
|
|
9
|
+
return { ok: false, error: this.error };
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function slackError(error, message) {
|
|
13
|
+
return new SlackMockError(error, message);
|
|
14
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { handleSlackApiRequest } from "./api";
|
|
2
|
+
export type { SlackApiRequest, SlackApiResponse } from "./api";
|
|
3
|
+
export { createSlackClient } from "./client";
|
|
4
|
+
export { SlackMockError } from "./errors";
|
|
5
|
+
export { asSlackResponse, SlackMock } from "./service";
|
|
6
|
+
import { SlackMock } from "./service";
|
|
7
|
+
export { demoChannels, demoFiles, demoMessages, demoSeed, demoTeam, demoUsers } from "./seed";
|
|
8
|
+
export type * from "./types";
|
|
9
|
+
export declare function createSlackMock(...args: ConstructorParameters<typeof SlackMock>): SlackMock;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AAC9C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC9F,mBAAmB,SAAS,CAAC;AAE7B,wBAAgB,eAAe,CAAC,GAAG,IAAI,EAAE,qBAAqB,CAAC,OAAO,SAAS,CAAC,GAAG,SAAS,CAE3F"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { handleSlackApiRequest } from "./api";
|
|
2
|
+
export { createSlackClient } from "./client";
|
|
3
|
+
export { SlackMockError } from "./errors";
|
|
4
|
+
export { asSlackResponse, SlackMock } from "./service";
|
|
5
|
+
import { SlackMock } from "./service";
|
|
6
|
+
export { demoChannels, demoFiles, demoMessages, demoSeed, demoTeam, demoUsers } from "./seed";
|
|
7
|
+
export function createSlackMock(...args) {
|
|
8
|
+
return new SlackMock(...args);
|
|
9
|
+
}
|
package/dist/seed.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SlackChannel, SlackFile, SlackMessage, SlackSeed, SlackTeam, SlackUser } from "./types";
|
|
2
|
+
export declare const demoTeam: SlackTeam;
|
|
3
|
+
export declare const demoUsers: SlackUser[];
|
|
4
|
+
export declare const demoChannels: SlackChannel[];
|
|
5
|
+
export declare const demoFiles: SlackFile[];
|
|
6
|
+
export declare const demoMessages: SlackMessage[];
|
|
7
|
+
export declare const demoSeed: SlackSeed;
|
|
8
|
+
//# sourceMappingURL=seed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../src/seed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEtG,eAAO,MAAM,QAAQ,EAAE,SAItB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,SAAS,EAwBhC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAAY,EA4CtC,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,SAAS,EAchC,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,YAAY,EAkCtC,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,SAOtB,CAAC"}
|
package/dist/seed.js
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
export const demoTeam = {
|
|
2
|
+
id: "TDEMO0001",
|
|
3
|
+
name: "Chidori Demo",
|
|
4
|
+
domain: "chidori-demo",
|
|
5
|
+
};
|
|
6
|
+
export const demoUsers = [
|
|
7
|
+
{
|
|
8
|
+
id: "UADA00001",
|
|
9
|
+
team_id: demoTeam.id,
|
|
10
|
+
name: "ada",
|
|
11
|
+
real_name: "Ada Lovelace",
|
|
12
|
+
is_admin: true,
|
|
13
|
+
profile: { email: "ada@example.com", display_name: "Ada", real_name: "Ada Lovelace" },
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
id: "UGRACE001",
|
|
17
|
+
team_id: demoTeam.id,
|
|
18
|
+
name: "grace",
|
|
19
|
+
real_name: "Grace Hopper",
|
|
20
|
+
profile: { email: "grace@example.com", display_name: "Grace", real_name: "Grace Hopper" },
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
id: "UBOT00001",
|
|
24
|
+
team_id: demoTeam.id,
|
|
25
|
+
name: "workflowbot",
|
|
26
|
+
real_name: "Workflow Bot",
|
|
27
|
+
is_bot: true,
|
|
28
|
+
profile: { display_name: "Workflow Bot", real_name: "Workflow Bot" },
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
export const demoChannels = [
|
|
32
|
+
{
|
|
33
|
+
id: "CGENERAL1",
|
|
34
|
+
name: "general",
|
|
35
|
+
is_channel: true,
|
|
36
|
+
is_private: false,
|
|
37
|
+
is_archived: false,
|
|
38
|
+
is_member: true,
|
|
39
|
+
created: 1780290000,
|
|
40
|
+
creator: "UADA00001",
|
|
41
|
+
topic: { value: "Company-wide announcements", creator: "UADA00001", last_set: 1780290000 },
|
|
42
|
+
purpose: { value: "Shared workspace discussion", creator: "UADA00001", last_set: 1780290000 },
|
|
43
|
+
num_members: 3,
|
|
44
|
+
members: ["UADA00001", "UGRACE001", "UBOT00001"],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: "CPROJECT1",
|
|
48
|
+
name: "project-launch",
|
|
49
|
+
is_channel: true,
|
|
50
|
+
is_private: false,
|
|
51
|
+
is_archived: false,
|
|
52
|
+
is_member: true,
|
|
53
|
+
created: 1780290000,
|
|
54
|
+
creator: "UADA00001",
|
|
55
|
+
topic: { value: "Launch planning", creator: "UADA00001", last_set: 1780290000 },
|
|
56
|
+
purpose: { value: "Coordinate launch work", creator: "UADA00001", last_set: 1780290000 },
|
|
57
|
+
num_members: 2,
|
|
58
|
+
members: ["UADA00001", "UGRACE001"],
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "DADA_GRACE",
|
|
62
|
+
name: "ada-grace",
|
|
63
|
+
is_channel: false,
|
|
64
|
+
is_im: true,
|
|
65
|
+
is_private: true,
|
|
66
|
+
is_archived: false,
|
|
67
|
+
is_member: true,
|
|
68
|
+
created: 1780290000,
|
|
69
|
+
creator: "UADA00001",
|
|
70
|
+
topic: { value: "" },
|
|
71
|
+
purpose: { value: "" },
|
|
72
|
+
num_members: 2,
|
|
73
|
+
members: ["UADA00001", "UGRACE001"],
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
export const demoFiles = [
|
|
77
|
+
{
|
|
78
|
+
id: "FBRIEF001",
|
|
79
|
+
created: 1780290100,
|
|
80
|
+
timestamp: 1780290100,
|
|
81
|
+
name: "launch-brief.txt",
|
|
82
|
+
title: "Launch Brief",
|
|
83
|
+
mimetype: "text/plain",
|
|
84
|
+
filetype: "text",
|
|
85
|
+
user: "UGRACE001",
|
|
86
|
+
size: 72,
|
|
87
|
+
content: "Launch brief fixture content",
|
|
88
|
+
url_private: "https://chidori-demo.slack.com/files/UGRACE001/FBRIEF001/launch-brief.txt",
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
export const demoMessages = [
|
|
92
|
+
{
|
|
93
|
+
type: "message",
|
|
94
|
+
channel: "CGENERAL1",
|
|
95
|
+
user: "UBOT00001",
|
|
96
|
+
username: "workflowbot",
|
|
97
|
+
text: "Daily workspace sync is ready.",
|
|
98
|
+
ts: "1780290050.000001",
|
|
99
|
+
reactions: [{ name: "white_check_mark", users: ["UADA00001"], count: 1 }],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
type: "message",
|
|
103
|
+
channel: "CPROJECT1",
|
|
104
|
+
user: "UGRACE001",
|
|
105
|
+
text: "Can someone review the launch brief before we send it to the customer?",
|
|
106
|
+
ts: "1780290100.000001",
|
|
107
|
+
files: [demoFiles[0]],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: "message",
|
|
111
|
+
channel: "CPROJECT1",
|
|
112
|
+
user: "UADA00001",
|
|
113
|
+
text: "I can review it this afternoon.",
|
|
114
|
+
ts: "1780290200.000001",
|
|
115
|
+
thread_ts: "1780290100.000001",
|
|
116
|
+
parent_user_id: "UGRACE001",
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
type: "message",
|
|
120
|
+
channel: "DADA_GRACE",
|
|
121
|
+
user: "UGRACE001",
|
|
122
|
+
text: "Thanks for handling the calendar invite.",
|
|
123
|
+
ts: "1780290300.000001",
|
|
124
|
+
},
|
|
125
|
+
];
|
|
126
|
+
export const demoSeed = {
|
|
127
|
+
team: demoTeam,
|
|
128
|
+
users: demoUsers,
|
|
129
|
+
channels: demoChannels,
|
|
130
|
+
messages: demoMessages,
|
|
131
|
+
files: demoFiles,
|
|
132
|
+
currentUserId: "UADA00001",
|
|
133
|
+
};
|