@magemetrics/core 0.5.3 → 0.6.0

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
@@ -1,16 +1,17 @@
1
+ import { sha256 } from '@noble/hashes/sha2.js';
1
2
  import z5, { z } from 'zod';
3
+ import { GoTrueClient } from '@supabase/auth-js';
4
+ import createApiClient2 from 'openapi-fetch';
2
5
  import dayjs from 'dayjs';
3
6
  import customParseFormat from 'dayjs/plugin/customParseFormat.js';
4
7
  import relativeTime from 'dayjs/plugin/relativeTime.js';
5
8
  import timezone from 'dayjs/plugin/timezone.js';
6
9
  import utc from 'dayjs/plugin/utc.js';
7
- import { GoTrueClient } from '@supabase/auth-js';
8
- import createApiClient from 'openapi-fetch';
9
- import { sha256 } from '@noble/hashes/sha2.js';
10
10
  import { DefaultChatTransport } from 'ai';
11
11
 
12
12
  // ../shared/dist/src/api/client/middleware.js
13
13
  var HEADER_CLIENT_VERSION = "X-Client-Version";
14
+ var HEADER_SP_TOKEN = "sp-access-token";
14
15
  var HEADER_API_KEY = "X-Api-Key";
15
16
  var ApiError = class extends Error {
16
17
  extra;
@@ -54,7 +55,103 @@ var addApiKeyHeader = (apiKey) => {
54
55
  };
55
56
  };
56
57
 
