@b10cks/client 1.0.0 → 1.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/README.md CHANGED
@@ -13,14 +13,11 @@ npm install @b10cks/client
13
13
  ```typescript
14
14
  import { ApiClient, createB10cksDataApi } from '@b10cks/client'
15
15
 
16
- const client = new ApiClient(
17
- {
18
- baseUrl: 'https://api.b10cks.com/api',
19
- token: 'your-access-token',
20
- fetchClient: fetch,
21
- },
22
- new URL(window.location.href)
23
- )
16
+ const client = new ApiClient({
17
+ baseUrl: 'https://api.b10cks.com/api',
18
+ token: 'your-access-token',
19
+ fetchClient: fetch,
20
+ })
24
21
 
25
22
  const dataApi = createB10cksDataApi(client)
26
23
 
@@ -28,7 +25,10 @@ const dataApi = createB10cksDataApi(client)
28
25
  const blocks = await dataApi.getBlocks()
29
26
 
30
27
  // Fetch all contents with pagination
31
- const contents = await dataApi.getContents()
28
+ const contents = await dataApi.getContents({ vid: 'published' })
29
+
30
+ // Fetch a specific content entry
31
+ const content = await dataApi.getContent('home', { vid: 'draft' })
32
32
 
33
33
  // Fetch specific datasource entries
34
34
  const entries = await dataApi.getDataEntries('my-datasource')
@@ -39,7 +39,7 @@ const entries = await dataApi.getDataEntries('my-datasource')
39
39
  - **Simple HTTP Client**: Type-safe API client for b10cks endpoints
40
40
  - **Framework-Agnostic Data API**: Shared `B10cksDataApi` used by all framework SDKs
41
41
  - **Pagination Support**: Automatic handling of paginated responses
42
- - **Revision Tracking**: Built-in support for revision (RV) and version (VID) parameters
42
+ - **Revision Tracking**: Built-in support for revision (RV), with VID passed explicitly in request params
43
43
  - **Flexible Fetch**: Use browser fetch, Node fetch, or a custom fetch implementation
44
44
 
45
45
  ## API Methods
@@ -49,8 +49,8 @@ const entries = await dataApi.getDataEntries('my-datasource')
49
49
 
50
50
  ## Data API Methods
51
51
 
52
- - `getContent(fullSlug, params)`
53
- - `getContents(params)`
52
+ - `getContent(fullSlug, params)` - pass `vid` in `params` when needed
53
+ - `getContents(params)` - pass `vid` in `params` when needed
54
54
  - `getBlocks(params)`
55
55
  - `getDataEntries(source, params)`
56
56
  - `getDataSources(params)`
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const u=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));class f{constructor(t){this.client=t}redirectsCache=null;configCache=new Map;async getResource(t,e={}){const s=await this.client.get(t,e);return this.unwrapResource(s)}async getCollection(t,e={}){return this.client.getAll(t,e)}async getContent(t,e={}){return this.getResource(`contents/${t}`,e)}async getContents(t={}){return this.getCollection("contents",t)}async getBlocks(t={}){return this.getCollection("blocks",t)}async getDataEntries(t,e={}){return this.getCollection(`datasources/${t}/entries`,e)}async getDataSources(t={}){return this.getCollection("datasources",t)}async getSpace(t={}){return this.getResource("spaces/me",t)}async getRedirects(t={},e=!1){if(this.redirectsCache&&!e)return this.redirectsCache;const s=await this.getCollection("redirects",t),i=Object.fromEntries(s.map(({source:n,target:o,status_code:r})=>[n,{target:o,status_code:r}]));return this.redirectsCache=i,i}async getConfig({slug:t="_config",language_iso:e,language:s,bypassCache:i=!1,...n}={}){const o=e??s,r=JSON.stringify({slug:t,language_iso:o,...n});if(!i&&this.configCache.has(r))return this.configCache.get(r);const d=(await this.getContent(t,{...n,language_iso:o})).content??{};return i||this.configCache.set(r,d),d}async syncRevision(t=426713400){const s=(await this.getSpace()).rv||t;return this.client.setRv(s),s}clearCache(){this.redirectsCache=null,this.configCache.clear()}unwrapResource(t){return typeof t=="object"&&t!==null&&"data"in t?t.data:t}}function g(c){return new f(c)}class a{static instance;listeners={};initialized=!1;constructor(){}static getInstance(){return a.instance||(a.instance=new a),a.instance}init(){!this.isInPreviewMode()||this.initialized||(window.addEventListener("message",this.handleMessage),this.initialized=!0)}destroy(){this.initialized&&typeof window<"u"&&window.removeEventListener("message",this.handleMessage),this.initialized=!1;for(const t of Object.keys(this.listeners))this.listeners[t]?.clear()}isInPreviewMode(){return typeof window<"u"&&window.self!==window.top}on(t,e){if(!this.isInPreviewMode())return()=>{};const s=this.listeners[t]||new Set;return this.listeners[t]=s,s.add(e),()=>{s.delete(e)}}selectItem(t){this.isInPreviewMode()&&window.parent.postMessage({type:"SELECT_UPDATE",payload:{selectedItem:t}},"*")}updateField(t,e,s){this.isInPreviewMode()&&window.parent.postMessage({type:"FIELD_UPDATE",payload:{itemId:t,field:e,value:s}},"*")}handleMessage=t=>{if(!t.data||typeof t.data!="object")return;const{type:e,payload:s}=t.data;!e||!s||this.notify(e,s)};notify(t,e){const s=this.listeners[t];if(s)for(const i of s)i(e)}}const p=a.getInstance();let l=0;class v{baseUrl;token;vid;fetchClient;getRvFn;setRvFn;constructor(t,e){this.baseUrl=t.baseUrl.endsWith("/")?t.baseUrl.slice(0,-1):t.baseUrl,this.token=t.token;const s=typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):null;if(t.fetchClient)this.fetchClient=t.fetchClient;else if(s)this.fetchClient=s;else throw new Error("No fetch implementation available. Provide `fetchClient` in ApiClient options.");this.getRvFn=t.getRv,this.setRvFn=t.setRv;const i=this.resolveRequestUrl(e);this.vid=i?.searchParams.get("b10cks_vid")||t.version||"published",this.setRv(i?.searchParams.get("b10cks_rv")||t.rv||l)}async get(t,e={}){const s=this.buildUrl(t,{vid:this.vid,...e,rv:this.getRv(),token:this.token}),i=await this.fetchClient(s),n=await this.parseResponse(i);return this.hasRevision(n)&&this.setRv(n.rv),n}async getAll(t,e={}){const s=await this.get(t,{...e,page:1}),i=this.normalizeCollectionResponse(s);if(i.rv&&this.setRv(i.rv),!i.meta||i.meta.last_page<=1)return i.data;const n=Array.from({length:i.meta.last_page-1},(r,h)=>this.get(t,{...e,page:h+2})),o=await Promise.all(n);return i.data.concat(o.flatMap(r=>this.normalizeCollectionResponse(r).data))}setRv(t){this.setRvFn?this.setRvFn(t):l=t}getRv(){return this.getRvFn?this.getRvFn():l}async parseResponse(t){if(this.isFetchResponse(t)){if(!t.ok)throw new Error(`Request failed with status ${t.status}`);return await t.json()}return t}normalizeCollectionResponse(t){if(this.isCollectionResponseEnvelope(t)){const e=t.data;return{data:e.data,meta:e.meta,rv:t.rv||e.rv}}if(Array.isArray(t))return{data:t,meta:void 0,rv:void 0};if(typeof t=="object"&&t!==null&&"data"in t){const{data:e,meta:s,rv:i}=t;return{data:e,meta:s,rv:i}}return{data:[],meta:void 0,rv:void 0}}buildUrl(t,e){const s=new URL(`${this.baseUrl}/v1/${t}`);return Object.entries(e).forEach(([i,n])=>{n!=null&&s.searchParams.append(i,String(n))}),s.toString()}resolveRequestUrl(t){return t?t instanceof URL?t:new URL(t,"http://localhost"):null}isFetchResponse(t){return typeof t=="object"&&t!==null&&"json"in t&&typeof t.json=="function"&&"ok"in t}hasRevision(t){return typeof t=="object"&&t!==null&&"rv"in t}isCollectionResponseEnvelope(t){return typeof t=="object"&&t!==null&&"data"in t&&typeof t.data=="object"&&t.data!==null&&"data"in t.data&&Array.isArray(t.data.data)}}exports.ApiClient=v;exports.B10cksDataApi=f;exports.PreviewBridge=a;exports.createB10cksDataApi=g;exports.previewBridge=p;exports.types=u;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class f{constructor(t){this.client=t}redirectsCache=null;configCache=new Map;async getResource(t,e={}){const i=await this.client.get(t,e);return this.unwrapResource(i)}async getCollection(t,e={}){return this.client.getAll(t,e)}async getContent(t,e={}){return this.getResource(`contents/${t}`,e)}async getContents(t={}){return this.getCollection("contents",t)}async getBlocks(t={}){return this.getCollection("blocks",t)}async getDataEntries(t,e={}){return this.getCollection(`datasources/${t}/entries`,e)}async getDataSources(t={}){return this.getCollection("datasources",t)}async getSpace(t={}){return this.getResource("spaces/me",t)}async getRedirects(t={},e=!1){if(this.redirectsCache&&!e)return this.redirectsCache;const i=await this.getCollection("redirects",t),s=Object.fromEntries(i.map(({source:n,target:o,status_code:r})=>[n,{target:o,status_code:r}]));return this.redirectsCache=s,s}async getConfig({slug:t="_config",language_iso:e,language:i,bypassCache:s=!1,...n}={}){const o=e??i,r=JSON.stringify({slug:t,language_iso:o,...n});if(!s&&this.configCache.has(r))return this.configCache.get(r);const d=(await this.getContent(t,{...n,language_iso:o})).content??{};return s||this.configCache.set(r,d),d}async syncRevision(t=426713400){const i=(await this.getSpace()).rv||t;return this.client.setRv(i),i}clearCache(){this.redirectsCache=null,this.configCache.clear()}unwrapResource(t){return typeof t=="object"&&t!==null&&"data"in t?t.data:t}}function u(c){return new f(c)}class a{static instance;listeners={};initialized=!1;constructor(){}static getInstance(){return a.instance||(a.instance=new a),a.instance}init(){!this.isInPreviewMode()||this.initialized||(window.addEventListener("message",this.handleMessage),this.initialized=!0)}destroy(){this.initialized&&typeof window<"u"&&window.removeEventListener("message",this.handleMessage),this.initialized=!1;for(const t of Object.keys(this.listeners))this.listeners[t]?.clear()}isInPreviewMode(){return typeof window<"u"&&window.self!==window.top}on(t,e){if(!this.isInPreviewMode())return()=>{};const i=this.listeners[t]||new Set;return this.listeners[t]=i,i.add(e),()=>{i.delete(e)}}selectItem(t){this.isInPreviewMode()&&window.parent.postMessage({type:"SELECT_UPDATE",payload:{selectedItem:t}},"*")}updateField(t,e,i){this.isInPreviewMode()&&window.parent.postMessage({type:"FIELD_UPDATE",payload:{itemId:t,field:e,value:i}},"*")}handleMessage=t=>{if(!t.data||typeof t.data!="object")return;const{type:e,payload:i}=t.data;!e||!i||this.notify(e,i)};notify(t,e){const i=this.listeners[t];if(i)for(const s of i)s(e)}}const g=a.getInstance(),p=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"}));let l=0;class v{baseUrl;token;vid;fetchClient;getRvFn;setRvFn;constructor(t,e){this.baseUrl=t.baseUrl.endsWith("/")?t.baseUrl.slice(0,-1):t.baseUrl,this.token=t.token;const i=typeof globalThis.fetch=="function"?globalThis.fetch.bind(globalThis):null;if(t.fetchClient)this.fetchClient=t.fetchClient;else if(i)this.fetchClient=i;else throw new Error("No fetch implementation available. Provide `fetchClient` in ApiClient options.");this.getRvFn=t.getRv,this.setRvFn=t.setRv;const s=this.resolveRequestUrl(e);this.vid=t.version||"published",this.setRv(s?.searchParams.get("b10cks_rv")||t.rv||l)}async get(t,e={}){const i=this.buildUrl(t,{vid:this.vid,...e,rv:this.getRv(),token:this.token}),s=await this.fetchClient(i),n=await this.parseResponse(s);return this.hasRevision(n)&&this.setRv(n.rv),n}async getAll(t,e={}){const i=await this.get(t,{...e,page:1}),s=this.normalizeCollectionResponse(i);if(s.rv&&this.setRv(s.rv),!s.meta||s.meta.last_page<=1)return s.data;const n=Array.from({length:s.meta.last_page-1},(r,h)=>this.get(t,{...e,page:h+2})),o=await Promise.all(n);return s.data.concat(o.flatMap(r=>this.normalizeCollectionResponse(r).data))}setRv(t){this.setRvFn?this.setRvFn(t):l=t}getRv(){return this.getRvFn?this.getRvFn():l}async parseResponse(t){if(this.isFetchResponse(t)){if(!t.ok)throw new Error(`Request failed with status ${t.status}`);return await t.json()}return t}normalizeCollectionResponse(t){if(this.isCollectionResponseEnvelope(t)){const e=t.data;return{data:e.data,meta:e.meta,rv:t.rv||e.rv}}if(Array.isArray(t))return{data:t,meta:void 0,rv:void 0};if(typeof t=="object"&&t!==null&&"data"in t){const{data:e,meta:i,rv:s}=t;return{data:e,meta:i,rv:s}}return{data:[],meta:void 0,rv:void 0}}buildUrl(t,e){const i=new URL(`${this.baseUrl}/v1/${t}`);return Object.entries(e).forEach(([s,n])=>{n!=null&&i.searchParams.append(s,String(n))}),i.toString()}resolveRequestUrl(t){return t?t instanceof URL?t:new URL(t,"http://localhost"):null}isFetchResponse(t){return typeof t=="object"&&t!==null&&"json"in t&&typeof t.json=="function"&&"ok"in t}hasRevision(t){return typeof t=="object"&&t!==null&&"rv"in t}isCollectionResponseEnvelope(t){return typeof t=="object"&&t!==null&&"data"in t&&typeof t.data=="object"&&t.data!==null&&"data"in t.data&&Array.isArray(t.data.data)}}exports.ApiClient=v;exports.B10cksDataApi=f;exports.PreviewBridge=a;exports.createB10cksDataApi=u;exports.previewBridge=g;exports.types=p;
2
2
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/data-api.ts","../src/preview-bridge.ts","../src/index.ts"],"sourcesContent":["import type {\n Endpoint,\n IBBaseQueryParams,\n IBBlock,\n IBContent,\n IBContentQueryParams,\n IBDataEntry,\n IBDataSource,\n IBRedirect,\n IBSpace,\n} from './types'\n\ntype ApiQueryParams = Omit<IBBaseQueryParams, 'token'>\n\nexport interface DataApiClient {\n get<T>(\n endpoint: Endpoint,\n params?: ApiQueryParams\n ): Promise<T | { data: T; rv?: string | number }>\n getAll<T>(endpoint: Endpoint, params?: ApiQueryParams): Promise<T[]>\n setRv(value: string | number): void\n}\n\nexport type RedirectMap = Record<string, { target: string; status_code: number }>\n\nexport interface GetConfigOptions extends Omit<IBContentQueryParams, 'token' | 'full_slug'> {\n slug?: string\n language?: string\n bypassCache?: boolean\n}\n\nexport class B10cksDataApi {\n private redirectsCache: RedirectMap | null = null\n private readonly configCache = new Map<string, unknown>()\n\n constructor(private readonly client: DataApiClient) {}\n\n async getResource<T>(endpoint: Endpoint, params: ApiQueryParams = {}): Promise<T> {\n const response = await this.client.get<T>(endpoint, params)\n return this.unwrapResource(response)\n }\n\n async getCollection<T>(endpoint: Endpoint, params: ApiQueryParams = {}): Promise<T[]> {\n return this.client.getAll<T>(endpoint, params)\n }\n\n async getContent<T = Record<string, unknown>>(\n fullSlug: string,\n params: Omit<IBContentQueryParams, 'token' | 'full_slug'> = {}\n ): Promise<IBContent<T>> {\n return this.getResource<IBContent<T>>(`contents/${fullSlug}`, params)\n }\n\n async getContents<T = Record<string, unknown>>(\n params: Omit<IBContentQueryParams, 'token'> = {}\n ): Promise<IBContent<T>[]> {\n return this.getCollection<IBContent<T>>('contents', params)\n }\n\n async getBlocks(params: ApiQueryParams = {}): Promise<IBBlock[]> {\n return this.getCollection<IBBlock>('blocks', params)\n }\n\n async getDataEntries(source: string, params: ApiQueryParams = {}): Promise<IBDataEntry[]> {\n return this.getCollection<IBDataEntry>(`datasources/${source}/entries`, params)\n }\n\n async getDataSources(params: ApiQueryParams = {}): Promise<IBDataSource[]> {\n return this.getCollection<IBDataSource>('datasources', params)\n }\n\n async getSpace(params: ApiQueryParams = {}): Promise<IBSpace> {\n return this.getResource<IBSpace>('spaces/me', params)\n }\n\n async getRedirects(params: ApiQueryParams = {}, forceRefresh = false): Promise<RedirectMap> {\n if (this.redirectsCache && !forceRefresh) {\n return this.redirectsCache\n }\n\n const redirects = await this.getCollection<IBRedirect>('redirects', params)\n const map = Object.fromEntries(\n redirects.map(({ source, target, status_code }) => [source, { target, status_code }])\n )\n this.redirectsCache = map\n return map\n }\n\n async getConfig<T = Record<string, unknown>>({\n slug = '_config',\n language_iso,\n language,\n bypassCache = false,\n ...params\n }: GetConfigOptions = {}): Promise<T> {\n const normalizedLanguage = language_iso ?? language\n const cacheKey = JSON.stringify({ slug, language_iso: normalizedLanguage, ...params })\n if (!bypassCache && this.configCache.has(cacheKey)) {\n return this.configCache.get(cacheKey) as T\n }\n\n const configContent = await this.getContent<Record<string, unknown>>(slug, {\n ...params,\n language_iso: normalizedLanguage,\n })\n const value = (configContent.content ?? {}) as T\n\n if (!bypassCache) {\n this.configCache.set(cacheKey, value)\n }\n\n return value\n }\n\n async syncRevision(fallbackRv = 426713400): Promise<string | number> {\n const space = await this.getSpace()\n const nextRv = space.rv || fallbackRv\n this.client.setRv(nextRv)\n return nextRv\n }\n\n clearCache() {\n this.redirectsCache = null\n this.configCache.clear()\n }\n\n private unwrapResource<T>(response: T | { data: T }): T {\n if (typeof response === 'object' && response !== null && 'data' in response) {\n return response.data\n }\n\n return response\n }\n}\n\nexport function createB10cksDataApi(client: DataApiClient): B10cksDataApi {\n return new B10cksDataApi(client)\n}\n","export type ContentUpdateEvent = {\n content: Record<string, unknown>\n}\n\nexport type SelectUpdateEvent = {\n selectedItem: string\n}\n\nexport type FieldUpdateEvent = {\n itemId: string\n field: string\n value: string\n}\n\nexport type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE' | 'FIELD_UPDATE'\n\nexport type EventPayloadMap = {\n CONTENT_UPDATE: ContentUpdateEvent\n SELECT_UPDATE: SelectUpdateEvent\n HOVER_UPDATE: SelectUpdateEvent\n FIELD_UPDATE: FieldUpdateEvent\n}\n\ntype EventCallback<T> = (payload: T) => void\n\nexport type BridgeEvent = {\n type: EventType\n payload: EventPayloadMap[EventType]\n b10cksId?: string\n}\n\nexport class PreviewBridge {\n private static instance: PreviewBridge\n private readonly listeners: Partial<Record<EventType, Set<EventCallback<unknown>>>> = {}\n private initialized = false\n\n private constructor() {}\n\n static getInstance() {\n if (!PreviewBridge.instance) {\n PreviewBridge.instance = new PreviewBridge()\n }\n return PreviewBridge.instance\n }\n\n init() {\n if (!this.isInPreviewMode() || this.initialized) {\n return\n }\n\n window.addEventListener('message', this.handleMessage)\n this.initialized = true\n }\n\n destroy() {\n if (this.initialized && typeof window !== 'undefined') {\n window.removeEventListener('message', this.handleMessage)\n }\n this.initialized = false\n for (const eventType of Object.keys(this.listeners) as EventType[]) {\n this.listeners[eventType]?.clear()\n }\n }\n\n isInPreviewMode(): boolean {\n return typeof window !== 'undefined' && window.self !== window.top\n }\n\n on<T extends EventType>(eventType: T, callback: EventCallback<EventPayloadMap[T]>): () => void {\n if (!this.isInPreviewMode()) {\n return () => {}\n }\n\n const listeners = this.listeners[eventType] || new Set<EventCallback<unknown>>()\n this.listeners[eventType] = listeners\n listeners.add(callback as EventCallback<unknown>)\n\n return () => {\n listeners.delete(callback as EventCallback<unknown>)\n }\n }\n\n selectItem(selectedItem: string) {\n if (!this.isInPreviewMode()) {\n return\n }\n\n window.parent.postMessage(\n {\n type: 'SELECT_UPDATE',\n payload: { selectedItem },\n },\n '*'\n )\n }\n\n updateField(itemId: string, field: string, value: string) {\n if (!this.isInPreviewMode()) {\n return\n }\n\n window.parent.postMessage(\n {\n type: 'FIELD_UPDATE',\n payload: { itemId, field, value },\n },\n '*'\n )\n }\n\n private handleMessage = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== 'object') {\n return\n }\n\n const { type, payload } = event.data as BridgeEvent\n if (!type || !payload) {\n return\n }\n\n this.notify(type, payload as never)\n }\n\n private notify<T extends EventType>(type: T, payload: EventPayloadMap[T]) {\n const callbacks = this.listeners[type]\n if (!callbacks) {\n return\n }\n\n for (const callback of callbacks) {\n ;(callback as EventCallback<EventPayloadMap[T]>)(payload)\n }\n }\n}\n\nexport const previewBridge = PreviewBridge.getInstance()\n","import type {\n B10cksApiClientOptions,\n Endpoint,\n FetchClient,\n IBBaseQueryParams,\n IBCollectionResponse,\n IBMeta,\n IBResponse,\n} from './types'\n\nexport interface B10cksApiClientRvOptions {\n getRv?: () => string | number\n setRv?: (value: string | number) => void\n}\n\nexport * as types from './types'\nexport type * from './types'\nexport * from './data-api'\nexport * from './preview-bridge'\n\nlet rv: string | number = 0\n\ntype ApiResourceResponse<T> = IBResponse<T> | T\ntype ApiCollectionResponse<T> =\n | IBCollectionResponse<T>\n | IBResponse<IBCollectionResponse<T>>\n | T[]\n | { data: T[]; meta?: IBMeta; rv?: string | number }\n\nexport class ApiClient {\n private readonly baseUrl: string\n readonly token: string\n private readonly vid: string | null\n private readonly fetchClient: FetchClient\n private readonly getRvFn?: () => string | number\n private readonly setRvFn?: (value: string | number) => void\n\n constructor(options: B10cksApiClientOptions, requestUrl?: URL | string) {\n this.baseUrl = options.baseUrl.endsWith('/') ? options.baseUrl.slice(0, -1) : options.baseUrl\n this.token = options.token\n const defaultFetch =\n typeof globalThis.fetch === 'function' ? globalThis.fetch.bind(globalThis) : null\n if (options.fetchClient) {\n this.fetchClient = options.fetchClient\n } else if (defaultFetch) {\n this.fetchClient = defaultFetch as FetchClient\n } else {\n throw new Error(\n 'No fetch implementation available. Provide `fetchClient` in ApiClient options.'\n )\n }\n\n this.getRvFn = options.getRv\n this.setRvFn = options.setRv\n\n const url = this.resolveRequestUrl(requestUrl)\n this.vid = url?.searchParams.get('b10cks_vid') || options.version || 'published'\n this.setRv(url?.searchParams.get('b10cks_rv') || options.rv || rv)\n }\n\n async get<T>(\n endpoint: Endpoint,\n params: Omit<IBBaseQueryParams, 'token'> = {}\n ): Promise<ApiResourceResponse<T>> {\n const url = this.buildUrl(endpoint, {\n vid: this.vid,\n ...params,\n rv: this.getRv(),\n token: this.token,\n })\n\n const payload = await this.fetchClient(url)\n const response = await this.parseResponse<ApiResourceResponse<T>>(payload)\n\n if (this.hasRevision(response)) {\n this.setRv(response.rv)\n }\n\n return response\n }\n\n async getAll<T>(endpoint: Endpoint, params: Omit<IBBaseQueryParams, 'token'> = {}): Promise<T[]> {\n const firstResponse = await this.get<IBCollectionResponse<T> & { meta?: IBMeta }>(endpoint, {\n ...params,\n page: 1,\n })\n const normalizedFirstResponse = this.normalizeCollectionResponse<T>(firstResponse)\n\n if (normalizedFirstResponse.rv) {\n this.setRv(normalizedFirstResponse.rv)\n }\n\n if (!normalizedFirstResponse.meta || normalizedFirstResponse.meta.last_page <= 1) {\n return normalizedFirstResponse.data\n }\n\n const pageRequests = Array.from(\n { length: normalizedFirstResponse.meta.last_page - 1 },\n (_, i) => this.get<IBCollectionResponse<T>>(endpoint, { ...params, page: i + 2 })\n )\n\n const allResponses = await Promise.all(pageRequests)\n\n return normalizedFirstResponse.data.concat(\n allResponses.flatMap((response) => this.normalizeCollectionResponse<T>(response).data)\n )\n }\n\n setRv(value: string | number) {\n if (this.setRvFn) {\n this.setRvFn(value)\n } else {\n rv = value\n }\n }\n\n getRv() {\n if (this.getRvFn) {\n return this.getRvFn()\n }\n return rv\n }\n\n private async parseResponse<T>(payload: unknown): Promise<T> {\n if (this.isFetchResponse(payload)) {\n if (!payload.ok) {\n throw new Error(`Request failed with status ${payload.status}`)\n }\n\n return (await payload.json()) as T\n }\n\n return payload as T\n }\n\n private normalizeCollectionResponse<T>(response: ApiCollectionResponse<T>) {\n if (this.isCollectionResponseEnvelope(response)) {\n const nestedResponse = response.data\n\n return {\n data: nestedResponse.data,\n meta: (nestedResponse as IBCollectionResponse<T> & { meta?: IBMeta }).meta,\n rv: response.rv || nestedResponse.rv,\n }\n }\n\n if (Array.isArray(response)) {\n return { data: response, meta: undefined, rv: undefined }\n }\n\n if (typeof response === 'object' && response !== null && 'data' in response) {\n const {\n data,\n meta,\n rv: responseRv,\n } = response as {\n data: T[]\n meta?: IBMeta\n rv?: string | number\n }\n return { data, meta, rv: responseRv }\n }\n\n return { data: [], meta: undefined, rv: undefined }\n }\n\n private buildUrl(endpoint: string, params: Record<string, unknown>): string {\n const url = new URL(`${this.baseUrl}/v1/${endpoint}`)\n\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value))\n }\n })\n\n return url.toString()\n }\n\n private resolveRequestUrl(requestUrl?: URL | string): URL | null {\n if (!requestUrl) {\n return null\n }\n\n if (requestUrl instanceof URL) {\n return requestUrl\n }\n\n return new URL(requestUrl, 'http://localhost')\n }\n\n private isFetchResponse(value: unknown): value is Response {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'json' in value &&\n typeof (value as Response).json === 'function' &&\n 'ok' in value\n )\n }\n\n private hasRevision(value: unknown): value is { rv: string | number } {\n return typeof value === 'object' && value !== null && 'rv' in value\n }\n\n private isCollectionResponseEnvelope<T>(\n value: ApiCollectionResponse<T>\n ): value is IBResponse<IBCollectionResponse<T>> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'data' in value &&\n typeof value.data === 'object' &&\n value.data !== null &&\n 'data' in value.data &&\n Array.isArray(value.data.data)\n )\n }\n}\n"],"names":["B10cksDataApi","client","endpoint","params","response","fullSlug","source","forceRefresh","redirects","map","target","status_code","slug","language_iso","language","bypassCache","normalizedLanguage","cacheKey","value","fallbackRv","nextRv","createB10cksDataApi","PreviewBridge","eventType","callback","listeners","selectedItem","itemId","field","event","type","payload","callbacks","previewBridge","rv","ApiClient","options","requestUrl","defaultFetch","url","firstResponse","normalizedFirstResponse","pageRequests","_","i","allResponses","nestedResponse","data","meta","responseRv","key"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/data-api.ts","../src/preview-bridge.ts","../src/index.ts"],"sourcesContent":["import type {\n Endpoint,\n IBBaseQueryParams,\n IBBlock,\n IBContent,\n IBContentQueryParams,\n IBDataEntry,\n IBDataSource,\n IBRedirect,\n IBSpace,\n} from './types'\n\ntype ApiQueryParams = Omit<IBBaseQueryParams, 'token'>\n\nexport interface DataApiClient {\n get<T>(\n endpoint: Endpoint,\n params?: ApiQueryParams\n ): Promise<T | { data: T; rv?: string | number }>\n getAll<T>(endpoint: Endpoint, params?: ApiQueryParams): Promise<T[]>\n setRv(value: string | number): void\n}\n\nexport type RedirectMap = Record<string, { target: string; status_code: number }>\n\nexport interface GetConfigOptions extends Omit<IBContentQueryParams, 'token' | 'full_slug'> {\n slug?: string\n language?: string\n bypassCache?: boolean\n}\n\nexport class B10cksDataApi {\n private redirectsCache: RedirectMap | null = null\n private readonly configCache = new Map<string, unknown>()\n\n constructor(private readonly client: DataApiClient) {}\n\n async getResource<T>(endpoint: Endpoint, params: ApiQueryParams = {}): Promise<T> {\n const response = await this.client.get<T>(endpoint, params)\n return this.unwrapResource(response)\n }\n\n async getCollection<T>(endpoint: Endpoint, params: ApiQueryParams = {}): Promise<T[]> {\n return this.client.getAll<T>(endpoint, params)\n }\n\n async getContent<T = Record<string, unknown>>(\n fullSlug: string,\n params: Omit<IBContentQueryParams, 'token' | 'full_slug'> = {}\n ): Promise<IBContent<T>> {\n return this.getResource<IBContent<T>>(`contents/${fullSlug}`, params)\n }\n\n async getContents<T = Record<string, unknown>>(\n params: Omit<IBContentQueryParams, 'token'> = {}\n ): Promise<IBContent<T>[]> {\n return this.getCollection<IBContent<T>>('contents', params)\n }\n\n async getBlocks(params: ApiQueryParams = {}): Promise<IBBlock[]> {\n return this.getCollection<IBBlock>('blocks', params)\n }\n\n async getDataEntries(source: string, params: ApiQueryParams = {}): Promise<IBDataEntry[]> {\n return this.getCollection<IBDataEntry>(`datasources/${source}/entries`, params)\n }\n\n async getDataSources(params: ApiQueryParams = {}): Promise<IBDataSource[]> {\n return this.getCollection<IBDataSource>('datasources', params)\n }\n\n async getSpace(params: ApiQueryParams = {}): Promise<IBSpace> {\n return this.getResource<IBSpace>('spaces/me', params)\n }\n\n async getRedirects(params: ApiQueryParams = {}, forceRefresh = false): Promise<RedirectMap> {\n if (this.redirectsCache && !forceRefresh) {\n return this.redirectsCache\n }\n\n const redirects = await this.getCollection<IBRedirect>('redirects', params)\n const map = Object.fromEntries(\n redirects.map(({ source, target, status_code }) => [source, { target, status_code }])\n )\n this.redirectsCache = map\n return map\n }\n\n async getConfig<T = Record<string, unknown>>({\n slug = '_config',\n language_iso,\n language,\n bypassCache = false,\n ...params\n }: GetConfigOptions = {}): Promise<T> {\n const normalizedLanguage = language_iso ?? language\n const cacheKey = JSON.stringify({ slug, language_iso: normalizedLanguage, ...params })\n if (!bypassCache && this.configCache.has(cacheKey)) {\n return this.configCache.get(cacheKey) as T\n }\n\n const configContent = await this.getContent<Record<string, unknown>>(slug, {\n ...params,\n language_iso: normalizedLanguage,\n })\n const value = (configContent.content ?? {}) as T\n\n if (!bypassCache) {\n this.configCache.set(cacheKey, value)\n }\n\n return value\n }\n\n async syncRevision(fallbackRv = 426713400): Promise<string | number> {\n const space = await this.getSpace()\n const nextRv = space.rv || fallbackRv\n this.client.setRv(nextRv)\n return nextRv\n }\n\n clearCache() {\n this.redirectsCache = null\n this.configCache.clear()\n }\n\n private unwrapResource<T>(response: T | { data: T }): T {\n if (typeof response === 'object' && response !== null && 'data' in response) {\n return response.data\n }\n\n return response\n }\n}\n\nexport function createB10cksDataApi(client: DataApiClient): B10cksDataApi {\n return new B10cksDataApi(client)\n}\n","export type ContentUpdateEvent = {\n content: Record<string, unknown>\n}\n\nexport type SelectUpdateEvent = {\n selectedItem: string\n}\n\nexport type FieldUpdateEvent = {\n itemId: string\n field: string\n value: string\n}\n\nexport type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE' | 'FIELD_UPDATE'\n\nexport type EventPayloadMap = {\n CONTENT_UPDATE: ContentUpdateEvent\n SELECT_UPDATE: SelectUpdateEvent\n HOVER_UPDATE: SelectUpdateEvent\n FIELD_UPDATE: FieldUpdateEvent\n}\n\ntype EventCallback<T> = (payload: T) => void\n\nexport type BridgeEvent = {\n type: EventType\n payload: EventPayloadMap[EventType]\n b10cksId?: string\n}\n\nexport class PreviewBridge {\n private static instance: PreviewBridge\n private readonly listeners: Partial<Record<EventType, Set<EventCallback<unknown>>>> = {}\n private initialized = false\n\n private constructor() {}\n\n static getInstance() {\n if (!PreviewBridge.instance) {\n PreviewBridge.instance = new PreviewBridge()\n }\n return PreviewBridge.instance\n }\n\n init() {\n if (!this.isInPreviewMode() || this.initialized) {\n return\n }\n\n window.addEventListener('message', this.handleMessage)\n this.initialized = true\n }\n\n destroy() {\n if (this.initialized && typeof window !== 'undefined') {\n window.removeEventListener('message', this.handleMessage)\n }\n this.initialized = false\n for (const eventType of Object.keys(this.listeners) as EventType[]) {\n this.listeners[eventType]?.clear()\n }\n }\n\n isInPreviewMode(): boolean {\n return typeof window !== 'undefined' && window.self !== window.top\n }\n\n on<T extends EventType>(eventType: T, callback: EventCallback<EventPayloadMap[T]>): () => void {\n if (!this.isInPreviewMode()) {\n return () => {}\n }\n\n const listeners = this.listeners[eventType] || new Set<EventCallback<unknown>>()\n this.listeners[eventType] = listeners\n listeners.add(callback as EventCallback<unknown>)\n\n return () => {\n listeners.delete(callback as EventCallback<unknown>)\n }\n }\n\n selectItem(selectedItem: string) {\n if (!this.isInPreviewMode()) {\n return\n }\n\n window.parent.postMessage(\n {\n type: 'SELECT_UPDATE',\n payload: { selectedItem },\n },\n '*'\n )\n }\n\n updateField(itemId: string, field: string, value: string) {\n if (!this.isInPreviewMode()) {\n return\n }\n\n window.parent.postMessage(\n {\n type: 'FIELD_UPDATE',\n payload: { itemId, field, value },\n },\n '*'\n )\n }\n\n private handleMessage = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== 'object') {\n return\n }\n\n const { type, payload } = event.data as BridgeEvent\n if (!type || !payload) {\n return\n }\n\n this.notify(type, payload as never)\n }\n\n private notify<T extends EventType>(type: T, payload: EventPayloadMap[T]) {\n const callbacks = this.listeners[type]\n if (!callbacks) {\n return\n }\n\n for (const callback of callbacks) {\n ;(callback as EventCallback<EventPayloadMap[T]>)(payload)\n }\n }\n}\n\nexport const previewBridge = PreviewBridge.getInstance()\n","import type {\n B10cksApiClientOptions,\n Endpoint,\n FetchClient,\n IBBaseQueryParams,\n IBCollectionResponse,\n IBMeta,\n IBResponse,\n} from './types'\n\nexport interface B10cksApiClientRvOptions {\n getRv?: () => string | number\n setRv?: (value: string | number) => void\n}\n\nexport * from './data-api'\nexport * from './preview-bridge'\nexport type * from './types'\nexport * as types from './types'\n\nlet rv: string | number = 0\n\ntype ApiResourceResponse<T> = IBResponse<T> | T\ntype ApiCollectionResponse<T> =\n | IBCollectionResponse<T>\n | IBResponse<IBCollectionResponse<T>>\n | T[]\n | { data: T[]; meta?: IBMeta; rv?: string | number }\n\nexport class ApiClient {\n private readonly baseUrl: string\n readonly token: string\n private readonly vid: string\n private readonly fetchClient: FetchClient\n private readonly getRvFn?: () => string | number\n private readonly setRvFn?: (value: string | number) => void\n\n constructor(options: B10cksApiClientOptions, requestUrl?: URL | string) {\n this.baseUrl = options.baseUrl.endsWith('/') ? options.baseUrl.slice(0, -1) : options.baseUrl\n this.token = options.token\n const defaultFetch =\n typeof globalThis.fetch === 'function' ? globalThis.fetch.bind(globalThis) : null\n if (options.fetchClient) {\n this.fetchClient = options.fetchClient\n } else if (defaultFetch) {\n this.fetchClient = defaultFetch as FetchClient\n } else {\n throw new Error(\n 'No fetch implementation available. Provide `fetchClient` in ApiClient options.'\n )\n }\n\n this.getRvFn = options.getRv\n this.setRvFn = options.setRv\n\n const url = this.resolveRequestUrl(requestUrl)\n this.vid = options.version || 'published'\n this.setRv(url?.searchParams.get('b10cks_rv') || options.rv || rv)\n }\n\n async get<T>(\n endpoint: Endpoint,\n params: Omit<IBBaseQueryParams, 'token'> = {}\n ): Promise<ApiResourceResponse<T>> {\n const url = this.buildUrl(endpoint, {\n vid: this.vid,\n ...params,\n rv: this.getRv(),\n token: this.token,\n })\n\n const payload = await this.fetchClient(url)\n const response = await this.parseResponse<ApiResourceResponse<T>>(payload)\n\n if (this.hasRevision(response)) {\n this.setRv(response.rv)\n }\n\n return response\n }\n\n async getAll<T>(endpoint: Endpoint, params: Omit<IBBaseQueryParams, 'token'> = {}): Promise<T[]> {\n const firstResponse = await this.get<IBCollectionResponse<T> & { meta?: IBMeta }>(endpoint, {\n ...params,\n page: 1,\n })\n const normalizedFirstResponse = this.normalizeCollectionResponse<T>(firstResponse)\n\n if (normalizedFirstResponse.rv) {\n this.setRv(normalizedFirstResponse.rv)\n }\n\n if (!normalizedFirstResponse.meta || normalizedFirstResponse.meta.last_page <= 1) {\n return normalizedFirstResponse.data\n }\n\n const pageRequests = Array.from(\n { length: normalizedFirstResponse.meta.last_page - 1 },\n (_, i) => this.get<IBCollectionResponse<T>>(endpoint, { ...params, page: i + 2 })\n )\n\n const allResponses = await Promise.all(pageRequests)\n\n return normalizedFirstResponse.data.concat(\n allResponses.flatMap((response) => this.normalizeCollectionResponse<T>(response).data)\n )\n }\n\n setRv(value: string | number) {\n if (this.setRvFn) {\n this.setRvFn(value)\n } else {\n rv = value\n }\n }\n\n getRv() {\n if (this.getRvFn) {\n return this.getRvFn()\n }\n return rv\n }\n\n private async parseResponse<T>(payload: unknown): Promise<T> {\n if (this.isFetchResponse(payload)) {\n if (!payload.ok) {\n throw new Error(`Request failed with status ${payload.status}`)\n }\n\n return (await payload.json()) as T\n }\n\n return payload as T\n }\n\n private normalizeCollectionResponse<T>(response: ApiCollectionResponse<T>) {\n if (this.isCollectionResponseEnvelope(response)) {\n const nestedResponse = response.data\n\n return {\n data: nestedResponse.data,\n meta: (nestedResponse as IBCollectionResponse<T> & { meta?: IBMeta }).meta,\n rv: response.rv || nestedResponse.rv,\n }\n }\n\n if (Array.isArray(response)) {\n return { data: response, meta: undefined, rv: undefined }\n }\n\n if (typeof response === 'object' && response !== null && 'data' in response) {\n const {\n data,\n meta,\n rv: responseRv,\n } = response as {\n data: T[]\n meta?: IBMeta\n rv?: string | number\n }\n return { data, meta, rv: responseRv }\n }\n\n return { data: [], meta: undefined, rv: undefined }\n }\n\n private buildUrl(endpoint: string, params: Record<string, unknown>): string {\n const url = new URL(`${this.baseUrl}/v1/${endpoint}`)\n\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value))\n }\n })\n\n return url.toString()\n }\n\n private resolveRequestUrl(requestUrl?: URL | string): URL | null {\n if (!requestUrl) {\n return null\n }\n\n if (requestUrl instanceof URL) {\n return requestUrl\n }\n\n return new URL(requestUrl, 'http://localhost')\n }\n\n private isFetchResponse(value: unknown): value is Response {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'json' in value &&\n typeof (value as Response).json === 'function' &&\n 'ok' in value\n )\n }\n\n private hasRevision(value: unknown): value is { rv: string | number } {\n return typeof value === 'object' && value !== null && 'rv' in value\n }\n\n private isCollectionResponseEnvelope<T>(\n value: ApiCollectionResponse<T>\n ): value is IBResponse<IBCollectionResponse<T>> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'data' in value &&\n typeof value.data === 'object' &&\n value.data !== null &&\n 'data' in value.data &&\n Array.isArray(value.data.data)\n )\n }\n}\n"],"names":["B10cksDataApi","client","endpoint","params","response","fullSlug","source","forceRefresh","redirects","map","target","status_code","slug","language_iso","language","bypassCache","normalizedLanguage","cacheKey","value","fallbackRv","nextRv","createB10cksDataApi","PreviewBridge","eventType","callback","listeners","selectedItem","itemId","field","event","type","payload","callbacks","previewBridge","rv","ApiClient","options","requestUrl","defaultFetch","url","firstResponse","normalizedFirstResponse","pageRequests","_","i","allResponses","nestedResponse","data","meta","responseRv","key"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,6 +1,3 @@
1
- const u = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2
- __proto__: null
3
- }, Symbol.toStringTag, { value: "Module" }));
4
1
  class f {
5
2
  constructor(t) {
6
3
  this.client = t;
@@ -8,8 +5,8 @@ class f {
8
5
  redirectsCache = null;
9
6
  configCache = /* @__PURE__ */ new Map();
10
7
  async getResource(t, e = {}) {
11
- const s = await this.client.get(t, e);
12
- return this.unwrapResource(s);
8
+ const n = await this.client.get(t, e);
9
+ return this.unwrapResource(n);
13
10
  }
14
11
  async getCollection(t, e = {}) {
15
12
  return this.client.getAll(t, e);
@@ -35,30 +32,30 @@ class f {
35
32
  async getRedirects(t = {}, e = !1) {
36
33
  if (this.redirectsCache && !e)
37
34
  return this.redirectsCache;
38
- const s = await this.getCollection("redirects", t), n = Object.fromEntries(
39
- s.map(({ source: i, target: a, status_code: r }) => [i, { target: a, status_code: r }])
35
+ const n = await this.getCollection("redirects", t), s = Object.fromEntries(
36
+ n.map(({ source: i, target: a, status_code: r }) => [i, { target: a, status_code: r }])
40
37
  );
41
- return this.redirectsCache = n, n;
38
+ return this.redirectsCache = s, s;
42
39
  }
43
40
  async getConfig({
44
41
  slug: t = "_config",
45
42
  language_iso: e,
46
- language: s,
47
- bypassCache: n = !1,
43
+ language: n,
44
+ bypassCache: s = !1,
48
45
  ...i
49
46
  } = {}) {
50
- const a = e ?? s, r = JSON.stringify({ slug: t, language_iso: a, ...i });
51
- if (!n && this.configCache.has(r))
47
+ const a = e ?? n, r = JSON.stringify({ slug: t, language_iso: a, ...i });
48
+ if (!s && this.configCache.has(r))
52
49
  return this.configCache.get(r);
53
50
  const d = (await this.getContent(t, {
54
51
  ...i,
55
52
  language_iso: a
56
53
  })).content ?? {};
57
- return n || this.configCache.set(r, d), d;
54
+ return s || this.configCache.set(r, d), d;
58
55
  }
59
56
  async syncRevision(t = 426713400) {
60
- const s = (await this.getSpace()).rv || t;
61
- return this.client.setRv(s), s;
57
+ const n = (await this.getSpace()).rv || t;
58
+ return this.client.setRv(n), n;
62
59
  }
63
60
  clearCache() {
64
61
  this.redirectsCache = null, this.configCache.clear();
@@ -67,7 +64,7 @@ class f {
67
64
  return typeof t == "object" && t !== null && "data" in t ? t.data : t;
68
65
  }
69
66
  }
70
- function g(c) {
67
+ function u(c) {
71
68
  return new f(c);
72
69
  }
73
70
  class o {
@@ -94,9 +91,9 @@ class o {
94
91
  if (!this.isInPreviewMode())
95
92
  return () => {
96
93
  };
97
- const s = this.listeners[t] || /* @__PURE__ */ new Set();
98
- return this.listeners[t] = s, s.add(e), () => {
99
- s.delete(e);
94
+ const n = this.listeners[t] || /* @__PURE__ */ new Set();
95
+ return this.listeners[t] = n, n.add(e), () => {
96
+ n.delete(e);
100
97
  };
101
98
  }
102
99
  selectItem(t) {
@@ -108,11 +105,11 @@ class o {
108
105
  "*"
109
106
  );
110
107
  }
111
- updateField(t, e, s) {
108
+ updateField(t, e, n) {
112
109
  this.isInPreviewMode() && window.parent.postMessage(
113
110
  {
114
111
  type: "FIELD_UPDATE",
115
- payload: { itemId: t, field: e, value: s }
112
+ payload: { itemId: t, field: e, value: n }
116
113
  },
117
114
  "*"
118
115
  );
@@ -120,19 +117,21 @@ class o {
120
117
  handleMessage = (t) => {
121
118
  if (!t.data || typeof t.data != "object")
122
119
  return;
123
- const { type: e, payload: s } = t.data;
124
- !e || !s || this.notify(e, s);
120
+ const { type: e, payload: n } = t.data;
121
+ !e || !n || this.notify(e, n);
125
122
  };
126
123
  notify(t, e) {
127
- const s = this.listeners[t];
128
- if (s)
129
- for (const n of s)
130
- n(e);
124
+ const n = this.listeners[t];
125
+ if (n)
126
+ for (const s of n)
127
+ s(e);
131
128
  }
132
129
  }
133
- const R = o.getInstance();
130
+ const g = o.getInstance(), R = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
131
+ __proto__: null
132
+ }, Symbol.toStringTag, { value: "Module" }));
134
133
  let l = 0;
135
- class v {
134
+ class p {
136
135
  baseUrl;
137
136
  token;
138
137
  vid;
@@ -141,40 +140,40 @@ class v {
141
140
  setRvFn;
142
141
  constructor(t, e) {
143
142
  this.baseUrl = t.baseUrl.endsWith("/") ? t.baseUrl.slice(0, -1) : t.baseUrl, this.token = t.token;
144
- const s = typeof globalThis.fetch == "function" ? globalThis.fetch.bind(globalThis) : null;
143
+ const n = typeof globalThis.fetch == "function" ? globalThis.fetch.bind(globalThis) : null;
145
144
  if (t.fetchClient)
146
145
  this.fetchClient = t.fetchClient;
147
- else if (s)
148
- this.fetchClient = s;
146
+ else if (n)
147
+ this.fetchClient = n;
149
148
  else
150
149
  throw new Error(
151
150
  "No fetch implementation available. Provide `fetchClient` in ApiClient options."
152
151
  );
153
152
  this.getRvFn = t.getRv, this.setRvFn = t.setRv;
154
- const n = this.resolveRequestUrl(e);
155
- this.vid = n?.searchParams.get("b10cks_vid") || t.version || "published", this.setRv(n?.searchParams.get("b10cks_rv") || t.rv || l);
153
+ const s = this.resolveRequestUrl(e);
154
+ this.vid = t.version || "published", this.setRv(s?.searchParams.get("b10cks_rv") || t.rv || l);
156
155
  }
157
156
  async get(t, e = {}) {
158
- const s = this.buildUrl(t, {
157
+ const n = this.buildUrl(t, {
159
158
  vid: this.vid,
160
159
  ...e,
161
160
  rv: this.getRv(),
162
161
  token: this.token
163
- }), n = await this.fetchClient(s), i = await this.parseResponse(n);
162
+ }), s = await this.fetchClient(n), i = await this.parseResponse(s);
164
163
  return this.hasRevision(i) && this.setRv(i.rv), i;
165
164
  }
166
165
  async getAll(t, e = {}) {
167
- const s = await this.get(t, {
166
+ const n = await this.get(t, {
168
167
  ...e,
169
168
  page: 1
170
- }), n = this.normalizeCollectionResponse(s);
171
- if (n.rv && this.setRv(n.rv), !n.meta || n.meta.last_page <= 1)
172
- return n.data;
169
+ }), s = this.normalizeCollectionResponse(n);
170
+ if (s.rv && this.setRv(s.rv), !s.meta || s.meta.last_page <= 1)
171
+ return s.data;
173
172
  const i = Array.from(
174
- { length: n.meta.last_page - 1 },
173
+ { length: s.meta.last_page - 1 },
175
174
  (r, h) => this.get(t, { ...e, page: h + 2 })
176
175
  ), a = await Promise.all(i);
177
- return n.data.concat(
176
+ return s.data.concat(
178
177
  a.flatMap((r) => this.normalizeCollectionResponse(r).data)
179
178
  );
180
179
  }
@@ -206,18 +205,18 @@ class v {
206
205
  if (typeof t == "object" && t !== null && "data" in t) {
207
206
  const {
208
207
  data: e,
209
- meta: s,
210
- rv: n
208
+ meta: n,
209
+ rv: s
211
210
  } = t;
212
- return { data: e, meta: s, rv: n };
211
+ return { data: e, meta: n, rv: s };
213
212
  }
214
213
  return { data: [], meta: void 0, rv: void 0 };
215
214
  }
216
215
  buildUrl(t, e) {
217
- const s = new URL(`${this.baseUrl}/v1/${t}`);
218
- return Object.entries(e).forEach(([n, i]) => {
219
- i != null && s.searchParams.append(n, String(i));
220
- }), s.toString();
216
+ const n = new URL(`${this.baseUrl}/v1/${t}`);
217
+ return Object.entries(e).forEach(([s, i]) => {
218
+ i != null && n.searchParams.append(s, String(i));
219
+ }), n.toString();
221
220
  }
222
221
  resolveRequestUrl(t) {
223
222
  return t ? t instanceof URL ? t : new URL(t, "http://localhost") : null;
@@ -233,11 +232,11 @@ class v {
233
232
  }
234
233
  }
235
234
  export {
236
- v as ApiClient,
235
+ p as ApiClient,
237
236
  f as B10cksDataApi,
238
237
  o as PreviewBridge,
239
- g as createB10cksDataApi,
240
- R as previewBridge,
241
- u as types
238
+ u as createB10cksDataApi,
239
+ g as previewBridge,
240
+ R as types
242
241
  };
243
242
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/data-api.ts","../src/preview-bridge.ts","../src/index.ts"],"sourcesContent":["import type {\n Endpoint,\n IBBaseQueryParams,\n IBBlock,\n IBContent,\n IBContentQueryParams,\n IBDataEntry,\n IBDataSource,\n IBRedirect,\n IBSpace,\n} from './types'\n\ntype ApiQueryParams = Omit<IBBaseQueryParams, 'token'>\n\nexport interface DataApiClient {\n get<T>(\n endpoint: Endpoint,\n params?: ApiQueryParams\n ): Promise<T | { data: T; rv?: string | number }>\n getAll<T>(endpoint: Endpoint, params?: ApiQueryParams): Promise<T[]>\n setRv(value: string | number): void\n}\n\nexport type RedirectMap = Record<string, { target: string; status_code: number }>\n\nexport interface GetConfigOptions extends Omit<IBContentQueryParams, 'token' | 'full_slug'> {\n slug?: string\n language?: string\n bypassCache?: boolean\n}\n\nexport class B10cksDataApi {\n private redirectsCache: RedirectMap | null = null\n private readonly configCache = new Map<string, unknown>()\n\n constructor(private readonly client: DataApiClient) {}\n\n async getResource<T>(endpoint: Endpoint, params: ApiQueryParams = {}): Promise<T> {\n const response = await this.client.get<T>(endpoint, params)\n return this.unwrapResource(response)\n }\n\n async getCollection<T>(endpoint: Endpoint, params: ApiQueryParams = {}): Promise<T[]> {\n return this.client.getAll<T>(endpoint, params)\n }\n\n async getContent<T = Record<string, unknown>>(\n fullSlug: string,\n params: Omit<IBContentQueryParams, 'token' | 'full_slug'> = {}\n ): Promise<IBContent<T>> {\n return this.getResource<IBContent<T>>(`contents/${fullSlug}`, params)\n }\n\n async getContents<T = Record<string, unknown>>(\n params: Omit<IBContentQueryParams, 'token'> = {}\n ): Promise<IBContent<T>[]> {\n return this.getCollection<IBContent<T>>('contents', params)\n }\n\n async getBlocks(params: ApiQueryParams = {}): Promise<IBBlock[]> {\n return this.getCollection<IBBlock>('blocks', params)\n }\n\n async getDataEntries(source: string, params: ApiQueryParams = {}): Promise<IBDataEntry[]> {\n return this.getCollection<IBDataEntry>(`datasources/${source}/entries`, params)\n }\n\n async getDataSources(params: ApiQueryParams = {}): Promise<IBDataSource[]> {\n return this.getCollection<IBDataSource>('datasources', params)\n }\n\n async getSpace(params: ApiQueryParams = {}): Promise<IBSpace> {\n return this.getResource<IBSpace>('spaces/me', params)\n }\n\n async getRedirects(params: ApiQueryParams = {}, forceRefresh = false): Promise<RedirectMap> {\n if (this.redirectsCache && !forceRefresh) {\n return this.redirectsCache\n }\n\n const redirects = await this.getCollection<IBRedirect>('redirects', params)\n const map = Object.fromEntries(\n redirects.map(({ source, target, status_code }) => [source, { target, status_code }])\n )\n this.redirectsCache = map\n return map\n }\n\n async getConfig<T = Record<string, unknown>>({\n slug = '_config',\n language_iso,\n language,\n bypassCache = false,\n ...params\n }: GetConfigOptions = {}): Promise<T> {\n const normalizedLanguage = language_iso ?? language\n const cacheKey = JSON.stringify({ slug, language_iso: normalizedLanguage, ...params })\n if (!bypassCache && this.configCache.has(cacheKey)) {\n return this.configCache.get(cacheKey) as T\n }\n\n const configContent = await this.getContent<Record<string, unknown>>(slug, {\n ...params,\n language_iso: normalizedLanguage,\n })\n const value = (configContent.content ?? {}) as T\n\n if (!bypassCache) {\n this.configCache.set(cacheKey, value)\n }\n\n return value\n }\n\n async syncRevision(fallbackRv = 426713400): Promise<string | number> {\n const space = await this.getSpace()\n const nextRv = space.rv || fallbackRv\n this.client.setRv(nextRv)\n return nextRv\n }\n\n clearCache() {\n this.redirectsCache = null\n this.configCache.clear()\n }\n\n private unwrapResource<T>(response: T | { data: T }): T {\n if (typeof response === 'object' && response !== null && 'data' in response) {\n return response.data\n }\n\n return response\n }\n}\n\nexport function createB10cksDataApi(client: DataApiClient): B10cksDataApi {\n return new B10cksDataApi(client)\n}\n","export type ContentUpdateEvent = {\n content: Record<string, unknown>\n}\n\nexport type SelectUpdateEvent = {\n selectedItem: string\n}\n\nexport type FieldUpdateEvent = {\n itemId: string\n field: string\n value: string\n}\n\nexport type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE' | 'FIELD_UPDATE'\n\nexport type EventPayloadMap = {\n CONTENT_UPDATE: ContentUpdateEvent\n SELECT_UPDATE: SelectUpdateEvent\n HOVER_UPDATE: SelectUpdateEvent\n FIELD_UPDATE: FieldUpdateEvent\n}\n\ntype EventCallback<T> = (payload: T) => void\n\nexport type BridgeEvent = {\n type: EventType\n payload: EventPayloadMap[EventType]\n b10cksId?: string\n}\n\nexport class PreviewBridge {\n private static instance: PreviewBridge\n private readonly listeners: Partial<Record<EventType, Set<EventCallback<unknown>>>> = {}\n private initialized = false\n\n private constructor() {}\n\n static getInstance() {\n if (!PreviewBridge.instance) {\n PreviewBridge.instance = new PreviewBridge()\n }\n return PreviewBridge.instance\n }\n\n init() {\n if (!this.isInPreviewMode() || this.initialized) {\n return\n }\n\n window.addEventListener('message', this.handleMessage)\n this.initialized = true\n }\n\n destroy() {\n if (this.initialized && typeof window !== 'undefined') {\n window.removeEventListener('message', this.handleMessage)\n }\n this.initialized = false\n for (const eventType of Object.keys(this.listeners) as EventType[]) {\n this.listeners[eventType]?.clear()\n }\n }\n\n isInPreviewMode(): boolean {\n return typeof window !== 'undefined' && window.self !== window.top\n }\n\n on<T extends EventType>(eventType: T, callback: EventCallback<EventPayloadMap[T]>): () => void {\n if (!this.isInPreviewMode()) {\n return () => {}\n }\n\n const listeners = this.listeners[eventType] || new Set<EventCallback<unknown>>()\n this.listeners[eventType] = listeners\n listeners.add(callback as EventCallback<unknown>)\n\n return () => {\n listeners.delete(callback as EventCallback<unknown>)\n }\n }\n\n selectItem(selectedItem: string) {\n if (!this.isInPreviewMode()) {\n return\n }\n\n window.parent.postMessage(\n {\n type: 'SELECT_UPDATE',\n payload: { selectedItem },\n },\n '*'\n )\n }\n\n updateField(itemId: string, field: string, value: string) {\n if (!this.isInPreviewMode()) {\n return\n }\n\n window.parent.postMessage(\n {\n type: 'FIELD_UPDATE',\n payload: { itemId, field, value },\n },\n '*'\n )\n }\n\n private handleMessage = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== 'object') {\n return\n }\n\n const { type, payload } = event.data as BridgeEvent\n if (!type || !payload) {\n return\n }\n\n this.notify(type, payload as never)\n }\n\n private notify<T extends EventType>(type: T, payload: EventPayloadMap[T]) {\n const callbacks = this.listeners[type]\n if (!callbacks) {\n return\n }\n\n for (const callback of callbacks) {\n ;(callback as EventCallback<EventPayloadMap[T]>)(payload)\n }\n }\n}\n\nexport const previewBridge = PreviewBridge.getInstance()\n","import type {\n B10cksApiClientOptions,\n Endpoint,\n FetchClient,\n IBBaseQueryParams,\n IBCollectionResponse,\n IBMeta,\n IBResponse,\n} from './types'\n\nexport interface B10cksApiClientRvOptions {\n getRv?: () => string | number\n setRv?: (value: string | number) => void\n}\n\nexport * as types from './types'\nexport type * from './types'\nexport * from './data-api'\nexport * from './preview-bridge'\n\nlet rv: string | number = 0\n\ntype ApiResourceResponse<T> = IBResponse<T> | T\ntype ApiCollectionResponse<T> =\n | IBCollectionResponse<T>\n | IBResponse<IBCollectionResponse<T>>\n | T[]\n | { data: T[]; meta?: IBMeta; rv?: string | number }\n\nexport class ApiClient {\n private readonly baseUrl: string\n readonly token: string\n private readonly vid: string | null\n private readonly fetchClient: FetchClient\n private readonly getRvFn?: () => string | number\n private readonly setRvFn?: (value: string | number) => void\n\n constructor(options: B10cksApiClientOptions, requestUrl?: URL | string) {\n this.baseUrl = options.baseUrl.endsWith('/') ? options.baseUrl.slice(0, -1) : options.baseUrl\n this.token = options.token\n const defaultFetch =\n typeof globalThis.fetch === 'function' ? globalThis.fetch.bind(globalThis) : null\n if (options.fetchClient) {\n this.fetchClient = options.fetchClient\n } else if (defaultFetch) {\n this.fetchClient = defaultFetch as FetchClient\n } else {\n throw new Error(\n 'No fetch implementation available. Provide `fetchClient` in ApiClient options.'\n )\n }\n\n this.getRvFn = options.getRv\n this.setRvFn = options.setRv\n\n const url = this.resolveRequestUrl(requestUrl)\n this.vid = url?.searchParams.get('b10cks_vid') || options.version || 'published'\n this.setRv(url?.searchParams.get('b10cks_rv') || options.rv || rv)\n }\n\n async get<T>(\n endpoint: Endpoint,\n params: Omit<IBBaseQueryParams, 'token'> = {}\n ): Promise<ApiResourceResponse<T>> {\n const url = this.buildUrl(endpoint, {\n vid: this.vid,\n ...params,\n rv: this.getRv(),\n token: this.token,\n })\n\n const payload = await this.fetchClient(url)\n const response = await this.parseResponse<ApiResourceResponse<T>>(payload)\n\n if (this.hasRevision(response)) {\n this.setRv(response.rv)\n }\n\n return response\n }\n\n async getAll<T>(endpoint: Endpoint, params: Omit<IBBaseQueryParams, 'token'> = {}): Promise<T[]> {\n const firstResponse = await this.get<IBCollectionResponse<T> & { meta?: IBMeta }>(endpoint, {\n ...params,\n page: 1,\n })\n const normalizedFirstResponse = this.normalizeCollectionResponse<T>(firstResponse)\n\n if (normalizedFirstResponse.rv) {\n this.setRv(normalizedFirstResponse.rv)\n }\n\n if (!normalizedFirstResponse.meta || normalizedFirstResponse.meta.last_page <= 1) {\n return normalizedFirstResponse.data\n }\n\n const pageRequests = Array.from(\n { length: normalizedFirstResponse.meta.last_page - 1 },\n (_, i) => this.get<IBCollectionResponse<T>>(endpoint, { ...params, page: i + 2 })\n )\n\n const allResponses = await Promise.all(pageRequests)\n\n return normalizedFirstResponse.data.concat(\n allResponses.flatMap((response) => this.normalizeCollectionResponse<T>(response).data)\n )\n }\n\n setRv(value: string | number) {\n if (this.setRvFn) {\n this.setRvFn(value)\n } else {\n rv = value\n }\n }\n\n getRv() {\n if (this.getRvFn) {\n return this.getRvFn()\n }\n return rv\n }\n\n private async parseResponse<T>(payload: unknown): Promise<T> {\n if (this.isFetchResponse(payload)) {\n if (!payload.ok) {\n throw new Error(`Request failed with status ${payload.status}`)\n }\n\n return (await payload.json()) as T\n }\n\n return payload as T\n }\n\n private normalizeCollectionResponse<T>(response: ApiCollectionResponse<T>) {\n if (this.isCollectionResponseEnvelope(response)) {\n const nestedResponse = response.data\n\n return {\n data: nestedResponse.data,\n meta: (nestedResponse as IBCollectionResponse<T> & { meta?: IBMeta }).meta,\n rv: response.rv || nestedResponse.rv,\n }\n }\n\n if (Array.isArray(response)) {\n return { data: response, meta: undefined, rv: undefined }\n }\n\n if (typeof response === 'object' && response !== null && 'data' in response) {\n const {\n data,\n meta,\n rv: responseRv,\n } = response as {\n data: T[]\n meta?: IBMeta\n rv?: string | number\n }\n return { data, meta, rv: responseRv }\n }\n\n return { data: [], meta: undefined, rv: undefined }\n }\n\n private buildUrl(endpoint: string, params: Record<string, unknown>): string {\n const url = new URL(`${this.baseUrl}/v1/${endpoint}`)\n\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value))\n }\n })\n\n return url.toString()\n }\n\n private resolveRequestUrl(requestUrl?: URL | string): URL | null {\n if (!requestUrl) {\n return null\n }\n\n if (requestUrl instanceof URL) {\n return requestUrl\n }\n\n return new URL(requestUrl, 'http://localhost')\n }\n\n private isFetchResponse(value: unknown): value is Response {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'json' in value &&\n typeof (value as Response).json === 'function' &&\n 'ok' in value\n )\n }\n\n private hasRevision(value: unknown): value is { rv: string | number } {\n return typeof value === 'object' && value !== null && 'rv' in value\n }\n\n private isCollectionResponseEnvelope<T>(\n value: ApiCollectionResponse<T>\n ): value is IBResponse<IBCollectionResponse<T>> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'data' in value &&\n typeof value.data === 'object' &&\n value.data !== null &&\n 'data' in value.data &&\n Array.isArray(value.data.data)\n )\n }\n}\n"],"names":["B10cksDataApi","client","endpoint","params","response","fullSlug","source","forceRefresh","redirects","map","target","status_code","slug","language_iso","language","bypassCache","normalizedLanguage","cacheKey","value","fallbackRv","nextRv","createB10cksDataApi","PreviewBridge","eventType","callback","listeners","selectedItem","itemId","field","event","type","payload","callbacks","previewBridge","rv","ApiClient","options","requestUrl","defaultFetch","url","firstResponse","normalizedFirstResponse","pageRequests","_","i","allResponses","nestedResponse","data","meta","responseRv","key"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/data-api.ts","../src/preview-bridge.ts","../src/index.ts"],"sourcesContent":["import type {\n Endpoint,\n IBBaseQueryParams,\n IBBlock,\n IBContent,\n IBContentQueryParams,\n IBDataEntry,\n IBDataSource,\n IBRedirect,\n IBSpace,\n} from './types'\n\ntype ApiQueryParams = Omit<IBBaseQueryParams, 'token'>\n\nexport interface DataApiClient {\n get<T>(\n endpoint: Endpoint,\n params?: ApiQueryParams\n ): Promise<T | { data: T; rv?: string | number }>\n getAll<T>(endpoint: Endpoint, params?: ApiQueryParams): Promise<T[]>\n setRv(value: string | number): void\n}\n\nexport type RedirectMap = Record<string, { target: string; status_code: number }>\n\nexport interface GetConfigOptions extends Omit<IBContentQueryParams, 'token' | 'full_slug'> {\n slug?: string\n language?: string\n bypassCache?: boolean\n}\n\nexport class B10cksDataApi {\n private redirectsCache: RedirectMap | null = null\n private readonly configCache = new Map<string, unknown>()\n\n constructor(private readonly client: DataApiClient) {}\n\n async getResource<T>(endpoint: Endpoint, params: ApiQueryParams = {}): Promise<T> {\n const response = await this.client.get<T>(endpoint, params)\n return this.unwrapResource(response)\n }\n\n async getCollection<T>(endpoint: Endpoint, params: ApiQueryParams = {}): Promise<T[]> {\n return this.client.getAll<T>(endpoint, params)\n }\n\n async getContent<T = Record<string, unknown>>(\n fullSlug: string,\n params: Omit<IBContentQueryParams, 'token' | 'full_slug'> = {}\n ): Promise<IBContent<T>> {\n return this.getResource<IBContent<T>>(`contents/${fullSlug}`, params)\n }\n\n async getContents<T = Record<string, unknown>>(\n params: Omit<IBContentQueryParams, 'token'> = {}\n ): Promise<IBContent<T>[]> {\n return this.getCollection<IBContent<T>>('contents', params)\n }\n\n async getBlocks(params: ApiQueryParams = {}): Promise<IBBlock[]> {\n return this.getCollection<IBBlock>('blocks', params)\n }\n\n async getDataEntries(source: string, params: ApiQueryParams = {}): Promise<IBDataEntry[]> {\n return this.getCollection<IBDataEntry>(`datasources/${source}/entries`, params)\n }\n\n async getDataSources(params: ApiQueryParams = {}): Promise<IBDataSource[]> {\n return this.getCollection<IBDataSource>('datasources', params)\n }\n\n async getSpace(params: ApiQueryParams = {}): Promise<IBSpace> {\n return this.getResource<IBSpace>('spaces/me', params)\n }\n\n async getRedirects(params: ApiQueryParams = {}, forceRefresh = false): Promise<RedirectMap> {\n if (this.redirectsCache && !forceRefresh) {\n return this.redirectsCache\n }\n\n const redirects = await this.getCollection<IBRedirect>('redirects', params)\n const map = Object.fromEntries(\n redirects.map(({ source, target, status_code }) => [source, { target, status_code }])\n )\n this.redirectsCache = map\n return map\n }\n\n async getConfig<T = Record<string, unknown>>({\n slug = '_config',\n language_iso,\n language,\n bypassCache = false,\n ...params\n }: GetConfigOptions = {}): Promise<T> {\n const normalizedLanguage = language_iso ?? language\n const cacheKey = JSON.stringify({ slug, language_iso: normalizedLanguage, ...params })\n if (!bypassCache && this.configCache.has(cacheKey)) {\n return this.configCache.get(cacheKey) as T\n }\n\n const configContent = await this.getContent<Record<string, unknown>>(slug, {\n ...params,\n language_iso: normalizedLanguage,\n })\n const value = (configContent.content ?? {}) as T\n\n if (!bypassCache) {\n this.configCache.set(cacheKey, value)\n }\n\n return value\n }\n\n async syncRevision(fallbackRv = 426713400): Promise<string | number> {\n const space = await this.getSpace()\n const nextRv = space.rv || fallbackRv\n this.client.setRv(nextRv)\n return nextRv\n }\n\n clearCache() {\n this.redirectsCache = null\n this.configCache.clear()\n }\n\n private unwrapResource<T>(response: T | { data: T }): T {\n if (typeof response === 'object' && response !== null && 'data' in response) {\n return response.data\n }\n\n return response\n }\n}\n\nexport function createB10cksDataApi(client: DataApiClient): B10cksDataApi {\n return new B10cksDataApi(client)\n}\n","export type ContentUpdateEvent = {\n content: Record<string, unknown>\n}\n\nexport type SelectUpdateEvent = {\n selectedItem: string\n}\n\nexport type FieldUpdateEvent = {\n itemId: string\n field: string\n value: string\n}\n\nexport type EventType = 'CONTENT_UPDATE' | 'SELECT_UPDATE' | 'HOVER_UPDATE' | 'FIELD_UPDATE'\n\nexport type EventPayloadMap = {\n CONTENT_UPDATE: ContentUpdateEvent\n SELECT_UPDATE: SelectUpdateEvent\n HOVER_UPDATE: SelectUpdateEvent\n FIELD_UPDATE: FieldUpdateEvent\n}\n\ntype EventCallback<T> = (payload: T) => void\n\nexport type BridgeEvent = {\n type: EventType\n payload: EventPayloadMap[EventType]\n b10cksId?: string\n}\n\nexport class PreviewBridge {\n private static instance: PreviewBridge\n private readonly listeners: Partial<Record<EventType, Set<EventCallback<unknown>>>> = {}\n private initialized = false\n\n private constructor() {}\n\n static getInstance() {\n if (!PreviewBridge.instance) {\n PreviewBridge.instance = new PreviewBridge()\n }\n return PreviewBridge.instance\n }\n\n init() {\n if (!this.isInPreviewMode() || this.initialized) {\n return\n }\n\n window.addEventListener('message', this.handleMessage)\n this.initialized = true\n }\n\n destroy() {\n if (this.initialized && typeof window !== 'undefined') {\n window.removeEventListener('message', this.handleMessage)\n }\n this.initialized = false\n for (const eventType of Object.keys(this.listeners) as EventType[]) {\n this.listeners[eventType]?.clear()\n }\n }\n\n isInPreviewMode(): boolean {\n return typeof window !== 'undefined' && window.self !== window.top\n }\n\n on<T extends EventType>(eventType: T, callback: EventCallback<EventPayloadMap[T]>): () => void {\n if (!this.isInPreviewMode()) {\n return () => {}\n }\n\n const listeners = this.listeners[eventType] || new Set<EventCallback<unknown>>()\n this.listeners[eventType] = listeners\n listeners.add(callback as EventCallback<unknown>)\n\n return () => {\n listeners.delete(callback as EventCallback<unknown>)\n }\n }\n\n selectItem(selectedItem: string) {\n if (!this.isInPreviewMode()) {\n return\n }\n\n window.parent.postMessage(\n {\n type: 'SELECT_UPDATE',\n payload: { selectedItem },\n },\n '*'\n )\n }\n\n updateField(itemId: string, field: string, value: string) {\n if (!this.isInPreviewMode()) {\n return\n }\n\n window.parent.postMessage(\n {\n type: 'FIELD_UPDATE',\n payload: { itemId, field, value },\n },\n '*'\n )\n }\n\n private handleMessage = (event: MessageEvent) => {\n if (!event.data || typeof event.data !== 'object') {\n return\n }\n\n const { type, payload } = event.data as BridgeEvent\n if (!type || !payload) {\n return\n }\n\n this.notify(type, payload as never)\n }\n\n private notify<T extends EventType>(type: T, payload: EventPayloadMap[T]) {\n const callbacks = this.listeners[type]\n if (!callbacks) {\n return\n }\n\n for (const callback of callbacks) {\n ;(callback as EventCallback<EventPayloadMap[T]>)(payload)\n }\n }\n}\n\nexport const previewBridge = PreviewBridge.getInstance()\n","import type {\n B10cksApiClientOptions,\n Endpoint,\n FetchClient,\n IBBaseQueryParams,\n IBCollectionResponse,\n IBMeta,\n IBResponse,\n} from './types'\n\nexport interface B10cksApiClientRvOptions {\n getRv?: () => string | number\n setRv?: (value: string | number) => void\n}\n\nexport * from './data-api'\nexport * from './preview-bridge'\nexport type * from './types'\nexport * as types from './types'\n\nlet rv: string | number = 0\n\ntype ApiResourceResponse<T> = IBResponse<T> | T\ntype ApiCollectionResponse<T> =\n | IBCollectionResponse<T>\n | IBResponse<IBCollectionResponse<T>>\n | T[]\n | { data: T[]; meta?: IBMeta; rv?: string | number }\n\nexport class ApiClient {\n private readonly baseUrl: string\n readonly token: string\n private readonly vid: string\n private readonly fetchClient: FetchClient\n private readonly getRvFn?: () => string | number\n private readonly setRvFn?: (value: string | number) => void\n\n constructor(options: B10cksApiClientOptions, requestUrl?: URL | string) {\n this.baseUrl = options.baseUrl.endsWith('/') ? options.baseUrl.slice(0, -1) : options.baseUrl\n this.token = options.token\n const defaultFetch =\n typeof globalThis.fetch === 'function' ? globalThis.fetch.bind(globalThis) : null\n if (options.fetchClient) {\n this.fetchClient = options.fetchClient\n } else if (defaultFetch) {\n this.fetchClient = defaultFetch as FetchClient\n } else {\n throw new Error(\n 'No fetch implementation available. Provide `fetchClient` in ApiClient options.'\n )\n }\n\n this.getRvFn = options.getRv\n this.setRvFn = options.setRv\n\n const url = this.resolveRequestUrl(requestUrl)\n this.vid = options.version || 'published'\n this.setRv(url?.searchParams.get('b10cks_rv') || options.rv || rv)\n }\n\n async get<T>(\n endpoint: Endpoint,\n params: Omit<IBBaseQueryParams, 'token'> = {}\n ): Promise<ApiResourceResponse<T>> {\n const url = this.buildUrl(endpoint, {\n vid: this.vid,\n ...params,\n rv: this.getRv(),\n token: this.token,\n })\n\n const payload = await this.fetchClient(url)\n const response = await this.parseResponse<ApiResourceResponse<T>>(payload)\n\n if (this.hasRevision(response)) {\n this.setRv(response.rv)\n }\n\n return response\n }\n\n async getAll<T>(endpoint: Endpoint, params: Omit<IBBaseQueryParams, 'token'> = {}): Promise<T[]> {\n const firstResponse = await this.get<IBCollectionResponse<T> & { meta?: IBMeta }>(endpoint, {\n ...params,\n page: 1,\n })\n const normalizedFirstResponse = this.normalizeCollectionResponse<T>(firstResponse)\n\n if (normalizedFirstResponse.rv) {\n this.setRv(normalizedFirstResponse.rv)\n }\n\n if (!normalizedFirstResponse.meta || normalizedFirstResponse.meta.last_page <= 1) {\n return normalizedFirstResponse.data\n }\n\n const pageRequests = Array.from(\n { length: normalizedFirstResponse.meta.last_page - 1 },\n (_, i) => this.get<IBCollectionResponse<T>>(endpoint, { ...params, page: i + 2 })\n )\n\n const allResponses = await Promise.all(pageRequests)\n\n return normalizedFirstResponse.data.concat(\n allResponses.flatMap((response) => this.normalizeCollectionResponse<T>(response).data)\n )\n }\n\n setRv(value: string | number) {\n if (this.setRvFn) {\n this.setRvFn(value)\n } else {\n rv = value\n }\n }\n\n getRv() {\n if (this.getRvFn) {\n return this.getRvFn()\n }\n return rv\n }\n\n private async parseResponse<T>(payload: unknown): Promise<T> {\n if (this.isFetchResponse(payload)) {\n if (!payload.ok) {\n throw new Error(`Request failed with status ${payload.status}`)\n }\n\n return (await payload.json()) as T\n }\n\n return payload as T\n }\n\n private normalizeCollectionResponse<T>(response: ApiCollectionResponse<T>) {\n if (this.isCollectionResponseEnvelope(response)) {\n const nestedResponse = response.data\n\n return {\n data: nestedResponse.data,\n meta: (nestedResponse as IBCollectionResponse<T> & { meta?: IBMeta }).meta,\n rv: response.rv || nestedResponse.rv,\n }\n }\n\n if (Array.isArray(response)) {\n return { data: response, meta: undefined, rv: undefined }\n }\n\n if (typeof response === 'object' && response !== null && 'data' in response) {\n const {\n data,\n meta,\n rv: responseRv,\n } = response as {\n data: T[]\n meta?: IBMeta\n rv?: string | number\n }\n return { data, meta, rv: responseRv }\n }\n\n return { data: [], meta: undefined, rv: undefined }\n }\n\n private buildUrl(endpoint: string, params: Record<string, unknown>): string {\n const url = new URL(`${this.baseUrl}/v1/${endpoint}`)\n\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.append(key, String(value))\n }\n })\n\n return url.toString()\n }\n\n private resolveRequestUrl(requestUrl?: URL | string): URL | null {\n if (!requestUrl) {\n return null\n }\n\n if (requestUrl instanceof URL) {\n return requestUrl\n }\n\n return new URL(requestUrl, 'http://localhost')\n }\n\n private isFetchResponse(value: unknown): value is Response {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'json' in value &&\n typeof (value as Response).json === 'function' &&\n 'ok' in value\n )\n }\n\n private hasRevision(value: unknown): value is { rv: string | number } {\n return typeof value === 'object' && value !== null && 'rv' in value\n }\n\n private isCollectionResponseEnvelope<T>(\n value: ApiCollectionResponse<T>\n ): value is IBResponse<IBCollectionResponse<T>> {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'data' in value &&\n typeof value.data === 'object' &&\n value.data !== null &&\n 'data' in value.data &&\n Array.isArray(value.data.data)\n )\n }\n}\n"],"names":["B10cksDataApi","client","endpoint","params","response","fullSlug","source","forceRefresh","redirects","map","target","status_code","slug","language_iso","language","bypassCache","normalizedLanguage","cacheKey","value","fallbackRv","nextRv","createB10cksDataApi","PreviewBridge","eventType","callback","listeners","selectedItem","itemId","field","event","type","payload","callbacks","previewBridge","rv","ApiClient","options","requestUrl","defaultFetch","url","firstResponse","normalizedFirstResponse","pageRequests","_","i","allResponses","nestedResponse","data","meta","responseRv","key"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b10cks/client",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Core b10cks API client",
5
5
  "license": "MIT",
6
6
  "author": "Michael Wallner @ Coder's Cantina",