@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.
- package/dist/cli/index.js +82143 -9661
- package/dist/connectors/asana.d.ts +5 -0
- package/dist/connectors/asana.js +661 -0
- package/dist/connectors/customerio.d.ts +5 -0
- package/dist/connectors/customerio.js +633 -0
- package/dist/connectors/gemini.js +1 -1
- package/dist/connectors/gmail-oauth.d.ts +5 -0
- package/dist/connectors/gmail-oauth.js +639 -0
- package/dist/connectors/google-ads.d.ts +5 -0
- package/dist/connectors/google-ads.js +784 -0
- package/dist/connectors/google-sheets.d.ts +5 -0
- package/dist/connectors/google-sheets.js +598 -0
- package/dist/connectors/hubspot.js +14 -5
- package/dist/connectors/intercom-oauth.d.ts +5 -0
- package/dist/connectors/intercom-oauth.js +510 -0
- package/dist/connectors/intercom.d.ts +5 -0
- package/dist/connectors/intercom.js +627 -0
- package/dist/connectors/jira-api-key.d.ts +5 -0
- package/dist/connectors/jira-api-key.js +524 -0
- package/dist/connectors/linkedin-ads-oauth.d.ts +5 -0
- package/dist/connectors/linkedin-ads-oauth.js +774 -0
- package/dist/connectors/linkedin-ads.d.ts +5 -0
- package/dist/connectors/linkedin-ads.js +782 -0
- package/dist/connectors/mailchimp-oauth.d.ts +5 -0
- package/dist/connectors/mailchimp-oauth.js +539 -0
- package/dist/connectors/mailchimp.d.ts +5 -0
- package/dist/connectors/mailchimp.js +646 -0
- package/dist/connectors/notion-oauth.d.ts +5 -0
- package/dist/connectors/notion-oauth.js +493 -0
- package/dist/connectors/notion.d.ts +5 -0
- package/dist/connectors/notion.js +580 -0
- package/dist/connectors/zendesk-oauth.d.ts +5 -0
- package/dist/connectors/zendesk-oauth.js +505 -0
- package/dist/connectors/zendesk.d.ts +5 -0
- package/dist/connectors/zendesk.js +631 -0
- package/dist/index.js +82350 -7194
- package/dist/main.js +82336 -7180
- package/dist/vite-plugin.js +82235 -7079
- package/package.json +66 -2
|
@@ -0,0 +1,661 @@
|
|
|
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/asana/parameters.ts
|
|
46
|
+
var parameters = {
|
|
47
|
+
personalAccessToken: new ParameterDefinition({
|
|
48
|
+
slug: "personal-access-token",
|
|
49
|
+
name: "Asana Personal Access Token",
|
|
50
|
+
description: "Personal Access Token for Asana API authentication. Generate one at https://app.asana.com/0/my-apps",
|
|
51
|
+
envVarBaseKey: "ASANA_PERSONAL_ACCESS_TOKEN",
|
|
52
|
+
type: "text",
|
|
53
|
+
secret: true,
|
|
54
|
+
required: true
|
|
55
|
+
})
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// ../connectors/src/connectors/asana/sdk/index.ts
|
|
59
|
+
var BASE_URL = "https://app.asana.com/api/1.0";
|
|
60
|
+
function createClient(params) {
|
|
61
|
+
const token = params[parameters.personalAccessToken.slug];
|
|
62
|
+
if (!token) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
`asana: missing required parameter: ${parameters.personalAccessToken.slug}`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function authHeaders(extra) {
|
|
68
|
+
const headers = new Headers(extra);
|
|
69
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
70
|
+
headers.set("Content-Type", "application/json");
|
|
71
|
+
headers.set("Accept", "application/json");
|
|
72
|
+
return headers;
|
|
73
|
+
}
|
|
74
|
+
async function assertOk(res, label) {
|
|
75
|
+
if (!res.ok) {
|
|
76
|
+
const body = await res.text().catch(() => "(unreadable body)");
|
|
77
|
+
throw new Error(
|
|
78
|
+
`asana ${label}: ${res.status} ${res.statusText} \u2014 ${body}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function buildQuery(base, opt_fields) {
|
|
83
|
+
const params2 = new URLSearchParams();
|
|
84
|
+
for (const [key, value] of Object.entries(base)) {
|
|
85
|
+
if (value !== void 0) params2.set(key, String(value));
|
|
86
|
+
}
|
|
87
|
+
if (opt_fields && opt_fields.length > 0) {
|
|
88
|
+
params2.set("opt_fields", opt_fields.join(","));
|
|
89
|
+
}
|
|
90
|
+
const qs = params2.toString();
|
|
91
|
+
return qs ? `?${qs}` : "";
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
request(path2, init) {
|
|
95
|
+
const url = `${BASE_URL}${path2}`;
|
|
96
|
+
const headers = new Headers(init?.headers);
|
|
97
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
98
|
+
headers.set("Content-Type", "application/json");
|
|
99
|
+
headers.set("Accept", "application/json");
|
|
100
|
+
return fetch(url, { ...init, headers });
|
|
101
|
+
},
|
|
102
|
+
async listWorkspaces(options) {
|
|
103
|
+
const qs = buildQuery(
|
|
104
|
+
{ limit: options?.limit, offset: options?.offset },
|
|
105
|
+
options?.opt_fields
|
|
106
|
+
);
|
|
107
|
+
const res = await fetch(`${BASE_URL}/workspaces${qs}`, {
|
|
108
|
+
method: "GET",
|
|
109
|
+
headers: authHeaders()
|
|
110
|
+
});
|
|
111
|
+
await assertOk(res, "listWorkspaces");
|
|
112
|
+
return await res.json();
|
|
113
|
+
},
|
|
114
|
+
async listProjects(workspaceGid, options) {
|
|
115
|
+
const qs = buildQuery(
|
|
116
|
+
{
|
|
117
|
+
workspace: workspaceGid,
|
|
118
|
+
archived: options?.archived,
|
|
119
|
+
limit: options?.limit,
|
|
120
|
+
offset: options?.offset
|
|
121
|
+
},
|
|
122
|
+
options?.opt_fields
|
|
123
|
+
);
|
|
124
|
+
const res = await fetch(`${BASE_URL}/projects${qs}`, {
|
|
125
|
+
method: "GET",
|
|
126
|
+
headers: authHeaders()
|
|
127
|
+
});
|
|
128
|
+
await assertOk(res, "listProjects");
|
|
129
|
+
return await res.json();
|
|
130
|
+
},
|
|
131
|
+
async listTasks(projectGid, options) {
|
|
132
|
+
const qs = buildQuery(
|
|
133
|
+
{
|
|
134
|
+
project: projectGid,
|
|
135
|
+
completed_since: options?.completed_since,
|
|
136
|
+
limit: options?.limit,
|
|
137
|
+
offset: options?.offset
|
|
138
|
+
},
|
|
139
|
+
options?.opt_fields
|
|
140
|
+
);
|
|
141
|
+
const res = await fetch(`${BASE_URL}/tasks${qs}`, {
|
|
142
|
+
method: "GET",
|
|
143
|
+
headers: authHeaders()
|
|
144
|
+
});
|
|
145
|
+
await assertOk(res, "listTasks");
|
|
146
|
+
return await res.json();
|
|
147
|
+
},
|
|
148
|
+
async getTask(taskGid, options) {
|
|
149
|
+
const qs = buildQuery({}, options?.opt_fields);
|
|
150
|
+
const res = await fetch(
|
|
151
|
+
`${BASE_URL}/tasks/${encodeURIComponent(taskGid)}${qs}`,
|
|
152
|
+
{ method: "GET", headers: authHeaders() }
|
|
153
|
+
);
|
|
154
|
+
await assertOk(res, "getTask");
|
|
155
|
+
return await res.json();
|
|
156
|
+
},
|
|
157
|
+
async createTask(taskData) {
|
|
158
|
+
const res = await fetch(`${BASE_URL}/tasks`, {
|
|
159
|
+
method: "POST",
|
|
160
|
+
headers: authHeaders(),
|
|
161
|
+
body: JSON.stringify({ data: taskData })
|
|
162
|
+
});
|
|
163
|
+
await assertOk(res, "createTask");
|
|
164
|
+
return await res.json();
|
|
165
|
+
},
|
|
166
|
+
async updateTask(taskGid, taskData) {
|
|
167
|
+
const res = await fetch(
|
|
168
|
+
`${BASE_URL}/tasks/${encodeURIComponent(taskGid)}`,
|
|
169
|
+
{
|
|
170
|
+
method: "PUT",
|
|
171
|
+
headers: authHeaders(),
|
|
172
|
+
body: JSON.stringify({ data: taskData })
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
await assertOk(res, "updateTask");
|
|
176
|
+
return await res.json();
|
|
177
|
+
},
|
|
178
|
+
async listUsers(workspaceGid, options) {
|
|
179
|
+
const qs = buildQuery(
|
|
180
|
+
{
|
|
181
|
+
workspace: workspaceGid,
|
|
182
|
+
limit: options?.limit,
|
|
183
|
+
offset: options?.offset
|
|
184
|
+
},
|
|
185
|
+
options?.opt_fields
|
|
186
|
+
);
|
|
187
|
+
const res = await fetch(`${BASE_URL}/users${qs}`, {
|
|
188
|
+
method: "GET",
|
|
189
|
+
headers: authHeaders()
|
|
190
|
+
});
|
|
191
|
+
await assertOk(res, "listUsers");
|
|
192
|
+
return await res.json();
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ../connectors/src/connector-onboarding.ts
|
|
198
|
+
var ConnectorOnboarding = class {
|
|
199
|
+
/** Phase 1: Connection setup instructions (optional — some connectors don't need this) */
|
|
200
|
+
connectionSetupInstructions;
|
|
201
|
+
/** Phase 2: Data overview instructions */
|
|
202
|
+
dataOverviewInstructions;
|
|
203
|
+
constructor(config) {
|
|
204
|
+
this.connectionSetupInstructions = config.connectionSetupInstructions;
|
|
205
|
+
this.dataOverviewInstructions = config.dataOverviewInstructions;
|
|
206
|
+
}
|
|
207
|
+
getConnectionSetupPrompt(language) {
|
|
208
|
+
return this.connectionSetupInstructions?.[language] ?? null;
|
|
209
|
+
}
|
|
210
|
+
getDataOverviewInstructions(language) {
|
|
211
|
+
return this.dataOverviewInstructions[language];
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
// ../connectors/src/connector-tool.ts
|
|
216
|
+
var ConnectorTool = class {
|
|
217
|
+
name;
|
|
218
|
+
description;
|
|
219
|
+
inputSchema;
|
|
220
|
+
outputSchema;
|
|
221
|
+
_execute;
|
|
222
|
+
constructor(config) {
|
|
223
|
+
this.name = config.name;
|
|
224
|
+
this.description = config.description;
|
|
225
|
+
this.inputSchema = config.inputSchema;
|
|
226
|
+
this.outputSchema = config.outputSchema;
|
|
227
|
+
this._execute = config.execute;
|
|
228
|
+
}
|
|
229
|
+
createTool(connections, config) {
|
|
230
|
+
return {
|
|
231
|
+
description: this.description,
|
|
232
|
+
inputSchema: this.inputSchema,
|
|
233
|
+
outputSchema: this.outputSchema,
|
|
234
|
+
execute: (input) => this._execute(input, connections, config)
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// ../connectors/src/connector-plugin.ts
|
|
240
|
+
var ConnectorPlugin = class _ConnectorPlugin {
|
|
241
|
+
slug;
|
|
242
|
+
authType;
|
|
243
|
+
name;
|
|
244
|
+
description;
|
|
245
|
+
iconUrl;
|
|
246
|
+
parameters;
|
|
247
|
+
releaseFlag;
|
|
248
|
+
proxyPolicy;
|
|
249
|
+
experimentalAttributes;
|
|
250
|
+
onboarding;
|
|
251
|
+
systemPrompt;
|
|
252
|
+
tools;
|
|
253
|
+
query;
|
|
254
|
+
checkConnection;
|
|
255
|
+
constructor(config) {
|
|
256
|
+
this.slug = config.slug;
|
|
257
|
+
this.authType = config.authType;
|
|
258
|
+
this.name = config.name;
|
|
259
|
+
this.description = config.description;
|
|
260
|
+
this.iconUrl = config.iconUrl;
|
|
261
|
+
this.parameters = config.parameters;
|
|
262
|
+
this.releaseFlag = config.releaseFlag;
|
|
263
|
+
this.proxyPolicy = config.proxyPolicy;
|
|
264
|
+
this.experimentalAttributes = config.experimentalAttributes;
|
|
265
|
+
this.onboarding = config.onboarding;
|
|
266
|
+
this.systemPrompt = config.systemPrompt;
|
|
267
|
+
this.tools = config.tools;
|
|
268
|
+
this.query = config.query;
|
|
269
|
+
this.checkConnection = config.checkConnection;
|
|
270
|
+
}
|
|
271
|
+
get connectorKey() {
|
|
272
|
+
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Create tools for connections that belong to this connector.
|
|
276
|
+
* Filters connections by connectorKey internally.
|
|
277
|
+
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
278
|
+
*/
|
|
279
|
+
createTools(connections, config) {
|
|
280
|
+
const myConnections = connections.filter(
|
|
281
|
+
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
282
|
+
);
|
|
283
|
+
const result = {};
|
|
284
|
+
for (const t of Object.values(this.tools)) {
|
|
285
|
+
result[`${this.connectorKey}_${t.name}`] = t.createTool(
|
|
286
|
+
myConnections,
|
|
287
|
+
config
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
return result;
|
|
291
|
+
}
|
|
292
|
+
static deriveKey(slug, authType) {
|
|
293
|
+
return authType ? `${slug}-${authType}` : slug;
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
// ../connectors/src/connectors/asana/setup.ts
|
|
298
|
+
var asanaOnboarding = new ConnectorOnboarding({
|
|
299
|
+
dataOverviewInstructions: {
|
|
300
|
+
en: `1. Call asana_request with GET /workspaces to list all available workspaces
|
|
301
|
+
2. Pick the first workspace and call asana_request with GET /projects?workspace=WORKSPACE_GID&opt_fields=name,archived,created_at to list projects
|
|
302
|
+
3. Pick one project and call asana_request with GET /tasks?project=PROJECT_GID&opt_fields=name,completed,assignee.name,due_on,created_at&limit=10 to sample tasks
|
|
303
|
+
4. Explore sections via GET /sections?project=PROJECT_GID if the project uses board or section-based workflows`,
|
|
304
|
+
ja: `1. asana_request \u3067 GET /workspaces \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97
|
|
305
|
+
2. \u6700\u521D\u306E\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3092\u9078\u3073\u3001asana_request \u3067 GET /projects?workspace=WORKSPACE_GID&opt_fields=name,archived,created_at \u3092\u547C\u3073\u51FA\u3057\u3066\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
|
|
306
|
+
3. \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30921\u3064\u9078\u3073\u3001asana_request \u3067 GET /tasks?project=PROJECT_GID&opt_fields=name,completed,assignee.name,due_on,created_at&limit=10 \u3092\u547C\u3073\u51FA\u3057\u3066\u30BF\u30B9\u30AF\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0
|
|
307
|
+
4. \u30DC\u30FC\u30C9\u3084\u30BB\u30AF\u30B7\u30E7\u30F3\u30D9\u30FC\u30B9\u306E\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u306E\u5834\u5408\u306F GET /sections?project=PROJECT_GID \u3067\u30BB\u30AF\u30B7\u30E7\u30F3\u3092\u78BA\u8A8D`
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// ../connectors/src/connectors/asana/tools/request.ts
|
|
312
|
+
import { z } from "zod";
|
|
313
|
+
var BASE_URL2 = "https://app.asana.com/api/1.0";
|
|
314
|
+
var REQUEST_TIMEOUT_MS = 6e4;
|
|
315
|
+
var inputSchema = z.object({
|
|
316
|
+
toolUseIntent: z.string().optional().describe(
|
|
317
|
+
"Brief description of what you intend to accomplish with this tool call"
|
|
318
|
+
),
|
|
319
|
+
connectionId: z.string().describe("ID of the Asana connection to use"),
|
|
320
|
+
method: z.enum(["GET", "POST", "PUT", "DELETE"]).describe(
|
|
321
|
+
"HTTP method. GET for reading resources, POST for creating, PUT for updating, DELETE for removing."
|
|
322
|
+
),
|
|
323
|
+
path: z.string().describe(
|
|
324
|
+
"API path (e.g., '/workspaces', '/projects', '/tasks', '/tasks/{task_gid}'). Query parameters can be appended (e.g., '/tasks?project=PROJECT_GID&opt_fields=name,completed')."
|
|
325
|
+
),
|
|
326
|
+
body: z.record(z.string(), z.unknown()).optional().describe(
|
|
327
|
+
'Request body (JSON) for POST/PUT requests. Wrap payload in a "data" key (e.g., { "data": { "name": "My Task", "workspace": "WORKSPACE_GID" } }).'
|
|
328
|
+
)
|
|
329
|
+
});
|
|
330
|
+
var outputSchema = z.discriminatedUnion("success", [
|
|
331
|
+
z.object({
|
|
332
|
+
success: z.literal(true),
|
|
333
|
+
status: z.number(),
|
|
334
|
+
data: z.record(z.string(), z.unknown())
|
|
335
|
+
}),
|
|
336
|
+
z.object({
|
|
337
|
+
success: z.literal(false),
|
|
338
|
+
error: z.string()
|
|
339
|
+
})
|
|
340
|
+
]);
|
|
341
|
+
var requestTool = new ConnectorTool({
|
|
342
|
+
name: "request",
|
|
343
|
+
description: `Send authenticated requests to the Asana REST API.
|
|
344
|
+
Authentication is handled automatically using the Personal Access Token (Bearer token).
|
|
345
|
+
Provide the API path relative to the base URL (https://app.asana.com/api/1.0).
|
|
346
|
+
Use opt_fields query parameter to request specific fields and reduce response size.
|
|
347
|
+
|
|
348
|
+
Common endpoints:
|
|
349
|
+
- GET /workspaces \u2014 List workspaces
|
|
350
|
+
- GET /projects?workspace=WORKSPACE_GID \u2014 List projects in a workspace
|
|
351
|
+
- GET /tasks?project=PROJECT_GID \u2014 List tasks in a project
|
|
352
|
+
- GET /tasks/{task_gid} \u2014 Get a single task
|
|
353
|
+
- POST /tasks \u2014 Create a task (body: { "data": { "name": "...", "workspace": "..." } })
|
|
354
|
+
- PUT /tasks/{task_gid} \u2014 Update a task
|
|
355
|
+
- GET /users?workspace=WORKSPACE_GID \u2014 List users in a workspace
|
|
356
|
+
- GET /sections?project=PROJECT_GID \u2014 List sections in a project
|
|
357
|
+
- GET /tags?workspace=WORKSPACE_GID \u2014 List tags
|
|
358
|
+
- POST /tasks/{task_gid}/subtasks \u2014 Create a subtask
|
|
359
|
+
- GET /tasks/{task_gid}/stories \u2014 Get task comments/stories
|
|
360
|
+
|
|
361
|
+
Pagination: Use limit (1-100) and offset query parameters. The response includes next_page.offset for the next page.`,
|
|
362
|
+
inputSchema,
|
|
363
|
+
outputSchema,
|
|
364
|
+
async execute({ connectionId, method, path: path2, body }, connections) {
|
|
365
|
+
const connection2 = connections.find((c) => c.id === connectionId);
|
|
366
|
+
if (!connection2) {
|
|
367
|
+
return {
|
|
368
|
+
success: false,
|
|
369
|
+
error: `Connection ${connectionId} not found`
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
console.log(
|
|
373
|
+
`[connector-request] asana/${connection2.name}: ${method} ${path2}`
|
|
374
|
+
);
|
|
375
|
+
try {
|
|
376
|
+
const token = parameters.personalAccessToken.getValue(connection2);
|
|
377
|
+
const url = `${BASE_URL2}${path2}`;
|
|
378
|
+
const controller = new AbortController();
|
|
379
|
+
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
380
|
+
try {
|
|
381
|
+
const response = await fetch(url, {
|
|
382
|
+
method,
|
|
383
|
+
headers: {
|
|
384
|
+
Authorization: `Bearer ${token}`,
|
|
385
|
+
"Content-Type": "application/json",
|
|
386
|
+
Accept: "application/json"
|
|
387
|
+
},
|
|
388
|
+
body: body ? JSON.stringify(body) : void 0,
|
|
389
|
+
signal: controller.signal
|
|
390
|
+
});
|
|
391
|
+
const data = await response.json();
|
|
392
|
+
if (!response.ok) {
|
|
393
|
+
const errors = data?.errors;
|
|
394
|
+
const errorMessage = Array.isArray(errors) && errors.length > 0 ? errors[0]?.message ?? `HTTP ${response.status} ${response.statusText}` : `HTTP ${response.status} ${response.statusText}`;
|
|
395
|
+
return { success: false, error: String(errorMessage) };
|
|
396
|
+
}
|
|
397
|
+
return { success: true, status: response.status, data };
|
|
398
|
+
} finally {
|
|
399
|
+
clearTimeout(timeout);
|
|
400
|
+
}
|
|
401
|
+
} catch (err) {
|
|
402
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
403
|
+
return { success: false, error: msg };
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// ../connectors/src/connectors/asana/index.ts
|
|
409
|
+
var tools = { request: requestTool };
|
|
410
|
+
var asanaConnector = new ConnectorPlugin({
|
|
411
|
+
slug: "asana",
|
|
412
|
+
authType: null,
|
|
413
|
+
name: "Asana",
|
|
414
|
+
description: "Connect to Asana for project management, task tracking, and team collaboration data.",
|
|
415
|
+
iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/3eIdaoqzIIZs2Md0OoDJMf/2fa66e0841adb985da4d3120466f3ec4/asana-icon.png",
|
|
416
|
+
parameters,
|
|
417
|
+
releaseFlag: { dev1: true, dev2: false, prod: false },
|
|
418
|
+
onboarding: asanaOnboarding,
|
|
419
|
+
systemPrompt: {
|
|
420
|
+
en: `### Tools
|
|
421
|
+
|
|
422
|
+
- \`asana_request\`: The only way to call the Asana REST API. Use it to list workspaces, projects, tasks, users, sections, tags, and more. Authentication (Bearer token with Personal Access Token) is configured automatically. Provide the API path and optionally append query parameters like opt_fields for field selection.
|
|
423
|
+
|
|
424
|
+
### Business Logic
|
|
425
|
+
|
|
426
|
+
The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
|
|
427
|
+
|
|
428
|
+
SDK methods (client created via \`connection(connectionId)\`):
|
|
429
|
+
- \`client.request(path, init?)\` \u2014 low-level authenticated fetch (provide path relative to base URL)
|
|
430
|
+
- \`client.listWorkspaces(options?)\` \u2014 list all workspaces
|
|
431
|
+
- \`client.listProjects(workspaceGid, options?)\` \u2014 list projects in a workspace
|
|
432
|
+
- \`client.listTasks(projectGid, options?)\` \u2014 list tasks in a project
|
|
433
|
+
- \`client.getTask(taskGid, options?)\` \u2014 get a single task
|
|
434
|
+
- \`client.createTask(taskData)\` \u2014 create a new task
|
|
435
|
+
- \`client.updateTask(taskGid, taskData)\` \u2014 update an existing task
|
|
436
|
+
- \`client.listUsers(workspaceGid, options?)\` \u2014 list users in a workspace
|
|
437
|
+
|
|
438
|
+
\`\`\`ts
|
|
439
|
+
import type { Context } from "hono";
|
|
440
|
+
import { connection } from "@squadbase/vite-server/connectors/asana";
|
|
441
|
+
|
|
442
|
+
const asana = connection("<connectionId>");
|
|
443
|
+
|
|
444
|
+
export default async function handler(c: Context) {
|
|
445
|
+
const { projectGid } = await c.req.json<{ projectGid: string }>();
|
|
446
|
+
|
|
447
|
+
const { data: tasks } = await asana.listTasks(projectGid, {
|
|
448
|
+
opt_fields: ["name", "completed", "assignee.name", "due_on"],
|
|
449
|
+
limit: 50,
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
return c.json({ tasks });
|
|
453
|
+
}
|
|
454
|
+
\`\`\`
|
|
455
|
+
|
|
456
|
+
### Asana REST API Reference
|
|
457
|
+
|
|
458
|
+
- Base URL: \`https://app.asana.com/api/1.0\`
|
|
459
|
+
- Authentication: Bearer token (Personal Access Token, handled automatically)
|
|
460
|
+
- All write requests wrap the payload in a \`data\` key: \`{ "data": { ... } }\`
|
|
461
|
+
- Use \`opt_fields\` query parameter to select specific fields and reduce response size
|
|
462
|
+
- Pagination: offset-based with \`limit\` (1-100) and \`offset\` query parameters; response includes \`next_page.offset\`
|
|
463
|
+
|
|
464
|
+
#### Resource Endpoints
|
|
465
|
+
|
|
466
|
+
**Workspaces**
|
|
467
|
+
- GET \`/workspaces\` \u2014 List all workspaces
|
|
468
|
+
|
|
469
|
+
**Projects**
|
|
470
|
+
- GET \`/projects?workspace=WORKSPACE_GID\` \u2014 List projects in a workspace
|
|
471
|
+
- GET \`/projects/{project_gid}\` \u2014 Get a project
|
|
472
|
+
- POST \`/projects\` \u2014 Create a project
|
|
473
|
+
- PUT \`/projects/{project_gid}\` \u2014 Update a project
|
|
474
|
+
|
|
475
|
+
**Tasks**
|
|
476
|
+
- GET \`/tasks?project=PROJECT_GID\` \u2014 List tasks in a project (requires project, or assignee+workspace)
|
|
477
|
+
- GET \`/tasks/{task_gid}\` \u2014 Get a task
|
|
478
|
+
- POST \`/tasks\` \u2014 Create a task (requires workspace or projects in body)
|
|
479
|
+
- PUT \`/tasks/{task_gid}\` \u2014 Update a task
|
|
480
|
+
- DELETE \`/tasks/{task_gid}\` \u2014 Delete a task
|
|
481
|
+
- POST \`/tasks/{task_gid}/subtasks\` \u2014 Create a subtask
|
|
482
|
+
- GET \`/tasks/{task_gid}/subtasks\` \u2014 List subtasks
|
|
483
|
+
|
|
484
|
+
**Sections**
|
|
485
|
+
- GET \`/sections?project=PROJECT_GID\` \u2014 List sections in a project
|
|
486
|
+
- POST \`/sections/{section_gid}/addTask\` \u2014 Add a task to a section
|
|
487
|
+
|
|
488
|
+
**Users**
|
|
489
|
+
- GET \`/users?workspace=WORKSPACE_GID\` \u2014 List users in a workspace
|
|
490
|
+
- GET \`/users/me\` \u2014 Get the authenticated user
|
|
491
|
+
- GET \`/users/{user_gid}\` \u2014 Get a user
|
|
492
|
+
|
|
493
|
+
**Tags**
|
|
494
|
+
- GET \`/tags?workspace=WORKSPACE_GID\` \u2014 List tags in a workspace
|
|
495
|
+
|
|
496
|
+
**Stories (comments)**
|
|
497
|
+
- GET \`/tasks/{task_gid}/stories\` \u2014 List comments/stories on a task
|
|
498
|
+
- POST \`/tasks/{task_gid}/stories\` \u2014 Add a comment to a task
|
|
499
|
+
|
|
500
|
+
**Search**
|
|
501
|
+
- GET \`/workspaces/{workspace_gid}/tasks/search?text=QUERY\` \u2014 Search tasks in a workspace
|
|
502
|
+
|
|
503
|
+
#### Common opt_fields
|
|
504
|
+
- Tasks: name, completed, assignee, assignee.name, due_on, due_at, created_at, modified_at, notes, projects, projects.name, tags, tags.name, parent, parent.name, memberships, memberships.section, memberships.section.name, custom_fields
|
|
505
|
+
- Projects: name, archived, created_at, modified_at, owner, owner.name, team, team.name, members
|
|
506
|
+
- Users: name, email, photo`,
|
|
507
|
+
ja: `### \u30C4\u30FC\u30EB
|
|
508
|
+
|
|
509
|
+
- \`asana_request\`: Asana REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3001\u30BF\u30B9\u30AF\u3001\u30E6\u30FC\u30B6\u30FC\u3001\u30BB\u30AF\u30B7\u30E7\u30F3\u3001\u30BF\u30B0\u306A\u3069\u306E\u4E00\u89A7\u53D6\u5F97\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Personal Access Token\u3092\u4F7F\u7528\u3057\u305FBearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002API\u30D1\u30B9\u3092\u6307\u5B9A\u3057\u3001\u5FC5\u8981\u306B\u5FDC\u3058\u3066opt_fields\u306A\u3069\u306E\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u4ED8\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
510
|
+
|
|
511
|
+
### Business Logic
|
|
512
|
+
|
|
513
|
+
\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
|
|
514
|
+
|
|
515
|
+
SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8):
|
|
516
|
+
- \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch\uFF08\u30D9\u30FC\u30B9URL\u304B\u3089\u306E\u76F8\u5BFE\u30D1\u30B9\u3092\u6307\u5B9A\uFF09
|
|
517
|
+
- \`client.listWorkspaces(options?)\` \u2014 \u5168\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306E\u4E00\u89A7
|
|
518
|
+
- \`client.listProjects(workspaceGid, options?)\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7
|
|
519
|
+
- \`client.listTasks(projectGid, options?)\` \u2014 \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u5185\u306E\u30BF\u30B9\u30AF\u4E00\u89A7
|
|
520
|
+
- \`client.getTask(taskGid, options?)\` \u2014 \u5358\u4E00\u30BF\u30B9\u30AF\u306E\u53D6\u5F97
|
|
521
|
+
- \`client.createTask(taskData)\` \u2014 \u65B0\u898F\u30BF\u30B9\u30AF\u306E\u4F5C\u6210
|
|
522
|
+
- \`client.updateTask(taskGid, taskData)\` \u2014 \u65E2\u5B58\u30BF\u30B9\u30AF\u306E\u66F4\u65B0
|
|
523
|
+
- \`client.listUsers(workspaceGid, options?)\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30E6\u30FC\u30B6\u30FC\u4E00\u89A7
|
|
524
|
+
|
|
525
|
+
\`\`\`ts
|
|
526
|
+
import type { Context } from "hono";
|
|
527
|
+
import { connection } from "@squadbase/vite-server/connectors/asana";
|
|
528
|
+
|
|
529
|
+
const asana = connection("<connectionId>");
|
|
530
|
+
|
|
531
|
+
export default async function handler(c: Context) {
|
|
532
|
+
const { projectGid } = await c.req.json<{ projectGid: string }>();
|
|
533
|
+
|
|
534
|
+
const { data: tasks } = await asana.listTasks(projectGid, {
|
|
535
|
+
opt_fields: ["name", "completed", "assignee.name", "due_on"],
|
|
536
|
+
limit: 50,
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
return c.json({ tasks });
|
|
540
|
+
}
|
|
541
|
+
\`\`\`
|
|
542
|
+
|
|
543
|
+
### Asana REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
544
|
+
|
|
545
|
+
- \u30D9\u30FC\u30B9URL: \`https://app.asana.com/api/1.0\`
|
|
546
|
+
- \u8A8D\u8A3C: Bearer\u30C8\u30FC\u30AF\u30F3\uFF08Personal Access Token\u3001\u81EA\u52D5\u8A2D\u5B9A\uFF09
|
|
547
|
+
- \u66F8\u304D\u8FBC\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u306F\u30DA\u30A4\u30ED\u30FC\u30C9\u3092 \`data\` \u30AD\u30FC\u3067\u56F2\u3080: \`{ "data": { ... } }\`
|
|
548
|
+
- \`opt_fields\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3067\u7279\u5B9A\u306E\u30D5\u30A3\u30FC\u30EB\u30C9\u3092\u6307\u5B9A\u3057\u3066\u30EC\u30B9\u30DD\u30F3\u30B9\u30B5\u30A4\u30BA\u3092\u524A\u6E1B\u53EF\u80FD
|
|
549
|
+
- \u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3: \`limit\`\uFF081-100\uFF09\u3068 \`offset\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AA\u30D5\u30BB\u30C3\u30C8\u30D9\u30FC\u30B9\u3001\u30EC\u30B9\u30DD\u30F3\u30B9\u306B \`next_page.offset\` \u304C\u542B\u307E\u308C\u308B
|
|
550
|
+
|
|
551
|
+
#### \u30EA\u30BD\u30FC\u30B9\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8
|
|
552
|
+
|
|
553
|
+
**\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9**
|
|
554
|
+
- GET \`/workspaces\` \u2014 \u5168\u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u306E\u4E00\u89A7
|
|
555
|
+
|
|
556
|
+
**\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8**
|
|
557
|
+
- GET \`/projects?workspace=WORKSPACE_GID\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7
|
|
558
|
+
- GET \`/projects/{project_gid}\` \u2014 \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u53D6\u5F97
|
|
559
|
+
- POST \`/projects\` \u2014 \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u4F5C\u6210
|
|
560
|
+
- PUT \`/projects/{project_gid}\` \u2014 \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E\u66F4\u65B0
|
|
561
|
+
|
|
562
|
+
**\u30BF\u30B9\u30AF**
|
|
563
|
+
- GET \`/tasks?project=PROJECT_GID\` \u2014 \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u5185\u306E\u30BF\u30B9\u30AF\u4E00\u89A7\uFF08project\u3001\u307E\u305F\u306Fassignee+workspace\u304C\u5FC5\u8981\uFF09
|
|
564
|
+
- GET \`/tasks/{task_gid}\` \u2014 \u30BF\u30B9\u30AF\u306E\u53D6\u5F97
|
|
565
|
+
- POST \`/tasks\` \u2014 \u30BF\u30B9\u30AF\u306E\u4F5C\u6210\uFF08body\u306Bworkspace\u307E\u305F\u306Fprojects\u304C\u5FC5\u8981\uFF09
|
|
566
|
+
- PUT \`/tasks/{task_gid}\` \u2014 \u30BF\u30B9\u30AF\u306E\u66F4\u65B0
|
|
567
|
+
- DELETE \`/tasks/{task_gid}\` \u2014 \u30BF\u30B9\u30AF\u306E\u524A\u9664
|
|
568
|
+
- POST \`/tasks/{task_gid}/subtasks\` \u2014 \u30B5\u30D6\u30BF\u30B9\u30AF\u306E\u4F5C\u6210
|
|
569
|
+
- GET \`/tasks/{task_gid}/subtasks\` \u2014 \u30B5\u30D6\u30BF\u30B9\u30AF\u306E\u4E00\u89A7
|
|
570
|
+
|
|
571
|
+
**\u30BB\u30AF\u30B7\u30E7\u30F3**
|
|
572
|
+
- GET \`/sections?project=PROJECT_GID\` \u2014 \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u5185\u306E\u30BB\u30AF\u30B7\u30E7\u30F3\u4E00\u89A7
|
|
573
|
+
- POST \`/sections/{section_gid}/addTask\` \u2014 \u30BB\u30AF\u30B7\u30E7\u30F3\u306B\u30BF\u30B9\u30AF\u3092\u8FFD\u52A0
|
|
574
|
+
|
|
575
|
+
**\u30E6\u30FC\u30B6\u30FC**
|
|
576
|
+
- GET \`/users?workspace=WORKSPACE_GID\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30E6\u30FC\u30B6\u30FC\u4E00\u89A7
|
|
577
|
+
- GET \`/users/me\` \u2014 \u8A8D\u8A3C\u30E6\u30FC\u30B6\u30FC\u306E\u53D6\u5F97
|
|
578
|
+
- GET \`/users/{user_gid}\` \u2014 \u30E6\u30FC\u30B6\u30FC\u306E\u53D6\u5F97
|
|
579
|
+
|
|
580
|
+
**\u30BF\u30B0**
|
|
581
|
+
- GET \`/tags?workspace=WORKSPACE_GID\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30BF\u30B0\u4E00\u89A7
|
|
582
|
+
|
|
583
|
+
**\u30B9\u30C8\u30FC\u30EA\u30FC\uFF08\u30B3\u30E1\u30F3\u30C8\uFF09**
|
|
584
|
+
- GET \`/tasks/{task_gid}/stories\` \u2014 \u30BF\u30B9\u30AF\u306E\u30B3\u30E1\u30F3\u30C8/\u30B9\u30C8\u30FC\u30EA\u30FC\u4E00\u89A7
|
|
585
|
+
- POST \`/tasks/{task_gid}/stories\` \u2014 \u30BF\u30B9\u30AF\u306B\u30B3\u30E1\u30F3\u30C8\u3092\u8FFD\u52A0
|
|
586
|
+
|
|
587
|
+
**\u691C\u7D22**
|
|
588
|
+
- GET \`/workspaces/{workspace_gid}/tasks/search?text=QUERY\` \u2014 \u30EF\u30FC\u30AF\u30B9\u30DA\u30FC\u30B9\u5185\u306E\u30BF\u30B9\u30AF\u691C\u7D22
|
|
589
|
+
|
|
590
|
+
#### \u3088\u304F\u4F7F\u3046opt_fields
|
|
591
|
+
- \u30BF\u30B9\u30AF: name, completed, assignee, assignee.name, due_on, due_at, created_at, modified_at, notes, projects, projects.name, tags, tags.name, parent, parent.name, memberships, memberships.section, memberships.section.name, custom_fields
|
|
592
|
+
- \u30D7\u30ED\u30B8\u30A7\u30AF\u30C8: name, archived, created_at, modified_at, owner, owner.name, team, team.name, members
|
|
593
|
+
- \u30E6\u30FC\u30B6\u30FC: name, email, photo`
|
|
594
|
+
},
|
|
595
|
+
tools
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
// src/connectors/create-connector-sdk.ts
|
|
599
|
+
import { readFileSync } from "fs";
|
|
600
|
+
import path from "path";
|
|
601
|
+
|
|
602
|
+
// src/connector-client/env.ts
|
|
603
|
+
function resolveEnvVar(entry, key, connectionId) {
|
|
604
|
+
const envVarName = entry.envVars[key];
|
|
605
|
+
if (!envVarName) {
|
|
606
|
+
throw new Error(`Connection "${connectionId}" is missing envVars mapping for key "${key}"`);
|
|
607
|
+
}
|
|
608
|
+
const value = process.env[envVarName];
|
|
609
|
+
if (!value) {
|
|
610
|
+
throw new Error(`Environment variable "${envVarName}" (for connection "${connectionId}", key "${key}") is not set`);
|
|
611
|
+
}
|
|
612
|
+
return value;
|
|
613
|
+
}
|
|
614
|
+
function resolveEnvVarOptional(entry, key) {
|
|
615
|
+
const envVarName = entry.envVars[key];
|
|
616
|
+
if (!envVarName) return void 0;
|
|
617
|
+
return process.env[envVarName] || void 0;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// src/connectors/create-connector-sdk.ts
|
|
621
|
+
function loadConnectionsSync() {
|
|
622
|
+
const filePath = process.env.CONNECTIONS_PATH ?? path.join(process.cwd(), ".squadbase/connections.json");
|
|
623
|
+
try {
|
|
624
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
625
|
+
return JSON.parse(raw);
|
|
626
|
+
} catch {
|
|
627
|
+
return {};
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
function createConnectorSdk(plugin, createClient2) {
|
|
631
|
+
return (connectionId) => {
|
|
632
|
+
const connections = loadConnectionsSync();
|
|
633
|
+
const entry = connections[connectionId];
|
|
634
|
+
if (!entry) {
|
|
635
|
+
throw new Error(
|
|
636
|
+
`Connection "${connectionId}" not found in .squadbase/connections.json`
|
|
637
|
+
);
|
|
638
|
+
}
|
|
639
|
+
if (entry.connector.slug !== plugin.slug) {
|
|
640
|
+
throw new Error(
|
|
641
|
+
`Connection "${connectionId}" is not a ${plugin.slug} connection (got "${entry.connector.slug}")`
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
const params = {};
|
|
645
|
+
for (const param of Object.values(plugin.parameters)) {
|
|
646
|
+
if (param.required) {
|
|
647
|
+
params[param.slug] = resolveEnvVar(entry, param.slug, connectionId);
|
|
648
|
+
} else {
|
|
649
|
+
const val = resolveEnvVarOptional(entry, param.slug);
|
|
650
|
+
if (val !== void 0) params[param.slug] = val;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
return createClient2(params);
|
|
654
|
+
};
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// src/connectors/entries/asana.ts
|
|
658
|
+
var connection = createConnectorSdk(asanaConnector, createClient);
|
|
659
|
+
export {
|
|
660
|
+
connection
|
|
661
|
+
};
|