@supyagent/sdk 0.1.39 → 0.2.1

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.
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/connect.ts
21
+ var connect_exports = {};
22
+ __export(connect_exports, {
23
+ handleConnectCallback: () => handleConnectCallback,
24
+ openConnectPopup: () => openConnectPopup
25
+ });
26
+ module.exports = __toCommonJS(connect_exports);
27
+
28
+ // src/connect/popup.ts
29
+ function openConnectPopup(options) {
30
+ const { connectUrl, width = 500, height = 700, onSuccess, onError } = options;
31
+ return new Promise((resolve, reject) => {
32
+ const left = Math.round(window.screenX + (window.outerWidth - width) / 2);
33
+ const top = Math.round(window.screenY + (window.outerHeight - height) / 2);
34
+ const features = `width=${width},height=${height},left=${left},top=${top},popup=1`;
35
+ const popup = window.open(connectUrl, "supyagent_connect", features);
36
+ if (!popup) {
37
+ const err = new Error(
38
+ "Popup was blocked by the browser. Please allow popups for this site."
39
+ );
40
+ onError?.(err);
41
+ reject(err);
42
+ return;
43
+ }
44
+ const popupRef = popup;
45
+ let settled = false;
46
+ function cleanup() {
47
+ window.removeEventListener("message", onMessage);
48
+ clearInterval(pollTimer);
49
+ }
50
+ function onMessage(event) {
51
+ const data = event.data;
52
+ if (!data || data.type !== "supyagent:connect") return;
53
+ settled = true;
54
+ cleanup();
55
+ try {
56
+ popupRef.close();
57
+ } catch {
58
+ }
59
+ if (data.status === "success" && data.provider && data.accountId) {
60
+ const result = {
61
+ status: "success",
62
+ provider: data.provider,
63
+ accountId: data.accountId
64
+ };
65
+ onSuccess?.(result);
66
+ resolve(result);
67
+ } else {
68
+ const err = new Error(data.error || "OAuth connect failed");
69
+ onError?.(err);
70
+ reject(err);
71
+ }
72
+ }
73
+ window.addEventListener("message", onMessage);
74
+ const pollTimer = setInterval(() => {
75
+ if (!settled && popupRef.closed) {
76
+ settled = true;
77
+ cleanup();
78
+ const err = new Error("Popup was closed before completing the OAuth flow");
79
+ onError?.(err);
80
+ reject(err);
81
+ }
82
+ }, 500);
83
+ });
84
+ }
85
+
86
+ // src/connect/callback.ts
87
+ function handleConnectCallback(options) {
88
+ const { targetOrigin = "*", autoClose = true } = options ?? {};
89
+ const params = new URLSearchParams(window.location.search);
90
+ const status = params.get("status");
91
+ const provider = params.get("provider");
92
+ const accountId = params.get("account_id");
93
+ const error = params.get("error");
94
+ const message = {
95
+ type: "supyagent:connect",
96
+ status: status === "success" ? "success" : "error",
97
+ ...provider ? { provider } : {},
98
+ ...accountId ? { accountId } : {},
99
+ ...error ? { error } : {}
100
+ };
101
+ if (window.opener) {
102
+ window.opener.postMessage(message, targetOrigin);
103
+ }
104
+ if (autoClose) {
105
+ window.close();
106
+ }
107
+ }
108
+ // Annotate the CommonJS export names for ESM import in node:
109
+ 0 && (module.exports = {
110
+ handleConnectCallback,
111
+ openConnectPopup
112
+ });
113
+ //# sourceMappingURL=connect.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connect.ts","../src/connect/popup.ts","../src/connect/callback.ts"],"sourcesContent":["export { openConnectPopup } from \"./connect/popup.js\";\nexport { handleConnectCallback } from \"./connect/callback.js\";\nexport type {\n ConnectMessage,\n ConnectPopupOptions,\n ConnectPopupResult,\n ConnectCallbackOptions,\n} from \"./connect/types.js\";\n","import type { ConnectMessage, ConnectPopupOptions, ConnectPopupResult } from \"./types.js\";\n\n/**\n * Opens an OAuth connect popup and returns a promise that resolves\n * when the flow completes. The partner's redirect page must call\n * `handleConnectCallback()` to post the result back via `postMessage`.\n */\nexport function openConnectPopup(options: ConnectPopupOptions): Promise<ConnectPopupResult> {\n const { connectUrl, width = 500, height = 700, onSuccess, onError } = options;\n\n return new Promise<ConnectPopupResult>((resolve, reject) => {\n // Center the popup on screen\n const left = Math.round(window.screenX + (window.outerWidth - width) / 2);\n const top = Math.round(window.screenY + (window.outerHeight - height) / 2);\n const features = `width=${width},height=${height},left=${left},top=${top},popup=1`;\n\n const popup = window.open(connectUrl, \"supyagent_connect\", features);\n\n if (!popup) {\n const err = new Error(\n \"Popup was blocked by the browser. Please allow popups for this site.\",\n );\n onError?.(err);\n reject(err);\n return;\n }\n\n // Capture non-null ref so TS narrows inside closures\n const popupRef = popup;\n let settled = false;\n\n function cleanup() {\n window.removeEventListener(\"message\", onMessage);\n clearInterval(pollTimer);\n }\n\n function onMessage(event: MessageEvent) {\n const data = event.data as ConnectMessage | undefined;\n if (!data || data.type !== \"supyagent:connect\") return;\n\n settled = true;\n cleanup();\n\n try {\n popupRef.close();\n } catch {\n // Ignore if already closed\n }\n\n if (data.status === \"success\" && data.provider && data.accountId) {\n const result: ConnectPopupResult = {\n status: \"success\",\n provider: data.provider,\n accountId: data.accountId,\n };\n onSuccess?.(result);\n resolve(result);\n } else {\n const err = new Error(data.error || \"OAuth connect failed\");\n onError?.(err);\n reject(err);\n }\n }\n\n window.addEventListener(\"message\", onMessage);\n\n // Poll for manual popup close\n const pollTimer = setInterval(() => {\n if (!settled && popupRef.closed) {\n settled = true;\n cleanup();\n const err = new Error(\"Popup was closed before completing the OAuth flow\");\n onError?.(err);\n reject(err);\n }\n }, 500);\n });\n}\n","import type { ConnectCallbackOptions, ConnectMessage } from \"./types.js\";\n\n/**\n * Call this on the partner's redirect page after OAuth completes.\n * Reads the result from URL query params and posts it back to the\n * opener window via `postMessage`, then optionally closes the window.\n */\nexport function handleConnectCallback(options?: ConnectCallbackOptions): void {\n const { targetOrigin = \"*\", autoClose = true } = options ?? {};\n\n const params = new URLSearchParams(window.location.search);\n const status = params.get(\"status\");\n const provider = params.get(\"provider\");\n const accountId = params.get(\"account_id\");\n const error = params.get(\"error\");\n\n const message: ConnectMessage = {\n type: \"supyagent:connect\",\n status: status === \"success\" ? \"success\" : \"error\",\n ...(provider ? { provider } : {}),\n ...(accountId ? { accountId } : {}),\n ...(error ? { error } : {}),\n };\n\n if (window.opener) {\n window.opener.postMessage(message, targetOrigin);\n }\n\n if (autoClose) {\n window.close();\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACOO,SAAS,iBAAiB,SAA2D;AAC1F,QAAM,EAAE,YAAY,QAAQ,KAAK,SAAS,KAAK,WAAW,QAAQ,IAAI;AAEtE,SAAO,IAAI,QAA4B,CAAC,SAAS,WAAW;AAE1D,UAAM,OAAO,KAAK,MAAM,OAAO,WAAW,OAAO,aAAa,SAAS,CAAC;AACxE,UAAM,MAAM,KAAK,MAAM,OAAO,WAAW,OAAO,cAAc,UAAU,CAAC;AACzE,UAAM,WAAW,SAAS,KAAK,WAAW,MAAM,SAAS,IAAI,QAAQ,GAAG;AAExE,UAAM,QAAQ,OAAO,KAAK,YAAY,qBAAqB,QAAQ;AAEnE,QAAI,CAAC,OAAO;AACV,YAAM,MAAM,IAAI;AAAA,QACd;AAAA,MACF;AACA,gBAAU,GAAG;AACb,aAAO,GAAG;AACV;AAAA,IACF;AAGA,UAAM,WAAW;AACjB,QAAI,UAAU;AAEd,aAAS,UAAU;AACjB,aAAO,oBAAoB,WAAW,SAAS;AAC/C,oBAAc,SAAS;AAAA,IACzB;AAEA,aAAS,UAAU,OAAqB;AACtC,YAAM,OAAO,MAAM;AACnB,UAAI,CAAC,QAAQ,KAAK,SAAS,oBAAqB;AAEhD,gBAAU;AACV,cAAQ;AAER,UAAI;AACF,iBAAS,MAAM;AAAA,MACjB,QAAQ;AAAA,MAER;AAEA,UAAI,KAAK,WAAW,aAAa,KAAK,YAAY,KAAK,WAAW;AAChE,cAAM,SAA6B;AAAA,UACjC,QAAQ;AAAA,UACR,UAAU,KAAK;AAAA,UACf,WAAW,KAAK;AAAA,QAClB;AACA,oBAAY,MAAM;AAClB,gBAAQ,MAAM;AAAA,MAChB,OAAO;AACL,cAAM,MAAM,IAAI,MAAM,KAAK,SAAS,sBAAsB;AAC1D,kBAAU,GAAG;AACb,eAAO,GAAG;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,iBAAiB,WAAW,SAAS;AAG5C,UAAM,YAAY,YAAY,MAAM;AAClC,UAAI,CAAC,WAAW,SAAS,QAAQ;AAC/B,kBAAU;AACV,gBAAQ;AACR,cAAM,MAAM,IAAI,MAAM,mDAAmD;AACzE,kBAAU,GAAG;AACb,eAAO,GAAG;AAAA,MACZ;AAAA,IACF,GAAG,GAAG;AAAA,EACR,CAAC;AACH;;;ACtEO,SAAS,sBAAsB,SAAwC;AAC5E,QAAM,EAAE,eAAe,KAAK,YAAY,KAAK,IAAI,WAAW,CAAC;AAE7D,QAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AACzD,QAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,QAAM,WAAW,OAAO,IAAI,UAAU;AACtC,QAAM,YAAY,OAAO,IAAI,YAAY;AACzC,QAAM,QAAQ,OAAO,IAAI,OAAO;AAEhC,QAAM,UAA0B;AAAA,IAC9B,MAAM;AAAA,IACN,QAAQ,WAAW,YAAY,YAAY;AAAA,IAC3C,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,EAC3B;AAEA,MAAI,OAAO,QAAQ;AACjB,WAAO,OAAO,YAAY,SAAS,YAAY;AAAA,EACjD;AAEA,MAAI,WAAW;AACb,WAAO,MAAM;AAAA,EACf;AACF;","names":[]}
@@ -0,0 +1,50 @@
1
+ /** Shape of the postMessage sent from the redirect page back to the opener */
2
+ interface ConnectMessage {
3
+ type: "supyagent:connect";
4
+ status: "success" | "error";
5
+ provider?: string;
6
+ accountId?: string;
7
+ error?: string;
8
+ }
9
+ /** Options for openConnectPopup() */
10
+ interface ConnectPopupOptions {
11
+ /** The connect URL returned by client.accounts.connect() */
12
+ connectUrl: string;
13
+ /** Popup width in pixels (default: 500) */
14
+ width?: number;
15
+ /** Popup height in pixels (default: 700) */
16
+ height?: number;
17
+ /** Called when the OAuth flow succeeds */
18
+ onSuccess?: (result: ConnectPopupResult) => void;
19
+ /** Called when the OAuth flow fails */
20
+ onError?: (error: Error) => void;
21
+ }
22
+ /** Resolved value of the openConnectPopup() promise */
23
+ interface ConnectPopupResult {
24
+ status: "success";
25
+ provider: string;
26
+ accountId: string;
27
+ }
28
+ /** Options for handleConnectCallback() */
29
+ interface ConnectCallbackOptions {
30
+ /** Target origin for postMessage (default: "*") */
31
+ targetOrigin?: string;
32
+ /** Whether to auto-close the window after posting (default: true) */
33
+ autoClose?: boolean;
34
+ }
35
+
36
+ /**
37
+ * Opens an OAuth connect popup and returns a promise that resolves
38
+ * when the flow completes. The partner's redirect page must call
39
+ * `handleConnectCallback()` to post the result back via `postMessage`.
40
+ */
41
+ declare function openConnectPopup(options: ConnectPopupOptions): Promise<ConnectPopupResult>;
42
+
43
+ /**
44
+ * Call this on the partner's redirect page after OAuth completes.
45
+ * Reads the result from URL query params and posts it back to the
46
+ * opener window via `postMessage`, then optionally closes the window.
47
+ */
48
+ declare function handleConnectCallback(options?: ConnectCallbackOptions): void;
49
+
50
+ export { type ConnectCallbackOptions, type ConnectMessage, type ConnectPopupOptions, type ConnectPopupResult, handleConnectCallback, openConnectPopup };
@@ -0,0 +1,50 @@
1
+ /** Shape of the postMessage sent from the redirect page back to the opener */
2
+ interface ConnectMessage {
3
+ type: "supyagent:connect";
4
+ status: "success" | "error";
5
+ provider?: string;
6
+ accountId?: string;
7
+ error?: string;
8
+ }
9
+ /** Options for openConnectPopup() */
10
+ interface ConnectPopupOptions {
11
+ /** The connect URL returned by client.accounts.connect() */
12
+ connectUrl: string;
13
+ /** Popup width in pixels (default: 500) */
14
+ width?: number;
15
+ /** Popup height in pixels (default: 700) */
16
+ height?: number;
17
+ /** Called when the OAuth flow succeeds */
18
+ onSuccess?: (result: ConnectPopupResult) => void;
19
+ /** Called when the OAuth flow fails */
20
+ onError?: (error: Error) => void;
21
+ }
22
+ /** Resolved value of the openConnectPopup() promise */
23
+ interface ConnectPopupResult {
24
+ status: "success";
25
+ provider: string;
26
+ accountId: string;
27
+ }
28
+ /** Options for handleConnectCallback() */
29
+ interface ConnectCallbackOptions {
30
+ /** Target origin for postMessage (default: "*") */
31
+ targetOrigin?: string;
32
+ /** Whether to auto-close the window after posting (default: true) */
33
+ autoClose?: boolean;
34
+ }
35
+
36
+ /**
37
+ * Opens an OAuth connect popup and returns a promise that resolves
38
+ * when the flow completes. The partner's redirect page must call
39
+ * `handleConnectCallback()` to post the result back via `postMessage`.
40
+ */
41
+ declare function openConnectPopup(options: ConnectPopupOptions): Promise<ConnectPopupResult>;
42
+
43
+ /**
44
+ * Call this on the partner's redirect page after OAuth completes.
45
+ * Reads the result from URL query params and posts it back to the
46
+ * opener window via `postMessage`, then optionally closes the window.
47
+ */
48
+ declare function handleConnectCallback(options?: ConnectCallbackOptions): void;
49
+
50
+ export { type ConnectCallbackOptions, type ConnectMessage, type ConnectPopupOptions, type ConnectPopupResult, handleConnectCallback, openConnectPopup };
@@ -0,0 +1,85 @@
1
+ // src/connect/popup.ts
2
+ function openConnectPopup(options) {
3
+ const { connectUrl, width = 500, height = 700, onSuccess, onError } = options;
4
+ return new Promise((resolve, reject) => {
5
+ const left = Math.round(window.screenX + (window.outerWidth - width) / 2);
6
+ const top = Math.round(window.screenY + (window.outerHeight - height) / 2);
7
+ const features = `width=${width},height=${height},left=${left},top=${top},popup=1`;
8
+ const popup = window.open(connectUrl, "supyagent_connect", features);
9
+ if (!popup) {
10
+ const err = new Error(
11
+ "Popup was blocked by the browser. Please allow popups for this site."
12
+ );
13
+ onError?.(err);
14
+ reject(err);
15
+ return;
16
+ }
17
+ const popupRef = popup;
18
+ let settled = false;
19
+ function cleanup() {
20
+ window.removeEventListener("message", onMessage);
21
+ clearInterval(pollTimer);
22
+ }
23
+ function onMessage(event) {
24
+ const data = event.data;
25
+ if (!data || data.type !== "supyagent:connect") return;
26
+ settled = true;
27
+ cleanup();
28
+ try {
29
+ popupRef.close();
30
+ } catch {
31
+ }
32
+ if (data.status === "success" && data.provider && data.accountId) {
33
+ const result = {
34
+ status: "success",
35
+ provider: data.provider,
36
+ accountId: data.accountId
37
+ };
38
+ onSuccess?.(result);
39
+ resolve(result);
40
+ } else {
41
+ const err = new Error(data.error || "OAuth connect failed");
42
+ onError?.(err);
43
+ reject(err);
44
+ }
45
+ }
46
+ window.addEventListener("message", onMessage);
47
+ const pollTimer = setInterval(() => {
48
+ if (!settled && popupRef.closed) {
49
+ settled = true;
50
+ cleanup();
51
+ const err = new Error("Popup was closed before completing the OAuth flow");
52
+ onError?.(err);
53
+ reject(err);
54
+ }
55
+ }, 500);
56
+ });
57
+ }
58
+
59
+ // src/connect/callback.ts
60
+ function handleConnectCallback(options) {
61
+ const { targetOrigin = "*", autoClose = true } = options ?? {};
62
+ const params = new URLSearchParams(window.location.search);
63
+ const status = params.get("status");
64
+ const provider = params.get("provider");
65
+ const accountId = params.get("account_id");
66
+ const error = params.get("error");
67
+ const message = {
68
+ type: "supyagent:connect",
69
+ status: status === "success" ? "success" : "error",
70
+ ...provider ? { provider } : {},
71
+ ...accountId ? { accountId } : {},
72
+ ...error ? { error } : {}
73
+ };
74
+ if (window.opener) {
75
+ window.opener.postMessage(message, targetOrigin);
76
+ }
77
+ if (autoClose) {
78
+ window.close();
79
+ }
80
+ }
81
+ export {
82
+ handleConnectCallback,
83
+ openConnectPopup
84
+ };
85
+ //# sourceMappingURL=connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connect/popup.ts","../src/connect/callback.ts"],"sourcesContent":["import type { ConnectMessage, ConnectPopupOptions, ConnectPopupResult } from \"./types.js\";\n\n/**\n * Opens an OAuth connect popup and returns a promise that resolves\n * when the flow completes. The partner's redirect page must call\n * `handleConnectCallback()` to post the result back via `postMessage`.\n */\nexport function openConnectPopup(options: ConnectPopupOptions): Promise<ConnectPopupResult> {\n const { connectUrl, width = 500, height = 700, onSuccess, onError } = options;\n\n return new Promise<ConnectPopupResult>((resolve, reject) => {\n // Center the popup on screen\n const left = Math.round(window.screenX + (window.outerWidth - width) / 2);\n const top = Math.round(window.screenY + (window.outerHeight - height) / 2);\n const features = `width=${width},height=${height},left=${left},top=${top},popup=1`;\n\n const popup = window.open(connectUrl, \"supyagent_connect\", features);\n\n if (!popup) {\n const err = new Error(\n \"Popup was blocked by the browser. Please allow popups for this site.\",\n );\n onError?.(err);\n reject(err);\n return;\n }\n\n // Capture non-null ref so TS narrows inside closures\n const popupRef = popup;\n let settled = false;\n\n function cleanup() {\n window.removeEventListener(\"message\", onMessage);\n clearInterval(pollTimer);\n }\n\n function onMessage(event: MessageEvent) {\n const data = event.data as ConnectMessage | undefined;\n if (!data || data.type !== \"supyagent:connect\") return;\n\n settled = true;\n cleanup();\n\n try {\n popupRef.close();\n } catch {\n // Ignore if already closed\n }\n\n if (data.status === \"success\" && data.provider && data.accountId) {\n const result: ConnectPopupResult = {\n status: \"success\",\n provider: data.provider,\n accountId: data.accountId,\n };\n onSuccess?.(result);\n resolve(result);\n } else {\n const err = new Error(data.error || \"OAuth connect failed\");\n onError?.(err);\n reject(err);\n }\n }\n\n window.addEventListener(\"message\", onMessage);\n\n // Poll for manual popup close\n const pollTimer = setInterval(() => {\n if (!settled && popupRef.closed) {\n settled = true;\n cleanup();\n const err = new Error(\"Popup was closed before completing the OAuth flow\");\n onError?.(err);\n reject(err);\n }\n }, 500);\n });\n}\n","import type { ConnectCallbackOptions, ConnectMessage } from \"./types.js\";\n\n/**\n * Call this on the partner's redirect page after OAuth completes.\n * Reads the result from URL query params and posts it back to the\n * opener window via `postMessage`, then optionally closes the window.\n */\nexport function handleConnectCallback(options?: ConnectCallbackOptions): void {\n const { targetOrigin = \"*\", autoClose = true } = options ?? {};\n\n const params = new URLSearchParams(window.location.search);\n const status = params.get(\"status\");\n const provider = params.get(\"provider\");\n const accountId = params.get(\"account_id\");\n const error = params.get(\"error\");\n\n const message: ConnectMessage = {\n type: \"supyagent:connect\",\n status: status === \"success\" ? \"success\" : \"error\",\n ...(provider ? { provider } : {}),\n ...(accountId ? { accountId } : {}),\n ...(error ? { error } : {}),\n };\n\n if (window.opener) {\n window.opener.postMessage(message, targetOrigin);\n }\n\n if (autoClose) {\n window.close();\n }\n}\n"],"mappings":";AAOO,SAAS,iBAAiB,SAA2D;AAC1F,QAAM,EAAE,YAAY,QAAQ,KAAK,SAAS,KAAK,WAAW,QAAQ,IAAI;AAEtE,SAAO,IAAI,QAA4B,CAAC,SAAS,WAAW;AAE1D,UAAM,OAAO,KAAK,MAAM,OAAO,WAAW,OAAO,aAAa,SAAS,CAAC;AACxE,UAAM,MAAM,KAAK,MAAM,OAAO,WAAW,OAAO,cAAc,UAAU,CAAC;AACzE,UAAM,WAAW,SAAS,KAAK,WAAW,MAAM,SAAS,IAAI,QAAQ,GAAG;AAExE,UAAM,QAAQ,OAAO,KAAK,YAAY,qBAAqB,QAAQ;AAEnE,QAAI,CAAC,OAAO;AACV,YAAM,MAAM,IAAI;AAAA,QACd;AAAA,MACF;AACA,gBAAU,GAAG;AACb,aAAO,GAAG;AACV;AAAA,IACF;AAGA,UAAM,WAAW;AACjB,QAAI,UAAU;AAEd,aAAS,UAAU;AACjB,aAAO,oBAAoB,WAAW,SAAS;AAC/C,oBAAc,SAAS;AAAA,IACzB;AAEA,aAAS,UAAU,OAAqB;AACtC,YAAM,OAAO,MAAM;AACnB,UAAI,CAAC,QAAQ,KAAK,SAAS,oBAAqB;AAEhD,gBAAU;AACV,cAAQ;AAER,UAAI;AACF,iBAAS,MAAM;AAAA,MACjB,QAAQ;AAAA,MAER;AAEA,UAAI,KAAK,WAAW,aAAa,KAAK,YAAY,KAAK,WAAW;AAChE,cAAM,SAA6B;AAAA,UACjC,QAAQ;AAAA,UACR,UAAU,KAAK;AAAA,UACf,WAAW,KAAK;AAAA,QAClB;AACA,oBAAY,MAAM;AAClB,gBAAQ,MAAM;AAAA,MAChB,OAAO;AACL,cAAM,MAAM,IAAI,MAAM,KAAK,SAAS,sBAAsB;AAC1D,kBAAU,GAAG;AACb,eAAO,GAAG;AAAA,MACZ;AAAA,IACF;AAEA,WAAO,iBAAiB,WAAW,SAAS;AAG5C,UAAM,YAAY,YAAY,MAAM;AAClC,UAAI,CAAC,WAAW,SAAS,QAAQ;AAC/B,kBAAU;AACV,gBAAQ;AACR,cAAM,MAAM,IAAI,MAAM,mDAAmD;AACzE,kBAAU,GAAG;AACb,eAAO,GAAG;AAAA,MACZ;AAAA,IACF,GAAG,GAAG;AAAA,EACR,CAAC;AACH;;;ACtEO,SAAS,sBAAsB,SAAwC;AAC5E,QAAM,EAAE,eAAe,KAAK,YAAY,KAAK,IAAI,WAAW,CAAC;AAE7D,QAAM,SAAS,IAAI,gBAAgB,OAAO,SAAS,MAAM;AACzD,QAAM,SAAS,OAAO,IAAI,QAAQ;AAClC,QAAM,WAAW,OAAO,IAAI,UAAU;AACtC,QAAM,YAAY,OAAO,IAAI,YAAY;AACzC,QAAM,QAAQ,OAAO,IAAI,OAAO;AAEhC,QAAM,UAA0B;AAAA,IAC9B,MAAM;AAAA,IACN,QAAQ,WAAW,YAAY,YAAY;AAAA,IAC3C,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,IAC/B,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,EAC3B;AAEA,MAAI,OAAO,QAAQ;AACjB,WAAO,OAAO,YAAY,SAAS,YAAY;AAAA,EACjD;AAEA,MAAI,WAAW;AACb,WAAO,MAAM;AAAA,EACf;AACF;","names":[]}
package/dist/index.cjs CHANGED
@@ -58,7 +58,7 @@ var TTLCache = class {
58
58
  var import_ai = require("ai");
59
59
 
60
60
  // src/core/http-executor.ts
61
- function createExecutor(metadata, baseUrl, apiKey) {
61
+ function createExecutor(metadata, baseUrl, apiKey, accountId) {
62
62
  return async (args) => {
63
63
  const { method, path, bodyDefaults } = metadata;
64
64
  const remainingArgs = { ...args };
@@ -97,7 +97,8 @@ function createExecutor(metadata, baseUrl, apiKey) {
97
97
  method,
98
98
  headers: {
99
99
  Authorization: `Bearer ${apiKey}`,
100
- "Content-Type": "application/json"
100
+ "Content-Type": "application/json",
101
+ ...accountId ? { "X-Account-Id": accountId } : {}
101
102
  }
102
103
  };
103
104
  if (method === "GET" || method === "DELETE") {
@@ -120,7 +121,7 @@ function createExecutor(metadata, baseUrl, apiKey) {
120
121
  }
121
122
 
122
123
  // src/core/tool-converter.ts
123
- function convertTools(tools, baseUrl, apiKey) {
124
+ function convertTools(tools, baseUrl, apiKey, accountId) {
124
125
  const result = {};
125
126
  for (const t of tools) {
126
127
  const { name, description, parameters } = t.function;
@@ -128,7 +129,7 @@ function convertTools(tools, baseUrl, apiKey) {
128
129
  result[name] = (0, import_ai.tool)({
129
130
  description,
130
131
  inputSchema: (0, import_ai.jsonSchema)(parameters),
131
- execute: async (args) => createExecutor(metadata, baseUrl, apiKey)(args)
132
+ execute: async (args) => createExecutor(metadata, baseUrl, apiKey, accountId)(args)
132
133
  });
133
134
  }
134
135
  return result;
@@ -252,7 +253,7 @@ function createLoadSkillTool(skills) {
252
253
  });
253
254
  }
254
255
  var VALID_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
255
- function createApiCallTool(baseUrl, apiKey) {
256
+ function createApiCallTool(baseUrl, apiKey, accountId) {
256
257
  return (0, import_ai2.tool)({
257
258
  description: "Make an authenticated HTTP request to the Supyagent API. Use loadSkill first to understand available endpoints. The authorization header and base URL are handled automatically \u2014 only provide the path (e.g., /api/v1/google/gmail/messages).",
258
259
  inputSchema: (0, import_ai2.jsonSchema)({
@@ -309,7 +310,8 @@ function createApiCallTool(baseUrl, apiKey) {
309
310
  method,
310
311
  headers: {
311
312
  Authorization: `Bearer ${apiKey}`,
312
- "Content-Type": "application/json"
313
+ "Content-Type": "application/json",
314
+ ...accountId ? { "X-Account-Id": accountId } : {}
313
315
  }
314
316
  };
315
317
  if (body && method !== "GET" && method !== "DELETE") {
@@ -334,32 +336,41 @@ function createApiCallTool(baseUrl, apiKey) {
334
336
  // src/core/client.ts
335
337
  var DEFAULT_BASE_URL = "https://app.supyagent.com";
336
338
  var CACHE_KEY = "tools";
337
- function supyagent(options) {
338
- const { apiKey, baseUrl = DEFAULT_BASE_URL } = options;
339
- const cache = new TTLCache();
339
+ function createFetcher(baseUrl, apiKey, accountId) {
340
+ return async function fetcher(path, init) {
341
+ const res = await fetch(`${baseUrl}${path}`, {
342
+ ...init,
343
+ headers: {
344
+ Authorization: `Bearer ${apiKey}`,
345
+ ...accountId ? { "X-Account-Id": accountId } : {},
346
+ ...init?.headers ?? {}
347
+ }
348
+ });
349
+ if (!res.ok) {
350
+ const text = await res.text();
351
+ throw new Error(`Supyagent API error (${res.status}): ${text}`);
352
+ }
353
+ return res;
354
+ };
355
+ }
356
+ function createDataPlane(fetcher, baseUrl, apiKey, accountId) {
357
+ const toolsCache = new TTLCache();
340
358
  const skillsCache = new TTLCache();
341
359
  const meCache = new TTLCache();
342
360
  return {
343
361
  async tools(filterOptions) {
344
362
  const cacheTTL = resolveCacheTTL(filterOptions?.cache);
345
- let response = cacheTTL > 0 ? cache.get(CACHE_KEY) : void 0;
363
+ let response = cacheTTL > 0 ? toolsCache.get(CACHE_KEY) : void 0;
346
364
  if (!response) {
347
- const res = await fetch(`${baseUrl}/api/v1/tools`, {
365
+ const res = await fetcher("/api/v1/tools", {
348
366
  headers: {
349
- Authorization: `Bearer ${apiKey}`,
350
367
  "Content-Type": "application/json"
351
368
  }
352
369
  });
353
- if (!res.ok) {
354
- const error = await res.text();
355
- throw new Error(
356
- `Supyagent API error (${res.status}): ${error}`
357
- );
358
- }
359
370
  const json = await res.json();
360
371
  response = json.data ?? json;
361
372
  if (cacheTTL > 0) {
362
- cache.set(CACHE_KEY, response, cacheTTL);
373
+ toolsCache.set(CACHE_KEY, response, cacheTTL);
363
374
  }
364
375
  }
365
376
  const toolBaseUrl = response.base_url || baseUrl;
@@ -368,23 +379,13 @@ function supyagent(options) {
368
379
  only: filterOptions?.only,
369
380
  except: filterOptions?.except
370
381
  });
371
- return convertTools(filtered, toolBaseUrl, apiKey);
382
+ return convertTools(filtered, toolBaseUrl, apiKey, accountId);
372
383
  },
373
- async skills(options2) {
374
- const cacheTTL = resolveCacheTTL(options2?.cache);
384
+ async skills(options) {
385
+ const cacheTTL = resolveCacheTTL(options?.cache);
375
386
  let parsed = cacheTTL > 0 ? skillsCache.get("skills") : void 0;
376
387
  if (!parsed) {
377
- const res = await fetch(`${baseUrl}/api/v1/skills`, {
378
- headers: {
379
- Authorization: `Bearer ${apiKey}`
380
- }
381
- });
382
- if (!res.ok) {
383
- const error = await res.text();
384
- throw new Error(
385
- `Supyagent API error (${res.status}): ${error}`
386
- );
387
- }
388
+ const res = await fetcher("/api/v1/skills");
388
389
  parsed = parseSkillsMarkdown(await res.text());
389
390
  if (cacheTTL > 0) {
390
391
  skillsCache.set("skills", parsed, cacheTTL);
@@ -394,25 +395,15 @@ function supyagent(options) {
394
395
  systemPrompt: buildSkillsSystemPrompt(parsed),
395
396
  tools: {
396
397
  loadSkill: createLoadSkillTool(parsed.skills),
397
- apiCall: createApiCallTool(baseUrl, apiKey)
398
+ apiCall: createApiCallTool(baseUrl, apiKey, accountId)
398
399
  }
399
400
  };
400
401
  },
401
- async me(options2) {
402
- const cacheTTL = resolveCacheTTL(options2?.cache);
402
+ async me(options) {
403
+ const cacheTTL = resolveCacheTTL(options?.cache);
403
404
  let response = cacheTTL > 0 ? meCache.get("me") : void 0;
404
405
  if (!response) {
405
- const res = await fetch(`${baseUrl}/api/v1/me`, {
406
- headers: {
407
- Authorization: `Bearer ${apiKey}`
408
- }
409
- });
410
- if (!res.ok) {
411
- const error = await res.text();
412
- throw new Error(
413
- `Supyagent API error (${res.status}): ${error}`
414
- );
415
- }
406
+ const res = await fetcher("/api/v1/me");
416
407
  const json = await res.json();
417
408
  response = json.data ?? json;
418
409
  if (cacheTTL > 0) {
@@ -420,6 +411,177 @@ function supyagent(options) {
420
411
  }
421
412
  }
422
413
  return response;
414
+ },
415
+ async searchTools(query) {
416
+ const res = await fetcher(`/api/v1/tools/search/${encodeURIComponent(query)}`);
417
+ const json = await res.json();
418
+ const data = json.data ?? json;
419
+ return {
420
+ tools: Array.isArray(data.tools) ? data.tools : [],
421
+ total: data.total ?? 0
422
+ };
423
+ },
424
+ async toolsByProvider(provider) {
425
+ const res = await fetcher(`/api/v1/tools/provider/${encodeURIComponent(provider)}`);
426
+ const json = await res.json();
427
+ const data = json.data ?? json;
428
+ return {
429
+ tools: Array.isArray(data.tools) ? data.tools : [],
430
+ total: data.total ?? 0
431
+ };
432
+ },
433
+ async toolsByService(service) {
434
+ const res = await fetcher(`/api/v1/tools/service/${encodeURIComponent(service)}`);
435
+ const json = await res.json();
436
+ const data = json.data ?? json;
437
+ return {
438
+ tools: Array.isArray(data.tools) ? data.tools : [],
439
+ total: data.total ?? 0
440
+ };
441
+ }
442
+ };
443
+ }
444
+ function supyagent(options) {
445
+ const { apiKey, baseUrl = DEFAULT_BASE_URL } = options;
446
+ const fetcher = createFetcher(baseUrl, apiKey);
447
+ const dataPlane = createDataPlane(fetcher, baseUrl, apiKey);
448
+ async function apiCall(method, path, body) {
449
+ const res = await fetcher(path, {
450
+ method,
451
+ ...body ? { headers: { "Content-Type": "application/json" }, body: JSON.stringify(body) } : {}
452
+ });
453
+ const json = await res.json();
454
+ return json.data ?? json;
455
+ }
456
+ return {
457
+ ...dataPlane,
458
+ accounts: createAccountsClient(apiCall),
459
+ asAccount(externalId) {
460
+ const scopedFetcher = createFetcher(baseUrl, apiKey, externalId);
461
+ const scopedDataPlane = createDataPlane(scopedFetcher, baseUrl, apiKey, externalId);
462
+ return {
463
+ accountId: externalId,
464
+ ...scopedDataPlane
465
+ };
466
+ }
467
+ };
468
+ }
469
+ function createAccountsClient(apiCall) {
470
+ function toAccount(raw) {
471
+ return {
472
+ id: raw.id,
473
+ externalId: raw.external_id,
474
+ displayName: raw.display_name ?? null,
475
+ metadata: raw.metadata ?? {},
476
+ createdAt: raw.created_at
477
+ };
478
+ }
479
+ function toIntegration(raw) {
480
+ return {
481
+ id: raw.id,
482
+ provider: raw.provider,
483
+ status: raw.status,
484
+ connectedAt: raw.connected_at
485
+ };
486
+ }
487
+ function toIntegrationDetail(raw) {
488
+ const services = raw.enabled_services ?? [];
489
+ return {
490
+ ...toIntegration(raw),
491
+ enabledServices: services.map((s) => ({
492
+ serviceName: s.service_name,
493
+ isEnabled: s.is_enabled
494
+ }))
495
+ };
496
+ }
497
+ return {
498
+ async create(opts) {
499
+ const raw = await apiCall("POST", "/api/v1/accounts", {
500
+ external_id: opts.externalId,
501
+ ...opts.displayName != null ? { display_name: opts.displayName } : {},
502
+ ...opts.metadata != null ? { metadata: opts.metadata } : {}
503
+ });
504
+ return toAccount(raw);
505
+ },
506
+ async list(opts) {
507
+ const params = new URLSearchParams();
508
+ if (opts?.limit != null) params.set("limit", String(opts.limit));
509
+ if (opts?.offset != null) params.set("offset", String(opts.offset));
510
+ const qs = params.toString();
511
+ const raw = await apiCall(
512
+ "GET",
513
+ `/api/v1/accounts${qs ? `?${qs}` : ""}`
514
+ );
515
+ return {
516
+ accounts: (raw.accounts ?? []).map(toAccount),
517
+ total: raw.total,
518
+ limit: raw.limit,
519
+ offset: raw.offset
520
+ };
521
+ },
522
+ async get(id) {
523
+ const raw = await apiCall("GET", `/api/v1/accounts/${id}`);
524
+ return {
525
+ ...toAccount(raw),
526
+ integrations: (raw.integrations ?? []).map(
527
+ toIntegration
528
+ )
529
+ };
530
+ },
531
+ async update(id, opts) {
532
+ const body = {};
533
+ if (opts.displayName !== void 0) body.display_name = opts.displayName;
534
+ if (opts.metadata !== void 0) body.metadata = opts.metadata;
535
+ const raw = await apiCall("PATCH", `/api/v1/accounts/${id}`, body);
536
+ return toAccount(raw);
537
+ },
538
+ async delete(id) {
539
+ return apiCall("DELETE", `/api/v1/accounts/${id}`);
540
+ },
541
+ async connect(id, opts) {
542
+ const raw = await apiCall(
543
+ "POST",
544
+ `/api/v1/accounts/${id}/connect`,
545
+ {
546
+ provider: opts.provider,
547
+ redirect_url: opts.redirectUrl,
548
+ ...opts.scopes ? { scopes: opts.scopes } : {}
549
+ }
550
+ );
551
+ return {
552
+ connectUrl: raw.connect_url,
553
+ sessionId: raw.session_id,
554
+ expiresAt: raw.expires_at
555
+ };
556
+ },
557
+ async getSession(id, sessionId) {
558
+ const raw = await apiCall(
559
+ "GET",
560
+ `/api/v1/accounts/${id}/connect/${sessionId}`
561
+ );
562
+ return {
563
+ sessionId: raw.session_id,
564
+ provider: raw.provider,
565
+ status: raw.status,
566
+ ...raw.error ? { error: raw.error } : {},
567
+ createdAt: raw.created_at,
568
+ expiresAt: raw.expires_at
569
+ };
570
+ },
571
+ async integrations(id) {
572
+ const raw = await apiCall(
573
+ "GET",
574
+ `/api/v1/accounts/${id}/integrations`
575
+ );
576
+ return (raw.integrations ?? []).map(
577
+ toIntegrationDetail
578
+ );
579
+ },
580
+ async disconnect(id, provider) {
581
+ return apiCall(
582
+ "DELETE",
583
+ `/api/v1/accounts/${id}/integrations/${provider}`
584
+ );
423
585
  }
424
586
  };
425
587
  }