@bettercms-ai/next 0.23.0 → 0.24.0
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 +321 -321
- package/dist/bettercms-snapshot.js +0 -0
- package/dist/bettercms-snapshot.js.map +1 -1
- package/dist/blocks.js.map +1 -1
- package/dist/draft-bridge.js.map +1 -1
- package/dist/form.js.map +1 -1
- package/dist/index.d.ts +31 -4
- package/dist/index.js +81 -0
- package/dist/index.js.map +1 -1
- package/dist/live.js.map +1 -1
- package/dist/phone-field.js.map +1 -1
- package/dist/search.js.map +1 -1
- package/dist/visual-editing.js.map +1 -1
- package/package.json +94 -94
package/dist/phone-field.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/phone-field.tsx"],"sourcesContent":["\"use client\";\
|
|
1
|
+
{"version":3,"sources":["../src/phone-field.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * The phone control for a field with `ui.countryPicker`, in its own entry so that\n * libphonenumber's metadata NEVER reaches `dist/form.js`.\n *\n * This file is lazy-imported by `<BcmsForm>` and is listed in tsup's `external`, so the\n * dynamic import survives into the built output instead of being inlined. `splitting` is\n * false for this package, and with it false esbuild inlines a dynamic import outright —\n * every consumer of `@bettercms-ai/next/form` would then ship ~80KB of metadata whether or\n * not any of their fields enabled a picker. Nothing errors when that happens; `form.js`\n * just quietly grows. The dist greps in this package's tests are what keep it honest.\n *\n * Markup contract, shared with the vanilla renderers (see `DeliveryFormFieldUi` in\n * `@bettercms-ai/sdk`): a `.bcms-phone` wrapper holding a country `<select>` and a `tel`\n * input, submitting ONE E.164 string under the field's own key. Everything is unstyled and\n * class-driven, like the rest of this package.\n */\n\nimport { useMemo, useState } from \"react\";\nimport PhoneInputBase, {\n getCountries,\n getCountryCallingCode,\n isSupportedCountry,\n type Country,\n} from \"react-phone-number-input/input\";\n\n/** Region names for the option labels, built once. Falls back to the ISO code. */\nconst regionNames =\n typeof Intl !== \"undefined\" && typeof Intl.DisplayNames === \"function\"\n ? new Intl.DisplayNames([\"en\"], { type: \"region\" })\n : null;\n\nconst countryName = (iso: string): string => {\n try {\n return regionNames?.of(iso) ?? iso;\n } catch {\n return iso;\n }\n};\n\n/**\n * Every supported country, sorted by name.\n *\n * Each helper is wrapped in an arrow rather than passed as a bare callback: `.filter`/`.map`\n * hand the array INDEX as the second argument, which every libphonenumber helper reads as its\n * `metadata` parameter and throws on.\n */\nconst COUNTRIES: { iso: Country; name: string; code: string }[] = getCountries()\n .filter((iso) => isSupportedCountry(iso))\n .map((iso) => ({ iso, name: countryName(iso), code: getCountryCallingCode(iso) }))\n .sort((a, b) => a.name.localeCompare(b.name));\n\n/**\n * Collapse a value that is only a calling code to `\"\"`.\n *\n * With `withCountryCallingCode` the `+CC` prefix is permanently present in the input, so\n * clearing every national digit leaves `\"+91\"`. Posting that is worse than it looks: the\n * server's loose phone shape is 3–32 characters, so `\"+1\"` is REFUSED (an untouched optional\n * field starts failing) while `\"+91\"` is ACCEPTED and stored as a real-looking submission that\n * is nothing but a country code. The silent case is the dangerous one.\n */\nexport function normalizeOut(value: string | undefined, country: Country | null): string {\n if (!value) return \"\";\n const digits = value.replace(/\\D/g, \"\");\n if (!digits) return \"\";\n if (country && digits === getCountryCallingCode(country)) return \"\";\n return value;\n}\n\n/** The national part of `value`, so switching country can re-prefix it. */\nfunction nationalDigits(value: string, current: Country | null): string {\n const digits = value.replace(/\\D/g, \"\");\n if (!digits) return \"\";\n if (current) {\n const cc = getCountryCallingCode(current);\n if (digits.startsWith(cc)) return digits.slice(cc.length);\n }\n if (value.trim().startsWith(\"+\")) {\n const codes = [...new Set(COUNTRIES.map((c) => c.code))].sort((a, b) => b.length - a.length);\n const match = codes.find((cc) => digits.startsWith(cc));\n if (match) return digits.slice(match.length);\n }\n return digits;\n}\n\nexport interface PhoneFieldProps {\n name: string;\n value: string;\n onChange: (next: string) => void;\n placeholder?: string;\n required?: boolean;\n /** ISO 3166-1 alpha-2 the picker starts on. Absent means international entry. */\n defaultCountry?: string;\n}\n\nexport default function PhoneField({\n name,\n value,\n onChange,\n placeholder,\n required,\n defaultCountry,\n}: PhoneFieldProps) {\n const seed = useMemo(\n () => (defaultCountry && isSupportedCountry(defaultCountry as Country) ? (defaultCountry as Country) : null),\n [defaultCountry],\n );\n const [country, setCountry] = useState<Country | null>(seed);\n\n /**\n * Changing the library's `country` prop does NOT rewrite an existing value — it only\n * re-renders it — so the select and the number would disagree. Rewrite it here.\n */\n const pickCountry = (next: Country | null) => {\n const national = nationalDigits(value, country);\n onChange(national ? `+${next ? getCountryCallingCode(next) : \"\"}${national}` : \"\");\n setCountry(next);\n };\n\n // `country` + `international` + `withCountryCallingCode` is the library's only legal trio;\n // with no country, none of them may be passed at all.\n const modeProps = country ? ({ country, international: true, withCountryCallingCode: true } as const) : ({} as const);\n\n return (\n <span className=\"bcms-phone\">\n <select\n className=\"bcms-phone-country\"\n aria-label=\"Country code\"\n value={country ?? \"\"}\n onChange={(e) => pickCountry((e.target.value || null) as Country | null)}\n >\n <option value=\"\">International</option>\n {COUNTRIES.map((c) => (\n <option key={c.iso} value={c.iso}>\n {c.name} +{c.code}\n </option>\n ))}\n </select>\n <PhoneInputBase\n {...modeProps}\n name={name}\n value={value || undefined}\n onChange={(next?: string) => onChange(normalizeOut(next, country))}\n placeholder={placeholder}\n required={required}\n autoComplete=\"tel\"\n dir=\"ltr\"\n />\n </span>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/search.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/search.tsx"],"sourcesContent":["\"use client\";\
|
|
1
|
+
{"version":3,"sources":["../src/search.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * <BcmsSearch> — an instant, typo-tolerant site-search box for React/Next.\n *\n * Debounced search-as-you-type against the public delivery search endpoint (via\n * `@bettercms-ai/sdk`'s `search`), rendering a dropdown of results under the input.\n * No API key — `project` (from the dashboard's Site Search settings) is the only\n * scope. All markup is unstyled and `bcms-search-*` class-driven, so the host\n * site owns the look. Mirrors <BcmsForm>.\n */\n\nimport { useEffect, useRef, useState, type ReactElement } from \"react\";\nimport { search, type SearchHit } from \"@bettercms-ai/sdk\";\n\nexport interface BcmsSearchProps {\n /** The project id (from Site Search settings). */\n project: string;\n /** API origin. Defaults to the SDK default (https://api.bettercms.ai). */\n apiBase?: string;\n /** Placeholder for the input. */\n placeholder?: string;\n /** Max results, 1–20 (default 8). */\n limit?: number;\n /** Debounce in ms (default 200). */\n debounceMs?: number;\n /** Class for the wrapper; inner elements use `bcms-search-*` classes. */\n className?: string;\n /** Called when a result is chosen; return false to suppress the default navigation. */\n onSelect?: (hit: SearchHit) => boolean | void;\n}\n\nexport function BcmsSearch({\n project,\n apiBase,\n placeholder = \"Search…\",\n limit,\n debounceMs = 200,\n className,\n onSelect,\n}: BcmsSearchProps): ReactElement {\n const [query, setQuery] = useState(\"\");\n const [hits, setHits] = useState<SearchHit[]>([]);\n const [open, setOpen] = useState(false);\n const [active, setActive] = useState(-1);\n const wrap = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n const q = query.trim();\n if (q.length < 2) {\n setHits([]);\n setOpen(false);\n return;\n }\n const ctrl = new AbortController();\n const t = setTimeout(() => {\n search({ project, q, limit, baseUrl: apiBase, signal: ctrl.signal }).then((r) => {\n setHits(r);\n setActive(-1);\n setOpen(true);\n });\n }, debounceMs);\n return () => {\n clearTimeout(t);\n ctrl.abort();\n };\n }, [query, project, apiBase, limit, debounceMs]);\n\n // Close on outside click.\n useEffect(() => {\n const onClick = (e: MouseEvent) => {\n if (wrap.current && !wrap.current.contains(e.target as Node)) setOpen(false);\n };\n document.addEventListener(\"click\", onClick);\n return () => document.removeEventListener(\"click\", onClick);\n }, []);\n\n const choose = (hit: SearchHit) => {\n if (onSelect?.(hit) === false) return;\n window.location.href = hit.url;\n };\n\n const onKeyDown = (e: React.KeyboardEvent) => {\n if (!open || !hits.length) return;\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n setActive((i) => (i + 1) % hits.length);\n } else if (e.key === \"ArrowUp\") {\n e.preventDefault();\n setActive((i) => (i - 1 + hits.length) % hits.length);\n } else if (e.key === \"Enter\" && active >= 0) {\n e.preventDefault();\n choose(hits[active]);\n } else if (e.key === \"Escape\") {\n setOpen(false);\n }\n };\n\n return (\n <div ref={wrap} className={`bcms-search${className ? ` ${className}` : \"\"}`} style={{ position: \"relative\" }}>\n <input\n type=\"search\"\n className=\"bcms-search-input\"\n placeholder={placeholder}\n aria-label=\"Search this site\"\n value={query}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={onKeyDown}\n onFocus={() => hits.length && setOpen(true)}\n />\n {open && (\n <div className=\"bcms-search-results\" role=\"listbox\">\n {hits.length === 0 ? (\n <div className=\"bcms-search-empty\">No results</div>\n ) : (\n hits.map((hit, i) => (\n <a\n key={`${hit.type}:${hit.slug}`}\n href={hit.url}\n role=\"option\"\n aria-selected={i === active}\n className={`bcms-search-hit${i === active ? \" is-active\" : \"\"}`}\n onClick={(e) => {\n e.preventDefault();\n choose(hit);\n }}\n >\n <span className=\"bcms-search-title\">{hit.title}</span>\n {hit.snippet && (\n <span\n className=\"bcms-search-snippet\"\n dangerouslySetInnerHTML={{ __html: hit.snippet }}\n />\n )}\n </a>\n ))\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;AAYA,SAAS,WAAW,QAAQ,gBAAmC;AAC/D,SAAS,cAA8B;AAuFjC,cAgBQ,YAhBR;AApEC,SAAS,WAAW;AAAA,EACzB;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA,aAAa;AAAA,EACb;AAAA,EACA;AACF,GAAkC;AAChC,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,EAAE;AACrC,QAAM,CAAC,MAAM,OAAO,IAAI,SAAsB,CAAC,CAAC;AAChD,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,EAAE;AACvC,QAAM,OAAO,OAAuB,IAAI;AAExC,YAAU,MAAM;AACd,UAAM,IAAI,MAAM,KAAK;AACrB,QAAI,EAAE,SAAS,GAAG;AAChB,cAAQ,CAAC,CAAC;AACV,cAAQ,KAAK;AACb;AAAA,IACF;AACA,UAAM,OAAO,IAAI,gBAAgB;AACjC,UAAM,IAAI,WAAW,MAAM;AACzB,aAAO,EAAE,SAAS,GAAG,OAAO,SAAS,SAAS,QAAQ,KAAK,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM;AAC/E,gBAAQ,CAAC;AACT,kBAAU,EAAE;AACZ,gBAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH,GAAG,UAAU;AACb,WAAO,MAAM;AACX,mBAAa,CAAC;AACd,WAAK,MAAM;AAAA,IACb;AAAA,EACF,GAAG,CAAC,OAAO,SAAS,SAAS,OAAO,UAAU,CAAC;AAG/C,YAAU,MAAM;AACd,UAAM,UAAU,CAAC,MAAkB;AACjC,UAAI,KAAK,WAAW,CAAC,KAAK,QAAQ,SAAS,EAAE,MAAc,EAAG,SAAQ,KAAK;AAAA,IAC7E;AACA,aAAS,iBAAiB,SAAS,OAAO;AAC1C,WAAO,MAAM,SAAS,oBAAoB,SAAS,OAAO;AAAA,EAC5D,GAAG,CAAC,CAAC;AAEL,QAAM,SAAS,CAAC,QAAmB;AACjC,QAAI,WAAW,GAAG,MAAM,MAAO;AAC/B,WAAO,SAAS,OAAO,IAAI;AAAA,EAC7B;AAEA,QAAM,YAAY,CAAC,MAA2B;AAC5C,QAAI,CAAC,QAAQ,CAAC,KAAK,OAAQ;AAC3B,QAAI,EAAE,QAAQ,aAAa;AACzB,QAAE,eAAe;AACjB,gBAAU,CAAC,OAAO,IAAI,KAAK,KAAK,MAAM;AAAA,IACxC,WAAW,EAAE,QAAQ,WAAW;AAC9B,QAAE,eAAe;AACjB,gBAAU,CAAC,OAAO,IAAI,IAAI,KAAK,UAAU,KAAK,MAAM;AAAA,IACtD,WAAW,EAAE,QAAQ,WAAW,UAAU,GAAG;AAC3C,QAAE,eAAe;AACjB,aAAO,KAAK,MAAM,CAAC;AAAA,IACrB,WAAW,EAAE,QAAQ,UAAU;AAC7B,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,SACE,qBAAC,SAAI,KAAK,MAAM,WAAW,cAAc,YAAY,IAAI,SAAS,KAAK,EAAE,IAAI,OAAO,EAAE,UAAU,WAAW,GACzG;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV;AAAA,QACA,cAAW;AAAA,QACX,OAAO;AAAA,QACP,UAAU,CAAC,MAAM,SAAS,EAAE,OAAO,KAAK;AAAA,QACxC;AAAA,QACA,SAAS,MAAM,KAAK,UAAU,QAAQ,IAAI;AAAA;AAAA,IAC5C;AAAA,IACC,QACC,oBAAC,SAAI,WAAU,uBAAsB,MAAK,WACvC,eAAK,WAAW,IACf,oBAAC,SAAI,WAAU,qBAAoB,wBAAU,IAE7C,KAAK,IAAI,CAAC,KAAK,MACb;AAAA,MAAC;AAAA;AAAA,QAEC,MAAM,IAAI;AAAA,QACV,MAAK;AAAA,QACL,iBAAe,MAAM;AAAA,QACrB,WAAW,kBAAkB,MAAM,SAAS,eAAe,EAAE;AAAA,QAC7D,SAAS,CAAC,MAAM;AACd,YAAE,eAAe;AACjB,iBAAO,GAAG;AAAA,QACZ;AAAA,QAEA;AAAA,8BAAC,UAAK,WAAU,qBAAqB,cAAI,OAAM;AAAA,UAC9C,IAAI,WACH;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,yBAAyB,EAAE,QAAQ,IAAI,QAAQ;AAAA;AAAA,UACjD;AAAA;AAAA;AAAA,MAfG,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI;AAAA,IAiB9B,CACD,GAEL;AAAA,KAEJ;AAEJ;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/visual-editing.tsx"],"sourcesContent":["\"use client\";\
|
|
1
|
+
{"version":3,"sources":["../src/visual-editing.tsx"],"sourcesContent":["\"use client\";\n/**\n * <VisualEditing> — click-to-edit overlay for draft preview. Alt+Click any value that\n * carries stega provenance to open the matching dashboard editor on that field.\n * Render it only in draft mode.\n *\n * import { VisualEditing } from \"@bettercms-ai/next/visual-editing\";\n * {isDraft && <VisualEditing studioUrl=\"https://bettercms.ai\" />}\n *\n * The decoder is NOT bundled here. It is one script served from the dashboard origin\n * (`/bcms-visual-editing.js`), shared with @bettercms-ai/astro and with plain-HTML sites\n * that install it by hand — a customer build is un-upgradable, so a copy baked into one\n * could never be fixed. Requires the read client to be in draft perspective with\n * `stega: true`; on a published build there is no provenance and the script is inert.\n */\nimport { useEffect } from \"react\";\n\nexport interface VisualEditingProps {\n /**\n * Studio origin, for the deep links and for the script itself. Defaults to\n * `https://bettercms.ai` — the same origin the dashboard hands out as\n * `NEXT_PUBLIC_BCMS_STUDIO_URL`, confirmed canonical 2026-08-16.\n * (`dashboard.bettercms.ai` resolves but 404s; `demo.bettercms.ai` still serves\n * but is a stale alias we no longer hand out.)\n */\n studioUrl?: string;\n}\n\nexport function VisualEditing({ studioUrl = \"https://bettercms.ai\" }: VisualEditingProps) {\n useEffect(() => {\n const src = `${studioUrl.replace(/\\/+$/, \"\")}/bcms-visual-editing.js`;\n if (document.querySelector(`script[src=\"${src}\"]`)) return;\n const el = document.createElement(\"script\");\n el.src = src;\n el.defer = true;\n el.dataset.bcmsStudio = studioUrl;\n document.head.appendChild(el);\n // No cleanup: removing the tag would not detach the listeners the script installed,\n // so a remove-and-remount would leave one set orphaned and add a second. The tag is\n // its own guard instead — this component is mounted once, in a draft-mode layout.\n }, [studioUrl]);\n return null;\n}\n"],"mappings":";;;;AAeA,SAAS,iBAAiB;AAanB,SAAS,cAAc,EAAE,YAAY,uBAAuB,GAAuB;AACxF,YAAU,MAAM;AACd,UAAM,MAAM,GAAG,UAAU,QAAQ,QAAQ,EAAE,CAAC;AAC5C,QAAI,SAAS,cAAc,eAAe,GAAG,IAAI,EAAG;AACpD,UAAM,KAAK,SAAS,cAAc,QAAQ;AAC1C,OAAG,MAAM;AACT,OAAG,QAAQ;AACX,OAAG,QAAQ,aAAa;AACxB,aAAS,KAAK,YAAY,EAAE;AAAA,EAI9B,GAAG,CAAC,SAAS,CAAC;AACd,SAAO;AACT;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@bettercms-ai/next",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"description": "The BetterCMS adapter for Next.js — typed, cache-aware content reads (getEntry/listEntries), draft preview, build-time content snapshot, and llms.txt generation for the App Router. The /blocks, /form, /field, /search and /visual-editing entries are framework-free React and work in any React app (see the React+TS starter), which is why `next` is an OPTIONAL peer.",
|
|
6
|
-
"bin": {
|
|
7
|
-
"bettercms-snapshot": "./dist/bettercms-snapshot.js"
|
|
8
|
-
},
|
|
9
|
-
"main": "./dist/index.js",
|
|
10
|
-
"module": "./dist/index.js",
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"sideEffects": false,
|
|
13
|
-
"exports": {
|
|
14
|
-
".": {
|
|
15
|
-
"types": "./dist/index.d.ts",
|
|
16
|
-
"import": "./dist/index.js",
|
|
17
|
-
"default": "./dist/index.js"
|
|
18
|
-
},
|
|
19
|
-
"./form": {
|
|
20
|
-
"types": "./dist/form.d.ts",
|
|
21
|
-
"import": "./dist/form.js",
|
|
22
|
-
"default": "./dist/form.js"
|
|
23
|
-
},
|
|
24
|
-
"./search": {
|
|
25
|
-
"types": "./dist/search.d.ts",
|
|
26
|
-
"import": "./dist/search.js",
|
|
27
|
-
"default": "./dist/search.js"
|
|
28
|
-
},
|
|
29
|
-
"./blocks": {
|
|
30
|
-
"types": "./dist/blocks.d.ts",
|
|
31
|
-
"import": "./dist/blocks.js",
|
|
32
|
-
"default": "./dist/blocks.js"
|
|
33
|
-
},
|
|
34
|
-
"./live": {
|
|
35
|
-
"types": "./dist/live.d.ts",
|
|
36
|
-
"import": "./dist/live.js",
|
|
37
|
-
"default": "./dist/live.js"
|
|
38
|
-
},
|
|
39
|
-
"./visual-editing": {
|
|
40
|
-
"types": "./dist/visual-editing.d.ts",
|
|
41
|
-
"import": "./dist/visual-editing.js",
|
|
42
|
-
"default": "./dist/visual-editing.js"
|
|
43
|
-
},
|
|
44
|
-
"./draft-bridge": {
|
|
45
|
-
"types": "./dist/draft-bridge.d.ts",
|
|
46
|
-
"import": "./dist/draft-bridge.js",
|
|
47
|
-
"default": "./dist/draft-bridge.js"
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
"files": [
|
|
51
|
-
"dist",
|
|
52
|
-
"README.md"
|
|
53
|
-
],
|
|
54
|
-
"scripts": {
|
|
55
|
-
"typecheck": "tsc --noEmit",
|
|
56
|
-
"build": "tsup",
|
|
57
|
-
"test": "vitest run",
|
|
58
|
-
"test:watch": "vitest"
|
|
59
|
-
},
|
|
60
|
-
"dependencies": {
|
|
61
|
-
"@bettercms-ai/icons": "^0.2.0",
|
|
62
|
-
"@bettercms-ai/image-url": "^0.4.0",
|
|
63
|
-
"@bettercms-ai/richtext": "^0.8.1",
|
|
64
|
-
"@bettercms-ai/sdk": "^1.
|
|
65
|
-
"@bettercms-ai/types": "^1.
|
|
66
|
-
"@bettercms-ai/ui": "^0.15.
|
|
67
|
-
"react-phone-number-input": "^3.4.18"
|
|
68
|
-
},
|
|
69
|
-
"peerDependencies": {
|
|
70
|
-
"next": ">=14",
|
|
71
|
-
"react": ">=18"
|
|
72
|
-
},
|
|
73
|
-
"peerDependenciesMeta": {
|
|
74
|
-
"next": {
|
|
75
|
-
"optional": true
|
|
76
|
-
},
|
|
77
|
-
"react": {
|
|
78
|
-
"optional": true
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
"devDependencies": {
|
|
82
|
-
"@types/node": "^20",
|
|
83
|
-
"@types/react": "^19.0.0",
|
|
84
|
-
"next": "^15.5.24",
|
|
85
|
-
"react": "^19.0.0",
|
|
86
|
-
"tsup": "^8.5.1",
|
|
87
|
-
"typescript": "^5",
|
|
88
|
-
"vitest": "^4.1.4"
|
|
89
|
-
},
|
|
90
|
-
"publishConfig": {
|
|
91
|
-
"registry": "https://registry.npmjs.org/",
|
|
92
|
-
"access": "public"
|
|
93
|
-
}
|
|
94
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@bettercms-ai/next",
|
|
3
|
+
"version": "0.24.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "The BetterCMS adapter for Next.js — typed, cache-aware content reads (getEntry/listEntries), draft preview, build-time content snapshot, and llms.txt generation for the App Router. The /blocks, /form, /field, /search and /visual-editing entries are framework-free React and work in any React app (see the React+TS starter), which is why `next` is an OPTIONAL peer.",
|
|
6
|
+
"bin": {
|
|
7
|
+
"bettercms-snapshot": "./dist/bettercms-snapshot.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"module": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"sideEffects": false,
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"./form": {
|
|
20
|
+
"types": "./dist/form.d.ts",
|
|
21
|
+
"import": "./dist/form.js",
|
|
22
|
+
"default": "./dist/form.js"
|
|
23
|
+
},
|
|
24
|
+
"./search": {
|
|
25
|
+
"types": "./dist/search.d.ts",
|
|
26
|
+
"import": "./dist/search.js",
|
|
27
|
+
"default": "./dist/search.js"
|
|
28
|
+
},
|
|
29
|
+
"./blocks": {
|
|
30
|
+
"types": "./dist/blocks.d.ts",
|
|
31
|
+
"import": "./dist/blocks.js",
|
|
32
|
+
"default": "./dist/blocks.js"
|
|
33
|
+
},
|
|
34
|
+
"./live": {
|
|
35
|
+
"types": "./dist/live.d.ts",
|
|
36
|
+
"import": "./dist/live.js",
|
|
37
|
+
"default": "./dist/live.js"
|
|
38
|
+
},
|
|
39
|
+
"./visual-editing": {
|
|
40
|
+
"types": "./dist/visual-editing.d.ts",
|
|
41
|
+
"import": "./dist/visual-editing.js",
|
|
42
|
+
"default": "./dist/visual-editing.js"
|
|
43
|
+
},
|
|
44
|
+
"./draft-bridge": {
|
|
45
|
+
"types": "./dist/draft-bridge.d.ts",
|
|
46
|
+
"import": "./dist/draft-bridge.js",
|
|
47
|
+
"default": "./dist/draft-bridge.js"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"README.md"
|
|
53
|
+
],
|
|
54
|
+
"scripts": {
|
|
55
|
+
"typecheck": "tsc --noEmit",
|
|
56
|
+
"build": "tsup",
|
|
57
|
+
"test": "vitest run",
|
|
58
|
+
"test:watch": "vitest"
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"@bettercms-ai/icons": "^0.2.0",
|
|
62
|
+
"@bettercms-ai/image-url": "^0.4.0",
|
|
63
|
+
"@bettercms-ai/richtext": "^0.8.1",
|
|
64
|
+
"@bettercms-ai/sdk": "^1.29.0",
|
|
65
|
+
"@bettercms-ai/types": "^1.41.0",
|
|
66
|
+
"@bettercms-ai/ui": "^0.15.1",
|
|
67
|
+
"react-phone-number-input": "^3.4.18"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"next": ">=14",
|
|
71
|
+
"react": ">=18"
|
|
72
|
+
},
|
|
73
|
+
"peerDependenciesMeta": {
|
|
74
|
+
"next": {
|
|
75
|
+
"optional": true
|
|
76
|
+
},
|
|
77
|
+
"react": {
|
|
78
|
+
"optional": true
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
"devDependencies": {
|
|
82
|
+
"@types/node": "^20",
|
|
83
|
+
"@types/react": "^19.0.0",
|
|
84
|
+
"next": "^15.5.24",
|
|
85
|
+
"react": "^19.0.0",
|
|
86
|
+
"tsup": "^8.5.1",
|
|
87
|
+
"typescript": "^5",
|
|
88
|
+
"vitest": "^4.1.4"
|
|
89
|
+
},
|
|
90
|
+
"publishConfig": {
|
|
91
|
+
"registry": "https://registry.npmjs.org/",
|
|
92
|
+
"access": "public"
|
|
93
|
+
}
|
|
94
|
+
}
|