@squadbase/vite-server 0.1.3-dev.9 → 0.1.4-dev.0
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 +14539 -29447
- package/dist/connectors/airtable-oauth.js +43 -6
- package/dist/connectors/airtable.js +43 -6
- package/dist/connectors/amplitude.js +43 -6
- package/dist/connectors/anthropic.js +43 -6
- package/dist/connectors/asana.js +43 -6
- package/dist/connectors/attio.js +522 -118
- package/dist/connectors/{google-ads-oauth.d.ts → backlog-api-key.d.ts} +1 -1
- package/dist/connectors/backlog-api-key.js +629 -0
- package/dist/connectors/customerio.js +43 -6
- package/dist/connectors/dbt.js +43 -6
- package/dist/connectors/{google-sheets-oauth.d.ts → gamma.d.ts} +1 -1
- package/dist/connectors/gamma.js +866 -0
- package/dist/connectors/gemini.js +43 -6
- package/dist/connectors/gmail-oauth.js +65 -8
- package/dist/connectors/gmail.js +104 -44
- package/dist/connectors/google-ads.d.ts +1 -1
- package/dist/connectors/google-ads.js +410 -332
- package/dist/connectors/google-analytics-oauth.js +61 -8
- package/dist/connectors/google-analytics.js +107 -292
- package/dist/connectors/google-calendar-oauth.js +61 -8
- package/dist/connectors/google-calendar.js +111 -58
- package/dist/connectors/{linkedin-ads-oauth.d.ts → google-docs.d.ts} +1 -1
- package/dist/connectors/google-docs.js +631 -0
- package/dist/connectors/google-drive.d.ts +5 -0
- package/dist/connectors/google-drive.js +875 -0
- package/dist/connectors/google-sheets.d.ts +1 -1
- package/dist/connectors/google-sheets.js +267 -285
- package/dist/connectors/google-slides.d.ts +5 -0
- package/dist/connectors/google-slides.js +663 -0
- package/dist/connectors/grafana.js +43 -6
- package/dist/connectors/hubspot-oauth.js +43 -6
- package/dist/connectors/hubspot.js +43 -6
- package/dist/connectors/intercom-oauth.js +43 -6
- package/dist/connectors/intercom.js +43 -6
- package/dist/connectors/jira-api-key.js +43 -6
- package/dist/connectors/kintone-api-token.js +256 -82
- package/dist/connectors/kintone.js +43 -6
- package/dist/connectors/linkedin-ads.js +188 -168
- package/dist/connectors/mailchimp-oauth.js +43 -6
- package/dist/connectors/mailchimp.js +43 -6
- package/dist/connectors/mixpanel.d.ts +5 -0
- package/dist/connectors/mixpanel.js +779 -0
- package/dist/connectors/notion-oauth.js +43 -6
- package/dist/connectors/notion.js +43 -6
- package/dist/connectors/openai.js +43 -6
- package/dist/connectors/sentry.d.ts +5 -0
- package/dist/connectors/sentry.js +761 -0
- package/dist/connectors/shopify-oauth.js +43 -6
- package/dist/connectors/shopify.js +43 -6
- package/dist/connectors/stripe-api-key.js +46 -7
- package/dist/connectors/stripe-oauth.js +43 -6
- package/dist/connectors/wix-store.js +43 -6
- package/dist/connectors/zendesk-oauth.js +43 -6
- package/dist/connectors/zendesk.js +43 -6
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4574 -3863
- package/dist/main.js +4572 -3862
- package/dist/vite-plugin.js +4572 -3862
- package/package.json +30 -12
- package/dist/connectors/google-ads-oauth.js +0 -890
- package/dist/connectors/google-sheets-oauth.js +0 -718
- package/dist/connectors/linkedin-ads-oauth.js +0 -848
|
@@ -61,6 +61,15 @@ var parameters = {
|
|
|
61
61
|
type: "text",
|
|
62
62
|
secret: true,
|
|
63
63
|
required: true
|
|
64
|
+
}),
|
|
65
|
+
appId: new ParameterDefinition({
|
|
66
|
+
slug: "app-id",
|
|
67
|
+
name: "kintone App ID",
|
|
68
|
+
description: "The numeric ID of the kintone app this token is scoped to (visible in the app URL: https://{subdomain}.cybozu.com/k/{appId}/). API tokens are always scoped to a single app.",
|
|
69
|
+
envVarBaseKey: "KINTONE_APP_ID",
|
|
70
|
+
type: "text",
|
|
71
|
+
secret: false,
|
|
72
|
+
required: true
|
|
64
73
|
})
|
|
65
74
|
};
|
|
66
75
|
|
|
@@ -68,19 +77,58 @@ var parameters = {
|
|
|
68
77
|
function createClient(params) {
|
|
69
78
|
const baseUrl = params[parameters.baseUrl.slug];
|
|
70
79
|
const apiToken = params[parameters.apiToken.slug];
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
80
|
+
const appId = params[parameters.appId.slug];
|
|
81
|
+
const required = [
|
|
82
|
+
parameters.baseUrl.slug,
|
|
83
|
+
parameters.apiToken.slug,
|
|
84
|
+
parameters.appId.slug
|
|
85
|
+
];
|
|
86
|
+
const missing = required.filter((s) => !params[s]);
|
|
87
|
+
if (missing.length > 0) {
|
|
74
88
|
throw new Error(
|
|
75
89
|
`kintone: missing required parameters: ${missing.join(", ")}`
|
|
76
90
|
);
|
|
77
91
|
}
|
|
92
|
+
let _restClient = null;
|
|
93
|
+
async function getRestClient() {
|
|
94
|
+
if (!_restClient) {
|
|
95
|
+
const { KintoneRestAPIClient } = await import("@kintone/rest-api-client");
|
|
96
|
+
_restClient = new KintoneRestAPIClient({
|
|
97
|
+
baseUrl,
|
|
98
|
+
auth: { apiToken }
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
return _restClient;
|
|
102
|
+
}
|
|
78
103
|
return {
|
|
104
|
+
appId,
|
|
79
105
|
request(path2, init) {
|
|
80
106
|
const url = `${baseUrl.replace(/\/+$/, "")}${path2}`;
|
|
81
107
|
const headers = new Headers(init?.headers);
|
|
82
108
|
headers.set("X-Cybozu-API-Token", apiToken);
|
|
83
109
|
return fetch(url, { ...init, headers });
|
|
110
|
+
},
|
|
111
|
+
async getRecords(targetAppId, options) {
|
|
112
|
+
const client = await getRestClient();
|
|
113
|
+
const result = await client.record.getRecords({
|
|
114
|
+
app: targetAppId ?? appId,
|
|
115
|
+
query: options?.query,
|
|
116
|
+
fields: options?.fields,
|
|
117
|
+
totalCount: options?.totalCount
|
|
118
|
+
});
|
|
119
|
+
return {
|
|
120
|
+
records: result.records,
|
|
121
|
+
totalCount: result.totalCount ? Number(result.totalCount) : null
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
async getRecord(appIdOrRecordId, recordId) {
|
|
125
|
+
const client = await getRestClient();
|
|
126
|
+
const [targetAppId, targetRecordId] = recordId === void 0 ? [appId, appIdOrRecordId] : [appIdOrRecordId, recordId];
|
|
127
|
+
const result = await client.record.getRecord({
|
|
128
|
+
app: targetAppId,
|
|
129
|
+
id: targetRecordId
|
|
130
|
+
});
|
|
131
|
+
return { record: result.record };
|
|
84
132
|
}
|
|
85
133
|
};
|
|
86
134
|
}
|
|
@@ -167,21 +215,58 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
167
215
|
* Filters connections by connectorKey internally.
|
|
168
216
|
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
169
217
|
*/
|
|
170
|
-
createTools(connections, config) {
|
|
218
|
+
createTools(connections, config, opts) {
|
|
171
219
|
const myConnections = connections.filter(
|
|
172
220
|
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
173
221
|
);
|
|
174
222
|
const result = {};
|
|
175
223
|
for (const t of Object.values(this.tools)) {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
224
|
+
const tool = t.createTool(myConnections, config);
|
|
225
|
+
const originalToModelOutput = tool.toModelOutput;
|
|
226
|
+
result[`${this.connectorKey}_${t.name}`] = {
|
|
227
|
+
...tool,
|
|
228
|
+
toModelOutput: async (options) => {
|
|
229
|
+
if (!originalToModelOutput) {
|
|
230
|
+
return opts.truncateOutput(options.output);
|
|
231
|
+
}
|
|
232
|
+
const modelOutput = await originalToModelOutput(options);
|
|
233
|
+
if (modelOutput.type === "text" || modelOutput.type === "json") {
|
|
234
|
+
return opts.truncateOutput(modelOutput.value);
|
|
235
|
+
}
|
|
236
|
+
return modelOutput;
|
|
237
|
+
}
|
|
238
|
+
};
|
|
180
239
|
}
|
|
181
240
|
return result;
|
|
182
241
|
}
|
|
183
242
|
static deriveKey(slug, authType) {
|
|
184
|
-
|
|
243
|
+
if (authType) return `${slug}-${authType}`;
|
|
244
|
+
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
245
|
+
// user-password
|
|
246
|
+
"postgresql": "user-password",
|
|
247
|
+
"mysql": "user-password",
|
|
248
|
+
"clickhouse": "user-password",
|
|
249
|
+
"kintone": "user-password",
|
|
250
|
+
"squadbase-db": "user-password",
|
|
251
|
+
// service-account
|
|
252
|
+
"snowflake": "service-account",
|
|
253
|
+
"bigquery": "service-account",
|
|
254
|
+
"google-analytics": "service-account",
|
|
255
|
+
"google-calendar": "service-account",
|
|
256
|
+
"aws-athena": "service-account",
|
|
257
|
+
"redshift": "service-account",
|
|
258
|
+
// api-key
|
|
259
|
+
"databricks": "api-key",
|
|
260
|
+
"dbt": "api-key",
|
|
261
|
+
"airtable": "api-key",
|
|
262
|
+
"openai": "api-key",
|
|
263
|
+
"gemini": "api-key",
|
|
264
|
+
"anthropic": "api-key",
|
|
265
|
+
"wix-store": "api-key"
|
|
266
|
+
};
|
|
267
|
+
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
268
|
+
if (fallbackAuthType) return `${slug}-${fallbackAuthType}`;
|
|
269
|
+
return slug;
|
|
185
270
|
}
|
|
186
271
|
};
|
|
187
272
|
|
|
@@ -198,23 +283,49 @@ var AUTH_TYPES = {
|
|
|
198
283
|
// ../connectors/src/connectors/kintone-api-token/setup.ts
|
|
199
284
|
var kintoneApiTokenOnboarding = new ConnectorOnboarding({
|
|
200
285
|
dataOverviewInstructions: {
|
|
201
|
-
en: `
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
286
|
+
en: `Each connection is scoped to a single kintone app (configured via the "app-id" parameter). The request tool auto-injects the configured app id, so you do NOT need to specify "app=" in paths or "app" in bodies. apps.json is NOT available with API Token auth.
|
|
287
|
+
|
|
288
|
+
1. Call kintone-api-key_request with GET app.json to fetch the scoped app's metadata (name, description, creator)
|
|
289
|
+
2. Call kintone-api-key_request with GET app/form/fields.json to get field definitions
|
|
290
|
+
3. Call kintone-api-key_request with GET records.json with query=limit 5 to sample records`,
|
|
291
|
+
ja: `\u5404\u63A5\u7D9A\u306F1\u3064\u306Ekintone\u30A2\u30D7\u30EA\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u307E\u3059\uFF08"app-id" \u30D1\u30E9\u30E1\u30FC\u30BF\u3067\u8A2D\u5B9A\uFF09\u3002request \u30C4\u30FC\u30EB\u306F\u8A2D\u5B9A\u3055\u308C\u305F\u30A2\u30D7\u30EAID\u3092\u81EA\u52D5\u6CE8\u5165\u3059\u308B\u305F\u3081\u3001\u30D1\u30B9\u306B "app=" \u3084 body \u306B "app" \u3092\u6307\u5B9A\u3059\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093\u3002API Token \u8A8D\u8A3C\u3067\u306F apps.json \u306F\u5229\u7528\u3067\u304D\u307E\u305B\u3093\u3002
|
|
292
|
+
|
|
293
|
+
1. kintone-api-key_request \u3067 GET app.json \u3092\u547C\u3073\u51FA\u3057\u3001\u30B9\u30B3\u30FC\u30D7\u5BFE\u8C61\u30A2\u30D7\u30EA\u306E\u30E1\u30BF\u60C5\u5831\uFF08\u30A2\u30D7\u30EA\u540D\u3001\u8AAC\u660E\u3001\u4F5C\u6210\u8005\uFF09\u3092\u53D6\u5F97
|
|
294
|
+
2. kintone-api-key_request \u3067 GET app/form/fields.json \u3092\u547C\u3073\u51FA\u3057\u3001\u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u3092\u53D6\u5F97
|
|
295
|
+
3. kintone-api-key_request \u3067 GET records.json \u3092 query=limit 5 \u3067\u547C\u3073\u51FA\u3057\u3001\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0`
|
|
207
296
|
}
|
|
208
297
|
});
|
|
209
298
|
|
|
210
299
|
// ../connectors/src/connectors/kintone-api-token/tools/request.ts
|
|
211
300
|
import { z } from "zod";
|
|
212
301
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
302
|
+
var APP_PARAM_KEY_BY_ENDPOINT = {
|
|
303
|
+
"app.json": "id"
|
|
304
|
+
};
|
|
305
|
+
var DEFAULT_APP_PARAM_KEY = "app";
|
|
306
|
+
function injectAppIntoPath(path2, appId) {
|
|
307
|
+
const [head, query = ""] = path2.split("?", 2);
|
|
308
|
+
const endpoint = head.toLowerCase();
|
|
309
|
+
const paramKey = APP_PARAM_KEY_BY_ENDPOINT[endpoint] ?? DEFAULT_APP_PARAM_KEY;
|
|
310
|
+
const params = new URLSearchParams(query);
|
|
311
|
+
if (!params.has(paramKey)) {
|
|
312
|
+
params.set(paramKey, appId);
|
|
313
|
+
}
|
|
314
|
+
const serialized = params.toString();
|
|
315
|
+
return serialized ? `${head}?${serialized}` : head;
|
|
316
|
+
}
|
|
317
|
+
function injectAppIntoBody(body, appId) {
|
|
318
|
+
if (!body) return body;
|
|
319
|
+
if ("app" in body) return body;
|
|
320
|
+
return { app: appId, ...body };
|
|
321
|
+
}
|
|
213
322
|
var inputSchema = z.object({
|
|
214
323
|
toolUseIntent: z.string().optional().describe("Brief description of what you intend to accomplish with this tool call"),
|
|
215
324
|
connectionId: z.string().describe("ID of the kintone connection to use"),
|
|
216
325
|
method: z.enum(["GET", "POST", "PUT", "DELETE"]).describe("HTTP method"),
|
|
217
|
-
path: z.string().describe(
|
|
326
|
+
path: z.string().describe(
|
|
327
|
+
"API path (e.g., 'app.json', 'app/form/fields.json', 'records.json?query=limit 5'). The connection's app id is auto-injected; you do not need to include 'app=' in the query string. 'apps.json' is not supported with API Token auth."
|
|
328
|
+
),
|
|
218
329
|
body: z.record(z.string(), z.unknown()).optional().describe("Request body (JSON)")
|
|
219
330
|
});
|
|
220
331
|
var outputSchema = z.discriminatedUnion("success", [
|
|
@@ -243,20 +354,31 @@ Authentication is handled automatically using the API token.`,
|
|
|
243
354
|
try {
|
|
244
355
|
const baseUrl = parameters.baseUrl.getValue(connection2);
|
|
245
356
|
const apiToken = parameters.apiToken.getValue(connection2);
|
|
246
|
-
const
|
|
357
|
+
const appId = parameters.appId.getValue(connection2);
|
|
358
|
+
const normalizedPath = path2.replace(/^\/+/, "");
|
|
359
|
+
const pathHead = normalizedPath.split("?")[0] ?? "";
|
|
360
|
+
if (/^apps\.json$/i.test(pathHead)) {
|
|
361
|
+
return {
|
|
362
|
+
success: false,
|
|
363
|
+
error: `kintone API tokens are scoped to a single app and cannot list apps. This connection is scoped to app ${appId}. Use app-specific endpoints (e.g., app.json, app/form/fields.json, records.json).`
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
const injectedPath = injectAppIntoPath(normalizedPath, appId);
|
|
367
|
+
const injectedBody = injectAppIntoBody(body, appId);
|
|
368
|
+
const url = `${baseUrl.replace(/\/+$/, "")}/k/v1/${injectedPath}`;
|
|
247
369
|
const controller = new AbortController();
|
|
248
370
|
const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
249
371
|
try {
|
|
250
372
|
const headers = {
|
|
251
373
|
"X-Cybozu-API-Token": apiToken
|
|
252
374
|
};
|
|
253
|
-
if (
|
|
375
|
+
if (injectedBody) {
|
|
254
376
|
headers["Content-Type"] = "application/json";
|
|
255
377
|
}
|
|
256
378
|
const response = await fetch(url, {
|
|
257
379
|
method,
|
|
258
380
|
headers,
|
|
259
|
-
body:
|
|
381
|
+
body: injectedBody ? JSON.stringify(injectedBody) : void 0,
|
|
260
382
|
signal: controller.signal
|
|
261
383
|
});
|
|
262
384
|
const data = await response.json();
|
|
@@ -291,98 +413,150 @@ var kintoneApiTokenConnector = new ConnectorPlugin({
|
|
|
291
413
|
systemPrompt: {
|
|
292
414
|
en: `### Tools
|
|
293
415
|
|
|
294
|
-
- \`kintone-api-key_request\`: The only way to call the kintone REST API. Use it to
|
|
416
|
+
- \`kintone-api-key_request\`: The only way to call the kintone REST API. Use it to fetch app metadata/field definitions and read/write records. Authentication (API Token), base URL, and the connection's app id are configured automatically. Each connection is scoped to exactly one app (kintone API tokens are per-app).
|
|
295
417
|
|
|
296
|
-
###
|
|
418
|
+
### App scoping (important)
|
|
297
419
|
|
|
298
|
-
|
|
299
|
-
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
-
|
|
303
|
-
|
|
304
|
-
### Get Records
|
|
305
|
-
- GET records.json?app={appId}&query={query}
|
|
306
|
-
- Query example: records.json?app=1&query=updatedTime > "2024-01-01" order by recordNumber asc limit 100
|
|
307
|
-
|
|
308
|
-
#### Add Record
|
|
309
|
-
- POST record.json
|
|
310
|
-
- Body: { "app": 1, "record": { "fieldName": { "value": "value" } } }
|
|
311
|
-
|
|
312
|
-
#### kintone Query Syntax
|
|
313
|
-
- Comparison: fieldName = "value", fieldName > 100
|
|
314
|
-
- Operators: and, or, not
|
|
315
|
-
- Sort: order by fieldName asc/desc
|
|
316
|
-
- Limit: limit 100 offset 0
|
|
317
|
-
- String: like "partial match"
|
|
420
|
+
- Each connection is scoped to one app, configured via the "app-id" parameter.
|
|
421
|
+
- The request tool auto-injects the configured app id:
|
|
422
|
+
- Query string: adds \`app=<appId>\` to paths like \`records.json\`, \`app/form/fields.json\`, etc. when missing. For \`app.json\` (app metadata), adds \`id=<appId>\` instead.
|
|
423
|
+
- Request body: adds \`"app": <appId>\` to POST/PUT bodies when missing.
|
|
424
|
+
- You do NOT need to include "app=" in paths or "app" in bodies \u2014 it is handled for you.
|
|
425
|
+
- \`apps.json\` (list all apps) is NOT callable with API Token auth.
|
|
318
426
|
|
|
319
427
|
### Business Logic
|
|
320
428
|
|
|
321
|
-
The business logic type for this connector is "typescript".
|
|
429
|
+
The business logic type for this connector is "typescript". Use the connector SDK in your handler. Do NOT read credentials from environment variables.
|
|
322
430
|
|
|
323
|
-
|
|
431
|
+
SDK surface (client created via \`connection(connectionId)\`):
|
|
432
|
+
- \`client.appId\` \u2014 the numeric app id this connection is scoped to
|
|
433
|
+
- \`client.request(path, init?)\` \u2014 low-level authenticated fetch (pass \`?app=\${client.appId}\` yourself)
|
|
434
|
+
- \`client.getRecords(appId?, options?)\` \u2014 fetch records; if \`appId\` is omitted, the connection's app id is used
|
|
435
|
+
- \`client.getRecord(appIdOrRecordId, recordId?)\` \u2014 fetch a single record; if called with one argument it is treated as the record id and the connection's app id is used
|
|
324
436
|
|
|
325
437
|
\`\`\`ts
|
|
326
|
-
import {
|
|
438
|
+
import type { Context } from "hono";
|
|
439
|
+
import { connection } from "@squadbase/vite-server/connectors/kintone-api-token";
|
|
327
440
|
|
|
328
441
|
const kintone = connection("<connectionId>");
|
|
329
442
|
|
|
330
|
-
|
|
331
|
-
const
|
|
332
|
-
|
|
443
|
+
export default async function handler(c: Context) {
|
|
444
|
+
const { status = "Active" } = await c.req.json<{ status?: string }>();
|
|
445
|
+
|
|
446
|
+
const { records, totalCount } = await kintone.getRecords(undefined, {
|
|
447
|
+
query: \`status = "\${status}" order by updatedTime desc limit 100\`,
|
|
448
|
+
fields: ["$id", "name", "email", "status", "updatedTime"],
|
|
449
|
+
totalCount: true,
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
return c.json({
|
|
453
|
+
totalCount,
|
|
454
|
+
rows: records.map((r) => ({
|
|
455
|
+
id: r.$id.value,
|
|
456
|
+
name: r.name?.value,
|
|
457
|
+
email: r.email?.value,
|
|
458
|
+
status: r.status?.value,
|
|
459
|
+
updatedTime: r.updatedTime?.value,
|
|
460
|
+
})),
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
\`\`\`
|
|
333
464
|
|
|
334
|
-
|
|
335
|
-
method: "POST",
|
|
336
|
-
body: JSON.stringify({ app: 1, record: { title: { value: "Hello" } } }),
|
|
337
|
-
});
|
|
338
|
-
\`\`\``,
|
|
339
|
-
ja: `### \u30C4\u30FC\u30EB
|
|
465
|
+
### kintone REST API Reference
|
|
340
466
|
|
|
341
|
-
|
|
467
|
+
#### Get App Metadata
|
|
468
|
+
- \`GET app.json\` \u2192 returns { appId, name, description, createdAt, modifiedAt, creator, ... }
|
|
342
469
|
|
|
343
|
-
|
|
470
|
+
#### Get Field Definitions
|
|
471
|
+
- \`GET app/form/fields.json\`
|
|
344
472
|
|
|
345
|
-
####
|
|
346
|
-
- GET
|
|
473
|
+
#### Get Records
|
|
474
|
+
- \`GET records.json?query={query}\`
|
|
475
|
+
- Query example: \`records.json?query=updatedTime > "2024-01-01" order by recordNumber asc limit 100\`
|
|
347
476
|
|
|
348
|
-
|
|
349
|
-
-
|
|
477
|
+
#### Add Record
|
|
478
|
+
- \`POST record.json\`
|
|
479
|
+
- Body: \`{ "record": { "fieldName": { "value": "value" } } }\`
|
|
350
480
|
|
|
351
|
-
|
|
352
|
-
-
|
|
353
|
-
-
|
|
481
|
+
#### kintone Query Syntax
|
|
482
|
+
- Comparison: \`fieldName = "value"\`, \`fieldName > 100\`
|
|
483
|
+
- Operators: \`and\`, \`or\`, \`not\`
|
|
484
|
+
- Sort: \`order by fieldName asc/desc\`
|
|
485
|
+
- Limit: \`limit 100 offset 0\`
|
|
486
|
+
- String: \`like "partial match"\``,
|
|
487
|
+
ja: `### \u30C4\u30FC\u30EB
|
|
354
488
|
|
|
355
|
-
|
|
356
|
-
- POST record.json
|
|
357
|
-
- Body: { "app": 1, "record": { "fieldName": { "value": "value" } } }
|
|
489
|
+
- \`kintone-api-key_request\`: kintone REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30A2\u30D7\u30EA\u306E\u30E1\u30BF\u60C5\u5831\u30FB\u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u8AAD\u307F\u66F8\u304D\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08API\u30C8\u30FC\u30AF\u30F3\uFF09\u3001\u30D9\u30FC\u30B9URL\u3001\u304A\u3088\u3073\u63A5\u7D9A\u306E\u30A2\u30D7\u30EAID\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u5404\u63A5\u7D9A\u306F\u3061\u3087\u3046\u30691\u3064\u306E\u30A2\u30D7\u30EA\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u307E\u3059\uFF08kintone API\u30C8\u30FC\u30AF\u30F3\u306F\u30A2\u30D7\u30EA\u5358\u4F4D\u306E\u305F\u3081\uFF09\u3002
|
|
358
490
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
- \
|
|
362
|
-
- \
|
|
363
|
-
- \
|
|
364
|
-
- \
|
|
491
|
+
### \u30A2\u30D7\u30EA\u30B9\u30B3\u30FC\u30D7\uFF08\u91CD\u8981\uFF09
|
|
492
|
+
|
|
493
|
+
- \u5404\u63A5\u7D9A\u306F1\u3064\u306E\u30A2\u30D7\u30EA\u306B\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u307E\u3059\uFF08"app-id" \u30D1\u30E9\u30E1\u30FC\u30BF\u3067\u8A2D\u5B9A\uFF09\u3002
|
|
494
|
+
- request \u30C4\u30FC\u30EB\u306F\u8A2D\u5B9A\u3055\u308C\u305F\u30A2\u30D7\u30EAID\u3092\u81EA\u52D5\u6CE8\u5165\u3057\u307E\u3059:
|
|
495
|
+
- \u30AF\u30A8\u30EA\u6587\u5B57\u5217: \`records.json\` \u3084 \`app/form/fields.json\` \u7B49\u306E\u30D1\u30B9\u306B \`app=\` \u304C\u7121\u3051\u308C\u3070 \`app=<appId>\` \u3092\u4ED8\u4E0E\u3057\u307E\u3059\u3002\`app.json\`\uFF08\u30A2\u30D7\u30EA\u30E1\u30BF\u60C5\u5831\uFF09\u306E\u5834\u5408\u306F\u4EE3\u308F\u308A\u306B \`id=<appId>\` \u3092\u4ED8\u4E0E\u3057\u307E\u3059\u3002
|
|
496
|
+
- \u30EA\u30AF\u30A8\u30B9\u30C8\u30DC\u30C7\u30A3: POST/PUT \u306E\u30DC\u30C7\u30A3\u306B \`"app"\` \u304C\u7121\u3051\u308C\u3070\u81EA\u52D5\u7684\u306B\u8FFD\u52A0\u3057\u307E\u3059\u3002
|
|
497
|
+
- \u30D1\u30B9\u306B "app=" \u3084\u30DC\u30C7\u30A3\u306B "app" \u3092\u660E\u793A\u3059\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093 \u2014 \u81EA\u52D5\u3067\u51E6\u7406\u3055\u308C\u307E\u3059\u3002
|
|
498
|
+
- \`apps.json\`\uFF08\u5168\u30A2\u30D7\u30EA\u4E00\u89A7\uFF09\u306F API Token \u8A8D\u8A3C\u3067\u306F\u547C\u3073\u51FA\u305B\u307E\u305B\u3093\u3002
|
|
365
499
|
|
|
366
500
|
### Business Logic
|
|
367
501
|
|
|
368
|
-
\u3053\u306E\u30B3\u30CD\u30AF\u30BF\u306E\u30D3\u30B8\u30CD\u30B9\u30ED\u30B8\u30C3\u30AF\u30BF\u30A4\u30D7\u306F "typescript" \u3067\u3059\u3002\
|
|
502
|
+
\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
|
|
369
503
|
|
|
370
|
-
|
|
504
|
+
SDK\uFF08\`connection(connectionId)\` \u3067\u4F5C\u6210\u3057\u305F\u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\uFF09:
|
|
505
|
+
- \`client.appId\` \u2014 \u3053\u306E\u63A5\u7D9A\u304C\u30B9\u30B3\u30FC\u30D7\u3055\u308C\u3066\u3044\u308B\u30A2\u30D7\u30EAID
|
|
506
|
+
- \`client.request(path, init?)\` \u2014 \u4F4E\u30EC\u30D9\u30EB\u306E\u8A8D\u8A3C\u4ED8\u304Dfetch\uFF08\`?app=\${client.appId}\` \u306F\u81EA\u5206\u3067\u4ED8\u3051\u308B\uFF09
|
|
507
|
+
- \`client.getRecords(appId?, options?)\` \u2014 \`appId\` \u3092\u7701\u7565\u3059\u308B\u3068\u63A5\u7D9A\u306E\u30A2\u30D7\u30EAID\u304C\u4F7F\u308F\u308C\u307E\u3059
|
|
508
|
+
- \`client.getRecord(appIdOrRecordId, recordId?)\` \u2014 \u5F15\u65701\u3064\u3067\u547C\u3076\u3068\u305D\u308C\u3092\u30EC\u30B3\u30FC\u30C9ID\u3068\u3057\u3066\u6271\u3044\u3001\u63A5\u7D9A\u306E\u30A2\u30D7\u30EAID\u3092\u4F7F\u3044\u307E\u3059
|
|
371
509
|
|
|
372
510
|
\`\`\`ts
|
|
373
|
-
import {
|
|
511
|
+
import type { Context } from "hono";
|
|
512
|
+
import { connection } from "@squadbase/vite-server/connectors/kintone-api-token";
|
|
374
513
|
|
|
375
514
|
const kintone = connection("<connectionId>");
|
|
376
515
|
|
|
377
|
-
|
|
378
|
-
const
|
|
379
|
-
|
|
516
|
+
export default async function handler(c: Context) {
|
|
517
|
+
const { status = "Active" } = await c.req.json<{ status?: string }>();
|
|
518
|
+
|
|
519
|
+
const { records, totalCount } = await kintone.getRecords(undefined, {
|
|
520
|
+
query: \`status = "\${status}" order by updatedTime desc limit 100\`,
|
|
521
|
+
fields: ["$id", "name", "email", "status", "updatedTime"],
|
|
522
|
+
totalCount: true,
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
return c.json({
|
|
526
|
+
totalCount,
|
|
527
|
+
rows: records.map((r) => ({
|
|
528
|
+
id: r.$id.value,
|
|
529
|
+
name: r.name?.value,
|
|
530
|
+
email: r.email?.value,
|
|
531
|
+
status: r.status?.value,
|
|
532
|
+
updatedTime: r.updatedTime?.value,
|
|
533
|
+
})),
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
\`\`\`
|
|
380
537
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
|
|
538
|
+
### kintone REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
539
|
+
|
|
540
|
+
#### \u30A2\u30D7\u30EA\u30E1\u30BF\u60C5\u5831\u306E\u53D6\u5F97
|
|
541
|
+
- \`GET app.json\` \u2192 { appId, name, description, createdAt, modifiedAt, creator, ... } \u3092\u8FD4\u3059
|
|
542
|
+
|
|
543
|
+
#### \u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u306E\u53D6\u5F97
|
|
544
|
+
- \`GET app/form/fields.json\`
|
|
545
|
+
|
|
546
|
+
#### \u30EC\u30B3\u30FC\u30C9\u306E\u53D6\u5F97
|
|
547
|
+
- \`GET records.json?query={query}\`
|
|
548
|
+
- \u30AF\u30A8\u30EA\u4F8B: \`records.json?query=updatedTime > "2024-01-01" order by recordNumber asc limit 100\`
|
|
549
|
+
|
|
550
|
+
#### \u30EC\u30B3\u30FC\u30C9\u306E\u8FFD\u52A0
|
|
551
|
+
- \`POST record.json\`
|
|
552
|
+
- Body: \`{ "record": { "fieldName": { "value": "value" } } }\`
|
|
553
|
+
|
|
554
|
+
#### kintone \u30AF\u30A8\u30EA\u69CB\u6587
|
|
555
|
+
- \u6BD4\u8F03: \`fieldName = "value"\`, \`fieldName > 100\`
|
|
556
|
+
- \u6F14\u7B97\u5B50: \`and\`, \`or\`, \`not\`
|
|
557
|
+
- \u30BD\u30FC\u30C8: \`order by fieldName asc/desc\`
|
|
558
|
+
- \u5236\u9650: \`limit 100 offset 0\`
|
|
559
|
+
- \u6587\u5B57\u5217: \`like "\u90E8\u5206\u4E00\u81F4"\``
|
|
386
560
|
},
|
|
387
561
|
tools
|
|
388
562
|
});
|
|
@@ -224,21 +224,58 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
224
224
|
* Filters connections by connectorKey internally.
|
|
225
225
|
* Returns tools keyed as `${connectorKey}_${toolName}`.
|
|
226
226
|
*/
|
|
227
|
-
createTools(connections, config) {
|
|
227
|
+
createTools(connections, config, opts) {
|
|
228
228
|
const myConnections = connections.filter(
|
|
229
229
|
(c) => _ConnectorPlugin.deriveKey(c.connector.slug, c.connector.authType) === this.connectorKey
|
|
230
230
|
);
|
|
231
231
|
const result = {};
|
|
232
232
|
for (const t of Object.values(this.tools)) {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
233
|
+
const tool = t.createTool(myConnections, config);
|
|
234
|
+
const originalToModelOutput = tool.toModelOutput;
|
|
235
|
+
result[`${this.connectorKey}_${t.name}`] = {
|
|
236
|
+
...tool,
|
|
237
|
+
toModelOutput: async (options) => {
|
|
238
|
+
if (!originalToModelOutput) {
|
|
239
|
+
return opts.truncateOutput(options.output);
|
|
240
|
+
}
|
|
241
|
+
const modelOutput = await originalToModelOutput(options);
|
|
242
|
+
if (modelOutput.type === "text" || modelOutput.type === "json") {
|
|
243
|
+
return opts.truncateOutput(modelOutput.value);
|
|
244
|
+
}
|
|
245
|
+
return modelOutput;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
237
248
|
}
|
|
238
249
|
return result;
|
|
239
250
|
}
|
|
240
251
|
static deriveKey(slug, authType) {
|
|
241
|
-
|
|
252
|
+
if (authType) return `${slug}-${authType}`;
|
|
253
|
+
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
254
|
+
// user-password
|
|
255
|
+
"postgresql": "user-password",
|
|
256
|
+
"mysql": "user-password",
|
|
257
|
+
"clickhouse": "user-password",
|
|
258
|
+
"kintone": "user-password",
|
|
259
|
+
"squadbase-db": "user-password",
|
|
260
|
+
// service-account
|
|
261
|
+
"snowflake": "service-account",
|
|
262
|
+
"bigquery": "service-account",
|
|
263
|
+
"google-analytics": "service-account",
|
|
264
|
+
"google-calendar": "service-account",
|
|
265
|
+
"aws-athena": "service-account",
|
|
266
|
+
"redshift": "service-account",
|
|
267
|
+
// api-key
|
|
268
|
+
"databricks": "api-key",
|
|
269
|
+
"dbt": "api-key",
|
|
270
|
+
"airtable": "api-key",
|
|
271
|
+
"openai": "api-key",
|
|
272
|
+
"gemini": "api-key",
|
|
273
|
+
"anthropic": "api-key",
|
|
274
|
+
"wix-store": "api-key"
|
|
275
|
+
};
|
|
276
|
+
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
277
|
+
if (fallbackAuthType) return `${slug}-${fallbackAuthType}`;
|
|
278
|
+
return slug;
|
|
242
279
|
}
|
|
243
280
|
};
|
|
244
281
|
|