@nuasite/cms 0.43.0-beta.1 → 0.43.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/editor.js +2221 -2219
- package/package.json +26 -4
- package/src/admin/entry.tsx +35 -0
- package/src/admin/env.d.ts +15 -0
- package/src/admin/tsconfig.json +15 -0
- package/src/admin/tsconfig.tsbuildinfo +1 -0
- package/src/editor/components/collections-browser.tsx +4 -1
- package/src/editor/components/toolbar.tsx +20 -11
- package/src/editor/signals.ts +4 -2
- package/src/index.ts +128 -55
- package/src/local-admin.ts +316 -0
- package/src/mode.ts +53 -0
- package/src/tsconfig.json +5 -1
- package/src/types.ts +7 -0
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"directory": "packages/astro-cms"
|
|
15
15
|
},
|
|
16
16
|
"license": "Apache-2.0",
|
|
17
|
-
"version": "0.43.0-beta.
|
|
17
|
+
"version": "0.43.0-beta.3",
|
|
18
18
|
"module": "src/index.ts",
|
|
19
19
|
"types": "src/index.ts",
|
|
20
20
|
"type": "module",
|
|
@@ -26,15 +26,21 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@nuasite/cms-core": "0.43.0-beta.
|
|
30
|
-
"@nuasite/cms-types": "0.43.0-beta.
|
|
29
|
+
"@nuasite/cms-core": "0.43.0-beta.3",
|
|
30
|
+
"@nuasite/cms-types": "0.43.0-beta.3",
|
|
31
31
|
"@astrojs/compiler": "^3.0.1",
|
|
32
32
|
"@babel/parser": "^7.29.2",
|
|
33
33
|
"node-html-parser": "^7.1.0",
|
|
34
34
|
"yaml": "^2.8.3"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
+
"@nuasite/cms-sidecar": "0.43.0-beta.3",
|
|
38
|
+
"@nuasite/collections-admin": "0.43.0-beta.3",
|
|
37
39
|
"@babel/types": "^7.29.0",
|
|
40
|
+
"@types/react": "^19.2.7",
|
|
41
|
+
"@types/react-dom": "^19.2.3",
|
|
42
|
+
"react": "^19.2.1",
|
|
43
|
+
"react-dom": "^19.2.1",
|
|
38
44
|
"@milkdown/core": "^7.20.0",
|
|
39
45
|
"@milkdown/ctx": "^7.20.0",
|
|
40
46
|
"@milkdown/plugin-listener": "^7.20.0",
|
|
@@ -65,11 +71,27 @@
|
|
|
65
71
|
"astro": "6.1.4",
|
|
66
72
|
"typescript": "^6.0.2",
|
|
67
73
|
"vite": "^7.0.0",
|
|
68
|
-
"@aws-sdk/client-s3": "^3.0.0"
|
|
74
|
+
"@aws-sdk/client-s3": "^3.0.0",
|
|
75
|
+
"@nuasite/cms-sidecar": "0.43.0-beta.3",
|
|
76
|
+
"@nuasite/collections-admin": "0.43.0-beta.3",
|
|
77
|
+
"react": "^19.0.0",
|
|
78
|
+
"react-dom": "^19.0.0"
|
|
69
79
|
},
|
|
70
80
|
"peerDependenciesMeta": {
|
|
71
81
|
"@aws-sdk/client-s3": {
|
|
72
82
|
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"@nuasite/cms-sidecar": {
|
|
85
|
+
"optional": true
|
|
86
|
+
},
|
|
87
|
+
"@nuasite/collections-admin": {
|
|
88
|
+
"optional": true
|
|
89
|
+
},
|
|
90
|
+
"react": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
93
|
+
"react-dom": {
|
|
94
|
+
"optional": true
|
|
73
95
|
}
|
|
74
96
|
},
|
|
75
97
|
"scripts": {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local `/_nua/admin` SPA entry (cms-headless F7).
|
|
3
|
+
*
|
|
4
|
+
* Mounts the host-agnostic `@nuasite/collections-admin` SPA into the page served
|
|
5
|
+
* by the local-admin dev middleware. The only host-specific input is `apiBase`,
|
|
6
|
+
* which the HTML shell injects as `window.__NUA_ADMIN_API_BASE__` — it points at
|
|
7
|
+
* the in-process cms-sidecar mounted by the dev middleware (`…/cms/v1`). The same
|
|
8
|
+
* lib backs the webmaster Collections tab; only `apiBase` differs.
|
|
9
|
+
*
|
|
10
|
+
* This file is served as a virtual module through Astro's Vite dev server, so it
|
|
11
|
+
* is transformed (TSX → JS, React resolved) and HMR-capable like any app module.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { CollectionsAdminApp } from '@nuasite/collections-admin'
|
|
15
|
+
import { StrictMode } from 'react'
|
|
16
|
+
import { createRoot } from 'react-dom/client'
|
|
17
|
+
|
|
18
|
+
function readApiBase(): string {
|
|
19
|
+
const value = window.__NUA_ADMIN_API_BASE__
|
|
20
|
+
if (typeof value !== 'string' || value === '') {
|
|
21
|
+
throw new Error('[nua-cms] /_nua/admin: window.__NUA_ADMIN_API_BASE__ is not set')
|
|
22
|
+
}
|
|
23
|
+
return value
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const container = document.getElementById('nua-admin-root')
|
|
27
|
+
if (!container) {
|
|
28
|
+
throw new Error('[nua-cms] /_nua/admin: #nua-admin-root container is missing')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
createRoot(container).render(
|
|
32
|
+
<StrictMode>
|
|
33
|
+
<CollectionsAdminApp apiBase={readApiBase()} />
|
|
34
|
+
</StrictMode>,
|
|
35
|
+
)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ambient globals for the local `/_nua/admin` SPA entry (cms-headless F7).
|
|
3
|
+
*
|
|
4
|
+
* The dev middleware injects the cms-sidecar `apiBase` into the HTML shell as a
|
|
5
|
+
* window global; the entry reads it to drive `<CollectionsAdminApp apiBase={…} />`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare global {
|
|
9
|
+
interface Window {
|
|
10
|
+
/** Base URL the in-process cms-sidecar is mounted at (the SPA adds nothing else; it is already the `/cms/v1` base). */
|
|
11
|
+
__NUA_ADMIN_API_BASE__?: string
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export {}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.settings.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"composite": false,
|
|
5
|
+
"noEmit": true,
|
|
6
|
+
"emitDeclarationOnly": false,
|
|
7
|
+
"jsx": "react-jsx",
|
|
8
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
9
|
+
"types": ["react", "react-dom"]
|
|
10
|
+
},
|
|
11
|
+
"references": [
|
|
12
|
+
{ "path": "../../../collections-admin/src" },
|
|
13
|
+
{ "path": "../../../cms-types/src" }
|
|
14
|
+
]
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"fileNames":["../../../../node_modules/typescript/lib/lib.es5.d.ts","../../../../node_modules/typescript/lib/lib.es2015.d.ts","../../../../node_modules/typescript/lib/lib.es2016.d.ts","../../../../node_modules/typescript/lib/lib.es2017.d.ts","../../../../node_modules/typescript/lib/lib.es2018.d.ts","../../../../node_modules/typescript/lib/lib.es2019.d.ts","../../../../node_modules/typescript/lib/lib.es2020.d.ts","../../../../node_modules/typescript/lib/lib.es2021.d.ts","../../../../node_modules/typescript/lib/lib.es2022.d.ts","../../../../node_modules/typescript/lib/lib.es2023.d.ts","../../../../node_modules/typescript/lib/lib.es2024.d.ts","../../../../node_modules/typescript/lib/lib.es2025.d.ts","../../../../node_modules/typescript/lib/lib.esnext.d.ts","../../../../node_modules/typescript/lib/lib.dom.d.ts","../../../../node_modules/typescript/lib/lib.dom.iterable.d.ts","../../../../node_modules/typescript/lib/lib.es2015.core.d.ts","../../../../node_modules/typescript/lib/lib.es2015.collection.d.ts","../../../../node_modules/typescript/lib/lib.es2015.generator.d.ts","../../../../node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../../../node_modules/typescript/lib/lib.es2015.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../../../node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../../../node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../../../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../../../node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../../../node_modules/typescript/lib/lib.es2016.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../../../node_modules/typescript/lib/lib.es2017.date.d.ts","../../../../node_modules/typescript/lib/lib.es2017.object.d.ts","../../../../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../../../node_modules/typescript/lib/lib.es2017.string.d.ts","../../../../node_modules/typescript/lib/lib.es2017.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../../../node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../../../node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../../../node_modules/typescript/lib/lib.es2018.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2018.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../../../node_modules/typescript/lib/lib.es2019.array.d.ts","../../../../node_modules/typescript/lib/lib.es2019.object.d.ts","../../../../node_modules/typescript/lib/lib.es2019.string.d.ts","../../../../node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../../../node_modules/typescript/lib/lib.es2019.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../../../node_modules/typescript/lib/lib.es2020.date.d.ts","../../../../node_modules/typescript/lib/lib.es2020.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../../../node_modules/typescript/lib/lib.es2020.string.d.ts","../../../../node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../../../node_modules/typescript/lib/lib.es2020.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2020.number.d.ts","../../../../node_modules/typescript/lib/lib.es2021.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2021.string.d.ts","../../../../node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../../../node_modules/typescript/lib/lib.es2021.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2022.array.d.ts","../../../../node_modules/typescript/lib/lib.es2022.error.d.ts","../../../../node_modules/typescript/lib/lib.es2022.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2022.object.d.ts","../../../../node_modules/typescript/lib/lib.es2022.string.d.ts","../../../../node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../../../node_modules/typescript/lib/lib.es2023.array.d.ts","../../../../node_modules/typescript/lib/lib.es2023.collection.d.ts","../../../../node_modules/typescript/lib/lib.es2023.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts","../../../../node_modules/typescript/lib/lib.es2024.collection.d.ts","../../../../node_modules/typescript/lib/lib.es2024.object.d.ts","../../../../node_modules/typescript/lib/lib.es2024.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2024.regexp.d.ts","../../../../node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts","../../../../node_modules/typescript/lib/lib.es2024.string.d.ts","../../../../node_modules/typescript/lib/lib.es2025.collection.d.ts","../../../../node_modules/typescript/lib/lib.es2025.float16.d.ts","../../../../node_modules/typescript/lib/lib.es2025.intl.d.ts","../../../../node_modules/typescript/lib/lib.es2025.iterator.d.ts","../../../../node_modules/typescript/lib/lib.es2025.promise.d.ts","../../../../node_modules/typescript/lib/lib.es2025.regexp.d.ts","../../../../node_modules/typescript/lib/lib.esnext.array.d.ts","../../../../node_modules/typescript/lib/lib.esnext.collection.d.ts","../../../../node_modules/typescript/lib/lib.esnext.date.d.ts","../../../../node_modules/typescript/lib/lib.esnext.decorators.d.ts","../../../../node_modules/typescript/lib/lib.esnext.disposable.d.ts","../../../../node_modules/typescript/lib/lib.esnext.error.d.ts","../../../../node_modules/typescript/lib/lib.esnext.intl.d.ts","../../../../node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts","../../../../node_modules/typescript/lib/lib.esnext.temporal.d.ts","../../../../node_modules/typescript/lib/lib.esnext.typedarrays.d.ts","../../../../node_modules/typescript/lib/lib.decorators.d.ts","../../../../node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../../../node_modules/@types/react/global.d.ts","../../../../node_modules/csstype/index.d.ts","../../../../node_modules/@types/react/index.d.ts","../../../../node_modules/@types/react/jsx-runtime.d.ts","../../../collections-admin/dist/types/app.d.ts","../../../cms-types/dist/types/index.d.ts","../../../collections-admin/dist/types/client.d.ts","../../../collections-admin/dist/types/form-model.d.ts","../../../collections-admin/dist/types/index.d.ts","../../../../node_modules/@types/react-dom/client.d.ts","./entry.tsx","./env.d.ts","../../../../node_modules/@types/react-dom/index.d.ts"],"fileIdsList":[[92],[90,91],[92,93,98,99],[95],[94,95,96,97]],"fileInfos":[{"version":"bcd24271a113971ba9eb71ff8cb01bc6b0f872a85c23fdbe5d93065b375933cd","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f88bedbeb09c6f5a6645cb24c7c55f1aa22d19ae96c8e6959cbd8b85a707bc6","impliedFormat":1},{"version":"7fe93b39b810eadd916be8db880dd7f0f7012a5cc6ffb62de8f62a2117fa6f1f","impliedFormat":1},{"version":"bb0074cc08b84a2374af33d8bf044b80851ccc9e719a5e202eacf40db2c31600","impliedFormat":1},{"version":"1a7daebe4f45fb03d9ec53d60008fbf9ac45a697fdc89e4ce218bc94b94f94d6","impliedFormat":1},{"version":"f94b133a3cb14a288803be545ac2683e0d0ff6661bcd37e31aaaec54fc382aed","impliedFormat":1},{"version":"f59d0650799f8782fd74cf73c19223730c6d1b9198671b1c5b3a38e1188b5953","impliedFormat":1},{"version":"8a15b4607d9a499e2dbeed9ec0d3c0d7372c850b2d5f1fb259e8f6d41d468a84","impliedFormat":1},{"version":"26e0fe14baee4e127f4365d1ae0b276f400562e45e19e35fd2d4c296684715e6","impliedFormat":1},{"version":"1e9332c23e9a907175e0ffc6a49e236f97b48838cc8aec9ce7e4cec21e544b65","impliedFormat":1},{"version":"3753fbc1113dc511214802a2342280a8b284ab9094f6420e7aa171e868679f91","impliedFormat":1},{"version":"999ca32883495a866aa5737fe1babc764a469e4cde6ee6b136a4b9ae68853e4b","impliedFormat":1},{"version":"17f13ecb98cbc39243f2eee1f16d45cd8ec4706b03ee314f1915f1a8b42f6984","impliedFormat":1},{"version":"d6b1eba8496bdd0eed6fc8a685768fe01b2da4a0388b5fe7df558290bffcf32f","affectsGlobalScope":true,"impliedFormat":1},{"version":"7f57fc4404ff020bc45b9c620aff2b40f700b95fe31164024c453a5e3c163c54","impliedFormat":1},{"version":"eadcffda2aa84802c73938e589b9e58248d74c59cb7fcbca6474e3435ac15504","affectsGlobalScope":true,"impliedFormat":1},{"version":"105ba8ff7ba746404fe1a2e189d1d3d2e0eb29a08c18dded791af02f29fb4711","affectsGlobalScope":true,"impliedFormat":1},{"version":"00343ca5b2e3d48fa5df1db6e32ea2a59afab09590274a6cccb1dbae82e60c7c","affectsGlobalScope":true,"impliedFormat":1},{"version":"ebd9f816d4002697cb2864bea1f0b70a103124e18a8cd9645eeccc09bdf80ab4","affectsGlobalScope":true,"impliedFormat":1},{"version":"2c1afac30a01772cd2a9a298a7ce7706b5892e447bb46bdbeef720f7b5da77ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"7b0225f483e4fa685625ebe43dd584bb7973bbd84e66a6ba7bbe175ee1048b4f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c0a4b8ac6ce74679c1da2b3795296f5896e31c38e888469a8e0f99dc3305de60","affectsGlobalScope":true,"impliedFormat":1},{"version":"3084a7b5f569088e0146533a00830e206565de65cae2239509168b11434cd84f","affectsGlobalScope":true,"impliedFormat":1},{"version":"c5079c53f0f141a0698faa903e76cb41cd664e3efb01cc17a5c46ec2eb0bef42","affectsGlobalScope":true,"impliedFormat":1},{"version":"32cafbc484dea6b0ab62cf8473182bbcb23020d70845b406f80b7526f38ae862","affectsGlobalScope":true,"impliedFormat":1},{"version":"fca4cdcb6d6c5ef18a869003d02c9f0fd95df8cfaf6eb431cd3376bc034cad36","affectsGlobalScope":true,"impliedFormat":1},{"version":"b93ec88115de9a9dc1b602291b85baf825c85666bf25985cc5f698073892b467","affectsGlobalScope":true,"impliedFormat":1},{"version":"f5c06dcc3fe849fcb297c247865a161f995cc29de7aa823afdd75aaaddc1419b","affectsGlobalScope":true,"impliedFormat":1},{"version":"b77e16112127a4b169ef0b8c3a4d730edf459c5f25fe52d5e436a6919206c4d7","affectsGlobalScope":true,"impliedFormat":1},{"version":"fbffd9337146eff822c7c00acbb78b01ea7ea23987f6c961eba689349e744f8c","affectsGlobalScope":true,"impliedFormat":1},{"version":"a995c0e49b721312f74fdfb89e4ba29bd9824c770bbb4021d74d2bf560e4c6bd","affectsGlobalScope":true,"impliedFormat":1},{"version":"c7b3542146734342e440a84b213384bfa188835537ddbda50d30766f0593aff9","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce6180fa19b1cccd07ee7f7dbb9a367ac19c0ed160573e4686425060b6df7f57","affectsGlobalScope":true,"impliedFormat":1},{"version":"3f02e2476bccb9dbe21280d6090f0df17d2f66b74711489415a8aa4df73c9675","affectsGlobalScope":true,"impliedFormat":1},{"version":"45e3ab34c1c013c8ab2dc1ba4c80c780744b13b5676800ae2e3be27ae862c40c","affectsGlobalScope":true,"impliedFormat":1},{"version":"805c86f6cca8d7702a62a844856dbaa2a3fd2abef0536e65d48732441dde5b5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"e42e397f1a5a77994f0185fd1466520691456c772d06bf843e5084ceb879a0ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"f4c2b41f90c95b1c532ecc874bd3c111865793b23aebcc1c3cbbabcd5d76ffb0","affectsGlobalScope":true,"impliedFormat":1},{"version":"ab26191cfad5b66afa11b8bf935ef1cd88fabfcb28d30b2dfa6fad877d050332","affectsGlobalScope":true,"impliedFormat":1},{"version":"2088bc26531e38fb05eedac2951480db5309f6be3fa4a08d2221abb0f5b4200d","affectsGlobalScope":true,"impliedFormat":1},{"version":"cb9d366c425fea79716a8fb3af0d78e6b22ebbab3bd64d25063b42dc9f531c1e","affectsGlobalScope":true,"impliedFormat":1},{"version":"500934a8089c26d57ebdb688fc9757389bb6207a3c8f0674d68efa900d2abb34","affectsGlobalScope":true,"impliedFormat":1},{"version":"689da16f46e647cef0d64b0def88910e818a5877ca5379ede156ca3afb780ac3","affectsGlobalScope":true,"impliedFormat":1},{"version":"bc21cc8b6fee4f4c2440d08035b7ea3c06b3511314c8bab6bef7a92de58a2593","affectsGlobalScope":true,"impliedFormat":1},{"version":"7ca53d13d2957003abb47922a71866ba7cb2068f8d154877c596d63c359fed25","affectsGlobalScope":true,"impliedFormat":1},{"version":"54725f8c4df3d900cb4dac84b64689ce29548da0b4e9b7c2de61d41c79293611","affectsGlobalScope":true,"impliedFormat":1},{"version":"e5594bc3076ac29e6c1ebda77939bc4c8833de72f654b6e376862c0473199323","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f3eb332c2d73e729f3364fcc0c2b375e72a121e8157d25a82d67a138c83a95c","affectsGlobalScope":true,"impliedFormat":1},{"version":"6f4427f9642ce8d500970e4e69d1397f64072ab73b97e476b4002a646ac743b1","affectsGlobalScope":true,"impliedFormat":1},{"version":"48915f327cd1dea4d7bd358d9dc7732f58f9e1626a29cc0c05c8c692419d9bb7","affectsGlobalScope":true,"impliedFormat":1},{"version":"b7bf9377723203b5a6a4b920164df22d56a43f593269ba6ae1fdc97774b68855","affectsGlobalScope":true,"impliedFormat":1},{"version":"db9709688f82c9e5f65a119c64d835f906efe5f559d08b11642d56eb85b79357","affectsGlobalScope":true,"impliedFormat":1},{"version":"4b25b8c874acd1a4cf8444c3617e037d444d19080ac9f634b405583fd10ce1f7","affectsGlobalScope":true,"impliedFormat":1},{"version":"37be57d7c90cf1f8112ee2636a068d8fd181289f82b744160ec56a7dc158a9f5","affectsGlobalScope":true,"impliedFormat":1},{"version":"a917a49ac94cd26b754ab84e113369a75d1a47a710661d7cd25e961cc797065f","affectsGlobalScope":true,"impliedFormat":1},{"version":"6d3261badeb7843d157ef3e6f5d1427d0eeb0af0cf9df84a62cfd29fd47ac86e","affectsGlobalScope":true,"impliedFormat":1},{"version":"195daca651dde22f2167ac0d0a05e215308119a3100f5e6268e8317d05a92526","affectsGlobalScope":true,"impliedFormat":1},{"version":"8b11e4285cd2bb164a4dc09248bdec69e9842517db4ca47c1ba913011e44ff2f","affectsGlobalScope":true,"impliedFormat":1},{"version":"0508571a52475e245b02bc50fa1394065a0a3d05277fbf5120c3784b85651799","affectsGlobalScope":true,"impliedFormat":1},{"version":"8f9af488f510c3015af3cc8c267a9e9d96c4dd38a1fdff0e11dc5a544711415b","affectsGlobalScope":true,"impliedFormat":1},{"version":"fc611fea8d30ea72c6bbfb599c9b4d393ce22e2f5bfef2172534781e7d138104","affectsGlobalScope":true,"impliedFormat":1},{"version":"0bd714129fca875f7d4c477a1a392200b0bcd13fb2e80928cd334b63830ea047","affectsGlobalScope":true,"impliedFormat":1},{"version":"e2c9037ae6cd2c52d80ceef0b3c5ffdb488627d71529cf4f63776daf11161c9a","affectsGlobalScope":true,"impliedFormat":1},{"version":"135d5cf4d345f59f1a9caadfafcd858d3d9cc68290db616cc85797224448cccc","affectsGlobalScope":true,"impliedFormat":1},{"version":"bc238c3f81c2984751932b6aab223cd5b830e0ac6cad76389e5e9d2ffc03287d","affectsGlobalScope":true,"impliedFormat":1},{"version":"4a07f9b76d361f572620927e5735b77d6d2101c23cdd94383eb5b706e7b36357","affectsGlobalScope":true,"impliedFormat":1},{"version":"7c4e8dc6ab834cc6baa0227e030606d29e3e8449a9f67cdf5605ea5493c4db29","affectsGlobalScope":true,"impliedFormat":1},{"version":"de7ba0fd02e06cd9a5bd4ab441ed0e122735786e67dde1e849cced1cd8b46b78","affectsGlobalScope":true,"impliedFormat":1},{"version":"6148e4e88d720a06855071c3db02069434142a8332cf9c182cda551adedf3156","affectsGlobalScope":true,"impliedFormat":1},{"version":"d63dba625b108316a40c95a4425f8d4294e0deeccfd6c7e59d819efa19e23409","affectsGlobalScope":true,"impliedFormat":1},{"version":"0568d6befee03dd435bed4fc25c4e46865b24bdcb8c563fdc21f580a2c301904","affectsGlobalScope":true,"impliedFormat":1},{"version":"30d62269b05b584741f19a5369852d5d34895aa2ac4fd948956f886d15f9cc0d","affectsGlobalScope":true,"impliedFormat":1},{"version":"f128dae7c44d8f35ee42e0a437000a57c9f06cc04f8b4fb42eebf44954d53dc8","affectsGlobalScope":true,"impliedFormat":1},{"version":"ffbe6d7b295306b2ba88030f65b74c107d8d99bdcf596ea99c62a02f606108b0","affectsGlobalScope":true,"impliedFormat":1},{"version":"996fb27b15277369c68a4ba46ed138b4e9e839a02fb4ec756f7997629242fd9f","affectsGlobalScope":true,"impliedFormat":1},{"version":"79b712591b270d4778c89706ca2cfc56ddb8c3f895840e477388f1710dc5eda9","affectsGlobalScope":true,"impliedFormat":1},{"version":"20884846cef428b992b9bd032e70a4ef88e349263f63aeddf04dda837a7dba26","affectsGlobalScope":true,"impliedFormat":1},{"version":"5fcab789c73a97cd43828ee3cc94a61264cf24d4c44472ce64ced0e0f148bdb2","affectsGlobalScope":true,"impliedFormat":1},{"version":"db59a81f070c1880ad645b2c0275022baa6a0c4f0acdc58d29d349c6efcf0903","affectsGlobalScope":true,"impliedFormat":1},{"version":"673294292640f5722b700e7d814e17aaf7d93f83a48a2c9b38f33cbc940ad8b0","affectsGlobalScope":true,"impliedFormat":1},{"version":"d786b48f934cbca483b3c6d0a798cb43bbb4ada283e76fb22c28e53ae05b9e69","affectsGlobalScope":true,"impliedFormat":1},{"version":"1ecb8e347cb6b2a8927c09b86263663289418df375f5e68e11a0ae683776978f","affectsGlobalScope":true,"impliedFormat":1},{"version":"142efd4ce210576f777dc34df121777be89eda476942d6d6663b03dcb53be3ff","affectsGlobalScope":true,"impliedFormat":1},{"version":"379bc41580c2d774f82e828c70308f24a005b490c25ba34d679d84bcf05c3d9d","affectsGlobalScope":true,"impliedFormat":1},{"version":"ed484fb2aa8a1a23d0277056ec3336e0a0b52f9b8d6a961f338a642faf43235d","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ffedae1d1c2d53fdbca1c96d3c7dda544281f7d262f99b6880634f8fd8d9820","affectsGlobalScope":true,"impliedFormat":1},{"version":"83a730b125d477dd264df8ba479afab27a3dae7152b005c214ab94dc7ee44fd3","affectsGlobalScope":true,"impliedFormat":1},{"version":"1ce14b81c5cc821994aa8ec1d42b220dd41b27fcc06373bce3958af7421b77d4","affectsGlobalScope":true,"impliedFormat":1},{"version":"b3a048b3e9302ef9a34ef4ebb9aecfb28b66abb3bce577206a79fee559c230da","affectsGlobalScope":true,"impliedFormat":1},{"version":"7e29f41b158de217f94cb9676bf9cbd0cd9b5a46e1985141ed36e075c52bf6ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"2577e7e800bdece2956ca027cb5c17aa359abd968eb9355760110c853f4fb9da","impliedFormat":1},{"version":"b838d4c72740eb0afd284bf7575b74c624b105eff2e8c7b4aeead57e7ac320ff","impliedFormat":1},"af732cf34bfa338fff320258775aa469d8bc3e0f25b5c82e231046ae5dccabf7","c43c2a0107a2a099fe50bcc754e90b50aa6b265ce57e464a2489798b38e4dc53","18be101c2011a0c364fc7e5ee231d6a9397808e9a095b4bb25c171adf4f23ff5","35ac5e9e25a23b55393daa079c3e7b85817598eed090c2b6b92d156fbde16c6b","d1a6a20b9ba01e597090d73d614ea6e39dc0a5424261f6980280f189c05b36b1",{"version":"bc03c3c352f689e38c0ddd50c39b1e65d59273991bfc8858a9e3c0ebb79c023b","impliedFormat":1},"3044ee76859e5dae484bafae0e31525f2a3378d41a3b24c495b2e8e7b690e52c",{"version":"55793e486e9c2ad120621fcba96981896ee79991dbfe795758e6e77e75d0df54","affectsGlobalScope":true},{"version":"be1cc4d94ea60cbe567bc29ed479d42587bf1e6cba490f123d329976b0fe4ee5","impliedFormat":1}],"root":[100,101],"options":{"allowImportingTsExtensions":true,"allowJs":true,"composite":false,"declaration":true,"declarationMap":true,"emitDeclarationOnly":false,"jsx":4,"module":200,"noEmitOnError":true,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":false,"noUncheckedIndexedAccess":true,"noUnusedLocals":false,"noUnusedParameters":false,"skipLibCheck":true,"strict":true,"target":99,"verbatimModuleSyntax":true},"referencedMap":[[99,1],[102,1],[92,2],[93,1],[100,3],[94,1],[96,4],[97,4],[98,5]],"affectedFilesPendingEmit":[[100,49]],"version":"6.0.2"}
|
|
@@ -22,7 +22,10 @@ const confirmDeleteSlug = signal<string | null>(null)
|
|
|
22
22
|
const EMPTY_ENTRIES: never[] = []
|
|
23
23
|
|
|
24
24
|
export function CollectionsBrowser() {
|
|
25
|
-
|
|
25
|
+
// Collection management (browse/list/open entries) can be owned by the host
|
|
26
|
+
// app; when disabled, the in-preview browser is hidden entirely.
|
|
27
|
+
const collectionManagementEnabled = config.value.features?.collectionManagement !== false
|
|
28
|
+
const visible = collectionManagementEnabled && isCollectionsBrowserOpen.value
|
|
26
29
|
const selected = selectedBrowserCollection.value
|
|
27
30
|
|
|
28
31
|
const collectionDefinitions = manifest.value.collectionDefinitions ?? {}
|
|
@@ -95,6 +95,11 @@ export const Toolbar = ({ callbacks, collectionDefinitions }: ToolbarProps) => {
|
|
|
95
95
|
})
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
// When collection management is disabled (e.g. it lives in the host app's
|
|
99
|
+
// Collections tab), hide the in-preview collection browser entry points.
|
|
100
|
+
// Inline editing of the current page's content ("Edit Content") is kept.
|
|
101
|
+
const collectionManagementEnabled = signals.config.value.features?.collectionManagement !== false
|
|
102
|
+
|
|
98
103
|
if (collectionDefinitions) {
|
|
99
104
|
const entries = Object.entries(collectionDefinitions)
|
|
100
105
|
if (entries.length > 0) {
|
|
@@ -111,12 +116,14 @@ export const Toolbar = ({ callbacks, collectionDefinitions }: ToolbarProps) => {
|
|
|
111
116
|
ordered.push([name, def, false])
|
|
112
117
|
}
|
|
113
118
|
|
|
114
|
-
const contentItems: MenuItem[] =
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
const contentItems: MenuItem[] = collectionManagementEnabled
|
|
120
|
+
? ordered.map(([name, def, indented]) => ({
|
|
121
|
+
label: def.label,
|
|
122
|
+
icon: <GridIcon />,
|
|
123
|
+
indented,
|
|
124
|
+
onClick: () => callbacks.onOpenCollection?.(name),
|
|
125
|
+
}))
|
|
126
|
+
: []
|
|
120
127
|
|
|
121
128
|
if (currentPageCollection && callbacks.onEditContent) {
|
|
122
129
|
contentItems.unshift({
|
|
@@ -134,11 +141,13 @@ export const Toolbar = ({ callbacks, collectionDefinitions }: ToolbarProps) => {
|
|
|
134
141
|
})
|
|
135
142
|
}
|
|
136
143
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
if (contentItems.length > 0) {
|
|
145
|
+
menuSections.push({
|
|
146
|
+
label: 'Content',
|
|
147
|
+
icon: <GridIcon />,
|
|
148
|
+
items: contentItems,
|
|
149
|
+
})
|
|
150
|
+
}
|
|
142
151
|
}
|
|
143
152
|
}
|
|
144
153
|
|
package/src/editor/signals.ts
CHANGED
|
@@ -1470,8 +1470,10 @@ export function setConfig(newConfig: CmsConfig): void {
|
|
|
1470
1470
|
|
|
1471
1471
|
export function setFeatures(features: CmsConfig['features']): void {
|
|
1472
1472
|
const current = config.value.features
|
|
1473
|
-
|
|
1474
|
-
|
|
1473
|
+
const next = { ...current, ...features }
|
|
1474
|
+
// Bail out when nothing actually changes, to avoid re-triggering effects.
|
|
1475
|
+
if (current?.selectElement === next.selectElement && current?.collectionManagement === next.collectionManagement) return
|
|
1476
|
+
config.value = { ...config.value, features: next }
|
|
1475
1477
|
}
|
|
1476
1478
|
|
|
1477
1479
|
// ============================================================================
|
package/src/index.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AstroIntegration } from 'astro'
|
|
2
|
-
import { existsSync
|
|
2
|
+
import { existsSync } from 'node:fs'
|
|
3
3
|
import fs from 'node:fs/promises'
|
|
4
4
|
import { dirname, join } from 'node:path'
|
|
5
5
|
import { fileURLToPath } from 'node:url'
|
|
@@ -11,8 +11,10 @@ import { ComponentRegistry } from './component-registry'
|
|
|
11
11
|
import { resetProjectRoot } from './config'
|
|
12
12
|
import { createDevMiddleware } from './dev-middleware'
|
|
13
13
|
import { getErrorCollector, resetErrorCollector } from './error-collector'
|
|
14
|
+
import { ADMIN_ROUTE, createLocalAdminMiddleware } from './local-admin'
|
|
14
15
|
import { ManifestWriter } from './manifest-writer'
|
|
15
16
|
import type { MediaStorageAdapter } from './media/types'
|
|
17
|
+
import { type CmsMode, resolveCmsMode } from './mode'
|
|
16
18
|
import { rehypeCmsMarker } from './rehype-cms-marker'
|
|
17
19
|
import type { CmsFeatures, CmsMarkerOptions, ComponentDefinition } from './types'
|
|
18
20
|
import { createPublicStaticFileChecker } from './utils'
|
|
@@ -20,8 +22,18 @@ import { createVitePlugin } from './vite-plugin'
|
|
|
20
22
|
|
|
21
23
|
export interface NuaCmsOptions extends CmsMarkerOptions {
|
|
22
24
|
/**
|
|
23
|
-
* URL to the CMS editor script.
|
|
24
|
-
*
|
|
25
|
+
* URL to the CMS editor (inline visual-editing widget) script.
|
|
26
|
+
*
|
|
27
|
+
* Resolution order in dev:
|
|
28
|
+
* 1. this `src`, if set;
|
|
29
|
+
* 2. the `NUA_CMS_EDITOR_SRC` environment variable (lets the host runtime point
|
|
30
|
+
* dev-preview at a specific CDN/local editor without a config change);
|
|
31
|
+
* 3. the public CDN editor (`DEFAULT_CDN_EDITOR_SRC`) when a pre-built editor
|
|
32
|
+
* bundle ships with the package (the npm-installed case — e.g. a generated
|
|
33
|
+
* site's dev-preview), so the inline editor updates via a CDN push,
|
|
34
|
+
* independent of the site's `@nuasite/cms` version (matching hosting);
|
|
35
|
+
* 4. the bundled editor served from the dev server, used only in the monorepo
|
|
36
|
+
* (no pre-built bundle) so editor source changes hot-reload.
|
|
25
37
|
*/
|
|
26
38
|
src?: string
|
|
27
39
|
/**
|
|
@@ -44,6 +56,22 @@ export interface NuaCmsOptions extends CmsMarkerOptions {
|
|
|
44
56
|
*/
|
|
45
57
|
siteTheme?: 'auto' | 'light' | 'dark'
|
|
46
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Run mode (cms-headless F7). Controls whether the plugin serves a local
|
|
61
|
+
* full-page collections admin:
|
|
62
|
+
*
|
|
63
|
+
* - `local` (default for `pletivo dev` on a developer machine): lazily spawn an
|
|
64
|
+
* in-process cms-sidecar over the project's `node:fs` and serve the
|
|
65
|
+
* `@nuasite/collections-admin` SPA at `/_nua/admin`. The inline widget runs
|
|
66
|
+
* in-page as usual.
|
|
67
|
+
* - `hosted` (inside the agent sandbox): a no-op for spawning/serving — the
|
|
68
|
+
* sidecar is a managed sandbox service and the admin is the webmaster tab.
|
|
69
|
+
* The plugin stays marker + CDN-inject only.
|
|
70
|
+
*
|
|
71
|
+
* Auto-detected from the environment when omitted (a sandbox env signal ⇒
|
|
72
|
+
* `hosted`; otherwise `local`). An explicit value always wins.
|
|
73
|
+
*/
|
|
74
|
+
mode?: CmsMode
|
|
47
75
|
/**
|
|
48
76
|
* Proxy /_nua/cms requests to this target URL during dev.
|
|
49
77
|
* Example: 'http://localhost:8787'
|
|
@@ -88,6 +116,20 @@ const DEFAULT_MAX_UPLOAD_SIZE = 10 * 1024 * 1024
|
|
|
88
116
|
|
|
89
117
|
const VIRTUAL_CMS_PATH = '/@nuasite/cms-editor.js'
|
|
90
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Virtual module id of the local `/_nua/admin` SPA entry (cms-headless F7). The
|
|
121
|
+
* HTML shell loads it as `<script type="module">`; the Vite plugin resolves it to
|
|
122
|
+
* `src/admin/entry.tsx` so the dev server transforms it (TSX → JS, real React).
|
|
123
|
+
*/
|
|
124
|
+
const VIRTUAL_ADMIN_ENTRY = '/@nuasite/cms-admin-entry.js'
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Public CDN editor script. Same URL hosting injects (see webmaster
|
|
128
|
+
* `packages/worker-hosting` `editorSrc`), so dev-preview and hosting load the
|
|
129
|
+
* identical inline editor and a CDN push updates both without touching the site.
|
|
130
|
+
*/
|
|
131
|
+
const DEFAULT_CDN_EDITOR_SRC = 'https://cdn.nuasite.com/script/latest/cms-editor.js'
|
|
132
|
+
|
|
91
133
|
export default function nuaCms(options: NuaCmsOptions = {}): AstroIntegration {
|
|
92
134
|
const {
|
|
93
135
|
// CMS editor options
|
|
@@ -111,6 +153,13 @@ export default function nuaCms(options: NuaCmsOptions = {}): AstroIntegration {
|
|
|
111
153
|
maxUploadSize = DEFAULT_MAX_UPLOAD_SIZE,
|
|
112
154
|
} = options
|
|
113
155
|
|
|
156
|
+
// Run mode (cms-headless F7): `local` serves a full-page collections admin at
|
|
157
|
+
// /_nua/admin over an in-process sidecar; `hosted` (inside the agent sandbox)
|
|
158
|
+
// is a no-op for that — the managed sandbox sidecar + the webmaster tab own it.
|
|
159
|
+
// An explicit `options.mode` wins; otherwise auto-detect from the environment.
|
|
160
|
+
const mode = resolveCmsMode(options.mode)
|
|
161
|
+
const serveLocalAdmin = mode === 'local'
|
|
162
|
+
|
|
114
163
|
// When no proxy, enable local CMS API with default media adapter
|
|
115
164
|
const enableCmsApi = !proxy
|
|
116
165
|
const mediaAdapter = media ?? (enableCmsApi ? createLocalStorageAdapter() : undefined)
|
|
@@ -218,15 +267,41 @@ export default function nuaCms(options: NuaCmsOptions = {}): AstroIntegration {
|
|
|
218
267
|
}
|
|
219
268
|
|
|
220
269
|
const vitePlugins: any[] = [...(createVitePlugin(pluginContext) as any)]
|
|
221
|
-
const cmsDir =
|
|
270
|
+
const cmsDir = dirname(fileURLToPath(import.meta.url))
|
|
271
|
+
|
|
272
|
+
// Local-mode (cms-headless F7): resolve the /_nua/admin SPA entry virtual
|
|
273
|
+
// module to src/admin/entry.tsx so Vite transforms it (TSX → JS, real
|
|
274
|
+
// React) and HMR works. The HTML shell loads this id as a module script.
|
|
275
|
+
if (serveLocalAdmin) {
|
|
276
|
+
vitePlugins.push({
|
|
277
|
+
name: 'nuasite-cms-admin-entry',
|
|
278
|
+
resolveId(id: string) {
|
|
279
|
+
if (id === VIRTUAL_ADMIN_ENTRY) {
|
|
280
|
+
return join(cmsDir, 'admin/entry.tsx')
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
})
|
|
284
|
+
}
|
|
222
285
|
|
|
223
286
|
// Detect pre-built editor bundle (present when installed from npm)
|
|
224
|
-
const editorBundlePath =
|
|
225
|
-
const hasPrebuiltBundle =
|
|
287
|
+
const editorBundlePath = join(cmsDir, '../dist/editor.js')
|
|
288
|
+
const hasPrebuiltBundle = existsSync(editorBundlePath)
|
|
289
|
+
|
|
290
|
+
// Resolve which editor script dev-preview injects:
|
|
291
|
+
// 1. explicit `src`; 2. `NUA_CMS_EDITOR_SRC` env; 3. the public CDN editor
|
|
292
|
+
// when shipping a pre-built bundle (npm-installed site) — so dev-preview
|
|
293
|
+
// loads the same CDN editor as hosting and a CDN push updates it without a
|
|
294
|
+
// site rebuild; 4. the bundled source (monorepo only) for editor HMR.
|
|
295
|
+
const envSrc = process.env.NUA_CMS_EDITOR_SRC
|
|
296
|
+
const resolvedEditorSrc = src ?? envSrc ?? (hasPrebuiltBundle ? DEFAULT_CDN_EDITOR_SRC : VIRTUAL_CMS_PATH)
|
|
297
|
+
|
|
298
|
+
// Local virtual-module serving is only needed when injecting the bundled
|
|
299
|
+
// editor (the monorepo source path) — not for an external/CDN URL.
|
|
300
|
+
const servesBundledEditor = resolvedEditorSrc === VIRTUAL_CMS_PATH
|
|
226
301
|
|
|
227
302
|
// --- CMS Editor setup (dev only) ---
|
|
228
303
|
if (command === 'dev') {
|
|
229
|
-
const editorSrc =
|
|
304
|
+
const editorSrc = resolvedEditorSrc
|
|
230
305
|
|
|
231
306
|
const configScript = `window.NuaCmsConfig = ${JSON.stringify(resolvedCmsConfig)};`
|
|
232
307
|
|
|
@@ -248,52 +323,32 @@ export default function nuaCms(options: NuaCmsOptions = {}): AstroIntegration {
|
|
|
248
323
|
`,
|
|
249
324
|
)
|
|
250
325
|
|
|
251
|
-
if (
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return join(cmsDir!, 'editor/index.tsx')
|
|
278
|
-
}
|
|
279
|
-
},
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
// Prepend @jsxImportSource pragma for editor .tsx files
|
|
283
|
-
// so Vite's esbuild uses Preact's h function
|
|
284
|
-
vitePlugins.push({
|
|
285
|
-
name: 'nuasite-cms-preact-jsx',
|
|
286
|
-
transform(code: string, id: string) {
|
|
287
|
-
if (id.includes('/src/editor/') && id.endsWith('.tsx') && !code.includes('@jsxImportSource')) {
|
|
288
|
-
return `/** @jsxImportSource preact */\n${code}`
|
|
289
|
-
}
|
|
290
|
-
},
|
|
291
|
-
})
|
|
292
|
-
|
|
293
|
-
// Add Tailwind CSS Vite plugin for editor styles
|
|
294
|
-
const tailwindcss = (await import('@tailwindcss/vite')).default
|
|
295
|
-
vitePlugins.push(tailwindcss())
|
|
296
|
-
}
|
|
326
|
+
if (servesBundledEditor) {
|
|
327
|
+
// Monorepo dev (no pre-built bundle): serve the editor source files
|
|
328
|
+
// directly so Vite transforms TSX, resolves imports, and HMR works.
|
|
329
|
+
vitePlugins.push({
|
|
330
|
+
name: 'nuasite-cms-editor',
|
|
331
|
+
resolveId(id: string) {
|
|
332
|
+
if (id === VIRTUAL_CMS_PATH) {
|
|
333
|
+
return join(cmsDir, 'editor/index.tsx')
|
|
334
|
+
}
|
|
335
|
+
},
|
|
336
|
+
})
|
|
337
|
+
|
|
338
|
+
// Prepend @jsxImportSource pragma for editor .tsx files
|
|
339
|
+
// so Vite's esbuild uses Preact's h function
|
|
340
|
+
vitePlugins.push({
|
|
341
|
+
name: 'nuasite-cms-preact-jsx',
|
|
342
|
+
transform(code: string, id: string) {
|
|
343
|
+
if (id.includes('/src/editor/') && id.endsWith('.tsx') && !code.includes('@jsxImportSource')) {
|
|
344
|
+
return `/** @jsxImportSource preact */\n${code}`
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
})
|
|
348
|
+
|
|
349
|
+
// Add Tailwind CSS Vite plugin for editor styles
|
|
350
|
+
const tailwindcss = (await import('@tailwindcss/vite')).default
|
|
351
|
+
vitePlugins.push(tailwindcss())
|
|
297
352
|
}
|
|
298
353
|
}
|
|
299
354
|
|
|
@@ -306,8 +361,9 @@ export default function nuaCms(options: NuaCmsOptions = {}): AstroIntegration {
|
|
|
306
361
|
}
|
|
307
362
|
}
|
|
308
363
|
|
|
309
|
-
// Only add react->preact aliases when serving source files
|
|
310
|
-
|
|
364
|
+
// Only add react->preact aliases when serving the editor source files
|
|
365
|
+
// (monorepo dev) — an external/CDN editor URL needs no module rewriting.
|
|
366
|
+
const needsAliases = servesBundledEditor
|
|
311
367
|
|
|
312
368
|
updateConfig({
|
|
313
369
|
markdown: {
|
|
@@ -349,6 +405,22 @@ export default function nuaCms(options: NuaCmsOptions = {}): AstroIntegration {
|
|
|
349
405
|
if (enableCmsApi) {
|
|
350
406
|
logger.info('CMS API enabled at /_nua/cms/')
|
|
351
407
|
}
|
|
408
|
+
|
|
409
|
+
// Local-mode full-page collections admin (cms-headless F7). Registered
|
|
410
|
+
// only in `local` mode — in `hosted` (sandbox) this is a strict no-op:
|
|
411
|
+
// the managed sandbox sidecar (F2) + the webmaster tab (F3) own it.
|
|
412
|
+
// The in-process sidecar + SPA are built lazily on the first /_nua/admin
|
|
413
|
+
// hit, so dev startup stays fast. Media defaults to local public/uploads.
|
|
414
|
+
if (serveLocalAdmin) {
|
|
415
|
+
createLocalAdminMiddleware(server, {
|
|
416
|
+
contentDir,
|
|
417
|
+
componentDirs,
|
|
418
|
+
mediaAdapter: media ?? createLocalStorageAdapter(),
|
|
419
|
+
maxUploadSize,
|
|
420
|
+
entryModuleId: VIRTUAL_ADMIN_ENTRY,
|
|
421
|
+
})
|
|
422
|
+
logger.info(`CMS collections admin available at ${ADMIN_ROUTE}`)
|
|
423
|
+
}
|
|
352
424
|
},
|
|
353
425
|
|
|
354
426
|
'astro:build:done': async ({ dir, logger }) => {
|
|
@@ -402,6 +474,7 @@ export { FIELD_TYPES, isFieldType } from '@nuasite/cms-types'
|
|
|
402
474
|
export { n } from './field-types'
|
|
403
475
|
export type { DateHints, ImageHints, NumberHints, TextareaHints, TextHints } from './field-types'
|
|
404
476
|
export type { MediaFolderItem, MediaItem, MediaListOptions, MediaListResult, MediaStorageAdapter, MediaTypeFilter } from './media/types'
|
|
477
|
+
export { type CmsMode, detectHostedFromEnv, resolveCmsMode } from './mode'
|
|
405
478
|
export type { Color, Date, DateTime, Email, Image, Reference, Textarea, Time, Url } from './prop-types'
|
|
406
479
|
|
|
407
480
|
export { scanCollections } from './collection-scanner'
|