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

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 (70) hide show
  1. package/dist/cli/index.js +82859 -9645
  2. package/dist/connectors/airtable-oauth.js +77 -3
  3. package/dist/connectors/airtable.js +85 -2
  4. package/dist/connectors/amplitude.js +85 -2
  5. package/dist/connectors/anthropic.js +85 -2
  6. package/dist/connectors/{slack.d.ts → asana.d.ts} +1 -1
  7. package/dist/connectors/asana.js +744 -0
  8. package/dist/connectors/attio.js +85 -2
  9. package/dist/connectors/{microsoft-teams-oauth.d.ts → customerio.d.ts} +1 -1
  10. package/dist/connectors/customerio.js +716 -0
  11. package/dist/connectors/dbt.js +85 -2
  12. package/dist/connectors/gemini.js +86 -3
  13. package/dist/connectors/{microsoft-teams.d.ts → gmail-oauth.d.ts} +1 -1
  14. package/dist/connectors/gmail-oauth.js +713 -0
  15. package/dist/connectors/gmail.d.ts +5 -0
  16. package/dist/connectors/gmail.js +875 -0
  17. package/dist/connectors/google-ads-oauth.js +78 -4
  18. package/dist/connectors/google-ads.d.ts +5 -0
  19. package/dist/connectors/google-ads.js +867 -0
  20. package/dist/connectors/google-analytics-oauth.js +90 -8
  21. package/dist/connectors/google-analytics.js +85 -2
  22. package/dist/connectors/google-calendar-oauth.d.ts +5 -0
  23. package/dist/connectors/google-calendar-oauth.js +817 -0
  24. package/dist/connectors/google-calendar.d.ts +5 -0
  25. package/dist/connectors/google-calendar.js +991 -0
  26. package/dist/connectors/google-sheets-oauth.js +144 -33
  27. package/dist/connectors/google-sheets.d.ts +5 -0
  28. package/dist/connectors/google-sheets.js +707 -0
  29. package/dist/connectors/grafana.d.ts +5 -0
  30. package/dist/connectors/grafana.js +638 -0
  31. package/dist/connectors/hubspot-oauth.js +77 -3
  32. package/dist/connectors/hubspot.js +89 -6
  33. package/dist/connectors/intercom-oauth.d.ts +5 -0
  34. package/dist/connectors/intercom-oauth.js +584 -0
  35. package/dist/connectors/intercom.d.ts +5 -0
  36. package/dist/connectors/intercom.js +710 -0
  37. package/dist/connectors/jira-api-key.d.ts +5 -0
  38. package/dist/connectors/jira-api-key.js +598 -0
  39. package/dist/connectors/kintone-api-token.js +77 -3
  40. package/dist/connectors/kintone.js +86 -3
  41. package/dist/connectors/linkedin-ads-oauth.d.ts +5 -0
  42. package/dist/connectors/linkedin-ads-oauth.js +848 -0
  43. package/dist/connectors/linkedin-ads.d.ts +5 -0
  44. package/dist/connectors/linkedin-ads.js +865 -0
  45. package/dist/connectors/mailchimp-oauth.d.ts +5 -0
  46. package/dist/connectors/mailchimp-oauth.js +613 -0
  47. package/dist/connectors/mailchimp.d.ts +5 -0
  48. package/dist/connectors/mailchimp.js +729 -0
  49. package/dist/connectors/notion-oauth.d.ts +5 -0
  50. package/dist/connectors/notion-oauth.js +567 -0
  51. package/dist/connectors/notion.d.ts +5 -0
  52. package/dist/connectors/notion.js +663 -0
  53. package/dist/connectors/openai.js +85 -2
  54. package/dist/connectors/shopify-oauth.js +77 -3
  55. package/dist/connectors/shopify.js +85 -2
  56. package/dist/connectors/stripe-api-key.d.ts +5 -0
  57. package/dist/connectors/stripe-api-key.js +600 -0
  58. package/dist/connectors/stripe-oauth.js +77 -3
  59. package/dist/connectors/wix-store.js +85 -2
  60. package/dist/connectors/zendesk-oauth.d.ts +5 -0
  61. package/dist/connectors/zendesk-oauth.js +579 -0
  62. package/dist/connectors/zendesk.d.ts +5 -0
  63. package/dist/connectors/zendesk.js +714 -0
  64. package/dist/index.js +83024 -7099
  65. package/dist/main.js +82988 -7063
  66. package/dist/vite-plugin.js +82862 -6974
  67. package/package.json +86 -2
  68. package/dist/connectors/microsoft-teams-oauth.js +0 -479
  69. package/dist/connectors/microsoft-teams.js +0 -381
  70. package/dist/connectors/slack.js +0 -362
