@kodelyth/googlechat 2026.5.39 → 2026.5.42

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 (91) hide show
  1. package/api.ts +3 -0
  2. package/channel-config-api.ts +1 -0
  3. package/channel-plugin-api.ts +1 -0
  4. package/config-api.ts +2 -0
  5. package/contract-api.ts +5 -0
  6. package/dist/actions-YK1wn4ed.js +160 -0
  7. package/dist/api-BkZX4VNX.js +633 -0
  8. package/dist/api.js +3 -0
  9. package/dist/channel-DFZdjXD6.js +584 -0
  10. package/dist/channel-config-api.js +6 -0
  11. package/dist/channel-plugin-api.js +2 -0
  12. package/dist/channel.runtime-en3RNg9S.js +998 -0
  13. package/dist/contract-api.js +3 -0
  14. package/dist/doctor-contract-8SF6XoKj.js +151 -0
  15. package/dist/doctor-contract-api.js +2 -0
  16. package/dist/index.js +22 -0
  17. package/dist/runtime-api-DUH2Cg-0.js +29 -0
  18. package/dist/runtime-api.js +2 -0
  19. package/dist/secret-contract-DWX4ikgT.js +99 -0
  20. package/dist/secret-contract-api.js +2 -0
  21. package/dist/setup-entry.js +15 -0
  22. package/dist/setup-plugin-api.js +75 -0
  23. package/dist/setup-surface-B3Fa7XRx.js +321 -0
  24. package/dist/test-api.js +3 -0
  25. package/doctor-contract-api.ts +1 -0
  26. package/index.ts +20 -0
  27. package/klaw.plugin.json +2 -967
  28. package/package.json +4 -4
  29. package/runtime-api.ts +55 -0
  30. package/secret-contract-api.ts +5 -0
  31. package/setup-entry.ts +13 -0
  32. package/setup-plugin-api.ts +3 -0
  33. package/src/accounts.ts +181 -0
  34. package/src/actions.test.ts +289 -0
  35. package/src/actions.ts +227 -0
  36. package/src/api.ts +316 -0
  37. package/src/approval-auth.test.ts +24 -0
  38. package/src/approval-auth.ts +32 -0
  39. package/src/auth.ts +218 -0
  40. package/src/channel-config.test.ts +39 -0
  41. package/src/channel.adapters.ts +340 -0
  42. package/src/channel.deps.runtime.ts +29 -0
  43. package/src/channel.runtime.ts +17 -0
  44. package/src/channel.setup.ts +98 -0
  45. package/src/channel.test.ts +784 -0
  46. package/src/channel.ts +277 -0
  47. package/src/config-schema.test.ts +31 -0
  48. package/src/config-schema.ts +3 -0
  49. package/src/doctor-contract.test.ts +75 -0
  50. package/src/doctor-contract.ts +182 -0
  51. package/src/doctor.ts +57 -0
  52. package/src/gateway.ts +63 -0
  53. package/src/google-auth.runtime.test.ts +543 -0
  54. package/src/google-auth.runtime.ts +568 -0
  55. package/src/group-policy.ts +17 -0
  56. package/src/monitor-access.test.ts +491 -0
  57. package/src/monitor-access.ts +465 -0
  58. package/src/monitor-durable.test.ts +39 -0
  59. package/src/monitor-durable.ts +23 -0
  60. package/src/monitor-reply-delivery.ts +156 -0
  61. package/src/monitor-routing.ts +65 -0
  62. package/src/monitor-types.ts +33 -0
  63. package/src/monitor-webhook.test.ts +587 -0
  64. package/src/monitor-webhook.ts +303 -0
  65. package/src/monitor.reply-delivery.test.ts +144 -0
  66. package/src/monitor.test.ts +159 -0
  67. package/src/monitor.ts +527 -0
  68. package/src/monitor.webhook-routing.test.ts +257 -0
  69. package/src/runtime.ts +9 -0
  70. package/src/secret-contract.test.ts +60 -0
  71. package/src/secret-contract.ts +161 -0
  72. package/src/setup-core.ts +40 -0
  73. package/src/setup-surface.ts +243 -0
  74. package/src/setup.test.ts +619 -0
  75. package/src/targets.test.ts +453 -0
  76. package/src/targets.ts +66 -0
  77. package/src/types.config.ts +3 -0
  78. package/src/types.ts +73 -0
  79. package/test-api.ts +2 -0
  80. package/tsconfig.json +16 -0
  81. package/api.js +0 -7
  82. package/channel-config-api.js +0 -7
  83. package/channel-plugin-api.js +0 -7
  84. package/contract-api.js +0 -7
  85. package/doctor-contract-api.js +0 -7
  86. package/index.js +0 -7
  87. package/runtime-api.js +0 -7
  88. package/secret-contract-api.js +0 -7
  89. package/setup-entry.js +0 -7
  90. package/setup-plugin-api.js +0 -7
  91. package/test-api.js +0 -7
