@inkindcards/semantic-layer 0.1.1 → 0.1.3
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-I4L4FFJY.cjs} +23 -3
- package/dist/chunk-I4L4FFJY.cjs.map +1 -0
- package/dist/{chunk-Y3A3T45C.cjs → chunk-OJVM3RPD.cjs} +12 -4
- package/dist/chunk-OJVM3RPD.cjs.map +1 -0
- package/dist/{chunk-IQARBGJP.js → chunk-P72N6ISJ.js} +23 -3
- package/dist/chunk-P72N6ISJ.js.map +1 -0
- package/dist/{chunk-NJ4IJBV3.js → chunk-RGVYFSW2.js} +12 -4
- package/dist/chunk-RGVYFSW2.js.map +1 -0
- package/dist/components.cjs +2 -2
- package/dist/components.js +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +7 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +1 -1
- package/dist/react.cjs +158 -22
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +12 -2
- package/dist/react.d.ts +12 -2
- package/dist/react.js +153 -17
- 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
- package/dist/chunk-NJ4IJBV3.js.map +0 -1
- package/dist/chunk-Y3A3T45C.cjs.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,26 @@ 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
|
+
}
|
|
43
|
+
/** Send a one-time code to the given email (for iframe/editor sign-in). */
|
|
44
|
+
async sendOtp(email) {
|
|
45
|
+
return this.supabase.auth.signInWithOtp({ email });
|
|
46
|
+
}
|
|
47
|
+
/** Verify a one-time code received via email. */
|
|
48
|
+
async verifyOtp(email, token) {
|
|
49
|
+
return this.supabase.auth.verifyOtp({ email, token, type: "email" });
|
|
50
|
+
}
|
|
31
51
|
async signOut() {
|
|
32
52
|
return this.supabase.auth.signOut();
|
|
33
53
|
}
|
|
@@ -127,5 +147,5 @@ var SemanticLayerError = class extends Error {
|
|
|
127
147
|
|
|
128
148
|
exports.SemanticLayerClient = SemanticLayerClient;
|
|
129
149
|
exports.SemanticLayerError = SemanticLayerError;
|
|
130
|
-
//# sourceMappingURL=chunk-
|
|
131
|
-
//# sourceMappingURL=chunk-
|
|
150
|
+
//# sourceMappingURL=chunk-I4L4FFJY.cjs.map
|
|
151
|
+
//# sourceMappingURL=chunk-I4L4FFJY.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":["createClient"],"mappings":"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","file":"chunk-I4L4FFJY.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 /** Send a one-time code to the given email (for iframe/editor sign-in). */\n async sendOtp(email: string) {\n return this.supabase.auth.signInWithOtp({ email });\n }\n\n /** Verify a one-time code received via email. */\n async verifyOtp(email: string, token: string) {\n return this.supabase.auth.verifyOtp({ email, token, type: \"email\" });\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"]}
|
|
@@ -12,13 +12,21 @@ function useSemanticLayer() {
|
|
|
12
12
|
return ctx;
|
|
13
13
|
}
|
|
14
14
|
function useAuth() {
|
|
15
|
-
const { client, auth } = useSemanticLayer();
|
|
15
|
+
const { client, auth, emailDomain } = useSemanticLayer();
|
|
16
16
|
const signIn = react.useCallback(
|
|
17
17
|
(redirectTo) => client.signInWithGoogle(redirectTo),
|
|
18
18
|
[client]
|
|
19
19
|
);
|
|
20
|
+
const sendOtp = react.useCallback(
|
|
21
|
+
(email) => client.sendOtp(email),
|
|
22
|
+
[client]
|
|
23
|
+
);
|
|
24
|
+
const verifyOtp = react.useCallback(
|
|
25
|
+
(email, token) => client.verifyOtp(email, token),
|
|
26
|
+
[client]
|
|
27
|
+
);
|
|
20
28
|
const signOut = react.useCallback(() => client.signOut(), [client]);
|
|
21
|
-
return { ...auth, signIn, signOut };
|
|
29
|
+
return { ...auth, signIn, sendOtp, verifyOtp, signOut, emailDomain };
|
|
22
30
|
}
|
|
23
31
|
function useMetrics() {
|
|
24
32
|
const { client, auth } = useSemanticLayer();
|
|
@@ -123,5 +131,5 @@ exports.useAuth = useAuth;
|
|
|
123
131
|
exports.useMetrics = useMetrics;
|
|
124
132
|
exports.usePivotQuery = usePivotQuery;
|
|
125
133
|
exports.useSemanticQuery = useSemanticQuery;
|
|
126
|
-
//# sourceMappingURL=chunk-
|
|
127
|
-
//# sourceMappingURL=chunk-
|
|
134
|
+
//# sourceMappingURL=chunk-OJVM3RPD.cjs.map
|
|
135
|
+
//# sourceMappingURL=chunk-OJVM3RPD.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/context.ts","../src/react/hooks.ts"],"names":["createContext","useContext","useCallback","useState","useRef","useEffect"],"mappings":"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","file":"chunk-OJVM3RPD.cjs","sourcesContent":["import { createContext } from \"react\";\nimport type { SemanticLayerClient } from \"../client\";\nimport type { AuthState } from \"../types\";\n\nexport interface SemanticLayerContextValue {\n client: SemanticLayerClient;\n auth: AuthState;\n emailDomain?: string;\n}\n\nexport const SemanticLayerContext = createContext<SemanticLayerContextValue | null>(null);\n","import { useContext, useCallback, useEffect, useState, useRef } from \"react\";\nimport { SemanticLayerContext } from \"./context\";\nimport type {\n SemanticField,\n FieldCategory,\n QueryResult,\n SimpleQueryInput,\n PivotConfig,\n AuthState,\n} from \"../types\";\n\nfunction useSemanticLayer() {\n const ctx = useContext(SemanticLayerContext);\n if (!ctx) {\n throw new Error(\"useSemanticLayer hooks must be used within a <SemanticLayerProvider>\");\n }\n return ctx;\n}\n\n/** Returns the current auth state and sign-in/sign-out methods. */\nexport function useAuth() {\n const { client, auth, emailDomain } = useSemanticLayer();\n\n const signIn = useCallback(\n (redirectTo?: string) => client.signInWithGoogle(redirectTo),\n [client],\n );\n\n const sendOtp = useCallback(\n (email: string) => client.sendOtp(email),\n [client],\n );\n\n const verifyOtp = useCallback(\n (email: string, token: string) => client.verifyOtp(email, token),\n [client],\n );\n\n const signOut = useCallback(() => client.signOut(), [client]);\n\n return { ...auth, signIn, sendOtp, verifyOtp, signOut, emailDomain };\n}\n\ninterface UseMetricsResult {\n fields: SemanticField[];\n metrics: SemanticField[];\n dimensions: SemanticField[];\n categories: FieldCategory[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\n/** Fetch the full curated catalog of metrics and dimensions. */\nexport function useMetrics(): UseMetricsResult {\n const { client, auth } = useSemanticLayer();\n const [fields, setFields] = useState<SemanticField[]>([]);\n const [categories, setCategories] = useState<FieldCategory[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const fetchedRef = useRef(false);\n\n const fetch = useCallback(\n async (force = false) => {\n if (!auth.isAuthenticated) return;\n setIsLoading(true);\n setError(null);\n try {\n const data = await client.getMetadata(force);\n setFields(data.fields);\n setCategories(data.categories);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load metadata\");\n } finally {\n setIsLoading(false);\n }\n },\n [client, auth.isAuthenticated],\n );\n\n useEffect(() => {\n if (auth.isAuthenticated && !fetchedRef.current) {\n fetchedRef.current = true;\n fetch();\n }\n }, [auth.isAuthenticated, fetch]);\n\n const refetch = useCallback(() => fetch(true), [fetch]);\n\n return {\n fields,\n metrics: fields.filter((f) => f.type === \"metric\"),\n dimensions: fields.filter((f) => f.type === \"dimension\" || f.type === \"time_dimension\"),\n categories,\n isLoading,\n error,\n refetch,\n };\n}\n\ninterface UseSemanticQueryOptions {\n /** Set to false to prevent the query from running automatically. */\n enabled?: boolean;\n}\n\ninterface UseSemanticQueryResult {\n data: QueryResult | null;\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\n/**\n * Execute a query against the dbt Semantic Layer using the simple input format.\n * The query runs automatically when the input changes (unless enabled=false).\n */\nexport function useSemanticQuery(\n input: SimpleQueryInput | null,\n options: UseSemanticQueryOptions = {},\n): UseSemanticQueryResult {\n const { client, auth } = useSemanticLayer();\n const { enabled = true } = options;\n const [data, setData] = useState<QueryResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const inputKey = JSON.stringify(input);\n\n const execute = useCallback(async () => {\n if (!auth.isAuthenticated || !input || !enabled) return;\n if (input.metrics.length === 0) {\n setData({ columns: [], rows: [], totalRows: 0, executionTimeMs: 0 });\n return;\n }\n\n setIsLoading(true);\n setError(null);\n try {\n const result = await client.simpleQuery(input);\n setData(result);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Query failed\");\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, auth.isAuthenticated, inputKey, enabled]);\n\n useEffect(() => {\n execute();\n }, [execute]);\n\n return { data, isLoading, error, refetch: execute };\n}\n\n/**\n * Execute a query using the full PivotConfig format.\n * Use this for advanced use cases (column pivoting, custom aggregations).\n */\nexport function usePivotQuery(\n config: PivotConfig | null,\n options: UseSemanticQueryOptions = {},\n): UseSemanticQueryResult {\n const { client, auth } = useSemanticLayer();\n const { enabled = true } = options;\n const [data, setData] = useState<QueryResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const configKey = JSON.stringify(config);\n\n const execute = useCallback(async () => {\n if (!auth.isAuthenticated || !config || !enabled) return;\n\n setIsLoading(true);\n setError(null);\n try {\n const result = await client.query(config);\n setData(result);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Query failed\");\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, auth.isAuthenticated, configKey, enabled]);\n\n useEffect(() => {\n execute();\n }, [execute]);\n\n return { data, isLoading, error, refetch: execute };\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,26 @@ 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
|
+
}
|
|
41
|
+
/** Send a one-time code to the given email (for iframe/editor sign-in). */
|
|
42
|
+
async sendOtp(email) {
|
|
43
|
+
return this.supabase.auth.signInWithOtp({ email });
|
|
44
|
+
}
|
|
45
|
+
/** Verify a one-time code received via email. */
|
|
46
|
+
async verifyOtp(email, token) {
|
|
47
|
+
return this.supabase.auth.verifyOtp({ email, token, type: "email" });
|
|
48
|
+
}
|
|
29
49
|
async signOut() {
|
|
30
50
|
return this.supabase.auth.signOut();
|
|
31
51
|
}
|
|
@@ -124,5 +144,5 @@ var SemanticLayerError = class extends Error {
|
|
|
124
144
|
};
|
|
125
145
|
|
|
126
146
|
export { SemanticLayerClient, SemanticLayerError };
|
|
127
|
-
//# sourceMappingURL=chunk-
|
|
128
|
-
//# sourceMappingURL=chunk-
|
|
147
|
+
//# sourceMappingURL=chunk-P72N6ISJ.js.map
|
|
148
|
+
//# sourceMappingURL=chunk-P72N6ISJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";;;AAUO,IAAM,sBAAN,MAA0B;AAAA,EAO/B,YAAY,MAAA,EAA6B;AALzC,IAAA,IAAA,CAAQ,aAAA,GAAyC,IAAA;AACjD,IAAA,IAAA,CAAQ,iBAAA,GAAoB,CAAA;AAC5B,IAAA,IAAA,CAAiB,YAAA,GAAe,IAAI,EAAA,GAAK,GAAA;AAIvC,IAAA,IAAA,CAAK,aAAa,MAAA,CAAO,UAAA;AACzB,IAAA,IAAA,CAAK,QAAA,GAAW,YAAA,CAAa,MAAA,CAAO,UAAA,EAAY,OAAO,OAAA,EAAS;AAAA,MAC9D,IAAA,EAAM;AAAA,QACJ,cAAA,EAAgB,IAAA;AAAA,QAChB,gBAAA,EAAkB,IAAA;AAAA,QAClB,UAAA,EAAY;AAAA;AACd,KACD,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,iBAAA,GAAoC;AAClC,IAAA,OAAO,IAAA,CAAK,QAAA;AAAA,EACd;AAAA;AAAA,EAIA,MAAM,iBAAiB,UAAA,EAAqB;AAC1C,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,eAAA,CAAgB;AAAA,MACxC,QAAA,EAAU,QAAA;AAAA,MACV,OAAA,EAAS,EAAE,UAAA;AAAW,KACvB,CAAA;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,aAAa,UAAA,EAA6C;AAC9D,IAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,IAAA,CAAK,QAAA,CAAS,KAAK,eAAA,CAAgB;AAAA,MAC/D,QAAA,EAAU,QAAA;AAAA,MACV,OAAA,EAAS;AAAA,QACP,UAAA;AAAA,QACA,mBAAA,EAAqB;AAAA;AACvB,KACD,CAAA;AACD,IAAA,IAAI,KAAA,IAAS,CAAC,IAAA,CAAK,GAAA,EAAK,OAAO,IAAA;AAC/B,IAAA,OAAO,IAAA,CAAK,GAAA;AAAA,EACd;AAAA;AAAA,EAGA,MAAM,QAAQ,KAAA,EAAe;AAC3B,IAAA,OAAO,KAAK,QAAA,CAAS,IAAA,CAAK,aAAA,CAAc,EAAE,OAAO,CAAA;AAAA,EACnD;AAAA;AAAA,EAGA,MAAM,SAAA,CAAU,KAAA,EAAe,KAAA,EAAe;AAC5C,IAAA,OAAO,IAAA,CAAK,SAAS,IAAA,CAAK,SAAA,CAAU,EAAE,KAAA,EAAO,KAAA,EAAO,IAAA,EAAM,OAAA,EAAS,CAAA;AAAA,EACrE;AAAA,EAEA,MAAM,OAAA,GAAU;AACd,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,OAAA,EAAQ;AAAA,EACpC;AAAA,EAEA,MAAM,UAAA,GAAsC;AAC1C,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,MAAM,IAAA,CAAK,QAAA,CAAS,KAAK,UAAA,EAAW;AACrD,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA,EAEA,kBAAkB,QAAA,EAA4D;AAC5E,IAAA,OAAO,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,iBAAA,CAAkB,QAAQ,CAAA;AAAA,EACtD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,WAAA,CAAY,YAAA,GAAe,KAAA,EAAkC;AACjE,IAAA,MAAM,GAAA,GAAM,KAAK,GAAA,EAAI;AACrB,IAAA,IAAI,CAAC,gBAAgB,IAAA,CAAK,aAAA,IAAiB,MAAM,IAAA,CAAK,iBAAA,GAAoB,KAAK,YAAA,EAAc;AAC3F,MAAA,OAAO,IAAA,CAAK,aAAA;AAAA,IACd;AAEA,IAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,MAAA,CAAO,cAAc,CAAA;AAE3E,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,0BAAA,EAA6B,KAAA,CAAM,OAAO,IAAI,gBAAgB,CAAA;AAAA,IAC7F;AACA,IAAA,IAAI,MAAM,KAAA,EAAO;AACf,MAAA,MAAM,IAAI,kBAAA,CAAmB,IAAA,CAAK,KAAA,EAAO,gBAAgB,CAAA;AAAA,IAC3D;AAEA,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,IAAA,IAAA,CAAK,iBAAA,GAAoB,GAAA;AACzB,IAAA,OAAO,IAAA,CAAK,aAAA;AAAA,EACd;AAAA;AAAA,EAGA,MAAM,UAAA,GAAuC;AAC3C,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,KAAK,WAAA,EAAY;AAC1C,IAAA,OAAO,OAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,QAAQ,CAAA;AAAA,EACjD;AAAA;AAAA,EAGA,MAAM,aAAA,GAA0C;AAC9C,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,KAAK,WAAA,EAAY;AAC1C,IAAA,OAAO,MAAA,CAAO,OAAO,CAAC,CAAA,KAAM,EAAE,IAAA,KAAS,WAAA,IAAe,CAAA,CAAE,IAAA,KAAS,gBAAgB,CAAA;AAAA,EACnF;AAAA;AAAA,EAGA,MAAM,SAAS,QAAA,EAAsD;AACnE,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,KAAK,WAAA,EAAY;AAC1C,IAAA,OAAO,MAAA,CAAO,KAAK,CAAC,CAAA,KAAM,EAAE,IAAA,KAAS,QAAA,IAAY,CAAA,CAAE,EAAA,KAAO,QAAQ,CAAA;AAAA,EACpE;AAAA;AAAA;AAAA,EAKA,MAAM,MAAM,MAAA,EAA2C;AACrD,IAAA,IAAI,MAAA,CAAO,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG;AAC9B,MAAA,OAAO,EAAE,OAAA,EAAS,EAAC,EAAG,IAAA,EAAM,EAAC,EAAG,SAAA,EAAW,CAAA,EAAG,eAAA,EAAiB,CAAA,EAAE;AAAA,IACnE;AAEA,IAAA,MAAM,EAAE,MAAM,KAAA,EAAM,GAAI,MAAM,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,MAAA,CAAO,WAAA,EAAa;AAAA,MACxE,IAAA,EAAM,EAAE,MAAA;AAAO,KAChB,CAAA;AAED,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,MAAM,IAAI,kBAAA,CAAmB,CAAA,cAAA,EAAiB,KAAA,CAAM,OAAO,IAAI,aAAa,CAAA;AAAA,IAC9E;AACA,IAAA,IAAI,MAAM,KAAA,EAAO;AACf,MAAA,MAAM,IAAI,kBAAA,CAAmB,IAAA,CAAK,KAAA,EAAO,aAAa,CAAA;AAAA,IACxD;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,YAAY,KAAA,EAA+C;AAC/D,IAAA,MAAM,EAAE,MAAA,EAAO,GAAI,MAAM,KAAK,WAAA,EAAY;AAC1C,IAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,MAAA,CAAO,GAAA,CAAI,CAAC,CAAA,KAAM,CAAC,CAAA,CAAE,IAAA,EAAM,CAAC,CAAC,CAAC,CAAA;AAEvD,IAAA,MAAM,MAAA,GAAS,KAAA,CAAM,OAAA,CAAQ,GAAA,CAAI,CAAC,IAAA,KAAS;AACzC,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAC/B,MAAA,IAAI,CAAC,OAAO,MAAM,IAAI,mBAAmB,CAAA,iBAAA,EAAoB,IAAI,KAAK,eAAe,CAAA;AACrF,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,CAAM,EAAA,EAAI,KAAA,EAAM;AAAA,IACpC,CAAC,CAAA;AAED,IAAA,MAAM,QAAQ,KAAA,CAAM,OAAA,IAAW,EAAC,EAAG,GAAA,CAAI,CAAC,IAAA,KAAS;AAC/C,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAC/B,MAAA,IAAI,CAAC,OAAO,MAAM,IAAI,mBAAmB,CAAA,oBAAA,EAAuB,IAAI,KAAK,eAAe,CAAA;AACxF,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,IAAA,KAAS,gBAAA,GAAmB,MAAM,KAAA,GAAQ,MAAA;AAC9D,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,CAAM,EAAA,EAAI,OAAO,KAAA,EAAM;AAAA,IAC3C,CAAC,CAAA;AAED,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,OAAA,CAAQ,KAAA,CAAM,OAAA,IAAW,EAAE,CAAA,CAAE,GAAA,CAAI,CAAC,CAAC,IAAA,EAAM,YAAY,CAAA,KAAM;AAChF,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAC/B,MAAA,IAAI,CAAC,OAAO,MAAM,IAAI,mBAAmB,CAAA,uBAAA,EAA0B,IAAI,KAAK,eAAe,CAAA;AAC3F,MAAA,OAAO,EAAE,OAAA,EAAS,KAAA,CAAM,EAAA,EAAI,OAAO,YAAA,EAAa;AAAA,IAClD,CAAC,CAAA;AAED,IAAA,OAAO,IAAA,CAAK,MAAM,EAAE,MAAA,EAAQ,MAAM,OAAA,EAAS,EAAC,EAAG,OAAA,EAAS,CAAA;AAAA,EAC1D;AACF;AAEO,IAAM,kBAAA,GAAN,cAAiC,KAAA,CAAM;AAAA,EAE5C,WAAA,CAAY,SAAiB,IAAA,EAAc;AACzC,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,IAAA,GAAO,oBAAA;AACZ,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AAAA,EACd;AACF","file":"chunk-P72N6ISJ.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 /** Send a one-time code to the given email (for iframe/editor sign-in). */\n async sendOtp(email: string) {\n return this.supabase.auth.signInWithOtp({ email });\n }\n\n /** Verify a one-time code received via email. */\n async verifyOtp(email: string, token: string) {\n return this.supabase.auth.verifyOtp({ email, token, type: \"email\" });\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"]}
|
|
@@ -10,13 +10,21 @@ function useSemanticLayer() {
|
|
|
10
10
|
return ctx;
|
|
11
11
|
}
|
|
12
12
|
function useAuth() {
|
|
13
|
-
const { client, auth } = useSemanticLayer();
|
|
13
|
+
const { client, auth, emailDomain } = useSemanticLayer();
|
|
14
14
|
const signIn = useCallback(
|
|
15
15
|
(redirectTo) => client.signInWithGoogle(redirectTo),
|
|
16
16
|
[client]
|
|
17
17
|
);
|
|
18
|
+
const sendOtp = useCallback(
|
|
19
|
+
(email) => client.sendOtp(email),
|
|
20
|
+
[client]
|
|
21
|
+
);
|
|
22
|
+
const verifyOtp = useCallback(
|
|
23
|
+
(email, token) => client.verifyOtp(email, token),
|
|
24
|
+
[client]
|
|
25
|
+
);
|
|
18
26
|
const signOut = useCallback(() => client.signOut(), [client]);
|
|
19
|
-
return { ...auth, signIn, signOut };
|
|
27
|
+
return { ...auth, signIn, sendOtp, verifyOtp, signOut, emailDomain };
|
|
20
28
|
}
|
|
21
29
|
function useMetrics() {
|
|
22
30
|
const { client, auth } = useSemanticLayer();
|
|
@@ -117,5 +125,5 @@ function usePivotQuery(config, options = {}) {
|
|
|
117
125
|
}
|
|
118
126
|
|
|
119
127
|
export { SemanticLayerContext, useAuth, useMetrics, usePivotQuery, useSemanticQuery };
|
|
120
|
-
//# sourceMappingURL=chunk-
|
|
121
|
-
//# sourceMappingURL=chunk-
|
|
128
|
+
//# sourceMappingURL=chunk-RGVYFSW2.js.map
|
|
129
|
+
//# sourceMappingURL=chunk-RGVYFSW2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/context.ts","../src/react/hooks.ts"],"names":[],"mappings":"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","file":"chunk-RGVYFSW2.js","sourcesContent":["import { createContext } from \"react\";\nimport type { SemanticLayerClient } from \"../client\";\nimport type { AuthState } from \"../types\";\n\nexport interface SemanticLayerContextValue {\n client: SemanticLayerClient;\n auth: AuthState;\n emailDomain?: string;\n}\n\nexport const SemanticLayerContext = createContext<SemanticLayerContextValue | null>(null);\n","import { useContext, useCallback, useEffect, useState, useRef } from \"react\";\nimport { SemanticLayerContext } from \"./context\";\nimport type {\n SemanticField,\n FieldCategory,\n QueryResult,\n SimpleQueryInput,\n PivotConfig,\n AuthState,\n} from \"../types\";\n\nfunction useSemanticLayer() {\n const ctx = useContext(SemanticLayerContext);\n if (!ctx) {\n throw new Error(\"useSemanticLayer hooks must be used within a <SemanticLayerProvider>\");\n }\n return ctx;\n}\n\n/** Returns the current auth state and sign-in/sign-out methods. */\nexport function useAuth() {\n const { client, auth, emailDomain } = useSemanticLayer();\n\n const signIn = useCallback(\n (redirectTo?: string) => client.signInWithGoogle(redirectTo),\n [client],\n );\n\n const sendOtp = useCallback(\n (email: string) => client.sendOtp(email),\n [client],\n );\n\n const verifyOtp = useCallback(\n (email: string, token: string) => client.verifyOtp(email, token),\n [client],\n );\n\n const signOut = useCallback(() => client.signOut(), [client]);\n\n return { ...auth, signIn, sendOtp, verifyOtp, signOut, emailDomain };\n}\n\ninterface UseMetricsResult {\n fields: SemanticField[];\n metrics: SemanticField[];\n dimensions: SemanticField[];\n categories: FieldCategory[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\n/** Fetch the full curated catalog of metrics and dimensions. */\nexport function useMetrics(): UseMetricsResult {\n const { client, auth } = useSemanticLayer();\n const [fields, setFields] = useState<SemanticField[]>([]);\n const [categories, setCategories] = useState<FieldCategory[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const fetchedRef = useRef(false);\n\n const fetch = useCallback(\n async (force = false) => {\n if (!auth.isAuthenticated) return;\n setIsLoading(true);\n setError(null);\n try {\n const data = await client.getMetadata(force);\n setFields(data.fields);\n setCategories(data.categories);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load metadata\");\n } finally {\n setIsLoading(false);\n }\n },\n [client, auth.isAuthenticated],\n );\n\n useEffect(() => {\n if (auth.isAuthenticated && !fetchedRef.current) {\n fetchedRef.current = true;\n fetch();\n }\n }, [auth.isAuthenticated, fetch]);\n\n const refetch = useCallback(() => fetch(true), [fetch]);\n\n return {\n fields,\n metrics: fields.filter((f) => f.type === \"metric\"),\n dimensions: fields.filter((f) => f.type === \"dimension\" || f.type === \"time_dimension\"),\n categories,\n isLoading,\n error,\n refetch,\n };\n}\n\ninterface UseSemanticQueryOptions {\n /** Set to false to prevent the query from running automatically. */\n enabled?: boolean;\n}\n\ninterface UseSemanticQueryResult {\n data: QueryResult | null;\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\n/**\n * Execute a query against the dbt Semantic Layer using the simple input format.\n * The query runs automatically when the input changes (unless enabled=false).\n */\nexport function useSemanticQuery(\n input: SimpleQueryInput | null,\n options: UseSemanticQueryOptions = {},\n): UseSemanticQueryResult {\n const { client, auth } = useSemanticLayer();\n const { enabled = true } = options;\n const [data, setData] = useState<QueryResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const inputKey = JSON.stringify(input);\n\n const execute = useCallback(async () => {\n if (!auth.isAuthenticated || !input || !enabled) return;\n if (input.metrics.length === 0) {\n setData({ columns: [], rows: [], totalRows: 0, executionTimeMs: 0 });\n return;\n }\n\n setIsLoading(true);\n setError(null);\n try {\n const result = await client.simpleQuery(input);\n setData(result);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Query failed\");\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, auth.isAuthenticated, inputKey, enabled]);\n\n useEffect(() => {\n execute();\n }, [execute]);\n\n return { data, isLoading, error, refetch: execute };\n}\n\n/**\n * Execute a query using the full PivotConfig format.\n * Use this for advanced use cases (column pivoting, custom aggregations).\n */\nexport function usePivotQuery(\n config: PivotConfig | null,\n options: UseSemanticQueryOptions = {},\n): UseSemanticQueryResult {\n const { client, auth } = useSemanticLayer();\n const { enabled = true } = options;\n const [data, setData] = useState<QueryResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const configKey = JSON.stringify(config);\n\n const execute = useCallback(async () => {\n if (!auth.isAuthenticated || !config || !enabled) return;\n\n setIsLoading(true);\n setError(null);\n try {\n const result = await client.query(config);\n setData(result);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Query failed\");\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, auth.isAuthenticated, configKey, enabled]);\n\n useEffect(() => {\n execute();\n }, [execute]);\n\n return { data, isLoading, error, refetch: execute };\n}\n"]}
|
package/dist/components.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkOJVM3RPD_cjs = require('./chunk-OJVM3RPD.cjs');
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
6
6
|
|
|
@@ -56,7 +56,7 @@ function MetricPicker({
|
|
|
56
56
|
searchPlaceholder = "Search metrics and dimensions...",
|
|
57
57
|
className
|
|
58
58
|
}) {
|
|
59
|
-
const { fields, categories, isLoading, error } =
|
|
59
|
+
const { fields, categories, isLoading, error } = chunkOJVM3RPD_cjs.useMetrics();
|
|
60
60
|
const [search, setSearch] = react.useState("");
|
|
61
61
|
const filtered = react.useMemo(() => {
|
|
62
62
|
let result = fields;
|
package/dist/components.js
CHANGED
package/dist/index.cjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkI4L4FFJY_cjs = require('./chunk-I4L4FFJY.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 chunkI4L4FFJY_cjs.SemanticLayerClient; }
|
|
10
10
|
});
|
|
11
11
|
Object.defineProperty(exports, "SemanticLayerError", {
|
|
12
12
|
enumerable: true,
|
|
13
|
-
get: function () { return
|
|
13
|
+
get: function () { return chunkI4L4FFJY_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,17 @@ 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>;
|
|
18
|
+
/** Send a one-time code to the given email (for iframe/editor sign-in). */
|
|
19
|
+
sendOtp(email: string): Promise<_supabase_auth_js.AuthOtpResponse>;
|
|
20
|
+
/** Verify a one-time code received via email. */
|
|
21
|
+
verifyOtp(email: string, token: string): Promise<_supabase_auth_js.AuthResponse>;
|
|
15
22
|
signOut(): Promise<{
|
|
16
23
|
error: _supabase_auth_js.AuthError | null;
|
|
17
24
|
}>;
|
package/dist/index.d.ts
CHANGED
|
@@ -8,10 +8,17 @@ 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>;
|
|
18
|
+
/** Send a one-time code to the given email (for iframe/editor sign-in). */
|
|
19
|
+
sendOtp(email: string): Promise<_supabase_auth_js.AuthOtpResponse>;
|
|
20
|
+
/** Verify a one-time code received via email. */
|
|
21
|
+
verifyOtp(email: string, token: string): Promise<_supabase_auth_js.AuthResponse>;
|
|
15
22
|
signOut(): Promise<{
|
|
16
23
|
error: _supabase_auth_js.AuthError | null;
|
|
17
24
|
}>;
|
package/dist/index.js
CHANGED
package/dist/react.cjs
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
3
|
+
var chunkI4L4FFJY_cjs = require('./chunk-I4L4FFJY.cjs');
|
|
4
|
+
var chunkOJVM3RPD_cjs = require('./chunk-OJVM3RPD.cjs');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
7
|
|
|
8
8
|
function SemanticLayerProvider({
|
|
9
9
|
gatewayUrl,
|
|
10
10
|
anonKey,
|
|
11
|
+
emailDomain,
|
|
11
12
|
client: externalClient,
|
|
12
13
|
children
|
|
13
14
|
}) {
|
|
14
15
|
const client = react.useMemo(() => {
|
|
15
16
|
if (externalClient) return externalClient;
|
|
16
|
-
return new
|
|
17
|
+
return new chunkI4L4FFJY_cjs.SemanticLayerClient({ gatewayUrl, anonKey });
|
|
17
18
|
}, [gatewayUrl, anonKey, externalClient]);
|
|
18
19
|
const [auth, setAuth] = react.useState({
|
|
19
20
|
isAuthenticated: false,
|
|
@@ -76,27 +77,27 @@ function SemanticLayerProvider({
|
|
|
76
77
|
subscription.unsubscribe();
|
|
77
78
|
};
|
|
78
79
|
}, [client]);
|
|
79
|
-
const value = react.useMemo(() => ({ client, auth }), [client, auth]);
|
|
80
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
80
|
+
const value = react.useMemo(() => ({ client, auth, emailDomain }), [client, auth, emailDomain]);
|
|
81
|
+
return /* @__PURE__ */ jsxRuntime.jsx(chunkOJVM3RPD_cjs.SemanticLayerContext.Provider, { value, children });
|
|
81
82
|
}
|
|
82
|
-
var
|
|
83
|
+
var containerStyle = {
|
|
83
84
|
display: "flex",
|
|
85
|
+
flexDirection: "column",
|
|
84
86
|
alignItems: "center",
|
|
85
87
|
justifyContent: "center",
|
|
86
88
|
minHeight: "100vh",
|
|
87
89
|
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
88
|
-
|
|
90
|
+
gap: "16px"
|
|
89
91
|
};
|
|
90
|
-
var
|
|
92
|
+
var loadingStyle = {
|
|
91
93
|
display: "flex",
|
|
92
|
-
flexDirection: "column",
|
|
93
94
|
alignItems: "center",
|
|
94
95
|
justifyContent: "center",
|
|
95
96
|
minHeight: "100vh",
|
|
96
97
|
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
97
|
-
|
|
98
|
+
color: "#6b7280"
|
|
98
99
|
};
|
|
99
|
-
var
|
|
100
|
+
var buttonStyle = {
|
|
100
101
|
padding: "12px 24px",
|
|
101
102
|
fontSize: "16px",
|
|
102
103
|
fontWeight: 500,
|
|
@@ -109,20 +110,155 @@ var defaultButtonStyle = {
|
|
|
109
110
|
alignItems: "center",
|
|
110
111
|
gap: "8px"
|
|
111
112
|
};
|
|
113
|
+
var inputStyle = {
|
|
114
|
+
padding: "10px 14px",
|
|
115
|
+
fontSize: "16px",
|
|
116
|
+
border: "1px solid #d1d5db",
|
|
117
|
+
borderRadius: "8px",
|
|
118
|
+
width: "280px",
|
|
119
|
+
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
120
|
+
};
|
|
121
|
+
var errorStyle = {
|
|
122
|
+
margin: 0,
|
|
123
|
+
color: "#ef4444",
|
|
124
|
+
fontSize: "14px"
|
|
125
|
+
};
|
|
126
|
+
var linkStyle = {
|
|
127
|
+
background: "none",
|
|
128
|
+
border: "none",
|
|
129
|
+
color: "#4285f4",
|
|
130
|
+
cursor: "pointer",
|
|
131
|
+
fontSize: "14px",
|
|
132
|
+
padding: 0,
|
|
133
|
+
textDecoration: "underline"
|
|
134
|
+
};
|
|
135
|
+
function isInIframe() {
|
|
136
|
+
try {
|
|
137
|
+
return typeof window !== "undefined" && window.self !== window.top;
|
|
138
|
+
} catch {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function OtpSignIn() {
|
|
143
|
+
const { sendOtp, verifyOtp, emailDomain } = chunkOJVM3RPD_cjs.useAuth();
|
|
144
|
+
const [email, setEmail] = react.useState("");
|
|
145
|
+
const [code, setCode] = react.useState("");
|
|
146
|
+
const [step, setStep] = react.useState("email");
|
|
147
|
+
const [sending, setSending] = react.useState(false);
|
|
148
|
+
const [error, setError] = react.useState(null);
|
|
149
|
+
const handleSendCode = react.useCallback(async () => {
|
|
150
|
+
setError(null);
|
|
151
|
+
const trimmed = email.trim().toLowerCase();
|
|
152
|
+
if (!trimmed) {
|
|
153
|
+
setError("Please enter your email.");
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (emailDomain && !trimmed.endsWith(`@${emailDomain}`)) {
|
|
157
|
+
setError(`Please use your @${emailDomain} email.`);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
setSending(true);
|
|
161
|
+
try {
|
|
162
|
+
const { error: otpError } = await sendOtp(trimmed);
|
|
163
|
+
if (otpError) {
|
|
164
|
+
setError(otpError.message);
|
|
165
|
+
} else {
|
|
166
|
+
setStep("code");
|
|
167
|
+
}
|
|
168
|
+
} catch (err) {
|
|
169
|
+
setError(err instanceof Error ? err.message : "Failed to send code");
|
|
170
|
+
} finally {
|
|
171
|
+
setSending(false);
|
|
172
|
+
}
|
|
173
|
+
}, [email, emailDomain, sendOtp]);
|
|
174
|
+
const handleVerifyCode = react.useCallback(async () => {
|
|
175
|
+
setError(null);
|
|
176
|
+
const trimmedCode = code.trim();
|
|
177
|
+
if (!trimmedCode) {
|
|
178
|
+
setError("Please enter the code from your email.");
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
setSending(true);
|
|
182
|
+
try {
|
|
183
|
+
const { error: verifyError } = await verifyOtp(email.trim().toLowerCase(), trimmedCode);
|
|
184
|
+
if (verifyError) {
|
|
185
|
+
setError(verifyError.message);
|
|
186
|
+
}
|
|
187
|
+
} catch (err) {
|
|
188
|
+
setError(err instanceof Error ? err.message : "Verification failed");
|
|
189
|
+
} finally {
|
|
190
|
+
setSending(false);
|
|
191
|
+
}
|
|
192
|
+
}, [email, code, verifyOtp]);
|
|
193
|
+
if (step === "code") {
|
|
194
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
|
|
195
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: "24px", color: "#111827" }, children: "Check your email" }),
|
|
196
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: { margin: 0, color: "#6b7280", textAlign: "center", maxWidth: "320px" }, children: [
|
|
197
|
+
"We sent a sign-in code to ",
|
|
198
|
+
/* @__PURE__ */ jsxRuntime.jsx("strong", { children: email.trim() })
|
|
199
|
+
] }),
|
|
200
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
201
|
+
"input",
|
|
202
|
+
{
|
|
203
|
+
style: inputStyle,
|
|
204
|
+
type: "text",
|
|
205
|
+
inputMode: "numeric",
|
|
206
|
+
autoComplete: "one-time-code",
|
|
207
|
+
placeholder: "Enter 6-digit code",
|
|
208
|
+
value: code,
|
|
209
|
+
onChange: (e) => setCode(e.target.value),
|
|
210
|
+
onKeyDown: (e) => e.key === "Enter" && handleVerifyCode()
|
|
211
|
+
}
|
|
212
|
+
),
|
|
213
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: errorStyle, children: error }),
|
|
214
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: buttonStyle, onClick: handleVerifyCode, disabled: sending, children: sending ? "Verifying..." : "Verify code" }),
|
|
215
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: linkStyle, onClick: () => {
|
|
216
|
+
setStep("email");
|
|
217
|
+
setCode("");
|
|
218
|
+
setError(null);
|
|
219
|
+
}, children: "Use a different email" })
|
|
220
|
+
] });
|
|
221
|
+
}
|
|
222
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
|
|
223
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: "24px", color: "#111827" }, children: "Sign in to continue" }),
|
|
224
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { style: { margin: 0, color: "#6b7280" }, children: [
|
|
225
|
+
"Enter your ",
|
|
226
|
+
emailDomain ? `@${emailDomain} ` : "",
|
|
227
|
+
"email to receive a sign-in code."
|
|
228
|
+
] }),
|
|
229
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
230
|
+
"input",
|
|
231
|
+
{
|
|
232
|
+
style: inputStyle,
|
|
233
|
+
type: "email",
|
|
234
|
+
placeholder: emailDomain ? `you@${emailDomain}` : "you@company.com",
|
|
235
|
+
value: email,
|
|
236
|
+
onChange: (e) => setEmail(e.target.value),
|
|
237
|
+
onKeyDown: (e) => e.key === "Enter" && handleSendCode()
|
|
238
|
+
}
|
|
239
|
+
),
|
|
240
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: errorStyle, children: error }),
|
|
241
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: buttonStyle, onClick: handleSendCode, disabled: sending, children: sending ? "Sending..." : "Send sign-in code" })
|
|
242
|
+
] });
|
|
243
|
+
}
|
|
112
244
|
function AuthGate({ children, loading, signInComponent }) {
|
|
113
|
-
const { isAuthenticated, isLoading, error, signIn
|
|
245
|
+
const { isAuthenticated, isLoading, error, signIn } = chunkOJVM3RPD_cjs.useAuth();
|
|
246
|
+
const inIframe = isInIframe();
|
|
114
247
|
if (isLoading) {
|
|
115
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: loading || /* @__PURE__ */ jsxRuntime.jsx("div", { style:
|
|
248
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: loading || /* @__PURE__ */ jsxRuntime.jsx("div", { style: loadingStyle, children: "Loading..." }) });
|
|
116
249
|
}
|
|
117
250
|
if (!isAuthenticated) {
|
|
251
|
+
if (inIframe) {
|
|
252
|
+
return /* @__PURE__ */ jsxRuntime.jsx(OtpSignIn, {});
|
|
253
|
+
}
|
|
118
254
|
if (signInComponent) {
|
|
119
255
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: signInComponent({ signIn: () => signIn(window.location.origin) }) });
|
|
120
256
|
}
|
|
121
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style:
|
|
257
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: containerStyle, children: [
|
|
122
258
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: "24px", color: "#111827" }, children: "Sign in to continue" }),
|
|
123
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, color: "#6b7280" }, children: "Use your
|
|
124
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style:
|
|
125
|
-
/* @__PURE__ */ jsxRuntime.jsx("button", { style:
|
|
259
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { style: { margin: 0, color: "#6b7280" }, children: "Use your Google account to access data." }),
|
|
260
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("p", { style: errorStyle, children: error }),
|
|
261
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { style: buttonStyle, onClick: () => signIn(window.location.origin), children: "Sign in with Google" })
|
|
126
262
|
] });
|
|
127
263
|
}
|
|
128
264
|
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
@@ -130,23 +266,23 @@ function AuthGate({ children, loading, signInComponent }) {
|
|
|
130
266
|
|
|
131
267
|
Object.defineProperty(exports, "SemanticLayerContext", {
|
|
132
268
|
enumerable: true,
|
|
133
|
-
get: function () { return
|
|
269
|
+
get: function () { return chunkOJVM3RPD_cjs.SemanticLayerContext; }
|
|
134
270
|
});
|
|
135
271
|
Object.defineProperty(exports, "useAuth", {
|
|
136
272
|
enumerable: true,
|
|
137
|
-
get: function () { return
|
|
273
|
+
get: function () { return chunkOJVM3RPD_cjs.useAuth; }
|
|
138
274
|
});
|
|
139
275
|
Object.defineProperty(exports, "useMetrics", {
|
|
140
276
|
enumerable: true,
|
|
141
|
-
get: function () { return
|
|
277
|
+
get: function () { return chunkOJVM3RPD_cjs.useMetrics; }
|
|
142
278
|
});
|
|
143
279
|
Object.defineProperty(exports, "usePivotQuery", {
|
|
144
280
|
enumerable: true,
|
|
145
|
-
get: function () { return
|
|
281
|
+
get: function () { return chunkOJVM3RPD_cjs.usePivotQuery; }
|
|
146
282
|
});
|
|
147
283
|
Object.defineProperty(exports, "useSemanticQuery", {
|
|
148
284
|
enumerable: true,
|
|
149
|
-
get: function () { return
|
|
285
|
+
get: function () { return chunkOJVM3RPD_cjs.useSemanticQuery; }
|
|
150
286
|
});
|
|
151
287
|
exports.AuthGate = AuthGate;
|
|
152
288
|
exports.SemanticLayerProvider = SemanticLayerProvider;
|
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(window.location.origin) })}</>;\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(window.location.origin)}>\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","useCallback","jsxs","Fragment"],"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: restrict sign-in to emails matching this domain (e.g. \"inkind.com\").\n * Used for client-side validation in the OTP sign-in form.\n */\n emailDomain?: 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 emailDomain,\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, emailDomain }), [client, auth, emailDomain]);\n\n return (\n <SemanticLayerContext.Provider value={value}>\n {children}\n </SemanticLayerContext.Provider>\n );\n}\n","import React, { useCallback, useState } 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 containerStyle: 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 loadingStyle: 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 buttonStyle: 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\nconst inputStyle: React.CSSProperties = {\n padding: \"10px 14px\",\n fontSize: \"16px\",\n border: \"1px solid #d1d5db\",\n borderRadius: \"8px\",\n width: \"280px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n};\n\nconst errorStyle: React.CSSProperties = {\n margin: 0,\n color: \"#ef4444\",\n fontSize: \"14px\",\n};\n\nconst linkStyle: React.CSSProperties = {\n background: \"none\",\n border: \"none\",\n color: \"#4285f4\",\n cursor: \"pointer\",\n fontSize: \"14px\",\n padding: 0,\n textDecoration: \"underline\",\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 * Email OTP sign-in form for use inside iframes (Lovable editor preview).\n * Two-step: enter email → enter code from inbox.\n */\nfunction OtpSignIn() {\n const { sendOtp, verifyOtp, emailDomain } = useAuth();\n const [email, setEmail] = useState(\"\");\n const [code, setCode] = useState(\"\");\n const [step, setStep] = useState<\"email\" | \"code\">(\"email\");\n const [sending, setSending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleSendCode = useCallback(async () => {\n setError(null);\n const trimmed = email.trim().toLowerCase();\n if (!trimmed) {\n setError(\"Please enter your email.\");\n return;\n }\n if (emailDomain && !trimmed.endsWith(`@${emailDomain}`)) {\n setError(`Please use your @${emailDomain} email.`);\n return;\n }\n setSending(true);\n try {\n const { error: otpError } = await sendOtp(trimmed);\n if (otpError) {\n setError(otpError.message);\n } else {\n setStep(\"code\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to send code\");\n } finally {\n setSending(false);\n }\n }, [email, emailDomain, sendOtp]);\n\n const handleVerifyCode = useCallback(async () => {\n setError(null);\n const trimmedCode = code.trim();\n if (!trimmedCode) {\n setError(\"Please enter the code from your email.\");\n return;\n }\n setSending(true);\n try {\n const { error: verifyError } = await verifyOtp(email.trim().toLowerCase(), trimmedCode);\n if (verifyError) {\n setError(verifyError.message);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Verification failed\");\n } finally {\n setSending(false);\n }\n }, [email, code, verifyOtp]);\n\n if (step === \"code\") {\n return (\n <div style={containerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Check your email</h2>\n <p style={{ margin: 0, color: \"#6b7280\", textAlign: \"center\", maxWidth: \"320px\" }}>\n We sent a sign-in code to <strong>{email.trim()}</strong>\n </p>\n <input\n style={inputStyle}\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n placeholder=\"Enter 6-digit code\"\n value={code}\n onChange={(e) => setCode(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && handleVerifyCode()}\n />\n {error && <p style={errorStyle}>{error}</p>}\n <button style={buttonStyle} onClick={handleVerifyCode} disabled={sending}>\n {sending ? \"Verifying...\" : \"Verify code\"}\n </button>\n <button style={linkStyle} onClick={() => { setStep(\"email\"); setCode(\"\"); setError(null); }}>\n Use a different email\n </button>\n </div>\n );\n }\n\n return (\n <div style={containerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Sign in to continue</h2>\n <p style={{ margin: 0, color: \"#6b7280\" }}>\n Enter your {emailDomain ? `@${emailDomain} ` : \"\"}email to receive a sign-in code.\n </p>\n <input\n style={inputStyle}\n type=\"email\"\n placeholder={emailDomain ? `you@${emailDomain}` : \"you@company.com\"}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && handleSendCode()}\n />\n {error && <p style={errorStyle}>{error}</p>}\n <button style={buttonStyle} onClick={handleSendCode} disabled={sending}>\n {sending ? \"Sending...\" : \"Send sign-in code\"}\n </button>\n </div>\n );\n}\n\n/**\n * Wraps children and only renders them when the user is authenticated.\n * In iframes (e.g. Lovable editor preview), shows an email OTP form.\n * In standalone tabs, shows the Google OAuth sign-in button.\n */\nexport function AuthGate({ children, loading, signInComponent }: AuthGateProps) {\n const { isAuthenticated, isLoading, error, signIn } = useAuth();\n const inIframe = isInIframe();\n\n if (isLoading) {\n return <>{loading || <div style={loadingStyle}>Loading...</div>}</>;\n }\n\n if (!isAuthenticated) {\n if (inIframe) {\n return <OtpSignIn />;\n }\n\n if (signInComponent) {\n return <>{signInComponent({ signIn: () => signIn(window.location.origin) })}</>;\n }\n\n return (\n <div style={containerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Sign in to continue</h2>\n <p style={{ margin: 0, color: \"#6b7280\" }}>\n Use your Google account to access data.\n </p>\n {error && <p style={errorStyle}>{error}</p>}\n <button style={buttonStyle} onClick={() => signIn(window.location.origin)}>\n Sign in with Google\n </button>\n </div>\n );\n }\n\n return <>{children}</>;\n}\n"]}
|
package/dist/react.d.cts
CHANGED
|
@@ -11,6 +11,11 @@ interface SemanticLayerProviderProps {
|
|
|
11
11
|
gatewayUrl: string;
|
|
12
12
|
/** The Supabase anon/publishable key of the gateway project. */
|
|
13
13
|
anonKey: string;
|
|
14
|
+
/**
|
|
15
|
+
* Optional: restrict sign-in to emails matching this domain (e.g. "inkind.com").
|
|
16
|
+
* Used for client-side validation in the OTP sign-in form.
|
|
17
|
+
*/
|
|
18
|
+
emailDomain?: string;
|
|
14
19
|
/**
|
|
15
20
|
* Optional: a pre-constructed client instance.
|
|
16
21
|
* If provided, gatewayUrl and anonKey are ignored.
|
|
@@ -18,7 +23,7 @@ interface SemanticLayerProviderProps {
|
|
|
18
23
|
client?: SemanticLayerClient;
|
|
19
24
|
children: React__default.ReactNode;
|
|
20
25
|
}
|
|
21
|
-
declare function SemanticLayerProvider({ gatewayUrl, anonKey, client: externalClient, children, }: SemanticLayerProviderProps): react_jsx_runtime.JSX.Element;
|
|
26
|
+
declare function SemanticLayerProvider({ gatewayUrl, anonKey, emailDomain, client: externalClient, children, }: SemanticLayerProviderProps): react_jsx_runtime.JSX.Element;
|
|
22
27
|
|
|
23
28
|
interface AuthGateProps {
|
|
24
29
|
children: React__default.ReactNode;
|
|
@@ -31,16 +36,20 @@ interface AuthGateProps {
|
|
|
31
36
|
}
|
|
32
37
|
/**
|
|
33
38
|
* Wraps children and only renders them when the user is authenticated.
|
|
34
|
-
*
|
|
39
|
+
* In iframes (e.g. Lovable editor preview), shows an email OTP form.
|
|
40
|
+
* In standalone tabs, shows the Google OAuth sign-in button.
|
|
35
41
|
*/
|
|
36
42
|
declare function AuthGate({ children, loading, signInComponent }: AuthGateProps): react_jsx_runtime.JSX.Element;
|
|
37
43
|
|
|
38
44
|
/** Returns the current auth state and sign-in/sign-out methods. */
|
|
39
45
|
declare function useAuth(): {
|
|
40
46
|
signIn: (redirectTo?: string) => Promise<_supabase_auth_js.OAuthResponse>;
|
|
47
|
+
sendOtp: (email: string) => Promise<_supabase_auth_js.AuthOtpResponse>;
|
|
48
|
+
verifyOtp: (email: string, token: string) => Promise<_supabase_auth_js.AuthResponse>;
|
|
41
49
|
signOut: () => Promise<{
|
|
42
50
|
error: _supabase_auth_js.AuthError | null;
|
|
43
51
|
}>;
|
|
52
|
+
emailDomain: string | undefined;
|
|
44
53
|
isAuthenticated: boolean;
|
|
45
54
|
isLoading: boolean;
|
|
46
55
|
user: {
|
|
@@ -84,6 +93,7 @@ declare function usePivotQuery(config: PivotConfig | null, options?: UseSemantic
|
|
|
84
93
|
interface SemanticLayerContextValue {
|
|
85
94
|
client: SemanticLayerClient;
|
|
86
95
|
auth: AuthState;
|
|
96
|
+
emailDomain?: string;
|
|
87
97
|
}
|
|
88
98
|
declare const SemanticLayerContext: React.Context<SemanticLayerContextValue | null>;
|
|
89
99
|
|
package/dist/react.d.ts
CHANGED
|
@@ -11,6 +11,11 @@ interface SemanticLayerProviderProps {
|
|
|
11
11
|
gatewayUrl: string;
|
|
12
12
|
/** The Supabase anon/publishable key of the gateway project. */
|
|
13
13
|
anonKey: string;
|
|
14
|
+
/**
|
|
15
|
+
* Optional: restrict sign-in to emails matching this domain (e.g. "inkind.com").
|
|
16
|
+
* Used for client-side validation in the OTP sign-in form.
|
|
17
|
+
*/
|
|
18
|
+
emailDomain?: string;
|
|
14
19
|
/**
|
|
15
20
|
* Optional: a pre-constructed client instance.
|
|
16
21
|
* If provided, gatewayUrl and anonKey are ignored.
|
|
@@ -18,7 +23,7 @@ interface SemanticLayerProviderProps {
|
|
|
18
23
|
client?: SemanticLayerClient;
|
|
19
24
|
children: React__default.ReactNode;
|
|
20
25
|
}
|
|
21
|
-
declare function SemanticLayerProvider({ gatewayUrl, anonKey, client: externalClient, children, }: SemanticLayerProviderProps): react_jsx_runtime.JSX.Element;
|
|
26
|
+
declare function SemanticLayerProvider({ gatewayUrl, anonKey, emailDomain, client: externalClient, children, }: SemanticLayerProviderProps): react_jsx_runtime.JSX.Element;
|
|
22
27
|
|
|
23
28
|
interface AuthGateProps {
|
|
24
29
|
children: React__default.ReactNode;
|
|
@@ -31,16 +36,20 @@ interface AuthGateProps {
|
|
|
31
36
|
}
|
|
32
37
|
/**
|
|
33
38
|
* Wraps children and only renders them when the user is authenticated.
|
|
34
|
-
*
|
|
39
|
+
* In iframes (e.g. Lovable editor preview), shows an email OTP form.
|
|
40
|
+
* In standalone tabs, shows the Google OAuth sign-in button.
|
|
35
41
|
*/
|
|
36
42
|
declare function AuthGate({ children, loading, signInComponent }: AuthGateProps): react_jsx_runtime.JSX.Element;
|
|
37
43
|
|
|
38
44
|
/** Returns the current auth state and sign-in/sign-out methods. */
|
|
39
45
|
declare function useAuth(): {
|
|
40
46
|
signIn: (redirectTo?: string) => Promise<_supabase_auth_js.OAuthResponse>;
|
|
47
|
+
sendOtp: (email: string) => Promise<_supabase_auth_js.AuthOtpResponse>;
|
|
48
|
+
verifyOtp: (email: string, token: string) => Promise<_supabase_auth_js.AuthResponse>;
|
|
41
49
|
signOut: () => Promise<{
|
|
42
50
|
error: _supabase_auth_js.AuthError | null;
|
|
43
51
|
}>;
|
|
52
|
+
emailDomain: string | undefined;
|
|
44
53
|
isAuthenticated: boolean;
|
|
45
54
|
isLoading: boolean;
|
|
46
55
|
user: {
|
|
@@ -84,6 +93,7 @@ declare function usePivotQuery(config: PivotConfig | null, options?: UseSemantic
|
|
|
84
93
|
interface SemanticLayerContextValue {
|
|
85
94
|
client: SemanticLayerClient;
|
|
86
95
|
auth: AuthState;
|
|
96
|
+
emailDomain?: string;
|
|
87
97
|
}
|
|
88
98
|
declare const SemanticLayerContext: React.Context<SemanticLayerContextValue | null>;
|
|
89
99
|
|
package/dist/react.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { SemanticLayerClient } from './chunk-
|
|
2
|
-
import { SemanticLayerContext, useAuth } from './chunk-
|
|
3
|
-
export { SemanticLayerContext, useAuth, useMetrics, usePivotQuery, useSemanticQuery } from './chunk-
|
|
4
|
-
import { useMemo, useState, useEffect } from 'react';
|
|
1
|
+
import { SemanticLayerClient } from './chunk-P72N6ISJ.js';
|
|
2
|
+
import { SemanticLayerContext, useAuth } from './chunk-RGVYFSW2.js';
|
|
3
|
+
export { SemanticLayerContext, useAuth, useMetrics, usePivotQuery, useSemanticQuery } from './chunk-RGVYFSW2.js';
|
|
4
|
+
import { useMemo, useState, useEffect, useCallback } from 'react';
|
|
5
5
|
import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
function SemanticLayerProvider({
|
|
8
8
|
gatewayUrl,
|
|
9
9
|
anonKey,
|
|
10
|
+
emailDomain,
|
|
10
11
|
client: externalClient,
|
|
11
12
|
children
|
|
12
13
|
}) {
|
|
@@ -75,27 +76,27 @@ function SemanticLayerProvider({
|
|
|
75
76
|
subscription.unsubscribe();
|
|
76
77
|
};
|
|
77
78
|
}, [client]);
|
|
78
|
-
const value = useMemo(() => ({ client, auth }), [client, auth]);
|
|
79
|
+
const value = useMemo(() => ({ client, auth, emailDomain }), [client, auth, emailDomain]);
|
|
79
80
|
return /* @__PURE__ */ jsx(SemanticLayerContext.Provider, { value, children });
|
|
80
81
|
}
|
|
81
|
-
var
|
|
82
|
+
var containerStyle = {
|
|
82
83
|
display: "flex",
|
|
84
|
+
flexDirection: "column",
|
|
83
85
|
alignItems: "center",
|
|
84
86
|
justifyContent: "center",
|
|
85
87
|
minHeight: "100vh",
|
|
86
88
|
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
87
|
-
|
|
89
|
+
gap: "16px"
|
|
88
90
|
};
|
|
89
|
-
var
|
|
91
|
+
var loadingStyle = {
|
|
90
92
|
display: "flex",
|
|
91
|
-
flexDirection: "column",
|
|
92
93
|
alignItems: "center",
|
|
93
94
|
justifyContent: "center",
|
|
94
95
|
minHeight: "100vh",
|
|
95
96
|
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
96
|
-
|
|
97
|
+
color: "#6b7280"
|
|
97
98
|
};
|
|
98
|
-
var
|
|
99
|
+
var buttonStyle = {
|
|
99
100
|
padding: "12px 24px",
|
|
100
101
|
fontSize: "16px",
|
|
101
102
|
fontWeight: 500,
|
|
@@ -108,20 +109,155 @@ var defaultButtonStyle = {
|
|
|
108
109
|
alignItems: "center",
|
|
109
110
|
gap: "8px"
|
|
110
111
|
};
|
|
112
|
+
var inputStyle = {
|
|
113
|
+
padding: "10px 14px",
|
|
114
|
+
fontSize: "16px",
|
|
115
|
+
border: "1px solid #d1d5db",
|
|
116
|
+
borderRadius: "8px",
|
|
117
|
+
width: "280px",
|
|
118
|
+
fontFamily: "system-ui, -apple-system, sans-serif"
|
|
119
|
+
};
|
|
120
|
+
var errorStyle = {
|
|
121
|
+
margin: 0,
|
|
122
|
+
color: "#ef4444",
|
|
123
|
+
fontSize: "14px"
|
|
124
|
+
};
|
|
125
|
+
var linkStyle = {
|
|
126
|
+
background: "none",
|
|
127
|
+
border: "none",
|
|
128
|
+
color: "#4285f4",
|
|
129
|
+
cursor: "pointer",
|
|
130
|
+
fontSize: "14px",
|
|
131
|
+
padding: 0,
|
|
132
|
+
textDecoration: "underline"
|
|
133
|
+
};
|
|
134
|
+
function isInIframe() {
|
|
135
|
+
try {
|
|
136
|
+
return typeof window !== "undefined" && window.self !== window.top;
|
|
137
|
+
} catch {
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function OtpSignIn() {
|
|
142
|
+
const { sendOtp, verifyOtp, emailDomain } = useAuth();
|
|
143
|
+
const [email, setEmail] = useState("");
|
|
144
|
+
const [code, setCode] = useState("");
|
|
145
|
+
const [step, setStep] = useState("email");
|
|
146
|
+
const [sending, setSending] = useState(false);
|
|
147
|
+
const [error, setError] = useState(null);
|
|
148
|
+
const handleSendCode = useCallback(async () => {
|
|
149
|
+
setError(null);
|
|
150
|
+
const trimmed = email.trim().toLowerCase();
|
|
151
|
+
if (!trimmed) {
|
|
152
|
+
setError("Please enter your email.");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (emailDomain && !trimmed.endsWith(`@${emailDomain}`)) {
|
|
156
|
+
setError(`Please use your @${emailDomain} email.`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
setSending(true);
|
|
160
|
+
try {
|
|
161
|
+
const { error: otpError } = await sendOtp(trimmed);
|
|
162
|
+
if (otpError) {
|
|
163
|
+
setError(otpError.message);
|
|
164
|
+
} else {
|
|
165
|
+
setStep("code");
|
|
166
|
+
}
|
|
167
|
+
} catch (err) {
|
|
168
|
+
setError(err instanceof Error ? err.message : "Failed to send code");
|
|
169
|
+
} finally {
|
|
170
|
+
setSending(false);
|
|
171
|
+
}
|
|
172
|
+
}, [email, emailDomain, sendOtp]);
|
|
173
|
+
const handleVerifyCode = useCallback(async () => {
|
|
174
|
+
setError(null);
|
|
175
|
+
const trimmedCode = code.trim();
|
|
176
|
+
if (!trimmedCode) {
|
|
177
|
+
setError("Please enter the code from your email.");
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
setSending(true);
|
|
181
|
+
try {
|
|
182
|
+
const { error: verifyError } = await verifyOtp(email.trim().toLowerCase(), trimmedCode);
|
|
183
|
+
if (verifyError) {
|
|
184
|
+
setError(verifyError.message);
|
|
185
|
+
}
|
|
186
|
+
} catch (err) {
|
|
187
|
+
setError(err instanceof Error ? err.message : "Verification failed");
|
|
188
|
+
} finally {
|
|
189
|
+
setSending(false);
|
|
190
|
+
}
|
|
191
|
+
}, [email, code, verifyOtp]);
|
|
192
|
+
if (step === "code") {
|
|
193
|
+
return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
|
|
194
|
+
/* @__PURE__ */ jsx("h2", { style: { margin: 0, fontSize: "24px", color: "#111827" }, children: "Check your email" }),
|
|
195
|
+
/* @__PURE__ */ jsxs("p", { style: { margin: 0, color: "#6b7280", textAlign: "center", maxWidth: "320px" }, children: [
|
|
196
|
+
"We sent a sign-in code to ",
|
|
197
|
+
/* @__PURE__ */ jsx("strong", { children: email.trim() })
|
|
198
|
+
] }),
|
|
199
|
+
/* @__PURE__ */ jsx(
|
|
200
|
+
"input",
|
|
201
|
+
{
|
|
202
|
+
style: inputStyle,
|
|
203
|
+
type: "text",
|
|
204
|
+
inputMode: "numeric",
|
|
205
|
+
autoComplete: "one-time-code",
|
|
206
|
+
placeholder: "Enter 6-digit code",
|
|
207
|
+
value: code,
|
|
208
|
+
onChange: (e) => setCode(e.target.value),
|
|
209
|
+
onKeyDown: (e) => e.key === "Enter" && handleVerifyCode()
|
|
210
|
+
}
|
|
211
|
+
),
|
|
212
|
+
error && /* @__PURE__ */ jsx("p", { style: errorStyle, children: error }),
|
|
213
|
+
/* @__PURE__ */ jsx("button", { style: buttonStyle, onClick: handleVerifyCode, disabled: sending, children: sending ? "Verifying..." : "Verify code" }),
|
|
214
|
+
/* @__PURE__ */ jsx("button", { style: linkStyle, onClick: () => {
|
|
215
|
+
setStep("email");
|
|
216
|
+
setCode("");
|
|
217
|
+
setError(null);
|
|
218
|
+
}, children: "Use a different email" })
|
|
219
|
+
] });
|
|
220
|
+
}
|
|
221
|
+
return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
|
|
222
|
+
/* @__PURE__ */ jsx("h2", { style: { margin: 0, fontSize: "24px", color: "#111827" }, children: "Sign in to continue" }),
|
|
223
|
+
/* @__PURE__ */ jsxs("p", { style: { margin: 0, color: "#6b7280" }, children: [
|
|
224
|
+
"Enter your ",
|
|
225
|
+
emailDomain ? `@${emailDomain} ` : "",
|
|
226
|
+
"email to receive a sign-in code."
|
|
227
|
+
] }),
|
|
228
|
+
/* @__PURE__ */ jsx(
|
|
229
|
+
"input",
|
|
230
|
+
{
|
|
231
|
+
style: inputStyle,
|
|
232
|
+
type: "email",
|
|
233
|
+
placeholder: emailDomain ? `you@${emailDomain}` : "you@company.com",
|
|
234
|
+
value: email,
|
|
235
|
+
onChange: (e) => setEmail(e.target.value),
|
|
236
|
+
onKeyDown: (e) => e.key === "Enter" && handleSendCode()
|
|
237
|
+
}
|
|
238
|
+
),
|
|
239
|
+
error && /* @__PURE__ */ jsx("p", { style: errorStyle, children: error }),
|
|
240
|
+
/* @__PURE__ */ jsx("button", { style: buttonStyle, onClick: handleSendCode, disabled: sending, children: sending ? "Sending..." : "Send sign-in code" })
|
|
241
|
+
] });
|
|
242
|
+
}
|
|
111
243
|
function AuthGate({ children, loading, signInComponent }) {
|
|
112
|
-
const { isAuthenticated, isLoading, error, signIn
|
|
244
|
+
const { isAuthenticated, isLoading, error, signIn } = useAuth();
|
|
245
|
+
const inIframe = isInIframe();
|
|
113
246
|
if (isLoading) {
|
|
114
|
-
return /* @__PURE__ */ jsx(Fragment, { children: loading || /* @__PURE__ */ jsx("div", { style:
|
|
247
|
+
return /* @__PURE__ */ jsx(Fragment, { children: loading || /* @__PURE__ */ jsx("div", { style: loadingStyle, children: "Loading..." }) });
|
|
115
248
|
}
|
|
116
249
|
if (!isAuthenticated) {
|
|
250
|
+
if (inIframe) {
|
|
251
|
+
return /* @__PURE__ */ jsx(OtpSignIn, {});
|
|
252
|
+
}
|
|
117
253
|
if (signInComponent) {
|
|
118
254
|
return /* @__PURE__ */ jsx(Fragment, { children: signInComponent({ signIn: () => signIn(window.location.origin) }) });
|
|
119
255
|
}
|
|
120
|
-
return /* @__PURE__ */ jsxs("div", { style:
|
|
256
|
+
return /* @__PURE__ */ jsxs("div", { style: containerStyle, children: [
|
|
121
257
|
/* @__PURE__ */ jsx("h2", { style: { margin: 0, fontSize: "24px", color: "#111827" }, children: "Sign in to continue" }),
|
|
122
|
-
/* @__PURE__ */ jsx("p", { style: { margin: 0, color: "#6b7280" }, children: "Use your
|
|
123
|
-
error && /* @__PURE__ */ jsx("p", { style:
|
|
124
|
-
/* @__PURE__ */ jsx("button", { style:
|
|
258
|
+
/* @__PURE__ */ jsx("p", { style: { margin: 0, color: "#6b7280" }, children: "Use your Google account to access data." }),
|
|
259
|
+
error && /* @__PURE__ */ jsx("p", { style: errorStyle, children: error }),
|
|
260
|
+
/* @__PURE__ */ jsx("button", { style: buttonStyle, onClick: () => signIn(window.location.origin), children: "Sign in with Google" })
|
|
125
261
|
] });
|
|
126
262
|
}
|
|
127
263
|
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":"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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 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(window.location.origin) })}</>;\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(window.location.origin)}>\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":["useState","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: restrict sign-in to emails matching this domain (e.g. \"inkind.com\").\n * Used for client-side validation in the OTP sign-in form.\n */\n emailDomain?: 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 emailDomain,\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, emailDomain }), [client, auth, emailDomain]);\n\n return (\n <SemanticLayerContext.Provider value={value}>\n {children}\n </SemanticLayerContext.Provider>\n );\n}\n","import React, { useCallback, useState } 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 containerStyle: 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 loadingStyle: 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 buttonStyle: 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\nconst inputStyle: React.CSSProperties = {\n padding: \"10px 14px\",\n fontSize: \"16px\",\n border: \"1px solid #d1d5db\",\n borderRadius: \"8px\",\n width: \"280px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n};\n\nconst errorStyle: React.CSSProperties = {\n margin: 0,\n color: \"#ef4444\",\n fontSize: \"14px\",\n};\n\nconst linkStyle: React.CSSProperties = {\n background: \"none\",\n border: \"none\",\n color: \"#4285f4\",\n cursor: \"pointer\",\n fontSize: \"14px\",\n padding: 0,\n textDecoration: \"underline\",\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 * Email OTP sign-in form for use inside iframes (Lovable editor preview).\n * Two-step: enter email → enter code from inbox.\n */\nfunction OtpSignIn() {\n const { sendOtp, verifyOtp, emailDomain } = useAuth();\n const [email, setEmail] = useState(\"\");\n const [code, setCode] = useState(\"\");\n const [step, setStep] = useState<\"email\" | \"code\">(\"email\");\n const [sending, setSending] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const handleSendCode = useCallback(async () => {\n setError(null);\n const trimmed = email.trim().toLowerCase();\n if (!trimmed) {\n setError(\"Please enter your email.\");\n return;\n }\n if (emailDomain && !trimmed.endsWith(`@${emailDomain}`)) {\n setError(`Please use your @${emailDomain} email.`);\n return;\n }\n setSending(true);\n try {\n const { error: otpError } = await sendOtp(trimmed);\n if (otpError) {\n setError(otpError.message);\n } else {\n setStep(\"code\");\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to send code\");\n } finally {\n setSending(false);\n }\n }, [email, emailDomain, sendOtp]);\n\n const handleVerifyCode = useCallback(async () => {\n setError(null);\n const trimmedCode = code.trim();\n if (!trimmedCode) {\n setError(\"Please enter the code from your email.\");\n return;\n }\n setSending(true);\n try {\n const { error: verifyError } = await verifyOtp(email.trim().toLowerCase(), trimmedCode);\n if (verifyError) {\n setError(verifyError.message);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Verification failed\");\n } finally {\n setSending(false);\n }\n }, [email, code, verifyOtp]);\n\n if (step === \"code\") {\n return (\n <div style={containerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Check your email</h2>\n <p style={{ margin: 0, color: \"#6b7280\", textAlign: \"center\", maxWidth: \"320px\" }}>\n We sent a sign-in code to <strong>{email.trim()}</strong>\n </p>\n <input\n style={inputStyle}\n type=\"text\"\n inputMode=\"numeric\"\n autoComplete=\"one-time-code\"\n placeholder=\"Enter 6-digit code\"\n value={code}\n onChange={(e) => setCode(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && handleVerifyCode()}\n />\n {error && <p style={errorStyle}>{error}</p>}\n <button style={buttonStyle} onClick={handleVerifyCode} disabled={sending}>\n {sending ? \"Verifying...\" : \"Verify code\"}\n </button>\n <button style={linkStyle} onClick={() => { setStep(\"email\"); setCode(\"\"); setError(null); }}>\n Use a different email\n </button>\n </div>\n );\n }\n\n return (\n <div style={containerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Sign in to continue</h2>\n <p style={{ margin: 0, color: \"#6b7280\" }}>\n Enter your {emailDomain ? `@${emailDomain} ` : \"\"}email to receive a sign-in code.\n </p>\n <input\n style={inputStyle}\n type=\"email\"\n placeholder={emailDomain ? `you@${emailDomain}` : \"you@company.com\"}\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n onKeyDown={(e) => e.key === \"Enter\" && handleSendCode()}\n />\n {error && <p style={errorStyle}>{error}</p>}\n <button style={buttonStyle} onClick={handleSendCode} disabled={sending}>\n {sending ? \"Sending...\" : \"Send sign-in code\"}\n </button>\n </div>\n );\n}\n\n/**\n * Wraps children and only renders them when the user is authenticated.\n * In iframes (e.g. Lovable editor preview), shows an email OTP form.\n * In standalone tabs, shows the Google OAuth sign-in button.\n */\nexport function AuthGate({ children, loading, signInComponent }: AuthGateProps) {\n const { isAuthenticated, isLoading, error, signIn } = useAuth();\n const inIframe = isInIframe();\n\n if (isLoading) {\n return <>{loading || <div style={loadingStyle}>Loading...</div>}</>;\n }\n\n if (!isAuthenticated) {\n if (inIframe) {\n return <OtpSignIn />;\n }\n\n if (signInComponent) {\n return <>{signInComponent({ signIn: () => signIn(window.location.origin) })}</>;\n }\n\n return (\n <div style={containerStyle}>\n <h2 style={{ margin: 0, fontSize: \"24px\", color: \"#111827\" }}>Sign in to continue</h2>\n <p style={{ margin: 0, color: \"#6b7280\" }}>\n Use your Google account to access data.\n </p>\n {error && <p style={errorStyle}>{error}</p>}\n <button style={buttonStyle} onClick={() => signIn(window.location.origin)}>\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"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/context.ts","../src/react/hooks.ts"],"names":[],"mappings":";;;AASO,IAAM,oBAAA,GAAuB,cAAgD,IAAI;ACExF,SAAS,gBAAA,GAAmB;AAC1B,EAAA,MAAM,GAAA,GAAM,WAAW,oBAAoB,CAAA;AAC3C,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,MAAM,IAAI,MAAM,sEAAsE,CAAA;AAAA,EACxF;AACA,EAAA,OAAO,GAAA;AACT;AAGO,SAAS,OAAA,GAAU;AACxB,EAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAK,GAAI,gBAAA,EAAiB;AAE1C,EAAA,MAAM,MAAA,GAAS,WAAA;AAAA,IACb,CAAC,UAAA,KAAwB,MAAA,CAAO,gBAAA,CAAiB,UAAU,CAAA;AAAA,IAC3D,CAAC,MAAM;AAAA,GACT;AAEA,EAAA,MAAM,OAAA,GAAU,YAAY,MAAM,MAAA,CAAO,SAAQ,EAAG,CAAC,MAAM,CAAC,CAAA;AAE5D,EAAA,OAAO,EAAE,GAAG,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAQ;AACpC;AAaO,SAAS,UAAA,GAA+B;AAC7C,EAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAK,GAAI,gBAAA,EAAiB;AAC1C,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,QAAA,CAA0B,EAAE,CAAA;AACxD,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAI,QAAA,CAA0B,EAAE,CAAA;AAChE,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,UAAA,GAAa,OAAO,KAAK,CAAA;AAE/B,EAAA,MAAM,KAAA,GAAQ,WAAA;AAAA,IACZ,OAAO,QAAQ,KAAA,KAAU;AACvB,MAAA,IAAI,CAAC,KAAK,eAAA,EAAiB;AAC3B,MAAA,YAAA,CAAa,IAAI,CAAA;AACjB,MAAA,QAAA,CAAS,IAAI,CAAA;AACb,MAAA,IAAI;AACF,QAAA,MAAM,IAAA,GAAO,MAAM,MAAA,CAAO,WAAA,CAAY,KAAK,CAAA;AAC3C,QAAA,SAAA,CAAU,KAAK,MAAM,CAAA;AACrB,QAAA,aAAA,CAAc,KAAK,UAAU,CAAA;AAAA,MAC/B,SAAS,GAAA,EAAK;AACZ,QAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,yBAAyB,CAAA;AAAA,MACzE,CAAA,SAAE;AACA,QAAA,YAAA,CAAa,KAAK,CAAA;AAAA,MACpB;AAAA,IACF,CAAA;AAAA,IACA,CAAC,MAAA,EAAQ,IAAA,CAAK,eAAe;AAAA,GAC/B;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,IAAA,CAAK,eAAA,IAAmB,CAAC,UAAA,CAAW,OAAA,EAAS;AAC/C,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AACrB,MAAA,KAAA,EAAM;AAAA,IACR;AAAA,EACF,CAAA,EAAG,CAAC,IAAA,CAAK,eAAA,EAAiB,KAAK,CAAC,CAAA;AAEhC,EAAA,MAAM,OAAA,GAAU,YAAY,MAAM,KAAA,CAAM,IAAI,CAAA,EAAG,CAAC,KAAK,CAAC,CAAA;AAEtD,EAAA,OAAO;AAAA,IACL,MAAA;AAAA,IACA,SAAS,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,QAAQ,CAAA;AAAA,IACjD,UAAA,EAAY,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,IAAA,KAAS,WAAA,IAAe,CAAA,CAAE,IAAA,KAAS,gBAAgB,CAAA;AAAA,IACtF,UAAA;AAAA,IACA,SAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GACF;AACF;AAkBO,SAAS,gBAAA,CACd,KAAA,EACA,OAAA,GAAmC,EAAC,EACZ;AACxB,EAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAK,GAAI,gBAAA,EAAiB;AAC1C,EAAA,MAAM,EAAE,OAAA,GAAU,IAAA,EAAK,GAAI,OAAA;AAC3B,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAA6B,IAAI,CAAA;AACzD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,KAAK,CAAA;AAErC,EAAA,MAAM,OAAA,GAAU,YAAY,YAAY;AACtC,IAAA,IAAI,CAAC,IAAA,CAAK,eAAA,IAAmB,CAAC,KAAA,IAAS,CAAC,OAAA,EAAS;AACjD,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AAC9B,MAAA,OAAA,CAAQ,EAAE,OAAA,EAAS,EAAC,EAAG,IAAA,EAAM,EAAC,EAAG,SAAA,EAAW,CAAA,EAAG,eAAA,EAAiB,CAAA,EAAG,CAAA;AACnE,MAAA;AAAA,IACF;AAEA,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,WAAA,CAAY,KAAK,CAAA;AAC7C,MAAA,OAAA,CAAQ,MAAM,CAAA;AAAA,IAChB,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,cAAc,CAAA;AAC5D,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,MAAA,EAAQ,KAAK,eAAA,EAAiB,QAAA,EAAU,OAAO,CAAC,CAAA;AAEpD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAA,EAAQ;AAAA,EACV,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,SAAS,OAAA,EAAQ;AACpD;AAMO,SAAS,aAAA,CACd,MAAA,EACA,OAAA,GAAmC,EAAC,EACZ;AACxB,EAAA,MAAM,EAAE,MAAA,EAAQ,IAAA,EAAK,GAAI,gBAAA,EAAiB;AAC1C,EAAA,MAAM,EAAE,OAAA,GAAU,IAAA,EAAK,GAAI,OAAA;AAC3B,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAI,SAA6B,IAAI,CAAA;AACzD,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,KAAK,CAAA;AAChD,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAAwB,IAAI,CAAA;AACtD,EAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,MAAM,CAAA;AAEvC,EAAA,MAAM,OAAA,GAAU,YAAY,YAAY;AACtC,IAAA,IAAI,CAAC,IAAA,CAAK,eAAA,IAAmB,CAAC,MAAA,IAAU,CAAC,OAAA,EAAS;AAElD,IAAA,YAAA,CAAa,IAAI,CAAA;AACjB,IAAA,QAAA,CAAS,IAAI,CAAA;AACb,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,KAAA,CAAM,MAAM,CAAA;AACxC,MAAA,OAAA,CAAQ,MAAM,CAAA;AAAA,IAChB,SAAS,GAAA,EAAK;AACZ,MAAA,QAAA,CAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,cAAc,CAAA;AAC5D,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,CAAA,SAAE;AACA,MAAA,YAAA,CAAa,KAAK,CAAA;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,MAAA,EAAQ,KAAK,eAAA,EAAiB,SAAA,EAAW,OAAO,CAAC,CAAA;AAErD,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,OAAA,EAAQ;AAAA,EACV,CAAA,EAAG,CAAC,OAAO,CAAC,CAAA;AAEZ,EAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,KAAA,EAAO,SAAS,OAAA,EAAQ;AACpD","file":"chunk-NJ4IJBV3.js","sourcesContent":["import { createContext } from \"react\";\nimport type { SemanticLayerClient } from \"../client\";\nimport type { AuthState } from \"../types\";\n\nexport interface SemanticLayerContextValue {\n client: SemanticLayerClient;\n auth: AuthState;\n}\n\nexport const SemanticLayerContext = createContext<SemanticLayerContextValue | null>(null);\n","import { useContext, useCallback, useEffect, useState, useRef } from \"react\";\nimport { SemanticLayerContext } from \"./context\";\nimport type {\n SemanticField,\n FieldCategory,\n QueryResult,\n SimpleQueryInput,\n PivotConfig,\n AuthState,\n} from \"../types\";\n\nfunction useSemanticLayer() {\n const ctx = useContext(SemanticLayerContext);\n if (!ctx) {\n throw new Error(\"useSemanticLayer hooks must be used within a <SemanticLayerProvider>\");\n }\n return ctx;\n}\n\n/** Returns the current auth state and sign-in/sign-out methods. */\nexport function useAuth() {\n const { client, auth } = useSemanticLayer();\n\n const signIn = useCallback(\n (redirectTo?: string) => client.signInWithGoogle(redirectTo),\n [client],\n );\n\n const signOut = useCallback(() => client.signOut(), [client]);\n\n return { ...auth, signIn, signOut };\n}\n\ninterface UseMetricsResult {\n fields: SemanticField[];\n metrics: SemanticField[];\n dimensions: SemanticField[];\n categories: FieldCategory[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\n/** Fetch the full curated catalog of metrics and dimensions. */\nexport function useMetrics(): UseMetricsResult {\n const { client, auth } = useSemanticLayer();\n const [fields, setFields] = useState<SemanticField[]>([]);\n const [categories, setCategories] = useState<FieldCategory[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const fetchedRef = useRef(false);\n\n const fetch = useCallback(\n async (force = false) => {\n if (!auth.isAuthenticated) return;\n setIsLoading(true);\n setError(null);\n try {\n const data = await client.getMetadata(force);\n setFields(data.fields);\n setCategories(data.categories);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load metadata\");\n } finally {\n setIsLoading(false);\n }\n },\n [client, auth.isAuthenticated],\n );\n\n useEffect(() => {\n if (auth.isAuthenticated && !fetchedRef.current) {\n fetchedRef.current = true;\n fetch();\n }\n }, [auth.isAuthenticated, fetch]);\n\n const refetch = useCallback(() => fetch(true), [fetch]);\n\n return {\n fields,\n metrics: fields.filter((f) => f.type === \"metric\"),\n dimensions: fields.filter((f) => f.type === \"dimension\" || f.type === \"time_dimension\"),\n categories,\n isLoading,\n error,\n refetch,\n };\n}\n\ninterface UseSemanticQueryOptions {\n /** Set to false to prevent the query from running automatically. */\n enabled?: boolean;\n}\n\ninterface UseSemanticQueryResult {\n data: QueryResult | null;\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\n/**\n * Execute a query against the dbt Semantic Layer using the simple input format.\n * The query runs automatically when the input changes (unless enabled=false).\n */\nexport function useSemanticQuery(\n input: SimpleQueryInput | null,\n options: UseSemanticQueryOptions = {},\n): UseSemanticQueryResult {\n const { client, auth } = useSemanticLayer();\n const { enabled = true } = options;\n const [data, setData] = useState<QueryResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const inputKey = JSON.stringify(input);\n\n const execute = useCallback(async () => {\n if (!auth.isAuthenticated || !input || !enabled) return;\n if (input.metrics.length === 0) {\n setData({ columns: [], rows: [], totalRows: 0, executionTimeMs: 0 });\n return;\n }\n\n setIsLoading(true);\n setError(null);\n try {\n const result = await client.simpleQuery(input);\n setData(result);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Query failed\");\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, auth.isAuthenticated, inputKey, enabled]);\n\n useEffect(() => {\n execute();\n }, [execute]);\n\n return { data, isLoading, error, refetch: execute };\n}\n\n/**\n * Execute a query using the full PivotConfig format.\n * Use this for advanced use cases (column pivoting, custom aggregations).\n */\nexport function usePivotQuery(\n config: PivotConfig | null,\n options: UseSemanticQueryOptions = {},\n): UseSemanticQueryResult {\n const { client, auth } = useSemanticLayer();\n const { enabled = true } = options;\n const [data, setData] = useState<QueryResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const configKey = JSON.stringify(config);\n\n const execute = useCallback(async () => {\n if (!auth.isAuthenticated || !config || !enabled) return;\n\n setIsLoading(true);\n setError(null);\n try {\n const result = await client.query(config);\n setData(result);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Query failed\");\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, auth.isAuthenticated, configKey, enabled]);\n\n useEffect(() => {\n execute();\n }, [execute]);\n\n return { data, isLoading, error, refetch: execute };\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/context.ts","../src/react/hooks.ts"],"names":["createContext","useContext","useCallback","useState","useRef","useEffect"],"mappings":"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","file":"chunk-Y3A3T45C.cjs","sourcesContent":["import { createContext } from \"react\";\nimport type { SemanticLayerClient } from \"../client\";\nimport type { AuthState } from \"../types\";\n\nexport interface SemanticLayerContextValue {\n client: SemanticLayerClient;\n auth: AuthState;\n}\n\nexport const SemanticLayerContext = createContext<SemanticLayerContextValue | null>(null);\n","import { useContext, useCallback, useEffect, useState, useRef } from \"react\";\nimport { SemanticLayerContext } from \"./context\";\nimport type {\n SemanticField,\n FieldCategory,\n QueryResult,\n SimpleQueryInput,\n PivotConfig,\n AuthState,\n} from \"../types\";\n\nfunction useSemanticLayer() {\n const ctx = useContext(SemanticLayerContext);\n if (!ctx) {\n throw new Error(\"useSemanticLayer hooks must be used within a <SemanticLayerProvider>\");\n }\n return ctx;\n}\n\n/** Returns the current auth state and sign-in/sign-out methods. */\nexport function useAuth() {\n const { client, auth } = useSemanticLayer();\n\n const signIn = useCallback(\n (redirectTo?: string) => client.signInWithGoogle(redirectTo),\n [client],\n );\n\n const signOut = useCallback(() => client.signOut(), [client]);\n\n return { ...auth, signIn, signOut };\n}\n\ninterface UseMetricsResult {\n fields: SemanticField[];\n metrics: SemanticField[];\n dimensions: SemanticField[];\n categories: FieldCategory[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\n/** Fetch the full curated catalog of metrics and dimensions. */\nexport function useMetrics(): UseMetricsResult {\n const { client, auth } = useSemanticLayer();\n const [fields, setFields] = useState<SemanticField[]>([]);\n const [categories, setCategories] = useState<FieldCategory[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const fetchedRef = useRef(false);\n\n const fetch = useCallback(\n async (force = false) => {\n if (!auth.isAuthenticated) return;\n setIsLoading(true);\n setError(null);\n try {\n const data = await client.getMetadata(force);\n setFields(data.fields);\n setCategories(data.categories);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load metadata\");\n } finally {\n setIsLoading(false);\n }\n },\n [client, auth.isAuthenticated],\n );\n\n useEffect(() => {\n if (auth.isAuthenticated && !fetchedRef.current) {\n fetchedRef.current = true;\n fetch();\n }\n }, [auth.isAuthenticated, fetch]);\n\n const refetch = useCallback(() => fetch(true), [fetch]);\n\n return {\n fields,\n metrics: fields.filter((f) => f.type === \"metric\"),\n dimensions: fields.filter((f) => f.type === \"dimension\" || f.type === \"time_dimension\"),\n categories,\n isLoading,\n error,\n refetch,\n };\n}\n\ninterface UseSemanticQueryOptions {\n /** Set to false to prevent the query from running automatically. */\n enabled?: boolean;\n}\n\ninterface UseSemanticQueryResult {\n data: QueryResult | null;\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\n/**\n * Execute a query against the dbt Semantic Layer using the simple input format.\n * The query runs automatically when the input changes (unless enabled=false).\n */\nexport function useSemanticQuery(\n input: SimpleQueryInput | null,\n options: UseSemanticQueryOptions = {},\n): UseSemanticQueryResult {\n const { client, auth } = useSemanticLayer();\n const { enabled = true } = options;\n const [data, setData] = useState<QueryResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const inputKey = JSON.stringify(input);\n\n const execute = useCallback(async () => {\n if (!auth.isAuthenticated || !input || !enabled) return;\n if (input.metrics.length === 0) {\n setData({ columns: [], rows: [], totalRows: 0, executionTimeMs: 0 });\n return;\n }\n\n setIsLoading(true);\n setError(null);\n try {\n const result = await client.simpleQuery(input);\n setData(result);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Query failed\");\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, auth.isAuthenticated, inputKey, enabled]);\n\n useEffect(() => {\n execute();\n }, [execute]);\n\n return { data, isLoading, error, refetch: execute };\n}\n\n/**\n * Execute a query using the full PivotConfig format.\n * Use this for advanced use cases (column pivoting, custom aggregations).\n */\nexport function usePivotQuery(\n config: PivotConfig | null,\n options: UseSemanticQueryOptions = {},\n): UseSemanticQueryResult {\n const { client, auth } = useSemanticLayer();\n const { enabled = true } = options;\n const [data, setData] = useState<QueryResult | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const configKey = JSON.stringify(config);\n\n const execute = useCallback(async () => {\n if (!auth.isAuthenticated || !config || !enabled) return;\n\n setIsLoading(true);\n setError(null);\n try {\n const result = await client.query(config);\n setData(result);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Query failed\");\n setData(null);\n } finally {\n setIsLoading(false);\n }\n }, [client, auth.isAuthenticated, configKey, enabled]);\n\n useEffect(() => {\n execute();\n }, [execute]);\n\n return { data, isLoading, error, refetch: execute };\n}\n"]}
|