@@ -0,0 +1,5 @@
1
+ import * as _squadbase_connectors_sdk from '@squadbase/connectors/sdk';
2
+
3
+ declare const connection: (connectionId: string) => _squadbase_connectors_sdk.JiraConnectorSdk;
4
+
5
+ export { connection };
@@ -0,0 +1,598 @@
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/jira/parameters.ts
46
+ var parameters = {
47
+ instanceUrl: new ParameterDefinition({
48
+ slug: "instance-url",
49
+ name: "Jira Instance URL",
50
+ description: "Your Jira Cloud site URL \u2014 just the base address, without any trailing path. For example: https://your-domain.atlassian.net",
51
+ envVarBaseKey: "JIRA_INSTANCE_URL",
52
+ type: "text",
53
+ secret: false,
54
+ required: true
55
+ }),
56
+ email: new ParameterDefinition({
57
+ slug: "email",
58
+ name: "Email Address",
59
+ description: "The email address associated with your Atlassian account used for API authentication.",
60
+ envVarBaseKey: "JIRA_EMAIL",
61
+ type: "text",
62
+ secret: false,
63
+ required: true
64
+ }),
65
+ apiToken: new ParameterDefinition({
66
+ slug: "api-token",
67
+ name: "Atlassian API Token",
68
+ description: "Your Atlassian account API token (used for Jira authentication). You can create one at: Atlassian Account Settings > Security > API tokens (https://id.atlassian.com/manage/api-tokens).",
69
+ envVarBaseKey: "JIRA_API_TOKEN",
70
+ type: "text",
71
+ secret: true,
72
+ required: true
73
+ })
74
+ };
75
+
76
+ // ../connectors/src/connectors/jira/sdk/index.ts
77
+ function createClient(params) {
78
+ const instanceUrl = params[parameters.instanceUrl.slug];
79
+ const email = params[parameters.email.slug];
80
+ const apiToken = params[parameters.apiToken.slug];
81
+ if (!instanceUrl || !email || !apiToken) {
82
+ const required = [
83
+ parameters.instanceUrl.slug,
84
+ parameters.email.slug,
85
+ parameters.apiToken.slug
86
+ ];
87
+ const missing = required.filter((s) => !params[s]);
88
+ throw new Error(
89
+ `jira: missing required parameters: ${missing.join(", ")}`
90
+ );
91
+ }
92
+ const credentials = Buffer.from(`${email}:${apiToken}`).toString("base64");
93
+ return {
94
+ request(path2, init) {
95
+ const url = `${instanceUrl.replace(/\/+$/, "")}${path2}`;
96
+ const headers = new Headers(init?.headers);
97
+ headers.set("Authorization", `Basic ${credentials}`);
98
+ headers.set("Accept", "application/json");
99
+ if (init?.body) {
100
+ headers.set("Content-Type", "application/json");
101
+ }
102
+ return fetch(url, { ...init, headers });
103
+ }
104
+ };
105
+ }
106
+
107
+ // ../connectors/src/connector-onboarding.ts
108
+ var ConnectorOnboarding = class {
109
+ /** Phase 1: Connection setup instructions (optional — some connectors don't need this) */
110
+ connectionSetupInstructions;
111
+ /** Phase 2: Data overview instructions */
112
+ dataOverviewInstructions;
113
+ constructor(config) {
114
+ this.connectionSetupInstructions = config.connectionSetupInstructions;
115
+ this.dataOverviewInstructions = config.dataOverviewInstructions;
116
+ }
117
+ getConnectionSetupPrompt(language) {
118
+ return this.connectionSetupInstructions?.[language] ?? null;
119
+ }
120
+ getDataOverviewInstructions(language) {
121
+ return this.dataOverviewInstructions[language];
122
+ }
123
+ };
124
+
125
+ // ../connectors/src/connector-tool.ts
126
+ var ConnectorTool = class {
127
+ name;
128
+ description;
129
+ inputSchema;
130
+ outputSchema;
131
+ _execute;
132
+ constructor(config) {
133
+ this.name = config.name;
134
+ this.description = config.description;
135
+ this.inputSchema = config.inputSchema;
136
+ this.outputSchema = config.outputSchema;
137
+ this._execute = config.execute;
138
+ }
139
+ createTool(connections, config) {
140
+ return {
141
+ description: this.description,
142
+ inputSchema: this.inputSchema,
143
+ outputSchema: this.outputSchema,
144
+ execute: (input) => this._execute(input, connections, config)
145
+ };
146
+ }
147
+ };
148
+
149
+ // ../connectors/src/connector-plugin.ts
150
+ var ConnectorPlugin = class _ConnectorPlugin {
151
+ slug;
152
+ authType;
153
+ name;
154
+ description;
155
+ iconUrl;
156
+ parameters;
157
+ releaseFlag;
158
+ proxyPolicy;
159
+ experimentalAttributes;
160
+ onboarding;
161
+ systemPrompt;
162
+ tools;
163
+ query;
164
+ checkConnection;
165
+ constructor(config) {
166
+ this.slug = config.slug;
167
+ this.authType = config.authType;
168
+ this.name = config.name;
169
+ this.description = config.description;
170
+ this.iconUrl = config.iconUrl;
171
+ this.parameters = config.parameters;
172
+ this.releaseFlag = config.releaseFlag;
173
+ this.proxyPolicy = config.proxyPolicy;
174
+ this.experimentalAttributes = config.experimentalAttributes;
175
+ this.onboarding = config.onboarding;
176
+ this.systemPrompt = config.systemPrompt;
177
+ this.tools = config.tools;
178
+ this.query = config.query;
179
+ this.checkConnection = config.checkConnection;
180
+ }
181
+ get connectorKey() {
182
+ return _ConnectorPlugin.deriveKey(this.slug, this.authType);
183
+ }
184
+ /**
185
+ * Create tools for connections that belong to this connector.
186
+ * Filters connections by connectorKey internally.
187
+ * Returns tools keyed as `${connectorKey}_${toolName}`.
188
+ */
189
+ createTools(connections, config) {
190
+ const myConnections = connections.filter(
191
+ (c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
192
+ );
193
+ const result = {};
194
+ for (const t of Object.values(this.tools)) {
195
+ result[`${this.connectorKey}_${t.name}`] = t.createTool(
196
+ myConnections,
197
+ config
198
+ );
199
+ }
200
+ return result;
201
+ }
202
+ static deriveKey(slug, authType) {
203
+ return authType ? `${slug}-${authType}` : slug;
204
+ }
205
+ };
206
+
207
+ // ../connectors/src/auth-types.ts
208
+ var AUTH_TYPES = {
209
+ OAUTH: "oauth",
210
+ API_KEY: "api-key",
211
+ JWT: "jwt",
212
+ SERVICE_ACCOUNT: "service-account",
213
+ PAT: "pat",
214
+ USER_PASSWORD: "user-password"
215
+ };
216
+
217
+ // ../connectors/src/connectors/jira/setup.ts
218
+ var jiraOnboarding = new ConnectorOnboarding({
219
+ dataOverviewInstructions: {
220
+ en: `1. Call jira-api-key_request with GET project to list all accessible projects
221
+ 2. For key projects, call jira-api-key_request with POST search to search issues using JQL (e.g., body: { "jql": "project = PROJ order by created DESC", "maxResults": 5, "fields": ["summary", "status", "assignee", "priority", "created"] })
222
+ 3. Call jira-api-key_request with GET issue/{issueKey} to inspect a sample issue's full details`,
223
+ ja: `1. jira-api-key_request \u3067 GET project \u3092\u547C\u3073\u51FA\u3057\u3001\u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306A\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
224
+ 2. \u4E3B\u8981\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306B\u3064\u3044\u3066 jira-api-key_request \u3067 POST search \u3092\u4F7F\u7528\u3057\u3066JQL\u3067\u30A4\u30B7\u30E5\u30FC\u3092\u691C\u7D22\uFF08\u4F8B: body: { "jql": "project = PROJ order by created DESC", "maxResults": 5, "fields": ["summary", "status", "assignee", "priority", "created"] }\uFF09
225
+ 3. jira-api-key_request \u3067 GET issue/{issueKey} \u3092\u547C\u3073\u51FA\u3057\u3001\u30B5\u30F3\u30D7\u30EB\u30A4\u30B7\u30E5\u30FC\u306E\u8A73\u7D30\u3092\u78BA\u8A8D`
226
+ }
227
+ });
228
+
229
+ // ../connectors/src/connectors/jira/tools/request.ts
230
+ import { z } from "zod";
231
+ var REQUEST_TIMEOUT_MS = 6e4;
232
+ var inputSchema = z.object({
233
+ toolUseIntent: z.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
234
+ connectionId: z.string().describe("ID of the Jira connection to use"),
235
+ method: z.enum(["GET", "POST", "PUT", "DELETE"]).describe("HTTP method. Use GET to read resources, POST to create or search, PUT to update, DELETE to remove."),
236
+ path: z.string().describe("API path relative to /rest/api/3/ (e.g., 'project', 'search', 'issue/PROJ-123'). Query parameters can be appended (e.g., 'project?maxResults=50')."),
237
+ body: z.record(z.string(), z.unknown()).optional().describe("Request body as JSON object. Required for POST and PUT requests (e.g., issue creation, JQL search).")
238
+ });
239
+ var outputSchema = z.discriminatedUnion("success", [
240
+ z.object({
241
+ success: z.literal(true),
242
+ status: z.number(),
243
+ data: z.union([z.record(z.string(), z.unknown()), z.array(z.unknown())])
244
+ }),
245
+ z.object({
246
+ success: z.literal(false),
247
+ error: z.string()
248
+ })
249
+ ]);
250
+ var requestTool = new ConnectorTool({
251
+ name: "request",
252
+ description: `Send authenticated requests to the Jira Cloud REST API (v3).
253
+ Authentication is handled automatically using Basic Auth (email + API token).
254
+ Use this tool for all Jira operations: listing projects, searching issues with JQL, creating/updating issues, managing transitions, and adding comments.
255
+ The base URL and authentication credentials are configured per connection \u2014 only specify the API path relative to /rest/api/3/.`,
256
+ inputSchema,
257
+ outputSchema,
258
+ async execute({ connectionId, method, path: path2, body }, connections) {
259
+ const connection2 = connections.find((c) => c.id === connectionId);
260
+ if (!connection2) {
261
+ return { success: false, error: `Connection ${connectionId} not found` };
262
+ }
263
+ console.log(`[connector-request] jira-api-key/${connection2.name}: ${method} ${path2}`);
264
+ try {
265
+ const instanceUrl = parameters.instanceUrl.getValue(connection2);
266
+ const email = parameters.email.getValue(connection2);
267
+ const apiToken = parameters.apiToken.getValue(connection2);
268
+ const baseUrl = `${instanceUrl.replace(/\/+$/, "")}/rest/api/3/${path2}`;
269
+ const credentials = Buffer.from(`${email}:${apiToken}`).toString("base64");
270
+ const controller = new AbortController();
271
+ const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
272
+ try {
273
+ const headers = {
274
+ Authorization: `Basic ${credentials}`,
275
+ Accept: "application/json"
276
+ };
277
+ if (body) {
278
+ headers["Content-Type"] = "application/json";
279
+ }
280
+ const response = await fetch(baseUrl, {
281
+ method,
282
+ headers,
283
+ body: body ? JSON.stringify(body) : void 0,
284
+ signal: controller.signal
285
+ });
286
+ if (response.status === 204) {
287
+ return { success: true, status: 204, data: {} };
288
+ }
289
+ const data = await response.json();
290
+ if (!response.ok) {
291
+ const errData = data;
292
+ const errorMessages = Array.isArray(errData?.errorMessages) ? errData.errorMessages.join("; ") : errData?.message ?? `HTTP ${response.status} ${response.statusText}`;
293
+ return { success: false, error: errorMessages };
294
+ }
295
+ return { success: true, status: response.status, data };
296
+ } finally {
297
+ clearTimeout(timeout);
298
+ }
299
+ } catch (err) {
300
+ const msg = err instanceof Error ? err.message : String(err);
301
+ return { success: false, error: msg };
302
+ }
303
+ }
304
+ });
305
+
306
+ // ../connectors/src/connectors/jira/index.ts
307
+ var tools = { request: requestTool };
308
+ var jiraConnector = new ConnectorPlugin({
309
+ slug: "jira",
310
+ authType: AUTH_TYPES.API_KEY,
311
+ name: "Jira",
312
+ description: "Connect to Jira Cloud for issue tracking, project management, and workflow data retrieval using API token authentication.",
313
+ iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/5zt4yjb36szSPPkCECYlPL/bc3e7223dc84fb16a1cce53a80f5afcc/jira.png",
314
+ parameters,
315
+ releaseFlag: { dev1: true, dev2: false, prod: false },
316
+ onboarding: jiraOnboarding,
317
+ systemPrompt: {
318
+ en: `### Tools
319
+
320
+ - \`jira-api-key_request\`: The only way to call the Jira Cloud REST API (v3). Use it to list projects, search issues with JQL, get issue details, create/update issues, manage transitions, and add comments. Authentication (Basic Auth with email + API token) and instance URL are configured automatically.
321
+
322
+ ### Business Logic
323
+
324
+ The business logic type for this connector is "typescript". Write handler code using the connector SDK shown below. Do NOT access credentials directly from environment variables.
325
+
326
+ #### Example
327
+
328
+ \`\`\`ts
329
+ import { connection } from "@squadbase/vite-server/connectors/jira-api-key";
330
+
331
+ const jira = connection("<connectionId>");
332
+
333
+ // Search issues with JQL
334
+ const res = await jira.request("/rest/api/3/search?jql=project=PROJ&maxResults=10");
335
+ const data = await res.json();
336
+
337
+ // Create an issue
338
+ await jira.request("/rest/api/3/issue", {
339
+ method: "POST",
340
+ body: JSON.stringify({
341
+ fields: {
342
+ project: { key: "PROJ" },
343
+ summary: "New issue title",
344
+ issuetype: { name: "Task" },
345
+ },
346
+ }),
347
+ });
348
+ \`\`\`
349
+
350
+ ### Jira Cloud REST API v3 Reference
351
+
352
+ #### List Projects
353
+ - GET project
354
+ - Query params: maxResults, startAt, expand
355
+
356
+ #### Search Issues (JQL)
357
+ - POST search
358
+ - Body: { "jql": "project = PROJ AND status = 'In Progress'", "maxResults": 50, "startAt": 0, "fields": ["summary", "status", "assignee", "priority"] }
359
+ - Supports pagination via startAt and maxResults
360
+
361
+ #### Get Issue
362
+ - GET issue/{issueIdOrKey}
363
+ - Query params: fields, expand
364
+
365
+ #### Create Issue
366
+ - POST issue
367
+ - Body: { "fields": { "project": { "key": "PROJ" }, "summary": "Title", "description": { "type": "doc", "version": 1, "content": [...] }, "issuetype": { "name": "Task" } } }
368
+ - Description uses Atlassian Document Format (ADF)
369
+
370
+ #### Update Issue
371
+ - PUT issue/{issueIdOrKey}
372
+ - Body: { "fields": { "summary": "Updated title" } }
373
+
374
+ #### Transition Issue
375
+ - POST issue/{issueIdOrKey}/transitions (list available transitions with GET)
376
+ - Body: { "transition": { "id": "31" } }
377
+
378
+ #### Add Comment
379
+ - POST issue/{issueIdOrKey}/comment
380
+ - Body: { "body": { "type": "doc", "version": 1, "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "Comment text" }] }] } }
381
+
382
+ #### JQL Syntax
383
+ - Comparison: project = "PROJ", status = "Done", assignee = "user@example.com"
384
+ - Operators: AND, OR, NOT, IN, IS, IS NOT
385
+ - Order: ORDER BY created DESC
386
+ - Functions: currentUser(), startOfDay(), endOfWeek()
387
+ - Text search: summary ~ "keyword"`,
388
+ ja: `### \u30C4\u30FC\u30EB
389
+
390
+ - \`jira-api-key_request\`: Jira Cloud REST API\uFF08v3\uFF09\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u306E\u53D6\u5F97\u3001JQL\u306B\u3088\u308B\u30A4\u30B7\u30E5\u30FC\u691C\u7D22\u3001\u30A4\u30B7\u30E5\u30FC\u8A73\u7D30\u306E\u53D6\u5F97\u3001\u30A4\u30B7\u30E5\u30FC\u306E\u4F5C\u6210\u30FB\u66F4\u65B0\u3001\u30C8\u30E9\u30F3\u30B8\u30B7\u30E7\u30F3\u7BA1\u7406\u3001\u30B3\u30E1\u30F3\u30C8\u8FFD\u52A0\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Basic Auth: \u30E1\u30FC\u30EB + API\u30C8\u30FC\u30AF\u30F3\uFF09\u3068\u30A4\u30F3\u30B9\u30BF\u30F3\u30B9URL\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
391
+
392
+ ### Business Logic
393
+
394
+ \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\u4EE5\u4E0B\u306B\u793A\u3059\u30B3\u30CD\u30AF\u30BFSDK\u3092\u4F7F\u7528\u3057\u3066\u30CF\u30F3\u30C9\u30E9\u30B3\u30FC\u30C9\u3092\u8A18\u8FF0\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u74B0\u5883\u5909\u6570\u304B\u3089\u76F4\u63A5\u8A8D\u8A3C\u60C5\u5831\u306B\u30A2\u30AF\u30BB\u30B9\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
395
+
396
+ #### Example
397
+
398
+ \`\`\`ts
399
+ import { connection } from "@squadbase/vite-server/connectors/jira-api-key";
400
+
401
+ const jira = connection("<connectionId>");
402
+
403
+ // JQL\u3067\u30A4\u30B7\u30E5\u30FC\u3092\u691C\u7D22
404
+ const res = await jira.request("/rest/api/3/search?jql=project=PROJ&maxResults=10");
405
+ const data = await res.json();
406
+
407
+ // \u30A4\u30B7\u30E5\u30FC\u3092\u4F5C\u6210
408
+ await jira.request("/rest/api/3/issue", {
409
+ method: "POST",
410
+ body: JSON.stringify({
411
+ fields: {
412
+ project: { key: "PROJ" },
413
+ summary: "\u65B0\u3057\u3044\u30A4\u30B7\u30E5\u30FC",
414
+ issuetype: { name: "Task" },
415
+ },
416
+ }),
417
+ });
418
+ \`\`\`
419
+
420
+ ### Jira Cloud REST API v3 \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
421
+
422
+ #### \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u306E\u53D6\u5F97
423
+ - GET project
424
+ - \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF: maxResults, startAt, expand
425
+
426
+ #### \u30A4\u30B7\u30E5\u30FC\u691C\u7D22\uFF08JQL\uFF09
427
+ - POST search
428
+ - Body: { "jql": "project = PROJ AND status = 'In Progress'", "maxResults": 50, "startAt": 0, "fields": ["summary", "status", "assignee", "priority"] }
429
+ - startAt \u3068 maxResults \u3067\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u53EF\u80FD
430
+
431
+ #### \u30A4\u30B7\u30E5\u30FC\u306E\u53D6\u5F97
432
+ - GET issue/{issueIdOrKey}
433
+ - \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF: fields, expand
434
+
435
+ #### \u30A4\u30B7\u30E5\u30FC\u306E\u4F5C\u6210
436
+ - POST issue
437
+ - Body: { "fields": { "project": { "key": "PROJ" }, "summary": "\u30BF\u30A4\u30C8\u30EB", "description": { "type": "doc", "version": 1, "content": [...] }, "issuetype": { "name": "Task" } } }
438
+ - description \u306F Atlassian Document Format (ADF) \u3092\u4F7F\u7528
439
+
440
+ #### \u30A4\u30B7\u30E5\u30FC\u306E\u66F4\u65B0
441
+ - PUT issue/{issueIdOrKey}
442
+ - Body: { "fields": { "summary": "\u66F4\u65B0\u3055\u308C\u305F\u30BF\u30A4\u30C8\u30EB" } }
443
+
444
+ #### \u30C8\u30E9\u30F3\u30B8\u30B7\u30E7\u30F3\u306E\u5B9F\u884C
445
+ - POST issue/{issueIdOrKey}/transitions\uFF08\u5229\u7528\u53EF\u80FD\u306A\u30C8\u30E9\u30F3\u30B8\u30B7\u30E7\u30F3\u306FGET\u3067\u53D6\u5F97\uFF09
446
+ - Body: { "transition": { "id": "31" } }
447
+
448
+ #### \u30B3\u30E1\u30F3\u30C8\u306E\u8FFD\u52A0
449
+ - POST issue/{issueIdOrKey}/comment
450
+ - Body: { "body": { "type": "doc", "version": 1, "content": [{ "type": "paragraph", "content": [{ "type": "text", "text": "\u30B3\u30E1\u30F3\u30C8\u5185\u5BB9" }] }] } }
451
+
452
+ #### JQL \u69CB\u6587
453
+ - \u6BD4\u8F03: project = "PROJ", status = "Done", assignee = "user@example.com"
454
+ - \u6F14\u7B97\u5B50: AND, OR, NOT, IN, IS, IS NOT
455
+ - \u30BD\u30FC\u30C8: ORDER BY created DESC
456
+ - \u95A2\u6570: currentUser(), startOfDay(), endOfWeek()
457
+ - \u30C6\u30AD\u30B9\u30C8\u691C\u7D22: summary ~ "\u30AD\u30FC\u30EF\u30FC\u30C9"`
458
+ },
459
+ tools
460
+ });
461
+
462
+ // src/connectors/create-connector-sdk.ts
463
+ import { readFileSync } from "fs";
464
+ import path from "path";
465
+
466
+ // src/connector-client/env.ts
467
+ function resolveEnvVar(entry, key, connectionId) {
468
+ const envVarName = entry.envVars[key];
469
+ if (!envVarName) {
470
+ throw new Error(`Connection "${connectionId}" is missing envVars mapping for key "${key}"`);
471
+ }
472
+ const value = process.env[envVarName];
473
+ if (!value) {
474
+ throw new Error(`Environment variable "${envVarName}" (for connection "${connectionId}", key "${key}") is not set`);
475
+ }
476
+ return value;
477
+ }
478
+ function resolveEnvVarOptional(entry, key) {
479
+ const envVarName = entry.envVars[key];
480
+ if (!envVarName) return void 0;
481
+ return process.env[envVarName] || void 0;
482
+ }
483
+
484
+ // src/connector-client/proxy-fetch.ts
485
+ import { getContext } from "hono/context-storage";
486
+ import { getCookie } from "hono/cookie";
487
+ var APP_SESSION_COOKIE_NAME = "__Host-squadbase-session";
488
+ function createSandboxProxyFetch(connectionId) {
489
+ return async (input, init) => {
490
+ const token = process.env.INTERNAL_SQUADBASE_OAUTH_MACHINE_CREDENTIAL;
491
+ const sandboxId = process.env.INTERNAL_SQUADBASE_SANDBOX_ID;
492
+ if (!token || !sandboxId) {
493
+ throw new Error(
494
+ "Connection proxy is not configured. Please check your deployment settings."
495
+ );
496
+ }
497
+ const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
498
+ const originalMethod = init?.method ?? "GET";
499
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
500
+ const baseDomain = process.env["SQUADBASE_PREVIEW_BASE_DOMAIN"] ?? "preview.app.squadbase.dev";
501
+ const proxyUrl = `https://${sandboxId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
502
+ return fetch(proxyUrl, {
503
+ method: "POST",
504
+ headers: {
505
+ "Content-Type": "application/json",
506
+ Authorization: `Bearer ${token}`
507
+ },
508
+ body: JSON.stringify({
509
+ url: originalUrl,
510
+ method: originalMethod,
511
+ body: originalBody
512
+ })
513
+ });
514
+ };
515
+ }
516
+ function createDeployedAppProxyFetch(connectionId) {
517
+ const projectId = process.env["SQUADBASE_PROJECT_ID"];
518
+ if (!projectId) {
519
+ throw new Error(
520
+ "Connection proxy is not configured. Please check your deployment settings."
521
+ );
522
+ }
523
+ const baseDomain = process.env["SQUADBASE_APP_BASE_DOMAIN"] ?? "squadbase.app";
524
+ const proxyUrl = `https://${projectId}.${baseDomain}/_sqcore/connections/${connectionId}/request`;
525
+ return async (input, init) => {
526
+ const originalUrl = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
527
+ const originalMethod = init?.method ?? "GET";
528
+ const originalBody = init?.body ? JSON.parse(init.body) : void 0;
529
+ const c = getContext();
530
+ const appSession = getCookie(c, APP_SESSION_COOKIE_NAME);
531
+ if (!appSession) {
532
+ throw new Error(
533
+ "No authentication method available for connection proxy."
534
+ );
535
+ }
536
+ return fetch(proxyUrl, {
537
+ method: "POST",
538
+ headers: {
539
+ "Content-Type": "application/json",
540
+ Authorization: `Bearer ${appSession}`
541
+ },
542
+ body: JSON.stringify({
543
+ url: originalUrl,
544
+ method: originalMethod,
545
+ body: originalBody
546
+ })
547
+ });
548
+ };
549
+ }
550
+ function createProxyFetch(connectionId) {
551
+ if (process.env.INTERNAL_SQUADBASE_SANDBOX_ID) {
552
+ return createSandboxProxyFetch(connectionId);
553
+ }
554
+ return createDeployedAppProxyFetch(connectionId);
555
+ }
556
+
557
+ // src/connectors/create-connector-sdk.ts
558
+ function loadConnectionsSync() {
559
+ const filePath = process.env.CONNECTIONS_PATH ?? path.join(process.cwd(), ".squadbase/connections.json");
560
+ try {
561
+ const raw = readFileSync(filePath, "utf-8");
562
+ return JSON.parse(raw);
563
+ } catch {
564
+ return {};
565
+ }
566
+ }
567
+ function createConnectorSdk(plugin, createClient2) {
568
+ return (connectionId) => {
569
+ const connections = loadConnectionsSync();
570
+ const entry = connections[connectionId];
571
+ if (!entry) {
572
+ throw new Error(
573
+ `Connection "${connectionId}" not found in .squadbase/connections.json`
574
+ );
575
+ }
576
+ if (entry.connector.slug !== plugin.slug) {
577
+ throw new Error(
578
+ `Connection "${connectionId}" is not a ${plugin.slug} connection (got "${entry.connector.slug}")`
579
+ );
580
+ }
581
+ const params = {};
582
+ for (const param of Object.values(plugin.parameters)) {
583
+ if (param.required) {
584
+ params[param.slug] = resolveEnvVar(entry, param.slug, connectionId);
585
+ } else {
586
+ const val = resolveEnvVarOptional(entry, param.slug);
587
+ if (val !== void 0) params[param.slug] = val;
588
+ }
589
+ }
590
+ return createClient2(params, createProxyFetch(connectionId));
591
+ };
592
+ }
593
+
594
+ // src/connectors/entries/jira-api-key.ts
595
+ var connection = createConnectorSdk(jiraConnector, createClient);
596
+ export {
597
+ connection
598
+ };