@agentworkforce/sage 1.0.6 → 1.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.
Files changed (56) hide show
  1. package/.env.example +5 -4
  2. package/dist/app.d.ts +0 -6
  3. package/dist/app.d.ts.map +1 -1
  4. package/dist/app.js +264 -217
  5. package/dist/integrations/cloud-proxy-provider.d.ts +42 -0
  6. package/dist/integrations/cloud-proxy-provider.d.ts.map +1 -0
  7. package/dist/integrations/cloud-proxy-provider.js +131 -0
  8. package/dist/integrations/github-context.d.ts +2 -1
  9. package/dist/integrations/github-context.d.ts.map +1 -1
  10. package/dist/integrations/github-context.js +4 -2
  11. package/dist/integrations/github.d.ts +4 -2
  12. package/dist/integrations/github.d.ts.map +1 -1
  13. package/dist/integrations/github.js +16 -11
  14. package/dist/integrations/slack-egress.d.ts +28 -0
  15. package/dist/integrations/slack-egress.d.ts.map +1 -0
  16. package/dist/integrations/slack-egress.js +181 -0
  17. package/dist/integrations/slack-ingress.d.ts +26 -0
  18. package/dist/integrations/slack-ingress.d.ts.map +1 -0
  19. package/dist/integrations/slack-ingress.js +31 -0
  20. package/dist/nango.d.ts +1 -6
  21. package/dist/nango.d.ts.map +1 -1
  22. package/dist/nango.js +9 -34
  23. package/dist/proactive/context-watcher.d.ts +2 -2
  24. package/dist/proactive/context-watcher.d.ts.map +1 -1
  25. package/dist/proactive/context-watcher.js +5 -3
  26. package/dist/proactive/engine.d.ts +5 -9
  27. package/dist/proactive/engine.d.ts.map +1 -1
  28. package/dist/proactive/engine.js +25 -20
  29. package/dist/proactive/evidence-sources/affirmative-reply-source.d.ts.map +1 -1
  30. package/dist/proactive/evidence-sources/affirmative-reply-source.js +4 -2
  31. package/dist/proactive/evidence-sources/explicit-close-source.d.ts.map +1 -1
  32. package/dist/proactive/evidence-sources/explicit-close-source.js +4 -2
  33. package/dist/proactive/evidence-sources/pr-merge-source.d.ts.map +1 -1
  34. package/dist/proactive/evidence-sources/pr-merge-source.js +12 -5
  35. package/dist/proactive/evidence-sources/reaction-source.d.ts.map +1 -1
  36. package/dist/proactive/evidence-sources/reaction-source.js +6 -15
  37. package/dist/proactive/follow-up-checker.d.ts +4 -4
  38. package/dist/proactive/follow-up-checker.d.ts.map +1 -1
  39. package/dist/proactive/follow-up-checker.js +40 -21
  40. package/dist/proactive/integrations/slack-egress.d.ts +2 -0
  41. package/dist/proactive/integrations/slack-egress.d.ts.map +1 -0
  42. package/dist/proactive/integrations/slack-egress.js +1 -0
  43. package/dist/proactive/pr-matcher.d.ts +2 -2
  44. package/dist/proactive/pr-matcher.d.ts.map +1 -1
  45. package/dist/proactive/pr-matcher.js +8 -6
  46. package/dist/proactive/stale-thread-detector.d.ts +2 -2
  47. package/dist/proactive/stale-thread-detector.d.ts.map +1 -1
  48. package/dist/proactive/stale-thread-detector.js +16 -23
  49. package/dist/proactive/types.d.ts +8 -6
  50. package/dist/proactive/types.d.ts.map +1 -1
  51. package/dist/slack.d.ts +3 -13
  52. package/dist/slack.d.ts.map +1 -1
  53. package/dist/slack.js +7 -108
  54. package/dist/types.d.ts +1 -2
  55. package/dist/types.d.ts.map +1 -1
  56. package/package.json +3 -1
