{"_id":"@allejo/decap-extras","_rev":"11-609985c134524f07fcfb4f2fad53c24d","name":"@allejo/decap-extras","dist-tags":{"latest":"0.0.10"},"versions":{"0.0.0":{"name":"@allejo/decap-extras","version":"0.0.0","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.0","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"f98de26aa80bb23a66224dfa1fc0424a154aacbd","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.0.tgz","fileCount":6,"integrity":"sha512-iqVf/aGc6haycha+tpzHA29uPnSyvCms9NW2kM9GqmQpw7737goIf0DE8KYrPyPutow/+I17AyQSdMXJ7i9lwg==","signatures":[{"sig":"MEUCIFsZAvPe9bey2WDATUCOYAFiXiBVNvOyhVkCdiof47+sAiEAxF2SRoXLytbV7olwJVn8HYJNLcD2T3GpkreTeR9sk+w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35366},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","gitHead":"3340e21a296c248076c0d74d585094145910fdec","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write ."},"_npmUser":{"name":"allejo","email":"me@allejo.io"},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.14.1","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.11.1","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0"},"peerDependencies":{"decap-cms-core":"^3.12.2"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.0_1778987919579_0.6219644026631075","host":"s3://npm-registry-packages-npm-production"}},"0.0.1":{"name":"@allejo/decap-extras","version":"0.0.1","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.1","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"396a9a41d89b0eeda29fa8179ee574a41cc46130","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.1.tgz","fileCount":6,"integrity":"sha512-GuirORfldJo5i5eyv4G3VEvu1dDwvMbG6TIBfVixa8oy064vKIEspdYXdr4O+OrodOJlqneNaDVLmmAnJge3+g==","signatures":[{"sig":"MEYCIQD/V1l6bbxuCQWW1fuj62WE8o7vwFILanccGu68tFCHvwIhAM7v+3vCITVt/7Yodczl1LvBbOV0Yx+I1DZdaARz+1pX","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36092},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","gitHead":"bf6183f7839b695967c2c58d6dd12b054b43a82d","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write ."},"_npmUser":{"name":"allejo","email":"me@allejo.io"},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.14.1","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.11.1","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0"},"peerDependencies":{"decap-cms-core":"^3.12.2"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.1_1779000039133_0.44813951056744994","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@allejo/decap-extras","version":"0.0.2","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.2","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"4e102c61eebb19e2e0a464b00424986216eb9f01","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.2.tgz","fileCount":11,"integrity":"sha512-eqowEGGN/KimVIV2oUDlNmAzRQ3oqcWGZW2fJgEiumlItXjVcM0u8NiAPI9RwxZw6yQWfm6FwggHlUwqdfYmfg==","signatures":[{"sig":"MEUCIQDKExW5Nz2/5vcXPf5Bu3fFuYPgGPyyFdaL9JXto5EU4AIgTT6dcGumekhoP2vB8iA4hHT6gR9prk8n/6PfS9eQAmE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":43942},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./server":{"types":"./dist/server.d.mts","import":"./dist/server.mjs"}},"gitHead":"99f7f1e8b75f5381f4ebb68be2f65aadded0fe83","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write ."},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3607171b-5284-41b5-9655-9b2ab936ad86"}},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.12.1","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.15.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0"},"peerDependencies":{"decap-cms-core":"^3.12.2"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.2_1779082032054_0.16312550968495976","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@allejo/decap-extras","version":"0.0.3","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.3","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"62ff9babfbf2dfb1ecd534323d2fe1350086b9e4","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.3.tgz","fileCount":15,"integrity":"sha512-n8vfn90YS+GqCkGY+zmqYzUlDfD0jSlLvh4Yn4BOy/NuPjViM9+WOPi1EyJ/88+BmVZWDjptwNLoEoFsvsE2VA==","signatures":[{"sig":"MEYCIQD0q7jucgsiBAO+luuhCbDqKZ/g6i6JcgXZXGWeRUJVCgIhAMy+8E/8TxnWmfz6wJ3lB9HNX5MJKjKj5soNmOW7DTr2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63385},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./next":{"types":"./dist/next/index.d.mts","import":"./dist/next/index.mjs"},"./react":{"types":"./dist/react/index.d.mts","import":"./dist/react/index.mjs"}},"gitHead":"331d8d6efe480ce552b25244a70d49a1bcb79e99","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write ."},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3607171b-5284-41b5-9655-9b2ab936ad86"}},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.12.1","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.15.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","react":"^19.2.6","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0","decap-cms-media-library-cloudinary":"^3.1.0"},"peerDependencies":{"react":"16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","decap-cms-core":"^3.12.2","decap-cms-media-library-cloudinary":"^3.1.0"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.3_1779859950139_0.11963418138956405","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@allejo/decap-extras","version":"0.0.4","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.4","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"265add9ea90a3c591cd450dc78f10fce83ac988a","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.4.tgz","fileCount":15,"integrity":"sha512-7N630/l0m/BZcYjAc6fQKUP1WUquBa2IbITY5fh9nx7e2Q95IYYf9MVwGg4Li6Ko/SKhaFPePHVoaBU8ECSJAQ==","signatures":[{"sig":"MEQCIGKzjdEmT4uEDTwoCMAnrzIhMONZfXgVtlSrc0DZgCh9AiBuue2hpieiUy9L52AgF+pvH/wBfy9kkVPTxPi1SZThDQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63315},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./next":{"types":"./dist/next/index.d.mts","import":"./dist/next/index.mjs"},"./react":{"types":"./dist/react/index.d.mts","import":"./dist/react/index.mjs"}},"gitHead":"00f8249f461380b13a267c3b4b8efd24c030d46c","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write ."},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3607171b-5284-41b5-9655-9b2ab936ad86"}},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.13.0","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.16.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","react":"^19.2.6","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0","decap-cms-media-library-cloudinary":"^3.1.0"},"peerDependencies":{"react":"16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","decap-cms-core":"^3.12.2","decap-cms-media-library-cloudinary":"^3.1.0"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.4_1779862749906_0.3658896990916658","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@allejo/decap-extras","version":"0.0.5","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.5","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"e87aede39a3a4109ffabff705a6de78e20bcae07","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.5.tgz","fileCount":15,"integrity":"sha512-5rqIOVbQpPEieFIPuJ2j14UDxrvcbv1pcDz8X6Nl62bCVaXseRNQbOKMSd81azcBpQ2LWy1kQXCcFQJNxsXPPg==","signatures":[{"sig":"MEUCIFqEfLEKULcwWHdEpOk+k/lvO506B4iaIuLP4UDsG7otAiEArSNuMBBRfYIefldPtEyd6jU52EX2rIE+YLEbTsyRJ3g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@allejo%2fdecap-extras@0.0.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":62603},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./next":{"types":"./dist/next/index.d.mts","import":"./dist/next/index.mjs"},"./react":{"types":"./dist/react/index.d.mts","import":"./dist/react/index.mjs"}},"gitHead":"8524a232c27ed0e26c0eb562e4cdf6615e46dab9","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write ."},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3607171b-5284-41b5-9655-9b2ab936ad86"}},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.12.1","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.15.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","react":"^19.2.6","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0","decap-cms-media-library-cloudinary":"^3.1.0"},"peerDependencies":{"react":"16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","decap-cms-core":"^3.12.2","decap-cms-media-library-cloudinary":"^3.1.0"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.5_1779941247777_0.24585194441640712","host":"s3://npm-registry-packages-npm-production"}},"0.0.6":{"name":"@allejo/decap-extras","version":"0.0.6","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.6","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"5602e24182a9f2a8c6ff1f909610094792aed891","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.6.tgz","fileCount":15,"integrity":"sha512-eQSq3v0ql8xHrEE5NeoMLfxcuJUH6JuGsiCpF2hGNSDRKAF585HCKOnN/m/XFqmtCglPG5mG2oLcbcpjCXuA+w==","signatures":[{"sig":"MEUCIQDbXuh8DWA6Bgout5sR+K7ZeBg3NNk2zj1Uqi9ck3hN7AIgUDAl1YHcsv8z8FTH1eADUavCTtyBN5R4YP6ZVV3itME=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@allejo%2fdecap-extras@0.0.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":62603},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./next":{"types":"./dist/next/index.d.mts","import":"./dist/next/index.mjs"},"./react":{"types":"./dist/react/index.d.mts","import":"./dist/react/index.mjs"}},"gitHead":"abde89acbd242bfc5c540feec538d0cfe827575c","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write ."},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3607171b-5284-41b5-9655-9b2ab936ad86"}},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.16.0","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","react":"^19.2.6","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0","decap-cms-media-library-cloudinary":"^3.1.0"},"peerDependencies":{"react":"16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","decap-cms-core":"^3.12.2","decap-cms-media-library-cloudinary":"^3.1.0"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.6_1783918862854_0.981530810700235","host":"s3://npm-registry-packages-npm-production"}},"0.0.7":{"name":"@allejo/decap-extras","version":"0.0.7","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.7","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"0be1a31f74ee09c532e379be67ae53664f23c358","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.7.tgz","fileCount":15,"integrity":"sha512-BZTosN5TuCwpCP+ZALT8/i9C0mmiwATkaFKb+oAA8Ly437s4P9ALyM/g9OImAVwhAKZM3XPyJWMw9S2DVKHyCg==","signatures":[{"sig":"MEYCIQC0yRGiLZ3IoaDOt3HZUz0ytIXLI2YakeTwjW+Xe46QXQIhAOtkb/PeHurwzNQ8PdavpT5oHW7jpHweyc277QCcXU7D","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@allejo%2fdecap-extras@0.0.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":95186},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./next":{"types":"./dist/next/index.d.mts","import":"./dist/next/index.mjs"},"./react":{"types":"./dist/react/index.d.mts","import":"./dist/react/index.mjs"}},"gitHead":"8e296998b7c7d3eb0a90571143c1295bbb60cd89","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write ."},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3607171b-5284-41b5-9655-9b2ab936ad86"}},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.16.0","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","react":"^19.2.6","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0","decap-cms-media-library-cloudinary":"^3.1.0"},"peerDependencies":{"react":"16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","decap-cms-core":"^3.12.2","decap-cms-media-library-cloudinary":"^3.1.0"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.7_1784702469029_0.9080593342455068","host":"s3://npm-registry-packages-npm-production"}},"0.0.8":{"name":"@allejo/decap-extras","version":"0.0.8","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.8","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"1760b67d342d5d14d62651a095bfc6c575806434","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.8.tgz","fileCount":15,"integrity":"sha512-cm1beNqKewzI50WP8fw1UOj7AbiT+PAr+XB/GDPtXoYzrARQ5TUh1NMv8GCnMysa+2UQVHsXzZEZQYfotuDHwg==","signatures":[{"sig":"MEYCIQCy95uAboUxeruByvqzhgTYxAjbT2zgO+hs4FdlfzS4IwIhAKhs+xF9nk8Wax8kwm6WQ1lXmVbwDxRgiXOmXdQ1D6X2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@allejo%2fdecap-extras@0.0.8","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":99158},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs"},"./next":{"types":"./dist/next/index.d.mts","import":"./dist/next/index.mjs"},"./react":{"types":"./dist/react/index.d.mts","import":"./dist/react/index.mjs"}},"gitHead":"7d03d08681bfb3211e3292fea75db02418f88a8f","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write ."},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3607171b-5284-41b5-9655-9b2ab936ad86"}},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.16.0","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","react":"^19.2.6","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0","decap-cms-media-library-cloudinary":"^3.1.0"},"peerDependencies":{"react":"16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","decap-cms-core":"^3.12.2","decap-cms-media-library-cloudinary":"^3.1.0"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.8_1784702800488_0.5623470891984335","host":"s3://npm-registry-packages-npm-production"}},"0.0.9":{"name":"@allejo/decap-extras","version":"0.0.9","keywords":["decapcms"],"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","_id":"@allejo/decap-extras@0.0.9","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"homepage":"https://github.com/allejo/decap-extras#readme","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"dist":{"shasum":"216a8b52908eb0ca6f883191bf84f1d3517870f4","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.9.tgz","fileCount":15,"integrity":"sha512-i+n8KIRlPShfcHJ5O+canHuYqsRYIgtKevJpv9QvK8lEf5Gq8KtQeKxmjZ3q/C64WwkZVEmerQlbOXhnXl1Gbg==","signatures":[{"sig":"MEQCIDkcJ+Ht2eGekWfNUoGD0otlpNjWwgOqAjFa5XvAGDA6AiBjSt3CbaDuCKvoUzrpPFlcNhP/O5LjrXyv+OKH5kFuhw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@allejo%2fdecap-extras@0.0.9","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":99886},"main":"./dist/index.mjs","type":"module","types":"./dist/index.d.mts","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./next":{"types":"./dist/next/index.d.mts","import":"./dist/next/index.mjs","default":"./dist/next/index.mjs"},"./react":{"types":"./dist/react/index.d.mts","import":"./dist/react/index.mjs","default":"./dist/react/index.mjs"}},"gitHead":"5a4d5351181a88004149d1e11398e0d21c80677f","scripts":{"test":"vitest run --typecheck","build":"tsdown","format":"prettier --write .","build:watch":"tsdown --watch"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3607171b-5284-41b5-9655-9b2ab936ad86"}},"repository":{"url":"git+https://github.com/allejo/decap-extras.git","type":"git"},"_npmVersion":"11.16.0","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","directories":{},"lint-staged":{"*.ts":"eslint --fix","*.{md,ts}":"prettier --write"},"_nodeVersion":"24.18.0","_hasShrinkwrap":false,"devDependencies":{"husky":"^9.0.10","react":"^19.2.6","eslint":"^9.21.0","tsdown":"^0.22.0","vitest":"^3.2.4","prettier":"^3.1.1","typescript":"^5.9.3","@types/node":"^24.12.4","lint-staged":"^15.4.3","@types/eslint":"^8.44.7","decap-cms-app":"^3.12.2","@commitlint/cli":"^18.6.0","@commitlint/types":"^21.0.1","@allejo/prettier-config":"^1.0.8","@commitlint/config-conventional":"^18.6.0","decap-cms-media-library-cloudinary":"^3.1.0"},"peerDependencies":{"react":"16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0","decap-cms-core":"^3.12.2","decap-cms-media-library-cloudinary":"^3.1.0"},"_npmOperationalInternal":{"tmp":"tmp/decap-extras_0.0.9_1784712280315_0.27329220435663815","host":"s3://npm-registry-packages-npm-production"}},"0.0.10":{"name":"@allejo/decap-extras","version":"0.0.10","description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","keywords":["decapcms"],"repository":{"type":"git","url":"git+https://github.com/allejo/decap-extras.git"},"license":"MIT","author":{"name":"Vladimir \"allejo\" Jimenez"},"type":"module","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs"},"./react":{"types":"./dist/react/index.d.mts","import":"./dist/react/index.mjs","default":"./dist/react/index.mjs"},"./next":{"types":"./dist/next/index.d.mts","import":"./dist/next/index.mjs","default":"./dist/next/index.mjs"}},"main":"./dist/index.mjs","types":"./dist/index.d.mts","scripts":{"build":"tsdown","build:watch":"tsdown --watch","format":"prettier --write .","test":"vitest run --typecheck"},"lint-staged":{"*.{md,ts}":"prettier --write","*.ts":"eslint --fix"},"devDependencies":{"@allejo/prettier-config":"^1.0.8","@commitlint/cli":"^18.6.0","@commitlint/config-conventional":"^18.6.0","@commitlint/types":"^21.0.1","@types/eslint":"^8.44.7","@types/node":"^24.12.4","decap-cms-app":"^3.12.2","decap-cms-media-library-cloudinary":"^3.1.0","eslint":"^9.21.0","husky":"^9.0.10","lint-staged":"^15.4.3","prettier":"^3.1.1","react":"^19.2.6","tsdown":"^0.22.0","typescript":"^5.9.3","vitest":"^3.2.4"},"peerDependencies":{"decap-cms-core":"^3.12.2","decap-cms-media-library-cloudinary":"^3.1.0","react":"16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"},"gitHead":"a1dcb1374b156d3e0588b8014ce16b0c983e6d89","_id":"@allejo/decap-extras@0.0.10","bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"homepage":"https://github.com/allejo/decap-extras#readme","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-LKYfWTREyGk73VABJumVLUicBYPa8CbQzynIecjtqpmxd8263QO9miCb1FtOj9n7WorIjjEvDQZdWmLSjJoHqQ==","shasum":"fec062242b04658613f5dd540962b685fc6ed344","tarball":"https://registry.npmjs.org/@allejo/decap-extras/-/decap-extras-0.0.10.tgz","fileCount":15,"unpackedSize":100162,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@allejo%2fdecap-extras@0.0.10","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICWoNP3gJCVzK3E0/LdIK11Zux987UYte3Y2WkSBbz+8AiBq0xvShdvsGzNAreqECqkbC7iajd7Tp9CDy8EzZtoQRA=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3607171b-5284-41b5-9655-9b2ab936ad86"}},"directories":{},"maintainers":[{"name":"allejo","email":"me@allejo.io"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/decap-extras_0.0.10_1784737405731_0.5953582606323116"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-17T03:18:39.460Z","modified":"2026-07-22T16:23:26.147Z","0.0.0":"2026-05-17T03:18:39.702Z","0.0.1":"2026-05-17T06:40:39.274Z","0.0.2":"2026-05-18T05:27:12.212Z","0.0.3":"2026-05-27T05:32:30.314Z","0.0.4":"2026-05-27T06:19:10.039Z","0.0.5":"2026-05-28T04:07:27.944Z","0.0.6":"2026-07-13T05:01:02.987Z","0.0.7":"2026-07-22T06:41:09.170Z","0.0.8":"2026-07-22T06:46:40.632Z","0.0.9":"2026-07-22T09:24:40.444Z","0.0.10":"2026-07-22T16:23:25.857Z"},"bugs":{"url":"https://github.com/allejo/decap-extras/issues"},"author":{"name":"Vladimir \"allejo\" Jimenez"},"license":"MIT","homepage":"https://github.com/allejo/decap-extras#readme","keywords":["decapcms"],"repository":{"type":"git","url":"git+https://github.com/allejo/decap-extras.git"},"description":"A TypeScript utility library for Decap CMS with utility types to derive types from Decap CMS configuration files.","maintainers":[{"name":"allejo","email":"me@allejo.io"}],"readme":"# @allejo/decap-extras\n\n> [!WARNING]\n>\n> This is an experimental package in early development. I'm currently dog feeding this project in my own projects and am constantly improving the API as I discover better patterns.\n>\n> See my [nextjs-decap-typescript-template](https://github.com/allejo/nextjs-decap-typescript-template) repository for a real-world example of how to use this package in a Next.js project.\n\nA TypeScript utility library for [Decap CMS](https://decapcms.org/) that does two things:\n\n1. **Widget factory functions** — type-safe helpers for building Decap CMS field configuration objects instead of writing raw object literals by hand.\n2. **Type inference utilities** — TypeScript utility types that derive content types directly from your CMS config, so you never have to maintain separate type definitions for your CMS content.\n\n## Installation\n\n```sh\nnpm install @allejo/decap-extras\n# or\npnpm add @allejo/decap-extras\n# or\nyarn add @allejo/decap-extras\n```\n\nThis package requires `decap-cms-core` as a peer dependency:\n\n```sh\nnpm install decap-cms-core\n```\n\n## Usage\n\n### Widget factories\n\nAll factory functions follow a similar signature of `widget(label, name, options?)`.\n\n```ts\nimport {\n\tboolWidget,\n\timageWidget,\n\tINLINE_MARKDOWN,\n\tlistWidget,\n\tmarkdownWidget,\n\tnumberWidget,\n\tobjectWidget,\n\toptional,\n\tRICH_MARKDOWN,\n\tselectWidget,\n\tstringWidget,\n\ttextWidget,\n} from '@allejo/decap-extras';\n```\n\n#### Widget modifiers\n\n##### `optional(widget)`\n\nMarks a widget field as optional, allowing it to be left empty in DecapCMS. This modifier can be applied to any widget type to make it non-required.\n\n**TypeScript:**\n\n```ts\noptional(stringWidget('Middle Name', 'middleName'));\n```\n\n**YAML Configuration:**\n\n```yaml\n- label: Middle Name\n  name: middleName\n  widget: string\n  required: false # All fields are required by default, so this is necessary to make it optional\n```\n\n**Data Store YAML:**\n\n```yaml\nmiddleName: # Can be left empty\n```\n\nThe `optional` modifier can be used with all widget types including complex ones:\n\n```ts\noptional(\n\tobjectWidget('Metadata', 'metadata', [stringWidget('Author', 'author')]),\n);\noptional(listWidget('Tags', 'tags', stringWidget('Tag', 'value')));\n```\n\nThe `optional` modifier affects both the Decap CMS UI (field is not required) and the derived TypeScript type (field becomes `T | undefined`).\n\n**Learn more:** [DecapCMS Common Widget Options](https://decapcms.org/docs/widgets/#common-widget-options)\n\n#### Primitive widgets\n\n##### `stringWidget(label, name, opts?)`\n\nCreates a single-line text input field for short text content.\n\n**TypeScript:**\n\n```ts\nstringWidget('Title', 'title');\n```\n\n**YAML Configuration:**\n\n```yaml\n- label: Title\n  name: title\n  widget: string\n```\n\n**Data Store YAML:**\n\n```yaml\ntitle: Welcome to My Blog\n```\n\nUnlike the `textWidget` which provides multi-line input, the string widget is designed for concise, single-line values like titles, slugs, or names.\n\n```ts\noptional(stringWidget('Slug', 'slug'));\n```\n\n**See also:** [`textWidget`](#textwidgetlabel-name-opts), [`markdownWidget`](#markdownwidgetlabel-name-opts)\n**Learn more:** [DecapCMS String Widget Docs](https://decapcms.org/docs/widgets/#string)\n\n##### `textWidget(label, name, opts?)`\n\nCreates a multi-line text input field for longer text content.\n\n**TypeScript:**\n\n```ts\ntextWidget('Description', 'description');\n```\n\n**YAML Configuration:**\n\n```yaml\n- label: Description\n  name: description\n  widget: text\n```\n\n**Data Store YAML:**\n\n```yaml\ndescription: |-\n  This is a longer description that spans\n  multiple lines in the data store.\n```\n\nUnlike the `stringWidget` which provides single-line input, the text widget is designed for paragraphs and multi-line content.\n\n```ts\noptional(textWidget('Notes', 'notes'));\n```\n\n**See also:** [`stringWidget`](#stringwidgetlabel-name-opts), [`markdownWidget`](#markdownwidgetlabel-name-opts)\n**Learn more:** [DecapCMS Text Widget Docs](https://decapcms.org/docs/widgets/#text)\n\n##### `numberWidget(label, name, opts?)`\n\nCreates a numeric input field with optional min, max, and step constraints.\n\n**TypeScript:**\n\n```ts\nnumberWidget('Priority', 'priority');\n```\n\n**YAML Configuration:**\n\n```yaml\n- label: Priority\n  name: priority\n  widget: number\n```\n\n**Data Store YAML:**\n\n```yaml\npriority: 1\n```\n\nThe number widget provides numeric input capabilities:\n\n```ts\noptional(numberWidget('Views', 'views'));\n```\n\n**Learn more:** [DecapCMS Number Widget Docs](https://decapcms.org/docs/widgets/#number)\n\n##### `boolWidget(label, name, opts?)`\n\nCreates a checkbox input field for boolean values.\n\n**TypeScript:**\n\n```ts\nboolWidget('Published', 'published');\n```\n\n**YAML Configuration:**\n\n```yaml\n- label: Published\n  name: published\n  widget: boolean\n```\n\n**Data Store YAML:**\n\n```yaml\npublished: true\n```\n\nThe boolean widget creates a checkbox input in the editor:\n\n```ts\noptional(boolWidget('Draft', 'isDraft'));\n```\n\n**Learn more:** [DecapCMS Boolean Widget Docs](https://decapcms.org/docs/widgets/#boolean)\n\n##### `selectWidget(label, name, choices, opts?)`\n\nCreates a dropdown menu with predefined options.\n\n**TypeScript:**\n\n```ts\nselectWidget('Status', 'status', ['draft', 'published', 'archived'] as const);\n```\n\n**YAML Configuration:**\n\n```yaml\n- label: Status\n  name: status\n  widget: select\n  options:\n    - draft\n    - published\n    - archived\n```\n\n**Data Store YAML:**\n\n```yaml\nstatus: published\n```\n\nPass the choices array `as const` to get a narrowed literal union type; omit `as const` to get `string`:\n\n```ts\nconst themeField = selectWidget('Theme', 'theme', ['light', 'dark'] as const);\n// TypeScript type: \"light\" | \"dark\"\n\nconst looseField = selectWidget('Size', 'size', ['sm', 'md', 'lg']);\n// TypeScript type: string\n```\n\nThe select widget can be made optional:\n\n```ts\noptional(\n\tselectWidget('Category', 'category', [\n\t\t'tech',\n\t\t'lifestyle',\n\t\t'business',\n\t] as const),\n);\n```\n\n**Learn more:** [DecapCMS Select Widget Docs](https://decapcms.org/docs/widgets/#select)\n\n##### `imageWidget(label, name, opts?)`\n\nCreates a file upload field with image preview capabilities.\n\n**TypeScript:**\n\n```ts\nimageWidget('Featured Image', 'featuredImage');\n```\n\n**YAML Configuration:**\n\n```yaml\n- label: Featured Image\n  name: featuredImage\n  widget: image\n```\n\n**Data Store YAML:**\n\n```yaml\nfeaturedImage: /images/hero.jpg\n```\n\nThe image widget provides file upload functionality with image preview. To pass a default transformation (supported by services like Cloudinary), use the `opts` parameter to pass a `media_library` configuration:\n\n```ts\nimageWidget('Hero Image', 'hero');\noptional(imageWidget('Avatar', 'avatar'));\n```\n\n**Learn more:** [DecapCMS Image Widget Docs](https://decapcms.org/docs/widgets/#image)\n\n#### Complex widgets\n\n##### `objectWidget(label, name, fields, opts?)`\n\nGroups multiple fields together as a nested object in the data store.\n\n**TypeScript:**\n\n```ts\nobjectWidget('Author', 'author', [\n\tstringWidget('Name', 'name'),\n\tstringWidget('Email', 'email'),\n]);\n```\n\n**YAML Configuration:**\n\n```yaml\n- label: Author\n  name: author\n  widget: object\n  fields:\n    - label: Name\n      name: name\n      widget: string\n    - label: Email\n      name: email\n      widget: string\n```\n\n**Data Store YAML:**\n\n```yaml\nauthor:\n  name: Jane Doe\n  email: jane@example.com\n```\n\nThis is useful for creating structured data with related properties. Objects can be nested within lists or other objects to create complex data structures:\n\n```ts\noptional(\n\tobjectWidget('Metadata', 'metadata', [\n\t\tstringWidget('SEO Title', 'seoTitle'),\n\t\ttextWidget('Description', 'description'),\n\t]),\n);\n```\n\n**Learn more:** [DecapCMS Object Widget Docs](https://decapcms.org/docs/widgets/#object)\n\n##### `listWidget(label, name, field/fields, opts?)`\n\nCreates a list widget that can contain either single-field items or multi-field items.\n\n**Single-field list:**\n\nTypeScript:\n\n```ts\nlistWidget('Tags', 'tags', stringWidget('Tag', 'value'));\n```\n\nYAML Configuration:\n\n```yaml\n- label: Tags\n  name: tags\n  widget: list\n  field:\n    label: Tag\n    name: value\n    widget: string\n```\n\nData Store YAML:\n\n```yaml\ntags:\n  - value: React\n  - value: TypeScript\n```\n\n**Multi-field list:**\n\nTypeScript:\n\n```ts\nlistWidget('Authors', 'authors', [\n\tstringWidget('Name', 'name'),\n\timageWidget('Avatar', 'avatar'),\n]);\n```\n\nYAML Configuration:\n\n```yaml\n- label: Authors\n  name: authors\n  widget: list\n  fields:\n    - label: Name\n      name: name\n      widget: string\n    - label: Avatar\n      name: avatar\n      widget: image\n```\n\nData Store YAML:\n\n```yaml\nauthors:\n  - name: Jane Doe\n    avatar: /images/jane.jpg\n  - name: John Smith\n    avatar: /images/john.jpg\n```\n\n> [!WARNING]\n>\n> When passing an Object widget (e.g., `objectWidget(...)`), this function will unwrap the object and return `Array<{ ... }>`, not `Array<T>`. This is done as a convenience so you don't have an extra layer of nesting in your data structure. For example, by unwrapping the object, you can have a list of items like this:\n>\n> ```yaml\n> listOfItems:\n>   - label: 'Item 1'\n>     value: 'Value 1'\n> ```\n>\n> If the object was not unwrapped, the data structure would look like this:\n>\n> ```yaml\n> listOfItems:\n>   - item:\n>       label: 'Item 1'\n>       value: 'Value 1'\n> ```\n>\n> If you do want the extra nesting, simply wrap the object in an array when passing it to `listWidget()`, like this:\n>\n> ```typescript\n> const nestedField = listWidget('Nested Items', 'nestedItems', [\n> \tobjectWidget('Item', 'item', [\n> \t\tstringWidget('Label', 'label'),\n> \t\tstringWidget('Value', 'value'),\n> \t]),\n> ]);\n> ```\n\nThe list widget can be made optional:\n\n```ts\noptional(listWidget('Tags', 'tags', stringWidget('Tag', 'value')));\n```\n\n**Learn more:** [DecapCMS List Widget Docs](https://decapcms.org/docs/widgets/#list)\n\n#### Markdown widget\n\n##### `markdownWidget(label, name, opts?)`\n\nCreates a rich text editor for markdown content.\n\n**TypeScript:**\n\n```ts\n// Full markdown editor\nmarkdownWidget('Content', 'content');\n\n// Restricted to bold, italic, lists, links, and quotes — no images or code blocks\nmarkdownWidget('Description', 'description', RICH_MARKDOWN);\n\n// Inline elements only: bold, italic, and links\nmarkdownWidget('Caption', 'caption', INLINE_MARKDOWN);\n```\n\n**YAML Configuration:**\n\n```yaml\n- label: Content\n  name: content\n  widget: richtext\n```\n\n**Data Store YAML:**\n\n```yaml\ncontent: |\n  # Heading\n  This is **bold** and *italic* text with [links](https://example.com).\n```\n\n**Learn more:** [DecapCMS RichText Widget Docs](https://decapcms.org/docs/widgets/#richtext-beta)\n\n#### Common options\n\nEvery factory accepts an optional last argument for [common widget options](https://decapcms.org/docs/widgets/#common-widget-options):\n\n```ts\nconst slugField = stringWidget('Slug', 'slug', {\n\trequired: true,\n\thint: 'URL-friendly identifier, e.g. my-page-title',\n\tpattern: ['^[a-z0-9-]+$', 'Lowercase letters, numbers, and hyphens only'],\n});\n```\n\n### Type inference\n\nDefine your CMS config using the widget factories and `as const`, then let `PropsByCollectionAndFile` derive a fully typed content object from it automatically.\n\n```ts\n// cms/config.ts\nimport {\n\tboolWidget,\n\timageWidget,\n\tmarkdownWidget,\n\tobjectWidget,\n\toptional,\n\tRICH_MARKDOWN,\n\tselectWidget,\n\tstringWidget,\n} from '@allejo/decap-extras';\n\nexport const config = {\n\tcollections: [\n\t\t{\n\t\t\tlabel: 'Pages',\n\t\t\tname: 'pages' as const,\n\t\t\tfiles: [\n\t\t\t\t{\n\t\t\t\t\tlabel: 'Home',\n\t\t\t\t\tname: 'home' as const,\n\t\t\t\t\tfile: 'content/home.yml',\n\t\t\t\t\tfields: [\n\t\t\t\t\t\tstringWidget('Title', 'title'),\n\t\t\t\t\t\toptional(stringWidget('Subtitle', 'subtitle')),\n\t\t\t\t\t\timageWidget('Hero Image', 'hero'),\n\t\t\t\t\t\tmarkdownWidget('Body', 'body', RICH_MARKDOWN),\n\t\t\t\t\t\tselectWidget('Theme', 'theme', ['light', 'dark'] as const),\n\t\t\t\t\t\tobjectWidget('SEO', 'seo', [\n\t\t\t\t\t\t\tstringWidget('Meta Title', 'metaTitle'),\n\t\t\t\t\t\t\toptional(stringWidget('Meta Description', 'metaDescription')),\n\t\t\t\t\t\t]),\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t],\n} as const;\n```\n\n```ts\n// components/HomePage.ts\nimport type { PropsByCollectionAndFile } from '@allejo/decap-extras';\n\nimport type { config } from '@/cms/config';\n\ntype HomePageProps = PropsByCollectionAndFile<typeof config, 'pages', 'home'>;\n// Resolves to:\n// {\n//   title: string;\n//   subtitle?: string;\n//   hero: string;\n//   body: string;\n//   theme: \"light\" | \"dark\";\n//   seo: {\n//     metaTitle: string;\n//     metaDescription?: string;\n//   };\n// }\n\nfunction render(page: HomePageProps) {\n\tconsole.log(page.title); // string\n\tconsole.log(page.subtitle); // string | undefined\n\tconsole.log(page.theme); // \"light\" | \"dark\"\n\tconsole.log(page.seo.metaTitle); // string\n}\n```\n\n#### Typing reusable widget functions\n\nUse `WidgetTypeFromFactory` to derive a TypeScript type from a widget factory function without duplicating the definition.\n\n```ts\nimport type { WidgetTypeFromFactory } from '@allejo/decap-extras';\nimport { objectWidget, optional, stringWidget } from '@allejo/decap-extras';\n\nfunction seoWidget() {\n\treturn objectWidget('SEO', 'seo', [\n\t\tstringWidget('Meta Title', 'metaTitle'),\n\t\toptional(stringWidget('Meta Description', 'metaDescription')),\n\t]);\n}\n\ntype SeoWidget = WidgetTypeFromFactory<typeof seoWidget>;\n// { metaTitle: string; metaDescription?: string }\n```\n\n#### Constraining to valid file names\n\nUse `CollectionItemNames` to get a union of all file name literals for a collection. This is useful for constraining generic components or functions that accept a page name.\n\n```ts\nimport type { CollectionItemNames } from '@allejo/decap-extras';\n\nimport type { config } from '@/cms/config';\n\ntype PageName = CollectionItemNames<typeof config, 'pages'>;\n// \"home\" | \"about\" | ...\n\nfunction getPageProps<F extends PageName>(\n\tpage: F,\n): PropsByCollectionAndFile<typeof config, 'pages', F> {\n\t// ...\n}\n```\n\n## React Integration\n\nDecap CMS is distributed either as [a single `.js` bundle you can load in an HTML file with `<script>` or as an ESM module you can import](https://decapcms.org/docs/install-decap-cms/). In order to integrate type-safety into working with Decap, we want to incorporate Decap CMS as a Next.js page so that we can get all the type-safety from working within it as a framework. There's one small problem with this though...\n\n> You can also use Decap CMS as an npm module. Wherever you import Decap CMS, it automatically runs, taking over the current page.\n\nThis means, we can't just import Decap CMS in a Next.js page and call it a day. This is because at build time, Next.js will run the code in the page to generate the static HTML, and if Decap CMS is imported and initialized at that time, it's going to try to take over the page during the build process, which is not what we want. We only want Decap CMS to take over the page when it's running in the browser.\n\nTo work around this, we can use [dynamic imports (i.e., `import()`)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/import) inside a `useEffect` hook to initialize Decap CMS only on the client after the Next.js boilerplate has rendered and allow the CMS instance to take over the page.\n\n```tsx\nuseEffect(() => {\n\tPromise.all([\n\t\timport('decap-cms-app'),\n\n\t\t// You can import other Decap CMS modules\n\t\t// import('decap-cms-media-library-cloudinary')\n\t]).then(([cmsMod /*, cloudinaryMod*/]) => {\n\t\tconst cms = cmsMod.default;\n\t\tconst cloudinary = cloudinaryMod.default;\n\n\t\tcms.init({ config });\n\n\t\t// ...\n\t\t// cms.registerPreviewStyle(...)\n\t\t// cms.registerPreviewTemplate(...);\n\t\t// cms.registerWidget(...);\n\t\t// cms.registerMediaLibrary(cloudinary);\n\t});\n}, []);\n```\n\n> The import() syntax, commonly called dynamic import, is a function-like expression that allows loading an ECMAScript module asynchronously and dynamically into a potentially non-module environment.\n\nIs there a more elegant solution to this problem? I'm not sure! If you can think of one, I would gladly welcome the idea.\n\nBut knowing all of this and setting it up gets tedious and boilerplate-y really fast. So, in this package, we export a React component called `DecapInstance` that abstracts away all of this dynamic importing and initialization logic, so you can just use it as a wrapper around your admin page and pass in your config, preview styles, templates, widgets, and Cloudinary flag as props.\n\n### The `<DecapInstance />` Component\n\nWe provide a React component called `DecapInstance` that handles the dynamic import and initialization of Decap CMS for you.\n\n```tsx\nimport type { PropsByCollectionAndFile } from '@allejo/decap-extras';\nimport { getCssFilesFromManifest } from '@allejo/decap-extras/next';\nimport { DecapInstance } from '@allejo/decap-extras/react';\nimport type { ComponentType } from 'react';\n\nimport type { cmsConfig } from '@/cms/config';\n\n// The HomePageProps type and HomePreview component are normally imported from\n// other files, but are included here inline for demonstration purposes.\ntype HomePageProps = PropsByCollectionAndFile<\n\ttypeof cmsConfig,\n\t'pages',\n\t'home'\n>;\nfunction HomePreview(props: HomePageProps) {\n\treturn (\n\t\t<article>\n\t\t\t<h1>{props.title}</h1>\n\t\t\t{props.subtitle ? <p>{props.subtitle}</p> : null}\n\t\t</article>\n\t);\n}\n\ntype AdminProps = {\n\tcssFiles: string[];\n};\n\nexport async function getStaticProps() {\n\tconst css = getCssFilesFromManifest(process.env.NODE_ENV ?? 'development', [\n\t\t'/',\n\t\t'/_app',\n\t]);\n\n\treturn {\n\t\tprops: {\n\t\t\tcssFiles: css.flattenedCssFiles,\n\t\t},\n\t};\n}\n\nexport default function Admin({ cssFiles }: AdminProps) {\n\treturn (\n\t\t<DecapInstance\n\t\t\tconfig={cmsConfig}\n\t\t\tcssFiles={cssFiles}\n\t\t\t// Pass explicitly so media-library behavior is visible in admin setup.\n\t\t\tuseCloudinary={true}\n\t\t\tpages={{\n\t\t\t\thome: HomePreview as unknown as ComponentType<never>,\n\t\t\t}}\n\t\t\twidgets={{}}\n\t\t\tonInit={(cms) => {\n\t\t\t\tconsole.log('Decap initialized', cms);\n\t\t\t}}\n\t\t/>\n\t);\n}\n```\n\n### How it Works\n\n`getCssFilesFromManifest` reads Next.js's `.next/build-manifest.json` at build time and returns all CSS files associated with the `/` and `/_app` routes. These are passed as props to the admin page so that we can [register the CSS files into Decap's preview functionality](https://decapcms.org/docs/customization/#registerpreviewstyle).\n\n```ts\nexport async function getStaticProps() {\n\tconst cssFiles = getCssFilesFromManifest(process.env.NODE_ENV, [\n\t\t'/',\n\t\t'/_app',\n\t]);\n\treturn { props: { cssFiles: cssFiles['flattenedCssFiles'] } };\n}\n```\n\n> [!WARNING]\n>\n> This is a bit of a hacky solution to get the CSS files and therefore has some known issues.\n>\n> The CSS for a page might not exist during local development because Next.js only generates the build manifest as the pages are requested. Therefore, if launch `next dev` and immediately open the admin page, the CSS files won't be found for the homepage (i.e., `/`) and won't be registered in the CMS preview, resulting in an unstyled preview. To work around this, you can either visit the homepage first to trigger the generation of the CSS files in the manifest, or run `next build` to generate the manifest with all CSS files before running `next dev`. During local development, this function will check the dev manifest at `.next/dev/build-manifest.json` first, and fallback to the regular manifest at `.next/build-manifest.json` if the dev manifest doesn't exist, so it should work in either case as long as the CSS files have been recorded.\n>\n> If you have a better idea of handling this, please reach out!\n\n#### Initialization sequence inside `useEffect`\n\n```ts\ncms.init({ config });\n```\n\nBootstraps the CMS with the config from `src/cms/config.ts`.\n\n```ts\ncssFiles.forEach((css) => cms.registerPreviewStyle(css));\n```\n\nRegisters every collected CSS file with the CMS preview panel so the editor renders with production styles.\n\n> [!WARNING]\n>\n> **FIXME**: There HAS to be a better way of handling this so that we only load the relevant stylesheets for specific previews. I'm not sure how to solve this yet, but I'll come back to it.\n\n```ts\ncms.registerPreviewTemplate(pageId, ({ entry }) => {\n  return <Component {...entry.get('data').toJSON()} />;\n});\n```\n\nMaps each CMS page entry (`home`, etc.) to its real Next.js page component, passing the editor's live data as props. Editors see the actual production component rendering their changes in real time.\n\n```ts\ncms.registerMediaLibrary(cloudinary);\n```\n\nRegisters the Cloudinary media picker.\n\n> [!WARNING]\n>\n> Being able to _disable_ Cloudinary is a work-in-progress. I've always needed it for the projects I'm building so it's enabled by default. I'll get to respecting the \"disable\" environment variable... eventually.\n\n## Next.js utilities\n\nA server-side utility for getting CSS from Next.js build manifests. This is useful for registering CSS stylesheets into Decap's CMS preview system.\n\n```ts\nimport { getCssFilesFromManifest } from '@allejo/decap-extras/next';\n```\n\nUse `getCssFilesFromManifest` in `getStaticProps` to collect the CSS paths needed by your page and pass them as props:\n\n```ts\nexport async function getStaticProps() {\n\tconst cssFiles = getCssFilesFromManifest(process.env.NODE_ENV, [\n\t\t'/',\n\t\t'/_app',\n\t]);\n\n\treturn {\n\t\tprops: {\n\t\t\tcssFiles: cssFiles['flattenedCssFiles'],\n\t\t},\n\t};\n}\n```\n\nThen register each path as a preview stylesheet in your Decap CMS admin component:\n\n```ts\nexport default function Admin({ cssFiles }: Props) {\n\t// ...\n\n\tcssFiles.forEach((css) => {\n\t\tcms.registerPreviewStyle(css);\n\t});\n}\n```\n\n## API reference\n\n### Widget API reference\n\n#### Widget modifiers\n\n| Function           | Description                                                                                                             |\n| ------------------ | ----------------------------------------------------------------------------------------------------------------------- |\n| `optional(widget)` | Marks a widget field as optional (non-required). [Learn more](https://decapcms.org/docs/widgets/#common-widget-options) |\n\n#### Primitive widgets\n\n| Function                                    | Decap widget                                            | TypeScript type           |\n| ------------------------------------------- | ------------------------------------------------------- | ------------------------- |\n| `stringWidget(label, name, opts?)`          | [`string`](https://decapcms.org/docs/widgets/#string)   | `string`                  |\n| `textWidget(label, name, opts?)`            | [`text`](https://decapcms.org/docs/widgets/#text)       | `string`                  |\n| `numberWidget(label, name, opts?)`          | [`number`](https://decapcms.org/docs/widgets/#number)   | `number`                  |\n| `boolWidget(label, name, opts?)`            | [`boolean`](https://decapcms.org/docs/widgets/#boolean) | `boolean`                 |\n| `selectWidget(label, name, choices, opts?)` | [`select`](https://decapcms.org/docs/widgets/#select)   | literal union or `string` |\n| `imageWidget(label, name, opts?)`           | [`image`](https://decapcms.org/docs/widgets/#image)     | `string`                  |\n\n#### Complex widgets\n\n| Function                                     | Decap widget                                          | TypeScript type  |\n| -------------------------------------------- | ----------------------------------------------------- | ---------------- |\n| `listWidget(label, name, field, opts?)`      | [`list`](https://decapcms.org/docs/widgets/#list)     | `Array<T>`       |\n| `listWidget(label, name, fields[], opts?)`   | [`list`](https://decapcms.org/docs/widgets/#list)     | `Array<{ ... }>` |\n| `objectWidget(label, name, fields[], opts?)` | [`object`](https://decapcms.org/docs/widgets/#object) | `{ ... }`        |\n\n#### Rich text widgets\n\n| Function                             | Decap widget                                                   | TypeScript type |\n| ------------------------------------ | -------------------------------------------------------------- | --------------- |\n| `markdownWidget(label, name, opts?)` | [`richtext`](https://decapcms.org/docs/widgets/#richtext-beta) | `string`        |\n\n### Markdown presets\n\n| Constant          | Description                                                                                                                                                     |\n| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `RICH_MARKDOWN`   | Stripped down markdown editor with bold, italic, lists (bullet + numbered), quotes, and links. No images or code blocks. Rich Text preview only.                |\n| `INLINE_MARKDOWN` | Stripped down markdown widget that allows only inline elements (bold, italic, and links). No block-level elements like lists or quotes. Rich Text preview only. |\n\n### Type utilities\n\n| Type                                      | Description                                                                          |\n| ----------------------------------------- | ------------------------------------------------------------------------------------ |\n| `PropsByCollectionAndFile<TConfig, C, F>` | Derives a typed content object from a CMS config for collection `C` and file `F`.    |\n| `CollectionItemNames<TConfig, C>`         | Union of all file name literals defined in collection `C`.                           |\n| `WidgetTypeFromFactory<F>`                | Returns the TypeScript content type produced by a widget factory function `F`.       |\n| `OptionalWidget<T>`                       | Brands a `CmsField` as optional (added by `optional()`).                             |\n| `WidgetOpts<T>`                           | The options type for a given widget field type, with `widget` and `fields` stripped. |\n\n### Server utilities\n\n| Function                              | Description                                                                                                                                                              |\n| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `getCssFilesFromManifest(env, pages)` | Reads the Next.js build manifest and returns CSS paths for the given page routes, grouped by page (`allCssFiles`) and as a deduplicated flat list (`flattenedCssFiles`). |\n\n### React utilities\n\n| Type/Function        | Description                                                                                                                                              |\n| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `DecapInstance`      | React component that initializes Decap CMS, registers preview CSS/templates/widgets, optionally enables Cloudinary, and returns `null` after setup.      |\n| `DecapInstanceProps` | Props contract for `DecapInstance`, including config, preview CSS paths, page template registry, widget registry, and optional `onInit`/`useCloudinary`. |\n\n## License\n\nMIT\n","readmeFilename":"README.md"}