@sprintup-cms/sdk 1.8.69 → 1.8.74
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/CHANGELOG.md +70 -0
- package/README.md +10 -5
- package/dist/catch-all-CTLOY9lm.d.cts +38 -0
- package/dist/catch-all-CTLOY9lm.d.ts +38 -0
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +17 -1
- package/dist/client.d.ts +17 -1
- package/dist/client.js.map +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js.map +1 -1
- package/dist/next/index.cjs +55 -92
- package/dist/next/index.cjs.map +1 -1
- package/dist/next/index.d.cts +5 -13
- package/dist/next/index.d.ts +5 -13
- package/dist/next/index.js +55 -92
- package/dist/next/index.js.map +1 -1
- package/dist/react/index.cjs +46 -89
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +46 -89
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
1
|
export { CMSBlock, CMSClientOptions, CMSFooterGroup, CMSGetPagesOptions, CMSMenuItem, CMSMenuItemType, CMSPage, CMSPageTreeNode, CMSPageType, CMSPageTypeField, CMSPageTypeSection, CMSPageTypeVariant, CMSSiteStructure, CMSSitemapResponse, CMSSitemapUrl, CMSStatusResponse, cmsClient, createCMSClient } from './client.cjs';
|
|
2
|
+
export { C as CMSCatchAllParams, a as CMSLayoutConfig } from './catch-all-CTLOY9lm.cjs';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
5
|
+
import 'next';
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1,5 @@
|
|
|
1
1
|
export { CMSBlock, CMSClientOptions, CMSFooterGroup, CMSGetPagesOptions, CMSMenuItem, CMSMenuItemType, CMSPage, CMSPageTreeNode, CMSPageType, CMSPageTypeField, CMSPageTypeSection, CMSPageTypeVariant, CMSSiteStructure, CMSSitemapResponse, CMSSitemapUrl, CMSStatusResponse, cmsClient, createCMSClient } from './client.js';
|
|
2
|
+
export { C as CMSCatchAllParams, a as CMSLayoutConfig } from './catch-all-CTLOY9lm.js';
|
|
3
|
+
import 'react/jsx-runtime';
|
|
4
|
+
import 'react';
|
|
5
|
+
import 'next';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";;;AAkOO,SAAS,gBAAgB,OAAA,EAA4B;AAK1D,EAAA,SAAS,GAAA,GAAM;AACb,IAAA,OAAO;AAAA,MACL,OAAA,EAAA,CAAU,OAAA,EAAS,OAAA,IAAW,OAAA,CAAQ,GAAA,CAAI,mBAAA,IAAuB,OAAA,CAAQ,GAAA,CAAI,YAAA,IAAgB,EAAA,EAAI,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAAA,MAClH,MAAA,EAAS,OAAA,EAAS,MAAA,IAAW,OAAA,CAAQ,IAAI,WAAA,IAAgB,EAAA;AAAA,MACzD,KAAA,EAAS,OAAA,EAAS,KAAA,IAAW,OAAA,CAAQ,IAAI,UAAA,IAAgB;AAAA,KAC3D;AAAA,EACF;AAEA,EAAA,SAAS,OAAA,GAAU;AACjB,IAAA,OAAO,EAAE,eAAA,EAAiB,GAAA,EAAI,CAAE,MAAA,EAAQ,gBAAgB,kBAAA,EAAmB;AAAA,EAC7E;AAIA,EAAA,eAAe,SAAS,MAAA,EAAiD;AACvE,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,KAAA,EAAO;AACjC,MAAA,OAAA,CAAQ,KAAK,oFAA+E,CAAA;AAC5F,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GAAK,IAAI,eAAA,EAAgB;AAC/B,MAAA,IAAI,QAAQ,IAAA,EAAS,EAAA,CAAG,GAAA,CAAI,MAAA,EAAW,OAAO,IAAI,CAAA;AAClD,MAAA,IAAI,QAAQ,KAAA,EAAS,EAAA,CAAG,GAAA,CAAI,OAAA,EAAW,OAAO,KAAK,CAAA;AACnD,MAAA,IAAI,MAAA,EAAQ,MAAS,EAAA,CAAG,GAAA,CAAI,QAAW,MAAA,CAAO,MAAA,CAAO,IAAI,CAAC,CAAA;AAC1D,MAAA,IAAI,MAAA,EAAQ,SAAS,EAAA,CAAG,GAAA,CAAI,WAAW,MAAA,CAAO,MAAA,CAAO,OAAO,CAAC,CAAA;AAC7D,MAAA,MAAM,GAAA,GAAM,CAAA,EAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,MAAA,EAAS,EAAA,CAAG,IAAA,GAAO,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA;AACtE,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,QAC3B,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,EAAA,EAAI,MAAM,CAAC,CAAA,UAAA,EAAa,KAAK,CAAA,CAAE,CAAA;AAAE,OACvC,CAAA;AAChB,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AAAE,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,yBAAA,EAA4B,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAAG,QAAA,OAAO,EAAC;AAAA,MAAE;AACnF,MAAA,MAAM,IAAA,GAAwB,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7C,MAAA,OAAO,IAAA,CAAK,QAAQ,EAAC;AAAA,IACvB,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM,kCAAkC,GAAG,CAAA;AACnD,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AAEA,EAAA,eAAe,QAAQ,IAAA,EAAuC;AAC5D,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,KAAA,EAAO;AACjC,MAAA,OAAA,CAAQ,KAAK,qDAAgD,CAAA;AAC7D,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,OAAA,EAAU,IAAI,CAAA,CAAA,EAAI;AAAA,QAClE,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,EAAA,EAAI,IAAA,EAAM,CAAC,CAAA,SAAA,EAAY,IAAI,CAAA,CAAA,EAAI,CAAA,UAAA,EAAa,KAAK,CAAA,CAAE,CAAA;AAAE,OAC3D,CAAA;AAChB,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,OAAO,IAAA;AAC/B,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AAAE,QAAA,OAAA,CAAQ,MAAM,CAAA,wBAAA,EAA2B,IAAI,CAAA,GAAA,EAAM,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAAG,QAAA,OAAO,IAAA;AAAA,MAAK;AAC9F,MAAA,MAAM,IAAA,GAA0B,MAAM,GAAA,CAAI,IAAA,EAAK;AAC/C,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,wBAAA,EAA2B,IAAI,CAAA,QAAA,CAAA,EAAY,GAAG,CAAA;AAC5D,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,eAAe,YAAA,GAAmC;AAChD,IAAA,OAAO,QAAA,CAAS,EAAE,IAAA,EAAM,WAAA,EAAa,CAAA;AAAA,EACvC;AAEA,EAAA,eAAe,SAAA,GAAgC;AAC7C,IAAA,OAAO,QAAA,CAAS,EAAE,IAAA,EAAM,YAAA,EAAc,CAAA;AAAA,EACxC;AAEA,EAAA,eAAe,gBAAA,GAAuC;AACpD,IAAA,OAAO,QAAA,CAAS,EAAE,IAAA,EAAM,mBAAA,EAAqB,CAAA;AAAA,EAC/C;AAIA,EAAA,eAAe,eAAe,KAAA,EAAwC;AACpE,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,GAAA,EAAI;AAC/B,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,KAAK,+EAA0E,CAAA;AACvF,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,eAAA,EAAkB,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AACjF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,KAAK,EAAE,KAAA,EAAO,YAAY,CAAA;AAClD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,YAAY,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACjD,QAAA,OAAA,CAAQ,MAAM,CAAA,sCAAA,EAAyC,GAAA,CAAI,MAAM,CAAA,GAAA,EAAM,SAAS,CAAA,CAAE,CAAA;AAClF,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM,wCAAwC,GAAG,CAAA;AACzD,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,eAAe,kBAAA,CAAmB,MAAc,YAAA,EAAuD;AACrG,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,YAAY,CAAA;AACjD,MAAA,IAAI,OAAA,EAAS,IAAA,KAAS,IAAA,EAAM,OAAO,OAAA;AAAA,IACrC;AACA,IAAA,OAAO,QAAQ,IAAI,CAAA;AAAA,EACrB;AAIA,EAAA,eAAe,YAAY,UAAA,EAAiD;AAC1E,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,WAAW,CAAC,MAAA,IAAU,CAAC,KAAA,IAAS,CAAC,YAAY,OAAO,IAAA;AACzD,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,YAAA,EAAe,UAAU,CAAA,CAAA,EAAI;AAAA,QAC7E,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,IAAA,EAAM,MAAM,CAAC,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAE,CAAA;AAAE,OAClD,CAAA;AAChB,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAIA,EAAA,eAAe,gBAAA,GAAqD;AAClE,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,OAAO,OAAO,IAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,eAAA,CAAA,EAAmB;AAAA,QACnE,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM;AAAA,UACJ,UAAA,EAAY,GAAA;AAAA,UACZ,IAAA,EAAM,CAAC,CAAA,eAAA,EAAkB,KAAK,CAAA,CAAE;AAAA;AAClC,OACc,CAAA;AAChB,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAqBA,EAAA,eAAe,UAAA,GAAiD;AAC9D,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,OAAO,OAAO,IAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,QAAA,CAAA,EAAY;AAAA,QAC5D,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,IAAA;AAAK,OACX,CAAA;AAChB,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AAAE,MAAA,OAAO,IAAA;AAAA,IAAK;AAAA,EACxB;AAOA,EAAA,eAAe,SAAA,GAA+C;AAC5D,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,OAAO,OAAO,IAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,OAAA,CAAA,EAAW;AAAA,QAC3D,SAAS,OAAA,EAAQ;AAAA,QACjB,KAAA,EAAO;AAAA,OACO,CAAA;AAChB,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AACpB,MAAA,OAAO,MAAM,IAAI,IAAA,EAAK;AAAA,IACxB,CAAA,CAAA,MAAQ;AAAE,MAAA,OAAO,IAAA;AAAA,IAAK;AAAA,EACxB;AAEA,EAAA,eAAe,UAAA,GAA8E;AAC3F,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,GAAA,EAAI;AAC/B,IAAA,IAAI,CAAC,WAAW,CAAC,KAAA,SAAc,EAAE,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAK;AAChE,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,QAAA,CAAA,EAAY;AAAA,QAC5D,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,EAAA,EAAI,MAAM,CAAC,CAAA,YAAA,EAAe,KAAK,CAAA,CAAE,CAAA;AAAE,OACzC,CAAA;AAChB,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,OAAO,EAAE,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAK;AAAA,MAC1C;AACA,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,IAAA,CAAK,IAAA,EAAM,UAAA,IAAc,IAAA;AAAA,QACrC,MAAA,EAAY,IAAA,CAAK,IAAA,EAAM,MAAA,IAAc;AAAA,OACvC;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAE,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAK;AAAA,IAC1C;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,cAAA;AAAA,IACA,kBAAA;AAAA,IACA,WAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAKO,IAAM,YAAY,eAAA","file":"index.js","sourcesContent":["/**\n * @sprintup-cms/sdk — Core Client\n *\n * Zero-dependency, framework-agnostic typed API client for SprintUp Forge CMS.\n *\n * @example\n * import { cmsClient } from '@sprintup-cms/sdk'\n * const page = await cmsClient.getPage('about')\n *\n * @example Custom instance\n * import { createCMSClient } from '@sprintup-cms/sdk'\n * const cms = createCMSClient({ baseUrl: '...', apiKey: '...', appId: '...' })\n */\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface CMSBlock {\n id: string\n type: string\n label?: string\n locked?: boolean\n data?: Record<string, any>\n /** Legacy field — blocks created before v1.1 used `content` instead of `data` */\n content?: Record<string, any>\n order?: number\n}\n\nexport interface CMSPage {\n _id?: string\n slug: string\n title: string\n description?: string\n pageType?: string\n pageTypeId?: string\n variant?: string\n status: 'draft' | 'published' | 'archived'\n visibility?: 'public' | 'private' | 'password'\n blocks: CMSBlock[]\n publishedAt?: string\n updatedAt?: string\n seo?: {\n title?: string\n description?: string\n keywords?: string[]\n ogImage?: string\n noIndex?: boolean\n }\n}\n\nexport interface CMSPageTypeField {\n id: string\n name: string\n label: string\n fieldType:\n | 'text' | 'textarea' | 'richtext' | 'image' | 'url'\n | 'number' | 'boolean' | 'date' | 'select' | 'relation'\n | 'email' | 'phone' | 'slug' | 'color' | 'embed'\n | 'multi-select' | 'repeater' | 'file' | 'code'\n required?: boolean\n options?: string[]\n description?: string\n maxLength?: number\n multiple?: boolean\n targetPageTypeKey?: string\n}\n\nexport interface CMSPageTypeSection {\n id: string\n name: string\n label: string\n order: number\n locked?: boolean\n fields: CMSPageTypeField[]\n}\n\nexport interface CMSPageTypeVariant {\n key: string\n label: string\n description?: string\n visibleSections?: string[]\n}\n\nexport interface CMSPageType {\n _id: string\n name: string\n key: string\n description?: string\n icon?: string\n /** Used by page-type-renderers to pick a specialised React component */\n rendererKey?: string\n /** Active variant key (set per-page) */\n variant?: string\n category: 'singleton' | 'collection' | 'global'\n contentCategory: 'singleton' | 'collection' | 'global'\n allowedRoles?: string[]\n variants: CMSPageTypeVariant[]\n sections: CMSPageTypeSection[]\n}\n\n// ── Sitemap ────────────────────────────────────────────────────────────────────\n\nexport interface CMSSitemapUrl {\n loc: string\n lastmod?: string\n changefreq?: string\n priority?: number\n title?: string\n}\n\nexport interface CMSSitemapResponse {\n enabled: boolean\n urls: CMSSitemapUrl[]\n config?: {\n defaultChangeFreq?: string\n defaultPriority?: number\n }\n}\n\n// ── Status ─────────────────────────────────────────────────────────────────────\n\nexport interface CMSStatusResponse {\n appId: string\n totalPages: number\n publishedPages: number\n connected: boolean\n pages: Array<{\n slug: string\n title: string\n pageType?: string\n group?: string\n }>\n}\n\n// ── Site Structure ─────────────────────────────────────────────────────────────\n\nexport type CMSMenuItemType = 'page' | 'url' | 'dynamic'\n\nexport interface CMSMenuItem {\n id: string\n type: CMSMenuItemType\n label: string\n contentId?: string\n url?: string\n /** Resolved href — ready to pass to <a href> or <Link href>. Never null, falls back to \"#\". */\n href: string\n locked: boolean\n openInNewTab: boolean\n children: CMSMenuItem[]\n page?: {\n title?: string\n slug?: string\n seoTitle?: string\n seoDescription?: string\n }\n}\n\nexport interface CMSPageTreeNode {\n id: string\n contentId: string\n parentId: string | null\n order: number\n locked: boolean\n visible?: boolean\n page?: {\n title?: string\n slug?: string\n seoTitle?: string\n seoDescription?: string\n }\n}\n\nexport interface CMSFooterGroup {\n id: string\n heading: string\n headingUrl?: string\n locked: boolean\n links: CMSMenuItem[]\n}\n\nexport interface CMSSiteStructure {\n appId: string\n pageTree: CMSPageTreeNode[]\n menus: {\n header: CMSMenuItem[]\n footer: CMSFooterGroup[]\n footerBottom: CMSMenuItem[]\n sidebar: CMSMenuItem[]\n [slot: string]: CMSMenuItem[] | CMSFooterGroup[]\n }\n updatedAt?: string\n}\n\n// ── Pagination & Responses ─────────────────────────────────────────────────────\n\n// v1 route returns { data, count } — flat, no nested meta object\ninterface CMSListResponse {\n data: CMSPage[]\n count: number\n appId?: string\n}\n\ninterface CMSSingleResponse {\n data: CMSPage\n}\n\n// ── Client Options ─────────────────────────────────────────────────────────────\n\nexport interface CMSClientOptions {\n /** Base URL of your Forge CMS instance, e.g. https://cms.yourschool.io */\n baseUrl?: string\n /** API key generated in CMS Admin → API Keys. Server-side only. */\n apiKey?: string\n /** App ID from CMS Admin → Apps, e.g. \"school-website\" */\n appId?: string\n}\n\nexport interface CMSGetPagesOptions {\n type?: string\n group?: string\n page?: number\n perPage?: number\n status?: 'published' | 'draft' | 'archived'\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport function createCMSClient(options?: CMSClientOptions) {\n /**\n * Resolve config lazily at request time — NOT at module/build time.\n * This prevents static prerendering crashes when env vars are absent during build.\n */\n function cfg() {\n return {\n baseUrl: (options?.baseUrl ?? process.env.NEXT_PUBLIC_CMS_URL ?? process.env.CMS_BASE_URL ?? '').replace(/\\/$/, ''),\n apiKey: options?.apiKey ?? process.env.CMS_API_KEY ?? '',\n appId: options?.appId ?? process.env.CMS_APP_ID ?? '',\n }\n }\n\n function headers() {\n return { 'X-CMS-API-Key': cfg().apiKey, 'Content-Type': 'application/json' }\n }\n\n // ── Pages ──────────────────────────────────────────────────────────────────\n\n async function getPages(params?: CMSGetPagesOptions): Promise<CMSPage[]> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) {\n console.warn('[sprintup-cms] Missing CMS_BASE_URL / CMS_API_KEY / CMS_APP_ID — returning []')\n return []\n }\n try {\n const qs = new URLSearchParams()\n if (params?.type) qs.set('type', params.type)\n if (params?.group) qs.set('group', params.group)\n if (params?.page) qs.set('page', String(params.page))\n if (params?.perPage) qs.set('perPage', String(params.perPage))\n const url = `${baseUrl}/api/v1/${appId}/pages${qs.size ? `?${qs}` : ''}`\n const res = await fetch(url, {\n headers: headers(),\n next: { revalidate: 60, tags: [`cms-pages-${appId}`] },\n } as RequestInit)\n if (!res.ok) { console.error(`[sprintup-cms] getPages (${res.status})`); return [] }\n const json: CMSListResponse = await res.json()\n return json.data ?? []\n } catch (err) {\n console.error('[sprintup-cms] getPages error:', err)\n return []\n }\n }\n\n async function getPage(slug: string): Promise<CMSPage | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) {\n console.warn('[sprintup-cms] Missing config — returning null')\n return null\n }\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/pages/${slug}`, {\n headers: headers(),\n next: { revalidate: 60, tags: [`cms-page-${slug}`, `cms-pages-${appId}`] },\n } as RequestInit)\n if (res.status === 404) return null\n if (!res.ok) { console.error(`[sprintup-cms] getPage \"${slug}\" (${res.status})`); return null }\n const json: CMSSingleResponse = await res.json()\n return json.data ?? null\n } catch (err) {\n console.error(`[sprintup-cms] getPage \"${slug}\" error:`, err)\n return null\n }\n }\n\n async function getBlogPosts(): Promise<CMSPage[]> {\n return getPages({ type: 'blog-post' })\n }\n\n async function getEvents(): Promise<CMSPage[]> {\n return getPages({ type: 'event-page' })\n }\n\n async function getAnnouncements(): Promise<CMSPage[]> {\n return getPages({ type: 'announcement-page' })\n }\n\n // ── Preview ────────────────────────────────────────────────────────────────\n\n async function getPreviewPage(token: string): Promise<CMSPage | null> {\n const { baseUrl, appId } = cfg()\n if (!baseUrl || !appId) {\n console.warn('[sprintup-cms] getPreviewPage: Missing baseUrl or appId — returning null')\n return null\n }\n try {\n const url = `${baseUrl}/api/v1/${appId}/preview?token=${encodeURIComponent(token)}`\n const res = await fetch(url, { cache: 'no-store' })\n if (!res.ok) {\n const errorText = await res.text().catch(() => '')\n console.error(`[sprintup-cms] getPreviewPage failed (${res.status}): ${errorText}`)\n return null\n }\n const json = await res.json()\n return json.data ?? null\n } catch (err) {\n console.error('[sprintup-cms] getPreviewPage error:', err)\n return null\n }\n }\n\n async function getPageWithPreview(slug: string, previewToken?: string | null): Promise<CMSPage | null> {\n if (previewToken) {\n const preview = await getPreviewPage(previewToken)\n if (preview?.slug === slug) return preview\n }\n return getPage(slug)\n }\n\n // ── Page Types ─────────────────────────────────────────────────────────────\n\n async function getPageType(pageTypeId: string): Promise<CMSPageType | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId || !pageTypeId) return null\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/page-types/${pageTypeId}`, {\n headers: headers(),\n next: { revalidate: 3600, tags: [`cms-page-type-${pageTypeId}`] },\n } as RequestInit)\n if (!res.ok) return null\n const json = await res.json()\n return json.data ?? null\n } catch {\n return null\n }\n }\n\n // ── Site Structure ─────────────────────────────────────────────────────────\n\n async function getSiteStructure(): Promise<CMSSiteStructure | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) return null\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/site-structure`, {\n headers: headers(),\n next: {\n revalidate: 300,\n tags: [`site-structure-${appId}`],\n },\n } as RequestInit)\n if (!res.ok) return null\n const json = await res.json()\n return json.data ?? null\n } catch {\n return null\n }\n }\n\n /**\n * GET /api/v1/{appId}/sitemap\n * Fetch sitemap data for all published pages (priority, changefreq, lastmod).\n *\n * @example app/sitemap.ts\n * import type { MetadataRoute } from 'next'\n * import { cmsClient } from '@sprintup-cms/sdk'\n *\n * export default async function sitemap(): Promise<MetadataRoute.Sitemap> {\n * const data = await cmsClient.getSitemap()\n * if (!data?.enabled) return []\n * return data.urls.map(url => ({\n * url: `${process.env.NEXT_PUBLIC_SITE_URL}${url.loc}`,\n * lastModified: url.lastmod,\n * changeFrequency: url.changefreq as MetadataRoute.Sitemap[0]['changeFrequency'],\n * priority: url.priority,\n * }))\n * }\n */\n async function getSitemap(): Promise<CMSSitemapResponse | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) return null\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/sitemap`, {\n headers: headers(),\n next: { revalidate: 3600 },\n } as RequestInit)\n if (!res.ok) return null\n const json = await res.json()\n return json.data ?? null\n } catch { return null }\n }\n\n /**\n * GET /api/v1/{appId}/status\n * Verify connectivity and retrieve page counts. Never cached — always fresh.\n * Useful for debugging API key setup.\n */\n async function getStatus(): Promise<CMSStatusResponse | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) return null\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/status`, {\n headers: headers(),\n cache: 'no-store',\n } as RequestInit)\n if (!res.ok) return null\n return await res.json()\n } catch { return null }\n }\n\n async function getGlobals(): Promise<{ navigation: CMSPage | null; footer: CMSPage | null }> {\n const { baseUrl, appId } = cfg()\n if (!baseUrl || !appId) return { navigation: null, footer: null }\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/globals`, {\n headers: headers(),\n next: { revalidate: 60, tags: [`cms-globals-${appId}`] },\n } as RequestInit)\n if (!res.ok) {\n return { navigation: null, footer: null }\n }\n const json = await res.json()\n return {\n navigation: json.data?.navigation ?? null,\n footer: json.data?.footer ?? null,\n }\n } catch {\n return { navigation: null, footer: null }\n }\n }\n\n return {\n getPages,\n getPage,\n getGlobals,\n getBlogPosts,\n getEvents,\n getAnnouncements,\n getPreviewPage,\n getPageWithPreview,\n getPageType,\n getSiteStructure,\n getSitemap,\n getStatus,\n }\n}\n\n// ── Default singleton ─────────────────────────────────────────────────────────\n\n/** Pre-configured singleton. Reads env vars lazily at request time. */\nexport const cmsClient = createCMSClient()\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"names":[],"mappings":";;;AAkPO,SAAS,gBAAgB,OAAA,EAA4B;AAK1D,EAAA,SAAS,GAAA,GAAM;AACb,IAAA,OAAO;AAAA,MACL,OAAA,EAAA,CAAU,OAAA,EAAS,OAAA,IAAW,OAAA,CAAQ,GAAA,CAAI,mBAAA,IAAuB,OAAA,CAAQ,GAAA,CAAI,YAAA,IAAgB,EAAA,EAAI,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAAA,MAClH,MAAA,EAAS,OAAA,EAAS,MAAA,IAAW,OAAA,CAAQ,IAAI,WAAA,IAAgB,EAAA;AAAA,MACzD,KAAA,EAAS,OAAA,EAAS,KAAA,IAAW,OAAA,CAAQ,IAAI,UAAA,IAAgB;AAAA,KAC3D;AAAA,EACF;AAEA,EAAA,SAAS,OAAA,GAAU;AACjB,IAAA,OAAO,EAAE,eAAA,EAAiB,GAAA,EAAI,CAAE,MAAA,EAAQ,gBAAgB,kBAAA,EAAmB;AAAA,EAC7E;AAIA,EAAA,eAAe,SAAS,MAAA,EAAiD;AACvE,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,KAAA,EAAO;AACjC,MAAA,OAAA,CAAQ,KAAK,oFAA+E,CAAA;AAC5F,MAAA,OAAO,EAAC;AAAA,IACV;AACA,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GAAK,IAAI,eAAA,EAAgB;AAC/B,MAAA,IAAI,QAAQ,IAAA,EAAS,EAAA,CAAG,GAAA,CAAI,MAAA,EAAW,OAAO,IAAI,CAAA;AAClD,MAAA,IAAI,QAAQ,KAAA,EAAS,EAAA,CAAG,GAAA,CAAI,OAAA,EAAW,OAAO,KAAK,CAAA;AACnD,MAAA,IAAI,MAAA,EAAQ,MAAS,EAAA,CAAG,GAAA,CAAI,QAAW,MAAA,CAAO,MAAA,CAAO,IAAI,CAAC,CAAA;AAC1D,MAAA,IAAI,MAAA,EAAQ,SAAS,EAAA,CAAG,GAAA,CAAI,WAAW,MAAA,CAAO,MAAA,CAAO,OAAO,CAAC,CAAA;AAC7D,MAAA,MAAM,GAAA,GAAM,CAAA,EAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,MAAA,EAAS,EAAA,CAAG,IAAA,GAAO,CAAA,CAAA,EAAI,EAAE,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA;AACtE,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,QAC3B,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,EAAA,EAAI,MAAM,CAAC,CAAA,UAAA,EAAa,KAAK,CAAA,CAAE,CAAA;AAAE,OACvC,CAAA;AAChB,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AAAE,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,yBAAA,EAA4B,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAAG,QAAA,OAAO,EAAC;AAAA,MAAE;AACnF,MAAA,MAAM,IAAA,GAAwB,MAAM,GAAA,CAAI,IAAA,EAAK;AAC7C,MAAA,OAAO,IAAA,CAAK,QAAQ,EAAC;AAAA,IACvB,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM,kCAAkC,GAAG,CAAA;AACnD,MAAA,OAAO,EAAC;AAAA,IACV;AAAA,EACF;AAEA,EAAA,eAAe,QAAQ,IAAA,EAAuC;AAC5D,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,KAAA,EAAO;AACjC,MAAA,OAAA,CAAQ,KAAK,qDAAgD,CAAA;AAC7D,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,OAAA,EAAU,IAAI,CAAA,CAAA,EAAI;AAAA,QAClE,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,EAAA,EAAI,IAAA,EAAM,CAAC,CAAA,SAAA,EAAY,IAAI,CAAA,CAAA,EAAI,CAAA,UAAA,EAAa,KAAK,CAAA,CAAE,CAAA;AAAE,OAC3D,CAAA;AAChB,MAAA,IAAI,GAAA,CAAI,MAAA,KAAW,GAAA,EAAK,OAAO,IAAA;AAC/B,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AAAE,QAAA,OAAA,CAAQ,MAAM,CAAA,wBAAA,EAA2B,IAAI,CAAA,GAAA,EAAM,GAAA,CAAI,MAAM,CAAA,CAAA,CAAG,CAAA;AAAG,QAAA,OAAO,IAAA;AAAA,MAAK;AAC9F,MAAA,MAAM,IAAA,GAA0B,MAAM,GAAA,CAAI,IAAA,EAAK;AAC/C,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,wBAAA,EAA2B,IAAI,CAAA,QAAA,CAAA,EAAY,GAAG,CAAA;AAC5D,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,eAAe,YAAA,GAAmC;AAChD,IAAA,OAAO,QAAA,CAAS,EAAE,IAAA,EAAM,WAAA,EAAa,CAAA;AAAA,EACvC;AAEA,EAAA,eAAe,SAAA,GAAgC;AAC7C,IAAA,OAAO,QAAA,CAAS,EAAE,IAAA,EAAM,YAAA,EAAc,CAAA;AAAA,EACxC;AAEA,EAAA,eAAe,gBAAA,GAAuC;AACpD,IAAA,OAAO,QAAA,CAAS,EAAE,IAAA,EAAM,mBAAA,EAAqB,CAAA;AAAA,EAC/C;AAIA,EAAA,eAAe,eAAe,KAAA,EAAwC;AACpE,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,GAAA,EAAI;AAC/B,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,KAAA,EAAO;AACtB,MAAA,OAAA,CAAQ,KAAK,+EAA0E,CAAA;AACvF,MAAA,OAAO,IAAA;AAAA,IACT;AACA,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,eAAA,EAAkB,kBAAA,CAAmB,KAAK,CAAC,CAAA,CAAA;AACjF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,KAAK,EAAE,KAAA,EAAO,YAAY,CAAA;AAClD,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,MAAM,YAAY,MAAM,GAAA,CAAI,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACjD,QAAA,OAAA,CAAQ,MAAM,CAAA,sCAAA,EAAyC,GAAA,CAAI,MAAM,CAAA,GAAA,EAAM,SAAS,CAAA,CAAE,CAAA;AAClF,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,SAAS,GAAA,EAAK;AACZ,MAAA,OAAA,CAAQ,KAAA,CAAM,wCAAwC,GAAG,CAAA;AACzD,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,eAAe,kBAAA,CAAmB,MAAc,YAAA,EAAuD;AACrG,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,MAAM,OAAA,GAAU,MAAM,cAAA,CAAe,YAAY,CAAA;AACjD,MAAA,IAAI,OAAA,EAAS,IAAA,KAAS,IAAA,EAAM,OAAO,OAAA;AAAA,IACrC;AACA,IAAA,OAAO,QAAQ,IAAI,CAAA;AAAA,EACrB;AAIA,EAAA,eAAe,YAAY,UAAA,EAAiD;AAC1E,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,WAAW,CAAC,MAAA,IAAU,CAAC,KAAA,IAAS,CAAC,YAAY,OAAO,IAAA;AACzD,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAM,KAAA,CAAM,CAAA,EAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,YAAA,EAAe,UAAU,CAAA,CAAA,EAAI;AAAA,QAC7E,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,IAAA,EAAM,MAAM,CAAC,CAAA,cAAA,EAAiB,UAAU,CAAA,CAAE,CAAA;AAAE,OAClD,CAAA;AAChB,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAIA,EAAA,eAAe,gBAAA,GAAqD;AAClE,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,OAAO,OAAO,IAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,eAAA,CAAA,EAAmB;AAAA,QACnE,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM;AAAA,UACJ,UAAA,EAAY,GAAA;AAAA,UACZ,IAAA,EAAM,CAAC,CAAA,eAAA,EAAkB,KAAK,CAAA,CAAE;AAAA;AAClC,OACc,CAAA;AAChB,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAqBA,EAAA,eAAe,UAAA,GAAiD;AAC9D,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,OAAO,OAAO,IAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,QAAA,CAAA,EAAY;AAAA,QAC5D,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,IAAA;AAAK,OACX,CAAA;AAChB,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AACpB,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO,KAAK,IAAA,IAAQ,IAAA;AAAA,IACtB,CAAA,CAAA,MAAQ;AAAE,MAAA,OAAO,IAAA;AAAA,IAAK;AAAA,EACxB;AAOA,EAAA,eAAe,SAAA,GAA+C;AAC5D,IAAA,MAAM,EAAE,OAAA,EAAS,MAAA,EAAQ,KAAA,KAAU,GAAA,EAAI;AACvC,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,MAAA,IAAU,CAAC,OAAO,OAAO,IAAA;AAC1C,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,OAAA,CAAA,EAAW;AAAA,QAC3D,SAAS,OAAA,EAAQ;AAAA,QACjB,KAAA,EAAO;AAAA,OACO,CAAA;AAChB,MAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,IAAA;AACpB,MAAA,OAAO,MAAM,IAAI,IAAA,EAAK;AAAA,IACxB,CAAA,CAAA,MAAQ;AAAE,MAAA,OAAO,IAAA;AAAA,IAAK;AAAA,EACxB;AAEA,EAAA,eAAe,UAAA,GAA8E;AAC3F,IAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,GAAA,EAAI;AAC/B,IAAA,IAAI,CAAC,WAAW,CAAC,KAAA,SAAc,EAAE,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAK;AAChE,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,MAAM,KAAA,CAAM,GAAG,OAAO,CAAA,QAAA,EAAW,KAAK,CAAA,QAAA,CAAA,EAAY;AAAA,QAC5D,SAAS,OAAA,EAAQ;AAAA,QACjB,IAAA,EAAM,EAAE,UAAA,EAAY,EAAA,EAAI,MAAM,CAAC,CAAA,YAAA,EAAe,KAAK,CAAA,CAAE,CAAA;AAAE,OACzC,CAAA;AAChB,MAAA,IAAI,CAAC,IAAI,EAAA,EAAI;AACX,QAAA,OAAO,EAAE,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAK;AAAA,MAC1C;AACA,MAAA,MAAM,IAAA,GAAO,MAAM,GAAA,CAAI,IAAA,EAAK;AAC5B,MAAA,OAAO;AAAA,QACL,UAAA,EAAY,IAAA,CAAK,IAAA,EAAM,UAAA,IAAc,IAAA;AAAA,QACrC,MAAA,EAAY,IAAA,CAAK,IAAA,EAAM,MAAA,IAAc;AAAA,OACvC;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,EAAE,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,IAAA,EAAK;AAAA,IAC1C;AAAA,EACF;AAEA,EAAA,OAAO;AAAA,IACL,QAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,YAAA;AAAA,IACA,SAAA;AAAA,IACA,gBAAA;AAAA,IACA,cAAA;AAAA,IACA,kBAAA;AAAA,IACA,WAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAKO,IAAM,YAAY,eAAA","file":"index.js","sourcesContent":["/**\n * @sprintup-cms/sdk — Core Client\n *\n * Zero-dependency, framework-agnostic typed API client for SprintUp Forge CMS.\n *\n * @example\n * import { cmsClient } from '@sprintup-cms/sdk'\n * const page = await cmsClient.getPage('about')\n *\n * @example Custom instance\n * import { createCMSClient } from '@sprintup-cms/sdk'\n * const cms = createCMSClient({ baseUrl: '...', apiKey: '...', appId: '...' })\n */\n\n// ── Types ─────────────────────────────────────────────────────────────────────\n\nexport interface CMSBlock {\n id: string\n type: string\n label?: string\n locked?: boolean\n data?: Record<string, any>\n /** Legacy field — blocks created before v1.1 used `content` instead of `data` */\n content?: Record<string, any>\n order?: number\n}\n\nexport interface CMSPage {\n _id?: string\n slug: string\n title: string\n description?: string\n pageType?: string\n pageTypeId?: string\n variant?: string\n status: 'draft' | 'published' | 'archived'\n visibility?: 'public' | 'private' | 'password'\n blocks: CMSBlock[]\n publishedAt?: string\n updatedAt?: string\n seo?: {\n title?: string\n description?: string\n keywords?: string[]\n ogImage?: string\n noIndex?: boolean\n }\n}\n\nexport interface CMSPageTypeField {\n id: string\n name: string\n label: string\n fieldType:\n | 'text' | 'textarea' | 'richtext' | 'image' | 'url'\n | 'number' | 'boolean' | 'date' | 'select' | 'relation'\n | 'email' | 'phone' | 'slug' | 'color' | 'embed'\n | 'multi-select' | 'repeater' | 'file' | 'code'\n required?: boolean\n options?: string[]\n description?: string\n maxLength?: number\n multiple?: boolean\n targetPageTypeKey?: string\n}\n\nexport interface CMSPageTypeSection {\n id: string\n name: string\n label: string\n order: number\n locked?: boolean\n fields: CMSPageTypeField[]\n}\n\nexport interface CMSPageTypeVariant {\n key: string\n label: string\n description?: string\n visibleSections?: string[]\n}\n\nexport interface CMSPageType {\n _id: string\n name: string\n key: string\n description?: string\n icon?: string\n /** Used by page-type-renderers to pick a specialised React component */\n rendererKey?: string\n /** Active variant key (set per-page) */\n variant?: string\n category: 'singleton' | 'collection' | 'global'\n contentCategory: 'singleton' | 'collection' | 'global'\n allowedRoles?: string[]\n variants: CMSPageTypeVariant[]\n sections: CMSPageTypeSection[]\n}\n\n// ── Sitemap ────────────────────────────────────────────────────────────────────\n\nexport interface CMSSitemapUrl {\n loc: string\n lastmod?: string\n changefreq?: string\n priority?: number\n title?: string\n}\n\nexport interface CMSSitemapResponse {\n enabled: boolean\n urls: CMSSitemapUrl[]\n config?: {\n defaultChangeFreq?: string\n defaultPriority?: number\n }\n}\n\n// ── Status ─────────────────────────────────────────────────────────────────────\n\nexport interface CMSStatusResponse {\n appId: string\n totalPages: number\n publishedPages: number\n connected: boolean\n pages: Array<{\n slug: string\n title: string\n pageType?: string\n group?: string\n }>\n}\n\n// ── Site Structure ─────────────────────────────────────────────────────────────\n\n/**\n * @deprecated Navigation and footer menus are now managed as CMS Globals.\n * Use `cmsClient.getGlobals()` instead.\n */\nexport type CMSMenuItemType = 'page' | 'url' | 'dynamic'\n\n/**\n * @deprecated Navigation and footer menus are now managed as CMS Globals.\n * Use `cmsClient.getGlobals()` instead.\n */\nexport interface CMSMenuItem {\n id: string\n type: CMSMenuItemType\n label: string\n contentId?: string\n url?: string\n /** Resolved href — ready to pass to <a href> or <Link href>. Never null, falls back to \"#\". */\n href: string\n locked: boolean\n openInNewTab: boolean\n children: CMSMenuItem[]\n page?: {\n title?: string\n slug?: string\n seoTitle?: string\n seoDescription?: string\n }\n}\n\nexport interface CMSPageTreeNode {\n id: string\n contentId: string\n parentId: string | null\n order: number\n locked: boolean\n visible?: boolean\n page?: {\n title?: string\n slug?: string\n seoTitle?: string\n seoDescription?: string\n }\n}\n\n/**\n * @deprecated Footer columns are now managed as CMS Globals.\n * Use `cmsClient.getGlobals()` instead.\n */\nexport interface CMSFooterGroup {\n id: string\n heading: string\n headingUrl?: string\n locked: boolean\n links: CMSMenuItem[]\n}\n\nexport interface CMSSiteStructure {\n appId: string\n pageTree: CMSPageTreeNode[]\n /**\n * @deprecated Menus are no longer stored in site-structure.\n * Use `cmsClient.getGlobals()` for navigation and footer data.\n */\n menus?: {\n header: CMSMenuItem[]\n footer: CMSFooterGroup[]\n footerBottom: CMSMenuItem[]\n sidebar: CMSMenuItem[]\n [slot: string]: CMSMenuItem[] | CMSFooterGroup[]\n }\n updatedAt?: string\n}\n\n// ── Pagination & Responses ─────────────────────────────────────────────────────\n\n// v1 route returns { data, count } — flat, no nested meta object\ninterface CMSListResponse {\n data: CMSPage[]\n count: number\n appId?: string\n}\n\ninterface CMSSingleResponse {\n data: CMSPage\n}\n\n// ── Client Options ─────────────────────────────────────────────────────────────\n\nexport interface CMSClientOptions {\n /** Base URL of your Forge CMS instance, e.g. https://cms.yourschool.io */\n baseUrl?: string\n /** API key generated in CMS Admin → API Keys. Server-side only. */\n apiKey?: string\n /** App ID from CMS Admin → Apps, e.g. \"school-website\" */\n appId?: string\n}\n\nexport interface CMSGetPagesOptions {\n type?: string\n group?: string\n page?: number\n perPage?: number\n status?: 'published' | 'draft' | 'archived'\n}\n\n// ── Factory ───────────────────────────────────────────────────────────────────\n\nexport function createCMSClient(options?: CMSClientOptions) {\n /**\n * Resolve config lazily at request time — NOT at module/build time.\n * This prevents static prerendering crashes when env vars are absent during build.\n */\n function cfg() {\n return {\n baseUrl: (options?.baseUrl ?? process.env.NEXT_PUBLIC_CMS_URL ?? process.env.CMS_BASE_URL ?? '').replace(/\\/$/, ''),\n apiKey: options?.apiKey ?? process.env.CMS_API_KEY ?? '',\n appId: options?.appId ?? process.env.CMS_APP_ID ?? '',\n }\n }\n\n function headers() {\n return { 'X-CMS-API-Key': cfg().apiKey, 'Content-Type': 'application/json' }\n }\n\n // ── Pages ──────────────────────────────────────────────────────────────────\n\n async function getPages(params?: CMSGetPagesOptions): Promise<CMSPage[]> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) {\n console.warn('[sprintup-cms] Missing CMS_BASE_URL / CMS_API_KEY / CMS_APP_ID — returning []')\n return []\n }\n try {\n const qs = new URLSearchParams()\n if (params?.type) qs.set('type', params.type)\n if (params?.group) qs.set('group', params.group)\n if (params?.page) qs.set('page', String(params.page))\n if (params?.perPage) qs.set('perPage', String(params.perPage))\n const url = `${baseUrl}/api/v1/${appId}/pages${qs.size ? `?${qs}` : ''}`\n const res = await fetch(url, {\n headers: headers(),\n next: { revalidate: 60, tags: [`cms-pages-${appId}`] },\n } as RequestInit)\n if (!res.ok) { console.error(`[sprintup-cms] getPages (${res.status})`); return [] }\n const json: CMSListResponse = await res.json()\n return json.data ?? []\n } catch (err) {\n console.error('[sprintup-cms] getPages error:', err)\n return []\n }\n }\n\n async function getPage(slug: string): Promise<CMSPage | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) {\n console.warn('[sprintup-cms] Missing config — returning null')\n return null\n }\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/pages/${slug}`, {\n headers: headers(),\n next: { revalidate: 60, tags: [`cms-page-${slug}`, `cms-pages-${appId}`] },\n } as RequestInit)\n if (res.status === 404) return null\n if (!res.ok) { console.error(`[sprintup-cms] getPage \"${slug}\" (${res.status})`); return null }\n const json: CMSSingleResponse = await res.json()\n return json.data ?? null\n } catch (err) {\n console.error(`[sprintup-cms] getPage \"${slug}\" error:`, err)\n return null\n }\n }\n\n async function getBlogPosts(): Promise<CMSPage[]> {\n return getPages({ type: 'blog-post' })\n }\n\n async function getEvents(): Promise<CMSPage[]> {\n return getPages({ type: 'event-page' })\n }\n\n async function getAnnouncements(): Promise<CMSPage[]> {\n return getPages({ type: 'announcement-page' })\n }\n\n // ── Preview ────────────────────────────────────────────────────────────────\n\n async function getPreviewPage(token: string): Promise<CMSPage | null> {\n const { baseUrl, appId } = cfg()\n if (!baseUrl || !appId) {\n console.warn('[sprintup-cms] getPreviewPage: Missing baseUrl or appId — returning null')\n return null\n }\n try {\n const url = `${baseUrl}/api/v1/${appId}/preview?token=${encodeURIComponent(token)}`\n const res = await fetch(url, { cache: 'no-store' })\n if (!res.ok) {\n const errorText = await res.text().catch(() => '')\n console.error(`[sprintup-cms] getPreviewPage failed (${res.status}): ${errorText}`)\n return null\n }\n const json = await res.json()\n return json.data ?? null\n } catch (err) {\n console.error('[sprintup-cms] getPreviewPage error:', err)\n return null\n }\n }\n\n async function getPageWithPreview(slug: string, previewToken?: string | null): Promise<CMSPage | null> {\n if (previewToken) {\n const preview = await getPreviewPage(previewToken)\n if (preview?.slug === slug) return preview\n }\n return getPage(slug)\n }\n\n // ── Page Types ─────────────────────────────────────────────────────────────\n\n async function getPageType(pageTypeId: string): Promise<CMSPageType | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId || !pageTypeId) return null\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/page-types/${pageTypeId}`, {\n headers: headers(),\n next: { revalidate: 3600, tags: [`cms-page-type-${pageTypeId}`] },\n } as RequestInit)\n if (!res.ok) return null\n const json = await res.json()\n return json.data ?? null\n } catch {\n return null\n }\n }\n\n // ── Site Structure ─────────────────────────────────────────────────────────\n\n async function getSiteStructure(): Promise<CMSSiteStructure | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) return null\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/site-structure`, {\n headers: headers(),\n next: {\n revalidate: 300,\n tags: [`site-structure-${appId}`],\n },\n } as RequestInit)\n if (!res.ok) return null\n const json = await res.json()\n return json.data ?? null\n } catch {\n return null\n }\n }\n\n /**\n * GET /api/v1/{appId}/sitemap\n * Fetch sitemap data for all published pages (priority, changefreq, lastmod).\n *\n * @example app/sitemap.ts\n * import type { MetadataRoute } from 'next'\n * import { cmsClient } from '@sprintup-cms/sdk'\n *\n * export default async function sitemap(): Promise<MetadataRoute.Sitemap> {\n * const data = await cmsClient.getSitemap()\n * if (!data?.enabled) return []\n * return data.urls.map(url => ({\n * url: `${process.env.NEXT_PUBLIC_SITE_URL}${url.loc}`,\n * lastModified: url.lastmod,\n * changeFrequency: url.changefreq as MetadataRoute.Sitemap[0]['changeFrequency'],\n * priority: url.priority,\n * }))\n * }\n */\n async function getSitemap(): Promise<CMSSitemapResponse | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) return null\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/sitemap`, {\n headers: headers(),\n next: { revalidate: 3600 },\n } as RequestInit)\n if (!res.ok) return null\n const json = await res.json()\n return json.data ?? null\n } catch { return null }\n }\n\n /**\n * GET /api/v1/{appId}/status\n * Verify connectivity and retrieve page counts. Never cached — always fresh.\n * Useful for debugging API key setup.\n */\n async function getStatus(): Promise<CMSStatusResponse | null> {\n const { baseUrl, apiKey, appId } = cfg()\n if (!baseUrl || !apiKey || !appId) return null\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/status`, {\n headers: headers(),\n cache: 'no-store',\n } as RequestInit)\n if (!res.ok) return null\n return await res.json()\n } catch { return null }\n }\n\n async function getGlobals(): Promise<{ navigation: CMSPage | null; footer: CMSPage | null }> {\n const { baseUrl, appId } = cfg()\n if (!baseUrl || !appId) return { navigation: null, footer: null }\n try {\n const res = await fetch(`${baseUrl}/api/v1/${appId}/globals`, {\n headers: headers(),\n next: { revalidate: 60, tags: [`cms-globals-${appId}`] },\n } as RequestInit)\n if (!res.ok) {\n return { navigation: null, footer: null }\n }\n const json = await res.json()\n return {\n navigation: json.data?.navigation ?? null,\n footer: json.data?.footer ?? null,\n }\n } catch {\n return { navigation: null, footer: null }\n }\n }\n\n return {\n getPages,\n getPage,\n getGlobals,\n getBlogPosts,\n getEvents,\n getAnnouncements,\n getPreviewPage,\n getPageWithPreview,\n getPageType,\n getSiteStructure,\n getSitemap,\n getStatus,\n }\n}\n\n// ── Default singleton ─────────────────────────────────────────────────────────\n\n/** Pre-configured singleton. Reads env vars lazily at request time. */\nexport const cmsClient = createCMSClient()\n"]}
|
package/dist/next/index.cjs
CHANGED
|
@@ -351,11 +351,15 @@ function ImageBlock({ block }) {
|
|
|
351
351
|
}
|
|
352
352
|
function HeroBlock({ block }) {
|
|
353
353
|
const d = getData(block);
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
354
|
+
const align = d.alignment || "left";
|
|
355
|
+
const textAlign = align === "right" ? "text-right" : align === "center" ? "text-center" : "text-left";
|
|
356
|
+
const itemsAlign = align === "right" ? "items-end" : align === "center" ? "items-center" : "items-start";
|
|
357
|
+
const mx = align === "center" ? "mx-auto" : align === "right" ? "ml-auto" : "";
|
|
358
|
+
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-12 md:py-20", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `max-w-3xl ${mx}`, children: [
|
|
359
|
+
d.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-block px-3 py-1 text-xs font-semibold rounded-full bg-secondary text-secondary-foreground mb-4`, children: d.badge }),
|
|
360
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: `text-4xl md:text-5xl font-bold tracking-tight mb-4 text-balance ${textAlign}`, children: d.title }),
|
|
361
|
+
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-xl text-muted-foreground mb-8 ${textAlign}`, children: d.subtitle }),
|
|
362
|
+
(d.primaryButton || d.cta) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-wrap ${itemsAlign}`, style: { gap: "1rem" }, children: [
|
|
359
363
|
(d.primaryButton || d.cta) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
360
364
|
"a",
|
|
361
365
|
{
|
|
@@ -380,7 +384,7 @@ function CTABlock({ block }) {
|
|
|
380
384
|
return /* @__PURE__ */ jsxRuntime.jsxs("section", { className: "py-12 px-8 rounded-xl bg-primary text-primary-foreground text-center", children: [
|
|
381
385
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-2xl md:text-3xl font-bold mb-4", children: d.title }),
|
|
382
386
|
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-primary-foreground/80 mb-6 max-w-2xl mx-auto", children: d.subtitle }),
|
|
383
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex
|
|
387
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-center flex-wrap", style: { gap: "1rem" }, children: [
|
|
384
388
|
d.primaryButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
385
389
|
"a",
|
|
386
390
|
{
|
|
@@ -767,7 +771,7 @@ function CenteredHeroBlock({ block }) {
|
|
|
767
771
|
children: d.subtitle
|
|
768
772
|
}
|
|
769
773
|
),
|
|
770
|
-
(d.primaryButton || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex
|
|
774
|
+
(d.primaryButton || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-center flex-wrap", style: { gap: "1rem" }, children: [
|
|
771
775
|
d.primaryButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
772
776
|
"a",
|
|
773
777
|
{
|
|
@@ -794,12 +798,16 @@ function CenteredHeroBlock({ block }) {
|
|
|
794
798
|
}
|
|
795
799
|
function ProductHeroBlock({ block }) {
|
|
796
800
|
const d = getData(block);
|
|
801
|
+
const align = d.alignment || "left";
|
|
802
|
+
const textAlign = align === "right" ? "text-right" : align === "center" ? "text-center" : "text-left";
|
|
803
|
+
const itemsAlign = align === "right" ? "justify-end" : align === "center" ? "justify-center" : "justify-start";
|
|
804
|
+
const mx = align === "center" ? "mx-auto" : align === "right" ? "ml-auto" : "";
|
|
797
805
|
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-16 md:py-24", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-6xl mx-auto px-4", children: [
|
|
798
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
799
|
-
d.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className:
|
|
800
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className:
|
|
801
|
-
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className:
|
|
802
|
-
(d.primaryButton || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
806
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `max-w-3xl ${mx} mb-12`, children: [
|
|
807
|
+
d.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex items-center gap-1.5 px-3 py-1 text-xs font-semibold rounded-full bg-primary/10 text-primary mb-5`, children: d.badge }),
|
|
808
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: `text-4xl md:text-5xl font-extrabold tracking-tight mb-5 text-balance leading-tight ${textAlign}`, children: d.title }),
|
|
809
|
+
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-lg text-muted-foreground leading-relaxed text-pretty mb-8 ${textAlign}`, children: d.subtitle }),
|
|
810
|
+
(d.primaryButton || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-wrap ${itemsAlign}`, style: { gap: "0.75rem" }, children: [
|
|
803
811
|
d.primaryButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
804
812
|
"a",
|
|
805
813
|
{
|
|
@@ -836,12 +844,16 @@ function ProductHeroBlock({ block }) {
|
|
|
836
844
|
function BentoHeroBlock({ block }) {
|
|
837
845
|
const d = getData(block);
|
|
838
846
|
const cards = Array.isArray(d.cards) ? d.cards : [];
|
|
847
|
+
const align = d.alignment || "center";
|
|
848
|
+
const textAlign = align === "right" ? "text-right" : align === "left" ? "text-left" : "text-center";
|
|
849
|
+
const itemsAlign = align === "right" ? "justify-end" : align === "left" ? "justify-start" : "justify-center";
|
|
850
|
+
const mx = align === "left" ? "" : align === "right" ? "ml-auto" : "mx-auto";
|
|
839
851
|
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-16 md:py-24", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-6xl mx-auto px-4", children: [
|
|
840
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
852
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `max-w-3xl ${mx} mb-12`, children: [
|
|
841
853
|
d.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block px-3 py-1 text-xs font-semibold rounded-full bg-secondary text-secondary-foreground mb-5", children: d.badge }),
|
|
842
|
-
/* @__PURE__ */ jsxRuntime.jsx("h1", { className:
|
|
843
|
-
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className:
|
|
844
|
-
(d.primaryButton || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
854
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: `text-4xl md:text-5xl font-extrabold tracking-tight mb-4 text-balance ${textAlign}`, children: d.title }),
|
|
855
|
+
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-lg text-muted-foreground leading-relaxed text-pretty ${textAlign}`, children: d.subtitle }),
|
|
856
|
+
(d.primaryButton || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-wrap ${itemsAlign}`, style: { gap: "0.75rem", marginTop: "1.75rem" }, children: [
|
|
845
857
|
d.primaryButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
846
858
|
"a",
|
|
847
859
|
{
|
|
@@ -867,7 +879,7 @@ function BentoHeroBlock({ block }) {
|
|
|
867
879
|
style: { background: card.background || "var(--muted)" },
|
|
868
880
|
children: [
|
|
869
881
|
card.icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-2xl", role: "img", "aria-label": card.title, children: card.icon }),
|
|
870
|
-
card.image && /* @__PURE__ */ jsxRuntime.jsx("img", { src: card.image, alt: card.title || "", className: "w-full rounded-lg object-cover mb-1", style: { maxHeight: card.featured ? "180px" : "120px" } }),
|
|
882
|
+
card.image && /* @__PURE__ */ jsxRuntime.jsx("img", { src: card.image, alt: card.imageAlt || card.title || "Feature illustration", className: "w-full rounded-lg object-cover mb-1", style: { maxHeight: card.featured ? "180px" : "120px" } }),
|
|
871
883
|
card.title && /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "font-semibold text-sm", children: card.title }),
|
|
872
884
|
card.description && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground leading-relaxed", children: card.description })
|
|
873
885
|
]
|
|
@@ -876,74 +888,17 @@ function BentoHeroBlock({ block }) {
|
|
|
876
888
|
)) })
|
|
877
889
|
] }) });
|
|
878
890
|
}
|
|
879
|
-
function AnimatedHeroBlock({ block }) {
|
|
880
|
-
const d = getData(block);
|
|
881
|
-
const words = Array.isArray(d.animatedWords) && d.animatedWords.length > 0 ? d.animatedWords : ["Fast", "Simple", "Powerful"];
|
|
882
|
-
const [wordIndex, setWordIndex] = React__default.default.useState(0);
|
|
883
|
-
const [visible, setVisible] = React__default.default.useState(true);
|
|
884
|
-
React__default.default.useEffect(() => {
|
|
885
|
-
const interval = setInterval(() => {
|
|
886
|
-
setVisible(false);
|
|
887
|
-
setTimeout(() => {
|
|
888
|
-
setWordIndex((i) => (i + 1) % words.length);
|
|
889
|
-
setVisible(true);
|
|
890
|
-
}, 300);
|
|
891
|
-
}, d.interval || 2500);
|
|
892
|
-
return () => clearInterval(interval);
|
|
893
|
-
}, [words.length, d.interval]);
|
|
894
|
-
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-24 flex flex-col items-center text-center px-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "max-w-3xl mx-auto", children: [
|
|
895
|
-
d.badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-block px-3 py-1 text-xs font-semibold rounded-full bg-secondary text-secondary-foreground mb-6", children: d.badge }),
|
|
896
|
-
/* @__PURE__ */ jsxRuntime.jsxs("h1", { className: "text-4xl md:text-6xl font-extrabold tracking-tight mb-3 text-balance leading-tight", children: [
|
|
897
|
-
d.titlePrefix && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
898
|
-
d.titlePrefix,
|
|
899
|
-
" "
|
|
900
|
-
] }),
|
|
901
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
902
|
-
"span",
|
|
903
|
-
{
|
|
904
|
-
style: {
|
|
905
|
-
display: "inline-block",
|
|
906
|
-
color: "var(--primary)",
|
|
907
|
-
transition: "opacity 0.3s ease, transform 0.3s ease",
|
|
908
|
-
opacity: visible ? 1 : 0,
|
|
909
|
-
transform: visible ? "translateY(0)" : "translateY(-8px)"
|
|
910
|
-
},
|
|
911
|
-
children: words[wordIndex]
|
|
912
|
-
}
|
|
913
|
-
),
|
|
914
|
-
d.titleSuffix && /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
915
|
-
" ",
|
|
916
|
-
d.titleSuffix
|
|
917
|
-
] })
|
|
918
|
-
] }),
|
|
919
|
-
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-lg md:text-xl text-muted-foreground leading-relaxed mb-9 text-pretty", children: d.subtitle }),
|
|
920
|
-
(d.primaryButton || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-4 justify-center flex-wrap", children: [
|
|
921
|
-
d.primaryButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
922
|
-
"a",
|
|
923
|
-
{
|
|
924
|
-
href: d.primaryUrl || "#",
|
|
925
|
-
className: "inline-flex items-center px-8 py-3.5 rounded-xl bg-primary text-primary-foreground font-semibold text-sm hover:opacity-90 transition-opacity",
|
|
926
|
-
children: d.primaryButton
|
|
927
|
-
}
|
|
928
|
-
),
|
|
929
|
-
d.secondaryButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
930
|
-
"a",
|
|
931
|
-
{
|
|
932
|
-
href: d.secondaryUrl || "#",
|
|
933
|
-
className: "inline-flex items-center px-8 py-3.5 rounded-xl border border-border text-foreground font-semibold text-sm hover:bg-muted transition-colors",
|
|
934
|
-
children: d.secondaryButton
|
|
935
|
-
}
|
|
936
|
-
)
|
|
937
|
-
] })
|
|
938
|
-
] }) });
|
|
939
|
-
}
|
|
940
891
|
function MinimalHeroBlock({ block }) {
|
|
941
892
|
const d = getData(block);
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
893
|
+
const align = d.alignment || "left";
|
|
894
|
+
const textAlign = align === "right" ? "text-right" : align === "center" ? "text-center" : "text-left";
|
|
895
|
+
const itemsAlign = align === "right" ? "justify-end" : align === "center" ? "justify-center" : "justify-start";
|
|
896
|
+
const mx = align === "center" ? "mx-auto" : align === "right" ? "ml-auto" : "";
|
|
897
|
+
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-20 md:py-28 px-4 border-b border-border", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `max-w-4xl ${mx}`, children: [
|
|
898
|
+
d.eyebrow && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-xs uppercase tracking-[0.2em] font-semibold text-muted-foreground mb-5 ${textAlign}`, children: d.eyebrow }),
|
|
899
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: `text-5xl md:text-7xl font-black tracking-tight mb-6 text-balance leading-none whitespace-pre-line ${textAlign}`, children: d.title }),
|
|
900
|
+
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-lg md:text-xl text-muted-foreground leading-relaxed text-pretty max-w-2xl mb-9 ${textAlign} ${mx}`, children: d.subtitle }),
|
|
901
|
+
(d.primaryButton || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-wrap items-center ${itemsAlign}`, style: { gap: "1rem" }, children: [
|
|
947
902
|
d.primaryButton && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
948
903
|
"a",
|
|
949
904
|
{
|
|
@@ -969,16 +924,19 @@ function MinimalHeroBlock({ block }) {
|
|
|
969
924
|
function SplitHeroBlock({ block }) {
|
|
970
925
|
const d = getData(block);
|
|
971
926
|
const imgLeft = d.imagePosition === "left";
|
|
927
|
+
const align = d.alignment || "left";
|
|
928
|
+
const textAlign = align === "center" ? "text-center" : "text-left";
|
|
929
|
+
const itemsAlign = align === "center" ? "items-center" : "items-start";
|
|
972
930
|
return /* @__PURE__ */ jsxRuntime.jsx("section", { className: "py-16", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-col ${imgLeft ? "md:flex-row-reverse" : "md:flex-row"} items-center gap-10 md:gap-16 max-w-6xl mx-auto px-4`, children: [
|
|
973
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
974
|
-
d.title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className:
|
|
975
|
-
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className:
|
|
976
|
-
(d.button || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className:
|
|
931
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex-1 space-y-5 ${itemsAlign} flex flex-col`, children: [
|
|
932
|
+
d.title && /* @__PURE__ */ jsxRuntime.jsx("h1", { className: `text-3xl md:text-5xl font-extrabold tracking-tight text-balance leading-tight ${textAlign}`, children: d.title }),
|
|
933
|
+
d.subtitle && /* @__PURE__ */ jsxRuntime.jsx("p", { className: `text-lg text-muted-foreground leading-relaxed text-pretty ${textAlign}`, children: d.subtitle }),
|
|
934
|
+
(d.button || d.secondaryButton) && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `flex flex-wrap ${align === "center" ? "justify-center" : "justify-start"}`, style: { gap: "0.75rem", paddingTop: "0.5rem" }, children: [
|
|
977
935
|
d.button && /* @__PURE__ */ jsxRuntime.jsx("a", { href: d.buttonUrl || "#", className: "inline-flex items-center px-6 py-3 rounded-lg bg-primary text-primary-foreground font-semibold text-sm hover:opacity-90 transition-opacity", children: d.button }),
|
|
978
936
|
d.secondaryButton && /* @__PURE__ */ jsxRuntime.jsx("a", { href: d.secondaryUrl || "#", className: "inline-flex items-center px-6 py-3 rounded-lg border border-border text-foreground font-semibold text-sm hover:bg-muted transition-colors", children: d.secondaryButton })
|
|
979
937
|
] })
|
|
980
938
|
] }),
|
|
981
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: d.image ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: d.image, alt: d.title || "", className: "w-full rounded-2xl object-cover shadow-lg border border-border" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full rounded-2xl bg-muted border border-border aspect-video flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "No image set" }) }) })
|
|
939
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 w-full", children: d.image ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: d.image, alt: d.imageAlt || d.title || "Hero image", className: "w-full rounded-2xl object-cover shadow-lg border border-border" }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-full rounded-2xl bg-muted border border-border aspect-video flex items-center justify-center", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground", children: "No image set" }) }) })
|
|
982
940
|
] }) });
|
|
983
941
|
}
|
|
984
942
|
function AccordionBlock({ block }) {
|
|
@@ -1229,7 +1187,6 @@ var BUILT_IN = {
|
|
|
1229
1187
|
"centered-hero": (b) => /* @__PURE__ */ jsxRuntime.jsx(CenteredHeroBlock, { block: b }),
|
|
1230
1188
|
"product-hero": (b) => /* @__PURE__ */ jsxRuntime.jsx(ProductHeroBlock, { block: b }),
|
|
1231
1189
|
"bento-hero": (b) => /* @__PURE__ */ jsxRuntime.jsx(BentoHeroBlock, { block: b }),
|
|
1232
|
-
"animated-hero": (b) => /* @__PURE__ */ jsxRuntime.jsx(AnimatedHeroBlock, { block: b }),
|
|
1233
1190
|
"minimal-hero": (b) => /* @__PURE__ */ jsxRuntime.jsx(MinimalHeroBlock, { block: b }),
|
|
1234
1191
|
cta: (b) => /* @__PURE__ */ jsxRuntime.jsx(CTABlock, { block: b }),
|
|
1235
1192
|
faq: (b) => /* @__PURE__ */ jsxRuntime.jsx(FAQBlock, { block: b }),
|
|
@@ -1569,7 +1526,7 @@ async function resolveProductListBlocks(blocks) {
|
|
|
1569
1526
|
}
|
|
1570
1527
|
}));
|
|
1571
1528
|
}
|
|
1572
|
-
async function CMSCatchAllPage({ params }) {
|
|
1529
|
+
async function CMSCatchAllPage({ params, layout = true }) {
|
|
1573
1530
|
const { slug } = await params;
|
|
1574
1531
|
const slugStr = slug.join("/");
|
|
1575
1532
|
const draft = await headers.draftMode();
|
|
@@ -1592,8 +1549,13 @@ async function CMSCatchAllPage({ params }) {
|
|
|
1592
1549
|
client.getGlobals().catch(() => ({ navigation: null, footer: null }))
|
|
1593
1550
|
]);
|
|
1594
1551
|
const resolvedBlocks = await resolveProductListBlocks(page.blocks ?? []);
|
|
1552
|
+
const showDefaultLayout = layout === true;
|
|
1553
|
+
const showCustomLayout = typeof layout === "object" && layout !== null;
|
|
1554
|
+
const CustomHeader = showCustomLayout ? layout.Header : null;
|
|
1555
|
+
const CustomFooter = showCustomLayout ? layout.Footer : null;
|
|
1595
1556
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-screen bg-background flex flex-col", children: [
|
|
1596
|
-
/* @__PURE__ */ jsxRuntime.jsx(CMSHeader, { nav: globals?.navigation }),
|
|
1557
|
+
showDefaultLayout && /* @__PURE__ */ jsxRuntime.jsx(CMSHeader, { nav: globals?.navigation }),
|
|
1558
|
+
CustomHeader && /* @__PURE__ */ jsxRuntime.jsx(CustomHeader, { nav: globals?.navigation, globals }),
|
|
1597
1559
|
isPreview && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "sticky top-0 z-50 flex items-center justify-between px-4 py-2.5 bg-amber-500 text-white text-sm font-medium shadow", children: [
|
|
1598
1560
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
|
|
1599
1561
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Draft Preview" }),
|
|
@@ -1623,7 +1585,8 @@ async function CMSCatchAllPage({ params }) {
|
|
|
1623
1585
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "No content added yet." }),
|
|
1624
1586
|
isPreview && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs mt-1 opacity-60", children: "Add blocks in the CMS editor to see them here." })
|
|
1625
1587
|
] }) }),
|
|
1626
|
-
/* @__PURE__ */ jsxRuntime.jsx(CMSFooter, { footer: globals?.footer })
|
|
1588
|
+
showDefaultLayout && /* @__PURE__ */ jsxRuntime.jsx(CMSFooter, { footer: globals?.footer }),
|
|
1589
|
+
CustomFooter && /* @__PURE__ */ jsxRuntime.jsx(CustomFooter, { footer: globals?.footer, globals })
|
|
1627
1590
|
] });
|
|
1628
1591
|
}
|
|
1629
1592
|
async function dynamicProxyGET(req) {
|