@squadbase/vite-server 0.1.17-dev.d4fff69 → 0.1.17-dev.e4768d1
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 +4786 -3023
- package/dist/connectors/airtable-oauth.js +39 -15
- package/dist/connectors/airtable.js +86 -15
- package/dist/connectors/amplitude.js +39 -15
- package/dist/connectors/anthropic.js +39 -15
- package/dist/connectors/asana.js +39 -15
- package/dist/connectors/attio.js +39 -15
- package/dist/connectors/aws-billing.js +39 -15
- package/dist/connectors/azure-sql.js +275 -15
- package/dist/connectors/backlog-api-key.js +39 -15
- package/dist/connectors/clickup.js +39 -15
- package/dist/connectors/cosmosdb.js +39 -15
- package/dist/connectors/customerio.js +39 -15
- package/dist/connectors/dbt.js +39 -15
- package/dist/connectors/freshdesk.js +39 -15
- package/dist/connectors/freshsales.js +39 -15
- package/dist/connectors/freshservice.js +39 -15
- package/dist/connectors/gamma.js +39 -15
- package/dist/connectors/gemini.js +39 -15
- package/dist/connectors/github.js +39 -15
- package/dist/connectors/gmail-oauth.js +32 -13
- package/dist/connectors/gmail.js +39 -15
- package/dist/connectors/google-ads.js +39 -15
- package/dist/connectors/google-analytics-oauth.js +39 -15
- package/dist/connectors/google-analytics.js +39 -15
- package/dist/connectors/google-audit-log.js +39 -15
- package/dist/connectors/google-calendar-oauth.js +39 -15
- package/dist/connectors/google-calendar.js +39 -15
- package/dist/connectors/google-docs.js +32 -13
- package/dist/connectors/google-drive.js +32 -13
- package/dist/connectors/google-search-console-oauth.js +39 -15
- package/dist/connectors/google-sheets.js +138 -195
- package/dist/connectors/google-slides.js +32 -13
- package/dist/connectors/grafana.js +39 -15
- package/dist/connectors/hackernews.js +32 -13
- package/dist/connectors/hubspot-oauth.js +32 -13
- package/dist/connectors/hubspot.js +39 -15
- package/dist/connectors/influxdb.js +39 -15
- package/dist/connectors/intercom-oauth.js +32 -13
- package/dist/connectors/intercom.js +39 -15
- package/dist/connectors/jdbc.js +39 -15
- package/dist/connectors/jira-api-key.js +39 -15
- package/dist/connectors/kintone-api-token.js +39 -15
- package/dist/connectors/kintone.js +128 -15
- package/dist/connectors/linear.js +39 -15
- package/dist/connectors/linkedin-ads.js +39 -15
- package/dist/connectors/mailchimp-oauth.js +39 -15
- package/dist/connectors/mailchimp.js +39 -15
- package/dist/connectors/meta-ads-oauth.js +39 -15
- package/dist/connectors/meta-ads.js +39 -15
- package/dist/connectors/mixpanel.js +39 -15
- package/dist/connectors/monday.js +39 -15
- package/dist/connectors/mongodb.js +39 -15
- package/dist/connectors/notion-oauth.js +32 -13
- package/dist/connectors/notion.js +84 -15
- package/dist/connectors/openai.js +39 -15
- package/dist/connectors/oracle.js +277 -15
- package/dist/connectors/outlook-oauth.js +32 -13
- package/dist/connectors/powerbi-oauth.js +32 -13
- package/dist/connectors/salesforce.js +108 -15
- package/dist/connectors/semrush.js +39 -15
- package/dist/connectors/sentry.js +39 -15
- package/dist/connectors/shopify-oauth.js +32 -13
- package/dist/connectors/shopify.js +39 -15
- package/dist/connectors/sqlserver.js +275 -15
- package/dist/connectors/stripe-api-key.js +39 -15
- package/dist/connectors/stripe-oauth.js +32 -13
- package/dist/connectors/supabase.js +284 -15
- package/dist/connectors/tableau.js +39 -15
- package/dist/connectors/tiktok-ads.js +39 -15
- package/dist/connectors/wix-store.js +39 -15
- package/dist/connectors/x.js +39 -15
- package/dist/connectors/zendesk-oauth.js +32 -13
- package/dist/connectors/zendesk.js +39 -15
- package/dist/index.js +4832 -3034
- package/dist/main.js +4832 -3034
- package/dist/vite-plugin.js +4786 -3023
- package/package.json +4 -4
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __esm = (fn, res) => function __init() {
|
|
4
|
-
|
|
3
|
+
var __esm = (fn, res, err) => function __init() {
|
|
4
|
+
if (err) throw err[0];
|
|
5
|
+
try {
|
|
6
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
|
+
} catch (e) {
|
|
8
|
+
throw err = [e], e;
|
|
9
|
+
}
|
|
5
10
|
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name in all)
|
|
@@ -514,6 +519,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
514
519
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
515
520
|
*/
|
|
516
521
|
setup;
|
|
522
|
+
/**
|
|
523
|
+
* 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
|
|
524
|
+
* メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
|
|
525
|
+
* {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
|
|
526
|
+
* 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
|
|
527
|
+
* `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
|
|
528
|
+
* coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
|
|
529
|
+
*/
|
|
530
|
+
introspect;
|
|
517
531
|
/**
|
|
518
532
|
* Opt-out of the default "verify before save" behavior on connection
|
|
519
533
|
* creation. The backend invokes `checkConnection` synchronously while
|
|
@@ -528,6 +542,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
528
542
|
* the default verify-on-create behavior without opt-in.
|
|
529
543
|
*/
|
|
530
544
|
skipConnectionCheckOnCreate;
|
|
545
|
+
/**
|
|
546
|
+
* 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
|
|
547
|
+
* read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
|
|
548
|
+
* recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
|
|
549
|
+
* driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
|
|
550
|
+
* 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
|
|
551
|
+
*/
|
|
552
|
+
surveyProbes;
|
|
531
553
|
constructor(config) {
|
|
532
554
|
this.slug = config.slug;
|
|
533
555
|
this.authType = config.authType;
|
|
@@ -545,7 +567,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
545
567
|
this.query = config.query;
|
|
546
568
|
this.checkConnection = config.checkConnection;
|
|
547
569
|
this.setup = config.setup;
|
|
570
|
+
this.introspect = config.introspect;
|
|
548
571
|
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
572
|
+
this.surveyProbes = config.surveyProbes;
|
|
549
573
|
}
|
|
550
574
|
get connectorKey() {
|
|
551
575
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -583,25 +607,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
583
607
|
if (authType) return `${slug}-${authType}`;
|
|
584
608
|
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
585
609
|
// user-password
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
610
|
+
postgresql: "user-password",
|
|
611
|
+
mysql: "user-password",
|
|
612
|
+
clickhouse: "user-password",
|
|
613
|
+
kintone: "user-password",
|
|
590
614
|
"squadbase-db": "user-password",
|
|
591
615
|
// service-account
|
|
592
|
-
|
|
593
|
-
|
|
616
|
+
snowflake: "service-account",
|
|
617
|
+
bigquery: "service-account",
|
|
594
618
|
"google-analytics": "service-account",
|
|
595
619
|
"google-calendar": "service-account",
|
|
596
620
|
"aws-athena": "service-account",
|
|
597
|
-
|
|
621
|
+
redshift: "service-account",
|
|
598
622
|
// api-key
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
623
|
+
databricks: "api-key",
|
|
624
|
+
dbt: "api-key",
|
|
625
|
+
airtable: "api-key",
|
|
626
|
+
openai: "api-key",
|
|
627
|
+
gemini: "api-key",
|
|
628
|
+
anthropic: "api-key",
|
|
605
629
|
"wix-store": "api-key"
|
|
606
630
|
};
|
|
607
631
|
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
@@ -610,6 +634,80 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
610
634
|
}
|
|
611
635
|
};
|
|
612
636
|
|
|
637
|
+
// ../connectors/src/survey-probe.ts
|
|
638
|
+
function rowsOf(output) {
|
|
639
|
+
if (!output || typeof output !== "object") return [];
|
|
640
|
+
const o = output;
|
|
641
|
+
if (o.success === false) return [];
|
|
642
|
+
return Array.isArray(o.rows) ? o.rows : [];
|
|
643
|
+
}
|
|
644
|
+
function pickString(row, candidates) {
|
|
645
|
+
for (const key of candidates) {
|
|
646
|
+
const v = row[key] ?? row[key.toUpperCase()] ?? row[key.toLowerCase()];
|
|
647
|
+
if (typeof v === "string" && v.length > 0) return v;
|
|
648
|
+
}
|
|
649
|
+
return void 0;
|
|
650
|
+
}
|
|
651
|
+
var TABLE_NAME_FIELDS = [
|
|
652
|
+
"table_name",
|
|
653
|
+
"name",
|
|
654
|
+
"tableName",
|
|
655
|
+
"tab_name",
|
|
656
|
+
"Table",
|
|
657
|
+
"table"
|
|
658
|
+
];
|
|
659
|
+
function makeQuoteIdent(opts) {
|
|
660
|
+
if (opts.bracket) {
|
|
661
|
+
return (name) => `[${name.replaceAll("]", "]]")}]`;
|
|
662
|
+
}
|
|
663
|
+
const q = opts.quote ?? '"';
|
|
664
|
+
return (name) => `${q}${name.replaceAll(q, q + q)}${q}`;
|
|
665
|
+
}
|
|
666
|
+
function sampleSql(ref, limit) {
|
|
667
|
+
return `SELECT * FROM (SELECT * FROM ${ref}) AS _sq LIMIT ${limit}`;
|
|
668
|
+
}
|
|
669
|
+
function distinctTables(prior, max) {
|
|
670
|
+
const names = [];
|
|
671
|
+
const seen = /* @__PURE__ */ new Set();
|
|
672
|
+
for (const row of rowsOf(prior[0]?.output)) {
|
|
673
|
+
const name = pickString(row, TABLE_NAME_FIELDS);
|
|
674
|
+
if (!name || seen.has(name)) continue;
|
|
675
|
+
seen.add(name);
|
|
676
|
+
names.push(name);
|
|
677
|
+
if (names.length >= max) break;
|
|
678
|
+
}
|
|
679
|
+
return names;
|
|
680
|
+
}
|
|
681
|
+
function makeOracleSurveyProbes(opts) {
|
|
682
|
+
const queryTool = opts?.queryTool ?? "executeQuery";
|
|
683
|
+
const sampleLimit = opts?.sampleLimit ?? 5;
|
|
684
|
+
const maxSampleTables = opts?.maxSampleTables ?? 4;
|
|
685
|
+
const quoteIdent = makeQuoteIdent({ quote: '"' });
|
|
686
|
+
return (_connectionId, prior) => {
|
|
687
|
+
if (prior.length === 0) {
|
|
688
|
+
return [
|
|
689
|
+
{
|
|
690
|
+
tool: queryTool,
|
|
691
|
+
input: {
|
|
692
|
+
toolUseIntent: "Survey table/column metadata",
|
|
693
|
+
sql: "SELECT table_name, column_name, data_type FROM user_tab_columns ORDER BY table_name, column_id FETCH FIRST 1000 ROWS ONLY"
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
];
|
|
697
|
+
}
|
|
698
|
+
if (prior.length === 1) {
|
|
699
|
+
return distinctTables(prior, maxSampleTables).map((name) => ({
|
|
700
|
+
tool: queryTool,
|
|
701
|
+
input: {
|
|
702
|
+
toolUseIntent: `Sample ${name}`,
|
|
703
|
+
sql: sampleSql(quoteIdent(name), sampleLimit)
|
|
704
|
+
}
|
|
705
|
+
}));
|
|
706
|
+
}
|
|
707
|
+
return [];
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
|
|
613
711
|
// ../connectors/src/setup-flow.ts
|
|
614
712
|
async function runSetupFlow(flow, params, ctx, config) {
|
|
615
713
|
const runtime = {
|
|
@@ -680,6 +778,58 @@ async function resolveSetupSelection(params) {
|
|
|
680
778
|
return resolved.slice(0, limit);
|
|
681
779
|
}
|
|
682
780
|
|
|
781
|
+
// ../connectors/src/introspect-concurrency.ts
|
|
782
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
783
|
+
const results = new Array(items.length);
|
|
784
|
+
let next = 0;
|
|
785
|
+
const workers = Array.from(
|
|
786
|
+
{ length: Math.min(Math.max(limit, 1), items.length) },
|
|
787
|
+
async () => {
|
|
788
|
+
for (; ; ) {
|
|
789
|
+
const i = next++;
|
|
790
|
+
if (i >= items.length) return;
|
|
791
|
+
results[i] = await fn(items[i]);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
);
|
|
795
|
+
await Promise.all(workers);
|
|
796
|
+
return results;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// ../connectors/src/introspect-profile.ts
|
|
800
|
+
var DEFAULT_MAX_TABLES = 200;
|
|
801
|
+
var DEFAULT_CONCURRENCY = 5;
|
|
802
|
+
function dq(ident) {
|
|
803
|
+
return `"${ident.replace(/"/g, '""')}"`;
|
|
804
|
+
}
|
|
805
|
+
var quoteAnsi = (schema, name) => [...schema.split("."), name].map(dq).join(".");
|
|
806
|
+
async function withRowCounts(ctx, schemaPromise, quoteRef, opts = {}) {
|
|
807
|
+
const schema = await schemaPromise;
|
|
808
|
+
if (!ctx.profile || !ctx.query) return schema;
|
|
809
|
+
return attachRowCounts(ctx.query, schema, quoteRef, opts);
|
|
810
|
+
}
|
|
811
|
+
async function attachRowCounts(run, schema, quoteRef, opts = {}) {
|
|
812
|
+
const targets = schema.tables.slice(0, opts.maxTables ?? DEFAULT_MAX_TABLES);
|
|
813
|
+
await mapWithConcurrency(
|
|
814
|
+
targets,
|
|
815
|
+
opts.concurrency ?? DEFAULT_CONCURRENCY,
|
|
816
|
+
async (table) => {
|
|
817
|
+
try {
|
|
818
|
+
const { rows } = await run(
|
|
819
|
+
`SELECT COUNT(*) AS row_count FROM ${quoteRef(table.schema, table.name)}`
|
|
820
|
+
);
|
|
821
|
+
const first = rows[0] ? Object.values(rows[0])[0] : void 0;
|
|
822
|
+
const rowCount = Number(first);
|
|
823
|
+
if (Number.isFinite(rowCount)) {
|
|
824
|
+
table.profile = { ...table.profile ?? {}, rowCount };
|
|
825
|
+
}
|
|
826
|
+
} catch {
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
);
|
|
830
|
+
return schema;
|
|
831
|
+
}
|
|
832
|
+
|
|
683
833
|
// ../connectors/src/auth-types.ts
|
|
684
834
|
var AUTH_TYPES = {
|
|
685
835
|
OAUTH: "oauth",
|
|
@@ -690,6 +840,63 @@ var AUTH_TYPES = {
|
|
|
690
840
|
USER_PASSWORD: "user-password"
|
|
691
841
|
};
|
|
692
842
|
|
|
843
|
+
// ../connectors/src/introspect-information-schema.ts
|
|
844
|
+
function pickCI(row, key) {
|
|
845
|
+
if (key in row) return String(row[key] ?? "");
|
|
846
|
+
const lower = key.toLowerCase();
|
|
847
|
+
for (const k of Object.keys(row)) {
|
|
848
|
+
if (k.toLowerCase() === lower) return String(row[k] ?? "");
|
|
849
|
+
}
|
|
850
|
+
return "";
|
|
851
|
+
}
|
|
852
|
+
function assembleIntrospectedSchema(input) {
|
|
853
|
+
const { colRows, pkRows = [], fkRows = [] } = input;
|
|
854
|
+
const pkSet = /* @__PURE__ */ new Set();
|
|
855
|
+
for (const r of pkRows) {
|
|
856
|
+
pkSet.add(
|
|
857
|
+
`${pickCI(r, "table_schema")}.${pickCI(r, "table_name")}.${pickCI(r, "column_name")}`
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
const fkMap = /* @__PURE__ */ new Map();
|
|
861
|
+
for (const r of fkRows) {
|
|
862
|
+
fkMap.set(
|
|
863
|
+
`${pickCI(r, "table_schema")}.${pickCI(r, "table_name")}.${pickCI(r, "column_name")}`,
|
|
864
|
+
{
|
|
865
|
+
schema: pickCI(r, "foreign_table_schema"),
|
|
866
|
+
table: pickCI(r, "foreign_table_name"),
|
|
867
|
+
column: pickCI(r, "foreign_column_name")
|
|
868
|
+
}
|
|
869
|
+
);
|
|
870
|
+
}
|
|
871
|
+
const tableMap = /* @__PURE__ */ new Map();
|
|
872
|
+
for (const r of colRows) {
|
|
873
|
+
const schema = pickCI(r, "table_schema");
|
|
874
|
+
const name = pickCI(r, "table_name");
|
|
875
|
+
const key = `${schema}.${name}`;
|
|
876
|
+
let table = tableMap.get(key);
|
|
877
|
+
if (!table) {
|
|
878
|
+
table = {
|
|
879
|
+
schema,
|
|
880
|
+
name,
|
|
881
|
+
type: pickCI(r, "table_type").toUpperCase() === "VIEW" ? "view" : "table",
|
|
882
|
+
columns: []
|
|
883
|
+
};
|
|
884
|
+
tableMap.set(key, table);
|
|
885
|
+
}
|
|
886
|
+
const colKey = `${schema}.${name}.${pickCI(r, "column_name")}`;
|
|
887
|
+
const column = {
|
|
888
|
+
name: pickCI(r, "column_name"),
|
|
889
|
+
dataType: pickCI(r, "data_type"),
|
|
890
|
+
nullable: pickCI(r, "is_nullable").toUpperCase() === "YES"
|
|
891
|
+
};
|
|
892
|
+
if (pkSet.has(colKey)) column.isPrimaryKey = true;
|
|
893
|
+
const fk = fkMap.get(colKey);
|
|
894
|
+
if (fk) column.foreignKey = fk;
|
|
895
|
+
table.columns.push(column);
|
|
896
|
+
}
|
|
897
|
+
return { tables: [...tableMap.values()] };
|
|
898
|
+
}
|
|
899
|
+
|
|
693
900
|
// ../connectors/src/lib/unwrap-sample-limit.ts
|
|
694
901
|
var STRICT_WRAPPER_RE = /^\s*SELECT\s+\*\s+FROM\s+\(([\s\S]+)\)\s+AS\s+\w+\s+LIMIT\s+(\d+)\s*;?\s*$/i;
|
|
695
902
|
var TRAILING_LIMIT_RE = /\s+LIMIT\s+(\d+)\s*;?\s*$/i;
|
|
@@ -910,6 +1117,58 @@ var oracleSetupFlow = {
|
|
|
910
1117
|
}
|
|
911
1118
|
};
|
|
912
1119
|
|
|
1120
|
+
// ../connectors/src/connectors/oracle/introspect.ts
|
|
1121
|
+
var OWNER_NOT_IN = [...INTERNAL_OWNERS].map((o) => `'${o}'`).join(", ");
|
|
1122
|
+
function ownerFilter(ownerCol) {
|
|
1123
|
+
return `${ownerCol} NOT IN (${OWNER_NOT_IN}) AND ${ownerCol} NOT LIKE 'APEX_%'`;
|
|
1124
|
+
}
|
|
1125
|
+
async function introspectOracle(run) {
|
|
1126
|
+
const [{ rows: colRows }, { rows: pkRows }, { rows: fkRows }] = await Promise.all([
|
|
1127
|
+
// 1) 全カラム(型 / nullable)+ テーブル種別(TABLE / VIEW)
|
|
1128
|
+
run(
|
|
1129
|
+
`SELECT c.owner AS table_schema, c.table_name AS table_name,
|
|
1130
|
+
c.column_name AS column_name, c.data_type AS data_type,
|
|
1131
|
+
CASE WHEN c.nullable = 'Y' THEN 'YES' ELSE 'NO' END AS is_nullable,
|
|
1132
|
+
c.column_id AS ordinal_position,
|
|
1133
|
+
CASE WHEN o.object_type = 'VIEW' THEN 'VIEW' ELSE 'BASE TABLE' END AS table_type
|
|
1134
|
+
FROM all_tab_columns c
|
|
1135
|
+
JOIN all_objects o
|
|
1136
|
+
ON o.owner = c.owner AND o.object_name = c.table_name
|
|
1137
|
+
AND o.object_type IN ('TABLE', 'VIEW')
|
|
1138
|
+
WHERE ${ownerFilter("c.owner")}
|
|
1139
|
+
ORDER BY c.owner, c.table_name, c.column_id`
|
|
1140
|
+
),
|
|
1141
|
+
// 2) 主キー(CONSTRAINT_TYPE = 'P')
|
|
1142
|
+
run(
|
|
1143
|
+
`SELECT ac.owner AS table_schema, ac.table_name AS table_name,
|
|
1144
|
+
acc.column_name AS column_name
|
|
1145
|
+
FROM all_constraints ac
|
|
1146
|
+
JOIN all_cons_columns acc
|
|
1147
|
+
ON acc.owner = ac.owner AND acc.constraint_name = ac.constraint_name
|
|
1148
|
+
WHERE ac.constraint_type = 'P'
|
|
1149
|
+
AND ${ownerFilter("ac.owner")}`
|
|
1150
|
+
),
|
|
1151
|
+
// 3) 外部キー(CONSTRAINT_TYPE = 'R')。参照元 → 参照先を position で突き合わせる。
|
|
1152
|
+
run(
|
|
1153
|
+
`SELECT ac.owner AS table_schema, ac.table_name AS table_name,
|
|
1154
|
+
acc.column_name AS column_name,
|
|
1155
|
+
rac.owner AS foreign_table_schema, rac.table_name AS foreign_table_name,
|
|
1156
|
+
racc.column_name AS foreign_column_name
|
|
1157
|
+
FROM all_constraints ac
|
|
1158
|
+
JOIN all_cons_columns acc
|
|
1159
|
+
ON acc.owner = ac.owner AND acc.constraint_name = ac.constraint_name
|
|
1160
|
+
JOIN all_constraints rac
|
|
1161
|
+
ON rac.owner = ac.r_owner AND rac.constraint_name = ac.r_constraint_name
|
|
1162
|
+
JOIN all_cons_columns racc
|
|
1163
|
+
ON racc.owner = rac.owner AND racc.constraint_name = rac.constraint_name
|
|
1164
|
+
AND racc.position = acc.position
|
|
1165
|
+
WHERE ac.constraint_type = 'R'
|
|
1166
|
+
AND ${ownerFilter("ac.owner")}`
|
|
1167
|
+
)
|
|
1168
|
+
]);
|
|
1169
|
+
return assembleIntrospectedSchema({ colRows, pkRows, fkRows });
|
|
1170
|
+
}
|
|
1171
|
+
|
|
913
1172
|
// ../connectors/src/connectors/oracle/tools/execute-query.ts
|
|
914
1173
|
import { z } from "zod";
|
|
915
1174
|
init_oracle_runner();
|
|
@@ -1049,6 +1308,9 @@ The business logic type for this connector is "sql".
|
|
|
1049
1308
|
- \u884C\u6570\u5236\u9650\u306E\u4E92\u63DB\u6027: \u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u306E server-logic \u30B9\u30AD\u30FC\u30DE\u63A8\u8AD6\u306F\u3001\u30AF\u30A8\u30EA\u3092 \`SELECT * FROM (<inner>) AS _sq LIMIT N\` \u306E\u5F62\u3067\u30E9\u30C3\u30D7\u3057\u3066\u304F\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002Oracle \u306B\u306F \`LIMIT\` \u30AD\u30FC\u30EF\u30FC\u30C9\u304C\u5B58\u5728\u3057\u306A\u3044\u305F\u3081\u3001\u30B3\u30CD\u30AF\u30BF\u306F \`query()\` \u5185\u3067\u3053\u306E\u30E9\u30C3\u30D1\u3092\u691C\u51FA\u3057\u3001\`<inner>\` \u3092\u305D\u306E\u307E\u307E\u5B9F\u884C\u3057\u3066 JS \u5074\u3067\u5148\u982D N \u884C\u306B\u5207\u308A\u8A70\u3081\u307E\u3059\u3002\u5229\u7528\u8005\u5074\u3067\u5BFE\u51E6\u3059\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093\u304C\u3001\u81EA\u5206\u3067\u66F8\u304F SQL \u3067\u306F \`LIMIT\` \u3092\u4F7F\u308F\u305A \`FETCH FIRST N ROWS ONLY\` / \`OFFSET m ROWS FETCH NEXT N ROWS ONLY\` / \`ROWNUM\` \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
1050
1309
|
},
|
|
1051
1310
|
tools,
|
|
1311
|
+
// 決定論的な立ち上げ survey(ルールベース prewarm)。Oracle は USER_TAB_COLUMNS でメタ取得。
|
|
1312
|
+
surveyProbes: makeOracleSurveyProbes(),
|
|
1313
|
+
introspect: (ctx) => withRowCounts(ctx, introspectOracle(ctx.query), quoteAnsi),
|
|
1052
1314
|
setup: (params, ctx, config) => runSetupFlow(oracleSetupFlow, params, ctx, config),
|
|
1053
1315
|
async checkConnection(params, _config) {
|
|
1054
1316
|
return checkOracleConnection(
|
|
@@ -193,6 +193,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
193
193
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
194
194
|
*/
|
|
195
195
|
setup;
|
|
196
|
+
/**
|
|
197
|
+
* 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
|
|
198
|
+
* メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
|
|
199
|
+
* {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
|
|
200
|
+
* 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
|
|
201
|
+
* `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
|
|
202
|
+
* coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
|
|
203
|
+
*/
|
|
204
|
+
introspect;
|
|
196
205
|
/**
|
|
197
206
|
* Opt-out of the default "verify before save" behavior on connection
|
|
198
207
|
* creation. The backend invokes `checkConnection` synchronously while
|
|
@@ -207,6 +216,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
207
216
|
* the default verify-on-create behavior without opt-in.
|
|
208
217
|
*/
|
|
209
218
|
skipConnectionCheckOnCreate;
|
|
219
|
+
/**
|
|
220
|
+
* 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
|
|
221
|
+
* read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
|
|
222
|
+
* recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
|
|
223
|
+
* driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
|
|
224
|
+
* 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
|
|
225
|
+
*/
|
|
226
|
+
surveyProbes;
|
|
210
227
|
constructor(config) {
|
|
211
228
|
this.slug = config.slug;
|
|
212
229
|
this.authType = config.authType;
|
|
@@ -224,7 +241,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
224
241
|
this.query = config.query;
|
|
225
242
|
this.checkConnection = config.checkConnection;
|
|
226
243
|
this.setup = config.setup;
|
|
244
|
+
this.introspect = config.introspect;
|
|
227
245
|
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
246
|
+
this.surveyProbes = config.surveyProbes;
|
|
228
247
|
}
|
|
229
248
|
get connectorKey() {
|
|
230
249
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -262,25 +281,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
262
281
|
if (authType) return `${slug}-${authType}`;
|
|
263
282
|
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
264
283
|
// user-password
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
284
|
+
postgresql: "user-password",
|
|
285
|
+
mysql: "user-password",
|
|
286
|
+
clickhouse: "user-password",
|
|
287
|
+
kintone: "user-password",
|
|
269
288
|
"squadbase-db": "user-password",
|
|
270
289
|
// service-account
|
|
271
|
-
|
|
272
|
-
|
|
290
|
+
snowflake: "service-account",
|
|
291
|
+
bigquery: "service-account",
|
|
273
292
|
"google-analytics": "service-account",
|
|
274
293
|
"google-calendar": "service-account",
|
|
275
294
|
"aws-athena": "service-account",
|
|
276
|
-
|
|
295
|
+
redshift: "service-account",
|
|
277
296
|
// api-key
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
297
|
+
databricks: "api-key",
|
|
298
|
+
dbt: "api-key",
|
|
299
|
+
airtable: "api-key",
|
|
300
|
+
openai: "api-key",
|
|
301
|
+
gemini: "api-key",
|
|
302
|
+
anthropic: "api-key",
|
|
284
303
|
"wix-store": "api-key"
|
|
285
304
|
};
|
|
286
305
|
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
@@ -151,6 +151,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
151
151
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
152
152
|
*/
|
|
153
153
|
setup;
|
|
154
|
+
/**
|
|
155
|
+
* 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
|
|
156
|
+
* メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
|
|
157
|
+
* {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
|
|
158
|
+
* 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
|
|
159
|
+
* `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
|
|
160
|
+
* coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
|
|
161
|
+
*/
|
|
162
|
+
introspect;
|
|
154
163
|
/**
|
|
155
164
|
* Opt-out of the default "verify before save" behavior on connection
|
|
156
165
|
* creation. The backend invokes `checkConnection` synchronously while
|
|
@@ -165,6 +174,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
165
174
|
* the default verify-on-create behavior without opt-in.
|
|
166
175
|
*/
|
|
167
176
|
skipConnectionCheckOnCreate;
|
|
177
|
+
/**
|
|
178
|
+
* 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
|
|
179
|
+
* read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
|
|
180
|
+
* recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
|
|
181
|
+
* driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
|
|
182
|
+
* 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
|
|
183
|
+
*/
|
|
184
|
+
surveyProbes;
|
|
168
185
|
constructor(config) {
|
|
169
186
|
this.slug = config.slug;
|
|
170
187
|
this.authType = config.authType;
|
|
@@ -182,7 +199,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
182
199
|
this.query = config.query;
|
|
183
200
|
this.checkConnection = config.checkConnection;
|
|
184
201
|
this.setup = config.setup;
|
|
202
|
+
this.introspect = config.introspect;
|
|
185
203
|
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
204
|
+
this.surveyProbes = config.surveyProbes;
|
|
186
205
|
}
|
|
187
206
|
get connectorKey() {
|
|
188
207
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -220,25 +239,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
220
239
|
if (authType) return `${slug}-${authType}`;
|
|
221
240
|
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
222
241
|
// user-password
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
242
|
+
postgresql: "user-password",
|
|
243
|
+
mysql: "user-password",
|
|
244
|
+
clickhouse: "user-password",
|
|
245
|
+
kintone: "user-password",
|
|
227
246
|
"squadbase-db": "user-password",
|
|
228
247
|
// service-account
|
|
229
|
-
|
|
230
|
-
|
|
248
|
+
snowflake: "service-account",
|
|
249
|
+
bigquery: "service-account",
|
|
231
250
|
"google-analytics": "service-account",
|
|
232
251
|
"google-calendar": "service-account",
|
|
233
252
|
"aws-athena": "service-account",
|
|
234
|
-
|
|
253
|
+
redshift: "service-account",
|
|
235
254
|
// api-key
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
255
|
+
databricks: "api-key",
|
|
256
|
+
dbt: "api-key",
|
|
257
|
+
airtable: "api-key",
|
|
258
|
+
openai: "api-key",
|
|
259
|
+
gemini: "api-key",
|
|
260
|
+
anthropic: "api-key",
|
|
242
261
|
"wix-store": "api-key"
|
|
243
262
|
};
|
|
244
263
|
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|