@@ -0,0 +1,42 @@
1
+ export type ProxyMethod = "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
2
+ export type ProxyHeaders = Record<string, string>;
3
+ export type ProxyQuery = Record<string, string>;
4
+ export interface ProxyRequest {
5
+ method: ProxyMethod;
6
+ endpoint: string;
7
+ workspaceId?: string;
8
+ data?: unknown;
9
+ params?: ProxyQuery;
10
+ }
11
+ export interface ProxyResponse<T = unknown> {
12
+ status: number;
13
+ headers: ProxyHeaders;
14
+ data: T;
15
+ }
16
+ export interface ConnectionProvider {
17
+ readonly name: string;
18
+ proxy<T = unknown>(request: ProxyRequest): Promise<ProxyResponse<T>>;
19
+ healthCheck(): Promise<boolean>;
20
+ }
21
+ export declare class CloudProxyError extends Error {
22
+ readonly status?: number;
23
+ readonly code: string;
24
+ readonly retryAfterMs?: number;
25
+ constructor(message: string, options?: {
26
+ status?: number;
27
+ code?: string;
28
+ retryAfterMs?: number;
29
+ });
30
+ }
31
+ export declare class CloudProxyProvider implements ConnectionProvider {
32
+ readonly name = "cloud-proxy";
33
+ private readonly baseUrl;
34
+ private readonly cloudApiToken;
35
+ constructor(config: {
36
+ cloudApiUrl: string;
37
+ cloudApiToken: string;
38
+ });
39
+ proxy<T = unknown>(request: ProxyRequest): Promise<ProxyResponse<T>>;
40
+ healthCheck(): Promise<boolean>;
41
+ }
42
+ //# sourceMappingURL=cloud-proxy-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-proxy-provider.d.ts","sourceRoot":"","sources":["../../src/integrations/cloud-proxy-provider.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAClD,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEhD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,GAAG,OAAO;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC;IACtB,IAAI,EAAE,CAAC,CAAC;CACT;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACrE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;CACjC;AA8CD,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAEnB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE;CAOjG;AAwBD,qBAAa,kBAAmB,YAAW,kBAAkB;IAC3D,QAAQ,CAAC,IAAI,iBAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAE3B,MAAM,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE;IAK5D,KAAK,CAAC,CAAC,GAAG,OAAO,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IA0DpE,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;CAWtC"}
@@ -0,0 +1,131 @@
1
+ const HEALTH_ENDPOINT = "/api/health";
2
+ const SLACK_PROXY_ENDPOINT = "/api/v1/proxy/slack";
3
+ const REQUEST_TIMEOUT_MS = 30_000;
4
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+ function readString(value) {
8
+ return typeof value === "string" && value.trim() ? value : undefined;
9
+ }
10
+ function readNumber(value) {
11
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
12
+ }
13
+ function requireNonEmpty(value, field) {
14
+ const normalized = value.trim();
15
+ if (!normalized) {
16
+ throw new CloudProxyError(`Cloud proxy configuration is missing ${field}`);
17
+ }
18
+ return normalized;
19
+ }
20
+ function readWorkspaceId(request) {
21
+ const workspaceId = readString(request.workspaceId);
22
+ if (!workspaceId) {
23
+ throw new CloudProxyError("Cloud Slack proxy request is missing workspaceId", {
24
+ code: "invalid_request",
25
+ });
26
+ }
27
+ return workspaceId;
28
+ }
29
+ export class CloudProxyError extends Error {
30
+ status;
31
+ code;
32
+ retryAfterMs;
33
+ constructor(message, options) {
34
+ super(message);
35
+ this.name = "CloudProxyError";
36
+ this.status = options?.status;
37
+ this.code = options?.code ?? "cloud_proxy_error";
38
+ this.retryAfterMs = options?.retryAfterMs;
39
+ }
40
+ }
41
+ function parseEnvelope(payload) {
42
+ if (!isRecord(payload) || typeof payload.ok !== "boolean") {
43
+ throw new CloudProxyError("Cloud Slack proxy returned an invalid response");
44
+ }
45
+ if (payload.ok) {
46
+ return {
47
+ ok: true,
48
+ data: ("data" in payload ? payload.data : undefined),
49
+ };
50
+ }
51
+ return {
52
+ ok: false,
53
+ ...(readString(payload.error) ? { error: readString(payload.error) } : {}),
54
+ ...(readString(payload.code) ? { code: readString(payload.code) } : {}),
55
+ ...(readNumber(payload.retryAfterMs) !== undefined
56
+ ? { retryAfterMs: readNumber(payload.retryAfterMs) }
57
+ : {}),
58
+ };
59
+ }
60
+ export class CloudProxyProvider {
61
+ name = "cloud-proxy";
62
+ baseUrl;
63
+ cloudApiToken;
64
+ constructor(config) {
65
+ this.baseUrl = requireNonEmpty(config.cloudApiUrl, "cloudApiUrl").replace(/\/+$/, "");
66
+ this.cloudApiToken = requireNonEmpty(config.cloudApiToken, "cloudApiToken");
67
+ }
68
+ async proxy(request) {
69
+ let response;
70
+ const workspaceId = readWorkspaceId(request);
71
+ try {
72
+ response = await fetch(`${this.baseUrl}${SLACK_PROXY_ENDPOINT}`, {
73
+ method: "POST",
74
+ headers: {
75
+ Authorization: `Bearer ${this.cloudApiToken}`,
76
+ "Content-Type": "application/json",
77
+ },
78
+ body: JSON.stringify({
79
+ workspaceId,
80
+ endpoint: request.endpoint,
81
+ method: request.method,
82
+ ...(request.data !== undefined ? { data: request.data } : {}),
83
+ ...(request.params !== undefined ? { params: request.params } : {}),
84
+ }),
85
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
86
+ });
87
+ }
88
+ catch (error) {
89
+ throw new CloudProxyError(error instanceof Error ? error.message : "Cloud Slack proxy request failed", { code: "network_error" });
90
+ }
91
+ if (!response.ok) {
92
+ throw new CloudProxyError(`Cloud Slack proxy request failed: ${response.status} ${response.statusText}`, {
93
+ code: "upstream_error",
94
+ status: response.status,
95
+ });
96
+ }
97
+ let payload;
98
+ try {
99
+ payload = parseEnvelope(await response.json());
100
+ }
101
+ catch (error) {
102
+ if (error instanceof CloudProxyError) {
103
+ throw error;
104
+ }
105
+ throw new CloudProxyError("Cloud Slack proxy returned invalid JSON");
106
+ }
107
+ if (!payload.ok) {
108
+ throw new CloudProxyError(payload.error ?? "Cloud Slack proxy returned an error", {
109
+ code: payload.code,
110
+ retryAfterMs: payload.retryAfterMs,
111
+ });
112
+ }
113
+ return {
114
+ status: response.status,
115
+ headers: {},
116
+ data: payload.data,
117
+ };
118
+ }
119
+ async healthCheck() {
120
+ try {
121
+ const response = await fetch(`${this.baseUrl}${HEALTH_ENDPOINT}`, {
122
+ method: "GET",
123
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
124
+ });
125
+ return response.ok;
126
+ }
127
+ catch {
128
+ return false;
129
+ }
130
+ }
131
+ }
@@ -6,10 +6,11 @@ export interface GitHubContextProviderOptions {
6
6
  }
