@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
|
@@ -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.
|
|
@@ -295,7 +297,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
295
297
|
/**
|
|
296
298
|
* Create tools for connections that belong to this connector.
|
|
297
299
|
* Filters connections by connectorKey internally.
|
|
298
|
-
* Returns tools keyed as
|
|
300
|
+
* Returns tools keyed as `connector_${connectorKey}_${toolName}`.
|
|
299
301
|
*/
|
|
300
302
|
createTools(connections, config, opts) {
|
|
301
303
|
const myConnections = connections.filter(
|
|
@@ -305,7 +307,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
305
307
|
for (const t of Object.values(this.tools)) {
|
|
306
308
|
const tool = t.createTool(myConnections, config);
|
|
307
309
|
const originalToModelOutput = tool.toModelOutput;
|
|
308
|
-
result[
|
|
310
|
+
result[`connector_${this.connectorKey}_${t.name}`] = {
|
|
309
311
|
...tool,
|
|
310
312
|
toModelOutput: async (options) => {
|
|
311
313
|
if (!originalToModelOutput) {
|
|
@@ -361,19 +363,34 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
361
363
|
};
|
|
362
364
|
let state = flow.initialState();
|
|
363
365
|
let answerIdx = 0;
|
|
366
|
+
const pendingParameterUpdates = [];
|
|
364
367
|
for (const step of flow.steps) {
|
|
365
368
|
const ans = ctx.answers[answerIdx];
|
|
366
369
|
if (ans && ans.questionSlug === step.slug) {
|
|
367
370
|
state = step.applyAnswer(state, ans.answer);
|
|
371
|
+
if (step.toParameterUpdates) {
|
|
372
|
+
pendingParameterUpdates.push(...step.toParameterUpdates(state));
|
|
373
|
+
}
|
|
368
374
|
answerIdx += 1;
|
|
369
375
|
continue;
|
|
370
376
|
}
|
|
377
|
+
const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
|
|
371
378
|
if (step.type === "text") {
|
|
379
|
+
if (step.fetchOptions) {
|
|
380
|
+
const options2 = await step.fetchOptions(state, runtime);
|
|
381
|
+
if (options2.length === 0) {
|
|
382
|
+
continue;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
372
385
|
return {
|
|
373
386
|
type: "nextQuestion",
|
|
374
387
|
questionSlug: step.slug,
|
|
375
388
|
question: step.question[ctx.language],
|
|
376
|
-
questionType: "text"
|
|
389
|
+
questionType: "text",
|
|
390
|
+
allowFreeText: resolvedAllowFreeText,
|
|
391
|
+
...pendingParameterUpdates.length > 0 && {
|
|
392
|
+
parameterUpdates: pendingParameterUpdates
|
|
393
|
+
}
|
|
377
394
|
};
|
|
378
395
|
}
|
|
379
396
|
const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
|
|
@@ -385,11 +402,21 @@ async function runSetupFlow(flow, params, ctx, config) {
|
|
|
385
402
|
questionSlug: step.slug,
|
|
386
403
|
question: step.question[ctx.language],
|
|
387
404
|
questionType: step.type,
|
|
388
|
-
options
|
|
405
|
+
options,
|
|
406
|
+
allowFreeText: resolvedAllowFreeText,
|
|
407
|
+
...pendingParameterUpdates.length > 0 && {
|
|
408
|
+
parameterUpdates: pendingParameterUpdates
|
|
409
|
+
}
|
|
389
410
|
};
|
|
390
411
|
}
|
|
391
412
|
const dataInvestigationResult = await flow.finalize(state, runtime);
|
|
392
|
-
return {
|
|
413
|
+
return {
|
|
414
|
+
type: "fulfilled",
|
|
415
|
+
dataInvestigationResult,
|
|
416
|
+
...pendingParameterUpdates.length > 0 && {
|
|
417
|
+
parameterUpdates: pendingParameterUpdates
|
|
418
|
+
}
|
|
419
|
+
};
|
|
393
420
|
}
|
|
394
421
|
async function resolveSetupSelection(params) {
|
|
395
422
|
const { selected, allSentinel, fetchAll, limit } = params;
|
|
@@ -593,7 +620,8 @@ var semrushOnboarding = new ConnectorOnboarding({
|
|
|
593
620
|
});
|
|
594
621
|
|
|
595
622
|
// ../connectors/src/connectors/semrush/utils.ts
|
|
596
|
-
var
|
|
623
|
+
var BASE_URL3 = "https://api.semrush.com";
|
|
624
|
+
var PROJECTS_BASE_URL = `${BASE_URL3}/management/v1`;
|
|
597
625
|
function projectsApiFetch(params, path2, init) {
|
|
598
626
|
const apiKey = params[parameters.apiKey.slug];
|
|
599
627
|
if (!apiKey) {
|
|
@@ -610,10 +638,103 @@ function projectsApiFetch(params, path2, init) {
|
|
|
610
638
|
if (!headers.has("Accept")) headers.set("Accept", "application/json");
|
|
611
639
|
return fetch(url.toString(), { ...init, headers });
|
|
612
640
|
}
|
|
641
|
+
async function reportFetch(params, query) {
|
|
642
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
643
|
+
if (!apiKey) {
|
|
644
|
+
throw new Error(
|
|
645
|
+
`semrush: missing required parameter: ${parameters.apiKey.slug}`
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
const url = new URL(`${BASE_URL3}/`);
|
|
649
|
+
for (const [k, v] of Object.entries(query)) {
|
|
650
|
+
url.searchParams.set(k, v);
|
|
651
|
+
}
|
|
652
|
+
url.searchParams.set("key", apiKey);
|
|
653
|
+
const res = await fetch(url.toString());
|
|
654
|
+
const text = await res.text();
|
|
655
|
+
if (text.startsWith("ERROR ")) throw new Error(text.trim());
|
|
656
|
+
return parseSemicolonCsv(text);
|
|
657
|
+
}
|
|
658
|
+
async function backlinksFetch(params, query) {
|
|
659
|
+
const apiKey = params[parameters.apiKey.slug];
|
|
660
|
+
if (!apiKey) {
|
|
661
|
+
throw new Error(
|
|
662
|
+
`semrush: missing required parameter: ${parameters.apiKey.slug}`
|
|
663
|
+
);
|
|
664
|
+
}
|
|
665
|
+
const url = new URL(`${BASE_URL3}/analytics/v1/`);
|
|
666
|
+
for (const [k, v] of Object.entries(query)) {
|
|
667
|
+
url.searchParams.set(k, v);
|
|
668
|
+
}
|
|
669
|
+
url.searchParams.set("key", apiKey);
|
|
670
|
+
const res = await fetch(url.toString());
|
|
671
|
+
const text = await res.text();
|
|
672
|
+
if (text.startsWith("ERROR ")) throw new Error(text.trim());
|
|
673
|
+
return parseSemicolonCsv(text);
|
|
674
|
+
}
|
|
675
|
+
function parseSemicolonCsv(raw) {
|
|
676
|
+
const lines = raw.trim().split("\n").filter(Boolean);
|
|
677
|
+
if (lines.length === 0) return { columns: [], rows: [] };
|
|
678
|
+
const columns = lines[0].split(";");
|
|
679
|
+
const rows = lines.slice(1).map((line) => {
|
|
680
|
+
const values = line.split(";");
|
|
681
|
+
const row = {};
|
|
682
|
+
for (let i = 0; i < columns.length; i++) {
|
|
683
|
+
row[columns[i]] = values[i] ?? "";
|
|
684
|
+
}
|
|
685
|
+
return row;
|
|
686
|
+
});
|
|
687
|
+
return { columns, rows };
|
|
688
|
+
}
|
|
613
689
|
|
|
614
690
|
// ../connectors/src/connectors/semrush/setup-flow.ts
|
|
615
691
|
var ALL_PROJECTS = "__ALL_PROJECTS__";
|
|
616
692
|
var SEMRUSH_SETUP_MAX_PROJECTS = 10;
|
|
693
|
+
var SEMRUSH_DATABASES = [
|
|
694
|
+
{ value: "us", label: "United States" },
|
|
695
|
+
{ value: "uk", label: "United Kingdom" },
|
|
696
|
+
{ value: "ca", label: "Canada" },
|
|
697
|
+
{ value: "au", label: "Australia" },
|
|
698
|
+
{ value: "de", label: "Germany" },
|
|
699
|
+
{ value: "fr", label: "France" },
|
|
700
|
+
{ value: "es", label: "Spain" },
|
|
701
|
+
{ value: "it", label: "Italy" },
|
|
702
|
+
{ value: "br", label: "Brazil" },
|
|
703
|
+
{ value: "jp", label: "Japan" },
|
|
704
|
+
{ value: "in", label: "India" },
|
|
705
|
+
{ value: "ru", label: "Russia" },
|
|
706
|
+
{ value: "nl", label: "Netherlands" },
|
|
707
|
+
{ value: "se", label: "Sweden" },
|
|
708
|
+
{ value: "mx", label: "Mexico" },
|
|
709
|
+
{ value: "kr", label: "South Korea" },
|
|
710
|
+
{ value: "sg", label: "Singapore" },
|
|
711
|
+
{ value: "hk", label: "Hong Kong" },
|
|
712
|
+
{ value: "tw", label: "Taiwan" }
|
|
713
|
+
];
|
|
714
|
+
var REPORT_TYPE_LABELS = {
|
|
715
|
+
domain_overview: {
|
|
716
|
+
en: "Domain Overview (rank, traffic, keyword count)",
|
|
717
|
+
ja: "Domain Overview (\u30E9\u30F3\u30AF\u30FB\u30C8\u30E9\u30D5\u30A3\u30C3\u30AF\u30FB\u30AD\u30FC\u30EF\u30FC\u30C9\u6570)"
|
|
718
|
+
},
|
|
719
|
+
organic_search: {
|
|
720
|
+
en: "Organic Search (top organic keywords)",
|
|
721
|
+
ja: "Organic Search (\u4E0A\u4F4D\u30AA\u30FC\u30AC\u30CB\u30C3\u30AF\u30AD\u30FC\u30EF\u30FC\u30C9)"
|
|
722
|
+
},
|
|
723
|
+
paid_search: {
|
|
724
|
+
en: "Paid Search (top paid keywords)",
|
|
725
|
+
ja: "Paid Search (\u4E0A\u4F4D\u6709\u6599\u30AD\u30FC\u30EF\u30FC\u30C9)"
|
|
726
|
+
},
|
|
727
|
+
backlinks: {
|
|
728
|
+
en: "Backlinks (referring domains, backlink count)",
|
|
729
|
+
ja: "Backlinks (\u53C2\u7167\u30C9\u30E1\u30A4\u30F3\u30FB\u88AB\u30EA\u30F3\u30AF\u6570)"
|
|
730
|
+
}
|
|
731
|
+
};
|
|
732
|
+
var REPORT_TYPE_VALUES = [
|
|
733
|
+
"domain_overview",
|
|
734
|
+
"organic_search",
|
|
735
|
+
"paid_search",
|
|
736
|
+
"backlinks"
|
|
737
|
+
];
|
|
617
738
|
function projectId(p) {
|
|
618
739
|
const raw = p.project_id ?? p.id;
|
|
619
740
|
return raw == null ? "" : String(raw);
|
|
@@ -622,7 +743,7 @@ function projectName(p) {
|
|
|
622
743
|
return p.project_name ?? p.name ?? p.domain ?? p.url ?? projectId(p);
|
|
623
744
|
}
|
|
624
745
|
function projectDomain(p) {
|
|
625
|
-
return p.domain ?? p.url ?? "";
|
|
746
|
+
return p.domain ?? p.domain_unicode ?? p.url ?? "";
|
|
626
747
|
}
|
|
627
748
|
function projectCreatedAt(p) {
|
|
628
749
|
return p.created_at ?? p.date_created ?? "";
|
|
@@ -630,13 +751,19 @@ function projectCreatedAt(p) {
|
|
|
630
751
|
async function fetchProjects(params) {
|
|
631
752
|
let res;
|
|
632
753
|
try {
|
|
633
|
-
res = await projectsApiFetch(params, "/projects
|
|
754
|
+
res = await projectsApiFetch(params, "/projects");
|
|
634
755
|
} catch (err) {
|
|
635
|
-
return {
|
|
756
|
+
return {
|
|
757
|
+
ok: false,
|
|
758
|
+
error: err instanceof Error ? err.message : String(err)
|
|
759
|
+
};
|
|
636
760
|
}
|
|
637
761
|
if (!res.ok) {
|
|
638
762
|
const body2 = await res.text().catch(() => res.statusText);
|
|
639
|
-
return {
|
|
763
|
+
return {
|
|
764
|
+
ok: false,
|
|
765
|
+
error: `HTTP ${res.status} ${body2 || res.statusText}`
|
|
766
|
+
};
|
|
640
767
|
}
|
|
641
768
|
let body;
|
|
642
769
|
try {
|
|
@@ -650,9 +777,171 @@ async function fetchProjects(params) {
|
|
|
650
777
|
const projects = Array.isArray(body) ? body : Array.isArray(body?.projects) ? body.projects : Array.isArray(body?.data) ? body.data : [];
|
|
651
778
|
return { ok: true, projects };
|
|
652
779
|
}
|
|
780
|
+
function formatNumber(n) {
|
|
781
|
+
return n.toLocaleString("en-US");
|
|
782
|
+
}
|
|
783
|
+
async function fetchDomainOverview(params, domain, database) {
|
|
784
|
+
const sections = [];
|
|
785
|
+
try {
|
|
786
|
+
const report = await reportFetch(params, {
|
|
787
|
+
type: "domain_ranks",
|
|
788
|
+
domain,
|
|
789
|
+
database
|
|
790
|
+
});
|
|
791
|
+
if (report.rows.length === 0) {
|
|
792
|
+
sections.push("_No data found for this domain._", "");
|
|
793
|
+
return sections;
|
|
794
|
+
}
|
|
795
|
+
const row = report.rows[0];
|
|
796
|
+
sections.push("| Metric | Value |");
|
|
797
|
+
sections.push("|--------|-------|");
|
|
798
|
+
sections.push(
|
|
799
|
+
`| Rank | ${row["Rank"] ?? "-"} |`,
|
|
800
|
+
`| Organic Keywords | ${formatNumber(Number(row["Organic Keywords"]) || 0)} |`,
|
|
801
|
+
`| Organic Traffic | ${formatNumber(Number(row["Organic Traffic"]) || 0)} |`,
|
|
802
|
+
`| Organic Cost | $${formatNumber(Number(row["Organic Cost"]) || 0)} |`,
|
|
803
|
+
`| Adwords Keywords | ${formatNumber(Number(row["Adwords Keywords"]) || 0)} |`,
|
|
804
|
+
`| Adwords Traffic | ${formatNumber(Number(row["Adwords Traffic"]) || 0)} |`,
|
|
805
|
+
`| Adwords Cost | $${formatNumber(Number(row["Adwords Cost"]) || 0)} |`
|
|
806
|
+
);
|
|
807
|
+
sections.push("");
|
|
808
|
+
} catch (err) {
|
|
809
|
+
sections.push(
|
|
810
|
+
`_Error: ${err instanceof Error ? err.message : String(err)}_`,
|
|
811
|
+
""
|
|
812
|
+
);
|
|
813
|
+
}
|
|
814
|
+
return sections;
|
|
815
|
+
}
|
|
816
|
+
async function fetchOrganicSearch(params, domain, database) {
|
|
817
|
+
return fetchKeywordReport(params, "domain_organic", domain, database);
|
|
818
|
+
}
|
|
819
|
+
async function fetchPaidSearch(params, domain, database) {
|
|
820
|
+
return fetchKeywordReport(params, "domain_adwords", domain, database);
|
|
821
|
+
}
|
|
822
|
+
async function fetchKeywordReport(params, type, domain, database) {
|
|
823
|
+
const sections = [];
|
|
824
|
+
try {
|
|
825
|
+
const report = await reportFetch(params, {
|
|
826
|
+
type,
|
|
827
|
+
domain,
|
|
828
|
+
database,
|
|
829
|
+
display_limit: "5"
|
|
830
|
+
});
|
|
831
|
+
if (report.rows.length === 0) {
|
|
832
|
+
sections.push("_No data found._", "");
|
|
833
|
+
return sections;
|
|
834
|
+
}
|
|
835
|
+
sections.push(...renderCsvTable(report, 5));
|
|
836
|
+
sections.push("");
|
|
837
|
+
} catch (err) {
|
|
838
|
+
sections.push(
|
|
839
|
+
`_Error: ${err instanceof Error ? err.message : String(err)}_`,
|
|
840
|
+
""
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
return sections;
|
|
844
|
+
}
|
|
845
|
+
async function fetchBacklinks(params, domain) {
|
|
846
|
+
const sections = [];
|
|
847
|
+
try {
|
|
848
|
+
const report = await backlinksFetch(params, {
|
|
849
|
+
type: "backlinks_overview",
|
|
850
|
+
target: domain,
|
|
851
|
+
target_type: "root_domain"
|
|
852
|
+
});
|
|
853
|
+
if (report.rows.length === 0) {
|
|
854
|
+
sections.push("_No backlink data found._", "");
|
|
855
|
+
return sections;
|
|
856
|
+
}
|
|
857
|
+
const row = report.rows[0];
|
|
858
|
+
sections.push("| Metric | Value |");
|
|
859
|
+
sections.push("|--------|-------|");
|
|
860
|
+
for (const col of report.columns) {
|
|
861
|
+
sections.push(`| ${col} | ${formatNumber(Number(row[col]) || 0)} |`);
|
|
862
|
+
}
|
|
863
|
+
sections.push("");
|
|
864
|
+
} catch (err) {
|
|
865
|
+
sections.push(
|
|
866
|
+
`_Error: ${err instanceof Error ? err.message : String(err)}_`,
|
|
867
|
+
""
|
|
868
|
+
);
|
|
869
|
+
}
|
|
870
|
+
return sections;
|
|
871
|
+
}
|
|
872
|
+
function renderCsvTable(report, maxRows) {
|
|
873
|
+
const cols = report.columns;
|
|
874
|
+
const rows = report.rows.slice(0, maxRows);
|
|
875
|
+
const lines = [];
|
|
876
|
+
lines.push(`| ${cols.join(" | ")} |`);
|
|
877
|
+
lines.push(`|${cols.map(() => "---").join("|")}|`);
|
|
878
|
+
for (const row of rows) {
|
|
879
|
+
const cells = cols.map((c) => (row[c] ?? "").replace(/\|/g, "\\|"));
|
|
880
|
+
lines.push(`| ${cells.join(" | ")} |`);
|
|
881
|
+
}
|
|
882
|
+
return lines;
|
|
883
|
+
}
|
|
653
884
|
var semrushSetupFlow = {
|
|
654
885
|
initialState: () => ({}),
|
|
655
886
|
steps: [
|
|
887
|
+
{
|
|
888
|
+
slug: "domain",
|
|
889
|
+
type: "select",
|
|
890
|
+
allowFreeText: true,
|
|
891
|
+
question: {
|
|
892
|
+
ja: "\u5206\u6790\u5BFE\u8C61\u306E\u30C9\u30E1\u30A4\u30F3\u3092\u9078\u629E\u307E\u305F\u306F\u5165\u529B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
893
|
+
en: "Select or enter the domain to analyze"
|
|
894
|
+
},
|
|
895
|
+
async fetchOptions(_state, rt) {
|
|
896
|
+
const result = await fetchProjects(rt.params);
|
|
897
|
+
if (!result.ok || result.projects.length === 0) return [];
|
|
898
|
+
const seen = /* @__PURE__ */ new Set();
|
|
899
|
+
const options = [];
|
|
900
|
+
for (const p of result.projects) {
|
|
901
|
+
const d = projectDomain(p);
|
|
902
|
+
if (d && !seen.has(d)) {
|
|
903
|
+
seen.add(d);
|
|
904
|
+
options.push({
|
|
905
|
+
value: d,
|
|
906
|
+
label: `${d} (${projectName(p)})`
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
return options;
|
|
911
|
+
},
|
|
912
|
+
applyAnswer: (state, answer) => ({ ...state, domain: answer[0] })
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
slug: "database",
|
|
916
|
+
type: "select",
|
|
917
|
+
allowFreeText: false,
|
|
918
|
+
question: {
|
|
919
|
+
ja: "\u30EA\u30FC\u30B8\u30E7\u30F3\u3092\u9078\u629E\u3057\u3066\u304F\u3060\u3055\u3044\uFF08\u5BFE\u8C61\u30C9\u30E1\u30A4\u30F3\u306E\u4E3B\u8981\u5E02\u5834\uFF09",
|
|
920
|
+
en: "Select the region (primary market for the target domain)"
|
|
921
|
+
},
|
|
922
|
+
async fetchOptions() {
|
|
923
|
+
return SEMRUSH_DATABASES.map((db) => ({
|
|
924
|
+
value: db.value,
|
|
925
|
+
label: `${db.label} (${db.value})`
|
|
926
|
+
}));
|
|
927
|
+
},
|
|
928
|
+
applyAnswer: (state, answer) => ({ ...state, database: answer[0] })
|
|
929
|
+
},
|
|
930
|
+
{
|
|
931
|
+
slug: "reportTypes",
|
|
932
|
+
type: "multiSelect",
|
|
933
|
+
question: {
|
|
934
|
+
ja: "\u63A2\u7D22\u3059\u308B\u30EC\u30DD\u30FC\u30C8\u7A2E\u5225\u3092\u9078\u3093\u3067\u304F\u3060\u3055\u3044\uFF08\u8907\u6570\u9078\u629E\u53EF\uFF09",
|
|
935
|
+
en: "Select report types to explore (multi-select allowed)"
|
|
936
|
+
},
|
|
937
|
+
async fetchOptions(_state, rt) {
|
|
938
|
+
return REPORT_TYPE_VALUES.map((value) => ({
|
|
939
|
+
value,
|
|
940
|
+
label: REPORT_TYPE_LABELS[value][rt.language]
|
|
941
|
+
}));
|
|
942
|
+
},
|
|
943
|
+
applyAnswer: (state, answer) => ({ ...state, reportTypes: answer })
|
|
944
|
+
},
|
|
656
945
|
{
|
|
657
946
|
slug: "projects",
|
|
658
947
|
type: "multiSelect",
|
|
@@ -669,7 +958,9 @@ var semrushSetupFlow = {
|
|
|
669
958
|
const id = projectId(p);
|
|
670
959
|
if (!id) return null;
|
|
671
960
|
return { value: id, label: projectName(p) };
|
|
672
|
-
}).filter(
|
|
961
|
+
}).filter(
|
|
962
|
+
(opt) => opt !== null
|
|
963
|
+
);
|
|
673
964
|
if (options.length === 0) return [];
|
|
674
965
|
return [
|
|
675
966
|
{
|
|
@@ -683,49 +974,80 @@ var semrushSetupFlow = {
|
|
|
683
974
|
}
|
|
684
975
|
],
|
|
685
976
|
async finalize(state, rt) {
|
|
686
|
-
|
|
687
|
-
|
|
977
|
+
if (!state.domain || !state.database || !state.reportTypes) {
|
|
978
|
+
throw new Error("Semrush setup: incomplete state on finalize");
|
|
979
|
+
}
|
|
980
|
+
const domain = state.domain;
|
|
981
|
+
const database = state.database;
|
|
982
|
+
const selected = state.reportTypes.filter(
|
|
983
|
+
(r) => REPORT_TYPE_VALUES.includes(r)
|
|
984
|
+
);
|
|
985
|
+
const sections = [
|
|
986
|
+
"## Semrush",
|
|
987
|
+
"",
|
|
988
|
+
`**Domain:** ${domain}`,
|
|
989
|
+
`**Region:** ${database}`,
|
|
990
|
+
""
|
|
991
|
+
];
|
|
992
|
+
for (const reportType of selected) {
|
|
688
993
|
sections.push(
|
|
689
|
-
|
|
994
|
+
`### ${REPORT_TYPE_LABELS[reportType].en}`,
|
|
690
995
|
""
|
|
691
996
|
);
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
sections.push("_No projects selected._", "");
|
|
713
|
-
return sections.join("\n");
|
|
997
|
+
switch (reportType) {
|
|
998
|
+
case "domain_overview":
|
|
999
|
+
sections.push(
|
|
1000
|
+
...await fetchDomainOverview(rt.params, domain, database)
|
|
1001
|
+
);
|
|
1002
|
+
break;
|
|
1003
|
+
case "organic_search":
|
|
1004
|
+
sections.push(
|
|
1005
|
+
...await fetchOrganicSearch(rt.params, domain, database)
|
|
1006
|
+
);
|
|
1007
|
+
break;
|
|
1008
|
+
case "paid_search":
|
|
1009
|
+
sections.push(
|
|
1010
|
+
...await fetchPaidSearch(rt.params, domain, database)
|
|
1011
|
+
);
|
|
1012
|
+
break;
|
|
1013
|
+
case "backlinks":
|
|
1014
|
+
sections.push(...await fetchBacklinks(rt.params, domain));
|
|
1015
|
+
break;
|
|
1016
|
+
}
|
|
714
1017
|
}
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
1018
|
+
if (state.projects?.length) {
|
|
1019
|
+
const result = await fetchProjects(rt.params);
|
|
1020
|
+
if (result.ok) {
|
|
1021
|
+
const projectByIdMap = /* @__PURE__ */ new Map();
|
|
1022
|
+
for (const p of result.projects) {
|
|
1023
|
+
const id = projectId(p);
|
|
1024
|
+
if (id) projectByIdMap.set(id, p);
|
|
1025
|
+
}
|
|
1026
|
+
const targetIds = await resolveSetupSelection({
|
|
1027
|
+
selected: state.projects,
|
|
1028
|
+
allSentinel: ALL_PROJECTS,
|
|
1029
|
+
fetchAll: async () => result.projects.map((p) => projectId(p)).filter((id) => id),
|
|
1030
|
+
limit: SEMRUSH_SETUP_MAX_PROJECTS
|
|
1031
|
+
});
|
|
1032
|
+
if (targetIds.length > 0) {
|
|
1033
|
+
sections.push("### Projects", "");
|
|
1034
|
+
sections.push("| Project | Domain | Created |");
|
|
1035
|
+
sections.push("|---------|--------|---------|");
|
|
1036
|
+
for (const id of targetIds) {
|
|
1037
|
+
const p = projectByIdMap.get(id);
|
|
1038
|
+
if (!p) {
|
|
1039
|
+
sections.push(`| ${id} | - | - |`);
|
|
1040
|
+
continue;
|
|
1041
|
+
}
|
|
1042
|
+
const name = projectName(p).replace(/\|/g, "\\|");
|
|
1043
|
+
const dom = projectDomain(p).replace(/\|/g, "\\|") || "-";
|
|
1044
|
+
const created = projectCreatedAt(p) || "-";
|
|
1045
|
+
sections.push(`| ${name} | ${dom} | ${created} |`);
|
|
1046
|
+
}
|
|
1047
|
+
sections.push("");
|
|
1048
|
+
}
|
|
722
1049
|
}
|
|
723
|
-
const name = projectName(p).replace(/\|/g, "\\|");
|
|
724
|
-
const domain = projectDomain(p).replace(/\|/g, "\\|") || "-";
|
|
725
|
-
const created = projectCreatedAt(p) || "-";
|
|
726
|
-
sections.push(`| ${name} | ${domain} | ${created} |`);
|
|
727
1050
|
}
|
|
728
|
-
sections.push("");
|
|
729
1051
|
return sections.join("\n");
|
|
730
1052
|
}
|
|
731
1053
|
};
|
|
@@ -745,7 +1067,7 @@ var semrushConnector = new ConnectorPlugin({
|
|
|
745
1067
|
systemPrompt: {
|
|
746
1068
|
en: `### Tools
|
|
747
1069
|
|
|
748
|
-
- \`
|
|
1070
|
+
- \`connector_semrush-api-key_request\`: The only way to call the Semrush API. Use it for the Standard Analytics API (\`/?type=...\` reports), the Trends API (\`/analytics/v1/...\`), and the Projects API (\`/management/v1/...\`). Authentication is handled automatically \u2014 the API key is appended as the \`key\` query parameter; never include it yourself. The Standard Analytics API returns semicolon-separated CSV with the first row as the header (use \`responseFormat="text"\`); the Trends and Projects APIs return JSON (use \`responseFormat="json"\`). Errors from the Standard API are returned as a body that starts with \`ERROR\`, often with HTTP 200 \u2014 the tool surfaces these as \`success: false\` automatically.
|
|
749
1071
|
|
|
750
1072
|
### Business Logic
|
|
751
1073
|
|
|
@@ -758,7 +1080,7 @@ SDK methods (client created via \`connection(connectionId)\`):
|
|
|
758
1080
|
- \`client.trends(path, query?)\` \u2014 call a Trends API endpoint (\`/analytics/v1/...\`) and return parsed JSON
|
|
759
1081
|
- \`client.projects(path, init?)\` \u2014 call a Projects API endpoint (\`/management/v1/...\`) and return parsed JSON
|
|
760
1082
|
|
|
761
|
-
\u{1F6A8} **MANDATORY pre-flight before creating any server logic that calls \`report()\`.** Before authoring a TypeScript handler that invokes \`client.report(...)\` (Standard Analytics \u2014 \`domain_ranks\`, \`domain_organic\`, \`phrase_this\`, etc.), you MUST first call the \`
|
|
1083
|
+
\u{1F6A8} **MANDATORY pre-flight before creating any server logic that calls \`report()\`.** Before authoring a TypeScript handler that invokes \`client.report(...)\` (Standard Analytics \u2014 \`domain_ranks\`, \`domain_organic\`, \`phrase_this\`, etc.), you MUST first call the \`connector_semrush-api-key_request\` tool with \`path: "https://www.semrush.com/users/countapiunits.html"\`, no \`queryParams\`, \`responseFormat: "text"\` to confirm the unit balance is greater than 0. If the balance is 0, **stop, do not create the server logic**, and report the issue to the user (the account owner needs to top up API units in the Semrush console). \`testFetchServerLogic\` will execute the handler and consume units; creating handlers when the balance is 0 produces \`ERROR 132 :: API UNITS BALANCE IS ZERO\` failures across every server logic.
|
|
762
1084
|
|
|
763
1085
|
\u{1F6A8} **Always set a small \`display_limit\` explicitly \u2014 never rely on the default.** Semrush computes "required units = display_limit \xD7 per-row cost" up front, and rejects the request with \`ERROR 132 :: API UNITS BALANCE IS ZERO\` when the *estimated* cost exceeds the remaining balance, **even when the actual balance is non-zero** (e.g. balance \u2248 40,950 still fails for \`display_limit=10000\` on costly reports). Default to \`display_limit: "1000"\` (or smaller \u2014 \`"100"\` is plenty for most dashboards), and only increase it when the user explicitly asks for a larger sample AND \`checkUnits()\` confirms enough headroom. If you truly need all rows, paginate with \`display_offset\` in chunks of 1000 instead of bumping \`display_limit\`. Treat \`ERROR 132\` as "request too large for the current balance" first, and only as "balance is literally zero" after re-checking units.
|
|
764
1086
|
|
|
@@ -848,7 +1170,7 @@ To check remaining API units (free, does NOT consume units), call the request to
|
|
|
848
1170
|
- Date strings in historical endpoints must be the 15th of the month (\`YYYYMM15\`)`,
|
|
849
1171
|
ja: `### \u30C4\u30FC\u30EB
|
|
850
1172
|
|
|
851
|
-
- \`
|
|
1173
|
+
- \`connector_semrush-api-key_request\`: Semrush API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002Standard Analytics API\uFF08\`/?type=...\` \u5F62\u5F0F\u306E\u30EC\u30DD\u30FC\u30C8\uFF09\u3001Trends API\uFF08\`/analytics/v1/...\`\uFF09\u3001Projects API\uFF08\`/management/v1/...\`\uFF09\u3059\u3079\u3066\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\u306F\u81EA\u52D5\u7684\u306B\u884C\u308F\u308C\u3001API\u30AD\u30FC\u306F \`key\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3068\u3057\u3066\u4ED8\u4E0E\u3055\u308C\u308B\u305F\u3081\u3001\u81EA\u5206\u3067\u542B\u3081\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002Standard Analytics API \u306F1\u884C\u76EE\u304C\u30D8\u30C3\u30C0\u30FC\u306E\u30BB\u30DF\u30B3\u30ED\u30F3\u533A\u5207\u308ACSV\u3092\u8FD4\u3059\u305F\u3081 \`responseFormat="text"\` \u3092\u4F7F\u7528\u3057\u3001Trends/Projects API \u306F JSON \u3092\u8FD4\u3059\u305F\u3081 \`responseFormat="json"\` \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002Standard API \u306E\u30A8\u30E9\u30FC\u306F HTTP 200 \u3067\u3082\u672C\u6587\u304C \`ERROR\` \u3067\u59CB\u307E\u308B\u5F62\u5F0F\u3067\u8FD4\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u304C\u3001\u30C4\u30FC\u30EB\u306F\u81EA\u52D5\u7684\u306B \`success: false\` \u3068\u3057\u3066\u8FD4\u3057\u307E\u3059\u3002
|
|
852
1174
|
|
|
853
1175
|
### Business Logic
|
|
854
1176
|
|
|
@@ -861,7 +1183,7 @@ SDK\u30E1\u30BD\u30C3\u30C9 (\`connection(connectionId)\` \u3067\u4F5C\u6210\u30
|
|
|
861
1183
|
- \`client.trends(path, query?)\` \u2014 Trends API \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08\`/analytics/v1/...\`\uFF09\u3092\u547C\u3073\u51FA\u3057 JSON \u3092\u8FD4\u3059
|
|
862
1184
|
- \`client.projects(path, init?)\` \u2014 Projects API \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08\`/management/v1/...\`\uFF09\u3092\u547C\u3073\u51FA\u3057 JSON \u3092\u8FD4\u3059
|
|
863
1185
|
|
|
864
|
-
\u{1F6A8} **\`report()\` \u3092\u547C\u3076\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u3092\u4F5C\u6210\u3059\u308B\u524D\u306E\u5FC5\u9808\u30D7\u30EA\u30D5\u30E9\u30A4\u30C8\u3002** Standard Analytics\uFF08\`domain_ranks\`\u3001\`domain_organic\`\u3001\`phrase_this\` \u306A\u3069\uFF09\u306E \`client.report(...)\` \u3092\u542B\u3080 TypeScript \u30CF\u30F3\u30C9\u30E9\u3092\u4F5C\u6210\u3059\u308B\u524D\u306B\u3001\u5FC5\u305A \`
|
|
1186
|
+
\u{1F6A8} **\`report()\` \u3092\u547C\u3076\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u3092\u4F5C\u6210\u3059\u308B\u524D\u306E\u5FC5\u9808\u30D7\u30EA\u30D5\u30E9\u30A4\u30C8\u3002** Standard Analytics\uFF08\`domain_ranks\`\u3001\`domain_organic\`\u3001\`phrase_this\` \u306A\u3069\uFF09\u306E \`client.report(...)\` \u3092\u542B\u3080 TypeScript \u30CF\u30F3\u30C9\u30E9\u3092\u4F5C\u6210\u3059\u308B\u524D\u306B\u3001\u5FC5\u305A \`connector_semrush-api-key_request\` \u30C4\u30FC\u30EB\u3092 \`path: "https://www.semrush.com/users/countapiunits.html"\`\u3001\`queryParams\` \u7121\u3057\u3001\`responseFormat: "text"\` \u3067\u547C\u3073\u51FA\u3057\u3066\u30E6\u30CB\u30C3\u30C8\u6B8B\u91CF\u304C 0 \u3088\u308A\u5927\u304D\u3044\u3053\u3068\u3092\u78BA\u8A8D\u3059\u308B\u3053\u3068\u3002\u6B8B\u91CF\u304C 0 \u306E\u5834\u5408\u306F **\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u3092\u4F5C\u6210\u305B\u305A\u306B\u505C\u6B62\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u306B\u5831\u544A**\u3059\u308B\uFF08Semrush \u306E\u7BA1\u7406\u30B3\u30F3\u30BD\u30FC\u30EB\u304B\u3089 API \u30E6\u30CB\u30C3\u30C8\u3092\u88DC\u5145\u3059\u308B\u5FC5\u8981\u304C\u3042\u308B\uFF09\u3002\`testFetchServerLogic\` \u306F\u30CF\u30F3\u30C9\u30E9\u3092\u5B9F\u884C\u3057\u3066\u30E6\u30CB\u30C3\u30C8\u3092\u6D88\u8CBB\u3059\u308B\u305F\u3081\u3001\u6B8B\u91CF 0 \u306E\u307E\u307E\u4F5C\u6210\u3059\u308B\u3068\u5168\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u304C \`ERROR 132 :: API UNITS BALANCE IS ZERO\` \u3067\u5931\u6557\u3059\u308B\u3002
|
|
865
1187
|
|
|
866
1188
|
\u{1F6A8} **\`display_limit\` \u306F\u5FC5\u305A\u660E\u793A\u7684\u306B\u5C0F\u3055\u3044\u5024\u3092\u6307\u5B9A\u3057\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u306B\u983C\u3089\u306A\u3044\u3053\u3068\u3002** Semrush \u306F\u4E8B\u524D\u306B\u300C\u5FC5\u8981\u30E6\u30CB\u30C3\u30C8 = display_limit \xD7 \u884C\u3042\u305F\u308A\u5358\u4FA1\u300D\u3092\u8A08\u7B97\u3057\u3001\u305D\u306E**\u898B\u7A4D\u984D**\u304C\u6B8B\u91CF\u3092\u8D85\u3048\u308B\u3068\u30EA\u30AF\u30A8\u30B9\u30C8\u3092 \`ERROR 132 :: API UNITS BALANCE IS ZERO\` \u3067\u62D2\u5426\u3059\u308B\u3002**\u5B9F\u6B8B\u91CF\u304C\u30BC\u30ED\u3067\u306A\u304F\u3066\u3082**\u8D77\u3053\u308B\uFF08\u4F8B\uFF1A\u6B8B\u91CF\u7D04 40,950 \u3067\u3082\u3001\u30B3\u30B9\u30C8\u306E\u9AD8\u3044\u30EC\u30DD\u30FC\u30C8\u3067 \`display_limit=10000\` \u3060\u3068\u5931\u6557\u3059\u308B\uFF09\u3002\u539F\u5247\u3068\u3057\u3066 \`display_limit: "1000"\`\uFF08\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u7528\u9014\u306A\u3089 \`"100"\` \u3067\u3082\u5341\u5206\uFF09\u3092\u6307\u5B9A\u3057\u3001\u30E6\u30FC\u30B6\u30FC\u304C\u660E\u793A\u7684\u306B\u5927\u304D\u306A\u30B5\u30F3\u30D7\u30EB\u3092\u8981\u6C42\u3057\u3001\u304B\u3064 \`checkUnits()\` \u3067\u6B8B\u91CF\u306B\u5341\u5206\u306A\u4F59\u88D5\u304C\u3042\u308B\u3053\u3068\u3092\u78BA\u8A8D\u3067\u304D\u305F\u5834\u5408\u306E\u307F\u5897\u3084\u3059\u3002\u5168\u884C\u304C\u5FC5\u8981\u306A\u5834\u5408\u306F \`display_limit\` \u3092\u4E0A\u3052\u308B\u306E\u3067\u306F\u306A\u304F\u3001\`display_offset\` \u3067 1000 \u4EF6\u523B\u307F\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u5B9F\u88C5\u3059\u308B\u3053\u3068\u3002\`ERROR 132\` \u306F\u300C\u6B8B\u91CF\u304C\u6587\u5B57\u901A\u308A\u30BC\u30ED\u300D\u3088\u308A\u5148\u306B\u300C\u73FE\u5728\u306E\u6B8B\u91CF\u306B\u5BFE\u3057\u3066\u30EA\u30AF\u30A8\u30B9\u30C8\u304C\u5927\u304D\u3059\u304E\u308B\u300D\u3092\u7591\u3044\u3001\u30E6\u30CB\u30C3\u30C8\u3092\u518D\u78BA\u8A8D\u3057\u3066\u304B\u3089\u5224\u65AD\u3059\u308B\u3053\u3068\u3002
|
|
867
1189
|
|