patchwork-os 0.2.0-alpha.26 → 0.2.0-alpha.27
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/deploy/bootstrap-vps.sh +1 -1
- package/deploy/deploy-dashboard.sh +164 -0
- package/deploy/deploy-landing.sh +79 -0
- package/dist/ccPermissions.js +6 -4
- package/dist/ccPermissions.js.map +1 -1
- package/dist/commands/recipe.js +1 -1
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/recipeInstall.d.ts +72 -0
- package/dist/commands/recipeInstall.js +339 -0
- package/dist/commands/recipeInstall.js.map +1 -0
- package/dist/connectors/datadog.d.ts +116 -0
- package/dist/connectors/datadog.js +385 -0
- package/dist/connectors/datadog.js.map +1 -0
- package/dist/connectors/hubspot.d.ts +112 -0
- package/dist/connectors/hubspot.js +408 -0
- package/dist/connectors/hubspot.js.map +1 -0
- package/dist/connectors/intercom.d.ts +102 -0
- package/dist/connectors/intercom.js +402 -0
- package/dist/connectors/intercom.js.map +1 -0
- package/dist/connectors/stripe.d.ts +116 -0
- package/dist/connectors/stripe.js +379 -0
- package/dist/connectors/stripe.js.map +1 -0
- package/dist/index.js +33 -26
- package/dist/index.js.map +1 -1
- package/dist/recipes/manifest.d.ts +47 -0
- package/dist/recipes/manifest.js +141 -0
- package/dist/recipes/manifest.js.map +1 -0
- package/dist/recipes/schemaGenerator.js +3 -3
- package/dist/recipes/schemaGenerator.js.map +1 -1
- package/dist/recipes/tools/datadog.d.ts +6 -0
- package/dist/recipes/tools/datadog.js +239 -0
- package/dist/recipes/tools/datadog.js.map +1 -0
- package/dist/recipes/tools/hubspot.d.ts +6 -0
- package/dist/recipes/tools/hubspot.js +232 -0
- package/dist/recipes/tools/hubspot.js.map +1 -0
- package/dist/recipes/tools/index.d.ts +4 -0
- package/dist/recipes/tools/index.js +4 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/intercom.d.ts +6 -0
- package/dist/recipes/tools/intercom.js +226 -0
- package/dist/recipes/tools/intercom.js.map +1 -0
- package/dist/recipes/tools/stripe.d.ts +6 -0
- package/dist/recipes/tools/stripe.js +265 -0
- package/dist/recipes/tools/stripe.js.map +1 -0
- package/dist/recipes/yamlRunner.js +28 -0
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/schemas/dry-run-plan.v1.json +1 -1
- package/dist/schemas/recipe.v1.json +1 -1
- package/dist/server.js +155 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/searchTools.js +1 -1
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/tools/testTraceToSource.js +2 -2
- package/dist/tools/testTraceToSource.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HubSpot connector — read/write HubSpot CRM via the HubSpot REST API v3.
|
|
3
|
+
*
|
|
4
|
+
* Auth: Private App access token (Bearer).
|
|
5
|
+
* - Env var: HUBSPOT_ACCESS_TOKEN
|
|
6
|
+
* - Stored: getSecretJsonSync("hubspot") → HubSpotTokens
|
|
7
|
+
*
|
|
8
|
+
* Tools: listContacts, getContact, listDeals, getDeal, createNote, searchContacts
|
|
9
|
+
*
|
|
10
|
+
* Extends BaseConnector for unified auth, retry, rate-limit, error handling.
|
|
11
|
+
*/
|
|
12
|
+
import { BaseConnector, } from "./baseConnector.js";
|
|
13
|
+
import { deleteSecretJsonSync, getSecretJsonSync, storeSecretJsonSync, } from "./tokenStorage.js";
|
|
14
|
+
const HUBSPOT_BASE = "https://api.hubapi.com";
|
|
15
|
+
export class HubSpotConnector extends BaseConnector {
|
|
16
|
+
providerName = "hubspot";
|
|
17
|
+
getOAuthConfig() {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
async authenticate() {
|
|
21
|
+
const tokens = loadTokens();
|
|
22
|
+
if (!tokens) {
|
|
23
|
+
throw new Error("HubSpot not connected. Run: patchwork-os connect hubspot or set HUBSPOT_ACCESS_TOKEN");
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
token: tokens.accessToken,
|
|
27
|
+
scopes: ["read", "write"],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async healthCheck() {
|
|
31
|
+
try {
|
|
32
|
+
const result = await this.apiCall(async (token) => {
|
|
33
|
+
const res = await fetch(`${HUBSPOT_BASE}/account-info/v3/details`, {
|
|
34
|
+
headers: this.buildHeaders(token),
|
|
35
|
+
});
|
|
36
|
+
if (!res.ok)
|
|
37
|
+
throw new Error(`HTTP ${res.status}`);
|
|
38
|
+
return res.json();
|
|
39
|
+
});
|
|
40
|
+
if ("error" in result)
|
|
41
|
+
return { ok: false, error: result.error };
|
|
42
|
+
return { ok: true };
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
return { ok: false, error: this.normalizeError(err) };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
normalizeError(error) {
|
|
49
|
+
if (error instanceof Response) {
|
|
50
|
+
const s = error.status;
|
|
51
|
+
if (s === 401)
|
|
52
|
+
return {
|
|
53
|
+
code: "auth_expired",
|
|
54
|
+
message: "HubSpot authentication expired — reconnect",
|
|
55
|
+
retryable: false,
|
|
56
|
+
suggestedAction: "patchwork-os connect hubspot",
|
|
57
|
+
};
|
|
58
|
+
if (s === 403)
|
|
59
|
+
return {
|
|
60
|
+
code: "permission_denied",
|
|
61
|
+
message: "Insufficient HubSpot permissions",
|
|
62
|
+
retryable: false,
|
|
63
|
+
};
|
|
64
|
+
if (s === 404)
|
|
65
|
+
return {
|
|
66
|
+
code: "not_found",
|
|
67
|
+
message: "HubSpot resource not found",
|
|
68
|
+
retryable: false,
|
|
69
|
+
};
|
|
70
|
+
if (s === 429)
|
|
71
|
+
return {
|
|
72
|
+
code: "rate_limited",
|
|
73
|
+
message: "HubSpot API rate limit exceeded",
|
|
74
|
+
retryable: true,
|
|
75
|
+
suggestedAction: "Wait and retry",
|
|
76
|
+
};
|
|
77
|
+
return {
|
|
78
|
+
code: "provider_error",
|
|
79
|
+
message: `HubSpot API error: HTTP ${s}`,
|
|
80
|
+
retryable: s >= 500,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (error instanceof Error) {
|
|
84
|
+
if (error.message.includes("ENOTFOUND") ||
|
|
85
|
+
error.message.includes("ECONNREFUSED")) {
|
|
86
|
+
return {
|
|
87
|
+
code: "network_error",
|
|
88
|
+
message: `Cannot connect to HubSpot: ${error.message}`,
|
|
89
|
+
retryable: true,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
code: "provider_error",
|
|
95
|
+
message: error instanceof Error ? error.message : String(error),
|
|
96
|
+
retryable: false,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
getStatus() {
|
|
100
|
+
const tokens = loadTokens();
|
|
101
|
+
return {
|
|
102
|
+
id: "hubspot",
|
|
103
|
+
status: tokens ? "connected" : "disconnected",
|
|
104
|
+
lastSync: tokens?.connected_at,
|
|
105
|
+
workspace: tokens?.portalName ?? (tokens ? "HubSpot" : undefined),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// ── API Methods ────────────────────────────────────────────────────────────
|
|
109
|
+
async listContacts(params = {}) {
|
|
110
|
+
const result = await this.apiCall(async (token) => {
|
|
111
|
+
const qs = new URLSearchParams({
|
|
112
|
+
limit: String(params.limit ?? 25),
|
|
113
|
+
properties: "firstname,lastname,email,phone,company",
|
|
114
|
+
});
|
|
115
|
+
if (params.after)
|
|
116
|
+
qs.set("after", params.after);
|
|
117
|
+
const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/contacts?${qs}`, {
|
|
118
|
+
headers: this.buildHeaders(token),
|
|
119
|
+
});
|
|
120
|
+
this.updateRateLimitFromHeaders({
|
|
121
|
+
"x-ratelimit-remaining": res.headers.get("x-ratelimit-remaining") ?? undefined,
|
|
122
|
+
"retry-after": res.headers.get("retry-after") ?? undefined,
|
|
123
|
+
});
|
|
124
|
+
if (!res.ok)
|
|
125
|
+
throw res;
|
|
126
|
+
return res.json();
|
|
127
|
+
});
|
|
128
|
+
if ("error" in result)
|
|
129
|
+
throw new Error(result.error.message);
|
|
130
|
+
return result.data;
|
|
131
|
+
}
|
|
132
|
+
async getContact(contactId) {
|
|
133
|
+
const result = await this.apiCall(async (token) => {
|
|
134
|
+
const qs = new URLSearchParams({
|
|
135
|
+
properties: "firstname,lastname,email,phone,company,lifecyclestage",
|
|
136
|
+
});
|
|
137
|
+
const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/contacts/${contactId}?${qs}`, { headers: this.buildHeaders(token) });
|
|
138
|
+
if (res.status === 404)
|
|
139
|
+
return null;
|
|
140
|
+
if (!res.ok)
|
|
141
|
+
throw res;
|
|
142
|
+
return res.json();
|
|
143
|
+
});
|
|
144
|
+
if ("error" in result)
|
|
145
|
+
throw new Error(result.error.message);
|
|
146
|
+
return result.data;
|
|
147
|
+
}
|
|
148
|
+
async listDeals(params = {}) {
|
|
149
|
+
const result = await this.apiCall(async (token) => {
|
|
150
|
+
const qs = new URLSearchParams({
|
|
151
|
+
limit: String(params.limit ?? 25),
|
|
152
|
+
properties: "dealname,amount,dealstage,closedate,pipeline",
|
|
153
|
+
});
|
|
154
|
+
const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/deals?${qs}`, {
|
|
155
|
+
headers: this.buildHeaders(token),
|
|
156
|
+
});
|
|
157
|
+
this.updateRateLimitFromHeaders({
|
|
158
|
+
"x-ratelimit-remaining": res.headers.get("x-ratelimit-remaining") ?? undefined,
|
|
159
|
+
"retry-after": res.headers.get("retry-after") ?? undefined,
|
|
160
|
+
});
|
|
161
|
+
if (!res.ok)
|
|
162
|
+
throw res;
|
|
163
|
+
const data = (await res.json());
|
|
164
|
+
// Client-side filter by stage if requested
|
|
165
|
+
if (params.stage) {
|
|
166
|
+
data.results = data.results.filter((d) => d.properties.dealstage === params.stage);
|
|
167
|
+
}
|
|
168
|
+
return data;
|
|
169
|
+
});
|
|
170
|
+
if ("error" in result)
|
|
171
|
+
throw new Error(result.error.message);
|
|
172
|
+
return result.data;
|
|
173
|
+
}
|
|
174
|
+
async getDeal(dealId) {
|
|
175
|
+
const result = await this.apiCall(async (token) => {
|
|
176
|
+
const qs = new URLSearchParams({
|
|
177
|
+
properties: "dealname,amount,dealstage,closedate,pipeline,hs_deal_stage_probability",
|
|
178
|
+
});
|
|
179
|
+
const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/deals/${dealId}?${qs}`, { headers: this.buildHeaders(token) });
|
|
180
|
+
if (res.status === 404)
|
|
181
|
+
return null;
|
|
182
|
+
if (!res.ok)
|
|
183
|
+
throw res;
|
|
184
|
+
return res.json();
|
|
185
|
+
});
|
|
186
|
+
if ("error" in result)
|
|
187
|
+
throw new Error(result.error.message);
|
|
188
|
+
return result.data;
|
|
189
|
+
}
|
|
190
|
+
async createNote(body, contactId, dealId) {
|
|
191
|
+
const result = await this.apiCall(async (token) => {
|
|
192
|
+
const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/notes`, {
|
|
193
|
+
method: "POST",
|
|
194
|
+
headers: {
|
|
195
|
+
...this.buildHeaders(token),
|
|
196
|
+
"Content-Type": "application/json",
|
|
197
|
+
},
|
|
198
|
+
body: JSON.stringify({
|
|
199
|
+
properties: {
|
|
200
|
+
hs_note_body: body,
|
|
201
|
+
hs_timestamp: String(Date.now()),
|
|
202
|
+
},
|
|
203
|
+
}),
|
|
204
|
+
});
|
|
205
|
+
if (!res.ok)
|
|
206
|
+
throw res;
|
|
207
|
+
const note = (await res.json());
|
|
208
|
+
// Associate with contact if provided
|
|
209
|
+
if (contactId) {
|
|
210
|
+
await fetch(`${HUBSPOT_BASE}/crm/v3/objects/notes/${note.id}/associations/contacts/${contactId}/note_to_contact`, {
|
|
211
|
+
method: "PUT",
|
|
212
|
+
headers: this.buildHeaders(token),
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
// Associate with deal if provided
|
|
216
|
+
if (dealId) {
|
|
217
|
+
await fetch(`${HUBSPOT_BASE}/crm/v3/objects/notes/${note.id}/associations/deals/${dealId}/note_to_deal`, {
|
|
218
|
+
method: "PUT",
|
|
219
|
+
headers: this.buildHeaders(token),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return note;
|
|
223
|
+
});
|
|
224
|
+
if ("error" in result)
|
|
225
|
+
throw new Error(result.error.message);
|
|
226
|
+
return result.data;
|
|
227
|
+
}
|
|
228
|
+
async searchContacts(query) {
|
|
229
|
+
const result = await this.apiCall(async (token) => {
|
|
230
|
+
const res = await fetch(`${HUBSPOT_BASE}/crm/v3/objects/contacts/search`, {
|
|
231
|
+
method: "POST",
|
|
232
|
+
headers: {
|
|
233
|
+
...this.buildHeaders(token),
|
|
234
|
+
"Content-Type": "application/json",
|
|
235
|
+
},
|
|
236
|
+
body: JSON.stringify({
|
|
237
|
+
query,
|
|
238
|
+
properties: ["firstname", "lastname", "email", "company"],
|
|
239
|
+
limit: 10,
|
|
240
|
+
}),
|
|
241
|
+
});
|
|
242
|
+
if (!res.ok)
|
|
243
|
+
throw res;
|
|
244
|
+
const data = (await res.json());
|
|
245
|
+
return data.results;
|
|
246
|
+
});
|
|
247
|
+
if ("error" in result)
|
|
248
|
+
throw new Error(result.error.message);
|
|
249
|
+
return result.data;
|
|
250
|
+
}
|
|
251
|
+
// ── Helpers ────────────────────────────────────────────────────────────────
|
|
252
|
+
buildHeaders(token) {
|
|
253
|
+
return {
|
|
254
|
+
Authorization: `Bearer ${token}`,
|
|
255
|
+
Accept: "application/json",
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
// ── Token persistence ────────────────────────────────────────────────────────
|
|
260
|
+
export function loadTokens() {
|
|
261
|
+
const envToken = process.env.HUBSPOT_ACCESS_TOKEN;
|
|
262
|
+
if (envToken) {
|
|
263
|
+
return {
|
|
264
|
+
accessToken: envToken,
|
|
265
|
+
connected_at: new Date().toISOString(),
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
return getSecretJsonSync("hubspot");
|
|
269
|
+
}
|
|
270
|
+
export function saveTokens(tokens) {
|
|
271
|
+
storeSecretJsonSync("hubspot", tokens);
|
|
272
|
+
}
|
|
273
|
+
export function clearTokens() {
|
|
274
|
+
try {
|
|
275
|
+
deleteSecretJsonSync("hubspot");
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
// ignore
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
// ── Singleton instance ───────────────────────────────────────────────────────
|
|
282
|
+
let _instance = null;
|
|
283
|
+
function resetHubSpotConnector() {
|
|
284
|
+
_instance = null;
|
|
285
|
+
}
|
|
286
|
+
export function getHubSpotConnector() {
|
|
287
|
+
if (!_instance) {
|
|
288
|
+
_instance = new HubSpotConnector();
|
|
289
|
+
}
|
|
290
|
+
return _instance;
|
|
291
|
+
}
|
|
292
|
+
export { getHubSpotConnector as hubspot };
|
|
293
|
+
/**
|
|
294
|
+
* POST /connections/hubspot/connect { accessToken }
|
|
295
|
+
*/
|
|
296
|
+
export async function handleHubSpotConnect(body) {
|
|
297
|
+
let accessToken;
|
|
298
|
+
try {
|
|
299
|
+
const parsed = JSON.parse(body);
|
|
300
|
+
if (typeof parsed.accessToken !== "string" || !parsed.accessToken) {
|
|
301
|
+
return {
|
|
302
|
+
status: 400,
|
|
303
|
+
contentType: "application/json",
|
|
304
|
+
body: JSON.stringify({ ok: false, error: "accessToken is required" }),
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
accessToken = parsed.accessToken;
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
return {
|
|
311
|
+
status: 400,
|
|
312
|
+
contentType: "application/json",
|
|
313
|
+
body: JSON.stringify({ ok: false, error: "Invalid JSON body" }),
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
try {
|
|
317
|
+
const res = await fetch(`${HUBSPOT_BASE}/account-info/v3/details`, {
|
|
318
|
+
headers: {
|
|
319
|
+
Authorization: `Bearer ${accessToken}`,
|
|
320
|
+
Accept: "application/json",
|
|
321
|
+
},
|
|
322
|
+
});
|
|
323
|
+
if (!res.ok) {
|
|
324
|
+
return {
|
|
325
|
+
status: 401,
|
|
326
|
+
contentType: "application/json",
|
|
327
|
+
body: JSON.stringify({
|
|
328
|
+
ok: false,
|
|
329
|
+
error: `Credentials rejected by HubSpot (HTTP ${res.status}) — check accessToken`,
|
|
330
|
+
}),
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
const details = (await res.json());
|
|
334
|
+
const tokens = {
|
|
335
|
+
accessToken,
|
|
336
|
+
hubId: details.portalId,
|
|
337
|
+
portalName: details.uiDomain,
|
|
338
|
+
connected_at: new Date().toISOString(),
|
|
339
|
+
};
|
|
340
|
+
saveTokens(tokens);
|
|
341
|
+
resetHubSpotConnector();
|
|
342
|
+
return {
|
|
343
|
+
status: 200,
|
|
344
|
+
contentType: "application/json",
|
|
345
|
+
body: JSON.stringify({
|
|
346
|
+
ok: true,
|
|
347
|
+
hubId: tokens.hubId,
|
|
348
|
+
portalName: tokens.portalName,
|
|
349
|
+
connectedAt: tokens.connected_at,
|
|
350
|
+
}),
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
catch (err) {
|
|
354
|
+
return {
|
|
355
|
+
status: 500,
|
|
356
|
+
contentType: "application/json",
|
|
357
|
+
body: JSON.stringify({
|
|
358
|
+
ok: false,
|
|
359
|
+
error: err instanceof Error ? err.message : String(err),
|
|
360
|
+
}),
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* POST /connections/hubspot/test
|
|
366
|
+
*/
|
|
367
|
+
export async function handleHubSpotTest() {
|
|
368
|
+
const tokens = loadTokens();
|
|
369
|
+
if (!tokens) {
|
|
370
|
+
return {
|
|
371
|
+
status: 400,
|
|
372
|
+
contentType: "application/json",
|
|
373
|
+
body: JSON.stringify({ ok: false, error: "HubSpot not connected" }),
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
const connector = getHubSpotConnector();
|
|
378
|
+
const check = await connector.healthCheck();
|
|
379
|
+
return {
|
|
380
|
+
status: check.ok ? 200 : 401,
|
|
381
|
+
contentType: "application/json",
|
|
382
|
+
body: JSON.stringify(check.ok ? { ok: true } : { ok: false, error: check.error?.message }),
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
catch (err) {
|
|
386
|
+
return {
|
|
387
|
+
status: 500,
|
|
388
|
+
contentType: "application/json",
|
|
389
|
+
body: JSON.stringify({
|
|
390
|
+
ok: false,
|
|
391
|
+
error: err instanceof Error ? err.message : String(err),
|
|
392
|
+
}),
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
/**
|
|
397
|
+
* DELETE /connections/hubspot
|
|
398
|
+
*/
|
|
399
|
+
export function handleHubSpotDisconnect() {
|
|
400
|
+
clearTokens();
|
|
401
|
+
resetHubSpotConnector();
|
|
402
|
+
return {
|
|
403
|
+
status: 200,
|
|
404
|
+
contentType: "application/json",
|
|
405
|
+
body: JSON.stringify({ ok: true }),
|
|
406
|
+
};
|
|
407
|
+
}
|
|
408
|
+
//# sourceMappingURL=hubspot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hubspot.js","sourceRoot":"","sources":["../../src/connectors/hubspot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAEL,aAAa,GAGd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,mBAAmB,CAAC;AAE3B,MAAM,YAAY,GAAG,wBAAwB,CAAC;AA2D9C,MAAM,OAAO,gBAAiB,SAAQ,aAAa;IACxC,YAAY,GAAG,SAAS,CAAC;IAExB,cAAc;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,YAAY;QAChB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,sFAAsF,CACvF,CAAC;QACJ,CAAC;QACD,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,WAAW;YACzB,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;SAC1B,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;gBAChD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,0BAA0B,EAAE;oBACjE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;iBAClC,CAAC,CAAC;gBACH,IAAI,CAAC,GAAG,CAAC,EAAE;oBAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;gBACnD,OAAO,GAAG,CAAC,IAAI,EAAE,CAAC;YACpB,CAAC,CAAC,CAAC;YACH,IAAI,OAAO,IAAI,MAAM;gBAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;YACjE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QACxD,CAAC;IACH,CAAC;IAED,cAAc,CAAC,KAAc;QAC3B,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;YACvB,IAAI,CAAC,KAAK,GAAG;gBACX,OAAO;oBACL,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,4CAA4C;oBACrD,SAAS,EAAE,KAAK;oBAChB,eAAe,EAAE,8BAA8B;iBAChD,CAAC;YACJ,IAAI,CAAC,KAAK,GAAG;gBACX,OAAO;oBACL,IAAI,EAAE,mBAAmB;oBACzB,OAAO,EAAE,kCAAkC;oBAC3C,SAAS,EAAE,KAAK;iBACjB,CAAC;YACJ,IAAI,CAAC,KAAK,GAAG;gBACX,OAAO;oBACL,IAAI,EAAE,WAAW;oBACjB,OAAO,EAAE,4BAA4B;oBACrC,SAAS,EAAE,KAAK;iBACjB,CAAC;YACJ,IAAI,CAAC,KAAK,GAAG;gBACX,OAAO;oBACL,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,iCAAiC;oBAC1C,SAAS,EAAE,IAAI;oBACf,eAAe,EAAE,gBAAgB;iBAClC,CAAC;YACJ,OAAO;gBACL,IAAI,EAAE,gBAAgB;gBACtB,OAAO,EAAE,2BAA2B,CAAC,EAAE;gBACvC,SAAS,EAAE,CAAC,IAAI,GAAG;aACpB,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,IACE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;gBACnC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,EACtC,CAAC;gBACD,OAAO;oBACL,IAAI,EAAE,eAAe;oBACrB,OAAO,EAAE,8BAA8B,KAAK,CAAC,OAAO,EAAE;oBACtD,SAAS,EAAE,IAAI;iBAChB,CAAC;YACJ,CAAC;QACH,CAAC;QACD,OAAO;YACL,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/D,SAAS,EAAE,KAAK;SACjB,CAAC;IACJ,CAAC;IAED,SAAS;QACP,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,OAAO;YACL,EAAE,EAAE,SAAS;YACb,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc;YAC7C,QAAQ,EAAE,MAAM,EAAE,YAAY;YAC9B,SAAS,EAAE,MAAM,EAAE,UAAU,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;SAClE,CAAC;IACJ,CAAC;IAED,8EAA8E;IAE9E,KAAK,CAAC,YAAY,CAChB,SAA6C,EAAE;QAE/C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAChD,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC;gBAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;gBACjC,UAAU,EAAE,wCAAwC;aACrD,CAAC,CAAC;YACH,IAAI,MAAM,CAAC,KAAK;gBAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,4BAA4B,EAAE,EAAE,EAAE;gBACvE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;aAClC,CAAC,CAAC;YACH,IAAI,CAAC,0BAA0B,CAAC;gBAC9B,uBAAuB,EACrB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,SAAS;gBACvD,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,SAAS;aAC3D,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,GAAG,CAAC;YACvB,OAAO,GAAG,CAAC,IAAI,EAAgD,CAAC;QAClE,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,IAAI,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,IAAyC,CAAC;IAC1D,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,SAAiB;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAChD,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC;gBAC7B,UAAU,EAAE,uDAAuD;aACpE,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,YAAY,4BAA4B,SAAS,IAAI,EAAE,EAAE,EAC5D,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CACtC,CAAC;YACF,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC;YACpC,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,GAAG,CAAC;YACvB,OAAO,GAAG,CAAC,IAAI,EAA6B,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,IAAI,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,IAA6B,CAAC;IAC9C,CAAC;IAED,KAAK,CAAC,SAAS,CACb,SAA6C,EAAE;QAE/C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAChD,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC;gBAC7B,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;gBACjC,UAAU,EAAE,8CAA8C;aAC3D,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,yBAAyB,EAAE,EAAE,EAAE;gBACpE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;aAClC,CAAC,CAAC;YACH,IAAI,CAAC,0BAA0B,CAAC;gBAC9B,uBAAuB,EACrB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,IAAI,SAAS;gBACvD,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,SAAS;aAC3D,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,GAAG,CAAC;YACvB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAmC,CAAC;YAClE,2CAA2C;YAC3C,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,KAAK,MAAM,CAAC,KAAK,CAC/C,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,IAAI,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,IAAsC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,MAAc;QAC1B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAChD,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC;gBAC7B,UAAU,EACR,wEAAwE;aAC3E,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,YAAY,yBAAyB,MAAM,IAAI,EAAE,EAAE,EACtD,EAAE,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CACtC,CAAC;YACF,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,IAAI,CAAC;YACpC,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,GAAG,CAAC;YACvB,OAAO,GAAG,CAAC,IAAI,EAA0B,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,IAAI,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,IAA0B,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,UAAU,CACd,IAAY,EACZ,SAAkB,EAClB,MAAe;QAEf,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAChD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,uBAAuB,EAAE;gBAC9D,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;oBAC3B,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,UAAU,EAAE;wBACV,YAAY,EAAE,IAAI;wBAClB,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;qBACjC;iBACF,CAAC;aACH,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,GAAG,CAAC;YACvB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAgB,CAAC;YAE/C,qCAAqC;YACrC,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,KAAK,CACT,GAAG,YAAY,yBAAyB,IAAI,CAAC,EAAE,0BAA0B,SAAS,kBAAkB,EACpG;oBACE,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;iBAClC,CACF,CAAC;YACJ,CAAC;YAED,kCAAkC;YAClC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,KAAK,CACT,GAAG,YAAY,yBAAyB,IAAI,CAAC,EAAE,uBAAuB,MAAM,eAAe,EAC3F;oBACE,MAAM,EAAE,KAAK;oBACb,OAAO,EAAE,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;iBAClC,CACF,CAAC;YACJ,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,IAAI,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,IAAmB,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,KAAa;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAChD,MAAM,GAAG,GAAG,MAAM,KAAK,CACrB,GAAG,YAAY,iCAAiC,EAChD;gBACE,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;oBAC3B,cAAc,EAAE,kBAAkB;iBACnC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,KAAK;oBACL,UAAU,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,CAAC;oBACzD,KAAK,EAAE,EAAE;iBACV,CAAC;aACH,CACF,CAAC;YACF,IAAI,CAAC,GAAG,CAAC,EAAE;gBAAE,MAAM,GAAG,CAAC;YACvB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsC,CAAC;YACrE,OAAO,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,IAAI,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7D,OAAO,MAAM,CAAC,IAAwB,CAAC;IACzC,CAAC;IAED,8EAA8E;IAEtE,YAAY,CAAC,KAAa;QAChC,OAAO;YACL,aAAa,EAAE,UAAU,KAAK,EAAE;YAChC,MAAM,EAAE,kBAAkB;SAC3B,CAAC;IACJ,CAAC;CACF;AAED,gFAAgF;AAEhF,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAClD,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO;YACL,WAAW,EAAE,QAAQ;YACrB,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACvC,CAAC;IACJ,CAAC;IACD,OAAO,iBAAiB,CAAgB,SAAS,CAAC,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAqB;IAC9C,mBAAmB,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC;QACH,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,SAAS;IACX,CAAC;AACH,CAAC;AAED,gFAAgF;AAEhF,IAAI,SAAS,GAA4B,IAAI,CAAC;AAE9C,SAAS,qBAAqB;IAC5B,SAAS,GAAG,IAAI,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,SAAS,GAAG,IAAI,gBAAgB,EAAE,CAAC;IACrC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,OAAO,EAAE,mBAAmB,IAAI,OAAO,EAAE,CAAC;AAW1C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAY;IAEZ,IAAI,WAAmB,CAAC;IAExB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA8B,CAAC;QAC7D,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YAClE,OAAO;gBACL,MAAM,EAAE,GAAG;gBACX,WAAW,EAAE,kBAAkB;gBAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC;aACtE,CAAC;QACJ,CAAC;QACD,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;YACL,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC;SAChE,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,YAAY,0BAA0B,EAAE;YACjE,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,WAAW,EAAE;gBACtC,MAAM,EAAE,kBAAkB;aAC3B;SACF,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,OAAO;gBACL,MAAM,EAAE,GAAG;gBACX,WAAW,EAAE,kBAAkB;gBAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,EAAE,EAAE,KAAK;oBACT,KAAK,EAAE,yCAAyC,GAAG,CAAC,MAAM,uBAAuB;iBAClF,CAAC;aACH,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAIhC,CAAC;QAEF,MAAM,MAAM,GAAkB;YAC5B,WAAW;YACX,KAAK,EAAE,OAAO,CAAC,QAAQ;YACvB,UAAU,EAAE,OAAO,CAAC,QAAQ;YAC5B,YAAY,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACvC,CAAC;QACF,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,qBAAqB,EAAE,CAAC;QAExB,OAAO;YACL,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,EAAE,EAAE,IAAI;gBACR,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,UAAU,EAAE,MAAM,CAAC,UAAU;gBAC7B,WAAW,EAAE,MAAM,CAAC,YAAY;aACjC,CAAC;SACH,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC;SACH,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;SACpE,CAAC;IACJ,CAAC;IACD,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,mBAAmB,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;QAC5C,OAAO;YACL,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;YAC5B,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE,CACrE;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,EAAE,EAAE,KAAK;gBACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC;SACH,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,uBAAuB;IACrC,WAAW,EAAE,CAAC;IACd,qBAAqB,EAAE,CAAC;IACxB,OAAO;QACL,MAAM,EAAE,GAAG;QACX,WAAW,EAAE,kBAAkB;QAC/B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;KACnC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intercom connector — read/write Intercom conversations via the Intercom REST API v2.10.
|
|
3
|
+
*
|
|
4
|
+
* Auth: Bearer access token (single workspace).
|
|
5
|
+
* - Env var: INTERCOM_ACCESS_TOKEN
|
|
6
|
+
* - Stored: getSecretJsonSync("intercom") → IntercomTokens
|
|
7
|
+
* - Header: Authorization: Bearer <token>, Intercom-Version: 2.10
|
|
8
|
+
*
|
|
9
|
+
* Tools: listConversations, getConversation, replyToConversation, closeConversation, listContacts
|
|
10
|
+
*
|
|
11
|
+
* Extends BaseConnector for unified auth, retry, rate-limit, error handling.
|
|
12
|
+
*/
|
|
13
|
+
import { type AuthContext, BaseConnector, type ConnectorError, type ConnectorStatus } from "./baseConnector.js";
|
|
14
|
+
export interface IntercomTokens {
|
|
15
|
+
accessToken: string;
|
|
16
|
+
workspaceName?: string;
|
|
17
|
+
connected_at: string;
|
|
18
|
+
}
|
|
19
|
+
export interface IntercomConversation {
|
|
20
|
+
id: string;
|
|
21
|
+
type: string;
|
|
22
|
+
title: string | null;
|
|
23
|
+
created_at: number;
|
|
24
|
+
updated_at: number;
|
|
25
|
+
state: "open" | "closed" | "snoozed" | "pending";
|
|
26
|
+
assignee: {
|
|
27
|
+
type: string;
|
|
28
|
+
id: string;
|
|
29
|
+
} | null;
|
|
30
|
+
contacts: {
|
|
31
|
+
contacts: Array<{
|
|
32
|
+
type: string;
|
|
33
|
+
id: string;
|
|
34
|
+
}>;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export interface IntercomContact {
|
|
38
|
+
id: string;
|
|
39
|
+
type: string;
|
|
40
|
+
name: string | null;
|
|
41
|
+
email: string | null;
|
|
42
|
+
created_at: number;
|
|
43
|
+
updated_at: number;
|
|
44
|
+
}
|
|
45
|
+
export interface IntercomListResult<T> {
|
|
46
|
+
conversations?: T[];
|
|
47
|
+
contacts?: T[];
|
|
48
|
+
total_count: number;
|
|
49
|
+
pages: {
|
|
50
|
+
type: string;
|
|
51
|
+
page: number;
|
|
52
|
+
per_page: number;
|
|
53
|
+
total_pages: number;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export declare class IntercomConnector extends BaseConnector {
|
|
57
|
+
readonly providerName = "intercom";
|
|
58
|
+
protected getOAuthConfig(): null;
|
|
59
|
+
authenticate(): Promise<AuthContext>;
|
|
60
|
+
healthCheck(): Promise<{
|
|
61
|
+
ok: boolean;
|
|
62
|
+
error?: ConnectorError;
|
|
63
|
+
}>;
|
|
64
|
+
normalizeError(error: unknown): ConnectorError;
|
|
65
|
+
getStatus(): ConnectorStatus;
|
|
66
|
+
listConversations(params?: {
|
|
67
|
+
status?: "open" | "closed" | "snoozed" | "pending";
|
|
68
|
+
assigneeId?: string;
|
|
69
|
+
perPage?: number;
|
|
70
|
+
}): Promise<IntercomListResult<IntercomConversation>>;
|
|
71
|
+
getConversation(conversationId: string): Promise<IntercomConversation>;
|
|
72
|
+
replyToConversation(conversationId: string, body: string, type?: "comment" | "note"): Promise<IntercomConversation>;
|
|
73
|
+
closeConversation(conversationId: string): Promise<IntercomConversation>;
|
|
74
|
+
listContacts(params?: {
|
|
75
|
+
query?: string;
|
|
76
|
+
perPage?: number;
|
|
77
|
+
}): Promise<IntercomListResult<IntercomContact>>;
|
|
78
|
+
searchContacts(query: string): Promise<IntercomListResult<IntercomContact>>;
|
|
79
|
+
private buildHeaders;
|
|
80
|
+
}
|
|
81
|
+
export declare function loadTokens(): IntercomTokens | null;
|
|
82
|
+
export declare function saveTokens(tokens: IntercomTokens): void;
|
|
83
|
+
export declare function clearTokens(): void;
|
|
84
|
+
export declare function getIntercomConnector(): IntercomConnector;
|
|
85
|
+
export { getIntercomConnector as intercom };
|
|
86
|
+
export interface ConnectorHandlerResult {
|
|
87
|
+
status: number;
|
|
88
|
+
body: string;
|
|
89
|
+
contentType?: string;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* POST /connections/intercom/connect { accessToken }
|
|
93
|
+
*/
|
|
94
|
+
export declare function handleIntercomConnect(body: string): Promise<ConnectorHandlerResult>;
|
|
95
|
+
/**
|
|
96
|
+
* POST /connections/intercom/test
|
|
97
|
+
*/
|
|
98
|
+
export declare function handleIntercomTest(): Promise<ConnectorHandlerResult>;
|
|
99
|
+
/**
|
|
100
|
+
* DELETE /connections/intercom
|
|
101
|
+
*/
|
|
102
|
+
export declare function handleIntercomDisconnect(): ConnectorHandlerResult;
|