7
7
  export declare class GitHubContextProvider {
8
8
  private readonly nangoClient;
9
+ private readonly providerConfigKey;
9
10
  private readonly cache;
10
11
  private readonly cacheTtlMs;
11
12
  private readonly logger;
12
- constructor(nangoClient: NangoClient, options?: GitHubContextProviderOptions);
13
+ constructor(nangoClient: NangoClient, providerConfigKey: string, options?: GitHubContextProviderOptions);
13
14
  getOrgsAndRepos(connectionId: string, relayfileReader?: SageRelayFileReader | null): Promise<GitHubOrgDiscovery>;
14
15
  private setCache;
15
16
  }
@@ -1 +1 @@
1
- {"version":3,"file":"github-context.d.ts","sourceRoot":"","sources":["../../src/integrations/github-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AASjE,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,qBAAa,qBAAqB;IAM9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAL9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;gBAG5B,WAAW,EAAE,WAAW,EACzC,OAAO,GAAE,4BAAiC;IAMtC,eAAe,CACnB,YAAY,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,mBAAmB,GAAG,IAAI,GAC3C,OAAO,CAAC,kBAAkB,CAAC;IAwB9B,OAAO,CAAC,QAAQ;CAMjB"}
1
+ {"version":3,"file":"github-context.d.ts","sourceRoot":"","sources":["../../src/integrations/github-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACnE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AASjE,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,qBAAa,qBAAqB;IAM9B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IANpC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiC;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;gBAG5B,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,MAAM,EAC1C,OAAO,GAAE,4BAAiC;IAMtC,eAAe,CACnB,YAAY,EAAE,MAAM,EACpB,eAAe,CAAC,EAAE,mBAAmB,GAAG,IAAI,GAC3C,OAAO,CAAC,kBAAkB,CAAC;IAwB9B,OAAO,CAAC,QAAQ;CAMjB"}
@@ -1,11 +1,13 @@
1
1
  const DEFAULT_CACHE_TTL_MS = 5 * 60_000;
2
2
  export class GitHubContextProvider {
3
3
  nangoClient;
4
+ providerConfigKey;
4
5
  cache = new Map();
5
6
  cacheTtlMs;
6
7
  logger;
7
- constructor(nangoClient, options = {}) {
8
+ constructor(nangoClient, providerConfigKey, options = {}) {
8
9
  this.nangoClient = nangoClient;
10
+ this.providerConfigKey = providerConfigKey;
9
11
  this.cacheTtlMs = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
10
12
  this.logger = options.logger ?? console;
11
13
  }
@@ -27,7 +29,7 @@ export class GitHubContextProvider {
27
29
  this.logger.warn('[sage] RelayFile GitHub discovery failed, falling back to Nango', error);
28
30
  }
29
31
  }
30
- const discovery = await this.nangoClient.discoverGitHubOrgs(connectionId);
32
+ const discovery = await this.nangoClient.discoverGitHubOrgs(connectionId, this.providerConfigKey);
31
33
  this.setCache(connectionId, discovery);
32
34
  return cloneGitHubOrgDiscovery(discovery);
33
35
  }
@@ -3,16 +3,18 @@
3
3
  *
4
4
  * All GitHub API calls are routed through Nango's proxy so that
5
5
  * authentication is handled automatically via the stored connection.
6
- * Uses the 'github' integration key for repo access.
6
+ * Uses the workspace-resolved provider config key for repo access.
7
7
  */
8
8
  import { NangoClient } from '../nango.js';
9
9
  import type { IntegrationResult, GitHubFile, GitHubIssue, GitHubPR, GitHubSearchResult } from './types.js';
10
10
  export declare class GitHubIntegration {
11
11
  private readonly nango;
12
12
  private readonly connectionId;
13
- constructor({ nangoClient, connectionId, }: {
13
+ private readonly providerConfigKey;
14
+ constructor({ nangoClient, connectionId, providerConfigKey, }: {
14
15
  nangoClient: NangoClient;
15
16
  connectionId: string;
17
+ providerConfigKey?: string | null;
16
18
  });
17
19
  private errorResult;
18
20
  private execute;
@@ -1 +1 @@
1
- {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/integrations/github.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAkC,MAAM,aAAa,CAAC;AAC1E,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,kBAAkB,EACnB,MAAM,YAAY,CAAC;AA6EpB,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;gBAE1B,EACV,WAAW,EACX,YAAY,GACb,EAAE;QACD,WAAW,EAAE,WAAW,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;KACtB;IAKD,OAAO,CAAC,WAAW;YAOL,OAAO;IAcf,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IAmCxF,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,EAAE,CAAC,CAAC;IAmCrF,QAAQ,CACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAmCnC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAuC7F,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC;IAmBjC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CA+BrG"}
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/integrations/github.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,QAAQ,EACR,kBAAkB,EACnB,MAAM,YAAY,CAAC;AA4EpB,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAc;IACpC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;gBAE/B,EACV,WAAW,EACX,YAAY,EACZ,iBAAiB,GAClB,EAAE;QACD,WAAW,EAAE,WAAW,CAAC;QACzB,YAAY,EAAE,MAAM,CAAC;QACrB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACnC;IAWD,OAAO,CAAC,WAAW;YAOL,OAAO;IAcf,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;IAmCxF,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,EAAE,CAAC,CAAC;IAmCrF,QAAQ,CACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAmCnC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAuC7F,aAAa,CACjB,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,CAAC;IAmBjC,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;CA+BrG"}
@@ -3,11 +3,10 @@
3
3
  *
4
4
  * All GitHub API calls are routed through Nango's proxy so that
5
5
  * authentication is handled automatically via the stored connection.
6
- * Uses the 'github' integration key for repo access.
6
+ * Uses the workspace-resolved provider config key for repo access.
7
7
  */
8
- import { NangoError, NANGO_INTEGRATIONS } from '../nango.js';
8
+ import { NangoError } from '../nango.js';
9
9
  const SOURCE = 'github';
10
- const PROVIDER = NANGO_INTEGRATIONS.GITHUB;
11
10
  function result(data, summary) {
12
11
  return {
13
12
  source: SOURCE,
@@ -64,9 +63,15 @@ function encodeRepoPath(path) {
64
63
  export class GitHubIntegration {
65
64
  nango;
66
65
  connectionId;
67
- constructor({ nangoClient, connectionId, }) {
66
+ providerConfigKey;
67
+ constructor({ nangoClient, connectionId, providerConfigKey, }) {
68
+ const resolvedProviderConfigKey = providerConfigKey?.trim();
69
+ if (!resolvedProviderConfigKey) {
70
+ throw new Error('GitHubIntegration requires a providerConfigKey');
71
+ }
68
72
  this.nango = nangoClient;
69
73
  this.connectionId = connectionId;
74
+ this.providerConfigKey = resolvedProviderConfigKey;
70
75
  }
71
76
  errorResult(action, fallback, error) {
72
77
  const prefix = isRateLimited(error)
@@ -88,7 +93,7 @@ export class GitHubIntegration {
88
93
  return this.execute(`searching code for "${query}"${repo ? ` in ${repo}` : ''}`, { items: [] }, async () => {
89
94
  const data = await this.nango.proxy({
90
95
  connectionId: this.connectionId,
91
- providerConfigKey: PROVIDER,
96
+ providerConfigKey: this.providerConfigKey,
92
97
  method: 'GET',
93
98
  endpoint: `/search/code?q=${encodeURIComponent(scopedQuery)}`,
94
99
  headers: { Accept: 'application/vnd.github.text-match+json' },
@@ -108,7 +113,7 @@ export class GitHubIntegration {
108
113
  return this.execute(`searching issues for "${query}"${repo ? ` in ${repo}` : ''}`, [], async () => {
109
114
  const data = await this.nango.proxy({
110
115
  connectionId: this.connectionId,
111
- providerConfigKey: PROVIDER,
116
+ providerConfigKey: this.providerConfigKey,
112
117
  method: 'GET',
113
118
  endpoint: `/search/issues?q=${encodeURIComponent(scopedQuery)}`,
114
119
  });
@@ -130,7 +135,7 @@ export class GitHubIntegration {
130
135
  return this.execute(`reading file ${owner}/${repo}/${path}${ref ? ` @ ${ref}` : ''}`, { path, content: '', sha: '' }, async () => {
131
136
  const data = await this.nango.proxy({
132
137
  connectionId: this.connectionId,
133
- providerConfigKey: PROVIDER,
138
+ providerConfigKey: this.providerConfigKey,
134
139
  method: 'GET',
135
140
  endpoint,
136
141
  });
@@ -148,13 +153,13 @@ export class GitHubIntegration {
148
153
  const [pr, files] = await Promise.all([
149
154
  this.nango.proxy({
150
155
  connectionId: this.connectionId,
151
- providerConfigKey: PROVIDER,
156
+ providerConfigKey: this.providerConfigKey,
152
157
  method: 'GET',
153
158
  endpoint: `/repos/${owner}/${repo}/pulls/${number}`,
154
159
  }),
155
160
  this.nango.proxy({
156
161
  connectionId: this.connectionId,
157
- providerConfigKey: PROVIDER,
162
+ providerConfigKey: this.providerConfigKey,
158
163
  method: 'GET',
159
164
  endpoint: `/repos/${owner}/${repo}/pulls/${number}/files`,
160
165
  }),
@@ -174,7 +179,7 @@ export class GitHubIntegration {
174
179
  return this.execute(`listing repository contents for ${owner}/${repo}${path ? `/${path}` : ''}`, [], async () => {
175
180
  const data = await this.nango.proxy({
176
181
  connectionId: this.connectionId,
177
- providerConfigKey: PROVIDER,
182
+ providerConfigKey: this.providerConfigKey,
178
183
  method: 'GET',
179
184
  endpoint: `/repos/${owner}/${repo}/contents${encodedPath}`,
180
185
  });
@@ -185,7 +190,7 @@ export class GitHubIntegration {
185
190
  return this.execute(`loading issue #${number} in ${owner}/${repo}`, { number, title: '', body: '', state: 'error', labels: [], url: '' }, async () => {
186
191
  const data = await this.nango.proxy({
187
192
  connectionId: this.connectionId,
188
- providerConfigKey: PROVIDER,
193
+ providerConfigKey: this.providerConfigKey,
189
194
  method: 'GET',
190
195
  endpoint: `/repos/${owner}/${repo}/issues/${number}`,
191
196
  });
@@ -0,0 +1,28 @@
1
+ import type { ConnectionProvider } from "./cloud-proxy-provider.js";
2
+ import { type ThreadMessage } from "../slack.js";
3
+ export interface SlackEgressResult {
4
+ ok: boolean;
5
+ ts?: string;
6
+ error?: string;
7
+ }
8
+ export declare class SlackEgressError extends Error {
9
+ readonly code: string;
10
+ readonly retryAfterMs?: number;
11
+ constructor(message: string, code?: string, retryAfterMs?: number);
12
+ }
13
+ export interface SlackReaction {
14
+ name: string;
15
+ count: number;
16
+ }
17
+ export interface SlackEgress {
18
+ postMessage(channel: string, text: string, threadTs?: string): Promise<SlackEgressResult>;
19
+ postMessageChunked(channel: string, text: string, threadTs?: string, maxChars?: number): Promise<SlackEgressResult>;
20
+ addReaction(channel: string, timestamp: string, emoji: string): Promise<void>;
21
+ fetchThreadHistory(channel: string, threadTs: string, botUserId?: string): Promise<ThreadMessage[]>;
22
+ getBotUserId(): Promise<string | undefined>;
23
+ getReactions(channel: string, timestamp: string): Promise<SlackReaction[]>;
24
+ }
25
+ export declare function createSlackEgress(provider: ConnectionProvider, workspaceId: string): SlackEgress;
26
+ export type { ConnectionProvider } from "./cloud-proxy-provider.js";
27
+ export type { ThreadMessage } from "../slack.js";
28
+ //# sourceMappingURL=slack-egress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-egress.d.ts","sourceRoot":"","sources":["../../src/integrations/slack-egress.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAgB,MAAM,2BAA2B,CAAC;AAElF,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AA4BrB,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;gBAEnB,OAAO,EAAE,MAAM,EAAE,IAAI,SAAwB,EAAE,YAAY,CAAC,EAAE,MAAM;CAMjF;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC1F,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9B,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,kBAAkB,CAChB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IAC5B,YAAY,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAC5C,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;CAC5E;AA+ED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,CAkKhG;AAED,YAAY,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AACpE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,181 @@
1
+ import { SLACK_MESSAGE_MAX_CHARS, chunkSlackMessage, cleanSlackText, } from "../slack.js";
2
+ export class SlackEgressError extends Error {
3
+ code;
4
+ retryAfterMs;
5
+ constructor(message, code = "slack_egress_failed", retryAfterMs) {
6
+ super(message);
7
+ this.name = "SlackEgressError";
8
+ this.code = code;
9
+ this.retryAfterMs = retryAfterMs;
10
+ }
11
+ }
12
+ function isRecord(value) {
13
+ return typeof value === "object" && value !== null && !Array.isArray(value);
14
+ }
15
+ function asString(value) {
16
+ return typeof value === "string" ? value : undefined;
17
+ }
18
+ function asNumber(value) {
19
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
20
+ }
21
+ function toSlackEgressError(error, fallbackCode = "slack_egress_failed") {
22
+ if (error instanceof SlackEgressError) {
23
+ return error;
24
+ }
25
+ if (isRecord(error)) {
26
+ const message = asString(error.message) ?? "Slack request failed";
27
+ const code = asString(error.code) ?? fallbackCode;
28
+ const retryAfterMs = asNumber(error.retryAfterMs);
29
+ return new SlackEgressError(message, code, retryAfterMs);
30
+ }
31
+ if (error instanceof Error) {
32
+ return new SlackEgressError(error.message, fallbackCode);
33
+ }
34
+ return new SlackEgressError("Slack request failed", fallbackCode);
35
+ }
36
+ function assertWorkspaceId(workspaceId) {
37
+ if (typeof workspaceId !== "string" || workspaceId.trim().length === 0) {
38
+ throw new Error("A workspaceId is required to create Slack egress");
39
+ }
40
+ return workspaceId.trim();
41
+ }
42
+ function createProxyRequest(workspaceId, endpoint, method, options) {
43
+ return {
44
+ method,
45
+ endpoint,
46
+ workspaceId,
47
+ ...(options?.data !== undefined ? { data: options.data } : {}),
48
+ ...(options?.params !== undefined ? { params: options.params } : {}),
49
+ };
50
+ }
51
+ async function executeSlackRequest(provider, request) {
52
+ try {
53
+ const response = await provider.proxy(request);
54
+ if (isRecord(response.data) && response.data.ok === false) {
55
+ throw new SlackEgressError(asString(response.data.error) ?? "Slack request failed", asString(response.data.code) ?? "slack_error", asNumber(response.data.retryAfterMs));
56
+ }
57
+ if (response.status >= 400) {
58
+ throw new SlackEgressError(`Slack request failed with status ${response.status}`, `http_${response.status}`);
59
+ }
60
+ return response.data;
61
+ }
62
+ catch (error) {
63
+ throw toSlackEgressError(error);
64
+ }
65
+ }
66
+ export function createSlackEgress(provider, workspaceId) {
67
+ const resolvedWorkspaceId = assertWorkspaceId(workspaceId);
68
+ let cachedBotUserId;
69
+ let botUserIdLoaded = false;
70
+ const postMessage = async (channel, text, threadTs) => {
71
+ const body = {
72
+ channel,
73
+ text,
74
+ ...(threadTs ? { thread_ts: threadTs } : {}),
75
+ };
76
+ const response = await executeSlackRequest(provider, createProxyRequest(resolvedWorkspaceId, "/chat.postMessage", "POST", { data: body }));
77
+ return {
78
+ ok: response.ok === true,
79
+ ...(response.ts ? { ts: response.ts } : {}),
80
+ ...(response.error ? { error: response.error } : {}),
81
+ };
82
+ };
83
+ return {
84
+ postMessage,
85
+ async postMessageChunked(channel, text, threadTs, maxChars = SLACK_MESSAGE_MAX_CHARS) {
86
+ const effectiveMaxChars = Math.min(Math.max(1, maxChars), SLACK_MESSAGE_MAX_CHARS);
87
+ const chunks = chunkSlackMessage(text, effectiveMaxChars);
88
+ if (!chunks.length) {
89
+ return { ok: false, error: "Cannot post an empty Slack message" };
90
+ }
91
+ let firstTs;
92
+ let replyThreadTs = threadTs;
93
+ for (const chunk of chunks) {
94
+ const result = await postMessage(channel, chunk, replyThreadTs);
95
+ if (!result.ok) {
96
+ return {
97
+ ok: false,
98
+ ...(firstTs ? { ts: firstTs } : {}),
99
+ ...(result.error ? { error: result.error } : {}),
100
+ };
101
+ }
102
+ firstTs ??= result.ts;
103
+ replyThreadTs ??= result.ts;
104
+ }
105
+ return {
106
+ ok: true,
107
+ ...(firstTs ? { ts: firstTs } : {}),
108
+ };
109
+ },
110
+ async addReaction(channel, timestamp, emoji) {
111
+ try {
112
+ await executeSlackRequest(provider, createProxyRequest(resolvedWorkspaceId, "/reactions.add", "POST", {
113
+ data: {
114
+ channel,
115
+ timestamp,
116
+ name: emoji,
117
+ },
118
+ }));
119
+ }
120
+ catch {
121
+ // Reactions are best-effort and should not block callers.
122
+ }
123
+ },
124
+ async fetchThreadHistory(channel, threadTs, botUserId) {
125
+ const response = await executeSlackRequest(provider, createProxyRequest(resolvedWorkspaceId, "/conversations.replies", "POST", {
126
+ data: {
127
+ channel,
128
+ ts: threadTs,
129
+ },
130
+ }));
131
+ if (!Array.isArray(response.messages)) {
132
+ return [];
133
+ }
134
+ return response.messages
135
+ .filter((message) => !message.subtype || message.subtype === "bot_message")
136
+ .sort((left, right) => Number(left.ts ?? "0") - Number(right.ts ?? "0"))
137
+ .map((message) => {
138
+ const content = cleanSlackText(message.text);
139
+ const isAssistant = Boolean(message.bot_id) || (!!botUserId && message.user === botUserId);
140
+ return {
141
+ role: isAssistant ? "assistant" : "user",
142
+ content,
143
+ ...(message.ts ? { ts: message.ts } : {}),
144
+ };
145
+ })
146
+ .filter((message) => message.content.length > 0)
147
+ .slice(-20);
148
+ },
149
+ async getBotUserId() {
150
+ if (botUserIdLoaded) {
151
+ return cachedBotUserId;
152
+ }
153
+ const response = await executeSlackRequest(provider, createProxyRequest(resolvedWorkspaceId, "/auth.test", "POST"));
154
+ cachedBotUserId = asString(response.user_id);
155
+ botUserIdLoaded = true;
156
+ return cachedBotUserId;
157
+ },
158
+ async getReactions(channel, timestamp) {
159
+ const response = await executeSlackRequest(provider, createProxyRequest(resolvedWorkspaceId, "/reactions.get", "GET", {
160
+ params: {
161
+ channel,
162
+ timestamp,
163
+ },
164
+ }));
165
+ const reactions = response.message?.reactions;
166
+ if (!Array.isArray(reactions)) {
167
+ return [];
168
+ }
169
+ return reactions
170
+ .map((reaction) => {
171
+ const name = asString(reaction.name);
172
+ const count = asNumber(reaction.count);
173
+ if (!name || count === undefined) {
174
+ return null;
175
+ }
176
+ return { name, count };
177
+ })
178
+ .filter((reaction) => reaction !== null);
179
+ },
180
+ };
181
+ }
@@ -0,0 +1,26 @@
1
+ import { normalizeSlackWebhook } from "@relayfile/adapter-slack";
2
+ import type { NormalizedWebhook, SlackEnvelope as AdapterSlackEventEnvelope, SlackEvent as AdapterSlackEvent } from "@relayfile/adapter-slack";
3
+ /**
4
+ * Parse a Slack webhook body that may have been forwarded through Nango.
5
+ *
6
+ * Real-world delivery path in production:
7
+ * Slack → Nango forward webhook → sage (this function)
8
+ *
9
+ * Nango wraps the underlying Slack event in its own envelope:
10
+ * { type: "forward", from: "slack", connectionId, providerConfigKey, payload: {...slack event...} }
11
+ *
12
+ * The raw Slack envelope (what the @relayfile/adapter-slack parser expects) is
13
+ * whatever is inside `.payload`. For direct webhook delivery paths (no Nango
14
+ * in front) the body IS the raw Slack envelope, no unwrap needed.
15
+ *
16
+ * This wrapper detects the envelope shape and hands the adapter parser the
17
+ * unwrapped inner payload in both cases.
18
+ */
19
+ export declare function parseSlackWebhookEnvelope(rawBody: unknown): AdapterSlackEventEnvelope;
20
+ export { normalizeSlackWebhook };
21
+ export type SlackEvent = AdapterSlackEvent;
22
+ export type SlackEventEnvelope = AdapterSlackEventEnvelope;
23
+ export type NormalizedSlackWebhook = Omit<NormalizedWebhook, "payload"> & {
24
+ payload: SlackEventEnvelope;
25
+ };
26
+ //# sourceMappingURL=slack-ingress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack-ingress.d.ts","sourceRoot":"","sources":["../../src/integrations/slack-ingress.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,qBAAqB,EAEtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EACV,iBAAiB,EACjB,aAAa,IAAI,yBAAyB,EAC1C,UAAU,IAAI,iBAAiB,EAChC,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,yBAAyB,CAerF;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAEjC,MAAM,MAAM,UAAU,GAAG,iBAAiB,CAAC;AAC3C,MAAM,MAAM,kBAAkB,GAAG,yBAAyB,CAAC;AAE3D,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,GAAG;IACxE,OAAO,EAAE,kBAAkB,CAAC;CAC7B,CAAC"}
@@ -0,0 +1,31 @@
1
+ import { parseNangoWebhookPayload, } from "@relayfile/provider-nango";
2
+ import { normalizeSlackWebhook, parseSlackWebhookEnvelope as parseRawSlackWebhookEnvelope, } from "@relayfile/adapter-slack";
3
+ /**
4
+ * Parse a Slack webhook body that may have been forwarded through Nango.
5
+ *
6
+ * Real-world delivery path in production:
7
+ * Slack → Nango forward webhook → sage (this function)
8
+ *
9
+ * Nango wraps the underlying Slack event in its own envelope:
10
+ * { type: "forward", from: "slack", connectionId, providerConfigKey, payload: {...slack event...} }
11
+ *
12
+ * The raw Slack envelope (what the @relayfile/adapter-slack parser expects) is
13
+ * whatever is inside `.payload`. For direct webhook delivery paths (no Nango
14
+ * in front) the body IS the raw Slack envelope, no unwrap needed.
15
+ *
16
+ * This wrapper detects the envelope shape and hands the adapter parser the
17
+ * unwrapped inner payload in both cases.
18
+ */
19
+ export function parseSlackWebhookEnvelope(rawBody) {
20
+ const envelope = parseNangoWebhookPayload(rawBody);
21
+ if (envelope.type === "forward") {
22
+ const inner = envelope.payload;
23
+ if (!inner || typeof inner !== "object") {
24
+ throw new TypeError("Nango forward webhook payload is missing its inner object — cannot extract Slack envelope");
25
+ }
26
+ return parseRawSlackWebhookEnvelope(inner);
27
+ }
28
+ // Direct webhook delivery — the body itself is already a raw Slack envelope.
29
+ return parseRawSlackWebhookEnvelope(envelope);
30
+ }
31
+ export { normalizeSlackWebhook };
package/dist/nango.d.ts CHANGED
@@ -1,6 +1,3 @@
1
- export declare const NANGO_INTEGRATIONS: {
2
- readonly GITHUB: "github-app-oauth";
3
- };
4
1
  export interface ProxyConfig {
5
2
  connectionId: string;
6
3
  providerConfigKey: string;
@@ -33,7 +30,6 @@ export declare class NangoError extends Error {
33
30
  export declare class NangoClient {
34
31
  private client;
35
32
  private readonly githubOrgDiscoveryCache;
36
- private readonly slackBotUserIdCache;
37
33
  private readonly secretKey;
38
34
  constructor({ secretKey }: {
39
35
  secretKey: string;
@@ -41,8 +37,7 @@ export declare class NangoClient {
41
37
  private getClient;
42
38
  proxy<T>(config: ProxyConfig): Promise<T>;
43
39
  getConnection(connectionId: string, providerConfigKey: string): Promise<NangoConnection | null>;
44
- discoverGitHubOrgs(connectionId: string): Promise<GitHubOrgDiscovery>;
45
- getSlackBotUserId(connectionId: string, providerConfigKey: string): Promise<string>;
40
+ discoverGitHubOrgs(connectionId: string, providerConfigKey: string): Promise<GitHubOrgDiscovery>;
46
41
  private listGitHubInstallationRepos;
47
42
  }
48
43
  //# sourceMappingURL=nango.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"nango.d.ts","sourceRoot":"","sources":["../src/nango.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,kBAAkB;;CAErB,CAAC;AAKX,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClE;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC9B;AAgCD,qBAAa,UAAW,SAAQ,KAAK;aAEjB,SAAS,EAAE,MAAM;aACjB,MAAM,EAAE,MAAM;aACd,KAAK,EAAE,OAAO;gBAFd,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO;CAKjC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAqD;IAC7F,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6B;IACjE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,EAAE,SAAS,EAAE,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE;IAIhD,OAAO,CAAC,SAAS;IAIX,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAQzC,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAQ/F,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAwDrE,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAsB3E,2BAA2B;CAmD1C"}
1
+ {"version":3,"file":"nango.d.ts","sourceRoot":"","sources":["../src/nango.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpD,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClE;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CAC9B;AA4BD,qBAAa,UAAW,SAAQ,KAAK;aAEjB,SAAS,EAAE,MAAM;aACjB,MAAM,EAAE,MAAM;aACd,KAAK,EAAE,OAAO;gBAFd,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO;CAKjC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAqD;IAC7F,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;gBAEvB,EAAE,SAAS,EAAE,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE;IAIhD,OAAO,CAAC,SAAS;IAIX,KAAK,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC;IAQzC,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IAQ/F,kBAAkB,CACtB,YAAY,EAAE,MAAM,EACpB,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,kBAAkB,CAAC;YA8DhB,2BAA2B;CAuD1C"}