@useago/sdk 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{createMockClient-BZKh_1em.cjs → AgoClient-BDO4avLq.cjs} +219 -124
- package/dist/AgoClient-BDO4avLq.cjs.map +1 -0
- package/dist/{createMockClient-uGlVyjbL.js → AgoClient-D-c91tx5.js} +221 -126
- package/dist/AgoClient-D-c91tx5.js.map +1 -0
- package/dist/angular/ago.service.d.ts +98 -0
- package/dist/angular/index.d.ts +4 -0
- package/dist/angular/provide.d.ts +27 -0
- package/dist/angular.cjs +105 -0
- package/dist/angular.cjs.map +1 -0
- package/dist/angular.d.ts +1 -0
- package/dist/angular.js +105 -0
- package/dist/angular.js.map +1 -0
- package/dist/auto/createAgo.d.ts +39 -0
- package/dist/auto/index.d.ts +1 -0
- package/dist/client/AgoClient.d.ts +56 -0
- package/dist/client/types.d.ts +4 -6
- package/dist/createMockClient-B1DcBiIK.js +94 -0
- package/dist/createMockClient-B1DcBiIK.js.map +1 -0
- package/dist/createMockClient-BqNSJUu4.cjs +93 -0
- package/dist/createMockClient-BqNSJUu4.cjs.map +1 -0
- package/dist/functions-B0Z0rNQW.cjs +306 -0
- package/dist/functions-B0Z0rNQW.cjs.map +1 -0
- package/dist/functions-C-wLEc8b.js +306 -0
- package/dist/functions-C-wLEc8b.js.map +1 -0
- package/dist/helpers/factory.d.ts +20 -0
- package/dist/helpers/functions.d.ts +62 -0
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers.cjs +17 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +17 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +179 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +173 -5
- package/dist/index.js.map +1 -1
- package/dist/react/context/AgoContext.d.ts +30 -4
- package/dist/react/context/index.d.ts +1 -1
- package/dist/react/hooks/index.d.ts +1 -0
- package/dist/react/hooks/useAgoContext.d.ts +40 -0
- package/dist/react/hooks/useAgoFunction.d.ts +14 -2
- package/dist/react/index.d.ts +2 -1
- package/dist/react.cjs +76 -11
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +81 -17
- package/dist/react.js.map +1 -1
- package/dist/state/ClientContextRegistry.d.ts +64 -0
- package/dist/streaming/helpers.d.ts +67 -0
- package/dist/vue/composables/useAgo.d.ts +17 -0
- package/dist/vue/composables/useAgoEvents.d.ts +11 -0
- package/dist/vue/composables/useAgoFunction.d.ts +34 -0
- package/dist/vue/composables/useChat.d.ts +251 -0
- package/dist/vue/composables/useConversation.d.ts +178 -0
- package/dist/vue/composables/useMessages.d.ts +89 -0
- package/dist/vue/index.d.ts +10 -0
- package/dist/vue/plugin.d.ts +16 -0
- package/dist/vue/symbols.d.ts +3 -0
- package/dist/vue.cjs +232 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.ts +1 -0
- package/dist/vue.js +232 -0
- package/dist/vue.js.map +1 -0
- package/dist/widget/types.d.ts +1 -0
- package/package.json +23 -3
- package/dist/createMockClient-BZKh_1em.cjs.map +0 -1
- package/dist/createMockClient-uGlVyjbL.js.map +0 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
function createMockClient(options = {}) {
|
|
3
|
+
const { overrides = {} } = options;
|
|
4
|
+
const noopMessage = {
|
|
5
|
+
id: "mock-msg-1",
|
|
6
|
+
conversationId: "mock-conv-1",
|
|
7
|
+
content: "Mock response",
|
|
8
|
+
role: "assistant",
|
|
9
|
+
status: "DONE",
|
|
10
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
11
|
+
};
|
|
12
|
+
const noopConversation = {
|
|
13
|
+
id: "mock-conv-1",
|
|
14
|
+
title: "Mock Conversation",
|
|
15
|
+
lastMessageDate: /* @__PURE__ */ new Date()
|
|
16
|
+
};
|
|
17
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
18
|
+
const calls = [];
|
|
19
|
+
const defaults = {
|
|
20
|
+
sendMessage: async () => noopMessage,
|
|
21
|
+
getConversations: async () => [noopConversation],
|
|
22
|
+
getConversation: async () => noopConversation,
|
|
23
|
+
getMessages: async () => [noopMessage],
|
|
24
|
+
submitToolCallForm: async () => void 0,
|
|
25
|
+
confirmToolCall: async () => void 0,
|
|
26
|
+
rejectToolCall: async () => void 0,
|
|
27
|
+
submitFeedback: async () => void 0,
|
|
28
|
+
registerFunction: () => void 0,
|
|
29
|
+
unregisterFunction: () => true,
|
|
30
|
+
getRegisteredFunctions: () => [],
|
|
31
|
+
registerNavigationFunction: () => void 0,
|
|
32
|
+
on: (event, handler) => {
|
|
33
|
+
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
34
|
+
listeners.get(event).add(handler);
|
|
35
|
+
},
|
|
36
|
+
off: (event, handler) => {
|
|
37
|
+
var _a;
|
|
38
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(handler);
|
|
39
|
+
},
|
|
40
|
+
once: (event, handler) => {
|
|
41
|
+
const wrapper = (...args) => {
|
|
42
|
+
var _a;
|
|
43
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(wrapper);
|
|
44
|
+
handler(...args);
|
|
45
|
+
};
|
|
46
|
+
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
47
|
+
listeners.get(event).add(wrapper);
|
|
48
|
+
},
|
|
49
|
+
waitFor: (event, options2) => {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
let timer;
|
|
52
|
+
const handler = (data) => {
|
|
53
|
+
var _a;
|
|
54
|
+
if (timer) clearTimeout(timer);
|
|
55
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(handler);
|
|
56
|
+
resolve(data);
|
|
57
|
+
};
|
|
58
|
+
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
59
|
+
listeners.get(event).add(handler);
|
|
60
|
+
if (options2 == null ? void 0 : options2.timeout) {
|
|
61
|
+
timer = setTimeout(() => {
|
|
62
|
+
var _a;
|
|
63
|
+
(_a = listeners.get(event)) == null ? void 0 : _a.delete(handler);
|
|
64
|
+
reject(new Error(`waitFor("${event}") timed out after ${options2.timeout}ms`));
|
|
65
|
+
}, options2.timeout);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
},
|
|
69
|
+
updateConfig: () => void 0,
|
|
70
|
+
destroy: () => {
|
|
71
|
+
listeners.clear();
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
const merged = { ...defaults, ...overrides };
|
|
75
|
+
const mock = {};
|
|
76
|
+
for (const [key, fn] of Object.entries(merged)) {
|
|
77
|
+
mock[key] = (...args) => {
|
|
78
|
+
calls.push({ method: key, args });
|
|
79
|
+
return fn(...args);
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
mock.__calls = calls;
|
|
83
|
+
mock.__callsFor = (method) => calls.filter((c) => c.method === method);
|
|
84
|
+
mock.__emitEvent = (event, data) => {
|
|
85
|
+
const handlers = listeners.get(event);
|
|
86
|
+
if (handlers) {
|
|
87
|
+
[...handlers].forEach((h) => h(data));
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
return mock;
|
|
91
|
+
}
|
|
92
|
+
exports.createMockClient = createMockClient;
|
|
93
|
+
//# sourceMappingURL=createMockClient-BqNSJUu4.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createMockClient-BqNSJUu4.cjs","sources":["../src/testing/createMockClient.ts"],"sourcesContent":["import type { AgoClient } from \"../client/AgoClient\";\nimport type {\n AgoClientEvents,\n AgoEventName,\n AgoMessage,\n Conversation,\n} from \"../client/types\";\nimport type { ClientFunctionSchema } from \"../functions/types\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype MockFn = (...args: any[]) => any;\n\nexport interface MockAgoClientOptions {\n overrides?: Partial<Record<string, MockFn>>;\n}\n\nexport interface MockAgoClient extends AgoClient {\n /**\n * Simulate a server-pushed event.\n * ```ts\n * mock.__emitEvent(\"message:complete\", { id: \"1\", content: \"hi\", ... });\n * ```\n */\n __emitEvent<K extends AgoEventName>(event: K, data: AgoClientEvents[K]): void;\n\n /**\n * All recorded method calls: `[methodName, ...args][]`\n */\n __calls: Array<{ method: string; args: unknown[] }>;\n\n /**\n * Get calls for a specific method.\n */\n __callsFor(method: string): Array<{ method: string; args: unknown[] }>;\n}\n\n/**\n * Create a mock AgoClient for testing. Works with any framework.\n *\n * ```ts\n * import { createMockClient } from \"@useago/sdk/testing\";\n *\n * const mock = createMockClient();\n * mock.__emitEvent(\"message:complete\", someMessage);\n * expect(mock.__callsFor(\"sendMessage\")).toHaveLength(1);\n * ```\n */\nexport function createMockClient(\n options: MockAgoClientOptions = {}\n): MockAgoClient {\n const { overrides = {} } = options;\n\n const noopMessage: AgoMessage = {\n id: \"mock-msg-1\",\n conversationId: \"mock-conv-1\",\n content: \"Mock response\",\n role: \"assistant\",\n status: \"DONE\",\n createdAt: new Date(),\n };\n\n const noopConversation: Conversation = {\n id: \"mock-conv-1\",\n title: \"Mock Conversation\",\n lastMessageDate: new Date(),\n };\n\n const listeners = new Map<string, Set<(...args: unknown[]) => void>>();\n const calls: Array<{ method: string; args: unknown[] }> = [];\n\n const defaults: Record<string, MockFn> = {\n sendMessage: async () => noopMessage,\n getConversations: async () => [noopConversation],\n getConversation: async () => noopConversation,\n getMessages: async () => [noopMessage],\n submitToolCallForm: async () => undefined,\n confirmToolCall: async () => undefined,\n rejectToolCall: async () => undefined,\n submitFeedback: async () => undefined,\n registerFunction: () => undefined,\n unregisterFunction: () => true,\n getRegisteredFunctions: () => [] as ClientFunctionSchema[],\n registerNavigationFunction: () => undefined,\n on: (event: string, handler: (...args: unknown[]) => void) => {\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n },\n off: (event: string, handler: (...args: unknown[]) => void) => {\n listeners.get(event)?.delete(handler);\n },\n once: (event: string, handler: (...args: unknown[]) => void) => {\n const wrapper = (...args: unknown[]) => {\n listeners.get(event)?.delete(wrapper);\n handler(...args);\n };\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(wrapper);\n },\n waitFor: (event: string, options?: { timeout?: number }) => {\n return new Promise((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const handler = (data: unknown) => {\n if (timer) clearTimeout(timer);\n listeners.get(event)?.delete(handler);\n resolve(data);\n };\n if (!listeners.has(event)) listeners.set(event, new Set());\n listeners.get(event)!.add(handler);\n if (options?.timeout) {\n timer = setTimeout(() => {\n listeners.get(event)?.delete(handler);\n reject(new Error(`waitFor(\"${event}\") timed out after ${options.timeout}ms`));\n }, options.timeout);\n }\n });\n },\n updateConfig: () => undefined,\n destroy: () => {\n listeners.clear();\n },\n };\n\n const merged = { ...defaults, ...overrides } as Record<string, MockFn>;\n\n // Wrap all methods to record calls\n const mock: Record<string, unknown> = {};\n\n for (const [key, fn] of Object.entries(merged)) {\n mock[key] = (...args: unknown[]) => {\n calls.push({ method: key, args });\n return (fn as MockFn)(...args);\n };\n }\n\n // Test helpers (not recorded)\n mock.__calls = calls;\n mock.__callsFor = (method: string) => calls.filter((c) => c.method === method);\n mock.__emitEvent = (event: string, data: unknown) => {\n // Copy the set to avoid mutation during iteration (once handlers remove themselves)\n const handlers = listeners.get(event);\n if (handlers) {\n [...handlers].forEach((h) => h(data));\n }\n };\n\n return mock as unknown as MockAgoClient;\n}\n"],"names":["options"],"mappings":"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"}
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const showToast = {
|
|
4
|
+
name: "showToast",
|
|
5
|
+
description: "Show a toast notification to the user. Use this to confirm actions or display brief messages.",
|
|
6
|
+
parameters: {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {
|
|
9
|
+
message: { type: "string", description: "The message to display" },
|
|
10
|
+
type: {
|
|
11
|
+
type: "string",
|
|
12
|
+
description: "Toast type",
|
|
13
|
+
enum: ["success", "error", "warning", "info"]
|
|
14
|
+
},
|
|
15
|
+
duration: {
|
|
16
|
+
type: "number",
|
|
17
|
+
description: "Duration in milliseconds (default 3000)"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
required: ["message"]
|
|
21
|
+
},
|
|
22
|
+
handler: async () => ({ shown: false, error: "No toast handler configured" })
|
|
23
|
+
};
|
|
24
|
+
const showNotification = {
|
|
25
|
+
name: "showNotification",
|
|
26
|
+
description: "Show a browser notification to the user. Useful for important alerts even when the tab is not focused.",
|
|
27
|
+
parameters: {
|
|
28
|
+
type: "object",
|
|
29
|
+
properties: {
|
|
30
|
+
title: { type: "string", description: "Notification title" },
|
|
31
|
+
body: { type: "string", description: "Notification body text" }
|
|
32
|
+
},
|
|
33
|
+
required: ["title"]
|
|
34
|
+
},
|
|
35
|
+
handler: async (args) => {
|
|
36
|
+
if (typeof Notification === "undefined") {
|
|
37
|
+
return { shown: false, error: "Notifications not supported" };
|
|
38
|
+
}
|
|
39
|
+
if (Notification.permission === "denied") {
|
|
40
|
+
return { shown: false, error: "Notification permission denied" };
|
|
41
|
+
}
|
|
42
|
+
if (Notification.permission !== "granted") {
|
|
43
|
+
await Notification.requestPermission();
|
|
44
|
+
}
|
|
45
|
+
if (Notification.permission === "granted") {
|
|
46
|
+
new Notification(args.title, { body: args.body });
|
|
47
|
+
return { shown: true };
|
|
48
|
+
}
|
|
49
|
+
return { shown: false, error: "Permission not granted" };
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
const openUrl = {
|
|
53
|
+
name: "openUrl",
|
|
54
|
+
description: "Open a URL in a new browser tab.",
|
|
55
|
+
parameters: {
|
|
56
|
+
type: "object",
|
|
57
|
+
properties: {
|
|
58
|
+
url: { type: "string", description: "The URL to open" }
|
|
59
|
+
},
|
|
60
|
+
required: ["url"]
|
|
61
|
+
},
|
|
62
|
+
handler: async (args) => {
|
|
63
|
+
window.open(args.url, "_blank", "noopener,noreferrer");
|
|
64
|
+
return { opened: true };
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const copyToClipboard = {
|
|
68
|
+
name: "copyToClipboard",
|
|
69
|
+
description: "Copy text to the user's clipboard.",
|
|
70
|
+
parameters: {
|
|
71
|
+
type: "object",
|
|
72
|
+
properties: {
|
|
73
|
+
text: { type: "string", description: "The text to copy" }
|
|
74
|
+
},
|
|
75
|
+
required: ["text"]
|
|
76
|
+
},
|
|
77
|
+
handler: async (args) => {
|
|
78
|
+
await navigator.clipboard.writeText(args.text);
|
|
79
|
+
return { copied: true };
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
const setTheme = {
|
|
83
|
+
name: "setTheme",
|
|
84
|
+
description: "Change the application's color theme. Sets a data-theme attribute on the document element.",
|
|
85
|
+
parameters: {
|
|
86
|
+
type: "object",
|
|
87
|
+
properties: {
|
|
88
|
+
theme: {
|
|
89
|
+
type: "string",
|
|
90
|
+
description: "Theme to apply",
|
|
91
|
+
enum: ["light", "dark", "system"]
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
required: ["theme"]
|
|
95
|
+
},
|
|
96
|
+
handler: async (args) => {
|
|
97
|
+
const theme = args.theme;
|
|
98
|
+
document.documentElement.setAttribute("data-theme", theme);
|
|
99
|
+
if (theme === "dark") {
|
|
100
|
+
document.documentElement.classList.add("dark");
|
|
101
|
+
} else {
|
|
102
|
+
document.documentElement.classList.remove("dark");
|
|
103
|
+
}
|
|
104
|
+
return { theme, applied: true };
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
const showConfirmDialog = {
|
|
108
|
+
name: "showConfirmDialog",
|
|
109
|
+
description: "Show a confirmation dialog to the user and return their choice (true/false).",
|
|
110
|
+
parameters: {
|
|
111
|
+
type: "object",
|
|
112
|
+
properties: {
|
|
113
|
+
message: {
|
|
114
|
+
type: "string",
|
|
115
|
+
description: "The confirmation message to display"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
required: ["message"]
|
|
119
|
+
},
|
|
120
|
+
handler: async (args) => {
|
|
121
|
+
const confirmed = window.confirm(args.message);
|
|
122
|
+
return { confirmed };
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
const getUserLocation = {
|
|
126
|
+
name: "getUserLocation",
|
|
127
|
+
description: "Get the user's current geographic location (requires permission).",
|
|
128
|
+
parameters: {
|
|
129
|
+
type: "object",
|
|
130
|
+
properties: {}
|
|
131
|
+
},
|
|
132
|
+
handler: async () => {
|
|
133
|
+
if (!navigator.geolocation) {
|
|
134
|
+
return { error: "Geolocation not supported" };
|
|
135
|
+
}
|
|
136
|
+
return new Promise((resolve) => {
|
|
137
|
+
navigator.geolocation.getCurrentPosition(
|
|
138
|
+
(pos) => resolve({
|
|
139
|
+
latitude: pos.coords.latitude,
|
|
140
|
+
longitude: pos.coords.longitude,
|
|
141
|
+
accuracy: pos.coords.accuracy
|
|
142
|
+
}),
|
|
143
|
+
(err) => resolve({ error: err.message })
|
|
144
|
+
);
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
const scrollToElement = {
|
|
149
|
+
name: "scrollToElement",
|
|
150
|
+
description: "Scroll the page to a specific element identified by CSS selector.",
|
|
151
|
+
parameters: {
|
|
152
|
+
type: "object",
|
|
153
|
+
properties: {
|
|
154
|
+
selector: {
|
|
155
|
+
type: "string",
|
|
156
|
+
description: "CSS selector of the element to scroll to (e.g. '#section-pricing')"
|
|
157
|
+
},
|
|
158
|
+
behavior: {
|
|
159
|
+
type: "string",
|
|
160
|
+
description: "Scroll behavior",
|
|
161
|
+
enum: ["smooth", "instant"]
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
required: ["selector"]
|
|
165
|
+
},
|
|
166
|
+
handler: async (args) => {
|
|
167
|
+
const el = document.querySelector(args.selector);
|
|
168
|
+
if (!el) {
|
|
169
|
+
return { scrolled: false, error: `Element not found: ${args.selector}` };
|
|
170
|
+
}
|
|
171
|
+
el.scrollIntoView({ behavior: args.behavior || "smooth" });
|
|
172
|
+
return { scrolled: true };
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
const setLocalStorage = {
|
|
176
|
+
name: "setLocalStorage",
|
|
177
|
+
description: "Store a value in the browser's localStorage.",
|
|
178
|
+
parameters: {
|
|
179
|
+
type: "object",
|
|
180
|
+
properties: {
|
|
181
|
+
key: { type: "string", description: "Storage key" },
|
|
182
|
+
value: { type: "string", description: "Value to store" }
|
|
183
|
+
},
|
|
184
|
+
required: ["key", "value"]
|
|
185
|
+
},
|
|
186
|
+
handler: async (args) => {
|
|
187
|
+
localStorage.setItem(args.key, args.value);
|
|
188
|
+
return { stored: true };
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
const getLocalStorage = {
|
|
192
|
+
name: "getLocalStorage",
|
|
193
|
+
description: "Retrieve a value from the browser's localStorage.",
|
|
194
|
+
parameters: {
|
|
195
|
+
type: "object",
|
|
196
|
+
properties: {
|
|
197
|
+
key: { type: "string", description: "Storage key" }
|
|
198
|
+
},
|
|
199
|
+
required: ["key"]
|
|
200
|
+
},
|
|
201
|
+
handler: async (args) => {
|
|
202
|
+
const value = localStorage.getItem(args.key);
|
|
203
|
+
return { key: args.key, value, found: value !== null };
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
const highlightElement = {
|
|
207
|
+
name: "highlightElement",
|
|
208
|
+
description: "Highlight a DOM element to draw the user's attention (e.g. for onboarding).",
|
|
209
|
+
parameters: {
|
|
210
|
+
type: "object",
|
|
211
|
+
properties: {
|
|
212
|
+
selector: {
|
|
213
|
+
type: "string",
|
|
214
|
+
description: "CSS selector of the element to highlight"
|
|
215
|
+
},
|
|
216
|
+
color: {
|
|
217
|
+
type: "string",
|
|
218
|
+
description: "Highlight border color (default: #3b82f6)"
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
required: ["selector"]
|
|
222
|
+
},
|
|
223
|
+
handler: async (args) => {
|
|
224
|
+
const el = document.querySelector(args.selector);
|
|
225
|
+
if (!el) {
|
|
226
|
+
return { highlighted: false, error: `Element not found: ${args.selector}` };
|
|
227
|
+
}
|
|
228
|
+
const prev = el.style.outline;
|
|
229
|
+
const color = args.color || "#3b82f6";
|
|
230
|
+
el.style.outline = `3px solid ${color}`;
|
|
231
|
+
el.style.outlineOffset = "2px";
|
|
232
|
+
el.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
233
|
+
setTimeout(() => {
|
|
234
|
+
el.style.outline = prev;
|
|
235
|
+
el.style.outlineOffset = "";
|
|
236
|
+
}, 3e3);
|
|
237
|
+
return { highlighted: true };
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
const submitForm = {
|
|
241
|
+
name: "submitForm",
|
|
242
|
+
description: "Fill and submit an HTML form on the page. Pass field values as key-value pairs.",
|
|
243
|
+
parameters: {
|
|
244
|
+
type: "object",
|
|
245
|
+
properties: {
|
|
246
|
+
selector: {
|
|
247
|
+
type: "string",
|
|
248
|
+
description: "CSS selector of the form element"
|
|
249
|
+
},
|
|
250
|
+
values: {
|
|
251
|
+
type: "string",
|
|
252
|
+
description: "JSON string of field name → value pairs"
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
required: ["selector"]
|
|
256
|
+
},
|
|
257
|
+
handler: async (args) => {
|
|
258
|
+
const form = document.querySelector(args.selector);
|
|
259
|
+
if (!form) {
|
|
260
|
+
return { submitted: false, error: `Form not found: ${args.selector}` };
|
|
261
|
+
}
|
|
262
|
+
if (args.values) {
|
|
263
|
+
const values = JSON.parse(args.values);
|
|
264
|
+
for (const [name, value] of Object.entries(values)) {
|
|
265
|
+
const input = form.elements.namedItem(name);
|
|
266
|
+
if (input) input.value = value;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
form.requestSubmit();
|
|
270
|
+
return { submitted: true };
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
const trackEvent = {
|
|
274
|
+
name: "trackEvent",
|
|
275
|
+
description: "Track a custom analytics event. Override the handler to wire up your analytics provider.",
|
|
276
|
+
parameters: {
|
|
277
|
+
type: "object",
|
|
278
|
+
properties: {
|
|
279
|
+
event: { type: "string", description: "Event name" },
|
|
280
|
+
properties: {
|
|
281
|
+
type: "string",
|
|
282
|
+
description: "JSON string of event properties"
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
required: ["event"]
|
|
286
|
+
},
|
|
287
|
+
handler: async (args) => {
|
|
288
|
+
const props = args.properties ? JSON.parse(args.properties) : {};
|
|
289
|
+
console.log(`[AGO Analytics] ${args.event}`, props);
|
|
290
|
+
return { tracked: true, event: args.event };
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
exports.copyToClipboard = copyToClipboard;
|
|
294
|
+
exports.getLocalStorage = getLocalStorage;
|
|
295
|
+
exports.getUserLocation = getUserLocation;
|
|
296
|
+
exports.highlightElement = highlightElement;
|
|
297
|
+
exports.openUrl = openUrl;
|
|
298
|
+
exports.scrollToElement = scrollToElement;
|
|
299
|
+
exports.setLocalStorage = setLocalStorage;
|
|
300
|
+
exports.setTheme = setTheme;
|
|
301
|
+
exports.showConfirmDialog = showConfirmDialog;
|
|
302
|
+
exports.showNotification = showNotification;
|
|
303
|
+
exports.showToast = showToast;
|
|
304
|
+
exports.submitForm = submitForm;
|
|
305
|
+
exports.trackEvent = trackEvent;
|
|
306
|
+
//# sourceMappingURL=functions-B0Z0rNQW.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"functions-B0Z0rNQW.cjs","sources":["../src/helpers/functions.ts"],"sourcesContent":["import type { ClientFunctionDefinition } from \"../functions/types\";\n\n/**\n * Show a toast/notification to the user.\n * The handler is a no-op by default — wire it up to your toast library.\n *\n * ```ts\n * import { showToast } from \"@useago/sdk/helpers\";\n * showToast.handler = async (args) => { myToast(args.message); return { shown: true }; };\n * client.registerFunction(showToast);\n * ```\n */\nexport const showToast: ClientFunctionDefinition = {\n name: \"showToast\",\n description:\n \"Show a toast notification to the user. Use this to confirm actions or display brief messages.\",\n parameters: {\n type: \"object\",\n properties: {\n message: { type: \"string\", description: \"The message to display\" },\n type: {\n type: \"string\",\n description: \"Toast type\",\n enum: [\"success\", \"error\", \"warning\", \"info\"],\n },\n duration: {\n type: \"number\",\n description: \"Duration in milliseconds (default 3000)\",\n },\n },\n required: [\"message\"],\n },\n handler: async () => ({ shown: false, error: \"No toast handler configured\" }),\n};\n\n/**\n * Show a browser notification (requires permission).\n */\nexport const showNotification: ClientFunctionDefinition = {\n name: \"showNotification\",\n description:\n \"Show a browser notification to the user. Useful for important alerts even when the tab is not focused.\",\n parameters: {\n type: \"object\",\n properties: {\n title: { type: \"string\", description: \"Notification title\" },\n body: { type: \"string\", description: \"Notification body text\" },\n },\n required: [\"title\"],\n },\n handler: async (args) => {\n if (typeof Notification === \"undefined\") {\n return { shown: false, error: \"Notifications not supported\" };\n }\n if (Notification.permission === \"denied\") {\n return { shown: false, error: \"Notification permission denied\" };\n }\n if (Notification.permission !== \"granted\") {\n await Notification.requestPermission();\n }\n if (Notification.permission === \"granted\") {\n new Notification(args.title as string, { body: args.body as string });\n return { shown: true };\n }\n return { shown: false, error: \"Permission not granted\" };\n },\n};\n\n/**\n * Open a URL in a new tab.\n */\nexport const openUrl: ClientFunctionDefinition = {\n name: \"openUrl\",\n description: \"Open a URL in a new browser tab.\",\n parameters: {\n type: \"object\",\n properties: {\n url: { type: \"string\", description: \"The URL to open\" },\n },\n required: [\"url\"],\n },\n handler: async (args) => {\n window.open(args.url as string, \"_blank\", \"noopener,noreferrer\");\n return { opened: true };\n },\n};\n\n/**\n * Copy text to clipboard.\n */\nexport const copyToClipboard: ClientFunctionDefinition = {\n name: \"copyToClipboard\",\n description: \"Copy text to the user's clipboard.\",\n parameters: {\n type: \"object\",\n properties: {\n text: { type: \"string\", description: \"The text to copy\" },\n },\n required: [\"text\"],\n },\n handler: async (args) => {\n await navigator.clipboard.writeText(args.text as string);\n return { copied: true };\n },\n};\n\n/**\n * Set the application theme (light/dark/system).\n * Default handler toggles a `data-theme` attribute on `<html>`.\n */\nexport const setTheme: ClientFunctionDefinition = {\n name: \"setTheme\",\n description:\n \"Change the application's color theme. Sets a data-theme attribute on the document element.\",\n parameters: {\n type: \"object\",\n properties: {\n theme: {\n type: \"string\",\n description: \"Theme to apply\",\n enum: [\"light\", \"dark\", \"system\"],\n },\n },\n required: [\"theme\"],\n },\n handler: async (args) => {\n const theme = args.theme as string;\n document.documentElement.setAttribute(\"data-theme\", theme);\n if (theme === \"dark\") {\n document.documentElement.classList.add(\"dark\");\n } else {\n document.documentElement.classList.remove(\"dark\");\n }\n return { theme, applied: true };\n },\n};\n\n/**\n * Show a confirm dialog and return the user's choice.\n */\nexport const showConfirmDialog: ClientFunctionDefinition = {\n name: \"showConfirmDialog\",\n description:\n \"Show a confirmation dialog to the user and return their choice (true/false).\",\n parameters: {\n type: \"object\",\n properties: {\n message: {\n type: \"string\",\n description: \"The confirmation message to display\",\n },\n },\n required: [\"message\"],\n },\n handler: async (args) => {\n const confirmed = window.confirm(args.message as string);\n return { confirmed };\n },\n};\n\n/**\n * Get the user's geolocation.\n */\nexport const getUserLocation: ClientFunctionDefinition = {\n name: \"getUserLocation\",\n description:\n \"Get the user's current geographic location (requires permission).\",\n parameters: {\n type: \"object\",\n properties: {},\n },\n handler: async () => {\n if (!navigator.geolocation) {\n return { error: \"Geolocation not supported\" };\n }\n return new Promise((resolve) => {\n navigator.geolocation.getCurrentPosition(\n (pos) =>\n resolve({\n latitude: pos.coords.latitude,\n longitude: pos.coords.longitude,\n accuracy: pos.coords.accuracy,\n }),\n (err) => resolve({ error: err.message })\n );\n });\n },\n};\n\n/**\n * Scroll to an element on the page.\n */\nexport const scrollToElement: ClientFunctionDefinition = {\n name: \"scrollToElement\",\n description: \"Scroll the page to a specific element identified by CSS selector.\",\n parameters: {\n type: \"object\",\n properties: {\n selector: {\n type: \"string\",\n description: \"CSS selector of the element to scroll to (e.g. '#section-pricing')\",\n },\n behavior: {\n type: \"string\",\n description: \"Scroll behavior\",\n enum: [\"smooth\", \"instant\"],\n },\n },\n required: [\"selector\"],\n },\n handler: async (args) => {\n const el = document.querySelector(args.selector as string);\n if (!el) {\n return { scrolled: false, error: `Element not found: ${args.selector}` };\n }\n el.scrollIntoView({ behavior: (args.behavior as ScrollBehavior) || \"smooth\" });\n return { scrolled: true };\n },\n};\n\n/**\n * Set a value in localStorage.\n */\nexport const setLocalStorage: ClientFunctionDefinition = {\n name: \"setLocalStorage\",\n description: \"Store a value in the browser's localStorage.\",\n parameters: {\n type: \"object\",\n properties: {\n key: { type: \"string\", description: \"Storage key\" },\n value: { type: \"string\", description: \"Value to store\" },\n },\n required: [\"key\", \"value\"],\n },\n handler: async (args) => {\n localStorage.setItem(args.key as string, args.value as string);\n return { stored: true };\n },\n};\n\n/**\n * Get a value from localStorage.\n */\nexport const getLocalStorage: ClientFunctionDefinition = {\n name: \"getLocalStorage\",\n description: \"Retrieve a value from the browser's localStorage.\",\n parameters: {\n type: \"object\",\n properties: {\n key: { type: \"string\", description: \"Storage key\" },\n },\n required: [\"key\"],\n },\n handler: async (args) => {\n const value = localStorage.getItem(args.key as string);\n return { key: args.key, value, found: value !== null };\n },\n};\n\n/**\n * Highlight an element on the page (useful for guided tours).\n */\nexport const highlightElement: ClientFunctionDefinition = {\n name: \"highlightElement\",\n description:\n \"Highlight a DOM element to draw the user's attention (e.g. for onboarding).\",\n parameters: {\n type: \"object\",\n properties: {\n selector: {\n type: \"string\",\n description: \"CSS selector of the element to highlight\",\n },\n color: {\n type: \"string\",\n description: \"Highlight border color (default: #3b82f6)\",\n },\n },\n required: [\"selector\"],\n },\n handler: async (args) => {\n const el = document.querySelector(args.selector as string) as HTMLElement | null;\n if (!el) {\n return { highlighted: false, error: `Element not found: ${args.selector}` };\n }\n const prev = el.style.outline;\n const color = (args.color as string) || \"#3b82f6\";\n el.style.outline = `3px solid ${color}`;\n el.style.outlineOffset = \"2px\";\n el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n setTimeout(() => {\n el.style.outline = prev;\n el.style.outlineOffset = \"\";\n }, 3000);\n return { highlighted: true };\n },\n};\n\n/**\n * Submit a form on the page programmatically.\n */\nexport const submitForm: ClientFunctionDefinition = {\n name: \"submitForm\",\n description:\n \"Fill and submit an HTML form on the page. Pass field values as key-value pairs.\",\n parameters: {\n type: \"object\",\n properties: {\n selector: {\n type: \"string\",\n description: \"CSS selector of the form element\",\n },\n values: {\n type: \"string\",\n description: \"JSON string of field name → value pairs\",\n },\n },\n required: [\"selector\"],\n },\n handler: async (args) => {\n const form = document.querySelector(args.selector as string) as HTMLFormElement | null;\n if (!form) {\n return { submitted: false, error: `Form not found: ${args.selector}` };\n }\n if (args.values) {\n const values = JSON.parse(args.values as string) as Record<string, string>;\n for (const [name, value] of Object.entries(values)) {\n const input = form.elements.namedItem(name) as HTMLInputElement | null;\n if (input) input.value = value;\n }\n }\n form.requestSubmit();\n return { submitted: true };\n },\n};\n\n/**\n * Track a custom analytics event.\n * Default handler logs to console — replace with your analytics provider.\n */\nexport const trackEvent: ClientFunctionDefinition = {\n name: \"trackEvent\",\n description:\n \"Track a custom analytics event. Override the handler to wire up your analytics provider.\",\n parameters: {\n type: \"object\",\n properties: {\n event: { type: \"string\", description: \"Event name\" },\n properties: {\n type: \"string\",\n description: \"JSON string of event properties\",\n },\n },\n required: [\"event\"],\n },\n handler: async (args) => {\n const props = args.properties ? JSON.parse(args.properties as string) : {};\n console.log(`[AGO Analytics] ${args.event}`, props);\n return { tracked: true, event: args.event };\n },\n};\n"],"names":[],"mappings":"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"}
|