@squadbase/vite-server 0.1.3-dev.0 → 0.1.3-dev.2

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 (39) hide show
  1. package/dist/cli/index.js +82143 -9661
  2. package/dist/connectors/asana.d.ts +5 -0
  3. package/dist/connectors/asana.js +661 -0
  4. package/dist/connectors/customerio.d.ts +5 -0
  5. package/dist/connectors/customerio.js +633 -0
  6. package/dist/connectors/gemini.js +1 -1
  7. package/dist/connectors/gmail-oauth.d.ts +5 -0
  8. package/dist/connectors/gmail-oauth.js +639 -0
  9. package/dist/connectors/google-ads.d.ts +5 -0
  10. package/dist/connectors/google-ads.js +784 -0
  11. package/dist/connectors/google-sheets.d.ts +5 -0
  12. package/dist/connectors/google-sheets.js +598 -0
  13. package/dist/connectors/hubspot.js +14 -5
  14. package/dist/connectors/intercom-oauth.d.ts +5 -0
  15. package/dist/connectors/intercom-oauth.js +510 -0
  16. package/dist/connectors/intercom.d.ts +5 -0
  17. package/dist/connectors/intercom.js +627 -0
  18. package/dist/connectors/jira-api-key.d.ts +5 -0
  19. package/dist/connectors/jira-api-key.js +524 -0
  20. package/dist/connectors/linkedin-ads-oauth.d.ts +5 -0
  21. package/dist/connectors/linkedin-ads-oauth.js +774 -0
  22. package/dist/connectors/linkedin-ads.d.ts +5 -0
  23. package/dist/connectors/linkedin-ads.js +782 -0
  24. package/dist/connectors/mailchimp-oauth.d.ts +5 -0
  25. package/dist/connectors/mailchimp-oauth.js +539 -0
  26. package/dist/connectors/mailchimp.d.ts +5 -0
  27. package/dist/connectors/mailchimp.js +646 -0
  28. package/dist/connectors/notion-oauth.d.ts +5 -0
  29. package/dist/connectors/notion-oauth.js +493 -0
  30. package/dist/connectors/notion.d.ts +5 -0
  31. package/dist/connectors/notion.js +580 -0
  32. package/dist/connectors/zendesk-oauth.d.ts +5 -0
  33. package/dist/connectors/zendesk-oauth.js +505 -0
  34. package/dist/connectors/zendesk.d.ts +5 -0
  35. package/dist/connectors/zendesk.js +631 -0
  36. package/dist/index.js +82350 -7194
  37. package/dist/main.js +82336 -7180
  38. package/dist/vite-plugin.js +82235 -7079
  39. package/package.json +66 -2
