@nuasite/collections-admin 0.43.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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","../../../cms-types/dist/types/index.d.ts","../../src/client.ts","../../src/field-view.tsx","../../src/app.tsx","../../src/css.d.ts","../../src/index.ts"],"fileIdsList":[[90,91],[92],[92,93,94,95,96,98],[93,94],[93,94,95,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},"c43c2a0107a2a099fe50bcc754e90b50aa6b265ce57e464a2489798b38e4dc53",{"version":"cae82386b5fba54f17a7396bbba0de750fd09b5b7d0f08039cb7538d2b9886e2","signature":"272f4c7faec64979122122d98606088555fe082d32160376b1b9dcc40caf4efe"},{"version":"3e8cc18b22f303501b4924d79d2730d1ebcf3365d993ab0ca19994c2cc6337bc","signature":"1bda9166693fe332fa4550821e176105daef955391b38071985daa47055a7011"},{"version":"1d9991b027426d9bd5513e0ac4521867bbcacb537bfe49d24dae939ba330c9b7","signature":"24d4a8d64adadf8ab262d66229e5485239556e6221d52bd05c893a7b86472aa5"},"35d32b2f157a4e27bfae13e57e73d458fb71335af717f590532c77e2b323d530",{"version":"670019c1f499438c6d5f2398deae4286ecd68c75ab10e9d921d3cf210a9efb40","signature":"1fa1ce30428a7b953b96fe89509a93927f7c047c7ebf0db68f0d143e5d880af6"}],"root":[[95,99]],"options":{"allowImportingTsExtensions":true,"allowJs":true,"composite":true,"declaration":true,"declarationMap":true,"emitDeclarationOnly":true,"jsx":4,"module":200,"noEmitOnError":true,"noFallthroughCasesInSwitch":true,"noImplicitOverride":true,"noPropertyAccessFromIndexSignature":false,"noUncheckedIndexedAccess":true,"noUnusedLocals":false,"noUnusedParameters":false,"outDir":"./","skipLibCheck":true,"strict":true,"target":99,"verbatimModuleSyntax":true},"referencedMap":[[92,1],[93,2],[97,3],[95,4],[96,4],[99,5]],"latestChangedDtsFile":"./index.d.ts","version":"6.0.2"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@nuasite/collections-admin",
3
+ "description": "Host-agnostic React SPA for browsing and editing Nua CMS collections over the cms-sidecar HTTP contract.",
4
+ "files": [
5
+ "dist/**",
6
+ "src/**",
7
+ "README.md",
8
+ "package.json"
9
+ ],
10
+ "homepage": "https://github.com/nuasite/nuasite/blob/main/packages/collections-admin/README.md",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/nuasite/nuasite.git",
14
+ "directory": "packages/collections-admin"
15
+ },
16
+ "license": "Apache-2.0",
17
+ "version": "0.43.0-beta.1",
18
+ "module": "src/index.ts",
19
+ "types": "src/index.ts",
20
+ "type": "module",
21
+ "exports": {
22
+ ".": {
23
+ "types": "./src/index.ts",
24
+ "import": "./src/index.ts",
25
+ "default": "./src/index.ts"
26
+ },
27
+ "./styles.css": "./src/styles.css"
28
+ },
29
+ "dependencies": {
30
+ "@nuasite/cms-types": "0.43.0-beta.1"
31
+ },
32
+ "devDependencies": {
33
+ "@types/react": "^19.2.7",
34
+ "@types/react-dom": "^19.2.3",
35
+ "react": "^19.2.1",
36
+ "react-dom": "^19.2.1"
37
+ },
38
+ "peerDependencies": {
39
+ "react": "^19.0.0",
40
+ "react-dom": "^19.0.0",
41
+ "typescript": "^6.0.2"
42
+ },
43
+ "scripts": {
44
+ "prepack": "bun run ../../scripts/workspace-deps/resolve-deps.ts"
45
+ },
46
+ "keywords": [
47
+ "cms",
48
+ "nuasite",
49
+ "react",
50
+ "admin"
51
+ ]
52
+ }
package/src/app.tsx ADDED
@@ -0,0 +1,329 @@
1
+ /**
2
+ * collections-admin SPA — read-only milestone (cms-headless F3.1).
3
+ *
4
+ * Host-agnostic: driven only by an `apiBase` prop, with internal view-state
5
+ * navigation (list → entries → detail) via React state — never the host router.
6
+ * That keeps the same component usable as a webmaster tab today and at
7
+ * `/_nua/admin` for local dev later (F7).
8
+ *
9
+ * Read-only: browse collections, list entries (sparse projection + cursor
10
+ * pagination), and view a single entry's frontmatter + markdown body. Mutations
11
+ * (editor/media/conflict) arrive in F3.2.
12
+ */
13
+
14
+ import type { CollectionDefinition, CollectionEntry, CollectionEntryInfo, FieldDefinition } from '@nuasite/cms-types'
15
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
16
+ import { type CmsClient, CmsClientError, createClient } from './client'
17
+ import { FieldRow } from './field-view'
18
+ import './styles.css'
19
+
20
+ // ============================================================================
21
+ // View state
22
+ // ============================================================================
23
+
24
+ type View =
25
+ | { view: 'list' }
26
+ | { view: 'entries'; collection: string }
27
+ | { view: 'detail'; collection: string; slug: string }
28
+
29
+ // ============================================================================
30
+ // Shared async-load hook
31
+ // ============================================================================
32
+
33
+ interface LoadState<T> {
34
+ data: T | null
35
+ error: CmsClientError | Error | null
36
+ loading: boolean
37
+ }
38
+
39
+ function useAsync<T>(load: () => Promise<T>, deps: readonly unknown[]): LoadState<T> & { reload: () => void } {
40
+ const [state, setState] = useState<LoadState<T>>({ data: null, error: null, loading: true })
41
+ const [nonce, setNonce] = useState(0)
42
+ const loadRef = useRef(load)
43
+ loadRef.current = load
44
+
45
+ // `load` is read through a ref; re-runs are driven by the explicit `deps` and
46
+ // the reload `nonce` so the effect deps stay stable and lint-clean.
47
+ const effectDeps = [...deps, nonce]
48
+ useEffect(() => {
49
+ let active = true
50
+ setState({ data: null, error: null, loading: true })
51
+ loadRef.current().then(
52
+ (data) => {
53
+ if (active) setState({ data, error: null, loading: false })
54
+ },
55
+ (error: unknown) => {
56
+ if (active) setState({ data: null, error: error instanceof Error ? error : new Error(String(error)), loading: false })
57
+ },
58
+ )
59
+ return () => {
60
+ active = false
61
+ }
62
+ }, effectDeps)
63
+
64
+ const reload = useCallback(() => setNonce((n) => n + 1), [])
65
+ return { ...state, reload }
66
+ }
67
+
68
+ // ============================================================================
69
+ // Presentational primitives
70
+ // ============================================================================
71
+
72
+ function Spinner({ label }: { label: string }) {
73
+ return (
74
+ <div className="nua-cadmin-state">
75
+ <div className="nua-cadmin-spinner" />
76
+ <div>{label}</div>
77
+ </div>
78
+ )
79
+ }
80
+
81
+ function ErrorState({ error, onRetry }: { error: CmsClientError | Error; onRetry?: () => void }) {
82
+ const title = error instanceof CmsClientError && error.isUnauthorized
83
+ ? 'Session expired'
84
+ : error instanceof CmsClientError && error.isForbidden
85
+ ? 'No access'
86
+ : 'Something went wrong'
87
+ return (
88
+ <div className="nua-cadmin-error">
89
+ <div className="nua-cadmin-error-title">{title}</div>
90
+ <div>{error.message}</div>
91
+ {onRetry ? <button type="button" className="nua-cadmin-retry" onClick={onRetry}>Try again</button> : null}
92
+ </div>
93
+ )
94
+ }
95
+
96
+ function EmptyState({ label }: { label: string }) {
97
+ return <div className="nua-cadmin-state">{label}</div>
98
+ }
99
+
100
+ // ============================================================================
101
+ // Collection list
102
+ // ============================================================================
103
+
104
+ function CollectionList({ client, onOpen }: { client: CmsClient; onOpen: (collection: string) => void }) {
105
+ const { data, error, loading, reload } = useAsync(() => client.getCollections(), [client])
106
+
107
+ if (loading) return <Spinner label="Loading collections…" />
108
+ if (error) return <ErrorState error={error} onRetry={reload} />
109
+ if (!data || data.length === 0) return <EmptyState label="No collections found in this project." />
110
+
111
+ return (
112
+ <div className="nua-cadmin-list">
113
+ {data.map((collection) => (
114
+ <button key={collection.name} type="button" className="nua-cadmin-card" onClick={() => onOpen(collection.name)}>
115
+ <span className="nua-cadmin-card-main">
116
+ <span className="nua-cadmin-card-label">{collection.label || collection.name}</span>
117
+ <span className="nua-cadmin-card-sub">
118
+ {collection.name}
119
+ {collection.type ? ` · ${collection.type}` : ''}
120
+ {` · ${collection.fileExtension}`}
121
+ </span>
122
+ </span>
123
+ <span className="nua-cadmin-badge">{collection.entryCount} {collection.entryCount === 1 ? 'entry' : 'entries'}</span>
124
+ </button>
125
+ ))}
126
+ </div>
127
+ )
128
+ }
129
+
130
+ // ============================================================================
131
+ // Entries table (sparse projection + cursor pagination)
132
+ // ============================================================================
133
+
134
+ const ENTRIES_PAGE_SIZE = 50
135
+ const ENTRIES_FIELDS = 'slug,title,draft,pathname'
136
+
137
+ function EntriesTable({ client, collection, onOpen }: { client: CmsClient; collection: string; onOpen: (slug: string) => void }) {
138
+ const [rows, setRows] = useState<CollectionEntryInfo[]>([])
139
+ const [cursor, setCursor] = useState<string | undefined>(undefined)
140
+ const [hasMore, setHasMore] = useState(false)
141
+ const [error, setError] = useState<CmsClientError | Error | null>(null)
142
+ const [loading, setLoading] = useState(true)
143
+ const [loadingMore, setLoadingMore] = useState(false)
144
+
145
+ const loadPage = useCallback(
146
+ async (nextCursor: string | undefined, append: boolean) => {
147
+ if (append) setLoadingMore(true)
148
+ else setLoading(true)
149
+ setError(null)
150
+ try {
151
+ const result = await client.getEntries(collection, {
152
+ fields: ENTRIES_FIELDS,
153
+ draft: 'all',
154
+ limit: ENTRIES_PAGE_SIZE,
155
+ cursor: nextCursor,
156
+ })
157
+ setRows((prev) => (append ? [...prev, ...result.entries] : result.entries))
158
+ setCursor(result.cursor)
159
+ setHasMore(result.hasMore)
160
+ } catch (e: unknown) {
161
+ setError(e instanceof Error ? e : new Error(String(e)))
162
+ } finally {
163
+ setLoading(false)
164
+ setLoadingMore(false)
165
+ }
166
+ },
167
+ [client, collection],
168
+ )
169
+
170
+ useEffect(() => {
171
+ setRows([])
172
+ setCursor(undefined)
173
+ setHasMore(false)
174
+ void loadPage(undefined, false)
175
+ }, [loadPage])
176
+
177
+ if (loading) return <Spinner label="Loading entries…" />
178
+ if (error) return <ErrorState error={error} onRetry={() => void loadPage(undefined, false)} />
179
+ if (rows.length === 0) return <EmptyState label="This collection has no entries." />
180
+
181
+ return (
182
+ <div>
183
+ <table className="nua-cadmin-table">
184
+ <thead>
185
+ <tr>
186
+ <th>Slug</th>
187
+ <th>Title</th>
188
+ <th>Draft</th>
189
+ <th>Pathname</th>
190
+ </tr>
191
+ </thead>
192
+ <tbody>
193
+ {rows.map((entry) => (
194
+ <tr key={entry.slug} className="nua-cadmin-row" onClick={() => onOpen(entry.slug)}>
195
+ <td className="nua-cadmin-cell-mono">{entry.slug}</td>
196
+ <td>{entry.title ?? <span className="nua-cadmin-field-empty">—</span>}</td>
197
+ <td>{entry.draft ? <span className="nua-cadmin-badge nua-cadmin-badge-draft">draft</span> : ''}</td>
198
+ <td className="nua-cadmin-cell-mono">{entry.pathname ?? '—'}</td>
199
+ </tr>
200
+ ))}
201
+ </tbody>
202
+ </table>
203
+ {hasMore
204
+ ? (
205
+ <button type="button" className="nua-cadmin-load-more" disabled={loadingMore} onClick={() => void loadPage(cursor, true)}>
206
+ {loadingMore ? 'Loading…' : 'Load more'}
207
+ </button>
208
+ )
209
+ : null}
210
+ </div>
211
+ )
212
+ }
213
+
214
+ // ============================================================================
215
+ // Entry detail
216
+ // ============================================================================
217
+
218
+ /**
219
+ * Order the collection's fields for display: `publish-toggle`/`publish-date`
220
+ * roles and `sidebar`/`header` positioned fields first, then the rest in schema
221
+ * order. Hidden fields are dropped.
222
+ */
223
+ function orderFields(fields: FieldDefinition[]): FieldDefinition[] {
224
+ const visible = fields.filter((f) => !f.hidden)
225
+ const pinned = visible.filter((f) => f.role !== undefined || f.position !== undefined)
226
+ const rest = visible.filter((f) => f.role === undefined && f.position === undefined)
227
+ return [...pinned, ...rest]
228
+ }
229
+
230
+ function EntryDetail({ client, collections, collection, slug }: {
231
+ client: CmsClient
232
+ collections: CollectionDefinition[]
233
+ collection: string
234
+ slug: string
235
+ }) {
236
+ const { data, error, loading, reload } = useAsync<CollectionEntry>(() => client.getEntry(collection, slug), [client, collection, slug])
237
+
238
+ const def = useMemo(() => collections.find((c) => c.name === collection), [collections, collection])
239
+
240
+ if (loading) return <Spinner label="Loading entry…" />
241
+ if (error) return <ErrorState error={error} onRetry={reload} />
242
+ if (!data) return <EmptyState label="Entry not found." />
243
+
244
+ const fieldDefs = def ? orderFields(def.fields) : []
245
+ const renderedNames = new Set(fieldDefs.map((f) => f.name))
246
+ // Frontmatter keys present on the entry but absent from the inferred schema.
247
+ const extraKeys = Object.keys(data.frontmatter).filter((k) => !renderedNames.has(k))
248
+
249
+ return (
250
+ <div>
251
+ <div className="nua-cadmin-fields">
252
+ {fieldDefs.length === 0 && extraKeys.length === 0 ? <EmptyState label="No frontmatter fields." /> : null}
253
+ {fieldDefs.map((field) => <FieldRow key={field.name} field={field} raw={data.frontmatter[field.name]?.value} />)}
254
+ {extraKeys.map((key) => <FieldRow key={key} field={{ name: key, type: 'text', required: false }} raw={data.frontmatter[key]?.value} />)}
255
+ </div>
256
+
257
+ <h3 className="nua-cadmin-section-title">Body</h3>
258
+ {data.body.trim() === ''
259
+ ? <EmptyState label="This entry has no markdown body." />
260
+ : <pre className="nua-cadmin-body-content">{data.body}</pre>}
261
+ </div>
262
+ )
263
+ }
264
+
265
+ // ============================================================================
266
+ // Root
267
+ // ============================================================================
268
+
269
+ export interface CollectionsAdminAppProps {
270
+ /**
271
+ * Base URL the cms-sidecar is mounted under (the host adds the `/cms/v1`
272
+ * prefix). In webmaster this is `/app/project/:slug/session/:sessionId/cms`.
273
+ */
274
+ apiBase: string
275
+ /** Optional close affordance shown in the header (e.g. to collapse the WM tab). */
276
+ onClose?: () => void
277
+ }
278
+
279
+ export function CollectionsAdminApp({ apiBase, onClose }: CollectionsAdminAppProps) {
280
+ const client = useMemo(() => createClient(apiBase), [apiBase])
281
+ const [state, setState] = useState<View>({ view: 'list' })
282
+
283
+ // The collection definitions are needed by the detail view to drive field
284
+ // rendering; load them once at the root and pass down.
285
+ const collectionsState = useAsync(() => client.getCollections(), [client])
286
+ const collections = collectionsState.data ?? []
287
+
288
+ const goList = useCallback(() => setState({ view: 'list' }), [])
289
+ const goEntries = useCallback((collection: string) => setState({ view: 'entries', collection }), [])
290
+ const goDetail = useCallback((collection: string, slug: string) => setState({ view: 'detail', collection, slug }), [])
291
+
292
+ const activeCollection = state.view !== 'list'
293
+ ? collections.find((c) => c.name === state.collection)
294
+ : undefined
295
+ const collectionLabel = activeCollection ? (activeCollection.label || activeCollection.name) : (state.view !== 'list' ? state.collection : '')
296
+
297
+ return (
298
+ <div className="nua-cadmin">
299
+ <div className="nua-cadmin-header">
300
+ {state.view === 'entries' ? <button type="button" className="nua-cadmin-back" onClick={goList}>← Collections</button> : null}
301
+ {state.view === 'detail'
302
+ ? <button type="button" className="nua-cadmin-back" onClick={() => goEntries(state.collection)}>← {collectionLabel}</button>
303
+ : null}
304
+
305
+ {state.view === 'list' ? <h2 className="nua-cadmin-title">Collections</h2> : null}
306
+ {state.view === 'entries' ? <h2 className="nua-cadmin-title">{collectionLabel}</h2> : null}
307
+ {state.view === 'detail'
308
+ ? (
309
+ <h2 className="nua-cadmin-title">
310
+ {collectionLabel}
311
+ <span className="nua-cadmin-crumb">/ {state.slug}</span>
312
+ </h2>
313
+ )
314
+ : null}
315
+
316
+ <span className="nua-cadmin-spacer" />
317
+ {onClose ? <button type="button" className="nua-cadmin-close" aria-label="Close" onClick={onClose}>×</button> : null}
318
+ </div>
319
+
320
+ <div className="nua-cadmin-body">
321
+ {state.view === 'list' ? <CollectionList client={client} onOpen={goEntries} /> : null}
322
+ {state.view === 'entries'
323
+ ? <EntriesTable client={client} collection={state.collection} onOpen={(slug) => goDetail(state.collection, slug)} />
324
+ : null}
325
+ {state.view === 'detail' ? <EntryDetail client={client} collections={collections} collection={state.collection} slug={state.slug} /> : null}
326
+ </div>
327
+ </div>
328
+ )
329
+ }
package/src/client.ts ADDED
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Typed read-only client over the cms-sidecar `/cms/v1` HTTP contract.
3
+ *
4
+ * The host (webmaster BFF, or a local dev proxy in F7) mounts the sidecar under
5
+ * an `apiBase` and adds the `/cms/v1` prefix itself — so this client requests
6
+ * `${apiBase}/project`, `${apiBase}/collections`, etc. (never `/cms/v1/...`).
7
+ *
8
+ * The structural model (collections/entries/fields) is reused 1:1 from
9
+ * `@nuasite/cms-types`. The thin HTTP envelope (project model, sparse entries
10
+ * list, error codes) mirrors the sidecar's wire types; it is declared here
11
+ * because those types are not part of the `@nuasite/cms-types` contract surface.
12
+ */
13
+
14
+ import type { CollectionDefinition, CollectionEntry, CollectionEntryInfo } from '@nuasite/cms-types'
15
+
16
+ // ============================================================================
17
+ // Wire envelope (mirrors @nuasite/cms-sidecar's `/cms/v1` contract)
18
+ // ============================================================================
19
+
20
+ /** Stable error codes the sidecar exposes, each mapped to an HTTP status. */
21
+ export type CmsErrorCode =
22
+ | 'not_found'
23
+ | 'conflict'
24
+ | 'validation'
25
+ | 'parse_error'
26
+ | 'io_error'
27
+ | 'unsupported'
28
+ | 'unauthorized'
29
+
30
+ /** JSON body returned for every non-2xx response that is not a conflict. */
31
+ export interface CmsApiError {
32
+ error: string
33
+ code: CmsErrorCode
34
+ sourcePath?: string
35
+ }
36
+
37
+ /** A static page route discovered under `src/pages` (pathname-only). */
38
+ export interface CmsPageEntry {
39
+ pathname: string
40
+ title?: string
41
+ }
42
+
43
+ /** Features the sidecar advertises so the UI can degrade gracefully. */
44
+ export interface CmsCapabilities {
45
+ coreVersion: string
46
+ features: string[]
47
+ }
48
+
49
+ /** `GET /project` — the whole structural model in one call. */
50
+ export interface CmsProjectModel {
51
+ collections: CollectionDefinition[]
52
+ pages: CmsPageEntry[]
53
+ capabilities: CmsCapabilities
54
+ }
55
+
56
+ /** `GET …/entries` — projected entries plus an opaque continuation cursor. */
57
+ export interface CmsEntriesListResult {
58
+ entries: CollectionEntryInfo[]
59
+ cursor?: string
60
+ hasMore: boolean
61
+ }
62
+
63
+ // ============================================================================
64
+ // Client error
65
+ // ============================================================================
66
+
67
+ /**
68
+ * Thrown for any non-2xx response. Carries the parsed sidecar error code so the
69
+ * UI can distinguish auth failures (`unauthorized`/`forbidden`) from a missing
70
+ * collection/entry (`not_found`) or a generic failure.
71
+ */
72
+ export class CmsClientError extends Error {
73
+ constructor(
74
+ readonly status: number,
75
+ readonly code: CmsErrorCode | 'forbidden' | 'unknown',
76
+ message: string,
77
+ ) {
78
+ super(message)
79
+ this.name = 'CmsClientError'
80
+ }
81
+
82
+ /** Session cookie missing/expired upstream — the user must re-authenticate. */
83
+ get isUnauthorized(): boolean {
84
+ return this.code === 'unauthorized' || this.status === 401
85
+ }
86
+
87
+ /** Authenticated but lacks access to this project. */
88
+ get isForbidden(): boolean {
89
+ return this.code === 'forbidden' || this.status === 403
90
+ }
91
+
92
+ get isNotFound(): boolean {
93
+ return this.code === 'not_found' || this.status === 404
94
+ }
95
+ }
96
+
97
+ // ============================================================================
98
+ // Query options
99
+ // ============================================================================
100
+
101
+ export interface GetEntriesOptions {
102
+ /** "slug,title" | "*" ; absent = light header (slug/title/draft/pathname). */
103
+ fields?: string
104
+ /** Draft filter — defaults to `'false'` (published only) on the sidecar. */
105
+ draft?: 'true' | 'false' | 'all'
106
+ /** Opaque continuation cursor from a previous page's `cursor`. */
107
+ cursor?: string
108
+ limit?: number
109
+ }
110
+
111
+ // ============================================================================
112
+ // Client
113
+ // ============================================================================
114
+
115
+ function isApiError(value: unknown): value is CmsApiError {
116
+ return typeof value === 'object'
117
+ && value !== null
118
+ && 'error' in value
119
+ && typeof (value as { error: unknown }).error === 'string'
120
+ && 'code' in value
121
+ && typeof (value as { code: unknown }).code === 'string'
122
+ }
123
+
124
+ const KNOWN_ERROR_CODES: readonly CmsErrorCode[] = [
125
+ 'not_found',
126
+ 'conflict',
127
+ 'validation',
128
+ 'parse_error',
129
+ 'io_error',
130
+ 'unsupported',
131
+ 'unauthorized',
132
+ ]
133
+
134
+ function isErrorCode(value: string): value is CmsErrorCode {
135
+ return (KNOWN_ERROR_CODES as readonly string[]).includes(value)
136
+ }
137
+
138
+ export interface CmsClient {
139
+ getProject(): Promise<CmsProjectModel>
140
+ getCollections(): Promise<CollectionDefinition[]>
141
+ getEntries(collection: string, options?: GetEntriesOptions): Promise<CmsEntriesListResult>
142
+ getEntry(collection: string, slug: string): Promise<CollectionEntry>
143
+ }
144
+
145
+ export function createClient(apiBase: string): CmsClient {
146
+ // Normalise: drop a trailing slash so `${base}${path}` joins cleanly.
147
+ const base = apiBase.endsWith('/') ? apiBase.slice(0, -1) : apiBase
148
+
149
+ async function request<T>(path: string): Promise<T> {
150
+ const response = await fetch(`${base}${path}`, {
151
+ method: 'GET',
152
+ credentials: 'include',
153
+ headers: { accept: 'application/json' },
154
+ })
155
+
156
+ if (!response.ok) {
157
+ throw await toError(response)
158
+ }
159
+
160
+ // Successful responses are always JSON in the read-only surface.
161
+ const value: T = await response.json()
162
+ return value
163
+ }
164
+
165
+ async function toError(response: Response): Promise<CmsClientError> {
166
+ // 403 is produced by the BFF (project scope), not the sidecar, so it has no
167
+ // sidecar `code`; surface it as a distinct `forbidden`.
168
+ if (response.status === 403) {
169
+ const message = await readErrorMessage(response, 'You do not have access to this project.')
170
+ return new CmsClientError(403, 'forbidden', message)
171
+ }
172
+
173
+ const body: unknown = await response.json().catch(() => null)
174
+ if (isApiError(body) && isErrorCode(body.code)) {
175
+ return new CmsClientError(response.status, body.code, body.error)
176
+ }
177
+ if (response.status === 401) {
178
+ return new CmsClientError(401, 'unauthorized', 'Your session has expired. Please reload.')
179
+ }
180
+ return new CmsClientError(response.status, 'unknown', `Request failed (${response.status})`)
181
+ }
182
+
183
+ async function readErrorMessage(response: Response, fallback: string): Promise<string> {
184
+ const body: unknown = await response.json().catch(() => null)
185
+ if (isApiError(body)) return body.error
186
+ if (typeof body === 'object' && body !== null && 'error' in body) {
187
+ const err = (body as { error: unknown }).error
188
+ if (typeof err === 'object' && err !== null && 'message' in err && typeof (err as { message: unknown }).message === 'string') {
189
+ return (err as { message: string }).message
190
+ }
191
+ }
192
+ return fallback
193
+ }
194
+
195
+ return {
196
+ getProject() {
197
+ return request<CmsProjectModel>('/project')
198
+ },
199
+ getCollections() {
200
+ return request<CollectionDefinition[]>('/collections')
201
+ },
202
+ getEntries(collection, options = {}) {
203
+ const params = new URLSearchParams()
204
+ if (options.fields !== undefined) params.set('fields', options.fields)
205
+ if (options.draft !== undefined) params.set('draft', options.draft)
206
+ if (options.cursor !== undefined) params.set('cursor', options.cursor)
207
+ if (options.limit !== undefined) params.set('limit', String(options.limit))
208
+ const query = params.toString()
209
+ const suffix = query === '' ? '' : `?${query}`
210
+ return request<CmsEntriesListResult>(`/collections/${encodeURIComponent(collection)}/entries${suffix}`)
211
+ },
212
+ getEntry(collection, slug) {
213
+ return request<CollectionEntry>(`/collections/${encodeURIComponent(collection)}/entries/${encodeURIComponent(slug)}`)
214
+ },
215
+ }
216
+ }
package/src/css.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Ambient declaration so a side-effect `import './styles.css'` typechecks in the
3
+ * lib's own build. Hosts (webmaster) already declare `*.css` via `vite/client`,
4
+ * and the bundler resolves the real file at build time.
5
+ */
6
+ declare module '*.css' {
7
+ const css: string
8
+ export default css
9
+ }