57
- // ../../node_modules/.pnpm/@asteasolutions+zod-to-openapi@8.1.0_zod@4.1.12/node_modules/@asteasolutions/zod-to-openapi/dist/index.mjs
58
+ // package.json
59
+ var package_default = {
60
+ version: "0.6.0"};
61
+
62
+ // src/core/MageMetricsEventEmitter.ts
63
+ var MageMetricsEventEmitter = class {
64
+ listeners = /* @__PURE__ */ new Map();
65
+ addEventListener(type, listener, options) {
66
+ if (!this.listeners.has(type)) {
67
+ this.listeners.set(type, /* @__PURE__ */ new Set());
68
+ }
69
+ if (options?.signal) {
70
+ if (options.signal.aborted) {
71
+ return;
72
+ }
73
+ const abortHandler = () => {
74
+ this.removeEventListener(type, listener);
75
+ };
76
+ options.signal.addEventListener("abort", abortHandler, { once: true });
77
+ }
78
+ this.listeners.get(type).add(listener);
79
+ }
80
+ removeEventListener(type, listener) {
81
+ const typeListeners = this.listeners.get(type);
82
+ if (typeListeners) {
83
+ typeListeners.delete(listener);
84
+ if (typeListeners.size === 0) {
85
+ this.listeners.delete(type);
86
+ }
87
+ }
88
+ }
89
+ dispatch(type, detail) {
90
+ const typeListeners = this.listeners.get(type);
91
+ if (typeListeners) {
92
+ const event = { type, detail };
93
+ typeListeners.forEach((listener) => {
94
+ try {
95
+ listener(event);
96
+ } catch (error) {
97
+ console.error(`Error in event listener for "${type}":`, error);
98
+ }
99
+ });
100
+ }
101
+ }
102
+ };
103
+
104
+ // src/core/auth/DirectAuthProvider.ts
105
+ var MM_CLIENT_VERSION = package_default.version;
106
+ var DirectAuthProvider = class {
107
+ state = "initializing";
108
+ jwt;
109
+ events = new MageMetricsEventEmitter();
110
+ constructor(jwt) {
111
+ this.jwt = jwt;
112
+ }
113
+ async initialize() {
114
+ return Promise.resolve(this.setState("ready"));
115
+ }
116
+ async getHeaders() {
117
+ return Promise.resolve({
118
+ [HEADER_CLIENT_VERSION]: MM_CLIENT_VERSION,
119
+ [HEADER_SP_TOKEN]: this.jwt
120
+ });
121
+ }
122
+ getState() {
123
+ return this.state;
124
+ }
125
+ async updateExternalJwt(jwt) {
126
+ this.jwt = jwt;
127
+ return Promise.resolve(this.setState("ready"));
128
+ }
129
+ async logout() {
130
+ return Promise.resolve(this.setState("initializing"));
131
+ }
132
+ getSupabaseClient() {
133
+ return null;
134
+ }
135
+ addEventListener(type, listener, options) {
136
+ this.events.addEventListener(type, listener, options);
137
+ }
138
+ removeEventListener(type, listener) {
139
+ this.events.removeEventListener(type, listener);
140
+ }
141
+ setState(state) {
142
+ this.state = state;
143
+ this.state = state;
144
+ this.events.dispatch("authStateChange", state);
145
+ }
146
+ };
147
+ var hashString = (value) => {
148
+ const encoder = new TextEncoder();
149
+ const data = encoder.encode(value);
150
+ const hash = sha256(data);
151
+ return Array.from(hash).map((b) => b.toString(16).padStart(2, "0")).join("");
152
+ };
153
+
154
+ // ../../node_modules/.pnpm/@asteasolutions+zod-to-openapi@8.1.0_zod@4.1.13/node_modules/@asteasolutions/zod-to-openapi/dist/index.mjs
58
155
  function __rest(s, e) {
59
156
  var t = {};
60
157
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -383,616 +480,674 @@ var createRoute = (routeConfig) => {
383
480
  };
384
481
  extendZodWithOpenApi(z);
385
482
 
386
- // ../shared/dist/src/endpoints/admin-console/sqlPreview.routes.js
387
- var TanStackColumnSchema = z.object({
388
- id: z.string(),
389
- accessorKey: z.string(),
390
- header: z.string(),
391
- cell: z.any().optional(),
392
- meta: z.record(z.string(), z.any()).optional()
393
- });
394
- var SqlPreviewResponseSchema = z.object({
395
- columns: z.array(TanStackColumnSchema),
396
- data: z.array(z.record(z.string(), z.any())),
397
- metadata: z.object({
398
- wasSampled: z.boolean(),
399
- originalCount: z.number(),
400
- sampledCount: z.number()
401
- }).optional()
483
+ // ../shared/dist/src/endpoints/auth.routes.js
484
+ var GetApiInformationInputSchema = z.object({
485
+ apiKey: z.string()
402
486
  });
403
- var SqlPreviewErrorSchema = z.object({
404
- error: z.string()
487
+ var GetApiInformationOutputSchema = z.object({
488
+ apiUrl: z.string(),
489
+ anonKey: z.string()
405
490
  });
406
- createRoute({
407
- method: "post",
408
- path: "/api/v1/admin-console/sql/preview",
409
- operationId: "sqlPreview",
491
+ var GetApiInformation = createRoute({
492
+ method: "get",
493
+ path: "/api/v1/auth/apiInformation",
494
+ operationId: "getApiInformation",
410
495
  request: {
411
- body: {
496
+ query: GetApiInformationInputSchema
497
+ },
498
+ responses: {
499
+ 200: {
500
+ content: {
501
+ "application/json": {
502
+ schema: GetApiInformationOutputSchema
503
+ }
504
+ },
505
+ description: "Retrieve the API URL and anon key"
506
+ },
507
+ 400: {
508
+ content: {
509
+ "application/json": {
510
+ schema: z.object({ error: z.string() })
511
+ }
512
+ },
513
+ description: "Invalid input"
514
+ },
515
+ 500: {
412
516
  content: {
413
517
  "application/json": {
414
518
  schema: z.object({
415
- sql: z.string().min(1, "SQL query is required")
519
+ error: z.string()
416
520
  })
417
521
  }
418
- }
522
+ },
523
+ description: "Unable to retrieve the API URL and anon key"
419
524
  }
525
+ }
526
+ });
527
+ createRoute({
528
+ hide: true,
529
+ method: "get",
530
+ path: "/api/auth/apiInformation",
531
+ operationId: "getApiInformation",
532
+ request: {
533
+ query: GetApiInformationInputSchema
420
534
  },
421
535
  responses: {
422
536
  200: {
423
- description: "SQL query executed successfully",
424
537
  content: {
425
538
  "application/json": {
426
- schema: SqlPreviewResponseSchema
539
+ schema: GetApiInformationOutputSchema
427
540
  }
428
- }
541
+ },
542
+ description: "Retrieve the API URL and anon key"
429
543
  },
430
544
  400: {
431
- description: "Invalid SQL query or request",
432
545
  content: {
433
546
  "application/json": {
434
- schema: SqlPreviewErrorSchema
547
+ schema: z.object({ error: z.string() })
435
548
  }
436
- }
549
+ },
550
+ description: "Invalid input"
437
551
  },
438
552
  500: {
439
- description: "Internal server error",
440
553
  content: {
441
554
  "application/json": {
442
- schema: SqlPreviewErrorSchema
555
+ schema: z.object({
556
+ error: z.string()
557
+ })
443
558
  }
444
- }
559
+ },
560
+ description: "Unable to retrieve the API URL and anon key"
445
561
  }
446
562
  }
447
563
  });
448
-
449
- // ../shared/dist/src/endpoints/utils.js
450
- var limitQueryParams = z.string().pipe(z.coerce.number()).optional().openapi({
451
- param: {
452
- required: false
453
- },
454
- type: "integer"
564
+ var ExchangeExternalTokenInputSchema = z.object({
565
+ apiKey: z.string(),
566
+ externalJWT: z.string()
455
567
  });
456
- var orderQueryParams = z.string().transform((str) => {
457
- if (!str)
458
- return [];
459
- return str.split(",").map((part) => {
460
- const [column, direction = "ASC"] = part.split(":");
461
- return {
462
- column,
463
- direction: direction.toUpperCase()
464
- };
465
- });
466
- }).pipe(z.array(z.object({
467
- column: z.string(),
468
- direction: z.enum(["ASC", "DESC"])
469
- }))).optional().openapi({
470
- param: {
471
- required: false,
472
- example: "name:asc,date:desc"
473
- },
474
- type: "string"
568
+ var ExchangeExternalTokenOutputSchema = z.object({
569
+ accessToken: z.string(),
570
+ refreshToken: z.string()
475
571
  });
476
- var cursorParams = z.string().pipe(z.coerce.number()).optional().openapi({
477
- param: {
478
- required: false
572
+ var ExchangeExternalToken = createRoute({
573
+ method: "post",
574
+ path: "/api/v1/auth/exchangeExternalToken",
575
+ operationId: "exchangeExternalToken",
576
+ request: {
577
+ body: {
578
+ required: true,
579
+ content: {
580
+ "application/json": {
581
+ schema: ExchangeExternalTokenInputSchema
582
+ }
583
+ }
584
+ }
479
585
  },
480
- type: "number"
481
- });
482
- var filterQueryParams = z.string().transform((str) => {
483
- if (!str)
484
- return [];
485
- return str.split(",").map((part) => {
486
- const [column, value = ""] = part.split(":").map(decodeURIComponent);
487
- return { column, value };
488
- });
489
- }).pipe(z.array(z.object({
490
- column: z.string(),
491
- value: z.string()
492
- }))).optional().openapi({
493
- param: {
494
- required: false,
495
- example: "status:active,name:John%20Doe"
496
- },
497
- type: "string"
498
- });
499
- var columnsQueryParams = z.string().transform((str) => {
500
- if (!str)
501
- return [];
502
- return str.split(",");
503
- }).optional().openapi({
504
- param: {
505
- required: false,
506
- example: "name,date"
507
- },
508
- type: "string"
509
- });
510
- var SupabaseUserHeaderSchema = z.object({
511
- "sp-access-token": z.string()
512
- });
513
- var SupabaseHeaderSchema = SupabaseUserHeaderSchema;
514
- var FEEDBACK_OPTIONS = [
515
- { label: "Helpful", value: "helpful" },
516
- { label: "Partially helpful", value: "partially helpful" },
517
- { label: "Not helpful", value: "not helpful" },
518
- { label: "Incorrect", value: "incorrect" }
519
- ];
520
- var FeedbackSchema = z.object({
521
- created_at: z.string(),
522
- flow_data_id: z.number(),
523
- helpfulness: z.enum(FEEDBACK_OPTIONS.map((option) => option.value)),
524
- id: z.number()
525
- });
526
- var Node3 = z.object({
527
- id: z.string(),
528
- type: z.enum([
529
- "entity",
530
- "attribute",
531
- "filter",
532
- "process",
533
- "combine",
534
- "result"
535
- ]),
536
- explanation: z.string()
537
- });
538
- var Edge = z.object({
539
- source: z.string(),
540
- target: z.string()
541
- });
542
- var LLMColumnsLineageResponse = z.record(z.string(), z.object({
543
- nodes: z.array(Node3),
544
- edges: z.array(Edge)
545
- }));
546
- var SqlAnalysisChunkSchema = z.object({
547
- chunk_title: z.string(),
548
- chunk_explanation: z.string(),
549
- lines: z.array(z.object({
550
- sql: z.string(),
551
- explanation: z.string()
552
- }))
553
- });
554
- var BusinessExplanationSchema = z.object({
555
- summary: z.string(),
556
- implementation: z.array(z.string()),
557
- assumptions: z.array(z.object({
558
- type: z.enum([
559
- "grain",
560
- "completeness",
561
- "transformation",
562
- "relationship",
563
- "other"
564
- ]),
565
- details: z.string(),
566
- explanation: z.string()
567
- }))
586
+ responses: {
587
+ 200: {
588
+ content: {
589
+ "application/json": {
590
+ schema: ExchangeExternalTokenOutputSchema
591
+ }
592
+ },
593
+ description: "Retrieve a JWT for an external user"
594
+ },
595
+ 400: {
596
+ content: {
597
+ "application/json": {
598
+ schema: z.object({ error: z.string() })
599
+ }
600
+ },
601
+ description: "Invalid input"
602
+ },
603
+ 500: {
604
+ content: {
605
+ "application/json": {
606
+ schema: z.object({
607
+ error: z.string()
608
+ })
609
+ }
610
+ },
611
+ description: "Unable to retrieve a JWT for an external user"
612
+ }
613
+ }
568
614
  });
569
615
 
570
- // ../shared/dist/src/schemas/flows.js
571
- var FlowStepSchema = z.object({
572
- name: z.string(),
573
- status: z.enum(["running", "completed", "failed", "awaiting_input"]),
574
- output: z.looseObject({}).or(z.unknown().array()).nullable()
575
- });
576
- var DatabaseFlowSchema = z.object({
577
- created_at: z.string(),
578
- id: z.string(),
579
- request: z.string(),
580
- title: z.string().nullable(),
581
- user_id: z.string().nullable(),
582
- application_id: z.number().nullable().optional(),
583
- flow_steps: z.array(FlowStepSchema),
584
- flow_chat_messages: z.array(z.object({ count: z.number() }))
585
- });
586
- z.object({
587
- table: z.string(),
588
- schema: z.string(),
589
- database: z.string()
590
- });
591
- var FrontendFlowSchema = DatabaseFlowSchema.omit({
592
- flow_chat_messages: true,
593
- flow_steps: true
594
- });
595
- var FrontendRecentFlowsSchema = DatabaseFlowSchema.omit({
596
- flow_steps: true,
597
- flow_chat_messages: true
598
- });
599
- var ReportColumnSchema = z.looseObject({
600
- position: z.number().nonnegative().optional(),
601
- data_type: z.string(),
602
- null_count: z.number().nullable(),
603
- unique_count: z.number().nullable(),
604
- unique_percentage: z.number().nullable()
605
- });
606
- var ReportSchema = z.object({
607
- created_at: z.string(),
608
- flow_id: z.string(),
609
- id: z.number(),
610
- is_sample: z.boolean(),
611
- schema: z.string(),
612
- sql: z.string(),
613
- table: z.string(),
614
- title: z.string(),
615
- request: z.string().nullable(),
616
- data_sample: z.array(z.record(z.string(), z.unknown())),
617
- data_summary: z.looseObject({
618
- columns: z.record(z.string(), ReportColumnSchema)
619
- }),
620
- bookmarked: z.boolean(),
621
- status: z.string().nullable(),
622
- is_removed: z.boolean()
623
- });
624
- var FrontendReportSchema = ReportSchema.omit({
625
- sql: true,
626
- table: true,
627
- data_sample: true,
628
- is_sample: true,
629
- schema: true
630
- });
631
- var ReportDataSchema = z.looseObject({}).array().openapi("ReportData");
632
- var ReportColumnsSchema = z.object({
633
- name: z.string(),
634
- data_type: z.string()
635
- }).array();
636
- z.object({
637
- render_type: z.string().nullish(),
638
- unit: z.string().nullish()
639
- });
640
- var FrontendReportColumnsSchema = z.object({
641
- ...ReportColumnsSchema.element.shape,
642
- dataType: z.string(),
643
- renderType: z.string().optional(),
644
- unit: z.string().optional()
645
- }).array().openapi("ReportColumns");
646
- z.object({
647
- goal: z.string(),
648
- user_friendly_goal: z.string().optional()
649
- });
650
- var ReportExplainabilitySchema = z.object({
651
- sql_explanation: z.array(SqlAnalysisChunkSchema).nullish(),
652
- business_explanation: BusinessExplanationSchema.nullish(),
653
- columns_lineage: LLMColumnsLineageResponse.nullish(),
654
- confidence_score: z.number(),
655
- confidence_score_reason: z.string(),
656
- assumptions_score: z.number().optional(),
657
- assumptions_score_reason: z.string().optional(),
658
- friendliness_score: z.number().optional(),
659
- friendliness_score_reason: z.string().optional(),
660
- id: z.number(),
661
- flow_data_id: z.number(),
662
- created_at: z.string()
663
- });
664
- var FrontendReportExplainabilitySchema = ReportExplainabilitySchema.omit({
665
- id: true,
666
- created_at: true
667
- });
668
- dayjs.extend(relativeTime);
669
- dayjs.extend(customParseFormat);
670
- dayjs.extend(utc);
671
- dayjs.extend(timezone);
672
- var daysjs_default = dayjs;
616
+ // src/core/types.ts
617
+ var TOKEN_STORAGE_KEY = "mm-ai-sp-token";
618
+ var CHECK_KEY = "mm-ai-check-key";
673
619
 
674
- // ../shared/dist/src/data/FormattedData.js
675
- var formatWithAutoPrecision = (value, options = {}) => {
676
- const { minPrecision = 0, maxPrecision = 6, trimZeros = true, useGrouping = true } = options;
677
- if (typeof value !== "number" || isNaN(value)) {
678
- return String(value);
679
- }
680
- if (value === 0) {
681
- return "0";
620
+ // src/core/auth/ExternalAuthProvider.ts
621
+ var MM_CLIENT_VERSION2 = package_default.version;
622
+ var ExternalAuthProvider = class {
623
+ config;
624
+ state = "initializing";
625
+ supabaseClient = null;
626
+ noAuthApiClient = null;
627
+ authApiResponse = null;
628
+ processedJwt = Symbol("initial");
629
+ userId = null;
630
+ events = new MageMetricsEventEmitter();
631
+ constructor(config) {
632
+ this.config = config;
682
633
  }
683
- const absValue = Math.abs(value);
684
- let maximumFractionDigits;
685
- if (absValue >= 1e3) {
686
- maximumFractionDigits = 0;
687
- } else if (absValue >= 100) {
688
- maximumFractionDigits = 1;
689
- } else if (absValue >= 10) {
690
- maximumFractionDigits = 2;
691
- } else if (absValue >= 1) {
692
- maximumFractionDigits = 3;
693
- } else if (absValue >= 0.1) {
694
- maximumFractionDigits = 4;
695
- } else if (absValue >= 0.01) {
696
- maximumFractionDigits = 5;
697
- } else {
698
- maximumFractionDigits = maxPrecision;
699
- if (absValue > 0) {
700
- const exponent = Math.floor(Math.log10(absValue));
701
- if (exponent < 0) {
702
- maximumFractionDigits = Math.min(Math.abs(exponent) + 2, maxPrecision);
634
+ async initialize() {
635
+ try {
636
+ this.setState("initializing");
637
+ const apiInfo = await this.getApiInformation();
638
+ this.initializeSupabaseClient(apiInfo.anonKey, apiInfo.apiUrl);
639
+ await this.handleAuthentication();
640
+ if (this.config.externalJwt) {
641
+ await this.saveCheckKey(this.config.externalJwt, this.config.apiKey);
703
642
  }
643
+ this.setState("ready");
644
+ } catch (error) {
645
+ console.error("Authentication flow failed:", error);
646
+ this.setState("error");
647
+ throw error;
704
648
  }
705
649
  }
706
- maximumFractionDigits = Math.max(maximumFractionDigits, minPrecision);
707
- const formatter = new Intl.NumberFormat(void 0, {
708
- minimumFractionDigits: trimZeros ? 0 : maximumFractionDigits,
709
- maximumFractionDigits,
710
- useGrouping
711
- });
712
- return formatter.format(value);
713
- };
714
- var MIN_VALID_YEAR = 1900;
715
- var MAX_VALID_YEAR = 2200;
716
- var zonedatetime = (format, zone) => ({ format, type: "zonedatetime", zone });
717
- var datetime = (format) => ({ format, type: "datetime" });
718
- var date = (format) => ({ format, type: "date" });
719
- var DATE_FORMATS = [
720
- // ISO 8601 formats
721
- zonedatetime("YYYY-MM-DDTHH:mm:ss.SSSZ", "UTC"),
722
- zonedatetime("YYYY-MM-DDTHH:mm:ssZ", "UTC"),
723
- zonedatetime("YYYY-MM-DDTHH:mmZ", "UTC"),
724
- datetime("YYYY-MM-DDTHH:mm:ss"),
725
- datetime("YYYY-MM-DDTHH:mm"),
726
- date("YYYY-MM-DDT"),
727
- // Standard date formats
728
- date("YYYY-MM-DD"),
729
- date("YYYY/MM/DD"),
730
- date("DD-MM-YYYY"),
731
- date("DD/MM/YYYY"),
732
- date("MM-DD-YYYY"),
733
- date("MM/DD/YYYY"),
734
- // Date time formats
735
- datetime("YYYY-MM-DD HH:mm:ss"),
736
- datetime("YYYY-MM-DD HH:mm"),
737
- datetime("YYYY/MM/DD HH:mm:ss"),
738
- datetime("YYYY/MM/DD HH:mm"),
739
- datetime("DD-MM-YYYY HH:mm:ss"),
740
- datetime("DD-MM-YYYY HH:mm"),
741
- datetime("DD/MM/YYYY HH:mm:ss"),
742
- datetime("DD/MM/YYYY HH:mm"),
743
- datetime("MM-DD-YYYY HH:mm:ss"),
744
- datetime("MM-DD-YYYY HH:mm"),
745
- datetime("MM/DD/YYYY HH:mm:ss"),
746
- datetime("MM/DD/YYYY HH:mm")
747
- ];
748
- var isDateString = (value) => {
749
- if (typeof value !== "string")
750
- return { isValid: false };
751
- const stripped = value.replace(/[-/.:\s]/g, "");
752
- if (/^\d+$/.test(stripped)) {
753
- if (stripped.length < 6)
754
- return { isValid: false };
755
- if (value.length === stripped.length)
756
- return { isValid: false };
650
+ async getHeaders() {
651
+ if (!this.supabaseClient) {
652
+ return {};
653
+ }
654
+ const session = await this.supabaseClient.getSession();
655
+ if (!session.data.session) {
656
+ return {};
657
+ }
658
+ const { access_token } = session.data.session;
659
+ return {
660
+ [HEADER_CLIENT_VERSION]: MM_CLIENT_VERSION2,
661
+ [HEADER_SP_TOKEN]: access_token
662
+ };
757
663
  }
758
- if (stripped.length > "YYYY-MM-DDTHH:mm:ss.SSS+00:00".length) {
759
- return { isValid: false };
664
+ getState() {
665
+ return this.state;
760
666
  }
761
- for (const format of DATE_FORMATS) {
762
- let date2;
667
+ async updateExternalJwt(jwt) {
668
+ if (this.config.externalJwt === jwt) return;
669
+ this.config.externalJwt = jwt;
670
+ this.processedJwt = Symbol("updating");
671
+ await this.initialize();
672
+ }
673
+ async logout() {
674
+ if (this.supabaseClient) {
675
+ await this.supabaseClient.signOut({ scope: "local" });
676
+ }
677
+ await this.clearStorage();
678
+ }
679
+ getSupabaseClient() {
680
+ return this.supabaseClient;
681
+ }
682
+ addEventListener(type, listener, options) {
683
+ this.events.addEventListener(type, listener, options);
684
+ }
685
+ removeEventListener(type, listener) {
686
+ this.events.removeEventListener(type, listener);
687
+ }
688
+ startAutoRefresh() {
689
+ return this.supabaseClient?.startAutoRefresh();
690
+ }
691
+ stopAutoRefresh() {
692
+ return this.supabaseClient?.stopAutoRefresh();
693
+ }
694
+ async getApiInformation() {
695
+ if (!this.noAuthApiClient || !this.authApiResponse) {
696
+ this.noAuthApiClient = createApiClient2({
697
+ baseUrl: this.config.apiUrl
698
+ });
699
+ this.noAuthApiClient.use(throwOnError);
700
+ this.noAuthApiClient.use(addVersionHeader(MM_CLIENT_VERSION2));
701
+ this.noAuthApiClient.use(addApiKeyHeader(this.config.apiKey));
702
+ const { data } = await this.noAuthApiClient.GET(GetApiInformation.path, {
703
+ params: {
704
+ query: {
705
+ apiKey: this.config.apiKey
706
+ }
707
+ }
708
+ });
709
+ if (!data) {
710
+ throw new Error("Failed to fetch API information");
711
+ }
712
+ this.authApiResponse = data;
713
+ }
714
+ return this.authApiResponse;
715
+ }
716
+ initializeSupabaseClient(anonKey, apiUrl) {
717
+ if (!this.supabaseClient) {
718
+ this.supabaseClient = new GoTrueClient({
719
+ url: `${apiUrl}/auth/v1`,
720
+ storageKey: TOKEN_STORAGE_KEY,
721
+ headers: {
722
+ apiKey: anonKey
723
+ },
724
+ storage: this.config.storage,
725
+ ...this.config.authOptions
726
+ });
727
+ this.supabaseClient.onAuthStateChange((event, session) => {
728
+ console.debug("Supabase auth state change:", event, !!session);
729
+ if (event === "SIGNED_IN" && session?.user) {
730
+ if (this.userId !== session.user.id && this.userId !== null) {
731
+ this.events.dispatch("userChange", { id: session.user.id });
732
+ }
733
+ this.userId = session.user.id;
734
+ }
735
+ if (event === "TOKEN_REFRESHED" && session) {
736
+ console.debug("Token refreshed successfully");
737
+ this.setState("ready");
738
+ } else if (event === "SIGNED_OUT") {
739
+ console.debug("User signed out");
740
+ void this.clearStorage();
741
+ this.setState("initializing");
742
+ }
743
+ });
744
+ }
745
+ }
746
+ async handleAuthentication() {
747
+ if (!this.supabaseClient) {
748
+ throw new Error("Supabase client not initialized");
749
+ }
750
+ if (this.processedJwt === this.config.externalJwt) {
751
+ return;
752
+ }
763
753
  try {
764
- if (format.type === "zonedatetime") {
765
- date2 = daysjs_default.tz(value, format.format, format.zone);
754
+ const { data, error } = await this.supabaseClient.getSession();
755
+ if (error) {
756
+ console.error("Error getting session:", error);
757
+ this.processedJwt = this.config.externalJwt || "";
758
+ return;
759
+ }
760
+ const isCheckValid = await this.compareCheckKey(
761
+ this.config.externalJwt ?? "",
762
+ this.config.apiKey
763
+ );
764
+ if (data.session && this.config.externalJwt && isCheckValid) {
765
+ console.debug("Session found, authentication ready");
766
+ this.processedJwt = this.config.externalJwt || "";
767
+ } else if (this.config.externalJwt) {
768
+ console.debug("No session found, exchanging external JWT");
769
+ await this.clearCheckKey();
770
+ await this.exchangeExternalToken();
771
+ this.processedJwt = this.config.externalJwt;
766
772
  } else {
767
- date2 = daysjs_default(value, format.format, true);
773
+ console.debug("No session and no external JWT provided");
774
+ this.processedJwt = this.config.externalJwt || "";
768
775
  }
769
- } catch {
770
- continue;
776
+ } catch (error) {
777
+ console.error("Unhandled error during authentication:", error);
778
+ this.processedJwt = this.config.externalJwt || "";
779
+ throw error;
771
780
  }
772
- if (date2.isValid()) {
773
- const year = date2.year();
774
- if (year < MIN_VALID_YEAR || year > MAX_VALID_YEAR)
775
- continue;
776
- const isDateTime = format.type === "zonedatetime" || format.type == "datetime";
777
- return {
778
- isValid: true,
779
- parsedDate: date2,
780
- isDateTime
781
- };
781
+ }
782
+ async exchangeExternalToken() {
783
+ if (!this.noAuthApiClient || !this.supabaseClient || !this.config.externalJwt) {
784
+ throw new Error(
785
+ "Required clients or JWT not available for token exchange"
786
+ );
787
+ }
788
+ const { data } = await this.noAuthApiClient.POST(
789
+ ExchangeExternalToken.path,
790
+ {
791
+ body: {
792
+ apiKey: this.config.apiKey,
793
+ externalJWT: this.config.externalJwt
794
+ },
795
+ headers: this.config.additionalHeaders || {}
796
+ }
797
+ );
798
+ if (!data) {
799
+ throw new Error("Failed to exchange tokens");
782
800
  }
801
+ await this.supabaseClient.setSession({
802
+ access_token: data.accessToken,
803
+ refresh_token: data.refreshToken
804
+ });
805
+ console.debug("Token exchange successful, session set");
783
806
  }
784
- return { isValid: false };
785
- };
786
- var formatDataValue = (value, { replaceNullValue } = {
787
- replaceNullValue: true
788
- }) => {
789
- if (value === null || value === void 0) {
790
- return {
791
- display: replaceNullValue ? "empty" : null,
792
- sortValue: null
793
- };
807
+ setState(state) {
808
+ this.state = state;
809
+ this.events.dispatch("authStateChange", state);
794
810
  }
795
- let processedValue = value;
796
- if (typeof processedValue === "string") {
811
+ encodeCheckKey(externalJwt, apiKey) {
812
+ return hashString(
813
+ JSON.stringify({
814
+ externalJwt,
815
+ apiKey
816
+ })
817
+ );
818
+ }
819
+ async saveCheckKey(externalJwt, apiKey) {
820
+ const encodedKey = this.encodeCheckKey(externalJwt, apiKey);
821
+ await this.config.storage.setItem(CHECK_KEY, encodedKey);
822
+ }
823
+ async compareCheckKey(externalJwt, apiKey) {
824
+ const storedKey = await this.config.storage.getItem(CHECK_KEY);
825
+ if (!storedKey) return false;
826
+ const newValue = this.encodeCheckKey(externalJwt, apiKey);
827
+ return storedKey === newValue;
828
+ }
829
+ async clearCheckKey() {
830
+ await this.config.storage.removeItem(CHECK_KEY);
831
+ }
832
+ async clearStorage() {
797
833
  try {
798
- const parsed = JSON.parse(processedValue);
799
- processedValue = parsed;
834
+ await this.config.storage.removeItem(TOKEN_STORAGE_KEY);
835
+ await this.config.storage.removeItem(CHECK_KEY);
800
836
  } catch {
801
837
  }
802
838
  }
803
- if (processedValue && typeof processedValue === "object" && Object.keys(processedValue).length === 1 && "value" in processedValue) {
804
- const extractedValue = processedValue.value;
805
- const dateResult2 = isDateString(extractedValue);
806
- if (dateResult2.isValid) {
807
- return {
808
- display: dateResult2.isDateTime ? dateResult2.parsedDate.format("YYYY-MM-DD HH:mm:ss") : dateResult2.parsedDate.format("YYYY-MM-DD"),
809
- sortValue: dateResult2.parsedDate.valueOf()
810
- };
839
+ };
840
+
841
+ // ../shared/dist/src/endpoints/admin-console/sqlPreview.routes.js
842
+ var TanStackColumnSchema = z.object({
843
+ id: z.string(),
844
+ accessorKey: z.string(),
845
+ header: z.string(),
846
+ cell: z.any().optional(),
847
+ meta: z.record(z.string(), z.any()).optional()
848
+ });
849
+ var SqlPreviewResponseSchema = z.object({
850
+ columns: z.array(TanStackColumnSchema),
851
+ data: z.array(z.record(z.string(), z.any())),
852
+ metadata: z.object({
853
+ wasSampled: z.boolean(),
854
+ originalCount: z.number(),
855
+ sampledCount: z.number()
856
+ }).optional()
857
+ });
858
+ var SqlPreviewErrorSchema = z.object({
859
+ error: z.string()
860
+ });
861
+ createRoute({
862
+ method: "post",
863
+ path: "/api/v1/admin-console/sql/preview",
864
+ operationId: "sqlPreview",
865
+ request: {
866
+ body: {
867
+ content: {
868
+ "application/json": {
869
+ schema: z.object({
870
+ sql: z.string().min(1, "SQL query is required")
871
+ })
872
+ }
873
+ }
874
+ }
875
+ },
876
+ responses: {
877
+ 200: {
878
+ description: "SQL query executed successfully",
879
+ content: {
880
+ "application/json": {
881
+ schema: SqlPreviewResponseSchema
882
+ }
883
+ }
884
+ },
885
+ 400: {
886
+ description: "Invalid SQL query or request",
887
+ content: {
888
+ "application/json": {
889
+ schema: SqlPreviewErrorSchema
890
+ }
891
+ }
892
+ },
893
+ 500: {
894
+ description: "Internal server error",
895
+ content: {
896
+ "application/json": {
897
+ schema: SqlPreviewErrorSchema
898
+ }
899
+ }
811
900
  }
812
- return {
813
- display: String(extractedValue),
814
- sortValue: extractedValue
815
- };
816
- }
817
- const dateResult = isDateString(processedValue);
818
- if (dateResult.isValid) {
819
- return {
820
- display: dateResult.isDateTime ? dateResult.parsedDate.format("YYYY-MM-DD HH:mm:ss") : dateResult.parsedDate.format("YYYY-MM-DD"),
821
- sortValue: dateResult.parsedDate.valueOf()
822
- };
823
- }
824
- if (typeof processedValue === "object") {
825
- const stringified = JSON.stringify(processedValue, null, 2);
826
- return {
827
- display: stringified,
828
- sortValue: stringified
829
- };
830
- }
831
- if (typeof processedValue === "boolean") {
832
- return {
833
- display: String(processedValue),
834
- sortValue: processedValue ? 1 : 0
835
- };
836
901
  }
837
- if (typeof processedValue === "number") {
902
+ });
903
+
904
+ // ../shared/dist/src/endpoints/utils.js
905
+ var limitQueryParams = z.string().pipe(z.coerce.number()).optional().openapi({
906
+ param: {
907
+ required: false
908
+ },
909
+ type: "integer"
910
+ });
911
+ var orderQueryParams = z.string().transform((str) => {
912
+ if (!str)
913
+ return [];
914
+ return str.split(",").map((part) => {
915
+ const [column, direction = "ASC"] = part.split(":");
838
916
  return {
839
- display: processedValue >= MIN_VALID_YEAR && processedValue <= MAX_VALID_YEAR && Number.isInteger(processedValue) ? String(processedValue) : formatWithAutoPrecision(processedValue),
840
- sortValue: processedValue
917
+ column,
918
+ direction: direction.toUpperCase()
841
919
  };
842
- }
843
- return {
844
- // eslint-disable-next-line @typescript-eslint/no-base-to-string
845
- display: String(processedValue),
846
- sortValue: processedValue
847
- };
848
- };
920
+ });
921
+ }).pipe(z.array(z.object({
922
+ column: z.string(),
923
+ direction: z.enum(["ASC", "DESC"])
924
+ }))).optional().openapi({
925
+ param: {
926
+ required: false,
927
+ example: "name:asc,date:desc"
928
+ },
929
+ type: "string"
930
+ });
931
+ var cursorParams = z.string().pipe(z.coerce.number()).optional().openapi({
932
+ param: {
933
+ required: false
934
+ },
935
+ type: "number"
936
+ });
937
+ var filterQueryParams = z.string().transform((str) => {
938
+ if (!str)
939
+ return [];
940
+ return str.split(",").map((part) => {
941
+ const [column, value = ""] = part.split(":").map(decodeURIComponent);
942
+ return { column, value };
943
+ });
944
+ }).pipe(z.array(z.object({
945
+ column: z.string(),
946
+ value: z.string()
947
+ }))).optional().openapi({
948
+ param: {
949
+ required: false,
950
+ example: "status:active,name:John%20Doe"
951
+ },
952
+ type: "string"
953
+ });
954
+ var columnsQueryParams = z.string().transform((str) => {
955
+ if (!str)
956
+ return [];
957
+ return str.split(",");
958
+ }).optional().openapi({
959
+ param: {
960
+ required: false,
961
+ example: "name,date"
962
+ },
963
+ type: "string"
964
+ });
965
+ var SupabaseUserHeaderSchema = z.object({
966
+ [HEADER_SP_TOKEN]: z.string()
967
+ });
968
+ var SupabaseHeaderSchema = SupabaseUserHeaderSchema;
969
+ var FEEDBACK_OPTIONS = [
970
+ { label: "Helpful", value: "helpful" },
971
+ { label: "Partially helpful", value: "partially helpful" },
972
+ { label: "Not helpful", value: "not helpful" },
973
+ { label: "Incorrect", value: "incorrect" }
974
+ ];
975
+ var FeedbackSchema = z.object({
976
+ created_at: z.string(),
977
+ flow_data_id: z.number(),
978
+ helpfulness: z.enum(FEEDBACK_OPTIONS.map((option) => option.value)),
979
+ id: z.number()
980
+ });
981
+ var Node3 = z.object({
982
+ id: z.string(),
983
+ type: z.enum([
984
+ "entity",
985
+ "attribute",
986
+ "filter",
987
+ "process",
988
+ "combine",
989
+ "result"
990
+ ]),
991
+ explanation: z.string()
992
+ });
993
+ var Edge = z.object({
994
+ source: z.string(),
995
+ target: z.string()
996
+ });
997
+ var LLMColumnsLineageResponse = z.record(z.string(), z.object({
998
+ nodes: z.array(Node3),
999
+ edges: z.array(Edge)
1000
+ }));
1001
+ var SqlAnalysisChunkSchema = z.object({
1002
+ chunk_title: z.string(),
1003
+ chunk_explanation: z.string(),
1004
+ lines: z.array(z.object({
1005
+ sql: z.string(),
1006
+ explanation: z.string()
1007
+ }))
1008
+ });
1009
+ var BusinessExplanationSchema = z.object({
1010
+ summary: z.string(),
1011
+ implementation: z.array(z.string()),
1012
+ assumptions: z.array(z.object({
1013
+ type: z.enum([
1014
+ "grain",
1015
+ "completeness",
1016
+ "transformation",
1017
+ "relationship",
1018
+ "other"
1019
+ ]),
1020
+ details: z.string(),
1021
+ explanation: z.string()
1022
+ }))
1023
+ });
849
1024
 
850
- // ../shared/dist/src/schemas/visualizations.js
851
- var commonConfigProperties = {
852
- title: z.string()
853
- };
854
- var cartesianConfigProperties = {
855
- xAxisLabel: z.string(),
856
- yAxisLabel: z.string(),
857
- xAxisDataKey: z.string().optional(),
858
- yAxisDataKey: z.string().optional(),
859
- dimensionDataKey: z.string().optional(),
860
- valueColumns: z.array(z.string()).optional()
861
- };
862
- var V1VisualizationConfigurationSchema = z.discriminatedUnion("type", [
863
- // Bar chart
864
- z.object({
865
- type: z.literal("bar"),
866
- ...commonConfigProperties,
867
- ...cartesianConfigProperties
868
- }),
869
- // Line/Area chart
870
- z.object({
871
- type: z.literal("line/area"),
872
- ...commonConfigProperties,
873
- ...cartesianConfigProperties
874
- }),
875
- // Scatter chart
876
- z.object({
877
- type: z.literal("scatter"),
878
- ...commonConfigProperties,
879
- ...cartesianConfigProperties
880
- }),
881
- // Pie chart
882
- z.object({
883
- type: z.literal("pie"),
884
- ...commonConfigProperties,
885
- nameKey: z.string(),
886
- dataKey: z.string()
887
- })
888
- ]);
889
- var VisualizationConfigurationSchema = z.discriminatedUnion("type", [
890
- z.object({
891
- type: z.literal("bar"),
892
- ...commonConfigProperties,
893
- config_version: z.literal(2),
894
- xAxisLabel: z.string(),
895
- yAxisLabel: z.string(),
896
- categoryColumn: z.string(),
897
- secondaryCategoryColumn: z.string().optional(),
898
- valueColumn: z.string()
899
- }),
900
- // Line/Area chart - version 2: New format
901
- z.object({
902
- type: z.literal("line/area"),
903
- config_version: z.literal(2),
904
- ...commonConfigProperties,
905
- xAxisColumn: z.string(),
906
- valueColumns: z.array(z.string()),
907
- yAxisLabels: z.array(z.string())
908
- }),
909
- // Line/Area chart - categorical format (requires pivoting)
910
- z.object({
911
- type: z.literal("line/area-categorical"),
912
- ...commonConfigProperties,
913
- config_version: z.literal(2),
914
- valueColumn: z.string(),
915
- xAxisColumn: z.string(),
916
- xAxisLabel: z.string(),
917
- yAxisLabel: z.string(),
918
- categoryColumn: z.string()
919
- }),
920
- // Scatter chart - new format (v2)
921
- z.object({
922
- type: z.literal("scatter"),
923
- ...commonConfigProperties,
924
- config_version: z.literal(2),
925
- xAxisLabel: z.string(),
926
- yAxisLabel: z.string(),
927
- xAxisValueColumn: z.string(),
928
- yAxisValueColumn: z.string()
929
- }),
930
- // Pie chart - new format (v2)
931
- z.object({
932
- type: z.literal("pie"),
933
- ...commonConfigProperties,
934
- config_version: z.literal(2),
935
- categoryColumn: z.string(),
936
- valueColumn: z.string()
937
- })
1025
+ // ../shared/dist/src/schemas/flows.js
1026
+ var FlowStepSchema = z.object({
1027
+ name: z.string(),
1028
+ status: z.enum(["running", "completed", "failed", "awaiting_input"]),
1029
+ output: z.looseObject({}).or(z.unknown().array()).nullable()
1030
+ });
1031
+ var DatabaseFlowSchema = z.object({
1032
+ created_at: z.string(),
1033
+ id: z.string(),
1034
+ request: z.string(),
1035
+ title: z.string().nullable(),
1036
+ user_id: z.string().nullable(),
1037
+ application_id: z.number().nullable().optional(),
1038
+ flow_steps: z.array(FlowStepSchema),
1039
+ flow_chat_messages: z.array(z.object({ count: z.number() }))
1040
+ });
1041
+ z.object({
1042
+ table: z.string(),
1043
+ schema: z.string(),
1044
+ database: z.string()
1045
+ });
1046
+ var FrontendFlowSchema = DatabaseFlowSchema.omit({
1047
+ flow_chat_messages: true,
1048
+ flow_steps: true
1049
+ });
1050
+ var FrontendRecentFlowsSchema = DatabaseFlowSchema.omit({
1051
+ flow_steps: true,
1052
+ flow_chat_messages: true
1053
+ });
1054
+ var ReportColumnSchema = z.looseObject({
1055
+ position: z.number().nonnegative().optional(),
1056
+ data_type: z.string(),
1057
+ null_count: z.number().nullable(),
1058
+ unique_count: z.number().nullable(),
1059
+ unique_percentage: z.number().nullable(),
1060
+ // Numeric column statistics
1061
+ min_value: z.number().nullable().optional(),
1062
+ max_value: z.number().nullable().optional(),
1063
+ avg_value: z.number().nullable().optional(),
1064
+ median_value: z.number().nullable().optional(),
1065
+ std_value: z.number().nullable().optional(),
1066
+ // Date column statistics
1067
+ min_date: z.string().nullable().optional(),
1068
+ max_date: z.string().nullable().optional(),
1069
+ // String column statistics
1070
+ min_length: z.number().nullable().optional(),
1071
+ max_length: z.number().nullable().optional(),
1072
+ avg_length: z.number().nullable().optional()
1073
+ });
1074
+ var MaterializationStatusSchema = z.enum([
1075
+ "completed",
1076
+ "running",
1077
+ "failed"
938
1078
  ]);
939
- var BaseVisualizationSchema = z.object({
940
- id: z.number(),
941
- flow_data_id: z.number(),
1079
+ var MaterializationFieldsSchema = z.object({
1080
+ is_materialized: z.boolean().nullable(),
1081
+ last_materialized_at: z.string().nullable(),
1082
+ materialized_error_message: z.string().nullable(),
1083
+ materialized_status: MaterializationStatusSchema.nullable()
1084
+ });
1085
+ var ReportSchema = z.object({
942
1086
  created_at: z.string(),
1087
+ flow_id: z.string(),
1088
+ id: z.number(),
1089
+ is_sample: z.boolean(),
1090
+ schema: z.string(),
943
1091
  sql: z.string(),
944
- bookmarked: z.boolean(),
1092
+ table: z.string(),
1093
+ title: z.string(),
1094
+ request: z.string().nullable(),
945
1095
  data_sample: z.array(z.record(z.string(), z.unknown())),
946
- is_sample: z.boolean(),
947
- data_summary: z.record(z.string(), z.unknown())
948
- });
949
- var V1VisualizationSchema = z.object({
950
- ...BaseVisualizationSchema.shape,
951
- configuration: V1VisualizationConfigurationSchema
952
- });
953
- var VisualizationSchema = z.object({
954
- ...BaseVisualizationSchema.shape,
955
- configuration: VisualizationConfigurationSchema
1096
+ data_summary: z.looseObject({
1097
+ columns: z.record(z.string(), ReportColumnSchema)
1098
+ }),
1099
+ bookmarked: z.boolean(),
1100
+ status: z.string().nullable(),
1101
+ is_removed: z.boolean(),
1102
+ ...MaterializationFieldsSchema.shape
956
1103
  });
957
- var VisualizationDataSchema = z.array(z.record(
958
- z.string(),
959
- // any key
960
- z.union([
961
- // Date objects FIRST
962
- z.date(),
963
- z.coerce.number(),
964
- // Handle various data types including BigQueryDate
965
- z.unknown().transform((val) => formatDataValue(val).display)
966
- ])
967
- )).openapi("VisualizationData");
968
- var V1FrontendVisualizationSchema = V1VisualizationSchema.omit({
1104
+ var FrontendReportSchema = ReportSchema.omit({
969
1105
  sql: true,
1106
+ table: true,
970
1107
  data_sample: true,
971
1108
  is_sample: true,
972
- data_summary: true
1109
+ schema: true
973
1110
  });
974
- var FrontendVisualizationSchema = VisualizationSchema.omit({
975
- sql: true,
976
- data_sample: true,
977
- is_sample: true,
978
- data_summary: true
1111
+ var ReportDataSchema = z.looseObject({}).array().openapi("ReportData");
1112
+ var ReportColumnsSchema = z.object({
1113
+ name: z.string(),
1114
+ data_type: z.string()
1115
+ }).array();
1116
+ z.object({
1117
+ render_type: z.string().nullish(),
1118
+ unit: z.string().nullish()
979
1119
  });
980
- var VisualizationMetadataSchema = z.object({
981
- wasSampled: z.boolean(),
982
- originalCount: z.number(),
983
- sampledCount: z.number()
984
- }).optional();
985
- var V1FrontendVisualizationWithDataSchema = V1FrontendVisualizationSchema.extend({
986
- data: VisualizationDataSchema,
987
- _metadata: VisualizationMetadataSchema
1120
+ var FrontendReportColumnsSchema = z.object({
1121
+ ...ReportColumnsSchema.element.shape,
1122
+ dataType: z.string(),
1123
+ renderType: z.string().optional(),
1124
+ unit: z.string().optional()
1125
+ }).array().openapi("ReportColumns");
1126
+ z.object({
1127
+ goal: z.string(),
1128
+ user_friendly_goal: z.string().optional()
1129
+ });
1130
+ var ReportExplainabilitySchema = z.object({
1131
+ sql_explanation: z.array(SqlAnalysisChunkSchema).nullish(),
1132
+ business_explanation: BusinessExplanationSchema.nullish(),
1133
+ columns_lineage: LLMColumnsLineageResponse.nullish(),
1134
+ confidence_score: z.number(),
1135
+ confidence_score_reason: z.string(),
1136
+ assumptions_score: z.number().optional(),
1137
+ assumptions_score_reason: z.string().optional(),
1138
+ friendliness_score: z.number().optional(),
1139
+ friendliness_score_reason: z.string().optional(),
1140
+ id: z.number(),
1141
+ flow_data_id: z.number(),
1142
+ created_at: z.string()
988
1143
  });
989
- var FrontendVisualizationWithDataSchema = FrontendVisualizationSchema.extend({
990
- data: VisualizationDataSchema,
991
- _metadata: VisualizationMetadataSchema
1144
+ var FrontendReportExplainabilitySchema = ReportExplainabilitySchema.omit({
1145
+ id: true,
1146
+ created_at: true
992
1147
  });
993
1148
 
994
1149
  // ../shared/dist/src/endpoints/companion/flows.routes.js
995
- var FlowIdParam = z.object({ flowId: z.string().uuid() }).openapi("FlowId", { type: "string" });
1150
+ var FlowIdParam = z.object({ flowId: z.uuid() }).openapi("FlowId", { type: "string" });
996
1151
  var FlowDataIdParam = z.object({ flowDataId: z.string().pipe(z.coerce.number()) }).openapi("FlowDataId", { type: "integer" });
997
1152
  var ReportId = z.string().pipe(z.coerce.number());
998
1153
  var ReportIdParam = z.object({ report_id: ReportId }).openapi("ReportId", { type: "integer" });
@@ -1070,96 +1225,6 @@ createRoute({
1070
1225
  }
1071
1226
  }
1072
1227
  });
1073
- createRoute({
1074
- // this endpoint is deprecated and will be removed in the future
1075
- hide: true,
1076
- method: "get",
1077
- path: "/api/v1/flows/{flowId}/insights",
1078
- operationId: "retrieveInsights",
1079
- request: {
1080
- headers: SupabaseHeaderSchema,
1081
- params: FlowIdParam,
1082
- query: z.object({
1083
- flowDataId: z.string().pipe(z.coerce.number()).optional().openapi({
1084
- param: {
1085
- required: false
1086
- },
1087
- type: "integer"
1088
- })
1089
- })
1090
- },
1091
- responses: {
1092
- 200: {
1093
- description: "The content of the flow",
1094
- content: {
1095
- "application/json": {
1096
- schema: z.object({
1097
- dataReports: FrontendReportSchema.array(),
1098
- visualizations: V1FrontendVisualizationSchema.array()
1099
- })
1100
- }
1101
- }
1102
- },
1103
- 404: {
1104
- content: {
1105
- "application/json": {
1106
- schema: z.object({ error: z.string() })
1107
- }
1108
- },
1109
- description: "Unable to retrieve flow with this id"
1110
- },
1111
- 500: {
1112
- description: "Something wrong happened",
1113
- content: {
1114
- "application/json": {
1115
- schema: z.object({
1116
- error: z.string()
1117
- })
1118
- }
1119
- }
1120
- }
1121
- }
1122
- });
1123
- createRoute({
1124
- // this endpoint is deprecated and will be removed in the future
1125
- hide: true,
1126
- method: "get",
1127
- path: "/api/v1/flows/{flowId}/columns",
1128
- operationId: "retrieveFlowColumns",
1129
- request: {
1130
- headers: SupabaseHeaderSchema,
1131
- params: FlowIdParam,
1132
- query: FlowDataIdParam
1133
- },
1134
- responses: {
1135
- 200: {
1136
- description: "A list containing the columns of the flow",
1137
- content: {
1138
- "application/json": {
1139
- schema: FrontendReportColumnsSchema
1140
- }
1141
- }
1142
- },
1143
- 404: {
1144
- content: {
1145
- "application/json": {
1146
- schema: z.object({ error: z.string() })
1147
- }
1148
- },
1149
- description: "Unable to retrieve flow with this id"
1150
- },
1151
- 500: {
1152
- description: "Something wrong happened",
1153
- content: {
1154
- "application/json": {
1155
- schema: z.object({
1156
- error: z.string()
1157
- })
1158
- }
1159
- }
1160
- }
1161
- }
1162
- });
1163
1228
  var RetrieveFlow = createRoute({
1164
1229
  method: "get",
1165
1230
  path: "/api/v1/flows/{flowId}",
@@ -1302,55 +1367,6 @@ var ExportReportData = createRoute({
1302
1367
  }
1303
1368
  }
1304
1369
  });
1305
- createRoute({
1306
- // this endpoint is deprecated and will be removed in the future
1307
- hide: true,
1308
- method: "get",
1309
- path: "/api/v1/flows/{flowId}/data",
1310
- operationId: "retrieveFlowData",
1311
- request: {
1312
- headers: SupabaseHeaderSchema,
1313
- params: FlowIdParam,
1314
- query: z.object({
1315
- limit: limitQueryParams,
1316
- order: orderQueryParams,
1317
- cursor: cursorParams,
1318
- filter: filterQueryParams,
1319
- flowDataId: FlowDataIdParam.shape.flowDataId.openapi({
1320
- type: "integer",
1321
- param: { required: true }
1322
- })
1323
- })
1324
- },
1325
- responses: {
1326
- 200: {
1327
- description: "The content of the flow",
1328
- content: {
1329
- "application/json": {
1330
- schema: ReportDataSchema
1331
- }
1332
- }
1333
- },
1334
- 404: {
1335
- content: {
1336
- "application/json": {
1337
- schema: z.object({ error: z.string() })
1338
- }
1339
- },
1340
- description: "Unable to retrieve flow with this id"
1341
- },
1342
- 500: {
1343
- description: "Something wrong happened",
1344
- content: {
1345
- "application/json": {
1346
- schema: z.object({
1347
- error: z.string()
1348
- })
1349
- }
1350
- }
1351
- }
1352
- }
1353
- });
1354
1370
  var GetReportData = createRoute({
1355
1371
  method: "get",
1356
1372
  path: "/api/v1/data-reports/{report_id}/data",
@@ -1395,55 +1411,6 @@ var GetReportData = createRoute({
1395
1411
  }
1396
1412
  }
1397
1413
  });
1398
- createRoute({
1399
- // this endpoint is deprecated and will be removed in the future
1400
- hide: true,
1401
- method: "get",
1402
- path: "/api/v1/flows/{flowId}/count",
1403
- operationId: "retrieveFlowDataCount",
1404
- request: {
1405
- headers: SupabaseHeaderSchema,
1406
- params: FlowIdParam,
1407
- query: z.object({
1408
- flowDataId: z.string().pipe(z.coerce.number()).openapi({
1409
- param: {
1410
- required: false
1411
- },
1412
- type: "integer"
1413
- })
1414
- })
1415
- },
1416
- responses: {
1417
- 200: {
1418
- description: "The total count of rows in the flow",
1419
- content: {
1420
- "application/json": {
1421
- schema: z.object({
1422
- count: z.number().int().nonnegative().describe("Total number of rows in the flow")
1423
- })
1424
- }
1425
- }
1426
- },
1427
- 404: {
1428
- content: {
1429
- "application/json": {
1430
- schema: z.object({ error: z.string() })
1431
- }
1432
- },
1433
- description: "Unable to retrieve flow with this id"
1434
- },
1435
- 500: {
1436
- description: "Something wrong happened",
1437
- content: {
1438
- "application/json": {
1439
- schema: z.object({
1440
- error: z.string()
1441
- })
1442
- }
1443
- }
1444
- }
1445
- }
1446
- });
1447
1414
  var GetReportRowCount = createRoute({
1448
1415
  method: "get",
1449
1416
  path: "/api/v1/data-reports/{report_id}/count",
@@ -1483,106 +1450,30 @@ var GetReportRowCount = createRoute({
1483
1450
  }
1484
1451
  }
1485
1452
  });
1486
- createRoute({
1487
- // this endpoint is deprecated and will be removed in the future
1488
- hide: true,
1489
- method: "get",
1490
- path: "/api/v1/flow-data/{flowDataId}/feedback",
1491
- operationId: "retrieveFeedback",
1492
- request: {
1493
- headers: SupabaseHeaderSchema,
1494
- params: FlowDataIdParam
1495
- },
1496
- responses: {
1497
- 200: {
1498
- description: "The feedback for the flow data",
1499
- content: {
1500
- "application/json": {
1501
- schema: FeedbackSchema.nullable()
1502
- }
1503
- }
1504
- },
1505
- 404: {
1506
- content: {
1507
- "application/json": {
1508
- schema: z.object({ error: z.string() })
1509
- }
1510
- },
1511
- description: "Unable to retrieve feedback"
1512
- },
1513
- 500: {
1514
- description: "Something wrong happened",
1515
- content: {
1516
- "application/json": {
1517
- schema: z.object({
1518
- error: z.string()
1519
- })
1520
- }
1521
- }
1522
- }
1523
- }
1524
- });
1525
1453
  createRoute({
1526
1454
  method: "get",
1527
1455
  path: "/api/v1/data-reports/{report_id}/feedback",
1528
1456
  operationId: "getDataReportFeedback",
1529
1457
  request: {
1530
1458
  headers: SupabaseHeaderSchema,
1531
- params: ReportIdParam
1532
- },
1533
- responses: {
1534
- 200: {
1535
- description: "The feedback for the report",
1536
- content: {
1537
- "application/json": {
1538
- schema: FeedbackSchema.nullable()
1539
- }
1540
- }
1541
- },
1542
- 404: {
1543
- content: {
1544
- "application/json": {
1545
- schema: z.object({ error: z.string() })
1546
- }
1547
- },
1548
- description: "Unable to retrieve feedback"
1549
- },
1550
- 500: {
1551
- description: "Something wrong happened",
1552
- content: {
1553
- "application/json": {
1554
- schema: z.object({
1555
- error: z.string()
1556
- })
1557
- }
1558
- }
1559
- }
1560
- }
1561
- });
1562
- createRoute({
1563
- // this endpoint is deprecated and will be removed in the future
1564
- hide: true,
1565
- method: "post",
1566
- path: "/api/v1/flow-data/{flowDataId}/feedback",
1567
- operationId: "upsertFeedback",
1568
- request: {
1569
- headers: SupabaseHeaderSchema,
1570
- params: FlowDataIdParam,
1571
- body: {
1572
- description: "The feedback for the flow data",
1573
- required: true,
1574
- content: {
1575
- "application/json": {
1576
- schema: z.object({
1577
- helpfulness: FeedbackSchema.shape.helpfulness
1578
- })
1579
- }
1580
- }
1581
- }
1459
+ params: ReportIdParam
1582
1460
  },
1583
1461
  responses: {
1584
1462
  200: {
1585
- description: "Successfully upserted feedback"
1463
+ description: "The feedback for the report",
1464
+ content: {
1465
+ "application/json": {
1466
+ schema: FeedbackSchema.nullable()
1467
+ }
1468
+ }
1469
+ },
1470
+ 404: {
1471
+ content: {
1472
+ "application/json": {
1473
+ schema: z.object({ error: z.string() })
1474
+ }
1475
+ },
1476
+ description: "Unable to retrieve feedback"
1586
1477
  },
1587
1478
  500: {
1588
1479
  description: "Something wrong happened",
@@ -1631,40 +1522,6 @@ createRoute({
1631
1522
  }
1632
1523
  }
1633
1524
  });
1634
- createRoute({
1635
- // this endpoint is deprecated and will be removed in the future
1636
- hide: true,
1637
- method: "delete",
1638
- path: "/api/v1/flow-data/{flowDataId}/feedback",
1639
- operationId: "deleteFeedback",
1640
- request: {
1641
- headers: SupabaseHeaderSchema,
1642
- params: FlowDataIdParam
1643
- },
1644
- responses: {
1645
- 200: {
1646
- description: "Successfully deleted feedback"
1647
- },
1648
- 404: {
1649
- content: {
1650
- "application/json": {
1651
- schema: z.object({ error: z.string() })
1652
- }
1653
- },
1654
- description: "Unable to retrieve feedback"
1655
- },
1656
- 500: {
1657
- description: "Something wrong happened",
1658
- content: {
1659
- "application/json": {
1660
- schema: z.object({
1661
- error: z.string()
1662
- })
1663
- }
1664
- }
1665
- }
1666
- }
1667
- });
1668
1525
  createRoute({
1669
1526
  method: "delete",
1670
1527
  path: "/api/v1/data-reports/{report_id}/feedback",
@@ -1698,18 +1555,16 @@ createRoute({
1698
1555
  }
1699
1556
  });
1700
1557
  createRoute({
1701
- // this endpoint is deprecated and will be removed in the future
1702
- hide: true,
1703
1558
  method: "get",
1704
- path: "/api/v1/flow-data/{flowDataId}/explainability",
1705
- operationId: "retrieveFlowDataExplainability",
1559
+ path: "/api/v1/data-reports/{report_id}/explainability",
1560
+ operationId: "getDataReportExplainability",
1706
1561
  request: {
1707
1562
  headers: SupabaseHeaderSchema,
1708
- params: FlowDataIdParam
1563
+ params: ReportIdParam
1709
1564
  },
1710
1565
  responses: {
1711
1566
  200: {
1712
- description: "The explainability of the flow data",
1567
+ description: "The explainability of the report",
1713
1568
  content: {
1714
1569
  "application/json": {
1715
1570
  schema: FrontendReportExplainabilitySchema
@@ -1722,7 +1577,7 @@ createRoute({
1722
1577
  schema: z.object({ error: z.string() })
1723
1578
  }
1724
1579
  },
1725
- description: "Unable to retrieve flow with this id"
1580
+ description: "Unable to retrieve report with this id"
1726
1581
  },
1727
1582
  500: {
1728
1583
  description: "Something wrong happened",
@@ -1738,18 +1593,18 @@ createRoute({
1738
1593
  });
1739
1594
  createRoute({
1740
1595
  method: "get",
1741
- path: "/api/v1/data-reports/{report_id}/explainability",
1742
- operationId: "getDataReportExplainability",
1596
+ path: "/api/v1/data-reports/{report_id}",
1597
+ operationId: "getDataReport",
1743
1598
  request: {
1744
1599
  headers: SupabaseHeaderSchema,
1745
1600
  params: ReportIdParam
1746
1601
  },
1747
1602
  responses: {
1748
1603
  200: {
1749
- description: "The explainability of the report",
1604
+ description: "The visualizations for the report",
1750
1605
  content: {
1751
1606
  "application/json": {
1752
- schema: FrontendReportExplainabilitySchema
1607
+ schema: FrontendReportSchema
1753
1608
  }
1754
1609
  }
1755
1610
  },
@@ -1774,29 +1629,44 @@ createRoute({
1774
1629
  }
1775
1630
  });
1776
1631
  createRoute({
1777
- method: "get",
1778
- path: "/api/v1/data-reports/{report_id}",
1779
- operationId: "getDataReport",
1632
+ method: "post",
1633
+ path: "/api/v1/flow_data/v1/materialized_views/refresh",
1634
+ operationId: "refreshMaterializedViews",
1780
1635
  request: {
1781
1636
  headers: SupabaseHeaderSchema,
1782
- params: ReportIdParam
1637
+ body: {
1638
+ required: true,
1639
+ content: {
1640
+ "application/json": {
1641
+ schema: z.object({
1642
+ flow_data_ids: z.array(z.number().int()).min(1).describe("List of flow_data IDs to refresh")
1643
+ })
1644
+ }
1645
+ }
1646
+ }
1783
1647
  },
1784
1648
  responses: {
1785
1649
  200: {
1786
- description: "The visualizations for the report",
1650
+ description: "Successfully triggered refresh for materialized views",
1787
1651
  content: {
1788
1652
  "application/json": {
1789
- schema: FrontendReportSchema
1653
+ schema: z.object({
1654
+ status: z.literal("success"),
1655
+ /** Server timestamp when refresh was triggered (ISO 8601) */
1656
+ triggered_at: z.string()
1657
+ })
1790
1658
  }
1791
1659
  }
1792
1660
  },
1793
- 404: {
1661
+ 400: {
1662
+ description: "Invalid request",
1794
1663
  content: {
1795
1664
  "application/json": {
1796
- schema: z.object({ error: z.string() })
1665
+ schema: z.object({
1666
+ error: z.string()
1667
+ })
1797
1668
  }
1798
- },
1799
- description: "Unable to retrieve report with this id"
1669
+ }
1800
1670
  },
1801
1671
  500: {
1802
1672
  description: "Something wrong happened",
@@ -1811,37 +1681,28 @@ createRoute({
1811
1681
  }
1812
1682
  });
1813
1683
  createRoute({
1814
- hide: true,
1815
1684
  method: "get",
1816
- path: "/api/v1/data-reports/{report_id}/visualizations",
1817
- operationId: "getDataReportVisualizations",
1685
+ path: "/api/v1/flow_data/materialization-status",
1686
+ operationId: "getMaterializationStatus",
1818
1687
  request: {
1819
1688
  headers: SupabaseHeaderSchema,
1820
- params: ReportIdParam
1689
+ query: z.object({
1690
+ ids: z.string().transform((s) => s.split(",").map(Number)).describe("Comma-separated list of flow_data IDs")
1691
+ })
1821
1692
  },
1822
1693
  responses: {
1823
1694
  200: {
1824
- description: "The visualizations for the report",
1695
+ description: "Materialization status for the requested flow_data IDs",
1825
1696
  content: {
1826
1697
  "application/json": {
1827
- schema: z.object({
1828
- ...FrontendReportSchema.shape,
1829
- visualizations: z.union([
1830
- V1FrontendVisualizationSchema,
1831
- FrontendVisualizationSchema
1832
- ]).array()
1833
- })
1698
+ schema: z.array(z.object({
1699
+ id: z.number(),
1700
+ materialized_status: MaterializationStatusSchema.nullable(),
1701
+ last_materialized_at: z.string().nullable()
1702
+ }))
1834
1703
  }
1835
1704
  }
1836
1705
  },
1837
- 404: {
1838
- content: {
1839
- "application/json": {
1840
- schema: z.object({ error: z.string() })
1841
- }
1842
- },
1843
- description: "Unable to retrieve report with this id"
1844
- },
1845
1706
  500: {
1846
1707
  description: "Something wrong happened",
1847
1708
  content: {
@@ -2196,191 +2057,118 @@ createRoute({
2196
2057
  }
2197
2058
  });
2198
2059
 
2199
- // ../shared/dist/src/endpoints/auth.routes.js
2200
- var GetApiInformationInputSchema = z.object({
2201
- apiKey: z.string()
2202
- });
2203
- var GetApiInformationOutputSchema = z.object({
2204
- apiUrl: z.string(),
2205
- anonKey: z.string()
2206
- });
2207
- var GetApiInformation = createRoute({
2208
- method: "get",
2209
- path: "/api/v1/auth/apiInformation",
2210
- operationId: "getApiInformation",
2211
- request: {
2212
- query: GetApiInformationInputSchema
2213
- },
2214
- responses: {
2215
- 200: {
2216
- content: {
2217
- "application/json": {
2218
- schema: GetApiInformationOutputSchema
2219
- }
2220
- },
2221
- description: "Retrieve the API URL and anon key"
2222
- },
2223
- 400: {
2224
- content: {
2225
- "application/json": {
2226
- schema: z.object({ error: z.string() })
2227
- }
2228
- },
2229
- description: "Invalid input"
2230
- },
2231
- 500: {
2232
- content: {
2233
- "application/json": {
2234
- schema: z.object({
2235
- error: z.string()
2236
- })
2237
- }
2238
- },
2239
- description: "Unable to retrieve the API URL and anon key"
2240
- }
2241
- }
2060
+ // ../shared/dist/src/endpoints/companion/speech.routes.js
2061
+ var SpeechTokenResponseSchema = z.object({
2062
+ token: z.string().describe("Temporary AssemblyAI streaming token"),
2063
+ expiresAt: z.string().datetime().describe("ISO timestamp describing when the token expires.")
2242
2064
  });
2243
- createRoute({
2244
- hide: true,
2245
- method: "get",
2246
- path: "/api/auth/apiInformation",
2247
- operationId: "getApiInformation",
2065
+ var CreateSpeechToken = createRoute({
2066
+ method: "post",
2067
+ path: "/api/v1/speech/token",
2068
+ operationId: "createSpeechToken",
2248
2069
  request: {
2249
- query: GetApiInformationInputSchema
2070
+ headers: SupabaseHeaderSchema
2250
2071
  },
2251
2072
  responses: {
2252
2073
  200: {
2074
+ description: "A short-lived token that can be used to stream audio.",
2253
2075
  content: {
2254
2076
  "application/json": {
2255
- schema: GetApiInformationOutputSchema
2256
- }
2257
- },
2258
- description: "Retrieve the API URL and anon key"
2259
- },
2260
- 400: {
2261
- content: {
2262
- "application/json": {
2263
- schema: z.object({ error: z.string() })
2077
+ schema: SpeechTokenResponseSchema
2264
2078
  }
2265
- },
2266
- description: "Invalid input"
2079
+ }
2267
2080
  },
2268
2081
  500: {
2082
+ description: "Failed to create a speech token",
2269
2083
  content: {
2270
2084
  "application/json": {
2271
2085
  schema: z.object({
2272
2086
  error: z.string()
2273
2087
  })
2274
2088
  }
2275
- },
2276
- description: "Unable to retrieve the API URL and anon key"
2089
+ }
2277
2090
  }
2278
2091
  }
2279
2092
  });
2280
- var ExchangeExternalTokenInputSchema = z.object({
2281
- apiKey: z.string(),
2282
- externalJWT: z.string()
2283
- });
2284
- var ExchangeExternalTokenOutputSchema = z.object({
2285
- accessToken: z.string(),
2286
- refreshToken: z.string()
2093
+ z5.discriminatedUnion("status", [
2094
+ z5.object({
2095
+ status: z5.literal("error"),
2096
+ error: z5.string()
2097
+ }),
2098
+ z5.object({
2099
+ status: z5.literal("success"),
2100
+ flowId: z5.string()
2101
+ })
2102
+ ]);
2103
+ var TriggerFlowBody = z5.object({
2104
+ triggerId: z5.string(),
2105
+ variables: z5.record(z5.string(), z5.string()),
2106
+ applicationName: z5.string().optional()
2287
2107
  });
2288
- var ExchangeExternalToken = createRoute({
2108
+ var TriggerFlow = createRoute({
2289
2109
  method: "post",
2290
- path: "/api/v1/auth/exchangeExternalToken",
2291
- operationId: "exchangeExternalToken",
2110
+ path: "/api/v1/trigger-flow",
2111
+ operationId: "triggerFlow",
2292
2112
  request: {
2113
+ headers: SupabaseHeaderSchema,
2293
2114
  body: {
2294
2115
  required: true,
2116
+ description: "Trigger flow request body",
2295
2117
  content: {
2296
2118
  "application/json": {
2297
- schema: ExchangeExternalTokenInputSchema
2119
+ schema: TriggerFlowBody
2298
2120
  }
2299
2121
  }
2300
2122
  }
2301
2123
  },
2302
2124
  responses: {
2303
2125
  200: {
2126
+ description: "Flow id",
2304
2127
  content: {
2305
2128
  "application/json": {
2306
- schema: ExchangeExternalTokenOutputSchema
2129
+ schema: z5.object({
2130
+ status: z5.literal("success"),
2131
+ flowId: z5.string()
2132
+ })
2307
2133
  }
2308
- },
2309
- description: "Retrieve a JWT for an external user"
2134
+ }
2310
2135
  },
2311
2136
  400: {
2312
2137
  content: {
2313
2138
  "application/json": {
2314
- schema: z.object({ error: z.string() })
2315
- }
2316
- },
2317
- description: "Invalid input"
2318
- },
2319
- 500: {
2320
- content: {
2321
- "application/json": {
2322
- schema: z.object({
2323
- error: z.string()
2139
+ schema: z5.object({
2140
+ error: z5.string()
2324
2141
  })
2325
2142
  }
2326
2143
  },
2327
- description: "Unable to retrieve a JWT for an external user"
2328
- }
2329
- }
2330
- });
2331
-
2332
- // ../shared/dist/src/endpoints/companion/speech.routes.js
2333
- var SpeechTokenResponseSchema = z.object({
2334
- token: z.string().describe("Temporary AssemblyAI streaming token"),
2335
- expiresAt: z.string().datetime().describe("ISO timestamp describing when the token expires.")
2336
- });
2337
- var CreateSpeechToken = createRoute({
2338
- method: "post",
2339
- path: "/api/v1/speech/token",
2340
- operationId: "createSpeechToken",
2341
- request: {
2342
- headers: SupabaseHeaderSchema
2343
- },
2344
- responses: {
2345
- 200: {
2346
- description: "A short-lived token that can be used to stream audio.",
2144
+ description: "Invalid template or variable values"
2145
+ },
2146
+ 404: {
2347
2147
  content: {
2348
2148
  "application/json": {
2349
- schema: SpeechTokenResponseSchema
2149
+ schema: z5.object({ error: z5.string() })
2350
2150
  }
2351
- }
2151
+ },
2152
+ description: "Unable to retrieve trigger with this id"
2352
2153
  },
2353
2154
  500: {
2354
- description: "Failed to create a speech token",
2155
+ description: "Something wrong happened",
2355
2156
  content: {
2356
2157
  "application/json": {
2357
- schema: z.object({
2358
- error: z.string()
2158
+ schema: z5.object({
2159
+ error: z5.string()
2359
2160
  })
2360
2161
  }
2361
2162
  }
2362
2163
  }
2363
2164
  }
2364
2165
  });
2365
- var End2EndApiResponseSchema = z5.discriminatedUnion("status", [
2366
- z5.object({
2367
- status: z5.literal("error"),
2368
- error: z5.string()
2369
- }),
2370
- z5.object({
2371
- status: z5.literal("success"),
2372
- flowId: z5.string()
2373
- })
2374
- ]);
2375
- var TriggerFlowBody = z5.object({
2376
- triggerId: z5.string(),
2377
- variables: z5.record(z5.string(), z5.string()),
2378
- applicationName: z5.string().optional()
2379
- });
2380
- var TriggerFlow = createRoute({
2166
+ createRoute({
2167
+ hide: true,
2168
+ deprecated: true,
2381
2169
  method: "post",
2382
2170
  path: "/api/v1/trigger-flow/",
2383
- operationId: "triggerFlow",
2171
+ operationId: "triggerFlowOld",
2384
2172
  request: {
2385
2173
  headers: SupabaseHeaderSchema,
2386
2174
  body: {
@@ -2398,14 +2186,19 @@ var TriggerFlow = createRoute({
2398
2186
  description: "Flow id",
2399
2187
  content: {
2400
2188
  "application/json": {
2401
- schema: End2EndApiResponseSchema
2189
+ schema: z5.object({
2190
+ status: z5.literal("success"),
2191
+ flowId: z5.string()
2192
+ })
2402
2193
  }
2403
2194
  }
2404
2195
  },
2405
2196
  400: {
2406
2197
  content: {
2407
2198
  "application/json": {
2408
- schema: z5.object({ error: z5.string() })
2199
+ schema: z5.object({
2200
+ error: z5.string()
2201
+ })
2409
2202
  }
2410
2203
  },
2411
2204
  description: "Invalid template or variable values"
@@ -2524,18 +2317,14 @@ var createStorageAdapter = () => {
2524
2317
  return new MemoryStorageAdapter();
2525
2318
  }
2526
2319
  };
2527
- var hashString = (value) => {
2528
- const encoder = new TextEncoder();
2529
- const data = encoder.encode(value);
2530
- const hash = sha256(data);
2531
- return Array.from(hash).map((b) => b.toString(16).padStart(2, "0")).join("");
2532
- };
2533
2320
 
2534
2321
  // ../shared/dist/src/schemas/canvas.js
2322
+ var DATA_REPORT_LABEL = "dataReport";
2323
+ var VISUALIZATION_LABEL = "visualization";
2535
2324
  var CanvasSchema = z.object({
2536
2325
  company_id: z.number(),
2537
2326
  created_at: z.string(),
2538
- id: z.string().uuid(),
2327
+ id: z.uuid(),
2539
2328
  title: z.string().nullable(),
2540
2329
  updated_at: z.string(),
2541
2330
  is_removed: z.boolean(),
@@ -2569,6 +2358,22 @@ var CanvasIdParam = CanvasSchema.shape.id.openapi("CanvasId", {
2569
2358
  type: "string",
2570
2359
  format: "uuid"
2571
2360
  });
2361
+ var dataReportNodeSchema = z.object({
2362
+ type: z.literal(DATA_REPORT_LABEL),
2363
+ data: z.object({
2364
+ reportId: z.number()
2365
+ })
2366
+ });
2367
+ var visualizationNodeSchema = z.object({
2368
+ type: z.literal(VISUALIZATION_LABEL),
2369
+ data: z.object({
2370
+ visualizationId: z.number()
2371
+ })
2372
+ });
2373
+ z.discriminatedUnion("type", [
2374
+ dataReportNodeSchema,
2375
+ visualizationNodeSchema
2376
+ ]);
2572
2377
 
2573
2378
  // ../shared/dist/src/endpoints/companion/canvas.routes.js
2574
2379
  var ListCanvases = createRoute({
@@ -2810,164 +2615,372 @@ var GetCanvasForFlow = createRoute({
2810
2615
  }
2811
2616
  }
2812
2617
  }
2813
- });
2814
- var QuickActionSchema = z.object({
2815
- label: z.string(),
2816
- explanation: z.string()
2817
- });
2818
- var QuickActionsSchema = QuickActionSchema.array();
2819
- var FrontendTimelineItemSchema = z.discriminatedUnion("type", [
2618
+ });
2619
+
2620
+ // ../shared/dist/src/endpoints/companion/chat.routes.js
2621
+ var ChatMessages = createRoute({
2622
+ method: "get",
2623
+ path: "/api/v1/chat/{flowId}/messages",
2624
+ operationId: "retrieveChatMessages",
2625
+ request: {
2626
+ headers: SupabaseHeaderSchema,
2627
+ params: FlowIdParam
2628
+ },
2629
+ responses: {
2630
+ 200: {
2631
+ description: "The messages from the given flow",
2632
+ content: {
2633
+ "application/json": {
2634
+ // we don't want to have to write a parser for Vercel AI messages
2635
+ schema: z.object({ messages: z.looseObject({}).array() })
2636
+ }
2637
+ }
2638
+ },
2639
+ 404: {
2640
+ content: {
2641
+ "application/json": {
2642
+ schema: z.object({ error: z.string() })
2643
+ }
2644
+ },
2645
+ description: "Unable to retrieve flow with this id"
2646
+ },
2647
+ 500: {
2648
+ description: "Something wrong happened",
2649
+ content: {
2650
+ "application/json": {
2651
+ schema: z.object({
2652
+ error: z.string()
2653
+ })
2654
+ }
2655
+ }
2656
+ }
2657
+ }
2658
+ });
2659
+ dayjs.extend(relativeTime);
2660
+ dayjs.extend(customParseFormat);
2661
+ dayjs.extend(utc);
2662
+ dayjs.extend(timezone);
2663
+ var daysjs_default = dayjs;
2664
+
2665
+ // ../shared/dist/src/data/FormattedData.js
2666
+ var formatWithAutoPrecision = (value, options = {}) => {
2667
+ const { minPrecision = 0, maxPrecision = 6, trimZeros = true, useGrouping = true } = options;
2668
+ if (typeof value !== "number" || isNaN(value)) {
2669
+ return String(value);
2670
+ }
2671
+ if (value === 0) {
2672
+ return "0";
2673
+ }
2674
+ const absValue = Math.abs(value);
2675
+ let maximumFractionDigits;
2676
+ if (absValue >= 1e3) {
2677
+ maximumFractionDigits = 0;
2678
+ } else if (absValue >= 100) {
2679
+ maximumFractionDigits = 1;
2680
+ } else if (absValue >= 10) {
2681
+ maximumFractionDigits = 2;
2682
+ } else if (absValue >= 1) {
2683
+ maximumFractionDigits = 3;
2684
+ } else if (absValue >= 0.1) {
2685
+ maximumFractionDigits = 4;
2686
+ } else if (absValue >= 0.01) {
2687
+ maximumFractionDigits = 5;
2688
+ } else {
2689
+ maximumFractionDigits = maxPrecision;
2690
+ if (absValue > 0) {
2691
+ const exponent = Math.floor(Math.log10(absValue));
2692
+ if (exponent < 0) {
2693
+ maximumFractionDigits = Math.min(Math.abs(exponent) + 2, maxPrecision);
2694
+ }
2695
+ }
2696
+ }
2697
+ maximumFractionDigits = Math.max(maximumFractionDigits, minPrecision);
2698
+ const formatter = new Intl.NumberFormat(void 0, {
2699
+ minimumFractionDigits: trimZeros ? 0 : maximumFractionDigits,
2700
+ maximumFractionDigits,
2701
+ useGrouping
2702
+ });
2703
+ return formatter.format(value);
2704
+ };
2705
+ var MIN_VALID_YEAR = 1900;
2706
+ var MAX_VALID_YEAR = 2200;
2707
+ var zonedatetime = (format, zone) => ({ format, type: "zonedatetime", zone });
2708
+ var datetime = (format) => ({ format, type: "datetime" });
2709
+ var date = (format) => ({ format, type: "date" });
2710
+ var DATE_FORMATS = [
2711
+ // ISO 8601 formats
2712
+ zonedatetime("YYYY-MM-DDTHH:mm:ss.SSSZ", "UTC"),
2713
+ zonedatetime("YYYY-MM-DDTHH:mm:ssZ", "UTC"),
2714
+ zonedatetime("YYYY-MM-DDTHH:mmZ", "UTC"),
2715
+ datetime("YYYY-MM-DDTHH:mm:ss"),
2716
+ datetime("YYYY-MM-DDTHH:mm"),
2717
+ date("YYYY-MM-DDT"),
2718
+ // Standard date formats
2719
+ date("YYYY-MM-DD"),
2720
+ date("YYYY/MM/DD"),
2721
+ date("DD-MM-YYYY"),
2722
+ date("DD/MM/YYYY"),
2723
+ date("MM-DD-YYYY"),
2724
+ date("MM/DD/YYYY"),
2725
+ // Date time formats
2726
+ datetime("YYYY-MM-DD HH:mm:ss"),
2727
+ datetime("YYYY-MM-DD HH:mm"),
2728
+ datetime("YYYY/MM/DD HH:mm:ss"),
2729
+ datetime("YYYY/MM/DD HH:mm"),
2730
+ datetime("DD-MM-YYYY HH:mm:ss"),
2731
+ datetime("DD-MM-YYYY HH:mm"),
2732
+ datetime("DD/MM/YYYY HH:mm:ss"),
2733
+ datetime("DD/MM/YYYY HH:mm"),
2734
+ datetime("MM-DD-YYYY HH:mm:ss"),
2735
+ datetime("MM-DD-YYYY HH:mm"),
2736
+ datetime("MM/DD/YYYY HH:mm:ss"),
2737
+ datetime("MM/DD/YYYY HH:mm")
2738
+ ];
2739
+ var isDateString = (value) => {
2740
+ if (typeof value !== "string")
2741
+ return { isValid: false };
2742
+ const stripped = value.replace(/[-/.:\s]/g, "");
2743
+ if (/^\d+$/.test(stripped)) {
2744
+ if (stripped.length < 6)
2745
+ return { isValid: false };
2746
+ if (value.length === stripped.length)
2747
+ return { isValid: false };
2748
+ }
2749
+ if (stripped.length > "YYYY-MM-DDTHH:mm:ss.SSS+00:00".length) {
2750
+ return { isValid: false };
2751
+ }
2752
+ for (const format of DATE_FORMATS) {
2753
+ let date2;
2754
+ try {
2755
+ if (format.type === "zonedatetime") {
2756
+ date2 = daysjs_default.tz(value, format.format, format.zone);
2757
+ } else {
2758
+ date2 = daysjs_default(value, format.format, true);
2759
+ }
2760
+ } catch {
2761
+ continue;
2762
+ }
2763
+ if (date2.isValid()) {
2764
+ const year = date2.year();
2765
+ if (year < MIN_VALID_YEAR || year > MAX_VALID_YEAR)
2766
+ continue;
2767
+ const isDateTime = format.type === "zonedatetime" || format.type == "datetime";
2768
+ return {
2769
+ isValid: true,
2770
+ parsedDate: date2,
2771
+ isDateTime
2772
+ };
2773
+ }
2774
+ }
2775
+ return { isValid: false };
2776
+ };
2777
+ var formatDataValue = (value, { replaceNullValue } = {
2778
+ replaceNullValue: true
2779
+ }) => {
2780
+ if (value === null || value === void 0) {
2781
+ return {
2782
+ display: replaceNullValue ? "empty" : null,
2783
+ sortValue: null
2784
+ };
2785
+ }
2786
+ let processedValue = value;
2787
+ if (typeof processedValue === "string") {
2788
+ try {
2789
+ const parsed = JSON.parse(processedValue);
2790
+ processedValue = parsed;
2791
+ } catch {
2792
+ }
2793
+ }
2794
+ if (processedValue && typeof processedValue === "object" && Object.keys(processedValue).length === 1 && "value" in processedValue) {
2795
+ const extractedValue = processedValue.value;
2796
+ const dateResult2 = isDateString(extractedValue);
2797
+ if (dateResult2.isValid) {
2798
+ return {
2799
+ display: dateResult2.isDateTime ? dateResult2.parsedDate.format("YYYY-MM-DD HH:mm:ss") : dateResult2.parsedDate.format("YYYY-MM-DD"),
2800
+ sortValue: dateResult2.parsedDate.valueOf()
2801
+ };
2802
+ }
2803
+ return {
2804
+ display: String(extractedValue),
2805
+ sortValue: extractedValue
2806
+ };
2807
+ }
2808
+ const dateResult = isDateString(processedValue);
2809
+ if (dateResult.isValid) {
2810
+ return {
2811
+ display: dateResult.isDateTime ? dateResult.parsedDate.format("YYYY-MM-DD HH:mm:ss") : dateResult.parsedDate.format("YYYY-MM-DD"),
2812
+ sortValue: dateResult.parsedDate.valueOf()
2813
+ };
2814
+ }
2815
+ if (typeof processedValue === "object") {
2816
+ const stringified = JSON.stringify(processedValue, null, 2);
2817
+ return {
2818
+ display: stringified,
2819
+ sortValue: stringified
2820
+ };
2821
+ }
2822
+ if (typeof processedValue === "boolean") {
2823
+ return {
2824
+ display: String(processedValue),
2825
+ sortValue: processedValue ? 1 : 0
2826
+ };
2827
+ }
2828
+ if (typeof processedValue === "number") {
2829
+ return {
2830
+ display: processedValue >= MIN_VALID_YEAR && processedValue <= MAX_VALID_YEAR && Number.isInteger(processedValue) ? String(processedValue) : formatWithAutoPrecision(processedValue),
2831
+ sortValue: processedValue
2832
+ };
2833
+ }
2834
+ return {
2835
+ // eslint-disable-next-line @typescript-eslint/no-base-to-string
2836
+ display: String(processedValue),
2837
+ sortValue: processedValue
2838
+ };
2839
+ };
2840
+
2841
+ // ../shared/dist/src/schemas/visualizations.js
2842
+ var commonConfigProperties = {
2843
+ title: z.string()
2844
+ };
2845
+ var cartesianConfigProperties = {
2846
+ xAxisLabel: z.string(),
2847
+ yAxisLabel: z.string(),
2848
+ xAxisDataKey: z.string().optional(),
2849
+ yAxisDataKey: z.string().optional(),
2850
+ dimensionDataKey: z.string().optional(),
2851
+ valueColumns: z.array(z.string()).optional()
2852
+ };
2853
+ var V1VisualizationConfigurationSchema = z.discriminatedUnion("type", [
2854
+ // Bar chart
2855
+ z.object({
2856
+ type: z.literal("bar"),
2857
+ ...commonConfigProperties,
2858
+ ...cartesianConfigProperties
2859
+ }),
2860
+ // Line/Area chart
2820
2861
  z.object({
2821
- type: z.literal("dataReport"),
2822
- flowDataId: z.number(),
2823
- flowId: z.string(),
2824
- title: z.string(),
2825
- bookmarked: z.boolean(),
2826
- answer: z.string().nullable()
2862
+ type: z.literal("line/area"),
2863
+ ...commonConfigProperties,
2864
+ ...cartesianConfigProperties
2827
2865
  }),
2866
+ // Scatter chart
2828
2867
  z.object({
2829
- type: z.literal("visualization"),
2830
- flowId: z.string(),
2831
- flowDataId: z.number(),
2832
- flowDataVisualizationId: z.number(),
2833
- title: z.string(),
2834
- bookmarked: z.boolean()
2868
+ type: z.literal("scatter"),
2869
+ ...commonConfigProperties,
2870
+ ...cartesianConfigProperties
2835
2871
  }),
2872
+ // Pie chart
2836
2873
  z.object({
2837
- type: z.literal("message")
2874
+ type: z.literal("pie"),
2875
+ ...commonConfigProperties,
2876
+ nameKey: z.string(),
2877
+ dataKey: z.string()
2838
2878
  })
2839
2879
  ]);
2840
-
2841
- // ../shared/dist/src/endpoints/companion/chat.routes.js
2842
- createRoute({
2843
- hide: true,
2844
- method: "get",
2845
- path: "/api/v1/chat/{flowId}/timeline",
2846
- operationId: "retrieveChatTimeline",
2847
- request: {
2848
- headers: SupabaseHeaderSchema,
2849
- params: FlowIdParam
2850
- },
2851
- responses: {
2852
- 200: {
2853
- description: "The timeline of generated insights for the flow",
2854
- content: {
2855
- "application/json": {
2856
- schema: FrontendTimelineItemSchema.array()
2857
- }
2858
- }
2859
- },
2860
- 404: {
2861
- content: {
2862
- "application/json": {
2863
- schema: z.object({ error: z.string() })
2864
- }
2865
- },
2866
- description: "Unable to retrieve flow with this id"
2867
- },
2868
- 500: {
2869
- description: "Something wrong happened",
2870
- content: {
2871
- "application/json": {
2872
- schema: z.object({
2873
- error: z.string()
2874
- })
2875
- }
2876
- }
2877
- }
2878
- }
2880
+ var VisualizationConfigurationSchema = z.discriminatedUnion("type", [
2881
+ z.object({
2882
+ type: z.literal("bar"),
2883
+ ...commonConfigProperties,
2884
+ config_version: z.literal(2),
2885
+ xAxisLabel: z.string(),
2886
+ yAxisLabel: z.string(),
2887
+ categoryColumn: z.string(),
2888
+ secondaryCategoryColumn: z.string().optional(),
2889
+ valueColumn: z.string()
2890
+ }),
2891
+ // Line/Area chart - version 2: New format
2892
+ z.object({
2893
+ type: z.literal("line/area"),
2894
+ config_version: z.literal(2),
2895
+ ...commonConfigProperties,
2896
+ xAxisColumn: z.string(),
2897
+ valueColumns: z.array(z.string()),
2898
+ yAxisLabels: z.array(z.string())
2899
+ }),
2900
+ // Line/Area chart - categorical format (requires pivoting)
2901
+ z.object({
2902
+ type: z.literal("line/area-categorical"),
2903
+ ...commonConfigProperties,
2904
+ config_version: z.literal(2),
2905
+ valueColumn: z.string(),
2906
+ xAxisColumn: z.string(),
2907
+ xAxisLabel: z.string(),
2908
+ yAxisLabel: z.string(),
2909
+ categoryColumn: z.string()
2910
+ }),
2911
+ // Scatter chart - new format (v2)
2912
+ z.object({
2913
+ type: z.literal("scatter"),
2914
+ ...commonConfigProperties,
2915
+ config_version: z.literal(2),
2916
+ xAxisLabel: z.string(),
2917
+ yAxisLabel: z.string(),
2918
+ xAxisValueColumn: z.string(),
2919
+ yAxisValueColumn: z.string()
2920
+ }),
2921
+ // Pie chart - new format (v2)
2922
+ z.object({
2923
+ type: z.literal("pie"),
2924
+ ...commonConfigProperties,
2925
+ config_version: z.literal(2),
2926
+ categoryColumn: z.string(),
2927
+ valueColumn: z.string()
2928
+ })
2929
+ ]);
2930
+ var BaseVisualizationSchema = z.object({
2931
+ id: z.number(),
2932
+ flow_data_id: z.number(),
2933
+ created_at: z.string(),
2934
+ sql: z.string(),
2935
+ bookmarked: z.boolean(),
2936
+ data_sample: z.array(z.record(z.string(), z.unknown())),
2937
+ is_sample: z.boolean(),
2938
+ data_summary: z.record(z.string(), z.unknown()),
2939
+ flow_data: MaterializationFieldsSchema.optional()
2879
2940
  });
2880
- var ChatMessages = createRoute({
2881
- method: "get",
2882
- path: "/api/v1/chat/{flowId}/messages",
2883
- operationId: "retrieveChatMessages",
2884
- request: {
2885
- headers: SupabaseHeaderSchema,
2886
- params: FlowIdParam
2887
- },
2888
- responses: {
2889
- 200: {
2890
- description: "The messages from the given flow",
2891
- content: {
2892
- "application/json": {
2893
- // we don't want to have to write a parser for Vercel AI messages
2894
- schema: z.object({ messages: z.looseObject({}).array() })
2895
- }
2896
- }
2897
- },
2898
- 404: {
2899
- content: {
2900
- "application/json": {
2901
- schema: z.object({ error: z.string() })
2902
- }
2903
- },
2904
- description: "Unable to retrieve flow with this id"
2905
- },
2906
- 500: {
2907
- description: "Something wrong happened",
2908
- content: {
2909
- "application/json": {
2910
- schema: z.object({
2911
- error: z.string()
2912
- })
2913
- }
2914
- }
2915
- }
2916
- }
2941
+ var V1VisualizationSchema = z.object({
2942
+ ...BaseVisualizationSchema.shape,
2943
+ configuration: V1VisualizationConfigurationSchema
2917
2944
  });
2918
- createRoute({
2919
- hide: true,
2920
- method: "post",
2921
- path: "/api/v1/chat/{flowId}/quick-actions",
2922
- request: {
2923
- headers: SupabaseHeaderSchema,
2924
- params: FlowIdParam,
2925
- body: {
2926
- content: {
2927
- "application/json": {
2928
- schema: z.object({
2929
- content: z.string()
2930
- })
2931
- }
2932
- }
2933
- }
2934
- },
2935
- responses: {
2936
- 200: {
2937
- description: "The quick actions for the given message",
2938
- content: {
2939
- "application/json": {
2940
- schema: QuickActionsSchema
2941
- }
2942
- }
2943
- },
2944
- 400: {
2945
- content: {
2946
- "application/json": {
2947
- schema: z.object({ error: z.string() })
2948
- }
2949
- },
2950
- description: "The provided content is invalid"
2951
- },
2952
- 404: {
2953
- content: {
2954
- "application/json": {
2955
- schema: z.object({ error: z.string() })
2956
- }
2957
- },
2958
- description: "Unable to retrieve flow with this id"
2959
- },
2960
- 500: {
2961
- description: "Something wrong happened",
2962
- content: {
2963
- "application/json": {
2964
- schema: z.object({
2965
- error: z.string()
2966
- })
2967
- }
2968
- }
2969
- }
2970
- }
2945
+ var VisualizationSchema = z.object({
2946
+ ...BaseVisualizationSchema.shape,
2947
+ configuration: VisualizationConfigurationSchema
2948
+ });
2949
+ var VisualizationDataSchema = z.array(z.record(
2950
+ z.string(),
2951
+ // any key
2952
+ z.union([
2953
+ // Date objects FIRST
2954
+ z.date(),
2955
+ z.coerce.number(),
2956
+ // Handle various data types including BigQueryDate
2957
+ z.unknown().transform((val) => formatDataValue(val).display)
2958
+ ])
2959
+ )).openapi("VisualizationData");
2960
+ var V1FrontendVisualizationSchema = V1VisualizationSchema.omit({
2961
+ sql: true,
2962
+ data_sample: true,
2963
+ is_sample: true,
2964
+ data_summary: true
2965
+ });
2966
+ var FrontendVisualizationSchema = VisualizationSchema.omit({
2967
+ sql: true,
2968
+ data_sample: true,
2969
+ is_sample: true,
2970
+ data_summary: true
2971
+ });
2972
+ var VisualizationMetadataSchema = z.object({
2973
+ wasSampled: z.boolean(),
2974
+ originalCount: z.number(),
2975
+ sampledCount: z.number()
2976
+ }).optional();
2977
+ var V1FrontendVisualizationWithDataSchema = V1FrontendVisualizationSchema.extend({
2978
+ data: VisualizationDataSchema,
2979
+ _metadata: VisualizationMetadataSchema
2980
+ });
2981
+ var FrontendVisualizationWithDataSchema = FrontendVisualizationSchema.extend({
2982
+ data: VisualizationDataSchema,
2983
+ _metadata: VisualizationMetadataSchema
2971
2984
  });
2972
2985
 
2973
2986
  // ../shared/dist/src/endpoints/visualizations.routes.js
@@ -3114,10 +3127,6 @@ var toSearchParams = ({ cursor, filters, sorting, limit }) => {
3114
3127
  }
3115
3128
  return params;
3116
3129
  };
3117
-
3118
- // package.json
3119
- var package_default = {
3120
- version: "0.5.3"};
3121
3130
  var MageMetricsChatTransport = class extends DefaultChatTransport {
3122
3131
  constructor(apiUrl, flowId, options) {
3123
3132
  super({
@@ -3130,48 +3139,6 @@ var MageMetricsChatTransport = class extends DefaultChatTransport {
3130
3139
  }
3131
3140
  };
3132
3141
 
3133
- // src/core/MageMetricsEventEmitter.ts
3134
- var MageMetricsEventEmitter = class {
3135
- listeners = /* @__PURE__ */ new Map();
3136
- addEventListener(type, listener, options) {
3137
- if (!this.listeners.has(type)) {
3138
- this.listeners.set(type, /* @__PURE__ */ new Set());
3139
- }
3140
- if (options?.signal) {
3141
- if (options.signal.aborted) {
3142
- return;
3143
- }
3144
- const abortHandler = () => {
3145
- this.removeEventListener(type, listener);
3146
- };
3147
- options.signal.addEventListener("abort", abortHandler, { once: true });
3148
- }
3149
- this.listeners.get(type).add(listener);
3150
- }
3151
- removeEventListener(type, listener) {
3152
- const typeListeners = this.listeners.get(type);
3153
- if (typeListeners) {
3154
- typeListeners.delete(listener);
3155
- if (typeListeners.size === 0) {
3156
- this.listeners.delete(type);
3157
- }
3158
- }
3159
- }
3160
- dispatch(type, detail) {
3161
- const typeListeners = this.listeners.get(type);
3162
- if (typeListeners) {
3163
- const event = { type, detail };
3164
- typeListeners.forEach((listener) => {
3165
- try {
3166
- listener(event);
3167
- } catch (error) {
3168
- console.error(`Error in event listener for "${type}":`, error);
3169
- }
3170
- });
3171
- }
3172
- }
3173
- };
3174
-
3175
3142
  // src/core/resolvable.ts
3176
3143
  var resolve = (value) => {
3177
3144
  if (typeof value === "function") {
@@ -3180,45 +3147,54 @@ var resolve = (value) => {
3180
3147
  return Promise.resolve(value);
3181
3148
  };
3182
3149
 
3183
- // src/core/types.ts
3184
- var TOKEN_STORAGE_KEY = "mm-ai-sp-token";
3185
- var CHECK_KEY = "mm-ai-check-key";
3186
-
3187
3150
  // src/core/MageMetricsClient.ts
3188
- var MM_CLIENT_VERSION = package_default.version;
3151
+ var MM_CLIENT_VERSION3 = package_default.version;
3189
3152
  var getPublicApiClient = (apiUrl, apiKey) => {
3190
- const client = createApiClient({ baseUrl: apiUrl });
3153
+ const client = createApiClient2({ baseUrl: apiUrl });
3191
3154
  client.use(throwOnError);
3192
- client.use(addVersionHeader(MM_CLIENT_VERSION));
3155
+ client.use(addVersionHeader(MM_CLIENT_VERSION3));
3193
3156
  client.use(addApiKeyHeader(apiKey));
3194
3157
  return client;
3195
3158
  };
3196
3159
  var MageMetricsClient = class {
3197
3160
  config;
3198
- authState = "initializing";
3199
- supabaseClient = null;
3161
+ authProvider;
3200
3162
  internalApiClient;
3201
- noAuthApiClient = null;
3202
- authApiResponse = null;
3203
3163
  authPromise = null;
3204
- processedJwt = Symbol("initial");
3205
- userId = null;
3206
- storageAdapter;
3207
- events = new MageMetricsEventEmitter();
3208
- authOptions;
3209
- constructor(config, auth) {
3164
+ constructor(config, authProviderOrAuthOptions) {
3210
3165
  this.config = config;
3211
- this.storageAdapter = config.storageAdapter || createStorageAdapter();
3212
- this.internalApiClient = createApiClient({
3166
+ const isAuthProvider = authProviderOrAuthOptions && "initialize" in authProviderOrAuthOptions && "getHeaders" in authProviderOrAuthOptions;
3167
+ if (isAuthProvider) {
3168
+ this.authProvider = authProviderOrAuthOptions;
3169
+ } else {
3170
+ const storageAdapter = config.storageAdapter || createStorageAdapter();
3171
+ this.authProvider = new ExternalAuthProvider({
3172
+ apiUrl: config.apiUrl,
3173
+ apiKey: config.apiKey,
3174
+ externalJwt: config.externalJwt,
3175
+ additionalHeaders: config.additionalHeaders,
3176
+ storage: storageAdapter,
3177
+ applicationName: config.applicationName,
3178
+ authOptions: authProviderOrAuthOptions
3179
+ });
3180
+ }
3181
+ this.internalApiClient = createApiClient2({
3213
3182
  baseUrl: this.config.apiUrl
3214
3183
  });
3215
3184
  this.internalApiClient.use(throwOnError);
3216
3185
  this.internalApiClient.use(this.createSupabaseHeaderMiddleware());
3217
- this.authOptions = auth || {};
3218
3186
  }
3187
+ /* This is used by react-query query keys to identify unique clients
3188
+ * we hash it to make it more digestible and safer to debug/log
3189
+ */
3219
3190
  toJSON() {
3220
3191
  return {
3221
- config: this.encodeCheckKey(this.config.apiKey, this.config.apiUrl)
3192
+ config: hashString(
3193
+ JSON.stringify({
3194
+ apiKey: this.config.apiKey,
3195
+ apiUrl: this.config.apiUrl
3196
+ })
3197
+ )
3222
3198
  };
3223
3199
  }
3224
3200
  get apiConfig() {
@@ -3235,7 +3211,7 @@ var MageMetricsClient = class {
3235
3211
  * @param options.signal an optional AbortSignal to abort the event listener
3236
3212
  */
3237
3213
  addEventListener(type, listener, options) {
3238
- this.events.addEventListener(type, listener, options);
3214
+ this.authProvider.addEventListener(type, listener, options);
3239
3215
  }
3240
3216
  /**
3241
3217
  * Remove an event listener
@@ -3243,60 +3219,42 @@ var MageMetricsClient = class {
3243
3219
  * @param listener the listener to remove
3244
3220
  */
3245
3221
  removeEventListener(type, listener) {
3246
- this.events.removeEventListener(type, listener);
3222
+ this.authProvider.removeEventListener(type, listener);
3247
3223
  }
3248
3224
  async waitForAuth() {
3249
- if (this.authState === "ready") {
3225
+ if (this.authProvider.getState() === "ready") {
3250
3226
  return Promise.resolve();
3251
3227
  }
3252
- if (this.authState === "error") {
3228
+ if (this.authProvider.getState() === "error") {
3253
3229
  throw new Error("Authentication failed");
3254
3230
  }
3255
3231
  if (!this.authPromise) {
3256
- this.authPromise = this.performAuthFlow();
3232
+ this.authPromise = this.authProvider.initialize();
3257
3233
  }
3258
3234
  return this.authPromise;
3259
3235
  }
3260
3236
  async updateExternalJwt(jwt) {
3261
- if (this.config.externalJwt === jwt) return;
3262
- this.config.externalJwt = jwt;
3263
- this.processedJwt = Symbol("updating");
3264
- await this.performAuthFlow();
3237
+ await this.authProvider.updateExternalJwt(jwt);
3265
3238
  }
3266
3239
  get state() {
3267
- return this.authState;
3240
+ return this.authProvider.getState();
3268
3241
  }
3269
3242
  async getHeaders() {
3270
3243
  await this.waitForAuth();
3271
- if (!this.supabaseClient) {
3272
- return {};
3273
- }
3274
- const session = await this.supabaseClient.getSession();
3275
- if (!session.data.session) {
3276
- return {};
3277
- }
3278
- const { access_token } = session.data.session;
3279
- return {
3280
- [HEADER_CLIENT_VERSION]: MM_CLIENT_VERSION,
3281
- "sp-access-token": access_token
3282
- };
3283
- }
3284
- async clearStorage() {
3285
- try {
3286
- await this.storageAdapter.removeItem(TOKEN_STORAGE_KEY);
3287
- await this.storageAdapter.removeItem(CHECK_KEY);
3288
- } catch {
3289
- }
3244
+ return this.authProvider.getHeaders();
3290
3245
  }
3291
3246
  async logout() {
3292
- if (this.supabaseClient) {
3293
- await this.supabaseClient.signOut({ scope: "local" });
3294
- }
3295
- await this.clearStorage();
3247
+ await this.authProvider.logout();
3296
3248
  }
3297
3249
  auth = {
3298
- startAutoRefresh: () => this.supabaseClient?.startAutoRefresh(),
3299
- stopAuthRefresh: () => this.supabaseClient?.startAutoRefresh()
3250
+ startAutoRefresh: () => {
3251
+ const supabaseClient = this.authProvider.getSupabaseClient();
3252
+ return supabaseClient?.startAutoRefresh();
3253
+ },
3254
+ stopAuthRefresh: () => {
3255
+ const supabaseClient = this.authProvider.getSupabaseClient();
3256
+ return supabaseClient?.stopAutoRefresh();
3257
+ }
3300
3258
  };
3301
3259
  /**
3302
3260
  * Public API methods that automatically wait for authentication
@@ -3395,7 +3353,7 @@ var MageMetricsClient = class {
3395
3353
  return { flowId: data.flowId };
3396
3354
  } else {
3397
3355
  const { triggerId, variables } = request;
3398
- const { data, response } = await this.internalApiClient.POST(
3356
+ const { data, error, response } = await this.internalApiClient.POST(
3399
3357
  TriggerFlow.path,
3400
3358
  {
3401
3359
  body: {
@@ -3405,17 +3363,13 @@ var MageMetricsClient = class {
3405
3363
  }
3406
3364
  }
3407
3365
  );
3408
- if (!data || data.status === "error") {
3409
- throw new ApiError(
3410
- data?.error ?? "Failed to trigger flow",
3411
- response,
3412
- {
3413
- status: response.status,
3414
- statusText: response.statusText,
3415
- url: response.url,
3416
- method: "POST"
3417
- }
3418
- );
3366
+ if (error) {
3367
+ throw new ApiError(error.error, response, {
3368
+ status: response.status,
3369
+ statusText: response.statusText,
3370
+ url: response.url,
3371
+ method: "POST"
3372
+ });
3419
3373
  }
3420
3374
  return { flowId: data.flowId };
3421
3375
  }
@@ -3707,156 +3661,13 @@ var MageMetricsClient = class {
3707
3661
  };
3708
3662
  }
3709
3663
  };
3710
- /**
3711
- * Perform the complete authentication flow
3712
- */
3713
- async performAuthFlow() {
3714
- try {
3715
- this.setState("initializing");
3716
- const apiInfo = await this.getApiInformation();
3717
- this.initializeSupabaseClient(apiInfo.anonKey, apiInfo.apiUrl);
3718
- await this.handleAuthentication();
3719
- if (this.config.externalJwt) {
3720
- await this.saveCheckKey(this.config.externalJwt, this.config.apiKey);
3721
- }
3722
- this.setState("ready");
3723
- } catch (error) {
3724
- console.error("Authentication flow failed:", error);
3725
- this.setState("error");
3726
- throw error;
3727
- }
3728
- }
3729
- async getApiInformation() {
3730
- if (!this.noAuthApiClient || !this.authApiResponse) {
3731
- this.noAuthApiClient = getPublicApiClient(
3732
- this.config.apiUrl,
3733
- this.config.apiKey
3734
- );
3735
- const { data } = await this.noAuthApiClient.GET(GetApiInformation.path, {
3736
- params: {
3737
- query: {
3738
- apiKey: this.config.apiKey
3739
- }
3740
- }
3741
- });
3742
- if (!data) {
3743
- throw new Error("Failed to fetch API information");
3744
- }
3745
- this.authApiResponse = data;
3746
- }
3747
- return this.authApiResponse;
3748
- }
3749
- initializeSupabaseClient(anonKey, apiUrl) {
3750
- if (!this.supabaseClient) {
3751
- this.supabaseClient = new GoTrueClient({
3752
- url: `${apiUrl}/auth/v1`,
3753
- storageKey: TOKEN_STORAGE_KEY,
3754
- headers: {
3755
- apiKey: anonKey
3756
- },
3757
- storage: this.storageAdapter,
3758
- ...this.authOptions
3759
- });
3760
- this.supabaseClient.onAuthStateChange((event, session) => {
3761
- console.debug("Supabase auth state change:", event, !!session);
3762
- if (event === "SIGNED_IN" && session?.user) {
3763
- if (this.userId !== session.user.id && this.userId !== null) {
3764
- this.events.dispatch("userChange", { id: session.user.id });
3765
- }
3766
- this.userId = session.user.id;
3767
- }
3768
- if (event === "TOKEN_REFRESHED" && session) {
3769
- console.debug("Token refreshed successfully");
3770
- this.setState("ready");
3771
- } else if (event === "SIGNED_OUT") {
3772
- console.debug("User signed out");
3773
- void this.clearStorage();
3774
- this.setState("initializing");
3775
- }
3776
- });
3777
- }
3778
- }
3779
3664
  client() {
3780
3665
  return this.internalApiClient;
3781
3666
  }
3782
- /**
3783
- * Handle the authentication logic (check session or exchange token)
3784
- */
3785
- async handleAuthentication() {
3786
- if (!this.supabaseClient) {
3787
- throw new Error("Supabase client not initialized");
3788
- }
3789
- if (this.processedJwt === this.config.externalJwt) {
3790
- return;
3791
- }
3792
- try {
3793
- const { data, error } = await this.supabaseClient.getSession();
3794
- if (error) {
3795
- console.error("Error getting session:", error);
3796
- this.processedJwt = this.config.externalJwt || "";
3797
- return;
3798
- }
3799
- const isCheckValid = await this.compareCheckKey(
3800
- this.config.externalJwt ?? "",
3801
- this.config.apiKey
3802
- );
3803
- if (data.session && this.config.externalJwt && isCheckValid) {
3804
- console.debug("Session found, authentication ready");
3805
- this.processedJwt = this.config.externalJwt || "";
3806
- } else if (this.config.externalJwt) {
3807
- console.debug("No session found, exchanging external JWT");
3808
- await this.clearCheckKey();
3809
- await this.exchangeExternalToken();
3810
- this.processedJwt = this.config.externalJwt;
3811
- } else {
3812
- console.debug("No session and no external JWT provided");
3813
- this.processedJwt = this.config.externalJwt || "";
3814
- }
3815
- } catch (error) {
3816
- console.error("Unhandled error during authentication:", error);
3817
- this.processedJwt = this.config.externalJwt || "";
3818
- throw error;
3819
- }
3820
- }
3821
- /**
3822
- * Exchange external JWT for Supabase tokens
3823
- */
3824
- async exchangeExternalToken() {
3825
- if (!this.noAuthApiClient || !this.supabaseClient || !this.config.externalJwt) {
3826
- throw new Error(
3827
- "Required clients or JWT not available for token exchange"
3828
- );
3829
- }
3830
- const { data } = await this.noAuthApiClient.POST(
3831
- ExchangeExternalToken.path,
3832
- {
3833
- body: {
3834
- apiKey: this.config.apiKey,
3835
- externalJWT: this.config.externalJwt
3836
- },
3837
- headers: this.config.additionalHeaders || {}
3838
- }
3839
- );
3840
- if (!data) {
3841
- throw new Error("Failed to exchange tokens");
3842
- }
3843
- await this.supabaseClient.setSession({
3844
- access_token: data.accessToken,
3845
- refresh_token: data.refreshToken
3846
- });
3847
- console.debug("Token exchange successful, session set");
3848
- }
3849
3667
  createSupabaseHeaderMiddleware() {
3850
3668
  return {
3851
3669
  onRequest: async ({ request }) => {
3852
3670
  const headers = await this.getHeaders();
3853
- if (!this.supabaseClient) {
3854
- return request;
3855
- }
3856
- const session = await this.supabaseClient.getSession();
3857
- if (!session.data.session) {
3858
- return request;
3859
- }
3860
3671
  for (const [key, value] of Object.entries(headers)) {
3861
3672
  request.headers.set(key, value);
3862
3673
  }
@@ -3864,33 +3675,8 @@ var MageMetricsClient = class {
3864
3675
  }
3865
3676
  };
3866
3677
  }
3867
- setState(state) {
3868
- this.authState = state;
3869
- this.events.dispatch("authStateChange", state);
3870
- }
3871
- encodeCheckKey(externalJwt, apiKey) {
3872
- return hashString(
3873
- JSON.stringify({
3874
- externalJwt,
3875
- apiKey
3876
- })
3877
- );
3878
- }
3879
- async saveCheckKey(externalJwt, apiKey) {
3880
- const encodedKey = this.encodeCheckKey(externalJwt, apiKey);
3881
- await this.storageAdapter.setItem(CHECK_KEY, encodedKey);
3882
- }
3883
- async compareCheckKey(externalJwt, apiKey) {
3884
- const storedKey = await this.storageAdapter.getItem(CHECK_KEY);
3885
- if (!storedKey) return false;
3886
- const newValue = this.encodeCheckKey(externalJwt, apiKey);
3887
- return storedKey === newValue;
3888
- }
3889
- async clearCheckKey() {
3890
- await this.storageAdapter.removeItem(CHECK_KEY);
3891
- }
3892
3678
  };
3893
3679
 
3894
- export { BrowserStorageAdapter, CHECK_KEY, MageMetricsClient, MageMetricsEventEmitter, MemoryStorageAdapter, TOKEN_STORAGE_KEY, getPublicApiClient };
3680
+ export { BrowserStorageAdapter, CHECK_KEY, DirectAuthProvider, ExternalAuthProvider, MageMetricsClient, MageMetricsEventEmitter, MemoryStorageAdapter, TOKEN_STORAGE_KEY, getPublicApiClient };
3895
3681
  //# sourceMappingURL=index.js.map
3896
3682
  //# sourceMappingURL=index.js.map