@@ -0,0 +1,633 @@
1
+ // ../connectors/src/parameter-definition.ts
2
+ var ParameterDefinition = class {
3
+ slug;
4
+ name;
5
+ description;
6
+ envVarBaseKey;
7
+ type;
8
+ secret;
9
+ required;
10
+ constructor(config) {
11
+ this.slug = config.slug;
12
+ this.name = config.name;
13
+ this.description = config.description;
14
+ this.envVarBaseKey = config.envVarBaseKey;
15
+ this.type = config.type;
16
+ this.secret = config.secret;
17
+ this.required = config.required;
18
+ }
19
+ /**
20
+ * Get the parameter value from a ConnectorConnectionObject.
21
+ */
22
+ getValue(connection2) {
23
+ const param = connection2.parameters.find(
24
+ (p) => p.parameterSlug === this.slug
25
+ );
26
+ if (!param || param.value == null) {
27
+ throw new Error(
28
+ `Parameter "${this.slug}" not found or has no value in connection "${connection2.id}"`
29
+ );
30
+ }
31
+ return param.value;
32
+ }
33
+ /**
34
+ * Try to get the parameter value. Returns undefined if not found (for optional params).
35
+ */
36
+ tryGetValue(connection2) {
37
+ const param = connection2.parameters.find(
38
+ (p) => p.parameterSlug === this.slug
39
+ );
40
+ if (!param || param.value == null) return void 0;
41
+ return param.value;
42
+ }
43
+ };
44
+
45
+ // ../connectors/src/connectors/customerio/parameters.ts
46
+ var parameters = {
47
+ appApiKey: new ParameterDefinition({
48
+ slug: "app-api-key",
49
+ name: "App API Key",
50
+ description: "Your Customer.io App API Key. Used for Bearer authentication. Found under Settings > API Credentials. Note: shown only once when created.",
51
+ envVarBaseKey: "CUSTOMERIO_API_KEY",
52
+ type: "text",
53
+ secret: true,
54
+ required: true
55
+ }),
56
+ region: new ParameterDefinition({
57
+ slug: "region",
58
+ name: "Region",
59
+ description: 'Set to "eu" for EU region. Leave empty for US/Global region (default).',
60
+ envVarBaseKey: "CUSTOMERIO_REGION",
61
+ type: "text",
62
+ secret: false,
63
+ required: false
64
+ })
65
+ };
66
+
67
+ // ../connectors/src/connectors/customerio/sdk/index.ts
68
+ function getBaseUrl(region) {
69
+ return region === "eu" ? "https://api-eu.customer.io" : "https://api.customer.io";
70
+ }
71
+ function createClient(params) {
72
+ const appApiKey = params[parameters.appApiKey.slug];
73
+ const region = params[parameters.region.slug];
74
+ if (!appApiKey) {
75
+ throw new Error(
76
+ `customerio: missing required parameter: ${parameters.appApiKey.slug}`
77
+ );
78
+ }
79
+ const baseUrl = getBaseUrl(region);
80
+ function authHeaders(extra) {
81
+ const headers = new Headers(extra);
82
+ headers.set("Authorization", `Bearer ${appApiKey}`);
83
+ headers.set("Content-Type", "application/json");
84
+ return headers;
85
+ }
86
+ async function assertOk(res, label) {
87
+ if (!res.ok) {
88
+ const body = await res.text().catch(() => "(unreadable body)");
89
+ throw new Error(
90
+ `customerio ${label}: ${res.status} ${res.statusText} \u2014 ${body}`
91
+ );
92
+ }
93
+ }
94
+ return {
95
+ request(path2, init) {
96
+ const url = `${baseUrl}${path2.startsWith("/") ? "" : "/"}${path2}`;
97
+ const headers = new Headers(init?.headers);
98
+ headers.set("Authorization", `Bearer ${appApiKey}`);
99
+ headers.set("Content-Type", "application/json");
100
+ return fetch(url, { ...init, headers });
101
+ },
102
+ async getCustomers(options) {
103
+ const sp = new URLSearchParams();
104
+ if (options?.start) sp.set("start", options.start);
105
+ if (options?.limit) sp.set("limit", String(options.limit));
106
+ const qs = sp.toString() ? `?${sp.toString()}` : "";
107
+ const res = await fetch(`${baseUrl}/v1/customers${qs}`, {
108
+ method: "GET",
109
+ headers: authHeaders()
110
+ });
111
+ await assertOk(res, "getCustomers");
112
+ return await res.json();
113
+ },
114
+ async getCustomer(identifier) {
115
+ const res = await fetch(
116
+ `${baseUrl}/v1/customers/${encodeURIComponent(identifier)}/attributes`,
117
+ { method: "GET", headers: authHeaders() }
118
+ );
119
+ await assertOk(res, "getCustomer");
120
+ return await res.json();
121
+ },
122
+ async getSegments() {
123
+ const res = await fetch(`${baseUrl}/v1/segments`, {
124
+ method: "GET",
125
+ headers: authHeaders()
126
+ });
127
+ await assertOk(res, "getSegments");
128
+ return await res.json();
129
+ },
130
+ async getSegmentMembership(segmentId) {
131
+ const res = await fetch(
132
+ `${baseUrl}/v1/segments/${segmentId}/membership`,
133
+ { method: "GET", headers: authHeaders() }
134
+ );
135
+ await assertOk(res, "getSegmentMembership");
136
+ return await res.json();
137
+ },
138
+ async getCampaigns() {
139
+ const res = await fetch(`${baseUrl}/v1/campaigns`, {
140
+ method: "GET",
141
+ headers: authHeaders()
142
+ });
143
+ await assertOk(res, "getCampaigns");
144
+ return await res.json();
145
+ },
146
+ async getCampaign(campaignId) {
147
+ const res = await fetch(`${baseUrl}/v1/campaigns/${campaignId}`, {
148
+ method: "GET",
149
+ headers: authHeaders()
150
+ });
151
+ await assertOk(res, "getCampaign");
152
+ return await res.json();
153
+ },
154
+ async sendEmail(emailParams) {
155
+ const res = await fetch(`${baseUrl}/v1/send/email`, {
156
+ method: "POST",
157
+ headers: authHeaders(),
158
+ body: JSON.stringify(emailParams)
159
+ });
160
+ await assertOk(res, "sendEmail");
161
+ return await res.json();
162
+ },
163
+ async triggerBroadcast(broadcastId, broadcastParams) {
164
+ const res = await fetch(
165
+ `${baseUrl}/v1/campaigns/${broadcastId}/triggers`,
166
+ {
167
+ method: "POST",
168
+ headers: authHeaders(),
169
+ body: JSON.stringify(broadcastParams ?? {})
170
+ }
171
+ );
172
+ await assertOk(res, "triggerBroadcast");
173
+ return await res.json();
174
+ }
175
+ };
176
+ }
177
+
178
+ // ../connectors/src/connector-onboarding.ts
179
+ var ConnectorOnboarding = class {
180
+ /** Phase 1: Connection setup instructions (optional — some connectors don't need this) */
181
+ connectionSetupInstructions;
182
+ /** Phase 2: Data overview instructions */
183
+ dataOverviewInstructions;
184
+ constructor(config) {
185
+ this.connectionSetupInstructions = config.connectionSetupInstructions;
186
+ this.dataOverviewInstructions = config.dataOverviewInstructions;
187
+ }
188
+ getConnectionSetupPrompt(language) {
189
+ return this.connectionSetupInstructions?.[language] ?? null;
190
+ }
191
+ getDataOverviewInstructions(language) {
192
+ return this.dataOverviewInstructions[language];
193
+ }
194
+ };
195
+
196
+ // ../connectors/src/connector-tool.ts
197
+ var ConnectorTool = class {
198
+ name;
199
+ description;
200
+ inputSchema;
201
+ outputSchema;
202
+ _execute;
203
+ constructor(config) {
204
+ this.name = config.name;
205
+ this.description = config.description;
206
+ this.inputSchema = config.inputSchema;
207
+ this.outputSchema = config.outputSchema;
208
+ this._execute = config.execute;
209
+ }
210
+ createTool(connections, config) {
211
+ return {
212
+ description: this.description,
213
+ inputSchema: this.inputSchema,
214
+ outputSchema: this.outputSchema,
215
+ execute: (input) => this._execute(input, connections, config)
216
+ };
217
+ }
218
+ };
219
+
220
+ // ../connectors/src/connector-plugin.ts
221
+ var ConnectorPlugin = class _ConnectorPlugin {
222
+ slug;
223
+ authType;
224
+ name;
225
+ description;
226
+ iconUrl;
227
+ parameters;
228
+ releaseFlag;
229
+ proxyPolicy;
230
+ experimentalAttributes;
231
+ onboarding;
232
+ systemPrompt;
233
+ tools;
234
+ query;
235
+ checkConnection;
236
+ constructor(config) {
237
+ this.slug = config.slug;
238
+ this.authType = config.authType;
239
+ this.name = config.name;
240
+ this.description = config.description;
241
+ this.iconUrl = config.iconUrl;
242
+ this.parameters = config.parameters;
243
+ this.releaseFlag = config.releaseFlag;
244
+ this.proxyPolicy = config.proxyPolicy;
245
+ this.experimentalAttributes = config.experimentalAttributes;
246
+ this.onboarding = config.onboarding;
247
+ this.systemPrompt = config.systemPrompt;
248
+ this.tools = config.tools;
249
+ this.query = config.query;
250
+ this.checkConnection = config.checkConnection;
251
+ }
252
+ get connectorKey() {
253
+ return _ConnectorPlugin.deriveKey(this.slug, this.authType);
254
+ }
255
+ /**
256
+ * Create tools for connections that belong to this connector.
257
+ * Filters connections by connectorKey internally.
258
+ * Returns tools keyed as `${connectorKey}_${toolName}`.
259
+ */
260
+ createTools(connections, config) {
261
+ const myConnections = connections.filter(
262
+ (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
263
+ );
264
+ const result = {};
265
+ for (const t of Object.values(this.tools)) {
266
+ result[`${this.connectorKey}_${t.name}`] = t.createTool(
267
+ myConnections,
268
+ config
269
+ );
270
+ }
271
+ return result;
272
+ }
273
+ static deriveKey(slug, authType) {
274
+ return authType ? `${slug}-${authType}` : slug;
275
+ }
276
+ };
277
+
278
+ // ../connectors/src/connectors/customerio/setup.ts
279
+ var customerioOnboarding = new ConnectorOnboarding({
280
+ dataOverviewInstructions: {
281
+ en: `1. Call customerio_request with GET /v1/segments to list all segments
282
+ 2. Call customerio_request with GET /v1/campaigns to list all campaigns
283
+ 3. Pick a segment and call GET /v1/segments/{segment_id}/membership to view member IDs
284
+ 4. Pick a customer ID and call GET /v1/customers/{id}/attributes to view customer attributes`,
285
+ ja: `1. customerio_request \u3067 GET /v1/segments \u3092\u547C\u3073\u51FA\u3057\u3001\u5168\u30BB\u30B0\u30E1\u30F3\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
286
+ 2. customerio_request \u3067 GET /v1/campaigns \u3092\u547C\u3073\u51FA\u3057\u3001\u5168\u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u4E00\u89A7\u3092\u53D6\u5F97
287
+ 3. \u30BB\u30B0\u30E1\u30F3\u30C8\u3092\u9078\u629E\u3057 GET /v1/segments/{segment_id}/membership \u3067\u30E1\u30F3\u30D0\u30FCID\u3092\u78BA\u8A8D
288
+ 4. \u9867\u5BA2ID\u3092\u9078\u629E\u3057 GET /v1/customers/{id}/attributes \u3067\u9867\u5BA2\u5C5E\u6027\u3092\u78BA\u8A8D`
289
+ }
290
+ });
291
+
292
+ // ../connectors/src/connectors/customerio/tools/request.ts
293
+ import { z } from "zod";
294
+ var REQUEST_TIMEOUT_MS = 6e4;
295
+ function getBaseUrl2(region) {
296
+ return region === "eu" ? "https://api-eu.customer.io" : "https://api.customer.io";
297
+ }
298
+ var inputSchema = z.object({
299
+ toolUseIntent: z.string().optional().describe(
300
+ "Brief description of what you intend to accomplish with this tool call"
301
+ ),
302
+ connectionId: z.string().describe("ID of the Customer.io connection to use"),
303
+ method: z.enum(["GET", "POST", "PUT", "PATCH", "DELETE"]).describe("HTTP method"),
304
+ path: z.string().describe(
305
+ "API path (e.g., '/v1/customers', '/v1/segments', '/v1/campaigns', '/v1/send/email')"
306
+ ),
307
+ queryParams: z.record(z.string(), z.string()).optional().describe("Query parameters to append to the URL"),
308
+ body: z.record(z.string(), z.unknown()).optional().describe("Request body (JSON) for POST/PUT/PATCH requests")
309
+ });
310
+ var outputSchema = z.discriminatedUnion("success", [
311
+ z.object({
312
+ success: z.literal(true),
313
+ status: z.number(),
314
+ data: z.record(z.string(), z.unknown())
315
+ }),
316
+ z.object({
317
+ success: z.literal(false),
318
+ error: z.string()
319
+ })
320
+ ]);
321
+ var requestTool = new ConnectorTool({
322
+ name: "request",
323
+ description: `Send authenticated requests to the Customer.io App API.
324
+ Authentication is handled automatically using the App API Key (Bearer token).
325
+ Use this tool for reading customer data, managing campaigns, segments, broadcasts, sending transactional messages, and retrieving delivery information.
326
+ The App API is the read and management path for Customer.io data.`,
327
+ inputSchema,
328
+ outputSchema,
329
+ async execute({ connectionId, method, path: path2, queryParams, body }, connections) {
330
+ const connection2 = connections.find((c) => c.id === connectionId);
331
+ if (!connection2) {
332
+ return {
333
+ success: false,
334
+ error: `Connection ${connectionId} not found`
335
+ };
336
+ }
337
+ console.log(
338
+ `[connector-request] customerio/${connection2.name}: ${method} ${path2}`
339
+ );
340
+ try {
341
+ const appApiKey = parameters.appApiKey.getValue(connection2);
342
+ const region = parameters.region.tryGetValue(connection2);
343
+ const baseUrl = getBaseUrl2(region);
344
+ let url = `${baseUrl}${path2.startsWith("/") ? "" : "/"}${path2}`;
345
+ if (queryParams) {
346
+ const searchParams = new URLSearchParams(queryParams);
347
+ url += `?${searchParams.toString()}`;
348
+ }
349
+ const controller = new AbortController();
350
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
351
+ try {
352
+ const response = await fetch(url, {
353
+ method,
354
+ headers: {
355
+ Authorization: `Bearer ${appApiKey}`,
356
+ "Content-Type": "application/json"
357
+ },
358
+ body: body ? JSON.stringify(body) : void 0,
359
+ signal: controller.signal
360
+ });
361
+ let data = {};
362
+ const text = await response.text();
363
+ if (text) {
364
+ try {
365
+ data = JSON.parse(text);
366
+ } catch {
367
+ data = { raw: text };
368
+ }
369
+ }
370
+ if (!response.ok) {
371
+ const meta = typeof data?.meta === "object" && data.meta !== null ? data.meta : null;
372
+ const errorMessage = typeof meta?.error === "string" ? meta.error : typeof data?.errors === "object" ? JSON.stringify(data.errors) : typeof data?.error === "string" ? data.error : `HTTP ${response.status} ${response.statusText}`;
373
+ return { success: false, error: errorMessage };
374
+ }
375
+ return { success: true, status: response.status, data };
376
+ } finally {
377
+ clearTimeout(timeout);
378
+ }
379
+ } catch (err) {
380
+ const msg = err instanceof Error ? err.message : String(err);
381
+ return { success: false, error: msg };
382
+ }
383
+ }
384
+ });
385
+
386
+ // ../connectors/src/connectors/customerio/index.ts
387
+ var tools = { request: requestTool };
388
+ var customerioConnector = new ConnectorPlugin({
389
+ slug: "customerio",
390
+ authType: null,
391
+ name: "Customer.io",
392
+ description: "Connect to Customer.io App API for reading customer data, managing campaigns, segments, and sending transactional messages.",
393
+ iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/nngohabT7oHDIgQYAVBpz/6f6c7662ef4692eb9869e3e69dd57114/customerio.png",
394
+ parameters,
395
+ releaseFlag: { dev1: true, dev2: false, prod: false },
396
+ onboarding: customerioOnboarding,
397
+ systemPrompt: {
398
+ en: `### Tools
399
+
400
+ - \`customerio_request\`: The only way to call the Customer.io App API. Use it to read customer data, manage campaigns and segments, send transactional messages, and trigger broadcasts. Authentication (Bearer token with App API Key) is configured automatically.
401
+
402
+ ### Business Logic
403
+
404
+ The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
405
+
406
+ SDK methods (client created via \`connection(connectionId)\`):
407
+ - \`client.request(path, init?)\` \u2014 low-level authenticated fetch
408
+ - \`client.getCustomers(options?)\` \u2014 list customers
409
+ - \`client.getCustomer(identifier)\` \u2014 get customer attributes
410
+ - \`client.getSegments()\` \u2014 list all segments
411
+ - \`client.getSegmentMembership(segmentId)\` \u2014 get segment member IDs
412
+ - \`client.getCampaigns()\` \u2014 list all campaigns
413
+ - \`client.getCampaign(campaignId)\` \u2014 get campaign details
414
+ - \`client.sendEmail(params)\` \u2014 send a transactional email
415
+ - \`client.triggerBroadcast(broadcastId, params?)\` \u2014 trigger a broadcast
416
+
417
+ \`\`\`ts
418
+ import type { Context } from "hono";
419
+ import { connection } from "@squadbase/vite-server/connectors/customerio";
420
+
421
+ const cio = connection("<connectionId>");
422
+
423
+ export default async function handler(c: Context) {
424
+ const { segments } = await cio.getSegments();
425
+ const { campaigns } = await cio.getCampaigns();
426
+
427
+ return c.json({ segments, campaigns });
428
+ }
429
+ \`\`\`
430
+
431
+ ### Customer.io App API Reference
432
+
433
+ - Base URL: \`https://api.customer.io\` (US/Global) or \`https://api-eu.customer.io\` (EU)
434
+ - Authentication: Bearer token (\`Authorization: Bearer {app_api_key}\`)
435
+ - The App API is the read and management path \u2014 use it to retrieve data and trigger messages
436
+
437
+ #### Customers
438
+ - GET \`/v1/customers/{identifier}/attributes\` \u2014 Get customer attributes
439
+ - GET \`/v1/customers/{identifier}/segments\` \u2014 Get customer's segments
440
+ - GET \`/v1/customers/{identifier}/messages\` \u2014 Get customer's messages
441
+ - GET \`/v1/customers/{identifier}/activities\` \u2014 Get customer's activities
442
+
443
+ #### Segments
444
+ - GET \`/v1/segments\` \u2014 List all segments
445
+ - GET \`/v1/segments/{segment_id}\` \u2014 Get segment details
446
+ - GET \`/v1/segments/{segment_id}/membership\` \u2014 Get segment member IDs
447
+
448
+ #### Campaigns
449
+ - GET \`/v1/campaigns\` \u2014 List all campaigns
450
+ - GET \`/v1/campaigns/{campaign_id}\` \u2014 Get campaign details
451
+ - GET \`/v1/campaigns/{campaign_id}/actions\` \u2014 Get campaign actions
452
+ - GET \`/v1/campaigns/{campaign_id}/metrics\` \u2014 Get campaign metrics
453
+
454
+ #### Newsletters
455
+ - GET \`/v1/newsletters\` \u2014 List all newsletters
456
+ - GET \`/v1/newsletters/{newsletter_id}\` \u2014 Get newsletter details
457
+ - GET \`/v1/newsletters/{newsletter_id}/metrics\` \u2014 Get newsletter metrics
458
+
459
+ #### Broadcasts
460
+ - GET \`/v1/campaigns/{broadcast_id}/triggers\` \u2014 List broadcast triggers
461
+ - POST \`/v1/campaigns/{broadcast_id}/triggers\` \u2014 Trigger a broadcast
462
+
463
+ #### Transactional Messages
464
+ - POST \`/v1/send/email\` \u2014 Send a transactional email
465
+ - POST \`/v1/send/push\` \u2014 Send a transactional push notification
466
+
467
+ #### Message Info
468
+ - GET \`/v1/messages/{message_id}\` \u2014 Get message details
469
+ - GET \`/v1/messages/{message_id}/deliveries\` \u2014 Get delivery attempts
470
+
471
+ #### Exports
472
+ - POST \`/v1/exports/customers\` \u2014 Export customer data
473
+ - POST \`/v1/exports/deliveries\` \u2014 Export delivery data
474
+ - GET \`/v1/exports/{export_id}\` \u2014 Get export status
475
+ - GET \`/v1/exports/{export_id}/download\` \u2014 Download export
476
+
477
+ ### Tips
478
+ - App API keys are shown only once when created \u2014 store them securely
479
+ - Segment membership returns an array of customer IDs
480
+ - Use the exports endpoints for bulk data retrieval
481
+ - Pagination uses cursor-based \`start\` parameter for customer listing`,
482
+ ja: `### \u30C4\u30FC\u30EB
483
+
484
+ - \`customerio_request\`: Customer.io App API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u9867\u5BA2\u30C7\u30FC\u30BF\u306E\u8AAD\u307F\u53D6\u308A\u3001\u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u3084\u30BB\u30B0\u30E1\u30F3\u30C8\u306E\u7BA1\u7406\u3001\u30C8\u30E9\u30F3\u30B6\u30AF\u30B7\u30E7\u30F3\u30E1\u30C3\u30BB\u30FC\u30B8\u306E\u9001\u4FE1\u3001\u30D6\u30ED\u30FC\u30C9\u30AD\u30E3\u30B9\u30C8\u306E\u30C8\u30EA\u30AC\u30FC\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08App API\u30AD\u30FC\u306B\u3088\u308BBearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
485
+
486
+ ### Business Logic
487
+
488
+ \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u30B3\u30CD\u30AF\u30BFSDK\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u8A8D\u8A3C\u60C5\u5831\u3092\u8AAD\u307F\u53D6\u3089\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
489
+
490
+ SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
491
+ - \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch
492
+ - \`client.getCustomers(options?)\` \u2014 \u9867\u5BA2\u4E00\u89A7
493
+ - \`client.getCustomer(identifier)\` \u2014 \u9867\u5BA2\u5C5E\u6027\u306E\u53D6\u5F97
494
+ - \`client.getSegments()\` \u2014 \u5168\u30BB\u30B0\u30E1\u30F3\u30C8\u306E\u4E00\u89A7
495
+ - \`client.getSegmentMembership(segmentId)\` \u2014 \u30BB\u30B0\u30E1\u30F3\u30C8\u30E1\u30F3\u30D0\u30FCID\u306E\u53D6\u5F97
496
+ - \`client.getCampaigns()\` \u2014 \u5168\u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u306E\u4E00\u89A7
497
+ - \`client.getCampaign(campaignId)\` \u2014 \u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u8A73\u7D30\u306E\u53D6\u5F97
498
+ - \`client.sendEmail(params)\` \u2014 \u30C8\u30E9\u30F3\u30B6\u30AF\u30B7\u30E7\u30F3\u30E1\u30FC\u30EB\u306E\u9001\u4FE1
499
+ - \`client.triggerBroadcast(broadcastId, params?)\` \u2014 \u30D6\u30ED\u30FC\u30C9\u30AD\u30E3\u30B9\u30C8\u306E\u30C8\u30EA\u30AC\u30FC
500
+
501
+ \`\`\`ts
502
+ import type { Context } from "hono";
503
+ import { connection } from "@squadbase/vite-server/connectors/customerio";
504
+
505
+ const cio = connection("<connectionId>");
506
+
507
+ export default async function handler(c: Context) {
508
+ const { segments } = await cio.getSegments();
509
+ const { campaigns } = await cio.getCampaigns();
510
+
511
+ return c.json({ segments, campaigns });
512
+ }
513
+ \`\`\`
514
+
515
+ ### Customer.io App API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
516
+
517
+ - \u30D9\u30FC\u30B9URL: \`https://api.customer.io\`\uFF08US/Global\uFF09\u307E\u305F\u306F \`https://api-eu.customer.io\`\uFF08EU\uFF09
518
+ - \u8A8D\u8A3C: Bearer\u30C8\u30FC\u30AF\u30F3 (\`Authorization: Bearer {app_api_key}\`)
519
+ - App API\u306F\u8AAD\u307F\u53D6\u308A\u3068\u7BA1\u7406\u30D1\u30B9\u3067\u3059 \u2014 \u30C7\u30FC\u30BF\u306E\u53D6\u5F97\u3068\u30E1\u30C3\u30BB\u30FC\u30B8\u306E\u30C8\u30EA\u30AC\u30FC\u306B\u4F7F\u7528\u3057\u307E\u3059
520
+
521
+ #### \u9867\u5BA2
522
+ - GET \`/v1/customers/{identifier}/attributes\` \u2014 \u9867\u5BA2\u5C5E\u6027\u306E\u53D6\u5F97
523
+ - GET \`/v1/customers/{identifier}/segments\` \u2014 \u9867\u5BA2\u306E\u30BB\u30B0\u30E1\u30F3\u30C8\u53D6\u5F97
524
+ - GET \`/v1/customers/{identifier}/messages\` \u2014 \u9867\u5BA2\u306E\u30E1\u30C3\u30BB\u30FC\u30B8\u53D6\u5F97
525
+ - GET \`/v1/customers/{identifier}/activities\` \u2014 \u9867\u5BA2\u306E\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3\u53D6\u5F97
526
+
527
+ #### \u30BB\u30B0\u30E1\u30F3\u30C8
528
+ - GET \`/v1/segments\` \u2014 \u5168\u30BB\u30B0\u30E1\u30F3\u30C8\u306E\u4E00\u89A7
529
+ - GET \`/v1/segments/{segment_id}\` \u2014 \u30BB\u30B0\u30E1\u30F3\u30C8\u306E\u8A73\u7D30
530
+ - GET \`/v1/segments/{segment_id}/membership\` \u2014 \u30BB\u30B0\u30E1\u30F3\u30C8\u30E1\u30F3\u30D0\u30FCID\u306E\u53D6\u5F97
531
+
532
+ #### \u30AD\u30E3\u30F3\u30DA\u30FC\u30F3
533
+ - GET \`/v1/campaigns\` \u2014 \u5168\u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u306E\u4E00\u89A7
534
+ - GET \`/v1/campaigns/{campaign_id}\` \u2014 \u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u306E\u8A73\u7D30
535
+ - GET \`/v1/campaigns/{campaign_id}/actions\` \u2014 \u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u30A2\u30AF\u30B7\u30E7\u30F3\u306E\u53D6\u5F97
536
+ - GET \`/v1/campaigns/{campaign_id}/metrics\` \u2014 \u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u30E1\u30C8\u30EA\u30AF\u30B9\u306E\u53D6\u5F97
537
+
538
+ #### \u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC
539
+ - GET \`/v1/newsletters\` \u2014 \u5168\u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u306E\u4E00\u89A7
540
+ - GET \`/v1/newsletters/{newsletter_id}\` \u2014 \u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u306E\u8A73\u7D30
541
+ - GET \`/v1/newsletters/{newsletter_id}/metrics\` \u2014 \u30CB\u30E5\u30FC\u30B9\u30EC\u30BF\u30FC\u30E1\u30C8\u30EA\u30AF\u30B9\u306E\u53D6\u5F97
542
+
543
+ #### \u30D6\u30ED\u30FC\u30C9\u30AD\u30E3\u30B9\u30C8
544
+ - GET \`/v1/campaigns/{broadcast_id}/triggers\` \u2014 \u30D6\u30ED\u30FC\u30C9\u30AD\u30E3\u30B9\u30C8\u30C8\u30EA\u30AC\u30FC\u4E00\u89A7
545
+ - POST \`/v1/campaigns/{broadcast_id}/triggers\` \u2014 \u30D6\u30ED\u30FC\u30C9\u30AD\u30E3\u30B9\u30C8\u306E\u30C8\u30EA\u30AC\u30FC
546
+
547
+ #### \u30C8\u30E9\u30F3\u30B6\u30AF\u30B7\u30E7\u30F3\u30E1\u30C3\u30BB\u30FC\u30B8
548
+ - POST \`/v1/send/email\` \u2014 \u30C8\u30E9\u30F3\u30B6\u30AF\u30B7\u30E7\u30F3\u30E1\u30FC\u30EB\u306E\u9001\u4FE1
549
+ - POST \`/v1/send/push\` \u2014 \u30C8\u30E9\u30F3\u30B6\u30AF\u30B7\u30E7\u30F3\u30D7\u30C3\u30B7\u30E5\u901A\u77E5\u306E\u9001\u4FE1
550
+
551
+ #### \u30E1\u30C3\u30BB\u30FC\u30B8\u60C5\u5831
552
+ - GET \`/v1/messages/{message_id}\` \u2014 \u30E1\u30C3\u30BB\u30FC\u30B8\u306E\u8A73\u7D30
553
+ - GET \`/v1/messages/{message_id}/deliveries\` \u2014 \u914D\u4FE1\u8A66\u884C\u306E\u53D6\u5F97
554
+
555
+ #### \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
556
+ - POST \`/v1/exports/customers\` \u2014 \u9867\u5BA2\u30C7\u30FC\u30BF\u306E\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
557
+ - POST \`/v1/exports/deliveries\` \u2014 \u914D\u4FE1\u30C7\u30FC\u30BF\u306E\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
558
+ - GET \`/v1/exports/{export_id}\` \u2014 \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u72B6\u614B\u306E\u53D6\u5F97
559
+ - GET \`/v1/exports/{export_id}/download\` \u2014 \u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u306E\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9
560
+
561
+ ### \u30D2\u30F3\u30C8
562
+ - App API\u30AD\u30FC\u306F\u4F5C\u6210\u6642\u306B\u4E00\u5EA6\u3060\u3051\u8868\u793A\u3055\u308C\u308B \u2014 \u5B89\u5168\u306B\u4FDD\u7BA1\u3059\u308B\u3053\u3068
563
+ - \u30BB\u30B0\u30E1\u30F3\u30C8\u30E1\u30F3\u30D0\u30FC\u30B7\u30C3\u30D7\u306F\u9867\u5BA2ID\u306E\u914D\u5217\u3092\u8FD4\u5374
564
+ - \u5927\u91CF\u30C7\u30FC\u30BF\u53D6\u5F97\u306B\u306Fexports\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528
565
+ - \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u306F\u9867\u5BA2\u4E00\u89A7\u3067\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\`start\`\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4F7F\u7528`
566
+ },
567
+ tools
568
+ });
569
+
570
+ // src/connectors/create-connector-sdk.ts
571
+ import { readFileSync } from "fs";
572
+ import path from "path";
573
+
574
+ // src/connector-client/env.ts
575
+ function resolveEnvVar(entry, key, connectionId) {
576
+ const envVarName = entry.envVars[key];
577
+ if (!envVarName) {
578
+ throw new Error(`Connection "${connectionId}" is missing envVars mapping for key "${key}"`);
579
+ }
580
+ const value = process.env[envVarName];
581
+ if (!value) {
582
+ throw new Error(`Environment variable "${envVarName}" (for connection "${connectionId}", key "${key}") is not set`);
583
+ }
584
+ return value;
585
+ }
586
+ function resolveEnvVarOptional(entry, key) {
587
+ const envVarName = entry.envVars[key];
588
+ if (!envVarName) return void 0;
589
+ return process.env[envVarName] || void 0;
590
+ }
591
+
592
+ // src/connectors/create-connector-sdk.ts
593
+ function loadConnectionsSync() {
594
+ const filePath = process.env.CONNECTIONS_PATH ?? path.join(process.cwd(), ".squadbase/connections.json");
595
+ try {
596
+ const raw = readFileSync(filePath, "utf-8");
597
+ return JSON.parse(raw);
598
+ } catch {
599
+ return {};
600
+ }
601
+ }
602
+ function createConnectorSdk(plugin, createClient2) {
603
+ return (connectionId) => {
604
+ const connections = loadConnectionsSync();
605
+ const entry = connections[connectionId];
606
+ if (!entry) {
607
+ throw new Error(
608
+ `Connection "${connectionId}" not found in .squadbase/connections.json`
609
+ );
610
+ }
611
+ if (entry.connector.slug !== plugin.slug) {
612
+ throw new Error(
613
+ `Connection "${connectionId}" is not a ${plugin.slug} connection (got "${entry.connector.slug}")`
614
+ );
615
+ }
616
+ const params = {};
617
+ for (const param of Object.values(plugin.parameters)) {
618
+ if (param.required) {
619
+ params[param.slug] = resolveEnvVar(entry, param.slug, connectionId);
620
+ } else {
621
+ const val = resolveEnvVarOptional(entry, param.slug);
622
+ if (val !== void 0) params[param.slug] = val;
623
+ }
624
+ }
625
+ return createClient2(params);
626
+ };
627
+ }
628
+
629
+ // src/connectors/entries/customerio.ts
630
+ var connection = createConnectorSdk(customerioConnector, createClient);
631
+ export {
632
+ connection
633
+ };
@@ -131,7 +131,7 @@ var geminiConnector = new ConnectorPlugin({
131
131
  authType: null,
132
132
  name: "Gemini",
133
133
  description: "Connect to Google Gemini for AI model inference, embeddings, and multimodal generation.",
134
- iconUrl: "https://www.gstatic.com/lamda/images/gemini_sparkle_v002_d4735304ff6292a690b6.svg",
134
+ iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/6K2qZQZEQq90YENfrXy5my/c83c0c3815af0a97d29ee70f37215f01/gemini.png",
135
135
  parameters,
136
136
  releaseFlag: { dev1: true, dev2: true, prod: true },
137
137
  systemPrompt: {
@@ -0,0 +1,5 @@
1
+ import * as _squadbase_connectors_sdk from '@squadbase/connectors/sdk';
2
+
3
+ declare const connection: (connectionId: string) => _squadbase_connectors_sdk.GmailConnectorSdk;
4
+
5
+ export { connection };