@spectrum-ts/slack 12.0.0 → 12.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/dist/index.d.ts +1 -1
- package/dist/index.js +14 -79
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ type SlackMessage = SchemaMessage<typeof userSchema, typeof spaceSchema> & {
|
|
|
15
15
|
};
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/index.d.ts
|
|
18
|
-
declare const slack: import("@spectrum-ts/core").Platform<import("@spectrum-ts/core").PlatformDef<"
|
|
18
|
+
declare const slack: import("@spectrum-ts/core").Platform<import("@spectrum-ts/core").PlatformDef<"slack", import("zod").ZodUnion<readonly [import("zod").ZodObject<{
|
|
19
19
|
endpoint: import("zod").ZodOptional<import("zod").ZodString>;
|
|
20
20
|
teams: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodObject<{
|
|
21
21
|
appId: import("zod").ZodString;
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
import { createClient, staticTokens } from "@photon-ai/slack";
|
|
2
2
|
import { UnsupportedError, cloud, definePlatform, mergeStreams, stream } from "@spectrum-ts/core";
|
|
3
|
-
import { asAttachment, asCustom, asReaction, asText,
|
|
3
|
+
import { asAttachment, asCustom, asReaction, asText, createTokenRenewal } from "@spectrum-ts/core/authoring";
|
|
4
4
|
import z from "zod";
|
|
5
5
|
//#region src/auth.ts
|
|
6
|
-
const log = createLogger("spectrum.slack.auth");
|
|
7
|
-
const RENEWAL_RATIO = .8;
|
|
8
|
-
const EXPIRY_BUFFER_MS = 3e4;
|
|
9
|
-
const RETRY_DELAY_MS = 3e4;
|
|
10
6
|
const cloudAuthState = /* @__PURE__ */ new WeakMap();
|
|
11
7
|
const toTeamMetadata = (meta) => ({
|
|
12
8
|
appId: meta.appId,
|
|
@@ -26,96 +22,34 @@ const toTeamMetadata = (meta) => ({
|
|
|
26
22
|
*/
|
|
27
23
|
async function createCloudClients(projectId, projectSecret, endpoint) {
|
|
28
24
|
let tokenData = await cloud.issueSlackTokens(projectId, projectSecret);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
if (renewalTimer !== void 0) {
|
|
35
|
-
clearTimeout(renewalTimer);
|
|
36
|
-
renewalTimer = void 0;
|
|
25
|
+
const renewal = createTokenRenewal({
|
|
26
|
+
expiresInSeconds: () => tokenData.expiresIn,
|
|
27
|
+
name: "slack",
|
|
28
|
+
refresh: async () => {
|
|
29
|
+
tokenData = await cloud.issueSlackTokens(projectId, projectSecret);
|
|
37
30
|
}
|
|
38
|
-
};
|
|
39
|
-
const refreshTokens = async () => {
|
|
40
|
-
tokenData = await cloud.issueSlackTokens(projectId, projectSecret);
|
|
41
|
-
tokenExpiresAt = Date.now() + tokenData.expiresIn * 1e3;
|
|
42
|
-
};
|
|
43
|
-
const onRefreshSuccess = () => {
|
|
44
|
-
if (refreshFailures > 0) {
|
|
45
|
-
log.info("slack token refresh recovered", { "spectrum.slack.auth.attempt": refreshFailures });
|
|
46
|
-
refreshFailures = 0;
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
const onRefreshFailure = (error) => {
|
|
50
|
-
refreshFailures += 1;
|
|
51
|
-
log.warn("slack token refresh failed; retrying", {
|
|
52
|
-
"spectrum.slack.auth.attempt": refreshFailures,
|
|
53
|
-
"spectrum.slack.auth.retry_in_ms": RETRY_DELAY_MS,
|
|
54
|
-
...errorAttrs(error)
|
|
55
|
-
}, error);
|
|
56
|
-
};
|
|
57
|
-
const scheduleRetry = () => {
|
|
58
|
-
if (disposed) return;
|
|
59
|
-
clearRenewalTimer();
|
|
60
|
-
renewalTimer = setTimeout(async () => {
|
|
61
|
-
if (disposed) return;
|
|
62
|
-
try {
|
|
63
|
-
await refreshTokens();
|
|
64
|
-
onRefreshSuccess();
|
|
65
|
-
scheduleRenewal();
|
|
66
|
-
} catch (retryErr) {
|
|
67
|
-
onRefreshFailure(retryErr);
|
|
68
|
-
scheduleRetry();
|
|
69
|
-
}
|
|
70
|
-
}, RETRY_DELAY_MS);
|
|
71
|
-
renewalTimer?.unref?.();
|
|
72
|
-
};
|
|
73
|
-
const scheduleRenewal = () => {
|
|
74
|
-
if (disposed) return;
|
|
75
|
-
clearRenewalTimer();
|
|
76
|
-
const ttlMs = tokenData.expiresIn * 1e3;
|
|
77
|
-
const renewInMs = Math.max(ttlMs * RENEWAL_RATIO, 5e3);
|
|
78
|
-
renewalTimer = setTimeout(async () => {
|
|
79
|
-
try {
|
|
80
|
-
await refreshTokens();
|
|
81
|
-
onRefreshSuccess();
|
|
82
|
-
scheduleRenewal();
|
|
83
|
-
} catch (err) {
|
|
84
|
-
onRefreshFailure(err);
|
|
85
|
-
scheduleRetry();
|
|
86
|
-
}
|
|
87
|
-
}, renewInMs);
|
|
88
|
-
renewalTimer?.unref?.();
|
|
89
|
-
};
|
|
90
|
-
const refreshIfNeeded = async () => {
|
|
91
|
-
if (Date.now() < tokenExpiresAt - EXPIRY_BUFFER_MS) return;
|
|
92
|
-
await refreshTokens();
|
|
93
|
-
onRefreshSuccess();
|
|
94
|
-
scheduleRenewal();
|
|
95
|
-
};
|
|
96
|
-
scheduleRenewal();
|
|
31
|
+
});
|
|
97
32
|
const client = createClient({
|
|
98
33
|
spectrumSlackEndpoint: endpoint,
|
|
99
34
|
tokenProvider: {
|
|
100
35
|
async getAccessToken(teamId) {
|
|
101
|
-
await refreshIfNeeded();
|
|
36
|
+
await renewal.refreshIfNeeded();
|
|
102
37
|
const token = tokenData.auth[teamId];
|
|
103
38
|
if (!token) throw new Error(`Slack team ${teamId} has no active installation in this project`);
|
|
104
39
|
return token;
|
|
105
40
|
},
|
|
106
41
|
invalidate(_teamId) {
|
|
107
|
-
|
|
42
|
+
renewal.invalidate();
|
|
108
43
|
},
|
|
109
44
|
async listTeams() {
|
|
110
|
-
await refreshIfNeeded();
|
|
45
|
+
await renewal.refreshIfNeeded();
|
|
111
46
|
const entries = Object.entries(tokenData.teams).map(([teamId, meta]) => [teamId, toTeamMetadata(meta)]);
|
|
112
47
|
return new Map(entries);
|
|
113
48
|
}
|
|
114
49
|
}
|
|
115
50
|
});
|
|
116
51
|
cloudAuthState.set(client, { dispose: async () => {
|
|
117
|
-
|
|
118
|
-
clearRenewalTimer();
|
|
52
|
+
renewal.dispose();
|
|
119
53
|
} });
|
|
120
54
|
return client;
|
|
121
55
|
}
|
|
@@ -404,7 +338,8 @@ const messageSchema = z.object({
|
|
|
404
338
|
});
|
|
405
339
|
//#endregion
|
|
406
340
|
//#region src/index.ts
|
|
407
|
-
const
|
|
341
|
+
const PLATFORM_ID = "slack";
|
|
342
|
+
const slack = definePlatform(PLATFORM_ID, {
|
|
408
343
|
config: configSchema,
|
|
409
344
|
lifecycle: {
|
|
410
345
|
createClient: async ({ config, projectId, projectSecret }) => {
|
|
@@ -433,7 +368,7 @@ const slack = definePlatform("Slack", {
|
|
|
433
368
|
create: async ({ input }) => {
|
|
434
369
|
const teamId = input.params?.teamId;
|
|
435
370
|
if (!teamId) throw new Error("Slack space creation requires a teamId param. Pass it via space.create(user, { teamId }).");
|
|
436
|
-
if (input.users.length > 1) throw UnsupportedError.action("space.create",
|
|
371
|
+
if (input.users.length > 1) throw UnsupportedError.action("space.create", PLATFORM_ID, "group DMs require an explicit channel id (Slack's conversations.open is not exposed); use space.get(channelId, { teamId })");
|
|
437
372
|
const user = input.users[0];
|
|
438
373
|
if (!user) throw new Error("Slack space creation requires a user");
|
|
439
374
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spectrum-ts/slack",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.1.0",
|
|
4
4
|
"description": "Slack provider for spectrum-ts.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"spectrum": {
|
|
29
29
|
"key": "slack",
|
|
30
30
|
"import": "slack",
|
|
31
|
-
"label": "
|
|
31
|
+
"label": "slack"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@photon-ai/slack": "^0.2.0",
|