@squadbase/vite-server 0.0.1-build-4 → 0.0.1-build-5

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/index.js CHANGED
@@ -26,29 +26,29 @@ function createPostgreSQLClient(connectionString) {
26
26
  }
27
27
 
28
28
  // src/connector-client/env.ts
29
- function resolveEnvVar(entry, key, slug) {
29
+ function resolveEnvVar(entry, key, connectionId) {
30
30
  const envVarName = entry.envVars[key];
31
31
  if (!envVarName) {
32
- throw new Error(`Connector "${slug}" is missing envVars mapping for key "${key}"`);
32
+ throw new Error(`Connection "${connectionId}" is missing envVars mapping for key "${key}"`);
33
33
  }
34
34
  const value = process.env[envVarName];
35
35
  if (!value) {
36
- throw new Error(`Environment variable "${envVarName}" (for "${slug}.${key}") is not set`);
36
+ throw new Error(`Environment variable "${envVarName}" (for connection "${connectionId}", key "${key}") is not set`);
37
37
  }
38
38
  return value;
39
39
  }
40
40
 
41
41
  // src/connector-client/bigquery.ts
42
- function createBigQueryClient(entry, slug) {
43
- const projectId = resolveEnvVar(entry, "project-id", slug);
44
- const serviceAccountJsonBase64 = resolveEnvVar(entry, "service-account-json-base64", slug);
42
+ function createBigQueryClient(entry, connectionId) {
43
+ const projectId = resolveEnvVar(entry, "project-id", connectionId);
44
+ const serviceAccountJsonBase64 = resolveEnvVar(entry, "service-account-json-base64", connectionId);
45
45
  const serviceAccountJson = Buffer.from(serviceAccountJsonBase64, "base64").toString("utf-8");
46
46
  let gcpCredentials;
47
47
  try {
48
48
  gcpCredentials = JSON.parse(serviceAccountJson);
49
49
  } catch {
50
50
  throw new Error(
51
- `BigQuery service account JSON (decoded from base64) is not valid JSON for slug "${slug}"`
51
+ `BigQuery service account JSON (decoded from base64) is not valid JSON for connection "${connectionId}"`
52
52
  );
53
53
  }
54
54
  return {
@@ -63,12 +63,12 @@ function createBigQueryClient(entry, slug) {
63
63
  }
64
64
 
65
65
  // src/connector-client/snowflake.ts
66
- function createSnowflakeClient(entry, slug) {
67
- const accountIdentifier = resolveEnvVar(entry, "account", slug);
68
- const user = resolveEnvVar(entry, "user", slug);
69
- const role = resolveEnvVar(entry, "role", slug);
70
- const warehouse = resolveEnvVar(entry, "warehouse", slug);
71
- const privateKeyBase64 = resolveEnvVar(entry, "private-key-base64", slug);
66
+ function createSnowflakeClient(entry, connectionId) {
67
+ const accountIdentifier = resolveEnvVar(entry, "account", connectionId);
68
+ const user = resolveEnvVar(entry, "user", connectionId);
69
+ const role = resolveEnvVar(entry, "role", connectionId);
70
+ const warehouse = resolveEnvVar(entry, "warehouse", connectionId);
71
+ const privateKeyBase64 = resolveEnvVar(entry, "private-key-base64", connectionId);
72
72
  const privateKey = Buffer.from(privateKeyBase64, "base64").toString("utf-8");
73
73
  return {
74
74
  async query(sql) {
@@ -123,53 +123,38 @@ function createConnectorRegistry() {
123
123
  }
124
124
  return connectionsCache;
125
125
  }
126
- async function getClient2(connectorSlug, connectorType) {
127
- if (!connectorSlug) {
128
- const cacheKey = "__squadbase-db__";
129
- const cached2 = clientCache.get(cacheKey);
130
- if (cached2) return cached2;
131
- const url = process.env.SQUADBASE_POSTGRESQL_URL;
132
- if (!url) throw new Error("SQUADBASE_POSTGRESQL_URL environment variable is not set");
133
- const client = createPostgreSQLClient(url);
134
- clientCache.set(cacheKey, client);
135
- return client;
136
- }
137
- const cached = clientCache.get(connectorSlug);
138
- if (cached) return cached;
126
+ async function getClient2(connectionId) {
139
127
  const connections = loadConnections();
140
- const entry = connections[connectorSlug];
128
+ const entry = connections[connectionId];
141
129
  if (!entry) {
142
- throw new Error(`connector slug '${connectorSlug}' not found in .squadbase/connections.json`);
143
- }
144
- const resolvedType = connectorType ?? entry.connectorType;
145
- if (!resolvedType) {
146
- throw new Error(
147
- `connector type could not be determined for slug '${connectorSlug}'. Specify connectorType in the data-source JSON or in .squadbase/connections.json.`
148
- );
130
+ throw new Error(`connection '${connectionId}' not found in .squadbase/connections.json`);
149
131
  }
150
- if (resolvedType === "snowflake") {
151
- return createSnowflakeClient(entry, connectorSlug);
132
+ const connectorSlug = entry.connector.slug;
133
+ const cached = clientCache.get(connectionId);
134
+ if (cached) return { client: cached, connectorSlug };
135
+ if (connectorSlug === "snowflake") {
136
+ return { client: createSnowflakeClient(entry, connectionId), connectorSlug };
152
137
  }
153
- if (resolvedType === "bigquery") {
154
- return createBigQueryClient(entry, connectorSlug);
138
+ if (connectorSlug === "bigquery") {
139
+ return { client: createBigQueryClient(entry, connectionId), connectorSlug };
155
140
  }
156
- if (resolvedType === "postgresql" || resolvedType === "squadbase-db") {
141
+ if (connectorSlug === "postgresql" || connectorSlug === "squadbase-db") {
157
142
  const urlEnvName = entry.envVars["connection-url"];
158
143
  if (!urlEnvName) {
159
- throw new Error(`'connection-url' is not defined in envVars for connector '${connectorSlug}'`);
144
+ throw new Error(`'connection-url' is not defined in envVars for connection '${connectionId}'`);
160
145
  }
161
146
  const connectionUrl = process.env[urlEnvName];
162
147
  if (!connectionUrl) {
163
148
  throw new Error(
164
- `environment variable '${urlEnvName}' (mapped from connector '${connectorSlug}') is not set`
149
+ `environment variable '${urlEnvName}' (mapped from connection '${connectionId}') is not set`
165
150
  );
166
151
  }
167
152
  const client = createPostgreSQLClient(connectionUrl);
168
- clientCache.set(connectorSlug, client);
169
- return client;
153
+ clientCache.set(connectionId, client);
154
+ return { client, connectorSlug };
170
155
  }
171
156
  throw new Error(
172
- `connector type '${resolvedType}' is not supported. Supported: "snowflake", "bigquery", "postgresql", "squadbase-db"`
157
+ `connector type '${connectorSlug}' is not supported. Supported: "snowflake", "bigquery", "postgresql", "squadbase-db"`
173
158
  );
174
159
  }
175
160
  function reloadEnvFile2(envPath) {
@@ -277,6 +262,10 @@ async function initialize() {
277
262
  console.warn(`[registry] Skipping ${file}: missing description`);
278
263
  return;
279
264
  }
265
+ if (!def.connectionId) {
266
+ console.warn(`[registry] Skipping ${file}: missing connectionId`);
267
+ return;
268
+ }
280
269
  if (def.type === "typescript") {
281
270
  if (!def.handlerPath) {
282
271
  console.warn(`[registry] Skipping ${file}: missing handlerPath`);
@@ -287,6 +276,7 @@ async function initialize() {
287
276
  description: def.description,
288
277
  parameters: def.parameters ?? [],
289
278
  response: def.response,
279
+ connectionId: def.connectionId,
290
280
  cacheConfig: def.cache,
291
281
  handler: async () => {
292
282
  throw new Error("TypeScript handler must be called via _tsHandlerPath");
@@ -306,13 +296,12 @@ async function initialize() {
306
296
  description: sqlDef.description,
307
297
  parameters: sqlDef.parameters ?? [],
308
298
  response: sqlDef.response,
309
- connectorSlug: sqlDef.connectorSlug,
299
+ connectionId: sqlDef.connectionId,
310
300
  cacheConfig: sqlDef.cache,
311
301
  _query: sqlDef.query,
312
- _connectorType: sqlDef.connectorType,
313
302
  handler: async (runtimeParams) => {
314
- const client = await getClient(sqlDef.connectorSlug, sqlDef.connectorType);
315
- const isExternalConnector = sqlDef.connectorType === "snowflake" || sqlDef.connectorType === "bigquery";
303
+ const { client, connectorSlug } = await getClient(sqlDef.connectionId);
304
+ const isExternalConnector = connectorSlug === "snowflake" || connectorSlug === "bigquery";
316
305
  let queryText;
317
306
  let queryValues;
318
307
  if (isExternalConnector) {
@@ -391,8 +380,7 @@ function buildMeta(slug, def) {
391
380
  parameters: def.parameters,
392
381
  response: def.response,
393
382
  query: def._query,
394
- connectorType: def._connectorType,
395
- connectorSlug: def.connectorSlug,
383
+ connectionId: def.connectionId,
396
384
  handlerPath: def._tsHandlerPath ? path2.relative(currentDirPath, def._tsHandlerPath) : void 0,
397
385
  cache: def.cacheConfig
398
386
  };
package/dist/main.js CHANGED
@@ -26,29 +26,29 @@ function createPostgreSQLClient(connectionString) {
26
26
  }
27
27
 
28
28
  // src/connector-client/env.ts
29
- function resolveEnvVar(entry, key, slug) {
29
+ function resolveEnvVar(entry, key, connectionId) {
30
30
  const envVarName = entry.envVars[key];
31
31
  if (!envVarName) {
32
- throw new Error(`Connector "${slug}" is missing envVars mapping for key "${key}"`);
32
+ throw new Error(`Connection "${connectionId}" is missing envVars mapping for key "${key}"`);
33
33
  }
34
34
  const value = process.env[envVarName];
35
35
  if (!value) {
36
- throw new Error(`Environment variable "${envVarName}" (for "${slug}.${key}") is not set`);
36
+ throw new Error(`Environment variable "${envVarName}" (for connection "${connectionId}", key "${key}") is not set`);
37
37
  }
38
38
  return value;
39
39
  }
40
40
 
41
41
  // src/connector-client/bigquery.ts
42
- function createBigQueryClient(entry, slug) {
43
- const projectId = resolveEnvVar(entry, "project-id", slug);
44
- const serviceAccountJsonBase64 = resolveEnvVar(entry, "service-account-json-base64", slug);
42
+ function createBigQueryClient(entry, connectionId) {
43
+ const projectId = resolveEnvVar(entry, "project-id", connectionId);
44
+ const serviceAccountJsonBase64 = resolveEnvVar(entry, "service-account-json-base64", connectionId);
45
45
  const serviceAccountJson = Buffer.from(serviceAccountJsonBase64, "base64").toString("utf-8");
46
46
  let gcpCredentials;
47
47
  try {
48
48
  gcpCredentials = JSON.parse(serviceAccountJson);
49
49
  } catch {
50
50
  throw new Error(
51
- `BigQuery service account JSON (decoded from base64) is not valid JSON for slug "${slug}"`
51
+ `BigQuery service account JSON (decoded from base64) is not valid JSON for connection "${connectionId}"`
52
52
  );
53
53
  }
54
54
  return {
@@ -63,12 +63,12 @@ function createBigQueryClient(entry, slug) {
63
63
  }
64
64
 
65
65
  // src/connector-client/snowflake.ts
66
- function createSnowflakeClient(entry, slug) {
67
- const accountIdentifier = resolveEnvVar(entry, "account", slug);
68
- const user = resolveEnvVar(entry, "user", slug);
69
- const role = resolveEnvVar(entry, "role", slug);
70
- const warehouse = resolveEnvVar(entry, "warehouse", slug);
71
- const privateKeyBase64 = resolveEnvVar(entry, "private-key-base64", slug);
66
+ function createSnowflakeClient(entry, connectionId) {
67
+ const accountIdentifier = resolveEnvVar(entry, "account", connectionId);
68
+ const user = resolveEnvVar(entry, "user", connectionId);
69
+ const role = resolveEnvVar(entry, "role", connectionId);
70
+ const warehouse = resolveEnvVar(entry, "warehouse", connectionId);
71
+ const privateKeyBase64 = resolveEnvVar(entry, "private-key-base64", connectionId);
72
72
  const privateKey = Buffer.from(privateKeyBase64, "base64").toString("utf-8");
73
73
  return {
74
74
  async query(sql) {
@@ -123,53 +123,38 @@ function createConnectorRegistry() {
123
123
  }
124
124
  return connectionsCache;
125
125
  }
126
- async function getClient2(connectorSlug, connectorType) {
127
- if (!connectorSlug) {
128
- const cacheKey = "__squadbase-db__";
129
- const cached2 = clientCache.get(cacheKey);
130
- if (cached2) return cached2;
131
- const url = process.env.SQUADBASE_POSTGRESQL_URL;
132
- if (!url) throw new Error("SQUADBASE_POSTGRESQL_URL environment variable is not set");
133
- const client = createPostgreSQLClient(url);
134
- clientCache.set(cacheKey, client);
135
- return client;
136
- }
137
- const cached = clientCache.get(connectorSlug);
138
- if (cached) return cached;
126
+ async function getClient2(connectionId) {
139
127
  const connections = loadConnections();
140
- const entry = connections[connectorSlug];
128
+ const entry = connections[connectionId];
141
129
  if (!entry) {
142
- throw new Error(`connector slug '${connectorSlug}' not found in .squadbase/connections.json`);
143
- }
144
- const resolvedType = connectorType ?? entry.connectorType;
145
- if (!resolvedType) {
146
- throw new Error(
147
- `connector type could not be determined for slug '${connectorSlug}'. Specify connectorType in the data-source JSON or in .squadbase/connections.json.`
148
- );
130
+ throw new Error(`connection '${connectionId}' not found in .squadbase/connections.json`);
149
131
  }
150
- if (resolvedType === "snowflake") {
151
- return createSnowflakeClient(entry, connectorSlug);
132
+ const connectorSlug = entry.connector.slug;
133
+ const cached = clientCache.get(connectionId);
134
+ if (cached) return { client: cached, connectorSlug };
135
+ if (connectorSlug === "snowflake") {
136
+ return { client: createSnowflakeClient(entry, connectionId), connectorSlug };
152
137
  }
153
- if (resolvedType === "bigquery") {
154
- return createBigQueryClient(entry, connectorSlug);
138
+ if (connectorSlug === "bigquery") {
139
+ return { client: createBigQueryClient(entry, connectionId), connectorSlug };
155
140
  }
156
- if (resolvedType === "postgresql" || resolvedType === "squadbase-db") {
141
+ if (connectorSlug === "postgresql" || connectorSlug === "squadbase-db") {
157
142
  const urlEnvName = entry.envVars["connection-url"];
158
143
  if (!urlEnvName) {
159
- throw new Error(`'connection-url' is not defined in envVars for connector '${connectorSlug}'`);
144
+ throw new Error(`'connection-url' is not defined in envVars for connection '${connectionId}'`);
160
145
  }
161
146
  const connectionUrl = process.env[urlEnvName];
162
147
  if (!connectionUrl) {
163
148
  throw new Error(
164
- `environment variable '${urlEnvName}' (mapped from connector '${connectorSlug}') is not set`
149
+ `environment variable '${urlEnvName}' (mapped from connection '${connectionId}') is not set`
165
150
  );
166
151
  }
167
152
  const client = createPostgreSQLClient(connectionUrl);
168
- clientCache.set(connectorSlug, client);
169
- return client;
153
+ clientCache.set(connectionId, client);
154
+ return { client, connectorSlug };
170
155
  }
171
156
  throw new Error(
172
- `connector type '${resolvedType}' is not supported. Supported: "snowflake", "bigquery", "postgresql", "squadbase-db"`
157
+ `connector type '${connectorSlug}' is not supported. Supported: "snowflake", "bigquery", "postgresql", "squadbase-db"`
173
158
  );
174
159
  }
175
160
  function reloadEnvFile2(envPath) {
@@ -277,6 +262,10 @@ async function initialize() {
277
262
  console.warn(`[registry] Skipping ${file}: missing description`);
278
263
  return;
279
264
  }
265
+ if (!def.connectionId) {
266
+ console.warn(`[registry] Skipping ${file}: missing connectionId`);
267
+ return;
268
+ }
280
269
  if (def.type === "typescript") {
281
270
  if (!def.handlerPath) {
282
271
  console.warn(`[registry] Skipping ${file}: missing handlerPath`);
@@ -287,6 +276,7 @@ async function initialize() {
287
276
  description: def.description,
288
277
  parameters: def.parameters ?? [],
289
278
  response: def.response,
279
+ connectionId: def.connectionId,
290
280
  cacheConfig: def.cache,
291
281
  handler: async () => {
292
282
  throw new Error("TypeScript handler must be called via _tsHandlerPath");
@@ -306,13 +296,12 @@ async function initialize() {
306
296
  description: sqlDef.description,
307
297
  parameters: sqlDef.parameters ?? [],
308
298
  response: sqlDef.response,
309
- connectorSlug: sqlDef.connectorSlug,
299
+ connectionId: sqlDef.connectionId,
310
300
  cacheConfig: sqlDef.cache,
311
301
  _query: sqlDef.query,
312
- _connectorType: sqlDef.connectorType,
313
302
  handler: async (runtimeParams) => {
314
- const client = await getClient(sqlDef.connectorSlug, sqlDef.connectorType);
315
- const isExternalConnector = sqlDef.connectorType === "snowflake" || sqlDef.connectorType === "bigquery";
303
+ const { client, connectorSlug } = await getClient(sqlDef.connectionId);
304
+ const isExternalConnector = connectorSlug === "snowflake" || connectorSlug === "bigquery";
316
305
  let queryText;
317
306
  let queryValues;
318
307
  if (isExternalConnector) {
@@ -391,8 +380,7 @@ function buildMeta(slug, def) {
391
380
  parameters: def.parameters,
392
381
  response: def.response,
393
382
  query: def._query,
394
- connectorType: def._connectorType,
395
- connectorSlug: def.connectorSlug,
383
+ connectionId: def.connectionId,
396
384
  handlerPath: def._tsHandlerPath ? path2.relative(currentDirPath, def._tsHandlerPath) : void 0,
397
385
  cache: def.cacheConfig
398
386
  };
@@ -47,13 +47,12 @@ interface DataSourceDefinition {
47
47
  description: string;
48
48
  parameters: ParameterMeta[];
49
49
  response?: DataSourceResponse;
50
- connectorSlug?: string;
50
+ connectionId: string;
51
51
  cacheConfig?: DataSourceCacheConfig;
52
52
  handler: (params: Record<string, unknown>) => Promise<unknown> | unknown;
53
53
  _isTypescript?: boolean;
54
54
  _tsHandlerPath?: string;
55
55
  _query?: string;
56
- _connectorType?: string;
57
56
  }
58
57
  interface DataSourceMeta {
59
58
  slug: string;
@@ -62,8 +61,7 @@ interface DataSourceMeta {
62
61
  parameters: ParameterMeta[];
63
62
  response?: DataSourceResponse;
64
63
  query?: string;
65
- connectorType?: string;
66
- connectorSlug?: string;
64
+ connectionId: string;
67
65
  handlerPath?: string;
68
66
  cache?: DataSourceCacheConfig;
69
67
  }
@@ -73,14 +71,14 @@ interface JsonDataSourceDefinition {
73
71
  parameters?: ParameterMeta[];
74
72
  response?: DataSourceResponse;
75
73
  query: string;
76
- connectorType?: string;
77
- connectorSlug?: string;
74
+ connectionId: string;
78
75
  cache?: DataSourceCacheConfig;
79
76
  }
80
77
  interface JsonTypeScriptDataSourceDefinition {
81
78
  description: string;
82
79
  type: "typescript";
83
80
  handlerPath: string;
81
+ connectionId: string;
84
82
  parameters?: ParameterMeta[];
85
83
  response?: DataSourceResponse;
86
84
  cache?: DataSourceCacheConfig;
@@ -26,29 +26,29 @@ function createPostgreSQLClient(connectionString) {
26
26
  }
27
27
 
28
28
  // src/connector-client/env.ts
29
- function resolveEnvVar(entry, key, slug) {
29
+ function resolveEnvVar(entry, key, connectionId) {
30
30
  const envVarName = entry.envVars[key];
31
31
  if (!envVarName) {
32
- throw new Error(`Connector "${slug}" is missing envVars mapping for key "${key}"`);
32
+ throw new Error(`Connection "${connectionId}" is missing envVars mapping for key "${key}"`);
33
33
  }
34
34
  const value = process.env[envVarName];
35
35
  if (!value) {
36
- throw new Error(`Environment variable "${envVarName}" (for "${slug}.${key}") is not set`);
36
+ throw new Error(`Environment variable "${envVarName}" (for connection "${connectionId}", key "${key}") is not set`);
37
37
  }
38
38
  return value;
39
39
  }
40
40
 
41
41
  // src/connector-client/bigquery.ts
42
- function createBigQueryClient(entry, slug) {
43
- const projectId = resolveEnvVar(entry, "project-id", slug);
44
- const serviceAccountJsonBase64 = resolveEnvVar(entry, "service-account-json-base64", slug);
42
+ function createBigQueryClient(entry, connectionId) {
43
+ const projectId = resolveEnvVar(entry, "project-id", connectionId);
44
+ const serviceAccountJsonBase64 = resolveEnvVar(entry, "service-account-json-base64", connectionId);
45
45
  const serviceAccountJson = Buffer.from(serviceAccountJsonBase64, "base64").toString("utf-8");
46
46
  let gcpCredentials;
47
47
  try {
48
48
  gcpCredentials = JSON.parse(serviceAccountJson);
49
49
  } catch {
50
50
  throw new Error(
51
- `BigQuery service account JSON (decoded from base64) is not valid JSON for slug "${slug}"`
51
+ `BigQuery service account JSON (decoded from base64) is not valid JSON for connection "${connectionId}"`
52
52
  );
53
53
  }
54
54
  return {
@@ -63,12 +63,12 @@ function createBigQueryClient(entry, slug) {
63
63
  }
64
64
 
65
65
  // src/connector-client/snowflake.ts
66
- function createSnowflakeClient(entry, slug) {
67
- const accountIdentifier = resolveEnvVar(entry, "account", slug);
68
- const user = resolveEnvVar(entry, "user", slug);
69
- const role = resolveEnvVar(entry, "role", slug);
70
- const warehouse = resolveEnvVar(entry, "warehouse", slug);
71
- const privateKeyBase64 = resolveEnvVar(entry, "private-key-base64", slug);
66
+ function createSnowflakeClient(entry, connectionId) {
67
+ const accountIdentifier = resolveEnvVar(entry, "account", connectionId);
68
+ const user = resolveEnvVar(entry, "user", connectionId);
69
+ const role = resolveEnvVar(entry, "role", connectionId);
70
+ const warehouse = resolveEnvVar(entry, "warehouse", connectionId);
71
+ const privateKeyBase64 = resolveEnvVar(entry, "private-key-base64", connectionId);
72
72
  const privateKey = Buffer.from(privateKeyBase64, "base64").toString("utf-8");
73
73
  return {
74
74
  async query(sql) {
@@ -123,53 +123,38 @@ function createConnectorRegistry() {
123
123
  }
124
124
  return connectionsCache;
125
125
  }
126
- async function getClient2(connectorSlug, connectorType) {
127
- if (!connectorSlug) {
128
- const cacheKey = "__squadbase-db__";
129
- const cached2 = clientCache.get(cacheKey);
130
- if (cached2) return cached2;
131
- const url = process.env.SQUADBASE_POSTGRESQL_URL;
132
- if (!url) throw new Error("SQUADBASE_POSTGRESQL_URL environment variable is not set");
133
- const client = createPostgreSQLClient(url);
134
- clientCache.set(cacheKey, client);
135
- return client;
136
- }
137
- const cached = clientCache.get(connectorSlug);
138
- if (cached) return cached;
126
+ async function getClient2(connectionId) {
139
127
  const connections = loadConnections();
140
- const entry = connections[connectorSlug];
128
+ const entry = connections[connectionId];
141
129
  if (!entry) {
142
- throw new Error(`connector slug '${connectorSlug}' not found in .squadbase/connections.json`);
143
- }
144
- const resolvedType = connectorType ?? entry.connectorType;
145
- if (!resolvedType) {
146
- throw new Error(
147
- `connector type could not be determined for slug '${connectorSlug}'. Specify connectorType in the data-source JSON or in .squadbase/connections.json.`
148
- );
130
+ throw new Error(`connection '${connectionId}' not found in .squadbase/connections.json`);
149
131
  }
150
- if (resolvedType === "snowflake") {
151
- return createSnowflakeClient(entry, connectorSlug);
132
+ const connectorSlug = entry.connector.slug;
133
+ const cached = clientCache.get(connectionId);
134
+ if (cached) return { client: cached, connectorSlug };
135
+ if (connectorSlug === "snowflake") {
136
+ return { client: createSnowflakeClient(entry, connectionId), connectorSlug };
152
137
  }
153
- if (resolvedType === "bigquery") {
154
- return createBigQueryClient(entry, connectorSlug);
138
+ if (connectorSlug === "bigquery") {
139
+ return { client: createBigQueryClient(entry, connectionId), connectorSlug };
155
140
  }
156
- if (resolvedType === "postgresql" || resolvedType === "squadbase-db") {
141
+ if (connectorSlug === "postgresql" || connectorSlug === "squadbase-db") {
157
142
  const urlEnvName = entry.envVars["connection-url"];
158
143
  if (!urlEnvName) {
159
- throw new Error(`'connection-url' is not defined in envVars for connector '${connectorSlug}'`);
144
+ throw new Error(`'connection-url' is not defined in envVars for connection '${connectionId}'`);
160
145
  }
161
146
  const connectionUrl = process.env[urlEnvName];
162
147
  if (!connectionUrl) {
163
148
  throw new Error(
164
- `environment variable '${urlEnvName}' (mapped from connector '${connectorSlug}') is not set`
149
+ `environment variable '${urlEnvName}' (mapped from connection '${connectionId}') is not set`
165
150
  );
166
151
  }
167
152
  const client = createPostgreSQLClient(connectionUrl);
168
- clientCache.set(connectorSlug, client);
169
- return client;
153
+ clientCache.set(connectionId, client);
154
+ return { client, connectorSlug };
170
155
  }
171
156
  throw new Error(
172
- `connector type '${resolvedType}' is not supported. Supported: "snowflake", "bigquery", "postgresql", "squadbase-db"`
157
+ `connector type '${connectorSlug}' is not supported. Supported: "snowflake", "bigquery", "postgresql", "squadbase-db"`
173
158
  );
174
159
  }
175
160
  function reloadEnvFile2(envPath) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squadbase/vite-server",
3
- "version": "0.0.1-build-4",
3
+ "version": "0.0.1-build-5",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
@@ -1 +0,0 @@
1
- #!/usr/bin/env node
package/dist/cli/index.js DELETED
@@ -1,659 +0,0 @@
1
- #!/usr/bin/env node
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropNames = Object.getOwnPropertyNames;
4
- var __esm = (fn, res) => function __init() {
5
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
- };
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
-
12
- // src/cli/interactive.ts
13
- var interactive_exports = {};
14
- __export(interactive_exports, {
15
- confirmRunAll: () => confirmRunAll,
16
- inputParameters: () => inputParameters,
17
- selectDataSource: () => selectDataSource
18
- });
19
- async function getPrompts() {
20
- try {
21
- const mod = await import("@clack/prompts");
22
- return mod;
23
- } catch {
24
- throw new Error(
25
- "@clack/prompts is not installed. Run: npm install @clack/prompts --save-dev"
26
- );
27
- }
28
- }
29
- async function selectDataSource(slugs) {
30
- const { select, isCancel } = await getPrompts();
31
- const result = await select({
32
- message: "Select a data source to test:",
33
- options: slugs.map((s) => ({ value: s, label: s }))
34
- });
35
- if (isCancel(result)) return null;
36
- return result;
37
- }
38
- async function inputParameters(params) {
39
- if (params.length === 0) return {};
40
- const { text, isCancel } = await getPrompts();
41
- const result = {};
42
- for (const p of params) {
43
- const defaultHint = p.default !== void 0 ? ` (default: ${p.default})` : "";
44
- const requiredHint = p.required ? " *required*" : "";
45
- const value = await text({
46
- message: `${p.name}${requiredHint} [${p.type}]${defaultHint}: ${p.description}`,
47
- placeholder: p.default !== void 0 ? String(p.default) : "",
48
- validate: (v) => {
49
- if (p.required && !v && p.default === void 0) {
50
- return `${p.name} is required`;
51
- }
52
- }
53
- });
54
- if (isCancel(value)) {
55
- process.exit(0);
56
- }
57
- const strValue = value;
58
- if (!strValue && p.default !== void 0) {
59
- result[p.name] = p.default;
60
- } else if (strValue) {
61
- if (p.type === "number") result[p.name] = Number(strValue);
62
- else if (p.type === "boolean") result[p.name] = strValue === "true";
63
- else result[p.name] = strValue;
64
- }
65
- }
66
- return result;
67
- }
68
- async function confirmRunAll() {
69
- const { confirm, isCancel } = await getPrompts();
70
- const result = await confirm({
71
- message: "Run all data sources?"
72
- });
73
- if (isCancel(result)) return false;
74
- return result;
75
- }
76
- var init_interactive = __esm({
77
- "src/cli/interactive.ts"() {
78
- "use strict";
79
- }
80
- });
81
-
82
- // src/cli/index.ts
83
- import { parseArgs } from "util";
84
- import path4 from "path";
85
- import { readFile as readFile3 } from "fs/promises";
86
-
87
- // src/connector-client/registry.ts
88
- import { readFileSync, watch as fsWatch } from "fs";
89
- import path from "path";
90
-
91
- // src/connector-client/postgresql.ts
92
- import pg from "pg";
93
- var { Pool } = pg;
94
- function createPostgreSQLClient(connectionString) {
95
- const pool = new Pool({ connectionString, ssl: { rejectUnauthorized: false } });
96
- return {
97
- async query(sql, params) {
98
- const result = await pool.query(sql, params);
99
- return { rows: result.rows };
100
- }
101
- };
102
- }
103
-
104
- // src/connector-client/env.ts
105
- function resolveEnvVar(entry, key, slug) {
106
- const envVarName = entry.envVars[key];
107
- if (!envVarName) {
108
- throw new Error(`Connector "${slug}" is missing envVars mapping for key "${key}"`);
109
- }
110
- const value = process.env[envVarName];
111
- if (!value) {
112
- throw new Error(`Environment variable "${envVarName}" (for "${slug}.${key}") is not set`);
113
- }
114
- return value;
115
- }
116
-
117
- // src/connector-client/bigquery.ts
118
- function createBigQueryClient(entry, slug) {
119
- const projectId = resolveEnvVar(entry, "project-id", slug);
120
- const serviceAccountJsonBase64 = resolveEnvVar(entry, "service-account-json-base64", slug);
121
- const serviceAccountJson = Buffer.from(serviceAccountJsonBase64, "base64").toString("utf-8");
122
- let gcpCredentials;
123
- try {
124
- gcpCredentials = JSON.parse(serviceAccountJson);
125
- } catch {
126
- throw new Error(
127
- `BigQuery service account JSON (decoded from base64) is not valid JSON for slug "${slug}"`
128
- );
129
- }
130
- return {
131
- async query(sql) {
132
- const { BigQuery } = await import("@google-cloud/bigquery");
133
- const bq = new BigQuery({ projectId, credentials: gcpCredentials });
134
- const [job] = await bq.createQueryJob({ query: sql });
135
- const [allRows] = await job.getQueryResults({ timeoutMs: 3e4 });
136
- return { rows: allRows };
137
- }
138
- };
139
- }
140
-
141
- // src/connector-client/snowflake.ts
142
- function createSnowflakeClient(entry, slug) {
143
- const accountIdentifier = resolveEnvVar(entry, "account", slug);
144
- const user = resolveEnvVar(entry, "user", slug);
145
- const role = resolveEnvVar(entry, "role", slug);
146
- const warehouse = resolveEnvVar(entry, "warehouse", slug);
147
- const privateKeyBase64 = resolveEnvVar(entry, "private-key-base64", slug);
148
- const privateKey = Buffer.from(privateKeyBase64, "base64").toString("utf-8");
149
- return {
150
- async query(sql) {
151
- const snowflake = (await import("snowflake-sdk")).default;
152
- snowflake.configure({ logLevel: "ERROR" });
153
- const connection = snowflake.createConnection({
154
- account: accountIdentifier,
155
- username: user,
156
- role,
157
- warehouse,
158
- authenticator: "SNOWFLAKE_JWT",
159
- privateKey
160
- });
161
- await new Promise((resolve, reject) => {
162
- connection.connect((err) => {
163
- if (err) reject(new Error(`Snowflake connect failed: ${err.message}`));
164
- else resolve();
165
- });
166
- });
167
- const rows = await new Promise((resolve, reject) => {
168
- connection.execute({
169
- sqlText: sql,
170
- complete: (err, _stmt, rows2) => {
171
- if (err) reject(new Error(`Snowflake query failed: ${err.message}`));
172
- else resolve(rows2 ?? []);
173
- }
174
- });
175
- });
176
- connection.destroy((err) => {
177
- if (err) console.warn(`[connector-client] Snowflake destroy error: ${err.message}`);
178
- });
179
- return { rows };
180
- }
181
- };
182
- }
183
-
184
- // src/connector-client/registry.ts
185
- function createConnectorRegistry() {
186
- let connectionsCache = null;
187
- const clientCache = /* @__PURE__ */ new Map();
188
- function getConnectionsFilePath() {
189
- return process.env.CONNECTIONS_PATH ?? path.join(process.cwd(), "../../.squadbase/connections.json");
190
- }
191
- function loadConnections() {
192
- if (connectionsCache !== null) return connectionsCache;
193
- const filePath = getConnectionsFilePath();
194
- try {
195
- const raw = readFileSync(filePath, "utf-8");
196
- connectionsCache = JSON.parse(raw);
197
- } catch {
198
- connectionsCache = {};
199
- }
200
- return connectionsCache;
201
- }
202
- async function getClient2(connectorSlug, connectorType) {
203
- if (!connectorSlug) {
204
- const cacheKey = "__squadbase-db__";
205
- const cached2 = clientCache.get(cacheKey);
206
- if (cached2) return cached2;
207
- const url = process.env.SQUADBASE_POSTGRESQL_URL;
208
- if (!url) throw new Error("SQUADBASE_POSTGRESQL_URL environment variable is not set");
209
- const client = createPostgreSQLClient(url);
210
- clientCache.set(cacheKey, client);
211
- return client;
212
- }
213
- const cached = clientCache.get(connectorSlug);
214
- if (cached) return cached;
215
- const connections = loadConnections();
216
- const entry = connections[connectorSlug];
217
- if (!entry) {
218
- throw new Error(`connector slug '${connectorSlug}' not found in .squadbase/connections.json`);
219
- }
220
- const resolvedType = connectorType ?? entry.connectorType;
221
- if (!resolvedType) {
222
- throw new Error(
223
- `connector type could not be determined for slug '${connectorSlug}'. Specify connectorType in the data-source JSON or in .squadbase/connections.json.`
224
- );
225
- }
226
- if (resolvedType === "snowflake") {
227
- return createSnowflakeClient(entry, connectorSlug);
228
- }
229
- if (resolvedType === "bigquery") {
230
- return createBigQueryClient(entry, connectorSlug);
231
- }
232
- if (resolvedType === "postgresql" || resolvedType === "squadbase-db") {
233
- const urlEnvName = entry.envVars["connection-url"];
234
- if (!urlEnvName) {
235
- throw new Error(`'connection-url' is not defined in envVars for connector '${connectorSlug}'`);
236
- }
237
- const connectionUrl = process.env[urlEnvName];
238
- if (!connectionUrl) {
239
- throw new Error(
240
- `environment variable '${urlEnvName}' (mapped from connector '${connectorSlug}') is not set`
241
- );
242
- }
243
- const client = createPostgreSQLClient(connectionUrl);
244
- clientCache.set(connectorSlug, client);
245
- return client;
246
- }
247
- throw new Error(
248
- `connector type '${resolvedType}' is not supported. Supported: "snowflake", "bigquery", "postgresql", "squadbase-db"`
249
- );
250
- }
251
- function reloadEnvFile2(envPath) {
252
- try {
253
- const raw = readFileSync(envPath, "utf-8");
254
- for (const line of raw.split("\n")) {
255
- const trimmed = line.trim();
256
- if (!trimmed || trimmed.startsWith("#")) continue;
257
- const eqIdx = trimmed.indexOf("=");
258
- if (eqIdx === -1) continue;
259
- const key = trimmed.slice(0, eqIdx).trim();
260
- const value = trimmed.slice(eqIdx + 1).trim();
261
- if (key) process.env[key] = value;
262
- }
263
- console.log("[connector-client] .env reloaded");
264
- } catch {
265
- }
266
- }
267
- function watchConnectionsFile2() {
268
- const filePath = getConnectionsFilePath();
269
- const envPath = path.join(process.cwd(), "..", "..", ".env");
270
- try {
271
- fsWatch(filePath, { persistent: false }, () => {
272
- console.log("[connector-client] connections.json changed, clearing cache");
273
- connectionsCache = null;
274
- clientCache.clear();
275
- setImmediate(() => reloadEnvFile2(envPath));
276
- });
277
- } catch {
278
- }
279
- }
280
- return { getClient: getClient2, reloadEnvFile: reloadEnvFile2, watchConnectionsFile: watchConnectionsFile2 };
281
- }
282
-
283
- // src/connector-client/index.ts
284
- var { getClient, reloadEnvFile, watchConnectionsFile } = createConnectorRegistry();
285
-
286
- // src/cli/env-loader.ts
287
- import { readFileSync as readFileSync2 } from "fs";
288
- function loadEnvFile(envPath) {
289
- reloadEnvFile(envPath);
290
- }
291
-
292
- // src/cli/runner.ts
293
- import { pathToFileURL } from "url";
294
- import { readFile as readFile2, readdir as readdir2 } from "fs/promises";
295
- import path3 from "path";
296
-
297
- // src/registry.ts
298
- import { readdir, readFile, mkdir } from "fs/promises";
299
- import { watch as fsWatch2 } from "fs";
300
- import path2 from "path";
301
- function buildQuery(queryTemplate, parameterMeta, runtimeParams) {
302
- const defaults = new Map(
303
- parameterMeta.map((p) => [p.name, p.default ?? null])
304
- );
305
- const placeholderToIndex = /* @__PURE__ */ new Map();
306
- const values = [];
307
- const text = queryTemplate.replace(
308
- /\{\{(\w+)\}\}/g,
309
- (_match, name) => {
310
- if (!placeholderToIndex.has(name)) {
311
- const value = Object.prototype.hasOwnProperty.call(runtimeParams, name) ? runtimeParams[name] : defaults.get(name) ?? null;
312
- values.push(value);
313
- placeholderToIndex.set(name, values.length);
314
- }
315
- return `$${placeholderToIndex.get(name)}`;
316
- }
317
- );
318
- return { text, values };
319
- }
320
- var defaultDataSourceDir = path2.join(process.cwd(), "data-source");
321
-
322
- // src/cli/runner.ts
323
- function createStubContext(params) {
324
- const stub = {
325
- req: {
326
- json: () => Promise.resolve(params),
327
- query: (name) => {
328
- if (name === void 0) {
329
- return Object.fromEntries(
330
- Object.entries(params).map(([k, v2]) => [k, String(v2)])
331
- );
332
- }
333
- const v = params[name];
334
- return v !== void 0 ? String(v) : "";
335
- },
336
- param: (_name) => void 0,
337
- header: (_name) => void 0,
338
- raw: new Request("http://localhost/cli")
339
- },
340
- json: (data) => data,
341
- text: (data) => data,
342
- body: (data) => data,
343
- env: {},
344
- var: {},
345
- get: (_key) => void 0,
346
- set: () => {
347
- }
348
- };
349
- return stub;
350
- }
351
- async function runSqlDataSource(slug, def, params, limit) {
352
- const start = Date.now();
353
- try {
354
- const client = await getClient(def.connectorSlug, def.connectorType);
355
- const isExternal = def.connectorType === "snowflake" || def.connectorType === "bigquery";
356
- let queryText;
357
- let queryValues;
358
- if (isExternal) {
359
- const defaults = new Map(
360
- (def.parameters ?? []).map((p) => [p.name, p.default ?? null])
361
- );
362
- queryText = def.query.replace(/\{\{(\w+)\}\}/g, (_match, name) => {
363
- const value = Object.prototype.hasOwnProperty.call(params, name) ? params[name] : defaults.get(name) ?? "";
364
- if (typeof value === "string") return `'${value.replace(/'/g, "''")}'`;
365
- if (value === null || value === void 0) return "NULL";
366
- return String(value);
367
- });
368
- queryValues = [];
369
- } else {
370
- const built = buildQuery(def.query, def.parameters ?? [], params);
371
- queryText = built.text;
372
- queryValues = built.values;
373
- }
374
- const result = await client.query(queryText, queryValues);
375
- const rows = result.rows.slice(0, limit);
376
- return {
377
- slug,
378
- rows,
379
- rowCount: result.rows.length,
380
- durationMs: Date.now() - start,
381
- query: queryText,
382
- queryValues
383
- };
384
- } catch (error) {
385
- return {
386
- slug,
387
- rows: [],
388
- rowCount: 0,
389
- durationMs: Date.now() - start,
390
- error: error instanceof Error ? error : new Error(String(error))
391
- };
392
- }
393
- }
394
- async function runTypescriptDataSource(slug, handlerPath, params) {
395
- const start = Date.now();
396
- try {
397
- const mod = await import(pathToFileURL(handlerPath).href);
398
- const handler = mod.default;
399
- if (typeof handler !== "function") {
400
- throw new Error(`Handler must export a default function: ${handlerPath}`);
401
- }
402
- const ctx = createStubContext(params);
403
- const raw = await handler(ctx);
404
- let rows;
405
- if (Array.isArray(raw)) {
406
- rows = raw;
407
- } else if (raw !== null && typeof raw === "object") {
408
- rows = [raw];
409
- } else {
410
- rows = [{ result: raw }];
411
- }
412
- return {
413
- slug,
414
- rows,
415
- rowCount: rows.length,
416
- durationMs: Date.now() - start
417
- };
418
- } catch (error) {
419
- return {
420
- slug,
421
- rows: [],
422
- rowCount: 0,
423
- durationMs: Date.now() - start,
424
- error: error instanceof Error ? error : new Error(String(error))
425
- };
426
- }
427
- }
428
- async function runDataSource(slug, dirPath, params, limit) {
429
- const jsonPath = path3.join(dirPath, `${slug}.json`);
430
- let def;
431
- try {
432
- const raw = await readFile2(jsonPath, "utf-8");
433
- def = JSON.parse(raw);
434
- } catch {
435
- return {
436
- slug,
437
- rows: [],
438
- rowCount: 0,
439
- durationMs: 0,
440
- error: new Error(`Data source not found: ${jsonPath}`)
441
- };
442
- }
443
- if (def.type === "typescript") {
444
- const absolutePath = path3.resolve(dirPath, def.handlerPath);
445
- return runTypescriptDataSource(slug, absolutePath, params);
446
- }
447
- return runSqlDataSource(slug, def, params, limit);
448
- }
449
- async function listSlugs(dirPath) {
450
- try {
451
- const files = await readdir2(dirPath);
452
- return files.filter((f) => f.endsWith(".json")).map((f) => f.replace(/\.json$/, ""));
453
- } catch {
454
- return [];
455
- }
456
- }
457
- async function runAll(dirPath, params, limit) {
458
- const slugs = await listSlugs(dirPath);
459
- return Promise.all(slugs.map((slug) => runDataSource(slug, dirPath, params, limit)));
460
- }
461
-
462
- // src/cli/display.ts
463
- var RESET = "\x1B[0m";
464
- var BOLD = "\x1B[1m";
465
- var RED = "\x1B[31m";
466
- var GREEN = "\x1B[32m";
467
- var YELLOW = "\x1B[33m";
468
- var CYAN = "\x1B[36m";
469
- var DIM = "\x1B[2m";
470
- function truncate(value, maxLen) {
471
- return value.length > maxLen ? value.slice(0, maxLen - 1) + "\u2026" : value;
472
- }
473
- function formatValue(value) {
474
- if (value === null || value === void 0) return DIM + "null" + RESET;
475
- if (typeof value === "object") return JSON.stringify(value);
476
- return String(value);
477
- }
478
- function displayTable(rows, limit) {
479
- if (rows.length === 0) {
480
- console.log(DIM + " (no rows)" + RESET);
481
- return;
482
- }
483
- const display = rows.slice(0, limit);
484
- const columns = Object.keys(display[0] ?? {});
485
- const colWidths = columns.map((col) => {
486
- const maxData = Math.max(...display.map((r) => formatValue(r[col]).replace(/\x1b\[[0-9;]*m/g, "").length));
487
- return Math.min(40, Math.max(col.length, maxData));
488
- });
489
- const header = columns.map((c, i) => BOLD + CYAN + c.padEnd(colWidths[i] ?? 0) + RESET).join(" ");
490
- const divider = colWidths.map((w) => "-".repeat(w)).join("--");
491
- console.log(" " + header);
492
- console.log(" " + DIM + divider + RESET);
493
- for (const row of display) {
494
- const line = columns.map((c, i) => {
495
- const raw = formatValue(row[c]);
496
- const plain = raw.replace(/\x1b\[[0-9;]*m/g, "");
497
- const padded = truncate(plain, colWidths[i] ?? 40).padEnd(colWidths[i] ?? 0);
498
- return raw.startsWith(DIM) ? DIM + padded + RESET : padded;
499
- }).join(" ");
500
- console.log(" " + line);
501
- }
502
- if (rows.length > limit) {
503
- console.log(DIM + ` \u2026 and ${rows.length - limit} more rows (use --limit to show more)` + RESET);
504
- }
505
- }
506
- function displaySummary(result) {
507
- const status = result.error ? RED + "\u2717 FAIL" + RESET : GREEN + "\u2713 OK" + RESET;
508
- const duration = DIM + `(${result.durationMs}ms)` + RESET;
509
- console.log(`
510
- ${BOLD}[${result.slug}]${RESET} ${status} ${duration}`);
511
- if (result.error) {
512
- console.log(RED + ` Error: ${result.error.message}` + RESET);
513
- return;
514
- }
515
- console.log(DIM + ` ${result.rowCount} row(s)` + RESET);
516
- }
517
- function displayDebug(result) {
518
- if (result.query) {
519
- console.log(YELLOW + " Query:" + RESET);
520
- console.log(DIM + ` ${result.query.replace(/\n/g, "\n ")}` + RESET);
521
- }
522
- if (result.queryValues && result.queryValues.length > 0) {
523
- console.log(YELLOW + " Params:" + RESET, result.queryValues);
524
- }
525
- }
526
- function displayJson(results) {
527
- const output = results.map((r) => ({
528
- slug: r.slug,
529
- rowCount: r.rowCount,
530
- durationMs: r.durationMs,
531
- rows: r.rows,
532
- error: r.error?.message
533
- }));
534
- console.log(JSON.stringify(output, null, 2));
535
- }
536
- function displayError(error) {
537
- console.error(RED + "Error: " + error.message + RESET);
538
- }
539
-
540
- // src/cli/index.ts
541
- var HELP = `
542
- Usage: squadbase-ds-test [options]
543
-
544
- Options:
545
- --slug <slug> Run a specific data source
546
- --all Run all data sources
547
- --params k=v,... Comma-separated key=value parameters
548
- --env <path> Path to .env file (default: ../../.env)
549
- --dir <path> Data source directory (default: ./data-source)
550
- --format table|json Output format (default: table)
551
- --limit <n> Max rows to display (default: 50)
552
- --debug Show SQL query and parameter values
553
- --help Show this help
554
-
555
- Examples:
556
- npx tsx src/cli/index.ts --slug sales-summary
557
- npx tsx src/cli/index.ts --slug sales-summary --params year=2024,limit=10
558
- npx tsx src/cli/index.ts --all --format json
559
- npx tsx src/cli/index.ts # interactive mode
560
- `;
561
- async function main() {
562
- const { values } = parseArgs({
563
- options: {
564
- slug: { type: "string" },
565
- all: { type: "boolean", default: false },
566
- params: { type: "string" },
567
- env: { type: "string" },
568
- dir: { type: "string" },
569
- format: { type: "string", default: "table" },
570
- limit: { type: "string", default: "50" },
571
- debug: { type: "boolean", default: false },
572
- help: { type: "boolean", default: false }
573
- },
574
- allowPositionals: false
575
- });
576
- if (values.help) {
577
- console.log(HELP);
578
- process.exit(0);
579
- }
580
- const cwd = process.cwd();
581
- const dirPath = values.dir ? path4.resolve(cwd, values.dir) : path4.join(cwd, "data-source");
582
- const envPath = values.env ? path4.resolve(cwd, values.env) : path4.join(cwd, "../../.env");
583
- const limit = parseInt(values.limit ?? "50", 10);
584
- const format = values.format ?? "table";
585
- loadEnvFile(envPath);
586
- const params = {};
587
- if (values.params) {
588
- for (const pair of values.params.split(",")) {
589
- const eqIdx = pair.indexOf("=");
590
- if (eqIdx === -1) continue;
591
- const key = pair.slice(0, eqIdx).trim();
592
- const val = pair.slice(eqIdx + 1).trim();
593
- params[key] = val;
594
- }
595
- }
596
- if (values.slug) {
597
- const result = await runDataSource(values.slug, dirPath, params, limit);
598
- if (format === "json") {
599
- displayJson([result]);
600
- } else {
601
- displaySummary(result);
602
- if (values.debug) displayDebug(result);
603
- if (!result.error) displayTable(result.rows, limit);
604
- }
605
- if (result.error) process.exit(1);
606
- } else if (values.all) {
607
- const results = await runAll(dirPath, params, limit);
608
- if (format === "json") {
609
- displayJson(results);
610
- } else {
611
- for (const r of results) {
612
- displaySummary(r);
613
- if (values.debug) displayDebug(r);
614
- if (!r.error) displayTable(r.rows, limit);
615
- }
616
- const failed = results.filter((r) => r.error).length;
617
- console.log(`
618
- Total: ${results.length}, Failed: ${failed}`);
619
- }
620
- const anyFailed = results.some((r) => r.error);
621
- if (anyFailed) process.exit(1);
622
- } else {
623
- const slugs = await listSlugs(dirPath);
624
- if (slugs.length === 0) {
625
- displayError(new Error(`No data sources found in ${dirPath}`));
626
- process.exit(1);
627
- }
628
- try {
629
- const { selectDataSource: selectDataSource2, inputParameters: inputParameters2 } = await Promise.resolve().then(() => (init_interactive(), interactive_exports));
630
- const slug = await selectDataSource2(slugs);
631
- if (!slug) {
632
- console.log("Cancelled.");
633
- process.exit(0);
634
- }
635
- const jsonPath = path4.join(dirPath, `${slug}.json`);
636
- let paramMeta = [];
637
- try {
638
- const raw = await readFile3(jsonPath, "utf-8");
639
- const def = JSON.parse(raw);
640
- paramMeta = def.parameters ?? [];
641
- } catch {
642
- }
643
- const interactiveParams = await inputParameters2(paramMeta);
644
- const merged = { ...interactiveParams, ...params };
645
- const result = await runDataSource(slug, dirPath, merged, limit);
646
- displaySummary(result);
647
- if (values.debug) displayDebug(result);
648
- if (!result.error) displayTable(result.rows, limit);
649
- if (result.error) process.exit(1);
650
- } catch (err) {
651
- displayError(err instanceof Error ? err : new Error(String(err)));
652
- process.exit(1);
653
- }
654
- }
655
- }
656
- main().catch((err) => {
657
- displayError(err instanceof Error ? err : new Error(String(err)));
658
- process.exit(1);
659
- });