@squadbase/connectors 0.0.12 → 0.0.14

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/sdk.js CHANGED
@@ -1,18 +1,22 @@
1
1
  import {
2
2
  parameters,
3
- parameters2
4
- } from "./chunk-E5AVUXWJ.js";
3
+ parameters2,
4
+ parameters3,
5
+ parameters4,
6
+ parameters5,
7
+ parameters6
8
+ } from "./chunk-4K4NERCT.js";
5
9
 
6
10
  // src/connectors/kintone/sdk/index.ts
7
11
  function createClient(params) {
8
- const baseUrl = params[parameters.baseUrl.slug];
9
- const username = params[parameters.username.slug];
10
- const password = params[parameters.password.slug];
12
+ const baseUrl = params[parameters3.baseUrl.slug];
13
+ const username = params[parameters3.username.slug];
14
+ const password = params[parameters3.password.slug];
11
15
  if (!baseUrl || !username || !password) {
12
16
  const required = [
13
- parameters.baseUrl.slug,
14
- parameters.username.slug,
15
- parameters.password.slug
17
+ parameters3.baseUrl.slug,
18
+ parameters3.username.slug,
19
+ parameters3.password.slug
16
20
  ];
17
21
  const missing = required.filter((s) => !params[s]);
18
22
  throw new Error(
@@ -74,15 +78,668 @@ function createClient(params) {
74
78
 
75
79
  // src/connectors/openai/sdk/index.ts
76
80
  function createClient2(params) {
77
- const apiKey = params[parameters2.apiKey.slug];
81
+ const apiKey = params[parameters6.apiKey.slug];
78
82
  if (!apiKey) {
79
83
  throw new Error(
80
- `openai: missing required parameter: ${parameters2.apiKey.slug}`
84
+ `openai: missing required parameter: ${parameters6.apiKey.slug}`
81
85
  );
82
86
  }
83
87
  return { apiKey };
84
88
  }
89
+
90
+ // src/connectors/airtable/sdk/index.ts
91
+ var BASE_URL = "https://api.airtable.com/v0";
92
+ function createClient3(params) {
93
+ const baseId = params[parameters.baseId.slug];
94
+ const apiKey = params[parameters.apiKey.slug];
95
+ if (!baseId || !apiKey) {
96
+ const required = [parameters.baseId.slug, parameters.apiKey.slug];
97
+ const missing = required.filter((s) => !params[s]);
98
+ throw new Error(
99
+ `airtable: missing required parameters: ${missing.join(", ")}`
100
+ );
101
+ }
102
+ function request(path, init) {
103
+ const resolvedPath = path.replace(/\{baseId\}/g, baseId);
104
+ const url = `${BASE_URL}${resolvedPath.startsWith("/") ? "" : "/"}${resolvedPath}`;
105
+ const headers = new Headers(init?.headers);
106
+ headers.set("Authorization", `Bearer ${apiKey}`);
107
+ return fetch(url, { ...init, headers });
108
+ }
109
+ async function listRecords(tableIdOrName, options) {
110
+ const searchParams = new URLSearchParams();
111
+ if (options?.fields) {
112
+ for (const field of options.fields) {
113
+ searchParams.append("fields[]", field);
114
+ }
115
+ }
116
+ if (options?.filterByFormula) {
117
+ searchParams.set("filterByFormula", options.filterByFormula);
118
+ }
119
+ if (options?.maxRecords != null) {
120
+ searchParams.set("maxRecords", String(options.maxRecords));
121
+ }
122
+ if (options?.sort) {
123
+ for (let i = 0; i < options.sort.length; i++) {
124
+ searchParams.set(`sort[${i}][field]`, options.sort[i].field);
125
+ if (options.sort[i].direction) {
126
+ searchParams.set(
127
+ `sort[${i}][direction]`,
128
+ options.sort[i].direction
129
+ );
130
+ }
131
+ }
132
+ }
133
+ if (options?.pageSize != null) {
134
+ searchParams.set("pageSize", String(options.pageSize));
135
+ }
136
+ if (options?.view) {
137
+ searchParams.set("view", options.view);
138
+ }
139
+ if (options?.offset) {
140
+ searchParams.set("offset", options.offset);
141
+ }
142
+ const qs = searchParams.toString();
143
+ const path = `/${baseId}/${encodeURIComponent(tableIdOrName)}${qs ? `?${qs}` : ""}`;
144
+ const response = await request(path);
145
+ if (!response.ok) {
146
+ const body = await response.text();
147
+ throw new Error(
148
+ `airtable: listRecords failed (${response.status}): ${body}`
149
+ );
150
+ }
151
+ return await response.json();
152
+ }
153
+ async function getRecord(tableIdOrName, recordId) {
154
+ const path = `/${baseId}/${encodeURIComponent(tableIdOrName)}/${encodeURIComponent(recordId)}`;
155
+ const response = await request(path);
156
+ if (!response.ok) {
157
+ const body = await response.text();
158
+ throw new Error(
159
+ `airtable: getRecord failed (${response.status}): ${body}`
160
+ );
161
+ }
162
+ return await response.json();
163
+ }
164
+ async function createRecords(tableIdOrName, records, options) {
165
+ const payload = { records };
166
+ if (options?.typecast != null) {
167
+ payload.typecast = options.typecast;
168
+ }
169
+ const path = `/${baseId}/${encodeURIComponent(tableIdOrName)}`;
170
+ const response = await request(path, {
171
+ method: "POST",
172
+ headers: { "Content-Type": "application/json" },
173
+ body: JSON.stringify(payload)
174
+ });
175
+ if (!response.ok) {
176
+ const body = await response.text();
177
+ throw new Error(
178
+ `airtable: createRecords failed (${response.status}): ${body}`
179
+ );
180
+ }
181
+ return await response.json();
182
+ }
183
+ async function updateRecords(tableIdOrName, records, options) {
184
+ const payload = { records };
185
+ if (options?.typecast != null) {
186
+ payload.typecast = options.typecast;
187
+ }
188
+ const path = `/${baseId}/${encodeURIComponent(tableIdOrName)}`;
189
+ const response = await request(path, {
190
+ method: "PATCH",
191
+ headers: { "Content-Type": "application/json" },
192
+ body: JSON.stringify(payload)
193
+ });
194
+ if (!response.ok) {
195
+ const body = await response.text();
196
+ throw new Error(
197
+ `airtable: updateRecords failed (${response.status}): ${body}`
198
+ );
199
+ }
200
+ return await response.json();
201
+ }
202
+ async function listTables() {
203
+ const path = `/meta/bases/${baseId}/tables`;
204
+ const response = await request(path);
205
+ if (!response.ok) {
206
+ const body = await response.text();
207
+ throw new Error(
208
+ `airtable: listTables failed (${response.status}): ${body}`
209
+ );
210
+ }
211
+ return await response.json();
212
+ }
213
+ return {
214
+ request,
215
+ listRecords,
216
+ getRecord,
217
+ createRecords,
218
+ updateRecords,
219
+ listTables
220
+ };
221
+ }
222
+
223
+ // src/connectors/google-analytics/sdk/index.ts
224
+ import * as crypto from "crypto";
225
+ var TOKEN_URL = "https://oauth2.googleapis.com/token";
226
+ var BASE_URL2 = "https://analyticsdata.googleapis.com/v1beta/";
227
+ var SCOPE = "https://www.googleapis.com/auth/analytics.readonly";
228
+ function base64url(input) {
229
+ const buf = typeof input === "string" ? Buffer.from(input) : input;
230
+ return buf.toString("base64url");
231
+ }
232
+ function buildJwt(clientEmail, privateKey, nowSec) {
233
+ const header = base64url(JSON.stringify({ alg: "RS256", typ: "JWT" }));
234
+ const payload = base64url(
235
+ JSON.stringify({
236
+ iss: clientEmail,
237
+ scope: SCOPE,
238
+ aud: TOKEN_URL,
239
+ iat: nowSec,
240
+ exp: nowSec + 3600
241
+ })
242
+ );
243
+ const signingInput = `${header}.${payload}`;
244
+ const sign = crypto.createSign("RSA-SHA256");
245
+ sign.update(signingInput);
246
+ sign.end();
247
+ const signature = base64url(sign.sign(privateKey));
248
+ return `${signingInput}.${signature}`;
249
+ }
250
+ function createClient4(params) {
251
+ const serviceAccountKeyJsonBase64 = params[parameters2.serviceAccountKeyJsonBase64.slug];
252
+ const propertyId = params[parameters2.propertyId.slug];
253
+ if (!serviceAccountKeyJsonBase64 || !propertyId) {
254
+ const required = [
255
+ parameters2.serviceAccountKeyJsonBase64.slug,
256
+ parameters2.propertyId.slug
257
+ ];
258
+ const missing = required.filter((s) => !params[s]);
259
+ throw new Error(
260
+ `google-analytics: missing required parameters: ${missing.join(", ")}`
261
+ );
262
+ }
263
+ let serviceAccountKey;
264
+ try {
265
+ const decoded = Buffer.from(
266
+ serviceAccountKeyJsonBase64,
267
+ "base64"
268
+ ).toString("utf-8");
269
+ serviceAccountKey = JSON.parse(decoded);
270
+ } catch {
271
+ throw new Error(
272
+ "google-analytics: failed to decode service account key JSON from base64"
273
+ );
274
+ }
275
+ if (!serviceAccountKey.client_email || !serviceAccountKey.private_key) {
276
+ throw new Error(
277
+ "google-analytics: service account key JSON must contain client_email and private_key"
278
+ );
279
+ }
280
+ let cachedToken = null;
281
+ let tokenExpiresAt = 0;
282
+ async function getAccessToken() {
283
+ const nowSec = Math.floor(Date.now() / 1e3);
284
+ if (cachedToken && nowSec < tokenExpiresAt - 60) {
285
+ return cachedToken;
286
+ }
287
+ const jwt = buildJwt(
288
+ serviceAccountKey.client_email,
289
+ serviceAccountKey.private_key,
290
+ nowSec
291
+ );
292
+ const response = await fetch(TOKEN_URL, {
293
+ method: "POST",
294
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
295
+ body: new URLSearchParams({
296
+ grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
297
+ assertion: jwt
298
+ })
299
+ });
300
+ if (!response.ok) {
301
+ const text = await response.text();
302
+ throw new Error(
303
+ `google-analytics: token exchange failed (${response.status}): ${text}`
304
+ );
305
+ }
306
+ const data = await response.json();
307
+ cachedToken = data.access_token;
308
+ tokenExpiresAt = nowSec + data.expires_in;
309
+ return cachedToken;
310
+ }
311
+ return {
312
+ async request(path, init) {
313
+ const accessToken = await getAccessToken();
314
+ const resolvedPath = path.replace(/\{propertyId\}/g, propertyId);
315
+ const url = `${BASE_URL2.replace(/\/+$/, "")}/${resolvedPath.replace(/^\/+/, "")}`;
316
+ const headers = new Headers(init?.headers);
317
+ headers.set("Authorization", `Bearer ${accessToken}`);
318
+ return fetch(url, { ...init, headers });
319
+ },
320
+ async runReport(request) {
321
+ const response = await this.request(
322
+ `properties/${propertyId}:runReport`,
323
+ {
324
+ method: "POST",
325
+ headers: { "Content-Type": "application/json" },
326
+ body: JSON.stringify(request)
327
+ }
328
+ );
329
+ if (!response.ok) {
330
+ const text = await response.text();
331
+ throw new Error(
332
+ `google-analytics: runReport failed (${response.status}): ${text}`
333
+ );
334
+ }
335
+ const data = await response.json();
336
+ return {
337
+ rows: data.rows ?? [],
338
+ rowCount: data.rowCount ?? 0
339
+ };
340
+ },
341
+ async getMetadata() {
342
+ const response = await this.request(
343
+ `properties/${propertyId}/metadata`,
344
+ { method: "GET" }
345
+ );
346
+ if (!response.ok) {
347
+ const text = await response.text();
348
+ throw new Error(
349
+ `google-analytics: getMetadata failed (${response.status}): ${text}`
350
+ );
351
+ }
352
+ return await response.json();
353
+ },
354
+ async runRealtimeReport(request) {
355
+ const response = await this.request(
356
+ `properties/${propertyId}:runRealtimeReport`,
357
+ {
358
+ method: "POST",
359
+ headers: { "Content-Type": "application/json" },
360
+ body: JSON.stringify(request)
361
+ }
362
+ );
363
+ if (!response.ok) {
364
+ const text = await response.text();
365
+ throw new Error(
366
+ `google-analytics: runRealtimeReport failed (${response.status}): ${text}`
367
+ );
368
+ }
369
+ const data = await response.json();
370
+ return {
371
+ rows: data.rows ?? [],
372
+ rowCount: data.rowCount ?? 0
373
+ };
374
+ }
375
+ };
376
+ }
377
+
378
+ // src/connectors/wix-store/sdk/index.ts
379
+ function createClient5(params) {
380
+ const accountId = params[parameters4.accountId.slug];
381
+ const siteId = params[parameters4.siteId.slug];
382
+ const apiKey = params[parameters4.apiKey.slug];
383
+ if (!accountId || !siteId || !apiKey) {
384
+ const required = [
385
+ parameters4.accountId.slug,
386
+ parameters4.siteId.slug,
387
+ parameters4.apiKey.slug
388
+ ];
389
+ const missing = required.filter((s) => !params[s]);
390
+ throw new Error(
391
+ `wix-store: missing required parameters: ${missing.join(", ")}`
392
+ );
393
+ }
394
+ const baseUrl = "https://www.wixapis.com";
395
+ function authHeaders(extra) {
396
+ const headers = new Headers(extra);
397
+ headers.set("Authorization", apiKey);
398
+ headers.set("wix-site-id", siteId);
399
+ return headers;
400
+ }
401
+ async function assertOk(res, label) {
402
+ if (!res.ok) {
403
+ const body = await res.text().catch(() => "(unreadable body)");
404
+ throw new Error(
405
+ `wix-store ${label}: ${res.status} ${res.statusText} \u2014 ${body}`
406
+ );
407
+ }
408
+ }
409
+ return {
410
+ request(path, init) {
411
+ const url = `${baseUrl}${path}`;
412
+ const headers = new Headers(init?.headers);
413
+ headers.set("Authorization", apiKey);
414
+ headers.set("wix-site-id", siteId);
415
+ return fetch(url, { ...init, headers });
416
+ },
417
+ async queryProducts(options) {
418
+ const query = {};
419
+ if (options?.filter) query.filter = options.filter;
420
+ if (options?.sort) query.sort = options.sort;
421
+ if (options?.paging) query.paging = options.paging;
422
+ const res = await fetch(`${baseUrl}/stores/v1/products/query`, {
423
+ method: "POST",
424
+ headers: authHeaders({ "Content-Type": "application/json" }),
425
+ body: JSON.stringify({ query })
426
+ });
427
+ await assertOk(res, "queryProducts");
428
+ const json = await res.json();
429
+ return {
430
+ products: json.products ?? [],
431
+ totalResults: json.totalResults ?? 0
432
+ };
433
+ },
434
+ async getProduct(productId) {
435
+ const res = await fetch(
436
+ `${baseUrl}/stores/v1/products/${encodeURIComponent(productId)}`,
437
+ { method: "GET", headers: authHeaders() }
438
+ );
439
+ await assertOk(res, "getProduct");
440
+ const json = await res.json();
441
+ return { product: json.product };
442
+ },
443
+ async queryOrders(options) {
444
+ const search = {};
445
+ if (options?.filter) search.filter = options.filter;
446
+ if (options?.sort) search.sort = options.sort;
447
+ if (options?.cursorPaging) search.cursorPaging = options.cursorPaging;
448
+ const res = await fetch(`${baseUrl}/ecom/v1/orders/search`, {
449
+ method: "POST",
450
+ headers: authHeaders({ "Content-Type": "application/json" }),
451
+ body: JSON.stringify({ search })
452
+ });
453
+ await assertOk(res, "queryOrders");
454
+ const json = await res.json();
455
+ return {
456
+ orders: json.orders ?? [],
457
+ pagingMetadata: json.pagingMetadata
458
+ };
459
+ },
460
+ async getOrder(orderId) {
461
+ const res = await fetch(
462
+ `${baseUrl}/ecom/v1/orders/${encodeURIComponent(orderId)}`,
463
+ { method: "GET", headers: authHeaders() }
464
+ );
465
+ await assertOk(res, "getOrder");
466
+ const json = await res.json();
467
+ return { order: json.order };
468
+ },
469
+ async queryCollections(options) {
470
+ const query = {};
471
+ if (options?.filter) query.filter = options.filter;
472
+ if (options?.sort) query.sort = options.sort;
473
+ if (options?.paging) query.paging = options.paging;
474
+ const res = await fetch(`${baseUrl}/stores/v1/collections/query`, {
475
+ method: "POST",
476
+ headers: authHeaders({ "Content-Type": "application/json" }),
477
+ body: JSON.stringify({ query })
478
+ });
479
+ await assertOk(res, "queryCollections");
480
+ const json = await res.json();
481
+ return {
482
+ collections: json.collections ?? []
483
+ };
484
+ },
485
+ async queryInventory(options) {
486
+ const query = {};
487
+ if (options?.filter) query.filter = options.filter;
488
+ if (options?.paging) query.paging = options.paging;
489
+ const res = await fetch(`${baseUrl}/stores/v2/inventoryItems/query`, {
490
+ method: "POST",
491
+ headers: authHeaders({ "Content-Type": "application/json" }),
492
+ body: JSON.stringify({ query })
493
+ });
494
+ await assertOk(res, "queryInventory");
495
+ const json = await res.json();
496
+ return {
497
+ inventoryItems: json.inventoryItems ?? [],
498
+ totalResults: json.totalResults ?? 0
499
+ };
500
+ }
501
+ };
502
+ }
503
+
504
+ // src/connectors/dbt/sdk/index.ts
505
+ function createClient6(params) {
506
+ const host = params[parameters5.host.slug];
507
+ const prodEnvId = params[parameters5.prodEnvId.slug];
508
+ const token = params[parameters5.token.slug];
509
+ if (!host || !prodEnvId || !token) {
510
+ const required = [
511
+ parameters5.host.slug,
512
+ parameters5.prodEnvId.slug,
513
+ parameters5.token.slug
514
+ ];
515
+ const missing = required.filter((s) => !params[s]);
516
+ throw new Error(
517
+ `dbt: missing required parameters: ${missing.join(", ")}`
518
+ );
519
+ }
520
+ const baseUrl = `https://${host.replace(/\/+$/, "")}`;
521
+ const environmentId = Number(prodEnvId);
522
+ function resolveGraphqlEndpoint() {
523
+ if (host.includes("emea")) return "https://metadata.emea.dbt.com/graphql";
524
+ if (host.includes(".au.")) return "https://metadata.au.dbt.com/graphql";
525
+ return "https://metadata.cloud.getdbt.com/graphql";
526
+ }
527
+ async function graphqlRequest(graphqlQuery, variables) {
528
+ const mergedVariables = {
529
+ environmentId,
530
+ ...variables
531
+ };
532
+ const response = await fetch(resolveGraphqlEndpoint(), {
533
+ method: "POST",
534
+ headers: {
535
+ "Content-Type": "application/json",
536
+ Authorization: `Bearer ${token}`
537
+ },
538
+ body: JSON.stringify({
539
+ query: graphqlQuery,
540
+ variables: mergedVariables
541
+ })
542
+ });
543
+ if (!response.ok) {
544
+ const body = await response.text().catch(() => "(unreadable body)");
545
+ throw new Error(
546
+ `dbt Discovery API error: ${response.status} ${response.statusText} \u2014 ${body}`
547
+ );
548
+ }
549
+ const json = await response.json();
550
+ if (json.errors && json.errors.length > 0) {
551
+ throw new Error(
552
+ `dbt GraphQL error: ${json.errors.map((e) => e.message).join("; ")}`
553
+ );
554
+ }
555
+ return json.data ?? {};
556
+ }
557
+ return {
558
+ request(path, init) {
559
+ const resolvedPath = path.replace(
560
+ /\{environmentId\}/g,
561
+ prodEnvId
562
+ );
563
+ const url = `${baseUrl}${resolvedPath}`;
564
+ const headers = new Headers(init?.headers);
565
+ headers.set("Authorization", `Bearer ${token}`);
566
+ return fetch(url, { ...init, headers });
567
+ },
568
+ query(graphqlQuery, variables) {
569
+ return graphqlRequest(graphqlQuery, variables);
570
+ },
571
+ async getModels(options) {
572
+ const first = options?.limit ?? 500;
573
+ const data = await graphqlRequest(
574
+ `query ($environmentId: BigInt!, $first: Int!) {
575
+ environment(id: $environmentId) {
576
+ applied {
577
+ models(first: $first) {
578
+ edges {
579
+ node {
580
+ uniqueId
581
+ name
582
+ description
583
+ materializedType
584
+ database
585
+ schema
586
+ alias
587
+ }
588
+ }
589
+ }
590
+ }
591
+ }
592
+ }`,
593
+ { first }
594
+ );
595
+ const env = data.environment;
596
+ const applied = env?.applied;
597
+ const models = applied?.models;
598
+ const edges = models?.edges ?? [];
599
+ return edges.map((edge) => edge.node);
600
+ },
601
+ async getModelByUniqueId(uniqueId) {
602
+ const data = await graphqlRequest(
603
+ `query ($environmentId: BigInt!, $uniqueIds: [String!]) {
604
+ environment(id: $environmentId) {
605
+ applied {
606
+ models(first: 1, filter: { uniqueIds: $uniqueIds }) {
607
+ edges {
608
+ node {
609
+ uniqueId
610
+ name
611
+ description
612
+ materializedType
613
+ database
614
+ schema
615
+ alias
616
+ catalog {
617
+ columns {
618
+ name
619
+ type
620
+ description
621
+ }
622
+ }
623
+ }
624
+ }
625
+ }
626
+ }
627
+ }
628
+ }`,
629
+ { uniqueIds: [uniqueId] }
630
+ );
631
+ const env = data.environment;
632
+ const applied = env?.applied;
633
+ const models = applied?.models;
634
+ const edges = models?.edges ?? [];
635
+ return edges.length > 0 ? edges[0].node : null;
636
+ },
637
+ async getSources(options) {
638
+ const first = options?.limit ?? 500;
639
+ const data = await graphqlRequest(
640
+ `query ($environmentId: BigInt!, $first: Int!) {
641
+ environment(id: $environmentId) {
642
+ applied {
643
+ sources(first: $first) {
644
+ edges {
645
+ node {
646
+ uniqueId
647
+ name
648
+ description
649
+ database
650
+ schema
651
+ identifier
652
+ sourceName
653
+ loader
654
+ freshness {
655
+ freshnessStatus
656
+ maxLoadedAt
657
+ freshnessChecked
658
+ }
659
+ }
660
+ }
661
+ }
662
+ }
663
+ }
664
+ }`,
665
+ { first }
666
+ );
667
+ const env = data.environment;
668
+ const applied = env?.applied;
669
+ const sources = applied?.sources;
670
+ const edges = sources?.edges ?? [];
671
+ return edges.map((edge) => edge.node);
672
+ },
673
+ async getTests(options) {
674
+ const first = options?.limit ?? 500;
675
+ const data = await graphqlRequest(
676
+ `query ($environmentId: BigInt!, $first: Int!) {
677
+ environment(id: $environmentId) {
678
+ applied {
679
+ tests(first: $first) {
680
+ edges {
681
+ node {
682
+ uniqueId
683
+ name
684
+ columnName
685
+ testType
686
+ lastKnownResult
687
+ executionInfo {
688
+ lastRunStatus
689
+ executionTime
690
+ lastRunGeneratedAt
691
+ }
692
+ }
693
+ }
694
+ }
695
+ }
696
+ }
697
+ }`,
698
+ { first }
699
+ );
700
+ const env = data.environment;
701
+ const applied = env?.applied;
702
+ const tests = applied?.tests;
703
+ const edges = tests?.edges ?? [];
704
+ return edges.map((edge) => edge.node);
705
+ },
706
+ async getMetrics(options) {
707
+ const first = options?.limit ?? 500;
708
+ const data = await graphqlRequest(
709
+ `query ($environmentId: BigInt!, $first: Int!) {
710
+ environment(id: $environmentId) {
711
+ definition {
712
+ metrics(first: $first) {
713
+ edges {
714
+ node {
715
+ uniqueId
716
+ name
717
+ description
718
+ type
719
+ label
720
+ filter
721
+ formula
722
+ }
723
+ }
724
+ }
725
+ }
726
+ }
727
+ }`,
728
+ { first }
729
+ );
730
+ const env = data.environment;
731
+ const definition = env?.definition;
732
+ const metrics = definition?.metrics;
733
+ const edges = metrics?.edges ?? [];
734
+ return edges.map((edge) => edge.node);
735
+ }
736
+ };
737
+ }
85
738
  export {
739
+ createClient3 as airtable,
740
+ createClient6 as dbt,
741
+ createClient4 as googleAnalytics,
86
742
  createClient as kintone,
87
- createClient2 as openai
743
+ createClient2 as openai,
744
+ createClient5 as wixStore
88
745
  };