@bonnard/sdk
Advanced tools
@@ -1,2 +0,2 @@ | ||
| "use strict";var Bonnard=(()=>{var m=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var b=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var w=(e,r)=>{for(var s in r)m(e,s,{get:r[s],enumerable:!0})},R=(e,r,s,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of b(r))!h.call(e,i)&&i!==s&&m(e,i,{get:()=>r[i],enumerable:!(a=f(r,i))||a.enumerable});return e};var T=e=>R(m({},"__esModule",{value:!0}),e);var Q={};w(Q,{createClient:()=>d,toCubeQuery:()=>l});function l(e){let r={};return e.measures&&(r.measures=e.measures),e.dimensions&&(r.dimensions=e.dimensions),e.filters&&(r.filters=e.filters.map(s=>({member:s.dimension,operator:s.operator,values:s.values}))),e.timeDimension&&(r.timeDimensions=[{dimension:e.timeDimension.dimension,granularity:e.timeDimension.granularity,dateRange:e.timeDimension.dateRange}]),e.orderBy&&(r.order=Object.entries(e.orderBy).map(([s,a])=>[s,a])),e.limit&&(r.limit=e.limit),r}function g(e){try{let r=e.split(".");if(r.length!==3)return 0;let s=r[1].replace(/-/g,"+").replace(/_/g,"/"),a=JSON.parse(atob(s));return typeof a.exp=="number"?a.exp*1e3:0}catch{return 0}}var D=6e4;function d(e){let r=e.baseUrl||"https://app.bonnard.dev",s=null,a=0;async function i(){if(e.apiKey)return e.apiKey;if(e.fetchToken){let t=Date.now();if(s&&a-D>t)return s;let n=await e.fetchToken();return s=n,a=g(n),n}throw new Error("BonnardConfig requires either apiKey or fetchToken")}async function y(t,n){let o=await i(),u=await fetch(`${r}${t}`,{method:"POST",headers:{Authorization:`Bearer ${o}`,"Content-Type":"application/json"},body:JSON.stringify(n)});if(!u.ok){let p=await u.json().catch(()=>({error:u.statusText}));throw new Error(p.error||"Query failed")}return u.json()}async function c(t){let n=await i(),o=await fetch(`${r}${t}`,{method:"GET",headers:{Authorization:`Bearer ${n}`}});if(!o.ok){let u=await o.json().catch(()=>({error:o.statusText}));throw new Error(u.error||"Request failed")}return o.json()}return{async query(t){let n=l(t),o=await y("/api/cube/query",{query:n});return{data:o.data,annotation:o.annotation}},async rawQuery(t){let n=await y("/api/cube/query",{query:t});return{data:n.data,annotation:n.annotation}},async sql(t){return y("/api/cube/query",{sql:t})},async explore(t){let n=await c("/api/cube/meta");return t?.viewsOnly??!0?{cubes:n.cubes.filter(u=>u.type==="view")}:n},async getDashboard(t){return c(`/api/dashboards/${encodeURIComponent(t)}`)},async listDashboards(){return c("/api/dashboards")},async docs(t){let n=new URLSearchParams;t?.topic?n.set("topic",t.topic):t?.category&&n.set("category",t.category);let o=n.toString();return c(`/api/docs${o?`?${o}`:""}`)}}}return T(Q);})(); | ||
| "use strict";var Bonnard=(()=>{var y=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var b=(e,r)=>{for(var o in r)y(e,o,{get:r[o],enumerable:!0})},R=(e,r,o,i)=>{if(r&&typeof r=="object"||typeof r=="function")for(let a of w(r))!T.call(e,a)&&a!==o&&y(e,a,{get:()=>r[a],enumerable:!(i=f(r,a))||i.enumerable});return e};var g=e=>R(y({},"__esModule",{value:!0}),e);var k={};b(k,{createClient:()=>p,toCubeQuery:()=>c});function c(e){let r={};return e.measures&&(r.measures=e.measures),e.dimensions&&(r.dimensions=e.dimensions),e.filters&&(r.filters=e.filters.map(o=>({member:o.dimension,operator:o.operator,values:o.values}))),e.timeDimension&&(r.timeDimensions=[{dimension:e.timeDimension.dimension,granularity:e.timeDimension.granularity,dateRange:e.timeDimension.dateRange}]),e.orderBy&&(r.order=Object.entries(e.orderBy).map(([o,i])=>[o,i])),e.limit&&(r.limit=e.limit),r}function h(e){try{let r=e.split(".");if(r.length!==3)return 0;let o=r[1].replace(/-/g,"+").replace(/_/g,"/"),i=JSON.parse(atob(o));return typeof i.exp=="number"?i.exp*1e3:0}catch{return 0}}var Q=6e4;function p(e){let r=e.baseUrl||"https://app.bonnard.dev",o=null,i=0;async function a(){if(e.apiKey)return e.apiKey;if(e.fetchToken){let n=Date.now();if(o&&i-Q>n)return o;let t=await e.fetchToken();return o=t,i=h(t),t}throw new Error("BonnardConfig requires either apiKey or fetchToken")}async function l(n,t){let s=await a(),u=await fetch(`${r}${n}`,{method:"POST",headers:{Authorization:`Bearer ${s}`,"Content-Type":"application/json"},body:JSON.stringify(t)});if(!u.ok){let d=await u.json().catch(()=>({error:u.statusText}));throw new Error(d.error||"Query failed")}return u.json()}async function m(n){let t=await a(),s=await fetch(`${r}${n}`,{method:"GET",headers:{Authorization:`Bearer ${t}`}});if(!s.ok){let u=await s.json().catch(()=>({error:s.statusText}));throw new Error(u.error||"Request failed")}return s.json()}return{async query(n){let t=c(n),s=await l("/api/cube/query",{query:t});return{data:s.data,annotation:s.annotation}},async rawQuery(n){let t=await l("/api/cube/query",{query:n});return{data:t.data,annotation:t.annotation}},async sql(n){return l("/api/cube/query",{sql:n})},async explore(n){let t=await m("/api/cube/meta");return n?.viewsOnly??!0?{cubes:t.cubes.filter(u=>u.type==="view")}:t},async docs(n){let t=new URLSearchParams;n?.topic?t.set("topic",n.topic):n?.category&&t.set("category",n.category);let s=t.toString();return m(`/api/docs${s?`?${s}`:""}`)}}}return g(k);})(); | ||
| //# sourceMappingURL=bonnard.iife.js.map |
| { | ||
| "version": 3, | ||
| "sources": ["../src/browser.ts", "../src/query.ts", "../src/client.ts"], | ||
| "sourcesContent": ["export { createClient } from './client.js';\nexport { toCubeQuery } from './query.js';\n", "/**\n * Bonnard SDK \u2014 Query format conversion (zero IO)\n */\n\nimport type { QueryOptions } from './types.js';\n\n/**\n * Convert SDK QueryOptions into a Cube-native query object.\n * All field names must be fully qualified (e.g. \"orders.revenue\").\n */\nexport function toCubeQuery(options: QueryOptions): Record<string, unknown> {\n const cubeQuery: Record<string, unknown> = {};\n\n if (options.measures) {\n cubeQuery.measures = options.measures;\n }\n\n if (options.dimensions) {\n cubeQuery.dimensions = options.dimensions;\n }\n\n if (options.filters) {\n cubeQuery.filters = options.filters.map(f => ({\n member: f.dimension,\n operator: f.operator,\n values: f.values,\n }));\n }\n\n if (options.timeDimension) {\n cubeQuery.timeDimensions = [{\n dimension: options.timeDimension.dimension,\n granularity: options.timeDimension.granularity,\n dateRange: options.timeDimension.dateRange,\n }];\n }\n\n if (options.orderBy) {\n cubeQuery.order = Object.entries(options.orderBy).map(([key, dir]) => [key, dir]);\n }\n\n if (options.limit) {\n cubeQuery.limit = options.limit;\n }\n\n return cubeQuery;\n}\n", "/**\n * Bonnard SDK \u2014 Client for querying semantic layer\n */\n\nimport type {\n BonnardConfig,\n QueryOptions,\n QueryResult,\n SqlResult,\n CubeQuery,\n ExploreMeta,\n ExploreOptions,\n DashboardResult,\n DashboardListResult,\n DocsOptions,\n DocsTopicListResult,\n DocsTopicResult,\n} from './types.js';\nimport { toCubeQuery } from './query.js';\n\n/**\n * Parse JWT expiry from the payload (base64url-decoded middle segment).\n * Returns the `exp` claim as a millisecond timestamp, or 0 if unparseable.\n */\nfunction parseJwtExpiry(token: string): number {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return 0;\n // base64url \u2192 base64 \u2192 decode\n const payload = parts[1]!.replace(/-/g, '+').replace(/_/g, '/');\n const json = JSON.parse(atob(payload));\n return typeof json.exp === 'number' ? json.exp * 1000 : 0;\n } catch {\n return 0;\n }\n}\n\nconst REFRESH_BUFFER_MS = 60_000; // refresh 60s before expiry\n\nexport function createClient(config: BonnardConfig) {\n const baseUrl = config.baseUrl || 'https://app.bonnard.dev';\n\n // Token cache for fetchToken mode\n let cachedToken: string | null = null;\n let cachedExpiry = 0;\n\n async function getToken(): Promise<string> {\n // Static API key \u2014 return directly\n if (config.apiKey) {\n return config.apiKey;\n }\n\n // Token callback \u2014 cache and refresh\n if (config.fetchToken) {\n const now = Date.now();\n if (cachedToken && cachedExpiry - REFRESH_BUFFER_MS > now) {\n return cachedToken;\n }\n\n const token = await config.fetchToken();\n cachedToken = token;\n cachedExpiry = parseJwtExpiry(token);\n return token;\n }\n\n throw new Error('BonnardConfig requires either apiKey or fetchToken');\n }\n\n async function request<T>(endpoint: string, body: unknown): Promise<T> {\n const token = await getToken();\n const res = await fetch(`${baseUrl}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const error = await res.json().catch(() => ({ error: res.statusText }));\n throw new Error(error.error || 'Query failed');\n }\n\n return res.json();\n }\n\n async function requestGet<T>(endpoint: string): Promise<T> {\n const token = await getToken();\n const res = await fetch(`${baseUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${token}`,\n },\n });\n\n if (!res.ok) {\n const error = await res.json().catch(() => ({ error: res.statusText }));\n throw new Error(error.error || 'Request failed');\n }\n\n return res.json();\n }\n\n return {\n /**\n * Execute a JSON query against the semantic layer.\n * All field names must be fully qualified (e.g. \"orders.revenue\").\n */\n async query<T = Record<string, unknown>>(options: QueryOptions): Promise<QueryResult<T>> {\n const cubeQuery = toCubeQuery(options);\n\n const result = await request<{ data: T[]; annotation?: QueryResult['annotation'] }>(\n '/api/cube/query',\n { query: cubeQuery }\n );\n\n return { data: result.data, annotation: result.annotation };\n },\n\n /**\n * Execute a raw Cube-native JSON query against the semantic layer.\n * Use this when you already have a Cube API query object.\n */\n async rawQuery<T = Record<string, unknown>>(cubeQuery: CubeQuery): Promise<QueryResult<T>> {\n const result = await request<{ data: T[]; annotation?: QueryResult['annotation'] }>(\n '/api/cube/query',\n { query: cubeQuery }\n );\n\n return { data: result.data, annotation: result.annotation };\n },\n\n /**\n * Execute a SQL query against the semantic layer\n */\n async sql<T = Record<string, unknown>>(query: string): Promise<SqlResult<T>> {\n return request<SqlResult<T>>('/api/cube/query', { sql: query });\n },\n\n /**\n * Discover available cubes, measures, dimensions, and segments.\n * By default returns only views (viewsOnly: true).\n */\n async explore(options?: ExploreOptions): Promise<ExploreMeta> {\n const meta = await requestGet<{ cubes: ExploreMeta['cubes'] }>('/api/cube/meta');\n const viewsOnly = options?.viewsOnly ?? true;\n\n if (viewsOnly) {\n return { cubes: meta.cubes.filter(c => c.type === 'view') };\n }\n\n return meta;\n },\n\n /**\n * Fetch a single dashboard by slug.\n */\n async getDashboard(slug: string): Promise<DashboardResult> {\n return requestGet<DashboardResult>(`/api/dashboards/${encodeURIComponent(slug)}`);\n },\n\n /**\n * List all dashboards for the current organization.\n */\n async listDashboards(): Promise<DashboardListResult> {\n return requestGet<DashboardListResult>('/api/dashboards');\n },\n\n /**\n * Access Bonnard documentation.\n * - `docs()` \u2014 list all topics\n * - `docs({ category: 'dashboards' })` \u2014 list topics in a category\n * - `docs({ topic: 'dashboards.components' })` \u2014 get full markdown content\n */\n async docs(options?: DocsOptions): Promise<DocsTopicListResult | DocsTopicResult> {\n const params = new URLSearchParams();\n if (options?.topic) params.set('topic', options.topic);\n else if (options?.category) params.set('category', options.category);\n const qs = params.toString();\n return requestGet(`/api/docs${qs ? `?${qs}` : ''}`);\n },\n };\n}\n"], | ||
| "mappings": "2bAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,kBAAAE,EAAA,gBAAAC,ICUO,SAASC,EAAYC,EAAgD,CAC1E,IAAMC,EAAqC,CAAC,EAE5C,OAAID,EAAQ,WACVC,EAAU,SAAWD,EAAQ,UAG3BA,EAAQ,aACVC,EAAU,WAAaD,EAAQ,YAG7BA,EAAQ,UACVC,EAAU,QAAUD,EAAQ,QAAQ,IAAIE,IAAM,CAC5C,OAAQA,EAAE,UACV,SAAUA,EAAE,SACZ,OAAQA,EAAE,MACZ,EAAE,GAGAF,EAAQ,gBACVC,EAAU,eAAiB,CAAC,CAC1B,UAAWD,EAAQ,cAAc,UACjC,YAAaA,EAAQ,cAAc,YACnC,UAAWA,EAAQ,cAAc,SACnC,CAAC,GAGCA,EAAQ,UACVC,EAAU,MAAQ,OAAO,QAAQD,EAAQ,OAAO,EAAE,IAAI,CAAC,CAACG,EAAKC,CAAG,IAAM,CAACD,EAAKC,CAAG,CAAC,GAG9EJ,EAAQ,QACVC,EAAU,MAAQD,EAAQ,OAGrBC,CACT,CCtBA,SAASI,EAAeC,EAAuB,CAC7C,GAAI,CACF,IAAMC,EAAQD,EAAM,MAAM,GAAG,EAC7B,GAAIC,EAAM,SAAW,EAAG,MAAO,GAE/B,IAAMC,EAAUD,EAAM,CAAC,EAAG,QAAQ,KAAM,GAAG,EAAE,QAAQ,KAAM,GAAG,EACxDE,EAAO,KAAK,MAAM,KAAKD,CAAO,CAAC,EACrC,OAAO,OAAOC,EAAK,KAAQ,SAAWA,EAAK,IAAM,IAAO,CAC1D,MAAQ,CACN,MAAO,EACT,CACF,CAEA,IAAMC,EAAoB,IAEnB,SAASC,EAAaC,EAAuB,CAClD,IAAMC,EAAUD,EAAO,SAAW,0BAG9BE,EAA6B,KAC7BC,EAAe,EAEnB,eAAeC,GAA4B,CAEzC,GAAIJ,EAAO,OACT,OAAOA,EAAO,OAIhB,GAAIA,EAAO,WAAY,CACrB,IAAMK,EAAM,KAAK,IAAI,EACrB,GAAIH,GAAeC,EAAeL,EAAoBO,EACpD,OAAOH,EAGT,IAAMR,EAAQ,MAAMM,EAAO,WAAW,EACtC,OAAAE,EAAcR,EACdS,EAAeV,EAAeC,CAAK,EAC5BA,CACT,CAEA,MAAM,IAAI,MAAM,oDAAoD,CACtE,CAEA,eAAeY,EAAWC,EAAkBC,EAA2B,CACrE,IAAMd,EAAQ,MAAMU,EAAS,EACvBK,EAAM,MAAM,MAAM,GAAGR,CAAO,GAAGM,CAAQ,GAAI,CAC/C,OAAQ,OACR,QAAS,CACP,cAAiB,UAAUb,CAAK,GAChC,eAAgB,kBAClB,EACA,KAAM,KAAK,UAAUc,CAAI,CAC3B,CAAC,EAED,GAAI,CAACC,EAAI,GAAI,CACX,IAAMC,EAAQ,MAAMD,EAAI,KAAK,EAAE,MAAM,KAAO,CAAE,MAAOA,EAAI,UAAW,EAAE,EACtE,MAAM,IAAI,MAAMC,EAAM,OAAS,cAAc,CAC/C,CAEA,OAAOD,EAAI,KAAK,CAClB,CAEA,eAAeE,EAAcJ,EAA8B,CACzD,IAAMb,EAAQ,MAAMU,EAAS,EACvBK,EAAM,MAAM,MAAM,GAAGR,CAAO,GAAGM,CAAQ,GAAI,CAC/C,OAAQ,MACR,QAAS,CACP,cAAiB,UAAUb,CAAK,EAClC,CACF,CAAC,EAED,GAAI,CAACe,EAAI,GAAI,CACX,IAAMC,EAAQ,MAAMD,EAAI,KAAK,EAAE,MAAM,KAAO,CAAE,MAAOA,EAAI,UAAW,EAAE,EACtE,MAAM,IAAI,MAAMC,EAAM,OAAS,gBAAgB,CACjD,CAEA,OAAOD,EAAI,KAAK,CAClB,CAEA,MAAO,CAKL,MAAM,MAAmCG,EAAgD,CACvF,IAAMC,EAAYC,EAAYF,CAAO,EAE/BG,EAAS,MAAMT,EACnB,kBACA,CAAE,MAAOO,CAAU,CACrB,EAEA,MAAO,CAAE,KAAME,EAAO,KAAM,WAAYA,EAAO,UAAW,CAC5D,EAMA,MAAM,SAAsCF,EAA+C,CACzF,IAAME,EAAS,MAAMT,EACnB,kBACA,CAAE,MAAOO,CAAU,CACrB,EAEA,MAAO,CAAE,KAAME,EAAO,KAAM,WAAYA,EAAO,UAAW,CAC5D,EAKA,MAAM,IAAiCC,EAAsC,CAC3E,OAAOV,EAAsB,kBAAmB,CAAE,IAAKU,CAAM,CAAC,CAChE,EAMA,MAAM,QAAQJ,EAAgD,CAC5D,IAAMK,EAAO,MAAMN,EAA4C,gBAAgB,EAG/E,OAFkBC,GAAS,WAAa,GAG/B,CAAE,MAAOK,EAAK,MAAM,OAAOC,GAAKA,EAAE,OAAS,MAAM,CAAE,EAGrDD,CACT,EAKA,MAAM,aAAaE,EAAwC,CACzD,OAAOR,EAA4B,mBAAmB,mBAAmBQ,CAAI,CAAC,EAAE,CAClF,EAKA,MAAM,gBAA+C,CACnD,OAAOR,EAAgC,iBAAiB,CAC1D,EAQA,MAAM,KAAKC,EAAuE,CAChF,IAAMQ,EAAS,IAAI,gBACfR,GAAS,MAAOQ,EAAO,IAAI,QAASR,EAAQ,KAAK,EAC5CA,GAAS,UAAUQ,EAAO,IAAI,WAAYR,EAAQ,QAAQ,EACnE,IAAMS,EAAKD,EAAO,SAAS,EAC3B,OAAOT,EAAW,YAAYU,EAAK,IAAIA,CAAE,GAAK,EAAE,EAAE,CACpD,CACF,CACF", | ||
| "names": ["browser_exports", "__export", "createClient", "toCubeQuery", "toCubeQuery", "options", "cubeQuery", "f", "key", "dir", "parseJwtExpiry", "token", "parts", "payload", "json", "REFRESH_BUFFER_MS", "createClient", "config", "baseUrl", "cachedToken", "cachedExpiry", "getToken", "now", "request", "endpoint", "body", "res", "error", "requestGet", "options", "cubeQuery", "toCubeQuery", "result", "query", "meta", "c", "slug", "params", "qs"] | ||
| "sourcesContent": ["export { createClient } from './client.js';\nexport { toCubeQuery } from './query.js';\n", "/**\n * Bonnard SDK \u2014 Query format conversion (zero IO)\n */\n\nimport type { QueryOptions } from './types.js';\n\n/**\n * Convert SDK QueryOptions into a Cube-native query object.\n * All field names must be fully qualified (e.g. \"orders.revenue\").\n */\nexport function toCubeQuery(options: QueryOptions): Record<string, unknown> {\n const cubeQuery: Record<string, unknown> = {};\n\n if (options.measures) {\n cubeQuery.measures = options.measures;\n }\n\n if (options.dimensions) {\n cubeQuery.dimensions = options.dimensions;\n }\n\n if (options.filters) {\n cubeQuery.filters = options.filters.map(f => ({\n member: f.dimension,\n operator: f.operator,\n values: f.values,\n }));\n }\n\n if (options.timeDimension) {\n cubeQuery.timeDimensions = [{\n dimension: options.timeDimension.dimension,\n granularity: options.timeDimension.granularity,\n dateRange: options.timeDimension.dateRange,\n }];\n }\n\n if (options.orderBy) {\n cubeQuery.order = Object.entries(options.orderBy).map(([key, dir]) => [key, dir]);\n }\n\n if (options.limit) {\n cubeQuery.limit = options.limit;\n }\n\n return cubeQuery;\n}\n", "/**\n * Bonnard SDK \u2014 Client for querying semantic layer\n */\n\nimport type {\n BonnardConfig,\n QueryOptions,\n QueryResult,\n SqlResult,\n CubeQuery,\n ExploreMeta,\n ExploreOptions,\n DocsOptions,\n DocsTopicListResult,\n DocsTopicResult,\n} from './types.js';\nimport { toCubeQuery } from './query.js';\n\n/**\n * Parse JWT expiry from the payload (base64url-decoded middle segment).\n * Returns the `exp` claim as a millisecond timestamp, or 0 if unparseable.\n */\nfunction parseJwtExpiry(token: string): number {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return 0;\n // base64url \u2192 base64 \u2192 decode\n const payload = parts[1]!.replace(/-/g, '+').replace(/_/g, '/');\n const json = JSON.parse(atob(payload));\n return typeof json.exp === 'number' ? json.exp * 1000 : 0;\n } catch {\n return 0;\n }\n}\n\nconst REFRESH_BUFFER_MS = 60_000; // refresh 60s before expiry\n\nexport function createClient(config: BonnardConfig) {\n const baseUrl = config.baseUrl || 'https://app.bonnard.dev';\n\n // Token cache for fetchToken mode\n let cachedToken: string | null = null;\n let cachedExpiry = 0;\n\n async function getToken(): Promise<string> {\n // Static API key \u2014 return directly\n if (config.apiKey) {\n return config.apiKey;\n }\n\n // Token callback \u2014 cache and refresh\n if (config.fetchToken) {\n const now = Date.now();\n if (cachedToken && cachedExpiry - REFRESH_BUFFER_MS > now) {\n return cachedToken;\n }\n\n const token = await config.fetchToken();\n cachedToken = token;\n cachedExpiry = parseJwtExpiry(token);\n return token;\n }\n\n throw new Error('BonnardConfig requires either apiKey or fetchToken');\n }\n\n async function request<T>(endpoint: string, body: unknown): Promise<T> {\n const token = await getToken();\n const res = await fetch(`${baseUrl}${endpoint}`, {\n method: 'POST',\n headers: {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(body),\n });\n\n if (!res.ok) {\n const error = await res.json().catch(() => ({ error: res.statusText }));\n throw new Error(error.error || 'Query failed');\n }\n\n return res.json();\n }\n\n async function requestGet<T>(endpoint: string): Promise<T> {\n const token = await getToken();\n const res = await fetch(`${baseUrl}${endpoint}`, {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${token}`,\n },\n });\n\n if (!res.ok) {\n const error = await res.json().catch(() => ({ error: res.statusText }));\n throw new Error(error.error || 'Request failed');\n }\n\n return res.json();\n }\n\n return {\n /**\n * Execute a JSON query against the semantic layer.\n * All field names must be fully qualified (e.g. \"orders.revenue\").\n */\n async query<T = Record<string, unknown>>(options: QueryOptions): Promise<QueryResult<T>> {\n const cubeQuery = toCubeQuery(options);\n\n const result = await request<{ data: T[]; annotation?: QueryResult['annotation'] }>(\n '/api/cube/query',\n { query: cubeQuery }\n );\n\n return { data: result.data, annotation: result.annotation };\n },\n\n /**\n * Execute a raw Cube-native JSON query against the semantic layer.\n * Use this when you already have a Cube API query object.\n */\n async rawQuery<T = Record<string, unknown>>(cubeQuery: CubeQuery): Promise<QueryResult<T>> {\n const result = await request<{ data: T[]; annotation?: QueryResult['annotation'] }>(\n '/api/cube/query',\n { query: cubeQuery }\n );\n\n return { data: result.data, annotation: result.annotation };\n },\n\n /**\n * Execute a SQL query against the semantic layer\n */\n async sql<T = Record<string, unknown>>(query: string): Promise<SqlResult<T>> {\n return request<SqlResult<T>>('/api/cube/query', { sql: query });\n },\n\n /**\n * Discover available cubes, measures, dimensions, and segments.\n * By default returns only views (viewsOnly: true).\n */\n async explore(options?: ExploreOptions): Promise<ExploreMeta> {\n const meta = await requestGet<{ cubes: ExploreMeta['cubes'] }>('/api/cube/meta');\n const viewsOnly = options?.viewsOnly ?? true;\n\n if (viewsOnly) {\n return { cubes: meta.cubes.filter(c => c.type === 'view') };\n }\n\n return meta;\n },\n\n /**\n * Access Bonnard documentation.\n * - `docs()` \u2014 list all topics\n * - `docs({ category: 'dashboards' })` \u2014 list topics in a category\n * - `docs({ topic: 'dashboards.components' })` \u2014 get full markdown content\n */\n async docs(options?: DocsOptions): Promise<DocsTopicListResult | DocsTopicResult> {\n const params = new URLSearchParams();\n if (options?.topic) params.set('topic', options.topic);\n else if (options?.category) params.set('category', options.category);\n const qs = params.toString();\n return requestGet(`/api/docs${qs ? `?${qs}` : ''}`);\n },\n };\n}\n"], | ||
| "mappings": "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", | ||
| "names": ["browser_exports", "__export", "createClient", "toCubeQuery", "toCubeQuery", "options", "cubeQuery", "f", "key", "dir", "parseJwtExpiry", "token", "parts", "payload", "json", "REFRESH_BUFFER_MS", "createClient", "config", "baseUrl", "cachedToken", "cachedExpiry", "getToken", "now", "request", "endpoint", "body", "res", "error", "requestGet", "options", "cubeQuery", "toCubeQuery", "result", "query", "meta", "c", "params", "qs"] | ||
| } |
+1
-9
| /** | ||
| * Bonnard SDK — Client for querying semantic layer | ||
| */ | ||
| import type { BonnardConfig, QueryOptions, QueryResult, SqlResult, CubeQuery, ExploreMeta, ExploreOptions, DashboardResult, DashboardListResult, DocsOptions, DocsTopicListResult, DocsTopicResult } from './types.js'; | ||
| import type { BonnardConfig, QueryOptions, QueryResult, SqlResult, CubeQuery, ExploreMeta, ExploreOptions, DocsOptions, DocsTopicListResult, DocsTopicResult } from './types.js'; | ||
| export declare function createClient(config: BonnardConfig): { | ||
@@ -26,10 +26,2 @@ /** | ||
| /** | ||
| * Fetch a single dashboard by slug. | ||
| */ | ||
| getDashboard(slug: string): Promise<DashboardResult>; | ||
| /** | ||
| * List all dashboards for the current organization. | ||
| */ | ||
| listDashboards(): Promise<DashboardListResult>; | ||
| /** | ||
| * Access Bonnard documentation. | ||
@@ -36,0 +28,0 @@ * - `docs()` — list all topics |
+0
-12
@@ -114,14 +114,2 @@ /** | ||
| /** | ||
| * Fetch a single dashboard by slug. | ||
| */ | ||
| async getDashboard(slug) { | ||
| return requestGet(`/api/dashboards/${encodeURIComponent(slug)}`); | ||
| }, | ||
| /** | ||
| * List all dashboards for the current organization. | ||
| */ | ||
| async listDashboards() { | ||
| return requestGet('/api/dashboards'); | ||
| }, | ||
| /** | ||
| * Access Bonnard documentation. | ||
@@ -128,0 +116,0 @@ * - `docs()` — list all topics |
+1
-1
| export { createClient } from './client.js'; | ||
| export { toCubeQuery } from './query.js'; | ||
| export type { BonnardConfig, QueryOptions, QueryResult, SqlResult, Filter, TimeDimension, InferQueryResult, CubeQuery, ExploreMeta, CubeMetaItem, CubeFieldMeta, CubeSegmentMeta, ExploreOptions, DashboardResult, DashboardListResult, DocsOptions, DocsTopicSummary, DocsTopicListResult, DocsTopicResult, } from './types.js'; | ||
| export type { BonnardConfig, QueryOptions, QueryResult, SqlResult, Filter, TimeDimension, InferQueryResult, CubeQuery, ExploreMeta, CubeMetaItem, CubeFieldMeta, CubeSegmentMeta, ExploreOptions, DocsOptions, DocsTopicSummary, DocsTopicListResult, DocsTopicResult, } from './types.js'; |
+0
-20
@@ -97,22 +97,2 @@ /** | ||
| }; | ||
| export interface DashboardResult { | ||
| dashboard: { | ||
| slug: string; | ||
| title: string; | ||
| description: string | null; | ||
| content: string; | ||
| version: number; | ||
| created_at: string; | ||
| updated_at: string; | ||
| }; | ||
| } | ||
| export interface DashboardListResult { | ||
| dashboards: Array<{ | ||
| slug: string; | ||
| title: string; | ||
| description: string | null; | ||
| version: number; | ||
| updated_at: string; | ||
| }>; | ||
| } | ||
| export interface DocsOptions { | ||
@@ -119,0 +99,0 @@ topic?: string; |
+1
-1
| { | ||
| "name": "@bonnard/sdk", | ||
| "version": "0.4.1", | ||
| "version": "0.4.2", | ||
| "description": "Bonnard SDK - query your semantic layer from any JavaScript or TypeScript app", | ||
@@ -5,0 +5,0 @@ "type": "module", |
28627
-6.18%348
-10.54%