@@ -0,0 +1,243 @@
1
+ import {
2
+ addWildcardAllowFrom,
3
+ applySetupAccountConfigPatch,
4
+ createPromptParsedAllowFromForAccount,
5
+ createStandardChannelSetupStatus,
6
+ DEFAULT_ACCOUNT_ID,
7
+ formatDocsLink,
8
+ mergeAllowFromEntries,
9
+ migrateBaseNameToDefaultAccount,
10
+ splitSetupEntries,
11
+ createSetupTranslator,
12
+ type ChannelSetupDmPolicy,
13
+ type ChannelSetupWizard,
14
+ } from "klaw/plugin-sdk/setup";
15
+ import {
16
+ normalizeOptionalString,
17
+ normalizeStringifiedOptionalString,
18
+ } from "klaw/plugin-sdk/string-coerce-runtime";
19
+ import { resolveDefaultGoogleChatAccountId, resolveGoogleChatAccount } from "./accounts.js";
20
+
21
+ const t = createSetupTranslator();
22
+
23
+ const channel = "googlechat" as const;
24
+ const ENV_SERVICE_ACCOUNT = "GOOGLE_CHAT_SERVICE_ACCOUNT";
25
+ const ENV_SERVICE_ACCOUNT_FILE = "GOOGLE_CHAT_SERVICE_ACCOUNT_FILE";
26
+ const USE_ENV_FLAG = "__googlechatUseEnv";
27
+ const AUTH_METHOD_FLAG = "__googlechatAuthMethod";
28
+
29
+ type GoogleChatTextInput = NonNullable<ChannelSetupWizard["textInputs"]>[number];
30
+ type GoogleChatTextInputKey = GoogleChatTextInput["inputKey"];
31
+
32
+ const promptAllowFrom = createPromptParsedAllowFromForAccount({
33
+ defaultAccountId: resolveDefaultGoogleChatAccountId,
34
+ message: t("wizard.googlechat.allowFromPrompt"),
35
+ placeholder: "users/123456789, name@example.com",
36
+ parseEntries: (raw) => ({
37
+ entries: mergeAllowFromEntries(undefined, splitSetupEntries(raw)),
38
+ }),
39
+ getExistingAllowFrom: ({ cfg, accountId }) =>
40
+ resolveGoogleChatAccount({ cfg, accountId }).config.dm?.allowFrom ?? [],
41
+ applyAllowFrom: ({ cfg, accountId, allowFrom }) =>
42
+ applySetupAccountConfigPatch({
43
+ cfg,
44
+ channelKey: channel,
45
+ accountId,
46
+ patch: {
47
+ dm: {
48
+ ...resolveGoogleChatAccount({ cfg, accountId }).config.dm,
49
+ allowFrom,
50
+ },
51
+ },
52
+ }),
53
+ });
54
+
55
+ const googlechatDmPolicy: ChannelSetupDmPolicy = {
56
+ label: "Google Chat",
57
+ channel,
58
+ policyKey: "channels.googlechat.dm.policy",
59
+ allowFromKey: "channels.googlechat.dm.allowFrom",
60
+ resolveConfigKeys: (cfg, accountId) =>
61
+ (accountId ?? resolveDefaultGoogleChatAccountId(cfg)) !== DEFAULT_ACCOUNT_ID
62
+ ? {
63
+ policyKey: `channels.googlechat.accounts.${accountId ?? resolveDefaultGoogleChatAccountId(cfg)}.dm.policy`,
64
+ allowFromKey: `channels.googlechat.accounts.${accountId ?? resolveDefaultGoogleChatAccountId(cfg)}.dm.allowFrom`,
65
+ }
66
+ : {
67
+ policyKey: "channels.googlechat.dm.policy",
68
+ allowFromKey: "channels.googlechat.dm.allowFrom",
69
+ },
70
+ getCurrent: (cfg, accountId) =>
71
+ resolveGoogleChatAccount({
72
+ cfg,
73
+ accountId: accountId ?? resolveDefaultGoogleChatAccountId(cfg),
74
+ }).config.dm?.policy ?? "pairing",
75
+ setPolicy: (cfg, policy, accountId) => {
76
+ const resolvedAccountId = accountId ?? resolveDefaultGoogleChatAccountId(cfg);
77
+ const currentDm = resolveGoogleChatAccount({
78
+ cfg,
79
+ accountId: resolvedAccountId,
80
+ }).config.dm;
81
+ return applySetupAccountConfigPatch({
82
+ cfg,
83
+ channelKey: channel,
84
+ accountId: resolvedAccountId,
85
+ patch: {
86
+ dm: {
87
+ ...currentDm,
88
+ policy,
89
+ ...(policy === "open" ? { allowFrom: addWildcardAllowFrom(currentDm?.allowFrom) } : {}),
90
+ },
91
+ },
92
+ });
93
+ },
94
+ promptAllowFrom,
95
+ };
96
+
97
+ function createServiceAccountTextInput(params: {
98
+ inputKey: GoogleChatTextInputKey;
99
+ message: string;
100
+ placeholder: string;
101
+ authMethod: "file" | "inline";
102
+ patchKey: "serviceAccountFile" | "serviceAccount";
103
+ }): GoogleChatTextInput {
104
+ return {
105
+ inputKey: params.inputKey,
106
+ message: params.message,
107
+ placeholder: params.placeholder,
108
+ shouldPrompt: ({ credentialValues }) =>
109
+ credentialValues[USE_ENV_FLAG] !== "1" &&
110
+ credentialValues[AUTH_METHOD_FLAG] === params.authMethod,
111
+ validate: ({ value }) => (normalizeStringifiedOptionalString(value) ? undefined : "Required"),
112
+ normalizeValue: ({ value }) => normalizeStringifiedOptionalString(value) ?? "",
113
+ applySet: async ({ cfg, accountId, value }) =>
114
+ applySetupAccountConfigPatch({
115
+ cfg,
116
+ channelKey: channel,
117
+ accountId,
118
+ patch: { [params.patchKey]: value },
119
+ }),
120
+ };
121
+ }
122
+
123
+ export const googlechatSetupWizard: ChannelSetupWizard = {
124
+ channel,
125
+ status: createStandardChannelSetupStatus({
126
+ channelLabel: "Google Chat",
127
+ configuredLabel: t("wizard.channels.statusConfigured"),
128
+ unconfiguredLabel: t("wizard.channels.statusNeedsServiceAccount"),
129
+ configuredHint: t("wizard.channels.statusConfigured"),
130
+ unconfiguredHint: t("wizard.channels.statusNeedsAuth"),
131
+ includeStatusLine: true,
132
+ resolveConfigured: ({ cfg, accountId }) =>
133
+ resolveGoogleChatAccount({ cfg, accountId }).credentialSource !== "none",
134
+ }),
135
+ introNote: {
136
+ title: t("wizard.googlechat.setupTitle"),
137
+ lines: [
138
+ t("wizard.googlechat.setupServiceAccount"),
139
+ t("wizard.googlechat.setupScopes"),
140
+ t("wizard.googlechat.setupAudience"),
141
+ t("wizard.channels.docs", { link: formatDocsLink("/channels/googlechat", "googlechat") }),
142
+ ],
143
+ },
144
+ prepare: async ({ cfg, accountId, credentialValues, prompter }) => {
145
+ const envReady =
146
+ accountId === DEFAULT_ACCOUNT_ID &&
147
+ (Boolean(process.env[ENV_SERVICE_ACCOUNT]) || Boolean(process.env[ENV_SERVICE_ACCOUNT_FILE]));
148
+ if (envReady) {
149
+ const useEnv = await prompter.confirm({
150
+ message: t("wizard.googlechat.useEnvPrompt"),
151
+ initialValue: true,
152
+ });
153
+ if (useEnv) {
154
+ return {
155
+ cfg: applySetupAccountConfigPatch({
156
+ cfg,
157
+ channelKey: channel,
158
+ accountId,
159
+ patch: {},
160
+ }),
161
+ credentialValues: {
162
+ ...credentialValues,
163
+ [USE_ENV_FLAG]: "1",
164
+ },
165
+ };
166
+ }
167
+ }
168
+
169
+ const method = await prompter.select({
170
+ message: t("wizard.googlechat.authMethod"),
171
+ options: [
172
+ { value: "file", label: t("wizard.googlechat.serviceAccountFile") },
173
+ { value: "inline", label: t("wizard.googlechat.serviceAccountInline") },
174
+ ],
175
+ initialValue: "file",
176
+ });
177
+
178
+ return {
179
+ credentialValues: {
180
+ ...credentialValues,
181
+ [USE_ENV_FLAG]: "0",
182
+ [AUTH_METHOD_FLAG]: method,
183
+ },
184
+ };
185
+ },
186
+ credentials: [],
187
+ textInputs: [
188
+ createServiceAccountTextInput({
189
+ inputKey: "tokenFile",
190
+ message: t("wizard.googlechat.serviceAccountPath"),
191
+ placeholder: "/path/to/service-account.json",
192
+ authMethod: "file",
193
+ patchKey: "serviceAccountFile",
194
+ }),
195
+ createServiceAccountTextInput({
196
+ inputKey: "token",
197
+ message: t("wizard.googlechat.serviceAccountJson"),
198
+ placeholder: '{"type":"service_account", ... }',
199
+ authMethod: "inline",
200
+ patchKey: "serviceAccount",
201
+ }),
202
+ ],
203
+ finalize: async ({ cfg, accountId, prompter }) => {
204
+ const account = resolveGoogleChatAccount({
205
+ cfg,
206
+ accountId,
207
+ });
208
+ const audienceType = await prompter.select({
209
+ message: t("wizard.googlechat.webhookAudienceType"),
210
+ options: [
211
+ { value: "app-url", label: t("wizard.googlechat.appUrlRecommended") },
212
+ { value: "project-number", label: t("wizard.googlechat.projectNumber") },
213
+ ],
214
+ initialValue: account.config.audienceType === "project-number" ? "project-number" : "app-url",
215
+ });
216
+ const audience = await prompter.text({
217
+ message:
218
+ audienceType === "project-number"
219
+ ? t("wizard.googlechat.projectNumber")
220
+ : t("wizard.googlechat.appUrl"),
221
+ placeholder:
222
+ audienceType === "project-number" ? "1234567890" : "https://your.host/googlechat",
223
+ initialValue: account.config.audience || undefined,
224
+ validate: (value) =>
225
+ normalizeStringifiedOptionalString(value) ? undefined : t("common.required"),
226
+ });
227
+ return {
228
+ cfg: migrateBaseNameToDefaultAccount({
229
+ cfg: applySetupAccountConfigPatch({
230
+ cfg,
231
+ channelKey: channel,
232
+ accountId,
233
+ patch: {
234
+ audienceType,
235
+ audience: normalizeOptionalString(audience) ?? "",
236
+ },
237
+ }),
238
+ channelKey: channel,
239
+ }),
240
+ };
241
+ },
242
+ dmPolicy: googlechatDmPolicy,
243
+ };