@inkindcards/semantic-layer 0.1.0 → 0.1.2
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/{chunk-4RECQ22F.cjs → chunk-B4AB5ZWB.cjs} +15 -3
- package/dist/chunk-B4AB5ZWB.cjs.map +1 -0
- package/dist/{chunk-IQARBGJP.js → chunk-DHFL2XZB.js} +15 -3
- package/dist/chunk-DHFL2XZB.js.map +1 -0
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -1
- package/dist/react.cjs +39 -5
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -0
- package/dist/react.d.ts +2 -0
- package/dist/react.js +39 -5
- package/dist/react.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-4RECQ22F.cjs.map +0 -1
- package/dist/chunk-IQARBGJP.js.map +0 -1
|
@@ -4,11 +4,11 @@ var supabaseJs = require('@supabase/supabase-js');
|
|
|
4
4
|
|
|
5
5
|
// src/client.ts
|
|
6
6
|
var SemanticLayerClient = class {
|
|
7
|
-
// 5 minutes
|
|
8
7
|
constructor(config) {
|
|
9
8
|
this.metadataCache = null;
|
|
10
9
|
this.metadataCacheTime = 0;
|
|
11
10
|
this.CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
11
|
+
this.gatewayUrl = config.gatewayUrl;
|
|
12
12
|
this.supabase = supabaseJs.createClient(config.gatewayUrl, config.anonKey, {
|
|
13
13
|
auth: {
|
|
14
14
|
persistSession: true,
|
|
@@ -28,6 +28,18 @@ var SemanticLayerClient = class {
|
|
|
28
28
|
options: { redirectTo }
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
|
+
/** Get the Google sign-in URL without triggering a redirect (for popup flows). */
|
|
32
|
+
async getSignInUrl(redirectTo) {
|
|
33
|
+
const { data, error } = await this.supabase.auth.signInWithOAuth({
|
|
34
|
+
provider: "google",
|
|
35
|
+
options: {
|
|
36
|
+
redirectTo,
|
|
37
|
+
skipBrowserRedirect: true
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
if (error || !data.url) return null;
|
|
41
|
+
return data.url;
|
|
42
|
+
}
|
|
31
43
|
async signOut() {
|
|
32
44
|
return this.supabase.auth.signOut();
|
|
33
45
|
}
|
|
@@ -127,5 +139,5 @@ var SemanticLayerError = class extends Error {
|
|
|
127
139
|
|
|
128
140
|
exports.SemanticLayerClient = SemanticLayerClient;
|
|
129
141
|
exports.SemanticLayerError = SemanticLayerError;
|
|
130
|
-
//# sourceMappingURL=chunk-
|
|
131
|
-
//# sourceMappingURL=chunk-
|
|
142
|
+
//# sourceMappingURL=chunk-B4AB5ZWB.cjs.map
|
|
143
|
+
//# sourceMappingURL=chunk-B4AB5ZWB.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":["createClient"],"mappings":"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","file":"chunk-B4AB5ZWB.cjs","sourcesContent":["import { createClient, SupabaseClient, Session } from \"@supabase/supabase-js\";\nimport type {\n SemanticLayerConfig,\n MetadataResponse,\n PivotConfig,\n QueryResult,\n SimpleQueryInput,\n SemanticField,\n} from \"./types\";\n\nexport class SemanticLayerClient {\n private supabase: SupabaseClient;\n private metadataCache: MetadataResponse | null = null;\n private metadataCacheTime = 0;\n private readonly CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n readonly gatewayUrl: string;\n\n constructor(config: SemanticLayerConfig) {\n this.gatewayUrl = config.gatewayUrl;\n this.supabase = createClient(config.gatewayUrl, config.anonKey, {\n auth: {\n persistSession: true,\n autoRefreshToken: true,\n storageKey: \"semantic-layer-auth\",\n },\n });\n }\n\n /** Access the underlying Supabase client (for auth operations). */\n getSupabaseClient(): SupabaseClient {\n return this.supabase;\n }\n\n // ─── Auth ────────────────────────────────────────────────────────────────────\n\n async signInWithGoogle(redirectTo?: string) {\n return this.supabase.auth.signInWithOAuth({\n provider: \"google\",\n options: { redirectTo },\n });\n }\n\n /** Get the Google sign-in URL without triggering a redirect (for popup flows). */\n async getSignInUrl(redirectTo?: string): Promise<string | null> {\n const { data, error } = await this.supabase.auth.signInWithOAuth({\n provider: \"google\",\n options: {\n redirectTo,\n skipBrowserRedirect: true,\n },\n });\n if (error || !data.url) return null;\n return data.url;\n }\n\n async signOut() {\n return this.supabase.auth.signOut();\n }\n\n async getSession(): Promise<Session | null> {\n const { data } = await this.supabase.auth.getSession();\n return data.session;\n }\n\n onAuthStateChange(callback: (event: string, session: Session | null) => void) {\n return this.supabase.auth.onAuthStateChange(callback);\n }\n\n // ─── Metadata ────────────────────────────────────────────────────────────────\n\n /**\n * Fetch the curated catalog of metrics and dimensions from the gateway.\n * Results are cached for 5 minutes.\n */\n async getMetadata(forceRefresh = false): Promise<MetadataResponse> {\n const now = Date.now();\n if (!forceRefresh && this.metadataCache && now - this.metadataCacheTime < this.CACHE_TTL_MS) {\n return this.metadataCache;\n }\n\n const { data, error } = await this.supabase.functions.invoke(\"dbt-metadata\");\n\n if (error) {\n throw new SemanticLayerError(`Failed to fetch metadata: ${error.message}`, \"METADATA_ERROR\");\n }\n if (data?.error) {\n throw new SemanticLayerError(data.error, \"METADATA_ERROR\");\n }\n\n this.metadataCache = data as MetadataResponse;\n this.metadataCacheTime = now;\n return this.metadataCache;\n }\n\n /** Get only metrics from the catalog. */\n async getMetrics(): Promise<SemanticField[]> {\n const { fields } = await this.getMetadata();\n return fields.filter((f) => f.type === \"metric\");\n }\n\n /** Get only dimensions (including time dimensions) from the catalog. */\n async getDimensions(): Promise<SemanticField[]> {\n const { fields } = await this.getMetadata();\n return fields.filter((f) => f.type === \"dimension\" || f.type === \"time_dimension\");\n }\n\n /** Find a field by name or id. */\n async getField(nameOrId: string): Promise<SemanticField | undefined> {\n const { fields } = await this.getMetadata();\n return fields.find((f) => f.name === nameOrId || f.id === nameOrId);\n }\n\n // ─── Query ───────────────────────────────────────────────────────────────────\n\n /** Execute a query using the full PivotConfig format. */\n async query(config: PivotConfig): Promise<QueryResult> {\n if (config.values.length === 0) {\n return { columns: [], rows: [], totalRows: 0, executionTimeMs: 0 };\n }\n\n const { data, error } = await this.supabase.functions.invoke(\"dbt-query\", {\n body: { config },\n });\n\n if (error) {\n throw new SemanticLayerError(`Query failed: ${error.message}`, \"QUERY_ERROR\");\n }\n if (data?.error) {\n throw new SemanticLayerError(data.error, \"QUERY_ERROR\");\n }\n\n return data as QueryResult;\n }\n\n /**\n * Execute a query using the simplified input format.\n * Automatically resolves metric/dimension names to full field objects.\n */\n async simpleQuery(input: SimpleQueryInput): Promise<QueryResult> {\n const { fields } = await this.getMetadata();\n const fieldMap = new Map(fields.map((f) => [f.name, f]));\n\n const values = input.metrics.map((name) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown metric: \"${name}\"`, \"UNKNOWN_FIELD\");\n return { fieldId: field.id, field };\n });\n\n const rows = (input.groupBy || []).map((name) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown dimension: \"${name}\"`, \"UNKNOWN_FIELD\");\n const grain = field.type === \"time_dimension\" ? input.grain : undefined;\n return { fieldId: field.id, field, grain };\n });\n\n const filters = Object.entries(input.filters || {}).map(([name, filterValues]) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown filter field: \"${name}\"`, \"UNKNOWN_FIELD\");\n return { fieldId: field.id, field, filterValues };\n });\n\n return this.query({ values, rows, columns: [], filters });\n }\n}\n\nexport class SemanticLayerError extends Error {\n code: string;\n constructor(message: string, code: string) {\n super(message);\n this.name = \"SemanticLayerError\";\n this.code = code;\n }\n}\n"]}
|
|
@@ -2,11 +2,11 @@ import { createClient } from '@supabase/supabase-js';
|
|
|
2
2
|
|
|
3
3
|
// src/client.ts
|
|
4
4
|
var SemanticLayerClient = class {
|
|
5
|
-
// 5 minutes
|
|
6
5
|
constructor(config) {
|
|
7
6
|
this.metadataCache = null;
|
|
8
7
|
this.metadataCacheTime = 0;
|
|
9
8
|
this.CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
9
|
+
this.gatewayUrl = config.gatewayUrl;
|
|
10
10
|
this.supabase = createClient(config.gatewayUrl, config.anonKey, {
|
|
11
11
|
auth: {
|
|
12
12
|
persistSession: true,
|
|
@@ -26,6 +26,18 @@ var SemanticLayerClient = class {
|
|
|
26
26
|
options: { redirectTo }
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
|
+
/** Get the Google sign-in URL without triggering a redirect (for popup flows). */
|
|
30
|
+
async getSignInUrl(redirectTo) {
|
|
31
|
+
const { data, error } = await this.supabase.auth.signInWithOAuth({
|
|
32
|
+
provider: "google",
|
|
33
|
+
options: {
|
|
34
|
+
redirectTo,
|
|
35
|
+
skipBrowserRedirect: true
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
if (error || !data.url) return null;
|
|
39
|
+
return data.url;
|
|
40
|
+
}
|
|
29
41
|
async signOut() {
|
|
30
42
|
return this.supabase.auth.signOut();
|
|
31
43
|
}
|
|
@@ -124,5 +136,5 @@ var SemanticLayerError = class extends Error {
|
|
|
124
136
|
};
|
|
125
137
|
|
|
126
138
|
export { SemanticLayerClient, SemanticLayerError };
|
|
127
|
-
//# sourceMappingURL=chunk-
|
|
128
|
-
//# sourceMappingURL=chunk-
|
|
139
|
+
//# sourceMappingURL=chunk-DHFL2XZB.js.map
|
|
140
|
+
//# sourceMappingURL=chunk-DHFL2XZB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":"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","file":"chunk-DHFL2XZB.js","sourcesContent":["import { createClient, SupabaseClient, Session } from \"@supabase/supabase-js\";\nimport type {\n SemanticLayerConfig,\n MetadataResponse,\n PivotConfig,\n QueryResult,\n SimpleQueryInput,\n SemanticField,\n} from \"./types\";\n\nexport class SemanticLayerClient {\n private supabase: SupabaseClient;\n private metadataCache: MetadataResponse | null = null;\n private metadataCacheTime = 0;\n private readonly CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n readonly gatewayUrl: string;\n\n constructor(config: SemanticLayerConfig) {\n this.gatewayUrl = config.gatewayUrl;\n this.supabase = createClient(config.gatewayUrl, config.anonKey, {\n auth: {\n persistSession: true,\n autoRefreshToken: true,\n storageKey: \"semantic-layer-auth\",\n },\n });\n }\n\n /** Access the underlying Supabase client (for auth operations). */\n getSupabaseClient(): SupabaseClient {\n return this.supabase;\n }\n\n // ─── Auth ────────────────────────────────────────────────────────────────────\n\n async signInWithGoogle(redirectTo?: string) {\n return this.supabase.auth.signInWithOAuth({\n provider: \"google\",\n options: { redirectTo },\n });\n }\n\n /** Get the Google sign-in URL without triggering a redirect (for popup flows). */\n async getSignInUrl(redirectTo?: string): Promise<string | null> {\n const { data, error } = await this.supabase.auth.signInWithOAuth({\n provider: \"google\",\n options: {\n redirectTo,\n skipBrowserRedirect: true,\n },\n });\n if (error || !data.url) return null;\n return data.url;\n }\n\n async signOut() {\n return this.supabase.auth.signOut();\n }\n\n async getSession(): Promise<Session | null> {\n const { data } = await this.supabase.auth.getSession();\n return data.session;\n }\n\n onAuthStateChange(callback: (event: string, session: Session | null) => void) {\n return this.supabase.auth.onAuthStateChange(callback);\n }\n\n // ─── Metadata ────────────────────────────────────────────────────────────────\n\n /**\n * Fetch the curated catalog of metrics and dimensions from the gateway.\n * Results are cached for 5 minutes.\n */\n async getMetadata(forceRefresh = false): Promise<MetadataResponse> {\n const now = Date.now();\n if (!forceRefresh && this.metadataCache && now - this.metadataCacheTime < this.CACHE_TTL_MS) {\n return this.metadataCache;\n }\n\n const { data, error } = await this.supabase.functions.invoke(\"dbt-metadata\");\n\n if (error) {\n throw new SemanticLayerError(`Failed to fetch metadata: ${error.message}`, \"METADATA_ERROR\");\n }\n if (data?.error) {\n throw new SemanticLayerError(data.error, \"METADATA_ERROR\");\n }\n\n this.metadataCache = data as MetadataResponse;\n this.metadataCacheTime = now;\n return this.metadataCache;\n }\n\n /** Get only metrics from the catalog. */\n async getMetrics(): Promise<SemanticField[]> {\n const { fields } = await this.getMetadata();\n return fields.filter((f) => f.type === \"metric\");\n }\n\n /** Get only dimensions (including time dimensions) from the catalog. */\n async getDimensions(): Promise<SemanticField[]> {\n const { fields } = await this.getMetadata();\n return fields.filter((f) => f.type === \"dimension\" || f.type === \"time_dimension\");\n }\n\n /** Find a field by name or id. */\n async getField(nameOrId: string): Promise<SemanticField | undefined> {\n const { fields } = await this.getMetadata();\n return fields.find((f) => f.name === nameOrId || f.id === nameOrId);\n }\n\n // ─── Query ───────────────────────────────────────────────────────────────────\n\n /** Execute a query using the full PivotConfig format. */\n async query(config: PivotConfig): Promise<QueryResult> {\n if (config.values.length === 0) {\n return { columns: [], rows: [], totalRows: 0, executionTimeMs: 0 };\n }\n\n const { data, error } = await this.supabase.functions.invoke(\"dbt-query\", {\n body: { config },\n });\n\n if (error) {\n throw new SemanticLayerError(`Query failed: ${error.message}`, \"QUERY_ERROR\");\n }\n if (data?.error) {\n throw new SemanticLayerError(data.error, \"QUERY_ERROR\");\n }\n\n return data as QueryResult;\n }\n\n /**\n * Execute a query using the simplified input format.\n * Automatically resolves metric/dimension names to full field objects.\n */\n async simpleQuery(input: SimpleQueryInput): Promise<QueryResult> {\n const { fields } = await this.getMetadata();\n const fieldMap = new Map(fields.map((f) => [f.name, f]));\n\n const values = input.metrics.map((name) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown metric: \"${name}\"`, \"UNKNOWN_FIELD\");\n return { fieldId: field.id, field };\n });\n\n const rows = (input.groupBy || []).map((name) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown dimension: \"${name}\"`, \"UNKNOWN_FIELD\");\n const grain = field.type === \"time_dimension\" ? input.grain : undefined;\n return { fieldId: field.id, field, grain };\n });\n\n const filters = Object.entries(input.filters || {}).map(([name, filterValues]) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown filter field: \"${name}\"`, \"UNKNOWN_FIELD\");\n return { fieldId: field.id, field, filterValues };\n });\n\n return this.query({ values, rows, columns: [], filters });\n }\n}\n\nexport class SemanticLayerError extends Error {\n code: string;\n constructor(message: string, code: string) {\n super(message);\n this.name = \"SemanticLayerError\";\n this.code = code;\n }\n}\n"]}
|
package/dist/index.cjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkB4AB5ZWB_cjs = require('./chunk-B4AB5ZWB.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
Object.defineProperty(exports, "SemanticLayerClient", {
|
|
8
8
|
enumerable: true,
|
|
9
|
-
get: function () { return
|
|
9
|
+
get: function () { return chunkB4AB5ZWB_cjs.SemanticLayerClient; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "SemanticLayerError", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkB4AB5ZWB_cjs.SemanticLayerError; }
|
|
14
14
|
});
|
|
15
15
|
//# sourceMappingURL=index.cjs.map
|
|
16
16
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.d.cts
CHANGED
|
@@ -8,10 +8,13 @@ declare class SemanticLayerClient {
|
|
|
8
8
|
private metadataCache;
|
|
9
9
|
private metadataCacheTime;
|
|
10
10
|
private readonly CACHE_TTL_MS;
|
|
11
|
+
readonly gatewayUrl: string;
|
|
11
12
|
constructor(config: SemanticLayerConfig);
|
|
12
13
|
/** Access the underlying Supabase client (for auth operations). */
|
|
13
14
|
getSupabaseClient(): SupabaseClient;
|
|
14
15
|
signInWithGoogle(redirectTo?: string): Promise<_supabase_auth_js.OAuthResponse>;
|
|
16
|
+
/** Get the Google sign-in URL without triggering a redirect (for popup flows). */
|
|
17
|
+
getSignInUrl(redirectTo?: string): Promise<string | null>;
|
|
15
18
|
signOut(): Promise<{
|
|
16
19
|
error: _supabase_auth_js.AuthError | null;
|
|
17
20
|
}>;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,10 +8,13 @@ declare class SemanticLayerClient {
|
|
|
8
8
|
private metadataCache;
|
|
9
9
|
private metadataCacheTime;
|
|
10
10
|
private readonly CACHE_TTL_MS;
|
|
11
|
+
readonly gatewayUrl: string;
|
|
11
12
|
constructor(config: SemanticLayerConfig);
|
|
12
13
|
/** Access the underlying Supabase client (for auth operations). */
|
|
13
14
|
getSupabaseClient(): SupabaseClient;
|
|
14
15
|
signInWithGoogle(redirectTo?: string): Promise<_supabase_auth_js.OAuthResponse>;
|
|
16
|
+
/** Get the Google sign-in URL without triggering a redirect (for popup flows). */
|
|
17
|
+
getSignInUrl(redirectTo?: string): Promise<string | null>;
|
|
15
18
|
signOut(): Promise<{
|
|
16
19
|
error: _supabase_auth_js.AuthError | null;
|
|
17
20
|
}>;
|
package/dist/index.js
CHANGED
package/dist/react.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkB4AB5ZWB_cjs = require('./chunk-B4AB5ZWB.cjs');
|
|
4
4
|
var chunkY3A3T45C_cjs = require('./chunk-Y3A3T45C.cjs');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -13,7 +13,7 @@ function SemanticLayerProvider({
|
|
|
13
13
|
}) {
|
|
14
14
|
const client = react.useMemo(() => {
|
|
15
15
|
if (externalClient) return externalClient;
|
|
16
|
-
return new
|
|
16
|
+
return new chunkB4AB5ZWB_cjs.SemanticLayerClient({ gatewayUrl, anonKey });
|
|
17
17
|
}, [gatewayUrl, anonKey, externalClient]);
|
|
18
18
|
const [auth, setAuth] = react.useState({
|
|
19
19
|
isAuthenticated: false,
|
|
@@ -109,20 +109,54 @@ var defaultButtonStyle = {
|
|
|
109
109
|
alignItems: "center",
|
|
110
110
|
gap: "8px"
|
|
111
111
|
};
|
|
112
|
+
function isInIframe() {
|
|
113
|
+
try {
|
|
114
|
+
return typeof window !== "undefined" && window.self !== window.top;
|
|
115
|
+
} catch {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
112
119
|
function AuthGate({ children, loading, signInComponent }) {
|
|
113
|
-
const { isAuthenticated, isLoading, error, signIn
|
|
120
|
+
const { isAuthenticated, isLoading, error, signIn } = chunkY3A3T45C_cjs.useAuth();
|
|
121
|
+
const ctx = react.useContext(chunkY3A3T45C_cjs.SemanticLayerContext);
|
|
122
|
+
const client = ctx?.client;
|
|
123
|
+
const inIframe = isInIframe();
|
|
124
|
+
react.useEffect(() => {
|
|
125
|
+
if (!inIframe || !client) return;
|
|
126
|
+
const handler = (event) => {
|
|
127
|
+
if (event.data?.type === "semantic-layer-auth-callback" && event.data.access_token) {
|
|
128
|
+
client.getSupabaseClient().auth.setSession({
|
|
129
|
+
access_token: event.data.access_token,
|
|
130
|
+
refresh_token: event.data.refresh_token
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
window.addEventListener("message", handler);
|
|
135
|
+
return () => window.removeEventListener("message", handler);
|
|
136
|
+
}, [inIframe, client]);
|
|
137
|
+
const handleSignIn = react.useCallback(async () => {
|
|
138
|
+
if (inIframe && client) {
|
|
139
|
+
const callbackUrl = `${client.gatewayUrl}/functions/v1/auth-callback`;
|
|
140
|
+
const url = await client.getSignInUrl(callbackUrl);
|
|
141
|
+
if (url) {
|
|
142
|
+
window.open(url, "semantic-layer-auth", "popup,width=600,height=700");
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
signIn(window.location.origin);
|
|
146
|
+
}
|
|
147
|
+
}, [inIframe, client, signIn]);
|
|
114
148
|
if (isLoading) {
|
|
115
149
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: loading || /* @__PURE__ */ jsxRuntime.jsx("div", { style: defaultLoadingStyle, children: "Loading..." }) });
|
|
116
150
|
}
|
|
117
151
|
if (!isAuthenticated) {
|
|
118
152
|
if (signInComponent) {
|
|
119
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: signInComponent({ signIn:
|
|
153
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: signInComponent({ signIn: handleSignIn }) });
|
|
120
154
|
}
|
|
121
155
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: defaultContainerStyle, children: [
|
|
122
156
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: "24px", color: "#111827" }, children: "Sign in to continue" }),
|
|
123
157
|
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, color: "#6b7280" }, children: "Use your inKind Google account to access data." }),
|
|
124
158
|
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, color: "#ef4444", fontSize: "14px" }, children: error }),
|
|
125
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style: defaultButtonStyle, onClick:
|
|
159
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: defaultButtonStyle, onClick: handleSignIn, children: "Sign in with Google" })
|
|
126
160
|
] });
|
|
127
161
|
}
|
|
128
162
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
package/dist/react.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/provider.tsx","../src/react/auth-gate.tsx"],"names":["useMemo","SemanticLayerClient","useState","useEffect","jsx","SemanticLayerContext","useAuth","Fragment","jsxs"],"mappings":"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","file":"react.cjs","sourcesContent":["import React, { useEffect, useMemo, useState } from \"react\";\nimport { SemanticLayerClient } from \"../client\";\nimport type { SemanticLayerConfig, AuthState } from \"../types\";\nimport { SemanticLayerContext } from \"./context\";\n\nexport interface SemanticLayerProviderProps {\n /** The Supabase URL of the gateway project. */\n gatewayUrl: string;\n /** The Supabase anon/publishable key of the gateway project. */\n anonKey: string;\n /**\n * Optional: a pre-constructed client instance.\n * If provided, gatewayUrl and anonKey are ignored.\n */\n client?: SemanticLayerClient;\n children: React.ReactNode;\n}\n\nexport function SemanticLayerProvider({\n gatewayUrl,\n anonKey,\n client: externalClient,\n children,\n}: SemanticLayerProviderProps) {\n const client = useMemo(() => {\n if (externalClient) return externalClient;\n return new SemanticLayerClient({ gatewayUrl, anonKey });\n }, [gatewayUrl, anonKey, externalClient]);\n\n const [auth, setAuth] = useState<AuthState>({\n isAuthenticated: false,\n isLoading: true,\n user: null,\n error: null,\n });\n\n useEffect(() => {\n let mounted = true;\n\n async function initAuth() {\n try {\n const session = await client.getSession();\n if (!mounted) return;\n\n if (session?.user) {\n setAuth({\n isAuthenticated: true,\n isLoading: false,\n user: { id: session.user.id, email: session.user.email || \"\" },\n error: null,\n });\n } else {\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: null,\n });\n }\n } catch (err) {\n if (!mounted) return;\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: err instanceof Error ? err.message : \"Auth initialization failed\",\n });\n }\n }\n\n initAuth();\n\n const { data: { subscription } } = client.onAuthStateChange((_event, session) => {\n if (!mounted) return;\n if (session?.user) {\n setAuth({\n isAuthenticated: true,\n isLoading: false,\n user: { id: session.user.id, email: session.user.email || \"\" },\n error: null,\n });\n } else {\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: null,\n });\n }\n });\n\n return () => {\n mounted = false;\n subscription.unsubscribe();\n };\n }, [client]);\n\n const value = useMemo(() => ({ client, auth }), [client, auth]);\n\n return (\n <SemanticLayerContext.Provider value={value}>\n {children}\n </SemanticLayerContext.Provider>\n );\n}\n","import React from \"react\";\nimport { useAuth } from \"./hooks\";\n\nexport interface AuthGateProps {\n children: React.ReactNode;\n /** Custom loading component. */\n loading?: React.ReactNode;\n /** Custom sign-in component. Receives a signIn callback. */\n signInComponent?: (props: { signIn: () => void }) => React.ReactNode;\n}\n\nconst defaultLoadingStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n color: \"#6b7280\",\n};\n\nconst defaultContainerStyle: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n gap: \"16px\",\n};\n\nconst defaultButtonStyle: React.CSSProperties = {\n padding: \"12px 24px\",\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#ffffff\",\n backgroundColor: \"#4285f4\",\n border: \"none\",\n borderRadius: \"8px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n};\n\n/**\n * Wraps children and only renders them when the user is authenticated.\n * Shows a sign-in screen when unauthenticated.\n */\nexport function AuthGate({ children, loading, signInComponent }: AuthGateProps) {\n const { isAuthenticated, isLoading, error, signIn, user } = useAuth();\n\n if (isLoading) {\n return <>{loading || <div style={defaultLoadingStyle}>Loading...</div>}</>;\n }\n\n if (!isAuthenticated) {\n if (signInComponent) {\n return <>{signInComponent({ signIn: () => signIn() })}</>;\n }\n\n return (\n <div style={defaultContainerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Sign in to continue</h2>\n <p style={{ margin: 0, color: \"#6b7280\" }}>\n Use your inKind Google account to access data.\n </p>\n {error && (\n <p style={{ margin: 0, color: \"#ef4444\", fontSize: \"14px\" }}>{error}</p>\n )}\n <button style={defaultButtonStyle} onClick={() => signIn()}>\n Sign in with Google\n </button>\n </div>\n );\n }\n\n return <>{children}</>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/react/provider.tsx","../src/react/auth-gate.tsx"],"names":["useMemo","SemanticLayerClient","useState","useEffect","jsx","SemanticLayerContext","useAuth","useContext","useCallback","Fragment","jsxs"],"mappings":"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","file":"react.cjs","sourcesContent":["import React, { useEffect, useMemo, useState } from \"react\";\nimport { SemanticLayerClient } from \"../client\";\nimport type { SemanticLayerConfig, AuthState } from \"../types\";\nimport { SemanticLayerContext } from \"./context\";\n\nexport interface SemanticLayerProviderProps {\n /** The Supabase URL of the gateway project. */\n gatewayUrl: string;\n /** The Supabase anon/publishable key of the gateway project. */\n anonKey: string;\n /**\n * Optional: a pre-constructed client instance.\n * If provided, gatewayUrl and anonKey are ignored.\n */\n client?: SemanticLayerClient;\n children: React.ReactNode;\n}\n\nexport function SemanticLayerProvider({\n gatewayUrl,\n anonKey,\n client: externalClient,\n children,\n}: SemanticLayerProviderProps) {\n const client = useMemo(() => {\n if (externalClient) return externalClient;\n return new SemanticLayerClient({ gatewayUrl, anonKey });\n }, [gatewayUrl, anonKey, externalClient]);\n\n const [auth, setAuth] = useState<AuthState>({\n isAuthenticated: false,\n isLoading: true,\n user: null,\n error: null,\n });\n\n useEffect(() => {\n let mounted = true;\n\n async function initAuth() {\n try {\n const session = await client.getSession();\n if (!mounted) return;\n\n if (session?.user) {\n setAuth({\n isAuthenticated: true,\n isLoading: false,\n user: { id: session.user.id, email: session.user.email || \"\" },\n error: null,\n });\n } else {\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: null,\n });\n }\n } catch (err) {\n if (!mounted) return;\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: err instanceof Error ? err.message : \"Auth initialization failed\",\n });\n }\n }\n\n initAuth();\n\n const { data: { subscription } } = client.onAuthStateChange((_event, session) => {\n if (!mounted) return;\n if (session?.user) {\n setAuth({\n isAuthenticated: true,\n isLoading: false,\n user: { id: session.user.id, email: session.user.email || \"\" },\n error: null,\n });\n } else {\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: null,\n });\n }\n });\n\n return () => {\n mounted = false;\n subscription.unsubscribe();\n };\n }, [client]);\n\n const value = useMemo(() => ({ client, auth }), [client, auth]);\n\n return (\n <SemanticLayerContext.Provider value={value}>\n {children}\n </SemanticLayerContext.Provider>\n );\n}\n","import React, { useCallback, useContext, useEffect } from \"react\";\nimport { useAuth } from \"./hooks\";\nimport { SemanticLayerContext } from \"./context\";\n\nexport interface AuthGateProps {\n children: React.ReactNode;\n /** Custom loading component. */\n loading?: React.ReactNode;\n /** Custom sign-in component. Receives a signIn callback. */\n signInComponent?: (props: { signIn: () => void }) => React.ReactNode;\n}\n\nconst defaultLoadingStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n color: \"#6b7280\",\n};\n\nconst defaultContainerStyle: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n gap: \"16px\",\n};\n\nconst defaultButtonStyle: React.CSSProperties = {\n padding: \"12px 24px\",\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#ffffff\",\n backgroundColor: \"#4285f4\",\n border: \"none\",\n borderRadius: \"8px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n};\n\nfunction isInIframe(): boolean {\n try {\n return typeof window !== \"undefined\" && window.self !== window.top;\n } catch {\n return true;\n }\n}\n\n/**\n * Wraps children and only renders them when the user is authenticated.\n * Shows a sign-in screen when unauthenticated.\n * When running inside an iframe (e.g. Lovable preview), uses a popup\n * for OAuth so the editor isn't navigated away.\n */\nexport function AuthGate({ children, loading, signInComponent }: AuthGateProps) {\n const { isAuthenticated, isLoading, error, signIn } = useAuth();\n const ctx = useContext(SemanticLayerContext);\n const client = ctx?.client;\n const inIframe = isInIframe();\n\n // Listen for auth tokens relayed from the popup via postMessage\n useEffect(() => {\n if (!inIframe || !client) return;\n\n const handler = (event: MessageEvent) => {\n if (event.data?.type === \"semantic-layer-auth-callback\" && event.data.access_token) {\n client.getSupabaseClient().auth.setSession({\n access_token: event.data.access_token,\n refresh_token: event.data.refresh_token,\n });\n }\n };\n\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }, [inIframe, client]);\n\n const handleSignIn = useCallback(async () => {\n if (inIframe && client) {\n const callbackUrl = `${client.gatewayUrl}/functions/v1/auth-callback`;\n const url = await client.getSignInUrl(callbackUrl);\n if (url) {\n window.open(url, \"semantic-layer-auth\", \"popup,width=600,height=700\");\n }\n } else {\n signIn(window.location.origin);\n }\n }, [inIframe, client, signIn]);\n\n if (isLoading) {\n return <>{loading || <div style={defaultLoadingStyle}>Loading...</div>}</>;\n }\n\n if (!isAuthenticated) {\n if (signInComponent) {\n return <>{signInComponent({ signIn: handleSignIn })}</>;\n }\n\n return (\n <div style={defaultContainerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Sign in to continue</h2>\n <p style={{ margin: 0, color: \"#6b7280\" }}>\n Use your inKind Google account to access data.\n </p>\n {error && (\n <p style={{ margin: 0, color: \"#ef4444\", fontSize: \"14px\" }}>{error}</p>\n )}\n <button style={defaultButtonStyle} onClick={handleSignIn}>\n Sign in with Google\n </button>\n </div>\n );\n }\n\n return <>{children}</>;\n}\n"]}
|
package/dist/react.d.cts
CHANGED
|
@@ -32,6 +32,8 @@ interface AuthGateProps {
|
|
|
32
32
|
/**
|
|
33
33
|
* Wraps children and only renders them when the user is authenticated.
|
|
34
34
|
* Shows a sign-in screen when unauthenticated.
|
|
35
|
+
* When running inside an iframe (e.g. Lovable preview), uses a popup
|
|
36
|
+
* for OAuth so the editor isn't navigated away.
|
|
35
37
|
*/
|
|
36
38
|
declare function AuthGate({ children, loading, signInComponent }: AuthGateProps): react_jsx_runtime.JSX.Element;
|
|
37
39
|
|
package/dist/react.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ interface AuthGateProps {
|
|
|
32
32
|
/**
|
|
33
33
|
* Wraps children and only renders them when the user is authenticated.
|
|
34
34
|
* Shows a sign-in screen when unauthenticated.
|
|
35
|
+
* When running inside an iframe (e.g. Lovable preview), uses a popup
|
|
36
|
+
* for OAuth so the editor isn't navigated away.
|
|
35
37
|
*/
|
|
36
38
|
declare function AuthGate({ children, loading, signInComponent }: AuthGateProps): react_jsx_runtime.JSX.Element;
|
|
37
39
|
|
package/dist/react.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { SemanticLayerClient } from './chunk-
|
|
1
|
+
import { SemanticLayerClient } from './chunk-DHFL2XZB.js';
|
|
2
2
|
import { SemanticLayerContext, useAuth } from './chunk-NJ4IJBV3.js';
|
|
3
3
|
export { SemanticLayerContext, useAuth, useMetrics, usePivotQuery, useSemanticQuery } from './chunk-NJ4IJBV3.js';
|
|
4
|
-
import { useMemo, useState, useEffect } from 'react';
|
|
4
|
+
import { useMemo, useState, useEffect, useContext, useCallback } from 'react';
|
|
5
5
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
function SemanticLayerProvider({
|
|
@@ -108,20 +108,54 @@ var defaultButtonStyle = {
|
|
|
108
108
|
alignItems: "center",
|
|
109
109
|
gap: "8px"
|
|
110
110
|
};
|
|
111
|
+
function isInIframe() {
|
|
112
|
+
try {
|
|
113
|
+
return typeof window !== "undefined" && window.self !== window.top;
|
|
114
|
+
} catch {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
111
118
|
function AuthGate({ children, loading, signInComponent }) {
|
|
112
|
-
const { isAuthenticated, isLoading, error, signIn
|
|
119
|
+
const { isAuthenticated, isLoading, error, signIn } = useAuth();
|
|
120
|
+
const ctx = useContext(SemanticLayerContext);
|
|
121
|
+
const client = ctx?.client;
|
|
122
|
+
const inIframe = isInIframe();
|
|
123
|
+
useEffect(() => {
|
|
124
|
+
if (!inIframe || !client) return;
|
|
125
|
+
const handler = (event) => {
|
|
126
|
+
if (event.data?.type === "semantic-layer-auth-callback" && event.data.access_token) {
|
|
127
|
+
client.getSupabaseClient().auth.setSession({
|
|
128
|
+
access_token: event.data.access_token,
|
|
129
|
+
refresh_token: event.data.refresh_token
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
window.addEventListener("message", handler);
|
|
134
|
+
return () => window.removeEventListener("message", handler);
|
|
135
|
+
}, [inIframe, client]);
|
|
136
|
+
const handleSignIn = useCallback(async () => {
|
|
137
|
+
if (inIframe && client) {
|
|
138
|
+
const callbackUrl = `${client.gatewayUrl}/functions/v1/auth-callback`;
|
|
139
|
+
const url = await client.getSignInUrl(callbackUrl);
|
|
140
|
+
if (url) {
|
|
141
|
+
window.open(url, "semantic-layer-auth", "popup,width=600,height=700");
|
|
142
|
+
}
|
|
143
|
+
} else {
|
|
144
|
+
signIn(window.location.origin);
|
|
145
|
+
}
|
|
146
|
+
}, [inIframe, client, signIn]);
|
|
113
147
|
if (isLoading) {
|
|
114
148
|
return /* @__PURE__ */ jsx(Fragment, { children: loading || /* @__PURE__ */ jsx("div", { style: defaultLoadingStyle, children: "Loading..." }) });
|
|
115
149
|
}
|
|
116
150
|
if (!isAuthenticated) {
|
|
117
151
|
if (signInComponent) {
|
|
118
|
-
return /* @__PURE__ */ jsx(Fragment, { children: signInComponent({ signIn:
|
|
152
|
+
return /* @__PURE__ */ jsx(Fragment, { children: signInComponent({ signIn: handleSignIn }) });
|
|
119
153
|
}
|
|
120
154
|
return /* @__PURE__ */ jsxs("div", { style: defaultContainerStyle, children: [
|
|
121
155
|
/* @__PURE__ */ jsx("h2", { style: { margin: 0, fontSize: "24px", color: "#111827" }, children: "Sign in to continue" }),
|
|
122
156
|
/* @__PURE__ */ jsx("p", { style: { margin: 0, color: "#6b7280" }, children: "Use your inKind Google account to access data." }),
|
|
123
157
|
error && /* @__PURE__ */ jsx("p", { style: { margin: 0, color: "#ef4444", fontSize: "14px" }, children: error }),
|
|
124
|
-
/* @__PURE__ */ jsx("button", { style: defaultButtonStyle, onClick:
|
|
158
|
+
/* @__PURE__ */ jsx("button", { style: defaultButtonStyle, onClick: handleSignIn, children: "Sign in with Google" })
|
|
125
159
|
] });
|
|
126
160
|
}
|
|
127
161
|
return /* @__PURE__ */ jsx(Fragment, { children });
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/provider.tsx","../src/react/auth-gate.tsx"],"names":["jsx"],"mappings":";;;;;;AAkBO,SAAS,qBAAA,CAAsB;AAAA,EACpC,UAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA,EAAQ,cAAA;AAAA,EACR;AACF,CAAA,EAA+B;AAC7B,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAM;AAC3B,IAAA,IAAI,gBAAgB,OAAO,cAAA;AAC3B,IAAA,OAAO,IAAI,mBAAA,CAAoB,EAAE,UAAA,EAAY,SAAS,CAAA;AAAA,EACxD,CAAA,EAAG,CAAC,UAAA,EAAY,OAAA,EAAS,cAAc,CAAC,CAAA;AAExC,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,QAAA,CAAoB;AAAA,IAC1C,eAAA,EAAiB,KAAA;AAAA,IACjB,SAAA,EAAW,IAAA;AAAA,IACX,IAAA,EAAM,IAAA;AAAA,IACN,KAAA,EAAO;AAAA,GACR,CAAA;AAED,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAA,GAAU,IAAA;AAEd,IAAA,eAAe,QAAA,GAAW;AACxB,MAAA,IAAI;AACF,QAAA,MAAM,OAAA,GAAU,MAAM,MAAA,CAAO,UAAA,EAAW;AACxC,QAAA,IAAI,CAAC,OAAA,EAAS;AAEd,QAAA,IAAI,SAAS,IAAA,EAAM;AACjB,UAAA,OAAA,CAAQ;AAAA,YACN,eAAA,EAAiB,IAAA;AAAA,YACjB,SAAA,EAAW,KAAA;AAAA,YACX,IAAA,EAAM,EAAE,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,IAAI,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,KAAA,IAAS,EAAA,EAAG;AAAA,YAC7D,KAAA,EAAO;AAAA,WACR,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,OAAA,CAAQ;AAAA,YACN,eAAA,EAAiB,KAAA;AAAA,YACjB,SAAA,EAAW,KAAA;AAAA,YACX,IAAA,EAAM,IAAA;AAAA,YACN,KAAA,EAAO;AAAA,WACR,CAAA;AAAA,QACH;AAAA,MACF,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,CAAC,OAAA,EAAS;AACd,QAAA,OAAA,CAAQ;AAAA,UACN,eAAA,EAAiB,KAAA;AAAA,UACjB,SAAA,EAAW,KAAA;AAAA,UACX,IAAA,EAAM,IAAA;AAAA,UACN,KAAA,EAAO,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU;AAAA,SAC7C,CAAA;AAAA,MACH;AAAA,IACF;AAEA,IAAA,QAAA,EAAS;AAET,IAAA,MAAM,EAAE,IAAA,EAAM,EAAE,YAAA,EAAa,KAAM,MAAA,CAAO,iBAAA,CAAkB,CAAC,MAAA,EAAQ,OAAA,KAAY;AAC/E,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,IAAI,SAAS,IAAA,EAAM;AACjB,QAAA,OAAA,CAAQ;AAAA,UACN,eAAA,EAAiB,IAAA;AAAA,UACjB,SAAA,EAAW,KAAA;AAAA,UACX,IAAA,EAAM,EAAE,EAAA,EAAI,OAAA,CAAQ,IAAA,CAAK,IAAI,KAAA,EAAO,OAAA,CAAQ,IAAA,CAAK,KAAA,IAAS,EAAA,EAAG;AAAA,UAC7D,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH,CAAA,MAAO;AACL,QAAA,OAAA,CAAQ;AAAA,UACN,eAAA,EAAiB,KAAA;AAAA,UACjB,SAAA,EAAW,KAAA;AAAA,UACX,IAAA,EAAM,IAAA;AAAA,UACN,KAAA,EAAO;AAAA,SACR,CAAA;AAAA,MACH;AAAA,IACF,CAAC,CAAA;AAED,IAAA,OAAO,MAAM;AACX,MAAA,OAAA,GAAU,KAAA;AACV,MAAA,YAAA,CAAa,WAAA,EAAY;AAAA,IAC3B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,OAAO,EAAE,MAAA,EAAQ,MAAK,CAAA,EAAI,CAAC,MAAA,EAAQ,IAAI,CAAC,CAAA;AAE9D,EAAA,uBACE,GAAA,CAAC,oBAAA,CAAqB,QAAA,EAArB,EAA8B,OAC5B,QAAA,EACH,CAAA;AAEJ;AC7FA,IAAM,mBAAA,GAA2C;AAAA,EAC/C,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,cAAA,EAAgB,QAAA;AAAA,EAChB,SAAA,EAAW,OAAA;AAAA,EACX,UAAA,EAAY,sCAAA;AAAA,EACZ,KAAA,EAAO;AACT,CAAA;AAEA,IAAM,qBAAA,GAA6C;AAAA,EACjD,OAAA,EAAS,MAAA;AAAA,EACT,aAAA,EAAe,QAAA;AAAA,EACf,UAAA,EAAY,QAAA;AAAA,EACZ,cAAA,EAAgB,QAAA;AAAA,EAChB,SAAA,EAAW,OAAA;AAAA,EACX,UAAA,EAAY,sCAAA;AAAA,EACZ,GAAA,EAAK;AACP,CAAA;AAEA,IAAM,kBAAA,GAA0C;AAAA,EAC9C,OAAA,EAAS,WAAA;AAAA,EACT,QAAA,EAAU,MAAA;AAAA,EACV,UAAA,EAAY,GAAA;AAAA,EACZ,KAAA,EAAO,SAAA;AAAA,EACP,eAAA,EAAiB,SAAA;AAAA,EACjB,MAAA,EAAQ,MAAA;AAAA,EACR,YAAA,EAAc,KAAA;AAAA,EACd,MAAA,EAAQ,SAAA;AAAA,EACR,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,GAAA,EAAK;AACP,CAAA;AAMO,SAAS,QAAA,CAAS,EAAE,QAAA,EAAU,OAAA,EAAS,iBAAgB,EAAkB;AAC9E,EAAA,MAAM,EAAE,eAAA,EAAiB,SAAA,EAAW,OAAO,MAAA,EAAQ,IAAA,KAAS,OAAA,EAAQ;AAEpE,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,uBAAOA,GAAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,OAAA,oBAAWA,IAAC,KAAA,EAAA,EAAI,KAAA,EAAO,mBAAA,EAAqB,QAAA,EAAA,YAAA,EAAU,CAAA,EAAO,CAAA;AAAA,EACzE;AAEA,EAAA,IAAI,CAAC,eAAA,EAAiB;AACpB,IAAA,IAAI,eAAA,EAAiB;AACnB,MAAA,uBAAOA,GAAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAA,eAAA,CAAgB,EAAE,QAAQ,MAAM,MAAA,EAAO,EAAG,CAAA,EAAE,CAAA;AAAA,IACxD;AAEA,IAAA,uBACE,IAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAO,qBAAA,EACV,QAAA,EAAA;AAAA,sBAAAA,GAAAA,CAAC,IAAA,EAAA,EAAG,KAAA,EAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,QAAA,EAAU,MAAA,EAAQ,KAAA,EAAO,SAAA,EAAU,EAAG,QAAA,EAAA,qBAAA,EAAmB,CAAA;AAAA,sBACjFA,GAAAA,CAAC,GAAA,EAAA,EAAE,KAAA,EAAO,EAAE,QAAQ,CAAA,EAAG,KAAA,EAAO,SAAA,EAAU,EAAG,QAAA,EAAA,gDAAA,EAE3C,CAAA;AAAA,MACC,KAAA,oBACCA,GAAAA,CAAC,GAAA,EAAA,EAAE,KAAA,EAAO,EAAE,MAAA,EAAQ,CAAA,EAAG,KAAA,EAAO,SAAA,EAAW,QAAA,EAAU,MAAA,IAAW,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,sBAEtEA,IAAC,QAAA,EAAA,EAAO,KAAA,EAAO,oBAAoB,OAAA,EAAS,MAAM,MAAA,EAAO,EAAG,QAAA,EAAA,qBAAA,EAE5D;AAAA,KAAA,EACF,CAAA;AAAA,EAEJ;AAEA,EAAA,uBAAOA,GAAAA,CAAA,QAAA,EAAA,EAAG,QAAA,EAAS,CAAA;AACrB","file":"react.js","sourcesContent":["import React, { useEffect, useMemo, useState } from \"react\";\nimport { SemanticLayerClient } from \"../client\";\nimport type { SemanticLayerConfig, AuthState } from \"../types\";\nimport { SemanticLayerContext } from \"./context\";\n\nexport interface SemanticLayerProviderProps {\n /** The Supabase URL of the gateway project. */\n gatewayUrl: string;\n /** The Supabase anon/publishable key of the gateway project. */\n anonKey: string;\n /**\n * Optional: a pre-constructed client instance.\n * If provided, gatewayUrl and anonKey are ignored.\n */\n client?: SemanticLayerClient;\n children: React.ReactNode;\n}\n\nexport function SemanticLayerProvider({\n gatewayUrl,\n anonKey,\n client: externalClient,\n children,\n}: SemanticLayerProviderProps) {\n const client = useMemo(() => {\n if (externalClient) return externalClient;\n return new SemanticLayerClient({ gatewayUrl, anonKey });\n }, [gatewayUrl, anonKey, externalClient]);\n\n const [auth, setAuth] = useState<AuthState>({\n isAuthenticated: false,\n isLoading: true,\n user: null,\n error: null,\n });\n\n useEffect(() => {\n let mounted = true;\n\n async function initAuth() {\n try {\n const session = await client.getSession();\n if (!mounted) return;\n\n if (session?.user) {\n setAuth({\n isAuthenticated: true,\n isLoading: false,\n user: { id: session.user.id, email: session.user.email || \"\" },\n error: null,\n });\n } else {\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: null,\n });\n }\n } catch (err) {\n if (!mounted) return;\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: err instanceof Error ? err.message : \"Auth initialization failed\",\n });\n }\n }\n\n initAuth();\n\n const { data: { subscription } } = client.onAuthStateChange((_event, session) => {\n if (!mounted) return;\n if (session?.user) {\n setAuth({\n isAuthenticated: true,\n isLoading: false,\n user: { id: session.user.id, email: session.user.email || \"\" },\n error: null,\n });\n } else {\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: null,\n });\n }\n });\n\n return () => {\n mounted = false;\n subscription.unsubscribe();\n };\n }, [client]);\n\n const value = useMemo(() => ({ client, auth }), [client, auth]);\n\n return (\n <SemanticLayerContext.Provider value={value}>\n {children}\n </SemanticLayerContext.Provider>\n );\n}\n","import React from \"react\";\nimport { useAuth } from \"./hooks\";\n\nexport interface AuthGateProps {\n children: React.ReactNode;\n /** Custom loading component. */\n loading?: React.ReactNode;\n /** Custom sign-in component. Receives a signIn callback. */\n signInComponent?: (props: { signIn: () => void }) => React.ReactNode;\n}\n\nconst defaultLoadingStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n color: \"#6b7280\",\n};\n\nconst defaultContainerStyle: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n gap: \"16px\",\n};\n\nconst defaultButtonStyle: React.CSSProperties = {\n padding: \"12px 24px\",\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#ffffff\",\n backgroundColor: \"#4285f4\",\n border: \"none\",\n borderRadius: \"8px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n};\n\n/**\n * Wraps children and only renders them when the user is authenticated.\n * Shows a sign-in screen when unauthenticated.\n */\nexport function AuthGate({ children, loading, signInComponent }: AuthGateProps) {\n const { isAuthenticated, isLoading, error, signIn, user } = useAuth();\n\n if (isLoading) {\n return <>{loading || <div style={defaultLoadingStyle}>Loading...</div>}</>;\n }\n\n if (!isAuthenticated) {\n if (signInComponent) {\n return <>{signInComponent({ signIn: () => signIn() })}</>;\n }\n\n return (\n <div style={defaultContainerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Sign in to continue</h2>\n <p style={{ margin: 0, color: \"#6b7280\" }}>\n Use your inKind Google account to access data.\n </p>\n {error && (\n <p style={{ margin: 0, color: \"#ef4444\", fontSize: \"14px\" }}>{error}</p>\n )}\n <button style={defaultButtonStyle} onClick={() => signIn()}>\n Sign in with Google\n </button>\n </div>\n );\n }\n\n return <>{children}</>;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/react/provider.tsx","../src/react/auth-gate.tsx"],"names":["useEffect","jsx"],"mappings":"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","file":"react.js","sourcesContent":["import React, { useEffect, useMemo, useState } from \"react\";\nimport { SemanticLayerClient } from \"../client\";\nimport type { SemanticLayerConfig, AuthState } from \"../types\";\nimport { SemanticLayerContext } from \"./context\";\n\nexport interface SemanticLayerProviderProps {\n /** The Supabase URL of the gateway project. */\n gatewayUrl: string;\n /** The Supabase anon/publishable key of the gateway project. */\n anonKey: string;\n /**\n * Optional: a pre-constructed client instance.\n * If provided, gatewayUrl and anonKey are ignored.\n */\n client?: SemanticLayerClient;\n children: React.ReactNode;\n}\n\nexport function SemanticLayerProvider({\n gatewayUrl,\n anonKey,\n client: externalClient,\n children,\n}: SemanticLayerProviderProps) {\n const client = useMemo(() => {\n if (externalClient) return externalClient;\n return new SemanticLayerClient({ gatewayUrl, anonKey });\n }, [gatewayUrl, anonKey, externalClient]);\n\n const [auth, setAuth] = useState<AuthState>({\n isAuthenticated: false,\n isLoading: true,\n user: null,\n error: null,\n });\n\n useEffect(() => {\n let mounted = true;\n\n async function initAuth() {\n try {\n const session = await client.getSession();\n if (!mounted) return;\n\n if (session?.user) {\n setAuth({\n isAuthenticated: true,\n isLoading: false,\n user: { id: session.user.id, email: session.user.email || \"\" },\n error: null,\n });\n } else {\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: null,\n });\n }\n } catch (err) {\n if (!mounted) return;\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: err instanceof Error ? err.message : \"Auth initialization failed\",\n });\n }\n }\n\n initAuth();\n\n const { data: { subscription } } = client.onAuthStateChange((_event, session) => {\n if (!mounted) return;\n if (session?.user) {\n setAuth({\n isAuthenticated: true,\n isLoading: false,\n user: { id: session.user.id, email: session.user.email || \"\" },\n error: null,\n });\n } else {\n setAuth({\n isAuthenticated: false,\n isLoading: false,\n user: null,\n error: null,\n });\n }\n });\n\n return () => {\n mounted = false;\n subscription.unsubscribe();\n };\n }, [client]);\n\n const value = useMemo(() => ({ client, auth }), [client, auth]);\n\n return (\n <SemanticLayerContext.Provider value={value}>\n {children}\n </SemanticLayerContext.Provider>\n );\n}\n","import React, { useCallback, useContext, useEffect } from \"react\";\nimport { useAuth } from \"./hooks\";\nimport { SemanticLayerContext } from \"./context\";\n\nexport interface AuthGateProps {\n children: React.ReactNode;\n /** Custom loading component. */\n loading?: React.ReactNode;\n /** Custom sign-in component. Receives a signIn callback. */\n signInComponent?: (props: { signIn: () => void }) => React.ReactNode;\n}\n\nconst defaultLoadingStyle: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n color: \"#6b7280\",\n};\n\nconst defaultContainerStyle: React.CSSProperties = {\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n justifyContent: \"center\",\n minHeight: \"100vh\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n gap: \"16px\",\n};\n\nconst defaultButtonStyle: React.CSSProperties = {\n padding: \"12px 24px\",\n fontSize: \"16px\",\n fontWeight: 500,\n color: \"#ffffff\",\n backgroundColor: \"#4285f4\",\n border: \"none\",\n borderRadius: \"8px\",\n cursor: \"pointer\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n};\n\nfunction isInIframe(): boolean {\n try {\n return typeof window !== \"undefined\" && window.self !== window.top;\n } catch {\n return true;\n }\n}\n\n/**\n * Wraps children and only renders them when the user is authenticated.\n * Shows a sign-in screen when unauthenticated.\n * When running inside an iframe (e.g. Lovable preview), uses a popup\n * for OAuth so the editor isn't navigated away.\n */\nexport function AuthGate({ children, loading, signInComponent }: AuthGateProps) {\n const { isAuthenticated, isLoading, error, signIn } = useAuth();\n const ctx = useContext(SemanticLayerContext);\n const client = ctx?.client;\n const inIframe = isInIframe();\n\n // Listen for auth tokens relayed from the popup via postMessage\n useEffect(() => {\n if (!inIframe || !client) return;\n\n const handler = (event: MessageEvent) => {\n if (event.data?.type === \"semantic-layer-auth-callback\" && event.data.access_token) {\n client.getSupabaseClient().auth.setSession({\n access_token: event.data.access_token,\n refresh_token: event.data.refresh_token,\n });\n }\n };\n\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }, [inIframe, client]);\n\n const handleSignIn = useCallback(async () => {\n if (inIframe && client) {\n const callbackUrl = `${client.gatewayUrl}/functions/v1/auth-callback`;\n const url = await client.getSignInUrl(callbackUrl);\n if (url) {\n window.open(url, \"semantic-layer-auth\", \"popup,width=600,height=700\");\n }\n } else {\n signIn(window.location.origin);\n }\n }, [inIframe, client, signIn]);\n\n if (isLoading) {\n return <>{loading || <div style={defaultLoadingStyle}>Loading...</div>}</>;\n }\n\n if (!isAuthenticated) {\n if (signInComponent) {\n return <>{signInComponent({ signIn: handleSignIn })}</>;\n }\n\n return (\n <div style={defaultContainerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Sign in to continue</h2>\n <p style={{ margin: 0, color: \"#6b7280\" }}>\n Use your inKind Google account to access data.\n </p>\n {error && (\n <p style={{ margin: 0, color: \"#ef4444\", fontSize: \"14px\" }}>{error}</p>\n )}\n <button style={defaultButtonStyle} onClick={handleSignIn}>\n Sign in with Google\n </button>\n </div>\n );\n }\n\n return <>{children}</>;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts"],"names":["createClient"],"mappings":"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","file":"chunk-4RECQ22F.cjs","sourcesContent":["import { createClient, SupabaseClient, Session } from \"@supabase/supabase-js\";\nimport type {\n SemanticLayerConfig,\n MetadataResponse,\n PivotConfig,\n QueryResult,\n SimpleQueryInput,\n SemanticField,\n} from \"./types\";\n\nexport class SemanticLayerClient {\n private supabase: SupabaseClient;\n private metadataCache: MetadataResponse | null = null;\n private metadataCacheTime = 0;\n private readonly CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\n constructor(config: SemanticLayerConfig) {\n this.supabase = createClient(config.gatewayUrl, config.anonKey, {\n auth: {\n persistSession: true,\n autoRefreshToken: true,\n storageKey: \"semantic-layer-auth\",\n },\n });\n }\n\n /** Access the underlying Supabase client (for auth operations). */\n getSupabaseClient(): SupabaseClient {\n return this.supabase;\n }\n\n // ─── Auth ────────────────────────────────────────────────────────────────────\n\n async signInWithGoogle(redirectTo?: string) {\n return this.supabase.auth.signInWithOAuth({\n provider: \"google\",\n options: { redirectTo },\n });\n }\n\n async signOut() {\n return this.supabase.auth.signOut();\n }\n\n async getSession(): Promise<Session | null> {\n const { data } = await this.supabase.auth.getSession();\n return data.session;\n }\n\n onAuthStateChange(callback: (event: string, session: Session | null) => void) {\n return this.supabase.auth.onAuthStateChange(callback);\n }\n\n // ─── Metadata ────────────────────────────────────────────────────────────────\n\n /**\n * Fetch the curated catalog of metrics and dimensions from the gateway.\n * Results are cached for 5 minutes.\n */\n async getMetadata(forceRefresh = false): Promise<MetadataResponse> {\n const now = Date.now();\n if (!forceRefresh && this.metadataCache && now - this.metadataCacheTime < this.CACHE_TTL_MS) {\n return this.metadataCache;\n }\n\n const { data, error } = await this.supabase.functions.invoke(\"dbt-metadata\");\n\n if (error) {\n throw new SemanticLayerError(`Failed to fetch metadata: ${error.message}`, \"METADATA_ERROR\");\n }\n if (data?.error) {\n throw new SemanticLayerError(data.error, \"METADATA_ERROR\");\n }\n\n this.metadataCache = data as MetadataResponse;\n this.metadataCacheTime = now;\n return this.metadataCache;\n }\n\n /** Get only metrics from the catalog. */\n async getMetrics(): Promise<SemanticField[]> {\n const { fields } = await this.getMetadata();\n return fields.filter((f) => f.type === \"metric\");\n }\n\n /** Get only dimensions (including time dimensions) from the catalog. */\n async getDimensions(): Promise<SemanticField[]> {\n const { fields } = await this.getMetadata();\n return fields.filter((f) => f.type === \"dimension\" || f.type === \"time_dimension\");\n }\n\n /** Find a field by name or id. */\n async getField(nameOrId: string): Promise<SemanticField | undefined> {\n const { fields } = await this.getMetadata();\n return fields.find((f) => f.name === nameOrId || f.id === nameOrId);\n }\n\n // ─── Query ───────────────────────────────────────────────────────────────────\n\n /** Execute a query using the full PivotConfig format. */\n async query(config: PivotConfig): Promise<QueryResult> {\n if (config.values.length === 0) {\n return { columns: [], rows: [], totalRows: 0, executionTimeMs: 0 };\n }\n\n const { data, error } = await this.supabase.functions.invoke(\"dbt-query\", {\n body: { config },\n });\n\n if (error) {\n throw new SemanticLayerError(`Query failed: ${error.message}`, \"QUERY_ERROR\");\n }\n if (data?.error) {\n throw new SemanticLayerError(data.error, \"QUERY_ERROR\");\n }\n\n return data as QueryResult;\n }\n\n /**\n * Execute a query using the simplified input format.\n * Automatically resolves metric/dimension names to full field objects.\n */\n async simpleQuery(input: SimpleQueryInput): Promise<QueryResult> {\n const { fields } = await this.getMetadata();\n const fieldMap = new Map(fields.map((f) => [f.name, f]));\n\n const values = input.metrics.map((name) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown metric: \"${name}\"`, \"UNKNOWN_FIELD\");\n return { fieldId: field.id, field };\n });\n\n const rows = (input.groupBy || []).map((name) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown dimension: \"${name}\"`, \"UNKNOWN_FIELD\");\n const grain = field.type === \"time_dimension\" ? input.grain : undefined;\n return { fieldId: field.id, field, grain };\n });\n\n const filters = Object.entries(input.filters || {}).map(([name, filterValues]) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown filter field: \"${name}\"`, \"UNKNOWN_FIELD\");\n return { fieldId: field.id, field, filterValues };\n });\n\n return this.query({ values, rows, columns: [], filters });\n }\n}\n\nexport class SemanticLayerError extends Error {\n code: string;\n constructor(message: string, code: string) {\n super(message);\n this.name = \"SemanticLayerError\";\n this.code = code;\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":"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","file":"chunk-IQARBGJP.js","sourcesContent":["import { createClient, SupabaseClient, Session } from \"@supabase/supabase-js\";\nimport type {\n SemanticLayerConfig,\n MetadataResponse,\n PivotConfig,\n QueryResult,\n SimpleQueryInput,\n SemanticField,\n} from \"./types\";\n\nexport class SemanticLayerClient {\n private supabase: SupabaseClient;\n private metadataCache: MetadataResponse | null = null;\n private metadataCacheTime = 0;\n private readonly CACHE_TTL_MS = 5 * 60 * 1000; // 5 minutes\n\n constructor(config: SemanticLayerConfig) {\n this.supabase = createClient(config.gatewayUrl, config.anonKey, {\n auth: {\n persistSession: true,\n autoRefreshToken: true,\n storageKey: \"semantic-layer-auth\",\n },\n });\n }\n\n /** Access the underlying Supabase client (for auth operations). */\n getSupabaseClient(): SupabaseClient {\n return this.supabase;\n }\n\n // ─── Auth ────────────────────────────────────────────────────────────────────\n\n async signInWithGoogle(redirectTo?: string) {\n return this.supabase.auth.signInWithOAuth({\n provider: \"google\",\n options: { redirectTo },\n });\n }\n\n async signOut() {\n return this.supabase.auth.signOut();\n }\n\n async getSession(): Promise<Session | null> {\n const { data } = await this.supabase.auth.getSession();\n return data.session;\n }\n\n onAuthStateChange(callback: (event: string, session: Session | null) => void) {\n return this.supabase.auth.onAuthStateChange(callback);\n }\n\n // ─── Metadata ────────────────────────────────────────────────────────────────\n\n /**\n * Fetch the curated catalog of metrics and dimensions from the gateway.\n * Results are cached for 5 minutes.\n */\n async getMetadata(forceRefresh = false): Promise<MetadataResponse> {\n const now = Date.now();\n if (!forceRefresh && this.metadataCache && now - this.metadataCacheTime < this.CACHE_TTL_MS) {\n return this.metadataCache;\n }\n\n const { data, error } = await this.supabase.functions.invoke(\"dbt-metadata\");\n\n if (error) {\n throw new SemanticLayerError(`Failed to fetch metadata: ${error.message}`, \"METADATA_ERROR\");\n }\n if (data?.error) {\n throw new SemanticLayerError(data.error, \"METADATA_ERROR\");\n }\n\n this.metadataCache = data as MetadataResponse;\n this.metadataCacheTime = now;\n return this.metadataCache;\n }\n\n /** Get only metrics from the catalog. */\n async getMetrics(): Promise<SemanticField[]> {\n const { fields } = await this.getMetadata();\n return fields.filter((f) => f.type === \"metric\");\n }\n\n /** Get only dimensions (including time dimensions) from the catalog. */\n async getDimensions(): Promise<SemanticField[]> {\n const { fields } = await this.getMetadata();\n return fields.filter((f) => f.type === \"dimension\" || f.type === \"time_dimension\");\n }\n\n /** Find a field by name or id. */\n async getField(nameOrId: string): Promise<SemanticField | undefined> {\n const { fields } = await this.getMetadata();\n return fields.find((f) => f.name === nameOrId || f.id === nameOrId);\n }\n\n // ─── Query ───────────────────────────────────────────────────────────────────\n\n /** Execute a query using the full PivotConfig format. */\n async query(config: PivotConfig): Promise<QueryResult> {\n if (config.values.length === 0) {\n return { columns: [], rows: [], totalRows: 0, executionTimeMs: 0 };\n }\n\n const { data, error } = await this.supabase.functions.invoke(\"dbt-query\", {\n body: { config },\n });\n\n if (error) {\n throw new SemanticLayerError(`Query failed: ${error.message}`, \"QUERY_ERROR\");\n }\n if (data?.error) {\n throw new SemanticLayerError(data.error, \"QUERY_ERROR\");\n }\n\n return data as QueryResult;\n }\n\n /**\n * Execute a query using the simplified input format.\n * Automatically resolves metric/dimension names to full field objects.\n */\n async simpleQuery(input: SimpleQueryInput): Promise<QueryResult> {\n const { fields } = await this.getMetadata();\n const fieldMap = new Map(fields.map((f) => [f.name, f]));\n\n const values = input.metrics.map((name) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown metric: \"${name}\"`, \"UNKNOWN_FIELD\");\n return { fieldId: field.id, field };\n });\n\n const rows = (input.groupBy || []).map((name) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown dimension: \"${name}\"`, \"UNKNOWN_FIELD\");\n const grain = field.type === \"time_dimension\" ? input.grain : undefined;\n return { fieldId: field.id, field, grain };\n });\n\n const filters = Object.entries(input.filters || {}).map(([name, filterValues]) => {\n const field = fieldMap.get(name);\n if (!field) throw new SemanticLayerError(`Unknown filter field: \"${name}\"`, \"UNKNOWN_FIELD\");\n return { fieldId: field.id, field, filterValues };\n });\n\n return this.query({ values, rows, columns: [], filters });\n }\n}\n\nexport class SemanticLayerError extends Error {\n code: string;\n constructor(message: string, code: string) {\n super(message);\n this.name = \"SemanticLayerError\";\n this.code = code;\n }\n}\n"]}
|