@squadbase/vite-server 0.1.17-dev.24af54e → 0.1.17-dev.423ee34
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 +4873 -1073
- package/dist/connectors/airtable-oauth.js +78 -11
- package/dist/connectors/airtable.js +74 -11
- package/dist/connectors/amplitude.js +38 -11
- package/dist/connectors/anthropic.js +4 -2
- package/dist/connectors/asana.js +67 -13
- package/dist/connectors/attio.js +60 -16
- package/dist/connectors/aws-billing.js +38 -11
- package/dist/connectors/azure-sql.js +64 -13
- package/dist/connectors/backlog-api-key.js +70 -18
- package/dist/connectors/clickup.js +80 -13
- package/dist/connectors/cosmosdb.js +42 -15
- package/dist/connectors/customerio.js +39 -12
- package/dist/connectors/dbt.js +716 -28
- package/dist/connectors/freshdesk.js +112 -11
- package/dist/connectors/freshsales.js +38 -11
- package/dist/connectors/freshservice.js +38 -11
- package/dist/connectors/gamma.js +47 -20
- package/dist/connectors/gemini.js +4 -2
- package/dist/connectors/github.js +42 -15
- package/dist/connectors/gmail-oauth.js +38 -13
- package/dist/connectors/gmail.js +34 -7
- package/dist/connectors/google-ads.js +38 -11
- package/dist/connectors/google-analytics-oauth.js +182 -28
- package/dist/connectors/google-analytics.js +653 -104
- package/dist/connectors/google-audit-log.js +34 -7
- package/dist/connectors/google-calendar-oauth.js +91 -18
- package/dist/connectors/google-calendar.js +91 -14
- package/dist/connectors/google-docs.js +38 -13
- package/dist/connectors/google-drive.js +60 -13
- package/dist/connectors/google-search-console-oauth.js +156 -20
- package/dist/connectors/google-sheets.js +36 -9
- package/dist/connectors/google-slides.js +38 -13
- package/dist/connectors/grafana.js +75 -13
- package/dist/connectors/hubspot-oauth.js +69 -12
- package/dist/connectors/hubspot.js +55 -12
- package/dist/connectors/influxdb.js +38 -11
- package/dist/connectors/intercom-oauth.js +100 -15
- package/dist/connectors/intercom.js +42 -15
- package/dist/connectors/jdbc.js +36 -9
- package/dist/connectors/jira-api-key.js +98 -14
- package/dist/connectors/kintone-api-token.js +96 -21
- package/dist/connectors/kintone.js +84 -14
- package/dist/connectors/linear.js +84 -15
- package/dist/connectors/linkedin-ads.js +71 -17
- package/dist/connectors/mailchimp-oauth.js +36 -9
- package/dist/connectors/mailchimp.js +36 -9
- package/dist/connectors/meta-ads-oauth.js +63 -17
- package/dist/connectors/meta-ads.js +65 -17
- package/dist/connectors/mixpanel.js +38 -11
- package/dist/connectors/monday.js +39 -12
- package/dist/connectors/mongodb.js +38 -11
- package/dist/connectors/notion-oauth.js +88 -14
- package/dist/connectors/notion.js +90 -14
- package/dist/connectors/openai.js +4 -2
- package/dist/connectors/oracle.js +78 -20
- package/dist/connectors/outlook-oauth.js +48 -23
- package/dist/connectors/powerbi-oauth.js +321 -49
- package/dist/connectors/salesforce.js +72 -12
- package/dist/connectors/semrush.js +374 -52
- package/dist/connectors/sentry.js +66 -13
- package/dist/connectors/shopify-oauth.js +71 -13
- package/dist/connectors/shopify.js +38 -11
- package/dist/connectors/sqlserver.js +64 -13
- package/dist/connectors/stripe-api-key.js +96 -18
- package/dist/connectors/stripe-oauth.js +98 -22
- package/dist/connectors/supabase.js +55 -11
- package/dist/connectors/tableau.js +262 -92
- package/dist/connectors/tiktok-ads.js +67 -19
- package/dist/connectors/wix-store.js +38 -11
- package/dist/connectors/zendesk-oauth.js +83 -15
- package/dist/connectors/zendesk.js +42 -15
- package/dist/index.d.ts +1 -0
- package/dist/index.js +4902 -1077
- package/dist/main.js +4891 -1071
- package/dist/vite-plugin.js +4871 -1071
- package/package.json +1 -1
|
@@ -172,7 +172,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
172
172
|
/**
|
|
173
173
|
* Create tools for connections that belong to this connector.
|
|
174
174
|
* Filters connections by connectorKey internally.
|
|
175
|
-
* Returns tools keyed as
|
|
175
|
+
* Returns tools keyed as `connector_${connectorKey}_${toolName}`.
|
|
176
176
|
*/
|
|
177
177
|
createTools(connections, config, opts) {
|
|
178
178
|
const myConnections = connections.filter(
|
|
@@ -182,7 +182,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
182
182
|
for (const t of Object.values(this.tools)) {
|
|
183
183
|
const tool = t.createTool(myConnections, config);
|
|
184
184
|
const originalToModelOutput = tool.toModelOutput;
|
|
185
|
-
result[
|
|
185
|
+
result[`connector_${this.connectorKey}_${t.name}`] = {
|
|
186
186
|
...tool,
|
|
187
187
|
toModelOutput: async (options) => {
|
|
188
188
|
if (!originalToModelOutput) {
|
|
@@ -238,19 +238,34 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
238
238
|
};
|
|
239
239
|
let state = flow.initialState();
|
|
240
240
|
let answerIdx = 0;
|
|
241
|
+
const pendingParameterUpdates = [];
|
|
241
242
|
for (const step of flow.steps) {
|
|
242
243
|
const ans = ctx.answers[answerIdx];
|
|
243
244
|
if (ans && ans.questionSlug === step.slug) {
|
|
244
245
|
state = step.applyAnswer(state, ans.answer);
|
|
246
|
+
if (step.toParameterUpdates) {
|
|
247
|
+
pendingParameterUpdates.push(...step.toParameterUpdates(state));
|
|
248
|
+
}
|
|
245
249
|
answerIdx += 1;
|
|
246
250
|
continue;
|
|
247
251
|
}
|
|
252
|
+
const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
|
|
248
253
|
if (step.type === "text") {
|
|
254
|
+
if (step.fetchOptions) {
|
|
255
|
+
const options2 = await step.fetchOptions(state, runtime);
|
|
256
|
+
if (options2.length === 0) {
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
249
260
|
return {
|
|
250
261
|
type: "nextQuestion",
|
|
251
262
|
questionSlug: step.slug,
|
|
252
263
|
question: step.question[ctx.language],
|
|
253
|
-
questionType: "text"
|
|
264
|
+
questionType: "text",
|
|
265
|
+
allowFreeText: resolvedAllowFreeText,
|
|
266
|
+
...pendingParameterUpdates.length > 0 && {
|
|
267
|
+
parameterUpdates: pendingParameterUpdates
|
|
268
|
+
}
|
|
254
269
|
};
|
|
255
270
|
}
|
|
256
271
|
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
@@ -262,11 +277,21 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
262
277
|
questionSlug: step.slug,
|
|
263
278
|
question: step.question[ctx.language],
|
|
264
279
|
questionType: step.type,
|
|
265
|
-
options
|
|
280
|
+
options,
|
|
281
|
+
allowFreeText: resolvedAllowFreeText,
|
|
282
|
+
...pendingParameterUpdates.length > 0 && {
|
|
283
|
+
parameterUpdates: pendingParameterUpdates
|
|
284
|
+
}
|
|
266
285
|
};
|
|
267
286
|
}
|
|
268
287
|
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
269
|
-
return {
|
|
288
|
+
return {
|
|
289
|
+
type: "fulfilled",
|
|
290
|
+
dataInvestigationResult,
|
|
291
|
+
...pendingParameterUpdates.length > 0 && {
|
|
292
|
+
parameterUpdates: pendingParameterUpdates
|
|
293
|
+
}
|
|
294
|
+
};
|
|
270
295
|
}
|
|
271
296
|
async function resolveSetupSelection(params) {
|
|
272
297
|
const { selected, allSentinel, fetchAll, limit } = params;
|
|
@@ -297,10 +322,10 @@ function normalizeRequestPath(path2, basePathSegment) {
|
|
|
297
322
|
// ../connectors/src/connectors/google-slides/setup.ts
|
|
298
323
|
var googleSlidesOnboarding = new ConnectorOnboarding({
|
|
299
324
|
dataOverviewInstructions: {
|
|
300
|
-
en: `1. Create a new presentation with
|
|
301
|
-
2. Call
|
|
302
|
-
ja: `1.
|
|
303
|
-
2.
|
|
325
|
+
en: `1. Create a new presentation with connector_google-slides-oauth_request (POST with body { title: "..." }) or use an existing presentation ID.
|
|
326
|
+
2. Call connector_google-slides-oauth_request with GET /{presentationId} to fetch presentation metadata (title, slide count, layout info).`,
|
|
327
|
+
ja: `1. connector_google-slides-oauth_request \u3092 POST\uFF08Body: { title: "..." }\uFF09\u3067\u547C\u3073\u51FA\u3057\u3066\u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3092\u4F5C\u6210\u3059\u308B\u304B\u3001\u65E2\u5B58\u306E\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3ID\u3092\u5229\u7528\u3057\u307E\u3059\u3002
|
|
328
|
+
2. connector_google-slides-oauth_request \u3067 GET /{presentationId} \u3092\u547C\u3073\u51FA\u3057\u3001\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\uFF08\u30BF\u30A4\u30C8\u30EB\u3001\u30B9\u30E9\u30A4\u30C9\u6570\u3001\u30EC\u30A4\u30A2\u30A6\u30C8\u60C5\u5831\uFF09\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002`
|
|
304
329
|
}
|
|
305
330
|
});
|
|
306
331
|
|
|
@@ -536,9 +561,9 @@ var googleSlidesConnector = new ConnectorPlugin({
|
|
|
536
561
|
systemPrompt: {
|
|
537
562
|
en: `### Tools (setup-time only)
|
|
538
563
|
|
|
539
|
-
- \`
|
|
564
|
+
- \`connector_google-slides-oauth_request\`: Call the Google Slides API directly during setup / data overview. Supports read and write operations. Use it to get presentation metadata, slide content, create new presentations, and modify slides. Authentication is configured automatically via OAuth.
|
|
540
565
|
|
|
541
|
-
> **Important**: The \`
|
|
566
|
+
> **Important**: The \`connector_google-slides-oauth_request\` tool is only available at setup time. Inside server-logic handlers, use the SDK (\`connection(id).createPresentation\`, etc.) \u2014 the SDK's fetch is already wired through the OAuth proxy. **Do NOT** hand-roll HTTP calls to \`_sqcore/connections/*/request\` from a handler.
|
|
542
567
|
|
|
543
568
|
### Google Slides API Reference
|
|
544
569
|
|
|
@@ -615,9 +640,9 @@ await slides.batchUpdate(presentationId, [
|
|
|
615
640
|
If a handler test fails with \`Connection proxy is not configured\`, retry \u2014 this usually means the sandbox is still initializing. Do NOT abandon the SDK and construct OAuth proxy URLs manually.`,
|
|
616
641
|
ja: `### \u30C4\u30FC\u30EB\uFF08\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306E\u307F\uFF09
|
|
617
642
|
|
|
618
|
-
- \`
|
|
643
|
+
- \`connector_google-slides-oauth_request\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3084\u30C7\u30FC\u30BF\u6982\u8981\u628A\u63E1\u6642\u306B Google Slides API \u3092\u76F4\u63A5\u53E9\u304F\u30C4\u30FC\u30EB\u3067\u3059\u3002\u8AAD\u307F\u53D6\u308A\u3068\u66F8\u304D\u8FBC\u307F\u306E\u4E21\u65B9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u30FB\u30B9\u30E9\u30A4\u30C9\u5185\u5BB9\u306E\u53D6\u5F97\u3001\u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u4F5C\u6210\u3001\u30B9\u30E9\u30A4\u30C9\u306E\u5909\u66F4\u306A\u3069\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth \u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
|
|
619
644
|
|
|
620
|
-
> **\u91CD\u8981**: \`
|
|
645
|
+
> **\u91CD\u8981**: \`connector_google-slides-oauth_request\` \u306F\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306E\u307F\u5229\u7528\u53EF\u80FD\u3067\u3059\u3002\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u306E\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u5FC5\u305A SDK\uFF08\`connection(id).createPresentation\` \u306A\u3069\uFF09\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002SDK \u306E fetch \u306F OAuth \u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u65E2\u306B\u914D\u7DDA\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u304B\u3089 \`_sqcore/connections/*/request\` \u3092\u624B\u66F8\u304D\u3067\u547C\u3073\u51FA\u3055\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
|
|
621
646
|
|
|
622
647
|
### Google Slides API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
623
648
|
|
|
@@ -16,6 +16,7 @@ var init_parameter_definition = __esm({
|
|
|
16
16
|
type;
|
|
17
17
|
secret;
|
|
18
18
|
required;
|
|
19
|
+
isDeprecated;
|
|
19
20
|
constructor(config) {
|
|
20
21
|
this.slug = config.slug;
|
|
21
22
|
this.name = config.name;
|
|
@@ -24,6 +25,7 @@ var init_parameter_definition = __esm({
|
|
|
24
25
|
this.type = config.type;
|
|
25
26
|
this.secret = config.secret;
|
|
26
27
|
this.required = config.required;
|
|
28
|
+
this.isDeprecated = config.isDeprecated ?? false;
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
29
31
|
* Get the parameter value from a ConnectorConnectionObject.
|
|
@@ -281,7 +283,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
281
283
|
/**
|
|
282
284
|
* Create tools for connections that belong to this connector.
|
|
283
285
|
* Filters connections by connectorKey internally.
|
|
284
|
-
* Returns tools keyed as
|
|
286
|
+
* Returns tools keyed as `connector_${connectorKey}_${toolName}`.
|
|
285
287
|
*/
|
|
286
288
|
createTools(connections, config, opts) {
|
|
287
289
|
const myConnections = connections.filter(
|
|
@@ -291,7 +293,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
291
293
|
for (const t of Object.values(this.tools)) {
|
|
292
294
|
const tool = t.createTool(myConnections, config);
|
|
293
295
|
const originalToModelOutput = tool.toModelOutput;
|
|
294
|
-
result[
|
|
296
|
+
result[`connector_${this.connectorKey}_${t.name}`] = {
|
|
295
297
|
...tool,
|
|
296
298
|
toModelOutput: async (options) => {
|
|
297
299
|
if (!originalToModelOutput) {
|
|
@@ -347,19 +349,34 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
347
349
|
};
|
|
348
350
|
let state = flow.initialState();
|
|
349
351
|
let answerIdx = 0;
|
|
352
|
+
const pendingParameterUpdates = [];
|
|
350
353
|
for (const step of flow.steps) {
|
|
351
354
|
const ans = ctx.answers[answerIdx];
|
|
352
355
|
if (ans && ans.questionSlug === step.slug) {
|
|
353
356
|
state = step.applyAnswer(state, ans.answer);
|
|
357
|
+
if (step.toParameterUpdates) {
|
|
358
|
+
pendingParameterUpdates.push(...step.toParameterUpdates(state));
|
|
359
|
+
}
|
|
354
360
|
answerIdx += 1;
|
|
355
361
|
continue;
|
|
356
362
|
}
|
|
363
|
+
const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
|
|
357
364
|
if (step.type === "text") {
|
|
365
|
+
if (step.fetchOptions) {
|
|
366
|
+
const options2 = await step.fetchOptions(state, runtime);
|
|
367
|
+
if (options2.length === 0) {
|
|
368
|
+
continue;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
358
371
|
return {
|
|
359
372
|
type: "nextQuestion",
|
|
360
373
|
questionSlug: step.slug,
|
|
361
374
|
question: step.question[ctx.language],
|
|
362
|
-
questionType: "text"
|
|
375
|
+
questionType: "text",
|
|
376
|
+
allowFreeText: resolvedAllowFreeText,
|
|
377
|
+
...pendingParameterUpdates.length > 0 && {
|
|
378
|
+
parameterUpdates: pendingParameterUpdates
|
|
379
|
+
}
|
|
363
380
|
};
|
|
364
381
|
}
|
|
365
382
|
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
@@ -371,11 +388,21 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
371
388
|
questionSlug: step.slug,
|
|
372
389
|
question: step.question[ctx.language],
|
|
373
390
|
questionType: step.type,
|
|
374
|
-
options
|
|
391
|
+
options,
|
|
392
|
+
allowFreeText: resolvedAllowFreeText,
|
|
393
|
+
...pendingParameterUpdates.length > 0 && {
|
|
394
|
+
parameterUpdates: pendingParameterUpdates
|
|
395
|
+
}
|
|
375
396
|
};
|
|
376
397
|
}
|
|
377
398
|
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
378
|
-
return {
|
|
399
|
+
return {
|
|
400
|
+
type: "fulfilled",
|
|
401
|
+
dataInvestigationResult,
|
|
402
|
+
...pendingParameterUpdates.length > 0 && {
|
|
403
|
+
parameterUpdates: pendingParameterUpdates
|
|
404
|
+
}
|
|
405
|
+
};
|
|
379
406
|
}
|
|
380
407
|
async function resolveSetupSelection(params) {
|
|
381
408
|
const { selected, allSentinel, fetchAll, limit } = params;
|
|
@@ -396,12 +423,12 @@ var AUTH_TYPES = {
|
|
|
396
423
|
// ../connectors/src/connectors/grafana/setup.ts
|
|
397
424
|
var grafanaOnboarding = new ConnectorOnboarding({
|
|
398
425
|
dataOverviewInstructions: {
|
|
399
|
-
en: `1. Call
|
|
400
|
-
2. Call
|
|
401
|
-
3. For a specific datasource, call
|
|
402
|
-
ja: `1.
|
|
403
|
-
2.
|
|
404
|
-
3. \u7279\u5B9A\u306E\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u306B\u5BFE\u3057\u3066
|
|
426
|
+
en: `1. Call connector_grafana_request with GET /api/datasources to list all configured datasources
|
|
427
|
+
2. Call connector_grafana_request with GET /api/search?type=dash-db&limit=10 to list dashboards
|
|
428
|
+
3. For a specific datasource, call connector_grafana_request with POST /api/ds/query to run a test query`,
|
|
429
|
+
ja: `1. connector_grafana_request \u3067 GET /api/datasources \u3092\u547C\u3073\u51FA\u3057\u3001\u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97
|
|
430
|
+
2. connector_grafana_request \u3067 GET /api/search?type=dash-db&limit=10 \u3092\u547C\u3073\u51FA\u3057\u3001\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u4E00\u89A7\u3092\u53D6\u5F97
|
|
431
|
+
3. \u7279\u5B9A\u306E\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u306B\u5BFE\u3057\u3066 connector_grafana_request \u3067 POST /api/ds/query \u3092\u547C\u3073\u51FA\u3057\u3001\u30C6\u30B9\u30C8\u30AF\u30A8\u30EA\u3092\u5B9F\u884C`
|
|
405
432
|
}
|
|
406
433
|
});
|
|
407
434
|
|
|
@@ -452,6 +479,26 @@ async function listDatasources(params) {
|
|
|
452
479
|
const data = await res.json();
|
|
453
480
|
return data ?? [];
|
|
454
481
|
}
|
|
482
|
+
async function countDashboards(params) {
|
|
483
|
+
try {
|
|
484
|
+
const res = await apiFetch(params, "/api/search?type=dash-db&limit=5000");
|
|
485
|
+
if (!res.ok) return null;
|
|
486
|
+
const data = await res.json();
|
|
487
|
+
return Array.isArray(data) ? data.length : null;
|
|
488
|
+
} catch {
|
|
489
|
+
return null;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
async function countAlertRules(params) {
|
|
493
|
+
try {
|
|
494
|
+
const res = await apiFetch(params, "/api/alert-rules");
|
|
495
|
+
if (!res.ok) return null;
|
|
496
|
+
const data = await res.json();
|
|
497
|
+
return Array.isArray(data) ? data.length : null;
|
|
498
|
+
} catch {
|
|
499
|
+
return null;
|
|
500
|
+
}
|
|
501
|
+
}
|
|
455
502
|
var grafanaSetupFlow = {
|
|
456
503
|
initialState: () => ({}),
|
|
457
504
|
steps: [
|
|
@@ -524,6 +571,21 @@ var grafanaSetupFlow = {
|
|
|
524
571
|
sections.push(`| Default | ${ds.isDefault ? "yes" : "no"} |`);
|
|
525
572
|
sections.push("");
|
|
526
573
|
}
|
|
574
|
+
const [dashboardCount, alertCount] = await Promise.all([
|
|
575
|
+
countDashboards(rt.params),
|
|
576
|
+
countAlertRules(rt.params)
|
|
577
|
+
]);
|
|
578
|
+
if (dashboardCount != null || alertCount != null) {
|
|
579
|
+
sections.push(
|
|
580
|
+
rt.language === "ja" ? "### \u30B3\u30F3\u30C6\u30F3\u30C4\u6982\u8981" : "### Content overview",
|
|
581
|
+
""
|
|
582
|
+
);
|
|
583
|
+
sections.push("| Resource | Count |");
|
|
584
|
+
sections.push("|----------|-------|");
|
|
585
|
+
sections.push(`| Dashboards | ${dashboardCount ?? "-"} |`);
|
|
586
|
+
sections.push(`| Alert rules | ${alertCount ?? "-"} |`);
|
|
587
|
+
sections.push("");
|
|
588
|
+
}
|
|
527
589
|
return sections.join("\n");
|
|
528
590
|
}
|
|
529
591
|
};
|
|
@@ -625,7 +687,7 @@ var grafanaConnector = new ConnectorPlugin({
|
|
|
625
687
|
systemPrompt: {
|
|
626
688
|
en: `### Tools
|
|
627
689
|
|
|
628
|
-
- \`
|
|
690
|
+
- \`connector_grafana_request\`: The only way to call the Grafana HTTP API. Use it to list datasources, search dashboards, execute datasource queries, manage alerts, and read annotations. Authentication is handled automatically via Bearer token. The path must start with \`/\`.
|
|
629
691
|
|
|
630
692
|
### Business Logic
|
|
631
693
|
|
|
@@ -683,7 +745,7 @@ export default async function handler(c: Context) {
|
|
|
683
745
|
- \`GET /api/health\` \u2014 Health check`,
|
|
684
746
|
ja: `### \u30C4\u30FC\u30EB
|
|
685
747
|
|
|
686
|
-
- \`
|
|
748
|
+
- \`connector_grafana_request\`: Grafana HTTP API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u306E\u4E00\u89A7\u53D6\u5F97\u3001\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u691C\u7D22\u3001\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u30AF\u30A8\u30EA\u306E\u5B9F\u884C\u3001\u30A2\u30E9\u30FC\u30C8\u7BA1\u7406\u3001\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u8AAD\u307F\u53D6\u308A\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\u306FBearer\u30C8\u30FC\u30AF\u30F3\u3067\u81EA\u52D5\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\u30D1\u30B9\u306F \`/\` \u3067\u59CB\u3081\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
|
|
687
749
|
|
|
688
750
|
### Business Logic
|
|
689
751
|
|
|
@@ -114,7 +114,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
114
114
|
/**
|
|
115
115
|
* Create tools for connections that belong to this connector.
|
|
116
116
|
* Filters connections by connectorKey internally.
|
|
117
|
-
* Returns tools keyed as
|
|
117
|
+
* Returns tools keyed as `connector_${connectorKey}_${toolName}`.
|
|
118
118
|
*/
|
|
119
119
|
createTools(connections, config, opts) {
|
|
120
120
|
const myConnections = connections.filter(
|
|
@@ -124,7 +124,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
124
124
|
for (const t of Object.values(this.tools)) {
|
|
125
125
|
const tool = t.createTool(myConnections, config);
|
|
126
126
|
const originalToModelOutput = tool.toModelOutput;
|
|
127
|
-
result[
|
|
127
|
+
result[`connector_${this.connectorKey}_${t.name}`] = {
|
|
128
128
|
...tool,
|
|
129
129
|
toModelOutput: async (options) => {
|
|
130
130
|
if (!originalToModelOutput) {
|
|
@@ -180,19 +180,34 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
180
180
|
};
|
|
181
181
|
let state = flow.initialState();
|
|
182
182
|
let answerIdx = 0;
|
|
183
|
+
const pendingParameterUpdates = [];
|
|
183
184
|
for (const step of flow.steps) {
|
|
184
185
|
const ans = ctx.answers[answerIdx];
|
|
185
186
|
if (ans && ans.questionSlug === step.slug) {
|
|
186
187
|
state = step.applyAnswer(state, ans.answer);
|
|
188
|
+
if (step.toParameterUpdates) {
|
|
189
|
+
pendingParameterUpdates.push(...step.toParameterUpdates(state));
|
|
190
|
+
}
|
|
187
191
|
answerIdx += 1;
|
|
188
192
|
continue;
|
|
189
193
|
}
|
|
194
|
+
const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
|
|
190
195
|
if (step.type === "text") {
|
|
196
|
+
if (step.fetchOptions) {
|
|
197
|
+
const options2 = await step.fetchOptions(state, runtime);
|
|
198
|
+
if (options2.length === 0) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
191
202
|
return {
|
|
192
203
|
type: "nextQuestion",
|
|
193
204
|
questionSlug: step.slug,
|
|
194
205
|
question: step.question[ctx.language],
|
|
195
|
-
questionType: "text"
|
|
206
|
+
questionType: "text",
|
|
207
|
+
allowFreeText: resolvedAllowFreeText,
|
|
208
|
+
...pendingParameterUpdates.length > 0 && {
|
|
209
|
+
parameterUpdates: pendingParameterUpdates
|
|
210
|
+
}
|
|
196
211
|
};
|
|
197
212
|
}
|
|
198
213
|
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
@@ -204,11 +219,21 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
204
219
|
questionSlug: step.slug,
|
|
205
220
|
question: step.question[ctx.language],
|
|
206
221
|
questionType: step.type,
|
|
207
|
-
options
|
|
222
|
+
options,
|
|
223
|
+
allowFreeText: resolvedAllowFreeText,
|
|
224
|
+
...pendingParameterUpdates.length > 0 && {
|
|
225
|
+
parameterUpdates: pendingParameterUpdates
|
|
226
|
+
}
|
|
208
227
|
};
|
|
209
228
|
}
|
|
210
229
|
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
211
|
-
return {
|
|
230
|
+
return {
|
|
231
|
+
type: "fulfilled",
|
|
232
|
+
dataInvestigationResult,
|
|
233
|
+
...pendingParameterUpdates.length > 0 && {
|
|
234
|
+
parameterUpdates: pendingParameterUpdates
|
|
235
|
+
}
|
|
236
|
+
};
|
|
212
237
|
}
|
|
213
238
|
async function resolveSetupSelection(params) {
|
|
214
239
|
const { selected, allSentinel, fetchAll, limit } = params;
|
|
@@ -367,11 +392,11 @@ var hubspotOnboarding = new ConnectorOnboarding({
|
|
|
367
392
|
- Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
|
|
368
393
|
},
|
|
369
394
|
dataOverviewInstructions: {
|
|
370
|
-
en: `1. Call
|
|
371
|
-
2. Call
|
|
395
|
+
en: `1. Call connector_hubspot-oauth_request with GET /crm/v3/objects/contacts?limit=5 to explore contacts structure
|
|
396
|
+
2. Call connector_hubspot-oauth_request with GET /crm/v3/objects/deals?limit=5 to explore deals structure
|
|
372
397
|
3. Explore other object types (companies, etc.) as needed to understand available data`,
|
|
373
|
-
ja: `1.
|
|
374
|
-
2.
|
|
398
|
+
ja: `1. connector_hubspot-oauth_request \u3067 GET /crm/v3/objects/contacts?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
|
|
399
|
+
2. connector_hubspot-oauth_request \u3067 GET /crm/v3/objects/deals?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u53D6\u5F15\u306E\u69CB\u9020\u3092\u78BA\u8A8D
|
|
375
400
|
3. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30BF\u30A4\u30D7\uFF08\u4F01\u696D\u306A\u3069\uFF09\u3092\u63A2\u7D22\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30FC\u30BF\u3092\u628A\u63E1`
|
|
376
401
|
}
|
|
377
402
|
});
|
|
@@ -409,6 +434,19 @@ async function listProperties(proxyFetch, objectType) {
|
|
|
409
434
|
const data = await res.json();
|
|
410
435
|
return data.results ?? [];
|
|
411
436
|
}
|
|
437
|
+
async function fetchObjectCount(proxyFetch, objectType) {
|
|
438
|
+
try {
|
|
439
|
+
const res = await apiFetch(
|
|
440
|
+
proxyFetch,
|
|
441
|
+
`/crm/v3/objects/${objectType}?limit=1`
|
|
442
|
+
);
|
|
443
|
+
if (!res.ok) return null;
|
|
444
|
+
const data = await res.json();
|
|
445
|
+
return typeof data.total === "number" ? data.total : null;
|
|
446
|
+
} catch {
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
412
450
|
var hubspotOauthSetupFlow = {
|
|
413
451
|
initialState: () => ({}),
|
|
414
452
|
steps: [
|
|
@@ -439,8 +477,27 @@ var hubspotOauthSetupFlow = {
|
|
|
439
477
|
limit: HUBSPOT_SETUP_MAX_OBJECT_TYPES
|
|
440
478
|
});
|
|
441
479
|
const sections = ["## HubSpot", ""];
|
|
480
|
+
const countByType = /* @__PURE__ */ new Map();
|
|
481
|
+
for (const objectType of targetObjectTypes) {
|
|
482
|
+
countByType.set(
|
|
483
|
+
objectType,
|
|
484
|
+
await fetchObjectCount(rt.config.proxyFetch, objectType)
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
sections.push("### Record counts", "");
|
|
488
|
+
sections.push("| Object type | Record count |");
|
|
489
|
+
sections.push("|-------------|-------------|");
|
|
490
|
+
for (const objectType of targetObjectTypes) {
|
|
491
|
+
const count = countByType.get(objectType);
|
|
492
|
+
sections.push(
|
|
493
|
+
`| ${objectType} | ${count == null ? "-" : count.toLocaleString()} |`
|
|
494
|
+
);
|
|
495
|
+
}
|
|
496
|
+
sections.push("");
|
|
442
497
|
for (const objectType of targetObjectTypes) {
|
|
443
|
-
|
|
498
|
+
const count = countByType.get(objectType);
|
|
499
|
+
const countLabel = count == null ? "" : ` (${count.toLocaleString()} records)`;
|
|
500
|
+
sections.push(`### Object: ${objectType}${countLabel}`, "");
|
|
444
501
|
const props = await listProperties(rt.config.proxyFetch, objectType);
|
|
445
502
|
const limited = props.slice(0, HUBSPOT_SETUP_MAX_PROPERTIES);
|
|
446
503
|
sections.push("| Property | Type | Label |");
|
|
@@ -490,7 +547,7 @@ var hubspotOauthConnector = new ConnectorPlugin({
|
|
|
490
547
|
systemPrompt: {
|
|
491
548
|
en: `### Tools
|
|
492
549
|
|
|
493
|
-
- \`
|
|
550
|
+
- \`connector_hubspot-oauth_request\`: The only way to call the HubSpot API. Use it to query contacts, deals, companies, and other CRM objects. Authentication is configured automatically via OAuth. HubSpot uses cursor-based pagination with the \`after\` parameter from \`paging.next.after\` in the response.
|
|
494
551
|
|
|
495
552
|
### HubSpot API Reference
|
|
496
553
|
|
|
@@ -535,7 +592,7 @@ const data = await res.json();
|
|
|
535
592
|
\`\`\``,
|
|
536
593
|
ja: `### \u30C4\u30FC\u30EB
|
|
537
594
|
|
|
538
|
-
- \`
|
|
595
|
+
- \`connector_hubspot-oauth_request\`: HubSpot API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u53D6\u5F15\u3001\u4F1A\u793E\u3001\u305D\u306E\u4ED6\u306ECRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002HubSpot\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`paging.next.after\` \u304B\u3089\u306E \`after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
|
|
539
596
|
|
|
540
597
|
### HubSpot API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
|
|
541
598
|
|
|
@@ -16,6 +16,7 @@ var init_parameter_definition = __esm({
|
|
|
16
16
|
type;
|
|
17
17
|
secret;
|
|
18
18
|
required;
|
|
19
|
+
isDeprecated;
|
|
19
20
|
constructor(config) {
|
|
20
21
|
this.slug = config.slug;
|
|
21
22
|
this.name = config.name;
|
|
@@ -24,6 +25,7 @@ var init_parameter_definition = __esm({
|
|
|
24
25
|
this.type = config.type;
|
|
25
26
|
this.secret = config.secret;
|
|
26
27
|
this.required = config.required;
|
|
28
|
+
this.isDeprecated = config.isDeprecated ?? false;
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
29
31
|
* Get the parameter value from a ConnectorConnectionObject.
|
|
@@ -255,7 +257,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
255
257
|
/**
|
|
256
258
|
* Create tools for connections that belong to this connector.
|
|
257
259
|
* Filters connections by connectorKey internally.
|
|
258
|
-
* Returns tools keyed as
|
|
260
|
+
* Returns tools keyed as `connector_${connectorKey}_${toolName}`.
|
|
259
261
|
*/
|
|
260
262
|
createTools(connections, config, opts) {
|
|
261
263
|
const myConnections = connections.filter(
|
|
@@ -265,7 +267,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
265
267
|
for (const t of Object.values(this.tools)) {
|
|
266
268
|
const tool = t.createTool(myConnections, config);
|
|
267
269
|
const originalToModelOutput = tool.toModelOutput;
|
|
268
|
-
result[
|
|
270
|
+
result[`connector_${this.connectorKey}_${t.name}`] = {
|
|
269
271
|
...tool,
|
|
270
272
|
toModelOutput: async (options) => {
|
|
271
273
|
if (!originalToModelOutput) {
|
|
@@ -321,19 +323,34 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
321
323
|
};
|
|
322
324
|
let state = flow.initialState();
|
|
323
325
|
let answerIdx = 0;
|
|
326
|
+
const pendingParameterUpdates = [];
|
|
324
327
|
for (const step of flow.steps) {
|
|
325
328
|
const ans = ctx.answers[answerIdx];
|
|
326
329
|
if (ans && ans.questionSlug === step.slug) {
|
|
327
330
|
state = step.applyAnswer(state, ans.answer);
|
|
331
|
+
if (step.toParameterUpdates) {
|
|
332
|
+
pendingParameterUpdates.push(...step.toParameterUpdates(state));
|
|
333
|
+
}
|
|
328
334
|
answerIdx += 1;
|
|
329
335
|
continue;
|
|
330
336
|
}
|
|
337
|
+
const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
|
|
331
338
|
if (step.type === "text") {
|
|
339
|
+
if (step.fetchOptions) {
|
|
340
|
+
const options2 = await step.fetchOptions(state, runtime);
|
|
341
|
+
if (options2.length === 0) {
|
|
342
|
+
continue;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
332
345
|
return {
|
|
333
346
|
type: "nextQuestion",
|
|
334
347
|
questionSlug: step.slug,
|
|
335
348
|
question: step.question[ctx.language],
|
|
336
|
-
questionType: "text"
|
|
349
|
+
questionType: "text",
|
|
350
|
+
allowFreeText: resolvedAllowFreeText,
|
|
351
|
+
...pendingParameterUpdates.length > 0 && {
|
|
352
|
+
parameterUpdates: pendingParameterUpdates
|
|
353
|
+
}
|
|
337
354
|
};
|
|
338
355
|
}
|
|
339
356
|
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
@@ -345,11 +362,21 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
345
362
|
questionSlug: step.slug,
|
|
346
363
|
question: step.question[ctx.language],
|
|
347
364
|
questionType: step.type,
|
|
348
|
-
options
|
|
365
|
+
options,
|
|
366
|
+
allowFreeText: resolvedAllowFreeText,
|
|
367
|
+
...pendingParameterUpdates.length > 0 && {
|
|
368
|
+
parameterUpdates: pendingParameterUpdates
|
|
369
|
+
}
|
|
349
370
|
};
|
|
350
371
|
}
|
|
351
372
|
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
352
|
-
return {
|
|
373
|
+
return {
|
|
374
|
+
type: "fulfilled",
|
|
375
|
+
dataInvestigationResult,
|
|
376
|
+
...pendingParameterUpdates.length > 0 && {
|
|
377
|
+
parameterUpdates: pendingParameterUpdates
|
|
378
|
+
}
|
|
379
|
+
};
|
|
353
380
|
}
|
|
354
381
|
async function resolveSetupSelection(params) {
|
|
355
382
|
const { selected, allSentinel, fetchAll, limit } = params;
|
|
@@ -370,11 +397,11 @@ var AUTH_TYPES = {
|
|
|
370
397
|
// ../connectors/src/connectors/hubspot/setup.ts
|
|
371
398
|
var hubspotOnboarding = new ConnectorOnboarding({
|
|
372
399
|
dataOverviewInstructions: {
|
|
373
|
-
en: `1. Call
|
|
374
|
-
2. Call
|
|
400
|
+
en: `1. Call connector_hubspot_request with GET /crm/v3/objects/contacts?limit=5 to explore contacts structure
|
|
401
|
+
2. Call connector_hubspot_request with GET /crm/v3/objects/deals?limit=5 to explore deals structure
|
|
375
402
|
3. Explore other object types (companies, tickets, etc.) as needed to understand available data`,
|
|
376
|
-
ja: `1.
|
|
377
|
-
2.
|
|
403
|
+
ja: `1. connector_hubspot_request \u3067 GET /crm/v3/objects/contacts?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
|
|
404
|
+
2. connector_hubspot_request \u3067 GET /crm/v3/objects/deals?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u53D6\u5F15\u306E\u69CB\u9020\u3092\u78BA\u8A8D
|
|
378
405
|
3. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30BF\u30A4\u30D7\uFF08\u4F01\u696D\u3001\u30C1\u30B1\u30C3\u30C8\u306A\u3069\uFF09\u3092\u63A2\u7D22\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30FC\u30BF\u3092\u628A\u63E1`
|
|
379
406
|
}
|
|
380
407
|
});
|
|
@@ -408,6 +435,20 @@ var HUBSPOT_OBJECT_TYPES = [
|
|
|
408
435
|
{ value: "meetings", label: "Meetings" },
|
|
409
436
|
{ value: "tasks", label: "Tasks" }
|
|
410
437
|
];
|
|
438
|
+
async function countObjects(params, objectType) {
|
|
439
|
+
try {
|
|
440
|
+
const res = await apiFetch(params, `/crm/v3/objects/${objectType}/search`, {
|
|
441
|
+
method: "POST",
|
|
442
|
+
headers: { "Content-Type": "application/json" },
|
|
443
|
+
body: JSON.stringify({ limit: 1 })
|
|
444
|
+
});
|
|
445
|
+
if (!res.ok) return null;
|
|
446
|
+
const data = await res.json();
|
|
447
|
+
return typeof data.total === "number" ? data.total : null;
|
|
448
|
+
} catch {
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
411
452
|
async function listProperties(params, objectType) {
|
|
412
453
|
const res = await apiFetch(params, `/crm/v3/properties/${objectType}`);
|
|
413
454
|
if (!res.ok) {
|
|
@@ -452,7 +493,9 @@ var hubspotSetupFlow = {
|
|
|
452
493
|
});
|
|
453
494
|
const sections = ["## HubSpot", ""];
|
|
454
495
|
for (const objectType of targetObjectTypes) {
|
|
455
|
-
|
|
496
|
+
const count = await countObjects(rt.params, objectType);
|
|
497
|
+
const heading = count != null ? `### Object: ${objectType} (${count.toLocaleString()} records)` : `### Object: ${objectType}`;
|
|
498
|
+
sections.push(heading, "");
|
|
456
499
|
const props = await listProperties(rt.params, objectType);
|
|
457
500
|
const limited = props.slice(0, HUBSPOT_SETUP_MAX_PROPERTIES);
|
|
458
501
|
sections.push("| Property | Type | Label |");
|
|
@@ -568,7 +611,7 @@ var hubspotConnector = new ConnectorPlugin({
|
|
|
568
611
|
systemPrompt: {
|
|
569
612
|
en: `### Tools
|
|
570
613
|
|
|
571
|
-
- \`
|
|
614
|
+
- \`connector_hubspot_request\`: The only way to call the HubSpot API. Use it to query contacts, deals, companies, tickets, and other CRM objects. Authentication (Bearer token) is configured automatically. HubSpot uses cursor-based pagination with the \`after\` parameter from \`paging.next.after\` in the response. Use the search endpoint for complex queries with filters.
|
|
572
615
|
|
|
573
616
|
### Business Logic
|
|
574
617
|
|
|
@@ -634,7 +677,7 @@ export default async function handler(c: Context) {
|
|
|
634
677
|
- \`after\` \u2014 Pagination offset`,
|
|
635
678
|
ja: `### \u30C4\u30FC\u30EB
|
|
636
679
|
|
|
637
|
-
- \`
|
|
680
|
+
- \`connector_hubspot_request\`: HubSpot API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u53D6\u5F15\u3001\u4F1A\u793E\u3001\u30C1\u30B1\u30C3\u30C8\u3001\u305D\u306E\u4ED6\u306ECRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002HubSpot\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`paging.next.after\` \u304B\u3089\u306E \`after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\u8907\u96D1\u306A\u30AF\u30A8\u30EA\u306B\u306F\u30D5\u30A3\u30EB\u30BF\u4ED8\u304D\u306Esearch\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
|
|
638
681
|
|
|
639
682
|
### Business Logic
|
|
640
683
|
|