@inkindcards/semantic-layer 0.2.2 → 2.0.1
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-SLRBAF37.js → chunk-3OR3QCN6.js} +8 -21
- package/dist/chunk-3OR3QCN6.js.map +1 -0
- package/dist/{chunk-SHHZ37FE.cjs → chunk-T2C43AAL.cjs} +8 -21
- package/dist/chunk-T2C43AAL.cjs.map +1 -0
- package/dist/chunk-W64RGDXH.cjs +225 -0
- package/dist/chunk-W64RGDXH.cjs.map +1 -0
- package/dist/chunk-WR4D3UI6.js +222 -0
- package/dist/chunk-WR4D3UI6.js.map +1 -0
- package/dist/components.cjs +555 -9
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +53 -2
- package/dist/components.d.ts +53 -2
- package/dist/components.js +546 -4
- package/dist/components.js.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.cts +36 -39
- package/dist/index.d.ts +36 -39
- package/dist/index.js +1 -1
- package/dist/react.cjs +59 -185
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +10 -21
- package/dist/react.d.ts +10 -21
- package/dist/react.js +51 -177
- package/dist/react.js.map +1 -1
- package/dist/{types-Dc8Zdacw.d.cts → types-c5qj4BKB.d.cts} +1 -2
- package/dist/{types-Dc8Zdacw.d.ts → types-c5qj4BKB.d.ts} +1 -2
- package/package.json +2 -4
- package/dist/chunk-B23E3XFB.cjs +0 -219
- package/dist/chunk-B23E3XFB.cjs.map +0 -1
- package/dist/chunk-SHHZ37FE.cjs.map +0 -1
- package/dist/chunk-SLRBAF37.js.map +0 -1
- package/dist/chunk-WPK37LJ6.js +0 -216
- package/dist/chunk-WPK37LJ6.js.map +0 -1
|
@@ -10,22 +10,9 @@ function useSemanticLayer() {
|
|
|
10
10
|
return ctx;
|
|
11
11
|
}
|
|
12
12
|
function useAuth() {
|
|
13
|
-
const { client, auth, emailDomain } = useSemanticLayer();
|
|
14
|
-
const signIn = useCallback(
|
|
15
|
-
(redirectTo) => client.signInWithGoogle(redirectTo),
|
|
16
|
-
[client]
|
|
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
|
-
);
|
|
26
|
-
const signInPopup = useCallback(() => client.signInWithPopup(), [client]);
|
|
13
|
+
const { client, auth, emailDomain, signIn } = useSemanticLayer();
|
|
27
14
|
const signOut = useCallback(() => client.signOut(), [client]);
|
|
28
|
-
return { ...auth, signIn,
|
|
15
|
+
return { ...auth, signIn, signOut, emailDomain };
|
|
29
16
|
}
|
|
30
17
|
function useMetrics() {
|
|
31
18
|
const { client, auth } = useSemanticLayer();
|
|
@@ -34,7 +21,7 @@ function useMetrics() {
|
|
|
34
21
|
const [isLoading, setIsLoading] = useState(false);
|
|
35
22
|
const [error, setError] = useState(null);
|
|
36
23
|
const fetchedRef = useRef(false);
|
|
37
|
-
const
|
|
24
|
+
const doFetch = useCallback(
|
|
38
25
|
async (force = false) => {
|
|
39
26
|
if (!auth.isAuthenticated) return;
|
|
40
27
|
setIsLoading(true);
|
|
@@ -54,10 +41,10 @@ function useMetrics() {
|
|
|
54
41
|
useEffect(() => {
|
|
55
42
|
if (auth.isAuthenticated && !fetchedRef.current) {
|
|
56
43
|
fetchedRef.current = true;
|
|
57
|
-
|
|
44
|
+
doFetch();
|
|
58
45
|
}
|
|
59
|
-
}, [auth.isAuthenticated,
|
|
60
|
-
const refetch = useCallback(() =>
|
|
46
|
+
}, [auth.isAuthenticated, doFetch]);
|
|
47
|
+
const refetch = useCallback(() => doFetch(true), [doFetch]);
|
|
61
48
|
return {
|
|
62
49
|
fields,
|
|
63
50
|
metrics: fields.filter((f) => f.type === "metric"),
|
|
@@ -249,5 +236,5 @@ function useAdminUsers() {
|
|
|
249
236
|
}
|
|
250
237
|
|
|
251
238
|
export { SemanticLayerContext, useAdminFields, useAdminRoles, useAdminUsers, useAuth, useMetrics, usePivotQuery, useSemanticQuery };
|
|
252
|
-
//# sourceMappingURL=chunk-
|
|
253
|
-
//# sourceMappingURL=chunk-
|
|
239
|
+
//# sourceMappingURL=chunk-3OR3QCN6.js.map
|
|
240
|
+
//# sourceMappingURL=chunk-3OR3QCN6.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/context.ts","../src/react/hooks.ts","../src/react/admin-hooks.ts"],"names":["useContext","useState","useCallback","useEffect"],"mappings":"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","file":"chunk-3OR3QCN6.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 signIn: () => void;\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} 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, signIn } = useSemanticLayer();\n\n const signOut = useCallback(() => client.signOut(), [client]);\n\n return { ...auth, signIn, 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 doFetch = 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 doFetch();\n }\n }, [auth.isAuthenticated, doFetch]);\n\n const refetch = useCallback(() => doFetch(true), [doFetch]);\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 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 */\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","import { useContext, useCallback, useEffect, useState } from \"react\";\nimport { SemanticLayerContext } from \"./context\";\nimport type {\n CuratedField,\n AccessRole,\n UserRoleAssignment,\n UserFieldOverride,\n} from \"../types\";\n\nfunction useClient() {\n const ctx = useContext(SemanticLayerContext);\n if (!ctx) throw new Error(\"Admin hooks must be used within <SemanticLayerProvider>\");\n return ctx.client;\n}\n\n// ─── Fields ───────────────────────────────────────────────────────────────────\n\nexport interface UseAdminFieldsResult {\n fields: CuratedField[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n createField: (input: { field_name: string; field_type: string; display_name?: string; description?: string }) => Promise<CuratedField>;\n updateField: (input: { id: number; field_name?: string; display_name?: string; description?: string; is_active?: boolean }) => Promise<CuratedField>;\n deleteField: (id: number) => Promise<void>;\n}\n\nexport function useAdminFields(): UseAdminFieldsResult {\n const client = useClient();\n const [fields, setFields] = useState<CuratedField[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const fetch = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const { fields: data } = await client.admin.listFields();\n setFields(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load fields\");\n } finally {\n setIsLoading(false);\n }\n }, [client]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n const createField: UseAdminFieldsResult[\"createField\"] = useCallback(async (input) => {\n const { field } = await client.admin.createField(input);\n setFields((prev) => [...prev, field]);\n return field;\n }, [client]);\n\n const updateField: UseAdminFieldsResult[\"updateField\"] = useCallback(async (input) => {\n const { field } = await client.admin.updateField(input);\n setFields((prev) => prev.map((f) => (f.id === field.id ? field : f)));\n return field;\n }, [client]);\n\n const deleteField = useCallback(async (id: number) => {\n await client.admin.deleteField(id);\n setFields((prev) => prev.filter((f) => f.id !== id));\n }, [client]);\n\n return { fields, isLoading, error, refetch: fetch, createField, updateField, deleteField };\n}\n\n// ─── Roles ────────────────────────────────────────────────────────────────────\n\nexport interface UseAdminRolesResult {\n roles: AccessRole[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n createRole: (input: { name: string; description?: string }) => Promise<AccessRole>;\n updateRole: (input: { id: number; name?: string; description?: string }) => Promise<AccessRole>;\n deleteRole: (id: number) => Promise<void>;\n setRoleFields: (roleId: number, fieldIds: number[]) => Promise<void>;\n}\n\nexport function useAdminRoles(): UseAdminRolesResult {\n const client = useClient();\n const [roles, setRoles] = useState<AccessRole[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const fetch = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const { roles: data } = await client.admin.listRoles();\n setRoles(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load roles\");\n } finally {\n setIsLoading(false);\n }\n }, [client]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n const createRole: UseAdminRolesResult[\"createRole\"] = useCallback(async (input) => {\n const { role } = await client.admin.createRole(input);\n setRoles((prev) => [...prev, role]);\n return role;\n }, [client]);\n\n const updateRole: UseAdminRolesResult[\"updateRole\"] = useCallback(async (input) => {\n const { role } = await client.admin.updateRole(input);\n setRoles((prev) => prev.map((r) => (r.id === role.id ? role : r)));\n return role;\n }, [client]);\n\n const deleteRole = useCallback(async (id: number) => {\n await client.admin.deleteRole(id);\n setRoles((prev) => prev.filter((r) => r.id !== id));\n }, [client]);\n\n const setRoleFields = useCallback(async (roleId: number, fieldIds: number[]) => {\n await client.admin.setRoleFields(roleId, fieldIds);\n await fetch();\n }, [client, fetch]);\n\n return { roles, isLoading, error, refetch: fetch, createRole, updateRole, deleteRole, setRoleFields };\n}\n\n// ─── Users ────────────────────────────────────────────────────────────────────\n\nexport interface UseAdminUsersResult {\n users: UserRoleAssignment[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n assignUserRole: (input: { email: string; role_id: number; is_admin?: boolean }) => Promise<UserRoleAssignment>;\n removeUserRole: (input: { email: string; role_id: number }) => Promise<void>;\n listOverrides: (userId: string) => Promise<UserFieldOverride[]>;\n setOverride: (input: { user_id: string; curated_field_id: number; access: \"grant\" | \"deny\" }) => Promise<UserFieldOverride>;\n removeOverride: (input: { user_id: string; curated_field_id: number }) => Promise<void>;\n}\n\nexport function useAdminUsers(): UseAdminUsersResult {\n const client = useClient();\n const [users, setUsers] = useState<UserRoleAssignment[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const fetch = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const { users: data } = await client.admin.listUsers();\n setUsers(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load users\");\n } finally {\n setIsLoading(false);\n }\n }, [client]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n const assignUserRole: UseAdminUsersResult[\"assignUserRole\"] = useCallback(async (input) => {\n const { assignment } = await client.admin.assignUserRole(input);\n await fetch();\n return assignment;\n }, [client, fetch]);\n\n const removeUserRole = useCallback(async (input: { email: string; role_id: number }) => {\n await client.admin.removeUserRole(input);\n setUsers((prev) => prev.filter((u) => !(u.email === input.email && u.role_id === input.role_id)));\n }, [client]);\n\n const listOverrides = useCallback(async (userId: string) => {\n const { overrides } = await client.admin.listUserOverrides(userId);\n return overrides;\n }, [client]);\n\n const setOverride: UseAdminUsersResult[\"setOverride\"] = useCallback(async (input) => {\n const { override } = await client.admin.setUserOverride(input);\n return override;\n }, [client]);\n\n const removeOverride = useCallback(async (input: { user_id: string; curated_field_id: number }) => {\n await client.admin.removeUserOverride(input);\n }, [client]);\n\n return { users, isLoading, error, refetch: fetch, assignUserRole, removeUserRole, listOverrides, setOverride, removeOverride };\n}\n"]}
|
|
@@ -12,22 +12,9 @@ function useSemanticLayer() {
|
|
|
12
12
|
return ctx;
|
|
13
13
|
}
|
|
14
14
|
function useAuth() {
|
|
15
|
-
const { client, auth, emailDomain } = useSemanticLayer();
|
|
16
|
-
const signIn = react.useCallback(
|
|
17
|
-
(redirectTo) => client.signInWithGoogle(redirectTo),
|
|
18
|
-
[client]
|
|
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
|
-
);
|
|
28
|
-
const signInPopup = react.useCallback(() => client.signInWithPopup(), [client]);
|
|
15
|
+
const { client, auth, emailDomain, signIn } = useSemanticLayer();
|
|
29
16
|
const signOut = react.useCallback(() => client.signOut(), [client]);
|
|
30
|
-
return { ...auth, signIn,
|
|
17
|
+
return { ...auth, signIn, signOut, emailDomain };
|
|
31
18
|
}
|
|
32
19
|
function useMetrics() {
|
|
33
20
|
const { client, auth } = useSemanticLayer();
|
|
@@ -36,7 +23,7 @@ function useMetrics() {
|
|
|
36
23
|
const [isLoading, setIsLoading] = react.useState(false);
|
|
37
24
|
const [error, setError] = react.useState(null);
|
|
38
25
|
const fetchedRef = react.useRef(false);
|
|
39
|
-
const
|
|
26
|
+
const doFetch = react.useCallback(
|
|
40
27
|
async (force = false) => {
|
|
41
28
|
if (!auth.isAuthenticated) return;
|
|
42
29
|
setIsLoading(true);
|
|
@@ -56,10 +43,10 @@ function useMetrics() {
|
|
|
56
43
|
react.useEffect(() => {
|
|
57
44
|
if (auth.isAuthenticated && !fetchedRef.current) {
|
|
58
45
|
fetchedRef.current = true;
|
|
59
|
-
|
|
46
|
+
doFetch();
|
|
60
47
|
}
|
|
61
|
-
}, [auth.isAuthenticated,
|
|
62
|
-
const refetch = react.useCallback(() =>
|
|
48
|
+
}, [auth.isAuthenticated, doFetch]);
|
|
49
|
+
const refetch = react.useCallback(() => doFetch(true), [doFetch]);
|
|
63
50
|
return {
|
|
64
51
|
fields,
|
|
65
52
|
metrics: fields.filter((f) => f.type === "metric"),
|
|
@@ -258,5 +245,5 @@ exports.useAuth = useAuth;
|
|
|
258
245
|
exports.useMetrics = useMetrics;
|
|
259
246
|
exports.usePivotQuery = usePivotQuery;
|
|
260
247
|
exports.useSemanticQuery = useSemanticQuery;
|
|
261
|
-
//# sourceMappingURL=chunk-
|
|
262
|
-
//# sourceMappingURL=chunk-
|
|
248
|
+
//# sourceMappingURL=chunk-T2C43AAL.cjs.map
|
|
249
|
+
//# sourceMappingURL=chunk-T2C43AAL.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/context.ts","../src/react/hooks.ts","../src/react/admin-hooks.ts"],"names":["createContext","useContext","useCallback","useState","useRef","useEffect"],"mappings":"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","file":"chunk-T2C43AAL.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 signIn: () => void;\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} 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, signIn } = useSemanticLayer();\n\n const signOut = useCallback(() => client.signOut(), [client]);\n\n return { ...auth, signIn, 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 doFetch = 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 doFetch();\n }\n }, [auth.isAuthenticated, doFetch]);\n\n const refetch = useCallback(() => doFetch(true), [doFetch]);\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 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 */\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","import { useContext, useCallback, useEffect, useState } from \"react\";\nimport { SemanticLayerContext } from \"./context\";\nimport type {\n CuratedField,\n AccessRole,\n UserRoleAssignment,\n UserFieldOverride,\n} from \"../types\";\n\nfunction useClient() {\n const ctx = useContext(SemanticLayerContext);\n if (!ctx) throw new Error(\"Admin hooks must be used within <SemanticLayerProvider>\");\n return ctx.client;\n}\n\n// ─── Fields ───────────────────────────────────────────────────────────────────\n\nexport interface UseAdminFieldsResult {\n fields: CuratedField[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n createField: (input: { field_name: string; field_type: string; display_name?: string; description?: string }) => Promise<CuratedField>;\n updateField: (input: { id: number; field_name?: string; display_name?: string; description?: string; is_active?: boolean }) => Promise<CuratedField>;\n deleteField: (id: number) => Promise<void>;\n}\n\nexport function useAdminFields(): UseAdminFieldsResult {\n const client = useClient();\n const [fields, setFields] = useState<CuratedField[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const fetch = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const { fields: data } = await client.admin.listFields();\n setFields(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load fields\");\n } finally {\n setIsLoading(false);\n }\n }, [client]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n const createField: UseAdminFieldsResult[\"createField\"] = useCallback(async (input) => {\n const { field } = await client.admin.createField(input);\n setFields((prev) => [...prev, field]);\n return field;\n }, [client]);\n\n const updateField: UseAdminFieldsResult[\"updateField\"] = useCallback(async (input) => {\n const { field } = await client.admin.updateField(input);\n setFields((prev) => prev.map((f) => (f.id === field.id ? field : f)));\n return field;\n }, [client]);\n\n const deleteField = useCallback(async (id: number) => {\n await client.admin.deleteField(id);\n setFields((prev) => prev.filter((f) => f.id !== id));\n }, [client]);\n\n return { fields, isLoading, error, refetch: fetch, createField, updateField, deleteField };\n}\n\n// ─── Roles ────────────────────────────────────────────────────────────────────\n\nexport interface UseAdminRolesResult {\n roles: AccessRole[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n createRole: (input: { name: string; description?: string }) => Promise<AccessRole>;\n updateRole: (input: { id: number; name?: string; description?: string }) => Promise<AccessRole>;\n deleteRole: (id: number) => Promise<void>;\n setRoleFields: (roleId: number, fieldIds: number[]) => Promise<void>;\n}\n\nexport function useAdminRoles(): UseAdminRolesResult {\n const client = useClient();\n const [roles, setRoles] = useState<AccessRole[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const fetch = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const { roles: data } = await client.admin.listRoles();\n setRoles(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load roles\");\n } finally {\n setIsLoading(false);\n }\n }, [client]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n const createRole: UseAdminRolesResult[\"createRole\"] = useCallback(async (input) => {\n const { role } = await client.admin.createRole(input);\n setRoles((prev) => [...prev, role]);\n return role;\n }, [client]);\n\n const updateRole: UseAdminRolesResult[\"updateRole\"] = useCallback(async (input) => {\n const { role } = await client.admin.updateRole(input);\n setRoles((prev) => prev.map((r) => (r.id === role.id ? role : r)));\n return role;\n }, [client]);\n\n const deleteRole = useCallback(async (id: number) => {\n await client.admin.deleteRole(id);\n setRoles((prev) => prev.filter((r) => r.id !== id));\n }, [client]);\n\n const setRoleFields = useCallback(async (roleId: number, fieldIds: number[]) => {\n await client.admin.setRoleFields(roleId, fieldIds);\n await fetch();\n }, [client, fetch]);\n\n return { roles, isLoading, error, refetch: fetch, createRole, updateRole, deleteRole, setRoleFields };\n}\n\n// ─── Users ────────────────────────────────────────────────────────────────────\n\nexport interface UseAdminUsersResult {\n users: UserRoleAssignment[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n assignUserRole: (input: { email: string; role_id: number; is_admin?: boolean }) => Promise<UserRoleAssignment>;\n removeUserRole: (input: { email: string; role_id: number }) => Promise<void>;\n listOverrides: (userId: string) => Promise<UserFieldOverride[]>;\n setOverride: (input: { user_id: string; curated_field_id: number; access: \"grant\" | \"deny\" }) => Promise<UserFieldOverride>;\n removeOverride: (input: { user_id: string; curated_field_id: number }) => Promise<void>;\n}\n\nexport function useAdminUsers(): UseAdminUsersResult {\n const client = useClient();\n const [users, setUsers] = useState<UserRoleAssignment[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const fetch = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n try {\n const { users: data } = await client.admin.listUsers();\n setUsers(data);\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to load users\");\n } finally {\n setIsLoading(false);\n }\n }, [client]);\n\n useEffect(() => { fetch(); }, [fetch]);\n\n const assignUserRole: UseAdminUsersResult[\"assignUserRole\"] = useCallback(async (input) => {\n const { assignment } = await client.admin.assignUserRole(input);\n await fetch();\n return assignment;\n }, [client, fetch]);\n\n const removeUserRole = useCallback(async (input: { email: string; role_id: number }) => {\n await client.admin.removeUserRole(input);\n setUsers((prev) => prev.filter((u) => !(u.email === input.email && u.role_id === input.role_id)));\n }, [client]);\n\n const listOverrides = useCallback(async (userId: string) => {\n const { overrides } = await client.admin.listUserOverrides(userId);\n return overrides;\n }, [client]);\n\n const setOverride: UseAdminUsersResult[\"setOverride\"] = useCallback(async (input) => {\n const { override } = await client.admin.setUserOverride(input);\n return override;\n }, [client]);\n\n const removeOverride = useCallback(async (input: { user_id: string; curated_field_id: number }) => {\n await client.admin.removeUserOverride(input);\n }, [client]);\n\n return { users, isLoading, error, refetch: fetch, assignUserRole, removeUserRole, listOverrides, setOverride, removeOverride };\n}\n"]}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/client.ts
|
|
4
|
+
var TOKEN_STORAGE_KEY = "semantic-layer-token";
|
|
5
|
+
var SemanticLayerClient = class {
|
|
6
|
+
constructor(config) {
|
|
7
|
+
this.accessToken = null;
|
|
8
|
+
this.tokenExpiry = 0;
|
|
9
|
+
this.userEmail = null;
|
|
10
|
+
this.metadataCache = null;
|
|
11
|
+
this.metadataCacheTime = 0;
|
|
12
|
+
this.CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
13
|
+
this.authListeners = /* @__PURE__ */ new Set();
|
|
14
|
+
this.admin = {
|
|
15
|
+
listFields: () => this.adminCall("fields.list"),
|
|
16
|
+
createField: (input) => this.adminCall("fields.create", input),
|
|
17
|
+
updateField: (input) => this.adminCall("fields.update", input),
|
|
18
|
+
deleteField: (id) => this.adminCall("fields.delete", { id }),
|
|
19
|
+
listRoles: () => this.adminCall("roles.list"),
|
|
20
|
+
createRole: (input) => this.adminCall("roles.create", input),
|
|
21
|
+
updateRole: (input) => this.adminCall("roles.update", input),
|
|
22
|
+
deleteRole: (id) => this.adminCall("roles.delete", { id }),
|
|
23
|
+
setRoleFields: (role_id, curated_field_ids) => this.adminCall("roles.setFields", { role_id, curated_field_ids }),
|
|
24
|
+
listUsers: () => this.adminCall("users.list"),
|
|
25
|
+
assignUserRole: (input) => this.adminCall("users.assignRole", input),
|
|
26
|
+
removeUserRole: (input) => this.adminCall("users.removeRole", input),
|
|
27
|
+
listUserOverrides: (user_id) => this.adminCall("users.listOverrides", { user_id }),
|
|
28
|
+
setUserOverride: (input) => this.adminCall("users.setOverride", input),
|
|
29
|
+
removeUserOverride: (input) => this.adminCall("users.removeOverride", input)
|
|
30
|
+
};
|
|
31
|
+
this.gatewayUrl = config.gatewayUrl;
|
|
32
|
+
if (typeof window !== "undefined") {
|
|
33
|
+
try {
|
|
34
|
+
const stored = sessionStorage.getItem(TOKEN_STORAGE_KEY);
|
|
35
|
+
if (stored) {
|
|
36
|
+
const parsed = JSON.parse(stored);
|
|
37
|
+
if (parsed.expiresAt > Date.now()) {
|
|
38
|
+
this.accessToken = parsed.token;
|
|
39
|
+
this.tokenExpiry = parsed.expiresAt;
|
|
40
|
+
this.userEmail = parsed.email || null;
|
|
41
|
+
} else {
|
|
42
|
+
sessionStorage.removeItem(TOKEN_STORAGE_KEY);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
} catch {
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// -- Auth ------------------------------------------------------------------
|
|
50
|
+
/**
|
|
51
|
+
* Returns the URL to redirect the browser to for Google sign-in.
|
|
52
|
+
* After the user authenticates, the gateway redirects back to returnUrl
|
|
53
|
+
* with the access token in the URL hash fragment.
|
|
54
|
+
*/
|
|
55
|
+
getSignInUrl(returnUrl) {
|
|
56
|
+
const target = returnUrl || (typeof window !== "undefined" ? window.location.href.split("#")[0] : "");
|
|
57
|
+
return `${this.gatewayUrl}/auth/google?returnUrl=${encodeURIComponent(target)}`;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Check the current URL hash for auth tokens (set by the gateway callback redirect).
|
|
61
|
+
* If found, extracts them, stores the session, clears the hash, and returns true.
|
|
62
|
+
*/
|
|
63
|
+
handleAuthCallback() {
|
|
64
|
+
if (typeof window === "undefined") return false;
|
|
65
|
+
const hash = window.location.hash.slice(1);
|
|
66
|
+
if (!hash) return false;
|
|
67
|
+
const params = new URLSearchParams(hash);
|
|
68
|
+
const authError = params.get("auth_error");
|
|
69
|
+
if (authError) {
|
|
70
|
+
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
71
|
+
throw new SemanticLayerError(authError, "AUTH_ERROR");
|
|
72
|
+
}
|
|
73
|
+
const accessToken = params.get("access_token");
|
|
74
|
+
const email = params.get("email");
|
|
75
|
+
const expiresIn = parseInt(params.get("expires_in") || "0", 10);
|
|
76
|
+
if (!accessToken || !email) return false;
|
|
77
|
+
window.history.replaceState(null, "", window.location.pathname + window.location.search);
|
|
78
|
+
this.setAccessToken(accessToken, email, expiresIn);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Set the Google access token (called after OAuth redirect callback).
|
|
83
|
+
*/
|
|
84
|
+
setAccessToken(token, email, expiresIn) {
|
|
85
|
+
this.accessToken = token;
|
|
86
|
+
this.userEmail = email;
|
|
87
|
+
this.tokenExpiry = Date.now() + expiresIn * 1e3;
|
|
88
|
+
if (typeof window !== "undefined") {
|
|
89
|
+
try {
|
|
90
|
+
sessionStorage.setItem(
|
|
91
|
+
TOKEN_STORAGE_KEY,
|
|
92
|
+
JSON.stringify({ token, email, expiresAt: this.tokenExpiry })
|
|
93
|
+
);
|
|
94
|
+
} catch {
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const session = { user: { id: email, email } };
|
|
98
|
+
for (const listener of this.authListeners) {
|
|
99
|
+
listener("SIGNED_IN", session);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
async getSession() {
|
|
103
|
+
if (this.accessToken && Date.now() < this.tokenExpiry) {
|
|
104
|
+
return { user: { id: this.userEmail || "", email: this.userEmail || "" } };
|
|
105
|
+
}
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
async signOut() {
|
|
109
|
+
this.accessToken = null;
|
|
110
|
+
this.tokenExpiry = 0;
|
|
111
|
+
this.userEmail = null;
|
|
112
|
+
this.metadataCache = null;
|
|
113
|
+
if (typeof window !== "undefined") {
|
|
114
|
+
try {
|
|
115
|
+
sessionStorage.removeItem(TOKEN_STORAGE_KEY);
|
|
116
|
+
} catch {
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
for (const listener of this.authListeners) {
|
|
120
|
+
listener("SIGNED_OUT", null);
|
|
121
|
+
}
|
|
122
|
+
return { error: null };
|
|
123
|
+
}
|
|
124
|
+
onAuthStateChange(callback) {
|
|
125
|
+
this.authListeners.add(callback);
|
|
126
|
+
return {
|
|
127
|
+
data: {
|
|
128
|
+
subscription: {
|
|
129
|
+
unsubscribe: () => {
|
|
130
|
+
this.authListeners.delete(callback);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// -- API calls -------------------------------------------------------------
|
|
137
|
+
async apiCall(path, body) {
|
|
138
|
+
if (!this.accessToken) {
|
|
139
|
+
throw new SemanticLayerError("Not authenticated", "AUTH_ERROR");
|
|
140
|
+
}
|
|
141
|
+
const resp = await fetch(`${this.gatewayUrl}${path}`, {
|
|
142
|
+
method: "POST",
|
|
143
|
+
headers: {
|
|
144
|
+
Authorization: `Bearer ${this.accessToken}`,
|
|
145
|
+
"Content-Type": "application/json"
|
|
146
|
+
},
|
|
147
|
+
body: body !== void 0 ? JSON.stringify(body) : void 0
|
|
148
|
+
});
|
|
149
|
+
const data = await resp.json();
|
|
150
|
+
if (!resp.ok || data?.error) {
|
|
151
|
+
throw new SemanticLayerError(
|
|
152
|
+
data?.error || `Request failed: ${resp.status}`,
|
|
153
|
+
resp.status === 401 ? "AUTH_ERROR" : "API_ERROR"
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
return data;
|
|
157
|
+
}
|
|
158
|
+
// -- Metadata --------------------------------------------------------------
|
|
159
|
+
async getMetadata(forceRefresh = false) {
|
|
160
|
+
const now = Date.now();
|
|
161
|
+
if (!forceRefresh && this.metadataCache && now - this.metadataCacheTime < this.CACHE_TTL_MS) {
|
|
162
|
+
return this.metadataCache;
|
|
163
|
+
}
|
|
164
|
+
const data = await this.apiCall("/v1/metadata");
|
|
165
|
+
this.metadataCache = data;
|
|
166
|
+
this.metadataCacheTime = now;
|
|
167
|
+
return data;
|
|
168
|
+
}
|
|
169
|
+
async getMetrics() {
|
|
170
|
+
const { fields } = await this.getMetadata();
|
|
171
|
+
return fields.filter((f) => f.type === "metric");
|
|
172
|
+
}
|
|
173
|
+
async getDimensions() {
|
|
174
|
+
const { fields } = await this.getMetadata();
|
|
175
|
+
return fields.filter((f) => f.type === "dimension" || f.type === "time_dimension");
|
|
176
|
+
}
|
|
177
|
+
async getField(nameOrId) {
|
|
178
|
+
const { fields } = await this.getMetadata();
|
|
179
|
+
return fields.find((f) => f.name === nameOrId || f.id === nameOrId);
|
|
180
|
+
}
|
|
181
|
+
// -- Query -----------------------------------------------------------------
|
|
182
|
+
async query(config) {
|
|
183
|
+
if (config.values.length === 0) {
|
|
184
|
+
return { columns: [], rows: [], totalRows: 0, executionTimeMs: 0 };
|
|
185
|
+
}
|
|
186
|
+
return this.apiCall("/v1/query", { config });
|
|
187
|
+
}
|
|
188
|
+
async simpleQuery(input) {
|
|
189
|
+
const { fields } = await this.getMetadata();
|
|
190
|
+
const fieldMap = new Map(fields.map((f) => [f.name, f]));
|
|
191
|
+
const values = input.metrics.map((name) => {
|
|
192
|
+
const field = fieldMap.get(name);
|
|
193
|
+
if (!field) throw new SemanticLayerError(`Unknown metric: "${name}"`, "UNKNOWN_FIELD");
|
|
194
|
+
return { fieldId: field.id, field };
|
|
195
|
+
});
|
|
196
|
+
const rows = (input.groupBy || []).map((name) => {
|
|
197
|
+
const field = fieldMap.get(name);
|
|
198
|
+
if (!field) throw new SemanticLayerError(`Unknown dimension: "${name}"`, "UNKNOWN_FIELD");
|
|
199
|
+
const grain = field.type === "time_dimension" ? input.grain : void 0;
|
|
200
|
+
return { fieldId: field.id, field, grain };
|
|
201
|
+
});
|
|
202
|
+
const filters = Object.entries(input.filters || {}).map(([name, filterValues]) => {
|
|
203
|
+
const field = fieldMap.get(name);
|
|
204
|
+
if (!field) throw new SemanticLayerError(`Unknown filter field: "${name}"`, "UNKNOWN_FIELD");
|
|
205
|
+
return { fieldId: field.id, field, filterValues };
|
|
206
|
+
});
|
|
207
|
+
return this.query({ values, rows, columns: [], filters });
|
|
208
|
+
}
|
|
209
|
+
// -- Admin -----------------------------------------------------------------
|
|
210
|
+
async adminCall(action, body = {}) {
|
|
211
|
+
return this.apiCall("/v1/admin", { action, ...body });
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
var SemanticLayerError = class extends Error {
|
|
215
|
+
constructor(message, code) {
|
|
216
|
+
super(message);
|
|
217
|
+
this.name = "SemanticLayerError";
|
|
218
|
+
this.code = code;
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
exports.SemanticLayerClient = SemanticLayerClient;
|
|
223
|
+
exports.SemanticLayerError = SemanticLayerError;
|
|
224
|
+
//# sourceMappingURL=chunk-W64RGDXH.cjs.map
|
|
225
|
+
//# sourceMappingURL=chunk-W64RGDXH.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":"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","file":"chunk-W64RGDXH.cjs","sourcesContent":["import type {\n SemanticLayerConfig,\n MetadataResponse,\n PivotConfig,\n QueryResult,\n SimpleQueryInput,\n SemanticField,\n CuratedField,\n AccessRole,\n UserRoleAssignment,\n UserFieldOverride,\n} from \"./types\";\n\nconst TOKEN_STORAGE_KEY = \"semantic-layer-token\";\n\nexport class SemanticLayerClient {\n readonly gatewayUrl: string;\n private accessToken: string | null = null;\n private tokenExpiry = 0;\n private userEmail: string | null = null;\n private metadataCache: MetadataResponse | null = null;\n private metadataCacheTime = 0;\n private readonly CACHE_TTL_MS = 5 * 60 * 1000;\n private authListeners = new Set<(event: string, session: SessionLike | null) => void>();\n\n constructor(config: SemanticLayerConfig) {\n this.gatewayUrl = config.gatewayUrl;\n\n if (typeof window !== \"undefined\") {\n try {\n const stored = sessionStorage.getItem(TOKEN_STORAGE_KEY);\n if (stored) {\n const parsed = JSON.parse(stored);\n if (parsed.expiresAt > Date.now()) {\n this.accessToken = parsed.token;\n this.tokenExpiry = parsed.expiresAt;\n this.userEmail = parsed.email || null;\n } else {\n sessionStorage.removeItem(TOKEN_STORAGE_KEY);\n }\n }\n } catch {\n // Ignore storage errors\n }\n }\n }\n\n // -- Auth ------------------------------------------------------------------\n\n /**\n * Returns the URL to redirect the browser to for Google sign-in.\n * After the user authenticates, the gateway redirects back to returnUrl\n * with the access token in the URL hash fragment.\n */\n getSignInUrl(returnUrl?: string): string {\n const target = returnUrl || (typeof window !== \"undefined\" ? window.location.href.split(\"#\")[0] : \"\");\n return `${this.gatewayUrl}/auth/google?returnUrl=${encodeURIComponent(target)}`;\n }\n\n /**\n * Check the current URL hash for auth tokens (set by the gateway callback redirect).\n * If found, extracts them, stores the session, clears the hash, and returns true.\n */\n handleAuthCallback(): boolean {\n if (typeof window === \"undefined\") return false;\n\n const hash = window.location.hash.slice(1);\n if (!hash) return false;\n\n const params = new URLSearchParams(hash);\n\n const authError = params.get(\"auth_error\");\n if (authError) {\n window.history.replaceState(null, \"\", window.location.pathname + window.location.search);\n throw new SemanticLayerError(authError, \"AUTH_ERROR\");\n }\n\n const accessToken = params.get(\"access_token\");\n const email = params.get(\"email\");\n const expiresIn = parseInt(params.get(\"expires_in\") || \"0\", 10);\n\n if (!accessToken || !email) return false;\n\n window.history.replaceState(null, \"\", window.location.pathname + window.location.search);\n this.setAccessToken(accessToken, email, expiresIn);\n return true;\n }\n\n /**\n * Set the Google access token (called after OAuth redirect callback).\n */\n setAccessToken(token: string, email: string, expiresIn: number) {\n this.accessToken = token;\n this.userEmail = email;\n this.tokenExpiry = Date.now() + expiresIn * 1000;\n\n if (typeof window !== \"undefined\") {\n try {\n sessionStorage.setItem(\n TOKEN_STORAGE_KEY,\n JSON.stringify({ token, email, expiresAt: this.tokenExpiry }),\n );\n } catch {\n // Ignore storage errors\n }\n }\n\n const session: SessionLike = { user: { id: email, email } };\n for (const listener of this.authListeners) {\n listener(\"SIGNED_IN\", session);\n }\n }\n\n async getSession(): Promise<SessionLike | null> {\n if (this.accessToken && Date.now() < this.tokenExpiry) {\n return { user: { id: this.userEmail || \"\", email: this.userEmail || \"\" } };\n }\n return null;\n }\n\n async signOut() {\n this.accessToken = null;\n this.tokenExpiry = 0;\n this.userEmail = null;\n this.metadataCache = null;\n\n if (typeof window !== \"undefined\") {\n try {\n sessionStorage.removeItem(TOKEN_STORAGE_KEY);\n } catch {\n // Ignore storage errors\n }\n }\n\n for (const listener of this.authListeners) {\n listener(\"SIGNED_OUT\", null);\n }\n\n return { error: null };\n }\n\n onAuthStateChange(callback: (event: string, session: SessionLike | null) => void) {\n this.authListeners.add(callback);\n return {\n data: {\n subscription: {\n unsubscribe: () => {\n this.authListeners.delete(callback);\n },\n },\n },\n };\n }\n\n // -- API calls -------------------------------------------------------------\n\n private async apiCall<T>(path: string, body?: unknown): Promise<T> {\n if (!this.accessToken) {\n throw new SemanticLayerError(\"Not authenticated\", \"AUTH_ERROR\");\n }\n\n const resp = await fetch(`${this.gatewayUrl}${path}`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.accessToken}`,\n \"Content-Type\": \"application/json\",\n },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n\n const data = await resp.json();\n\n if (!resp.ok || data?.error) {\n throw new SemanticLayerError(\n data?.error || `Request failed: ${resp.status}`,\n resp.status === 401 ? \"AUTH_ERROR\" : \"API_ERROR\",\n );\n }\n\n return data as T;\n }\n\n // -- Metadata --------------------------------------------------------------\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 = await this.apiCall<MetadataResponse>(\"/v1/metadata\");\n this.metadataCache = data;\n this.metadataCacheTime = now;\n return data;\n }\n\n async getMetrics(): Promise<SemanticField[]> {\n const { fields } = await this.getMetadata();\n return fields.filter((f) => f.type === \"metric\");\n }\n\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 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 async query(config: PivotConfig): Promise<QueryResult> {\n if (config.values.length === 0) {\n return { columns: [], rows: [], totalRows: 0, executionTimeMs: 0 };\n }\n return this.apiCall<QueryResult>(\"/v1/query\", { config });\n }\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 // -- Admin -----------------------------------------------------------------\n\n private async adminCall<T>(action: string, body: Record<string, unknown> = {}): Promise<T> {\n return this.apiCall<T>(\"/v1/admin\", { action, ...body });\n }\n\n readonly admin = {\n listFields: () => this.adminCall<{ fields: CuratedField[] }>(\"fields.list\"),\n createField: (input: { field_name: string; field_type: string; display_name?: string; description?: string }) =>\n this.adminCall<{ field: CuratedField }>(\"fields.create\", input),\n updateField: (input: { id: number; field_name?: string; display_name?: string; description?: string; is_active?: boolean }) =>\n this.adminCall<{ field: CuratedField }>(\"fields.update\", input),\n deleteField: (id: number) =>\n this.adminCall<{ deleted: boolean }>(\"fields.delete\", { id }),\n\n listRoles: () => this.adminCall<{ roles: AccessRole[] }>(\"roles.list\"),\n createRole: (input: { name: string; description?: string; is_default?: boolean }) =>\n this.adminCall<{ role: AccessRole }>(\"roles.create\", input),\n updateRole: (input: { id: number; name?: string; description?: string; is_default?: boolean }) =>\n this.adminCall<{ role: AccessRole }>(\"roles.update\", input),\n deleteRole: (id: number) =>\n this.adminCall<{ deleted: boolean }>(\"roles.delete\", { id }),\n setRoleFields: (role_id: number, curated_field_ids: number[]) =>\n this.adminCall<{ role_id: number; field_count: number }>(\"roles.setFields\", { role_id, curated_field_ids }),\n\n listUsers: () => this.adminCall<{ users: UserRoleAssignment[] }>(\"users.list\"),\n assignUserRole: (input: { email: string; role_id: number; is_admin?: boolean }) =>\n this.adminCall<{ assignment: UserRoleAssignment }>(\"users.assignRole\", input),\n removeUserRole: (input: { email: string; role_id: number }) =>\n this.adminCall<{ deleted: boolean }>(\"users.removeRole\", input),\n\n listUserOverrides: (user_id: string) =>\n this.adminCall<{ overrides: UserFieldOverride[] }>(\"users.listOverrides\", { user_id }),\n setUserOverride: (input: { user_id: string; curated_field_id: number; access: \"grant\" | \"deny\" }) =>\n this.adminCall<{ override: UserFieldOverride }>(\"users.setOverride\", input),\n removeUserOverride: (input: { user_id: string; curated_field_id: number }) =>\n this.adminCall<{ deleted: boolean }>(\"users.removeOverride\", input),\n };\n}\n\nexport interface SessionLike {\n user: { id: string; email: string };\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"]}
|