{"_id":"@bonniernews/json-templates","_rev":"14-83f6618918d8f1c81eacb2a71e5b23af","name":"@bonniernews/json-templates","dist-tags":{"latest":"0.2.0"},"versions":{"0.0.1":{"name":"@bonniernews/json-templates","version":"0.0.1","keywords":["JSON","templates"],"author":{"name":"Bonnier News"},"license":"MIT","_id":"@bonniernews/json-templates@0.0.1","maintainers":[{"name":"markusn","email":"markus@botten.org"},{"name":"mxtr","email":"max.olofsson@bonniernews.se"},{"name":"matsrorbecker","email":"mats@rorbecker.com"},{"name":"dan.karlsson","email":"dan.karlsson@bonniernews.se"},{"name":"jonaswalden","email":"jonas.waldeen@gmail.com"},{"name":"marie-winther","email":"marie.winther@bonniernews.se"},{"name":"marcusgronblad","email":"marcus.gronblad@bonniernews.se"},{"name":"axeljohanssonbonniernews","email":"axel.johansson@bonniernews.se"},{"name":"karlbergc","email":"christoffer.karlberg@bonniernews.se"},{"name":"chavah","email":"chavah.forler@bonniernews.se"},{"name":"joelekman","email":"joel.ekman@bonniernews.se"},{"name":"adam.hakansson","email":"adam.hakansson@bonniernews.se"},{"name":"hilleso","email":"marcus.hilleso@expressen.se"},{"name":"gusliden","email":"gusliden@gmail.com"},{"name":"andreas.samuelsson","email":"andreas.samuelsson@bonniernews.se"},{"name":"jzachrisson","email":"jesper.zachrisson@bonniernews.se"},{"name":"norla","email":"mattias.norlander@gmail.com"},{"name":"varneynz","email":"simon.varney@bonniernews.se"},{"name":"aliceboberg","email":"alice.boberg@bonniernews.se"},{"name":"johark","email":"johan.arkad@bonniernews.se"},{"name":"nifo","email":"niklas.forsstrom@bonniernews.se"},{"name":"herbola","email":"herman.jansson@bonniernews.se"},{"name":"vitryssen","email":"andre.nordlund@bonniernews.se"},{"name":"takolander","email":"william.takolander@bonniernews.se"},{"name":"morre","email":"marten.persson@hdsydsvenskan.se"},{"name":"mikael.mattsson","email":"mikael.mattsson@bonniernews.se"},{"name":"schristianssonbn","email":"seb.christiansson@bonniernews.se"},{"name":"mattiasobn","email":"mattias.olla@bonniernews.se"},{"name":"daghall","email":"markus@daghall.se"},{"name":"erandersson","email":"ericandersson1@gmail.com"},{"name":"jonaek","email":"jonathan.ek@bonniernews.se"},{"name":"amundsentb","email":"amundsentb@gmail.com"},{"name":"drgeobn","email":"daniel.rasmussen@bonniernews.se"},{"name":"oscartholander","email":"oscar@tholander.nu"},{"name":"peterpettersson","email":"peter.pettersson@bonniernews.se"},{"name":"liroliro","email":"basistoscar@gmail.com"},{"name":"ollenolle","email":"olle.nordin@bonniernews.se"},{"name":"torkelberget","email":"andreas.egneblad@bonniernews.se"},{"name":"nblom","email":"niklas.blom@bonniernews.se"},{"name":"jackesa","email":"jakob.pedersen@bonniernews.se"},{"name":"emilbjorklund","email":"emil@thatemil.com"},{"name":"lilianj","email":"japlilian@gmail.com"},{"name":"kristofferjansson","email":"kristoffer.jansson@bonniernews.se"},{"name":"kitgus","email":"kit.gustavsson@bonniernews.se"},{"name":"odynvolk","email":"alexi.rahman@r76.se"}],"homepage":"https://github.com/BonnierNews/json-templates#readme","bugs":{"url":"https://github.com/BonnierNews/json-templates/issues"},"dist":{"shasum":"c8289010663ca137c7290608e24d13fdf8ff32cd","tarball":"https://registry.npmjs.org/@bonniernews/json-templates/-/json-templates-0.0.1.tgz","fileCount":9,"integrity":"sha512-BAHvFIAwY23g8ZAxZS7EaJRGsd68c7LUG4ufdoMb7Rhdrc/sP6V/ONuHjromXFWAxvxc5q6WlYX6ChJn9tUE9g==","signatures":[{"sig":"MEUCIQD/KJj2jEuogZhbr/Ag10jYDjWyoLrdjJ+1W2U7wFIpvgIgZNA9iHiJZXLUn871Z32KlThR9sX8z3r3O8Nz4sjuABc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":15406},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{"import":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","require":"./dist/index.cjs"}},"gitHead":"85c656b852db7f275a041ea9393f2daaef444ffc","scripts":{"lint":"eslint . --cache && npm run typecheck","test":"mocha --exit --reporter ${REPORTER:-spec}","build":"tsup","format":"prettier --write . && npm run lint:fix","coverage":"c8 npm test && c8 check-coverage","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","local-coverage":"c8 --reporter html npm test && c8 check-coverage || open ./coverage/index.html","prepublishOnly":"npm run build"},"_npmUser":{"name":"herbola","email":"herman.jansson@bonniernews.se"},"repository":{"url":"git+https://github.com/BonnierNews/json-templates.git","type":"git"},"_npmVersion":"10.9.3","description":"Completes incomplete JSON string with caching capabilites","directories":{},"_nodeVersion":"22.20.0","dependencies":{"json-templates":"^5.2.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","tsx":"^4.19.1","chai":"^5.1.1","tsup":"^8.3.5","mocha":"^11.0.0","eslint":"^8.57.1","prettier":"^3.3.3","typescript":"^5.6.3","@types/chai":"^5.0.0","@types/node":"^22.9.0","@types/mocha":"^10.0.10","@types/sinon":"^17.0.3","mocha-cakes-2":"^3.3.0","typescript-eslint":"^8.13.0","@bonniernews/tsconfig":"^0.0.2","@types/json-templates":"^3.0.3","@bonniernews/eslint-config":"^1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/json-templates_0.0.1_1773154859102_0.010793662060957887","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@bonniernews/json-templates","version":"0.0.2","keywords":["JSON","templates"],"author":{"name":"Bonnier News"},"license":"MIT","_id":"@bonniernews/json-templates@0.0.2","maintainers":[{"name":"markusn","email":"markus@botten.org"},{"name":"mxtr","email":"max.olofsson@bonniernews.se"},{"name":"matsrorbecker","email":"mats@rorbecker.com"},{"name":"dan.karlsson","email":"dan.karlsson@bonniernews.se"},{"name":"jonaswalden","email":"jonas.waldeen@gmail.com"},{"name":"marie-winther","email":"marie.winther@bonniernews.se"},{"name":"marcusgronblad","email":"marcus.gronblad@bonniernews.se"},{"name":"axeljohanssonbonniernews","email":"axel.johansson@bonniernews.se"},{"name":"karlbergc","email":"christoffer.karlberg@bonniernews.se"},{"name":"chavah","email":"chavah.forler@bonniernews.se"},{"name":"joelekman","email":"joel.ekman@bonniernews.se"},{"name":"adam.hakansson","email":"adam.hakansson@bonniernews.se"},{"name":"hilleso","email":"marcus.hilleso@expressen.se"},{"name":"gusliden","email":"gusliden@gmail.com"},{"name":"andreas.samuelsson","email":"andreas.samuelsson@bonniernews.se"},{"name":"jzachrisson","email":"jesper.zachrisson@bonniernews.se"},{"name":"norla","email":"mattias.norlander@gmail.com"},{"name":"varneynz","email":"simon.varney@bonniernews.se"},{"name":"aliceboberg","email":"alice.boberg@bonniernews.se"},{"name":"johark","email":"johan.arkad@bonniernews.se"},{"name":"nifo","email":"niklas.forsstrom@bonniernews.se"},{"name":"herbola","email":"herman.jansson@bonniernews.se"},{"name":"vitryssen","email":"andre.nordlund@bonniernews.se"},{"name":"takolander","email":"william.takolander@bonniernews.se"},{"name":"morre","email":"marten.persson@hdsydsvenskan.se"},{"name":"mikael.mattsson","email":"mikael.mattsson@bonniernews.se"},{"name":"schristianssonbn","email":"seb.christiansson@bonniernews.se"},{"name":"mattiasobn","email":"mattias.olla@bonniernews.se"},{"name":"daghall","email":"markus@daghall.se"},{"name":"erandersson","email":"ericandersson1@gmail.com"},{"name":"jonaek","email":"jonathan.ek@bonniernews.se"},{"name":"amundsentb","email":"amundsentb@gmail.com"},{"name":"drgeobn","email":"daniel.rasmussen@bonniernews.se"},{"name":"oscartholander","email":"oscar@tholander.nu"},{"name":"peterpettersson","email":"peter.pettersson@bonniernews.se"},{"name":"liroliro","email":"basistoscar@gmail.com"},{"name":"ollenolle","email":"olle.nordin@bonniernews.se"},{"name":"torkelberget","email":"andreas.egneblad@bonniernews.se"},{"name":"nblom","email":"niklas.blom@bonniernews.se"},{"name":"jackesa","email":"jakob.pedersen@bonniernews.se"},{"name":"emilbjorklund","email":"emil@thatemil.com"},{"name":"lilianj","email":"japlilian@gmail.com"},{"name":"kristofferjansson","email":"kristoffer.jansson@bonniernews.se"},{"name":"kitgus","email":"kit.gustavsson@bonniernews.se"},{"name":"odynvolk","email":"alexi.rahman@r76.se"}],"homepage":"https://github.com/BonnierNews/json-templates#readme","bugs":{"url":"https://github.com/BonnierNews/json-templates/issues"},"dist":{"shasum":"fd4af23126e5a9d3c3b8455052f8782d9db20792","tarball":"https://registry.npmjs.org/@bonniernews/json-templates/-/json-templates-0.0.2.tgz","fileCount":9,"integrity":"sha512-PJC5eBaV4P0YhAaJ2UbW60RNcf9p3k87+ORQ5Ns/0TF2FELUf7JdQ4Os1GC0DGXLrqzRIJsmIo6WE5Fn9K2Qqw==","signatures":[{"sig":"MEUCIBYuHagLGuFFy4dWRg8ggVwTvul5ILg8PV42elqIWYuOAiEAx0N0c/UFFNRtWeXAD2PxWOW8cYVlIl/Ao8qf9Qwx7Mo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":14651},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{"import":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","require":"./dist/index.cjs"}},"gitHead":"03f5e22d97a7cf527035817cf123773acd805954","scripts":{"lint":"eslint . --cache && npm run typecheck","test":"mocha --exit --reporter ${REPORTER:-spec}","build":"tsup","format":"prettier --write . && npm run lint:fix","coverage":"c8 npm test && c8 check-coverage","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","local-coverage":"c8 --reporter html npm test && c8 check-coverage || open ./coverage/index.html","prepublishOnly":"npm run build"},"_npmUser":{"name":"herbola","email":"herman.jansson@bonniernews.se"},"repository":{"url":"git+https://github.com/BonnierNews/json-templates.git","type":"git"},"_npmVersion":"10.9.3","description":"Completes incomplete JSON string with caching capabilites","directories":{},"_nodeVersion":"22.20.0","dependencies":{"json-templates":"^5.2.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","tsx":"^4.19.1","chai":"^5.1.1","tsup":"^8.3.5","mocha":"^11.0.0","eslint":"^8.57.1","prettier":"^3.3.3","typescript":"^5.6.3","@types/chai":"^5.0.0","@types/node":"^22.9.0","@types/mocha":"^10.0.10","@types/sinon":"^17.0.3","mocha-cakes-2":"^3.3.0","typescript-eslint":"^8.13.0","@bonniernews/tsconfig":"^0.0.2","@types/json-templates":"^3.0.3","@bonniernews/eslint-config":"^1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/json-templates_0.0.2_1773155218171_0.37012754933012837","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@bonniernews/json-templates","version":"0.0.3","keywords":["JSON","templates"],"author":{"name":"Bonnier News"},"license":"MIT","_id":"@bonniernews/json-templates@0.0.3","maintainers":[{"name":"markusn","email":"markus@botten.org"},{"name":"mxtr","email":"max.olofsson@bonniernews.se"},{"name":"matsrorbecker","email":"mats@rorbecker.com"},{"name":"dan.karlsson","email":"dan.karlsson@bonniernews.se"},{"name":"jonaswalden","email":"jonas.waldeen@gmail.com"},{"name":"marie-winther","email":"marie.winther@bonniernews.se"},{"name":"marcusgronblad","email":"marcus.gronblad@bonniernews.se"},{"name":"axeljohanssonbonniernews","email":"axel.johansson@bonniernews.se"},{"name":"karlbergc","email":"christoffer.karlberg@bonniernews.se"},{"name":"chavah","email":"chavah.forler@bonniernews.se"},{"name":"joelekman","email":"joel.ekman@bonniernews.se"},{"name":"adam.hakansson","email":"adam.hakansson@bonniernews.se"},{"name":"hilleso","email":"marcus.hilleso@expressen.se"},{"name":"gusliden","email":"gusliden@gmail.com"},{"name":"andreas.samuelsson","email":"andreas.samuelsson@bonniernews.se"},{"name":"jzachrisson","email":"jesper.zachrisson@bonniernews.se"},{"name":"norla","email":"mattias.norlander@gmail.com"},{"name":"varneynz","email":"simon.varney@bonniernews.se"},{"name":"aliceboberg","email":"alice.boberg@bonniernews.se"},{"name":"johark","email":"johan.arkad@bonniernews.se"},{"name":"nifo","email":"niklas.forsstrom@bonniernews.se"},{"name":"herbola","email":"herman.jansson@bonniernews.se"},{"name":"vitryssen","email":"andre.nordlund@bonniernews.se"},{"name":"takolander","email":"william.takolander@bonniernews.se"},{"name":"morre","email":"marten.persson@hdsydsvenskan.se"},{"name":"mikael.mattsson","email":"mikael.mattsson@bonniernews.se"},{"name":"schristianssonbn","email":"seb.christiansson@bonniernews.se"},{"name":"mattiasobn","email":"mattias.olla@bonniernews.se"},{"name":"daghall","email":"markus@daghall.se"},{"name":"erandersson","email":"ericandersson1@gmail.com"},{"name":"jonaek","email":"jonathan.ek@bonniernews.se"},{"name":"amundsentb","email":"amundsentb@gmail.com"},{"name":"drgeobn","email":"daniel.rasmussen@bonniernews.se"},{"name":"oscartholander","email":"oscar@tholander.nu"},{"name":"peterpettersson","email":"peter.pettersson@bonniernews.se"},{"name":"liroliro","email":"basistoscar@gmail.com"},{"name":"ollenolle","email":"olle.nordin@bonniernews.se"},{"name":"torkelberget","email":"andreas.egneblad@bonniernews.se"},{"name":"nblom","email":"niklas.blom@bonniernews.se"},{"name":"jackesa","email":"jakob.pedersen@bonniernews.se"},{"name":"emilbjorklund","email":"emil@thatemil.com"},{"name":"lilianj","email":"japlilian@gmail.com"},{"name":"kristofferjansson","email":"kristoffer.jansson@bonniernews.se"},{"name":"kitgus","email":"kit.gustavsson@bonniernews.se"},{"name":"odynvolk","email":"alexi.rahman@r76.se"}],"homepage":"https://github.com/BonnierNews/json-templates#readme","bugs":{"url":"https://github.com/BonnierNews/json-templates/issues"},"dist":{"shasum":"c6f12b641561e1dc32bd43e6fe74510a5ee0fe29","tarball":"https://registry.npmjs.org/@bonniernews/json-templates/-/json-templates-0.0.3.tgz","fileCount":9,"integrity":"sha512-QBnAod9i2p8QR6DI7dsNvrh6WWqjKzSr6eU6p69V2vinAJMGVDrqO8kfruFaLyId6qvY4KjVU5TRr2UU9B74Dw==","signatures":[{"sig":"MEYCIQDJvmvciDtVY0BXTlhaYd6fKPBNHNv1SpYIvRJ7G5wfFQIhAMPyKPd80rFMFbKwDhRw+jeRFr7bP2WrB47hhI/q8uWG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23112},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{"import":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","require":"./dist/index.cjs"}},"gitHead":"5a4c140254d7222ccca559d0c012ec844df47474","scripts":{"lint":"eslint . --cache && npm run typecheck","test":"mocha --exit --reporter ${REPORTER:-spec}","build":"tsup","format":"prettier --write . && npm run lint:fix","coverage":"c8 npm test && c8 check-coverage","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","local-coverage":"c8 --reporter html npm test && c8 check-coverage || open ./coverage/index.html","prepublishOnly":"npm run build"},"_npmUser":{"name":"jackesa","email":"jakob.pedersen@bonniernews.se"},"repository":{"url":"git+https://github.com/BonnierNews/json-templates.git","type":"git"},"_npmVersion":"10.9.4","description":"Completes incomplete JSON string with caching capabilites","directories":{},"_nodeVersion":"22.21.1","dependencies":{"json-templates":"^5.2.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","tsx":"^4.19.1","chai":"^5.1.1","tsup":"^8.3.5","mocha":"^11.0.0","eslint":"^8.57.1","prettier":"^3.3.3","typescript":"^5.6.3","@types/chai":"^5.0.0","@types/node":"^22.9.0","@types/mocha":"^10.0.10","@types/sinon":"^17.0.3","mocha-cakes-2":"^3.3.0","typescript-eslint":"^8.13.0","@bonniernews/tsconfig":"^0.0.2","@types/json-templates":"^3.0.3","@bonniernews/eslint-config":"^1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/json-templates_0.0.3_1774019721227_0.6188416567309605","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@bonniernews/json-templates","version":"0.1.0","keywords":["JSON","templates"],"author":{"name":"Bonnier News"},"license":"MIT","_id":"@bonniernews/json-templates@0.1.0","maintainers":[{"name":"markusn","email":"markus@botten.org"},{"name":"mxtr","email":"max.olofsson@bonniernews.se"},{"name":"matsrorbecker","email":"mats@rorbecker.com"},{"name":"dan.karlsson","email":"dan.karlsson@bonniernews.se"},{"name":"jonaswalden","email":"jonas.waldeen@gmail.com"},{"name":"marie-winther","email":"marie.winther@bonniernews.se"},{"name":"marcusgronblad","email":"marcus.gronblad@bonniernews.se"},{"name":"axeljohanssonbonniernews","email":"axel.johansson@bonniernews.se"},{"name":"karlbergc","email":"christoffer.karlberg@bonniernews.se"},{"name":"chavah","email":"chavah.forler@bonniernews.se"},{"name":"joelekman","email":"joel.ekman@bonniernews.se"},{"name":"adam.hakansson","email":"adam.hakansson@bonniernews.se"},{"name":"hilleso","email":"marcus.hilleso@expressen.se"},{"name":"gusliden","email":"gusliden@gmail.com"},{"name":"andreas.samuelsson","email":"andreas.samuelsson@bonniernews.se"},{"name":"jzachrisson","email":"jesper.zachrisson@bonniernews.se"},{"name":"norla","email":"mattias.norlander@gmail.com"},{"name":"varneynz","email":"simon.varney@bonniernews.se"},{"name":"aliceboberg","email":"alice.boberg@bonniernews.se"},{"name":"johark","email":"johan.arkad@bonniernews.se"},{"name":"nifo","email":"niklas.forsstrom@bonniernews.se"},{"name":"herbola","email":"herman.jansson@bonniernews.se"},{"name":"vitryssen","email":"andre.nordlund@bonniernews.se"},{"name":"takolander","email":"william.takolander@bonniernews.se"},{"name":"morre","email":"marten.persson@hdsydsvenskan.se"},{"name":"mikael.mattsson","email":"mikael.mattsson@bonniernews.se"},{"name":"schristianssonbn","email":"seb.christiansson@bonniernews.se"},{"name":"mattiasobn","email":"mattias.olla@bonniernews.se"},{"name":"daghall","email":"markus@daghall.se"},{"name":"erandersson","email":"ericandersson1@gmail.com"},{"name":"jonaek","email":"jonathan.ek@bonniernews.se"},{"name":"amundsentb","email":"amundsentb@gmail.com"},{"name":"drgeobn","email":"daniel.rasmussen@bonniernews.se"},{"name":"oscartholander","email":"oscar@tholander.nu"},{"name":"peterpettersson","email":"peter.pettersson@bonniernews.se"},{"name":"liroliro","email":"basistoscar@gmail.com"},{"name":"ollenolle","email":"olle.nordin@bonniernews.se"},{"name":"torkelberget","email":"andreas.egneblad@bonniernews.se"},{"name":"nblom","email":"niklas.blom@bonniernews.se"},{"name":"jackesa","email":"jakob.pedersen@bonniernews.se"},{"name":"emilbjorklund","email":"emil@thatemil.com"},{"name":"lilianj","email":"japlilian@gmail.com"},{"name":"kristofferjansson","email":"kristoffer.jansson@bonniernews.se"},{"name":"kitgus","email":"kit.gustavsson@bonniernews.se"},{"name":"odynvolk","email":"alexi.rahman@r76.se"}],"homepage":"https://github.com/BonnierNews/json-templates#readme","bugs":{"url":"https://github.com/BonnierNews/json-templates/issues"},"dist":{"shasum":"2f7ae714bc78f1e9247472d534ad2f93d838fe25","tarball":"https://registry.npmjs.org/@bonniernews/json-templates/-/json-templates-0.1.0.tgz","fileCount":9,"integrity":"sha512-2zMaK36cZ9BTVtmF2Tr4vCG+iZSsAAQL66KJy76YIrmtMKHhVnvrBWu1LihINSZzSskMIntfGl9CLyqcA3iSqw==","signatures":[{"sig":"MEUCIQCefnUFmiaRY1526kj8jCZpKqtSX5GBzC16THVnqJ8kTAIgW5lcP7BRHgdAs5lCwBzaeP1cYvPA2zEabjPEFOa1Yks=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":115121},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{"import":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","require":"./dist/index.cjs"}},"gitHead":"86b777a8f3b4c51076717690643fa0b733c7ae33","scripts":{"lint":"eslint . --cache && npm run typecheck","test":"mocha --exit --reporter ${REPORTER:-spec}","build":"tsup","format":"prettier --write . && npm run lint:fix","coverage":"c8 npm test && c8 check-coverage","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","local-coverage":"c8 --reporter html npm test && c8 check-coverage || open ./coverage/index.html","prepublishOnly":"npm run build"},"_npmUser":{"name":"herbola","email":"herman.jansson@bonniernews.se"},"repository":{"url":"git+https://github.com/BonnierNews/json-templates.git","type":"git"},"_npmVersion":"10.9.3","description":"Completes incomplete JSON string with caching capabilites","directories":{},"_nodeVersion":"22.20.0","dependencies":{"json-templates":"^5.2.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","tsx":"^4.19.1","chai":"^5.1.1","tsup":"^8.3.5","mocha":"^11.0.0","eslint":"^8.57.1","prettier":"^3.3.3","typescript":"^5.6.3","@types/chai":"^5.0.0","@types/node":"^22.9.0","@types/mocha":"^10.0.10","@types/sinon":"^17.0.3","mocha-cakes-2":"^3.3.0","typescript-eslint":"^8.13.0","@bonniernews/tsconfig":"^0.0.2","@types/json-templates":"^3.0.3","@bonniernews/eslint-config":"^1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/json-templates_0.1.0_1774253116867_0.4791003753990539","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@bonniernews/json-templates","version":"0.1.1","keywords":["JSON","templates"],"author":{"name":"Bonnier News"},"license":"MIT","_id":"@bonniernews/json-templates@0.1.1","maintainers":[{"name":"markusn","email":"markus@botten.org"},{"name":"mxtr","email":"max.olofsson@bonniernews.se"},{"name":"matsrorbecker","email":"mats@rorbecker.com"},{"name":"dan.karlsson","email":"dan.karlsson@bonniernews.se"},{"name":"jonaswalden","email":"jonas.waldeen@gmail.com"},{"name":"marie-winther","email":"marie.winther@bonniernews.se"},{"name":"marcusgronblad","email":"marcus.gronblad@bonniernews.se"},{"name":"axeljohanssonbonniernews","email":"axel.johansson@bonniernews.se"},{"name":"karlbergc","email":"christoffer.karlberg@bonniernews.se"},{"name":"chavah","email":"chavah.forler@bonniernews.se"},{"name":"joelekman","email":"joel.ekman@bonniernews.se"},{"name":"adam.hakansson","email":"adam.hakansson@bonniernews.se"},{"name":"hilleso","email":"marcus.hilleso@expressen.se"},{"name":"gusliden","email":"gusliden@gmail.com"},{"name":"andreas.samuelsson","email":"andreas.samuelsson@bonniernews.se"},{"name":"jzachrisson","email":"jesper.zachrisson@bonniernews.se"},{"name":"norla","email":"mattias.norlander@gmail.com"},{"name":"varneynz","email":"simon.varney@bonniernews.se"},{"name":"aliceboberg","email":"alice.boberg@bonniernews.se"},{"name":"johark","email":"johan.arkad@bonniernews.se"},{"name":"nifo","email":"niklas.forsstrom@bonniernews.se"},{"name":"herbola","email":"herman.jansson@bonniernews.se"},{"name":"vitryssen","email":"andre.nordlund@bonniernews.se"},{"name":"takolander","email":"william.takolander@bonniernews.se"},{"name":"morre","email":"marten.persson@hdsydsvenskan.se"},{"name":"mikael.mattsson","email":"mikael.mattsson@bonniernews.se"},{"name":"schristianssonbn","email":"seb.christiansson@bonniernews.se"},{"name":"mattiasobn","email":"mattias.olla@bonniernews.se"},{"name":"daghall","email":"markus@daghall.se"},{"name":"erandersson","email":"ericandersson1@gmail.com"},{"name":"jonaek","email":"jonathan.ek@bonniernews.se"},{"name":"amundsentb","email":"amundsentb@gmail.com"},{"name":"drgeobn","email":"daniel.rasmussen@bonniernews.se"},{"name":"oscartholander","email":"oscar@tholander.nu"},{"name":"peterpettersson","email":"peter.pettersson@bonniernews.se"},{"name":"liroliro","email":"basistoscar@gmail.com"},{"name":"ollenolle","email":"olle.nordin@bonniernews.se"},{"name":"torkelberget","email":"andreas.egneblad@bonniernews.se"},{"name":"nblom","email":"niklas.blom@bonniernews.se"},{"name":"jackesa","email":"jakob.pedersen@bonniernews.se"},{"name":"emilbjorklund","email":"emil@thatemil.com"},{"name":"lilianj","email":"japlilian@gmail.com"},{"name":"kristofferjansson","email":"kristoffer.jansson@bonniernews.se"},{"name":"kitgus","email":"kit.gustavsson@bonniernews.se"},{"name":"odynvolk","email":"alexi.rahman@r76.se"}],"homepage":"https://github.com/BonnierNews/json-templates#readme","bugs":{"url":"https://github.com/BonnierNews/json-templates/issues"},"dist":{"shasum":"d353ca6e21d84b0c3e1dcd6212d436fe84a8d99e","tarball":"https://registry.npmjs.org/@bonniernews/json-templates/-/json-templates-0.1.1.tgz","fileCount":9,"integrity":"sha512-iy/DfxDHeZlviFEml0jiFpeNb3h53DcDX+EkVqJMAdkFxjkkwjV6aVq8+XDDh65M+Yuf2koJyDKC+KTQe6B5Gg==","signatures":[{"sig":"MEUCICgculRoVEFwEaZHLPuSDetiGmdBdaymQJ6+3nsto4q0AiEAy622Ca4y7j8w8nfbTb0Gx2d/mDzXkaAFPaOIfzvemL0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":156500},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{"import":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","require":"./dist/index.cjs"}},"gitHead":"ffd62863eb547f29092746e24a422bbfc3f00932","scripts":{"lint":"eslint . --cache && npm run typecheck","test":"mocha --exit --reporter ${REPORTER:-spec}","build":"tsup","format":"prettier --write . && npm run lint:fix","coverage":"c8 npm test && c8 check-coverage","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","local-coverage":"c8 --reporter html npm test && c8 check-coverage || open ./coverage/index.html","prepublishOnly":"npm run build"},"_npmUser":{"name":"herbola","email":"herman.jansson@bonniernews.se"},"repository":{"url":"git+https://github.com/BonnierNews/json-templates.git","type":"git"},"_npmVersion":"10.9.3","description":"Completes incomplete JSON string with caching capabilites","directories":{},"_nodeVersion":"22.20.0","dependencies":{"json-templates":"^5.2.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","tsx":"^4.19.1","chai":"^5.1.1","tsup":"^8.3.5","mocha":"^11.0.0","eslint":"^8.57.1","prettier":"^3.3.3","typescript":"^5.6.3","@types/chai":"^5.0.0","@types/node":"^22.9.0","@types/mocha":"^10.0.10","@types/sinon":"^17.0.3","mocha-cakes-2":"^3.3.0","typescript-eslint":"^8.13.0","@bonniernews/tsconfig":"^0.0.2","@types/json-templates":"^3.0.3","@bonniernews/eslint-config":"^1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/json-templates_0.1.1_1774294511006_0.9215787163395894","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bonniernews/json-templates","version":"0.1.2","keywords":["JSON","templates"],"author":{"name":"Bonnier News"},"license":"MIT","_id":"@bonniernews/json-templates@0.1.2","maintainers":[{"name":"markusn","email":"markus@botten.org"},{"name":"mxtr","email":"max.olofsson@bonniernews.se"},{"name":"matsrorbecker","email":"mats@rorbecker.com"},{"name":"dan.karlsson","email":"dan.karlsson@bonniernews.se"},{"name":"jonaswalden","email":"jonas.waldeen@gmail.com"},{"name":"marie-winther","email":"marie.winther@bonniernews.se"},{"name":"marcusgronblad","email":"marcus.gronblad@bonniernews.se"},{"name":"axeljohanssonbonniernews","email":"axel.johansson@bonniernews.se"},{"name":"karlbergc","email":"christoffer.karlberg@bonniernews.se"},{"name":"chavah","email":"chavah.forler@bonniernews.se"},{"name":"joelekman","email":"joel.ekman@bonniernews.se"},{"name":"adam.hakansson","email":"adam.hakansson@bonniernews.se"},{"name":"hilleso","email":"marcus.hilleso@expressen.se"},{"name":"gusliden","email":"gusliden@gmail.com"},{"name":"andreas.samuelsson","email":"andreas.samuelsson@bonniernews.se"},{"name":"jzachrisson","email":"jesper.zachrisson@bonniernews.se"},{"name":"norla","email":"mattias.norlander@gmail.com"},{"name":"varneynz","email":"simon.varney@bonniernews.se"},{"name":"aliceboberg","email":"alice.boberg@bonniernews.se"},{"name":"johark","email":"johan.arkad@bonniernews.se"},{"name":"nifo","email":"niklas.forsstrom@bonniernews.se"},{"name":"herbola","email":"herman.jansson@bonniernews.se"},{"name":"vitryssen","email":"andre.nordlund@bonniernews.se"},{"name":"takolander","email":"william.takolander@bonniernews.se"},{"name":"morre","email":"marten.persson@hdsydsvenskan.se"},{"name":"mikael.mattsson","email":"mikael.mattsson@bonniernews.se"},{"name":"schristianssonbn","email":"seb.christiansson@bonniernews.se"},{"name":"mattiasobn","email":"mattias.olla@bonniernews.se"},{"name":"daghall","email":"markus@daghall.se"},{"name":"erandersson","email":"ericandersson1@gmail.com"},{"name":"jonaek","email":"jonathan.ek@bonniernews.se"},{"name":"amundsentb","email":"amundsentb@gmail.com"},{"name":"drgeobn","email":"daniel.rasmussen@bonniernews.se"},{"name":"oscartholander","email":"oscar@tholander.nu"},{"name":"peterpettersson","email":"peter.pettersson@bonniernews.se"},{"name":"liroliro","email":"basistoscar@gmail.com"},{"name":"ollenolle","email":"olle.nordin@bonniernews.se"},{"name":"torkelberget","email":"andreas.egneblad@bonniernews.se"},{"name":"nblom","email":"niklas.blom@bonniernews.se"},{"name":"jackesa","email":"jakob.pedersen@bonniernews.se"},{"name":"emilbjorklund","email":"emil@thatemil.com"},{"name":"lilianj","email":"japlilian@gmail.com"},{"name":"kristofferjansson","email":"kristoffer.jansson@bonniernews.se"},{"name":"kitgus","email":"kit.gustavsson@bonniernews.se"},{"name":"odynvolk","email":"alexi.rahman@r76.se"}],"homepage":"https://github.com/BonnierNews/json-templates#readme","bugs":{"url":"https://github.com/BonnierNews/json-templates/issues"},"dist":{"shasum":"ebbafa3a63fa7bd32ac8fbdbf93e6edb07483b90","tarball":"https://registry.npmjs.org/@bonniernews/json-templates/-/json-templates-0.1.2.tgz","fileCount":9,"integrity":"sha512-QKQL8zx9txTjdrwJq3PN94av3MebkedTO8T4efrg9JouMrJwbLb8OL8Xv57Iqy8skMnlEm/GsLYVKeAsypC+Yw==","signatures":[{"sig":"MEUCIERWLMAVrpNb02wVxVvHqimzOwDXssaEycD4beKPLLZrAiEA/PzTR0TMKiLgpM9JmAai1uikpXf4+PSbNI4jWnO6A/Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":160516},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{"import":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","require":"./dist/index.cjs"}},"gitHead":"8d683ee341671e757b61c8c409011416581ee325","scripts":{"lint":"eslint . --cache && npm run typecheck","test":"mocha --exit --reporter ${REPORTER:-spec}","build":"tsup","format":"prettier --write . && npm run lint:fix","coverage":"c8 npm test && c8 check-coverage","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","local-coverage":"c8 --reporter html npm test && c8 check-coverage || open ./coverage/index.html","prepublishOnly":"npm run build"},"_npmUser":{"name":"herbola","email":"herman.jansson@bonniernews.se"},"repository":{"url":"git+https://github.com/BonnierNews/json-templates.git","type":"git"},"_npmVersion":"10.9.3","description":"Completes incomplete JSON string with caching capabilites","directories":{},"_nodeVersion":"22.20.0","dependencies":{"json-templates":"^5.2.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","tsx":"^4.19.1","chai":"^5.1.1","tsup":"^8.3.5","mocha":"^11.0.0","eslint":"^8.57.1","prettier":"^3.3.3","typescript":"^5.6.3","@types/chai":"^5.0.0","@types/node":"^22.9.0","@types/mocha":"^10.0.10","@types/sinon":"^17.0.3","mocha-cakes-2":"^3.3.0","typescript-eslint":"^8.13.0","@bonniernews/tsconfig":"^0.0.2","@types/json-templates":"^3.0.3","@bonniernews/eslint-config":"^1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/json-templates_0.1.2_1774475844761_0.02821628911527907","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@bonniernews/json-templates","version":"0.1.3","keywords":["JSON","templates"],"author":{"name":"Bonnier News"},"license":"MIT","_id":"@bonniernews/json-templates@0.1.3","maintainers":[{"name":"markusn","email":"markus@botten.org"},{"name":"mxtr","email":"max.olofsson@bonniernews.se"},{"name":"matsrorbecker","email":"mats@rorbecker.com"},{"name":"dan.karlsson","email":"dan.karlsson@bonniernews.se"},{"name":"jonaswalden","email":"jonas.waldeen@gmail.com"},{"name":"marie-winther","email":"marie.winther@bonniernews.se"},{"name":"marcusgronblad","email":"marcus.gronblad@bonniernews.se"},{"name":"axeljohanssonbonniernews","email":"axel.johansson@bonniernews.se"},{"name":"karlbergc","email":"christoffer.karlberg@bonniernews.se"},{"name":"chavah","email":"chavah.forler@bonniernews.se"},{"name":"joelekman","email":"joel.ekman@bonniernews.se"},{"name":"adam.hakansson","email":"adam.hakansson@bonniernews.se"},{"name":"hilleso","email":"marcus.hilleso@expressen.se"},{"name":"gusliden","email":"gusliden@gmail.com"},{"name":"andreas.samuelsson","email":"andreas.samuelsson@bonniernews.se"},{"name":"jzachrisson","email":"jesper.zachrisson@bonniernews.se"},{"name":"norla","email":"mattias.norlander@gmail.com"},{"name":"varneynz","email":"simon.varney@bonniernews.se"},{"name":"aliceboberg","email":"alice.boberg@bonniernews.se"},{"name":"johark","email":"johan.arkad@bonniernews.se"},{"name":"nifo","email":"niklas.forsstrom@bonniernews.se"},{"name":"herbola","email":"herman.jansson@bonniernews.se"},{"name":"vitryssen","email":"andre.nordlund@bonniernews.se"},{"name":"takolander","email":"william.takolander@bonniernews.se"},{"name":"morre","email":"marten.persson@hdsydsvenskan.se"},{"name":"mikael.mattsson","email":"mikael.mattsson@bonniernews.se"},{"name":"schristianssonbn","email":"seb.christiansson@bonniernews.se"},{"name":"mattiasobn","email":"mattias.olla@bonniernews.se"},{"name":"daghall","email":"markus@daghall.se"},{"name":"erandersson","email":"ericandersson1@gmail.com"},{"name":"jonaek","email":"jonathan.ek@bonniernews.se"},{"name":"amundsentb","email":"amundsentb@gmail.com"},{"name":"drgeobn","email":"daniel.rasmussen@bonniernews.se"},{"name":"oscartholander","email":"oscar@tholander.nu"},{"name":"peterpettersson","email":"peter.pettersson@bonniernews.se"},{"name":"liroliro","email":"basistoscar@gmail.com"},{"name":"ollenolle","email":"olle.nordin@bonniernews.se"},{"name":"torkelberget","email":"andreas.egneblad@bonniernews.se"},{"name":"nblom","email":"niklas.blom@bonniernews.se"},{"name":"jackesa","email":"jakob.pedersen@bonniernews.se"},{"name":"emilbjorklund","email":"emil@thatemil.com"},{"name":"lilianj","email":"japlilian@gmail.com"},{"name":"kristofferjansson","email":"kristoffer.jansson@bonniernews.se"},{"name":"kitgus","email":"kit.gustavsson@bonniernews.se"},{"name":"odynvolk","email":"alexi.rahman@r76.se"}],"homepage":"https://github.com/BonnierNews/json-templates#readme","bugs":{"url":"https://github.com/BonnierNews/json-templates/issues"},"dist":{"shasum":"c335ab2b5d61f2a18c12861aebfc8db6f63cb512","tarball":"https://registry.npmjs.org/@bonniernews/json-templates/-/json-templates-0.1.3.tgz","fileCount":9,"integrity":"sha512-yaenSYWiLCPvE9+nhMXNdWSjkFMgb9U44TkXMJ9N1ROmyDmRmQFeggUjsg8evvjGzWXzt1qae96AdXgLNqsIuw==","signatures":[{"sig":"MEYCIQCAJdY3tMSm4Yni9Cn9WM1uwu8xQQsEf42ddQiPUJln4AIhAL9cLxl0qIHwmker92zYBojb2Mr9RadANCtAdQpee2nU","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":174435},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{"import":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","require":"./dist/index.cjs"}},"gitHead":"bb6724eaeae9cdee2e93d695b9d1271a8f441cbe","scripts":{"lint":"eslint . --cache && npm run typecheck","test":"mocha --exit --reporter ${REPORTER:-spec}","build":"tsup","format":"prettier --write . && npm run lint:fix","coverage":"c8 npm test && c8 check-coverage","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","local-coverage":"c8 --reporter html npm test && c8 check-coverage || open ./coverage/index.html","prepublishOnly":"npm run build"},"_npmUser":{"name":"herbola","email":"herman.jansson@bonniernews.se"},"repository":{"url":"git+https://github.com/BonnierNews/json-templates.git","type":"git"},"_npmVersion":"10.9.3","description":"Completes incomplete JSON string with caching capabilites","directories":{},"_nodeVersion":"22.20.0","dependencies":{"json-templates":"^5.2.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","tsx":"^4.19.1","chai":"^5.1.1","tsup":"^8.3.5","mocha":"^11.0.0","eslint":"^8.57.1","prettier":"^3.3.3","typescript":"^5.6.3","@types/chai":"^5.0.0","@types/node":"^22.9.0","@types/mocha":"^10.0.10","@types/sinon":"^17.0.3","mocha-cakes-2":"^3.3.0","typescript-eslint":"^8.13.0","@bonniernews/tsconfig":"^0.0.2","@types/json-templates":"^3.0.3","@bonniernews/eslint-config":"^1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/json-templates_0.1.3_1774476766875_0.7499567880002194","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bonniernews/json-templates","version":"0.2.0","keywords":["JSON","templates"],"author":{"name":"Bonnier News"},"license":"MIT","_id":"@bonniernews/json-templates@0.2.0","maintainers":[{"name":"markusn","email":"markus@botten.org"},{"name":"mxtr","email":"max.olofsson@bonniernews.se"},{"name":"matsrorbecker","email":"mats@rorbecker.com"},{"name":"dan.karlsson","email":"dan.arola@bonniernews.se"},{"name":"jonaswalden","email":"jonas.waldeen@gmail.com"},{"name":"marie-winther","email":"marie.winther@bonniernews.se"},{"name":"marcusgronblad","email":"marcus.gronblad@bonniernews.se"},{"name":"axeljohanssonbonniernews","email":"axel.johansson@bonniernews.se"},{"name":"karlbergc","email":"christoffer.karlberg@bonniernews.se"},{"name":"chavah","email":"chavah.forler@bonniernews.se"},{"name":"joelekman","email":"joel.ekman@bonniernews.se"},{"name":"adam.hakansson","email":"adam.hakansson@bonniernews.se"},{"name":"hilleso","email":"marcus.hilleso@expressen.se"},{"name":"gusliden","email":"gusliden@gmail.com"},{"name":"andreas.samuelsson","email":"andreas.samuelsson@bonniernews.se"},{"name":"jzachrisson","email":"jesper.zachrisson@bonniernews.se"},{"name":"norla","email":"mattias.norlander@gmail.com"},{"name":"varneynz","email":"simon.varney@bonniernews.se"},{"name":"aliceboberg","email":"alice.boberg@bonniernews.se"},{"name":"johark","email":"johan.arkad@bonniernews.se"},{"name":"nifo","email":"niklas.forsstrom@bonniernews.se"},{"name":"herbola","email":"herman.jansson@bonniernews.se"},{"name":"vitryssen","email":"andre.nordlund@bonniernews.se"},{"name":"takolander","email":"william.takolander@bonniernews.se"},{"name":"morre","email":"marten.persson@hdsydsvenskan.se"},{"name":"mikael.mattsson","email":"mikael.mattsson@bonniernews.se"},{"name":"schristianssonbn","email":"seb.christiansson@bonniernews.se"},{"name":"mattiasobn","email":"mattias.olla@bonniernews.se"},{"name":"daghall","email":"markus@daghall.se"},{"name":"erandersson","email":"ericandersson1@gmail.com"},{"name":"jonaek","email":"jonathan.ek@bonniernews.se"},{"name":"amundsentb","email":"amundsentb@gmail.com"},{"name":"drgeobn","email":"daniel.rasmussen@bonniernews.se"},{"name":"oscartholander","email":"oscar@tholander.nu"},{"name":"peterpettersson","email":"peter.pettersson@bonniernews.se"},{"name":"liroliro","email":"basistoscar@gmail.com"},{"name":"ollenolle","email":"olle.nordin@bonniernews.se"},{"name":"torkelberget","email":"andreas.egneblad@bonniernews.se"},{"name":"nblom","email":"niklas.blom@bonniernews.se"},{"name":"jackesa","email":"jakob.pedersen@bonniernews.se"},{"name":"emilbjorklund","email":"emil@thatemil.com"},{"name":"lilianj","email":"japlilian@gmail.com"},{"name":"kristofferjansson","email":"kristoffer.jansson@bonniernews.se"},{"name":"kitgus","email":"kit.gustavsson@bonniernews.se"},{"name":"odynvolk","email":"alexi.rahman@r76.se"}],"homepage":"https://github.com/BonnierNews/json-templates#readme","bugs":{"url":"https://github.com/BonnierNews/json-templates/issues"},"dist":{"shasum":"b6347f1ab0911f2c5b560d43c0fc3f194217b2ac","tarball":"https://registry.npmjs.org/@bonniernews/json-templates/-/json-templates-0.2.0.tgz","fileCount":9,"integrity":"sha512-cRMo7GXxhyPBkrQlA1KsAYL4YLhvrV6z/6GRG7+0hB1NLrleje4X+HsNZiMHojnXnqluL8WCQ4z3/clOPTvEuQ==","signatures":[{"sig":"MEQCIDyLmemt6FmDdgc89xj6iRnIl9XMsCQ9K1HAZVxAn8gNAiBGeZJpzI+6mVV2MaLJnDiCXza9qAUIrz/b722NKHlahw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":237176},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"node":">=18"},"exports":{"import":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"require":{"types":"./dist/index.d.cts","require":"./dist/index.cjs"}},"gitHead":"b1aa54ce8fac08ea66cc1233e5ac135f8143a14d","scripts":{"lint":"eslint . --cache && npm run typecheck","test":"mocha --exit --reporter ${REPORTER:-spec}","build":"tsup","format":"prettier --write . && npm run lint:fix","coverage":"c8 npm test && c8 check-coverage","lint:fix":"eslint . --fix","typecheck":"tsc --noEmit","local-coverage":"c8 --reporter html npm test && c8 check-coverage || open ./coverage/index.html","prepublishOnly":"npm run build"},"_npmUser":{"name":"herbola","email":"herman.jansson@bonniernews.se"},"repository":{"url":"git+https://github.com/BonnierNews/json-templates.git","type":"git"},"_npmVersion":"10.9.3","description":"Completes incomplete JSON string with caching capabilites","directories":{},"_nodeVersion":"22.20.0","dependencies":{"json-templates":"^5.2.0"},"_hasShrinkwrap":false,"devDependencies":{"c8":"^10.1.3","tsx":"^4.19.1","chai":"^5.1.1","tsup":"^8.3.5","mocha":"^11.0.0","eslint":"^8.57.1","prettier":"^3.3.3","typescript":"^5.6.3","@types/chai":"^5.0.0","@types/node":"^22.9.0","@types/mocha":"^10.0.10","@types/sinon":"^17.0.3","mocha-cakes-2":"^3.3.0","typescript-eslint":"^8.13.0","@bonniernews/tsconfig":"^0.0.2","@types/json-templates":"^3.0.3","@bonniernews/eslint-config":"^1.2.0"},"_npmOperationalInternal":{"tmp":"tmp/json-templates_0.2.0_1776315393050_0.06886774438240217","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-03-10T15:00:59.004Z","modified":"2026-08-26T12:06:51.212Z","0.0.1":"2026-03-10T15:00:59.269Z","0.0.2":"2026-03-10T15:06:58.364Z","0.0.3":"2026-03-20T15:15:21.376Z","0.1.0":"2026-03-23T08:05:17.032Z","0.1.1":"2026-03-23T19:35:11.166Z","0.1.2":"2026-03-25T21:57:25.019Z","0.1.3":"2026-03-25T22:12:47.063Z","0.2.0":"2026-04-16T04:56:33.203Z"},"bugs":{"url":"https://github.com/BonnierNews/json-templates/issues"},"author":{"name":"Bonnier News"},"license":"MIT","homepage":"https://github.com/BonnierNews/json-templates#readme","keywords":["JSON","templates"],"repository":{"url":"git+https://github.com/BonnierNews/json-templates.git","type":"git"},"description":"Completes incomplete JSON string with caching capabilites","maintainers":[{"email":"markus@botten.org","name":"markusn"},{"email":"max.olofsson@bonniernews.se","name":"mxtr"},{"email":"mats@rorbecker.com","name":"matsrorbecker"},{"email":"dan.arola@bonniernews.se","name":"dan.karlsson"},{"email":"adil.aboulkacim@bonniernews.se","name":"adil.aboulkacim"},{"email":"marie.winther@bonniernews.se","name":"marie-winther"},{"email":"marcus.gronblad@bonniernews.se","name":"marcusgronblad"},{"email":"axel.johansson@bonniernews.se","name":"axeljohanssonbonniernews"},{"email":"christoffer.karlberg@bonniernews.se","name":"karlbergc"},{"email":"chavah.forler@bonniernews.se","name":"chavah"},{"email":"joel.ekman@bonniernews.se","name":"joelekman"},{"email":"adam.hakansson@bonniernews.se","name":"adam.hakansson"},{"email":"marcus.hilleso@expressen.se","name":"hilleso"},{"email":"gusliden@gmail.com","name":"gusliden"},{"email":"andreas.samuelsson@bonniernews.se","name":"andreas.samuelsson"},{"email":"jesper.zachrisson@bonniernews.se","name":"jzachrisson"},{"email":"mattias.norlander@gmail.com","name":"norla"},{"email":"simon.varney@bonniernews.se","name":"varneynz"},{"email":"alice.boberg@bonniernews.se","name":"aliceboberg"},{"email":"johan.arkad@bonniernews.se","name":"johark"},{"email":"niklas.forsstrom@bonniernews.se","name":"nifo"},{"email":"herman.jansson@bonniernews.se","name":"herbola"},{"email":"andre.nordlund@bonniernews.se","name":"vitryssen"},{"email":"william.takolander@bonniernews.se","name":"takolander"},{"email":"marten.persson@hdsydsvenskan.se","name":"morre"},{"email":"mikael.mattsson@bonniernews.se","name":"mikael.mattsson"},{"email":"seb.christiansson@bonniernews.se","name":"schristianssonbn"},{"email":"mattias.olla@bonniernews.se","name":"mattiasobn"},{"email":"markus@daghall.se","name":"daghall"},{"email":"ericandersson1@gmail.com","name":"erandersson"},{"email":"jonathan.ek@bonniernews.se","name":"jonaek"},{"email":"amundsentb@gmail.com","name":"amundsentb"},{"email":"daniel.rasmussen@bonniernews.se","name":"drgeobn"},{"email":"oscar@tholander.nu","name":"oscartholander"},{"email":"peter.pettersson@bonniernews.se","name":"peterpettersson"},{"email":"basistoscar@gmail.com","name":"liroliro"},{"email":"andreas.egneblad@bonniernews.se","name":"torkelberget"},{"email":"johan@kasperi.se","name":"johankasperi"},{"email":"jon.eldeklint@bonniernews.se","name":"jon.eldeklint"},{"email":"niklas.blom@bonniernews.se","name":"nblom"},{"email":"jakob.pedersen@bonniernews.se","name":"jackesa"},{"email":"olle.nordin@bonniernews.se","name":"ollenolle"},{"email":"emil@thatemil.com","name":"emilbjorklund"},{"email":"japlilian@gmail.com","name":"lilianj"},{"email":"kristoffer.jansson@bonniernews.se","name":"kristofferjansson"},{"email":"kit.gustavsson@bonniernews.se","name":"kitgus"},{"email":"alexi.rahman@r76.se","name":"odynvolk"}],"readme":"# @bonniernews/json-templates\n\nA template engine for strings, objects, and arrays. Placeholders use `{{ }}` and support path access, optional chaining, nullish defaults, ternary conditions, logical operators, arithmetic, array methods with arrow functions, template string interpolation, and strict mode.\n\n## Installation\n\n```bash\nnpm install @bonniernews/json-templates\n```\n\n---\n\n## API\n\n```ts\nimport { render, validate, MissingVariableError, ArithmeticError, ParseError, TypeError, JsonTemplateError } from \"@bonniernews/json-templates\";\n\nrender(template, data, options?)\nvalidate(template, data?)\n```\n\n| Argument   | Type                        | Description                   |\n| ---------- | --------------------------- | ----------------------------- |\n| `template` | `string \\| object \\| array` | The template to render        |\n| `data`     | `Record<string, any>`       | The values to substitute      |\n| `options`  | `RenderOptions`             | Optional settings (see below) |\n\n### Options\n\n| Option            | Type      | Default | Description                                                                    |\n| ----------------- | --------- | ------- | ------------------------------------------------------------------------------ |\n| `strict`          | `boolean` | `false` | Throw on missing variables and invalid arithmetic                              |\n| `preserveMissing` | `boolean` | `false` | Keep `{{expr}}` verbatim in output when the expression resolves to `undefined` |\n\n#### `strict`\n\n```ts\nrender(\"Hello {{name}}\", {}, { strict: true });\n// → throws MissingVariableError: Missing variable: \"name\"\n\nrender(\"{{name ?? 'Guest'}}\", {}, { strict: true });\n// → \"Guest\"  — default covers the missing variable, no throw\n\nrender(\"{{'hello' * 2}}\", {}, { strict: true });\n// → throws ArithmeticError: Arithmetic operation produced NaN — operands must be numeric\n\nrender(\"{{1 / 0}}\", {}, { strict: true });\n// → \"Infinity\"  — division by zero is allowed\n```\n\n#### `preserveMissing`\n\nWhen `true`, any placeholder that resolves to `undefined` is left unchanged in the output — the original `{{expr}}` string is preserved verbatim — instead of being replaced with `\"\"` or `undefined`.\n\nTokens that resolve successfully are rendered as normal. Tokens with a fallback (`: default` or `??`) use their fallback as normal.\n\n```ts\nrender(\"hello {{name}}\", {}, { preserveMissing: true });\n// → \"hello {{name}}\"\n\nrender({ city: \"{{order.city}}\" }, {}, { preserveMissing: true });\n// → { city: \"{{order.city}}\" }\n\n// Mixed: found tokens render, missing tokens are preserved\nrender(\"{{first}} {{last}}\", { first: \"John\" }, { preserveMissing: true });\n// → \"John {{last}}\"\n\n// Fallbacks still apply — not treated as missing\nrender(\"{{name ?? 'Guest'}}\", {}, { preserveMissing: true });\n// → \"Guest\"\n```\n\n`MissingVariableError` extends `JsonTemplateError` and has a `path` property with the variable path (e.g. `\"user.name\"`, `\"list[0]\"`). `ArithmeticError` extends `JsonTemplateError` and is thrown in strict mode when an arithmetic operation produces `NaN` (i.e. non-numeric operands). `ParseError` extends `JsonTemplateError` and is thrown when a placeholder has invalid syntax. `TypeError` extends `JsonTemplateError` and is thrown in strict mode when array methods are called on non-array values. All error classes are exported from the package.\n\n### Return type\n\n**Return type** matches the template type:\n\n- `string` template → always returns `string` (objects are JSON-stringified)\n- `object` / `array` template → returns the same shape with values rendered; a value that is exactly one `{{expr}}` returns the raw evaluated value (preserving non-string types)\n\n---\n\n## Example\n\nA JSON template using all preferred syntaxes:\n\n```json\n{\n  \"to\": \"{{user.email}}\",\n  \"subject\": \"{{user.active ? `Welcome back, ${user.firstName}!` : 'Your account is inactive'}}\",\n  \"role\": \"{{user.role || 'viewer'}}\",\n  \"isAdmin\": \"{{user.role && user.active}}\",\n  \"optedOut\": \"{{!user.notifications}}\",\n  \"firstTag\": \"{{user.tags[0]}}\",\n  \"contact\": \"{{user.contact}}\",\n  \"contactJson\": \"Contact info: {{user.contact}}\",\n  \"contactPhone\": \"{{user?.contact?.phone ?? 'not provided'}}\",\n  \"Display Name\": \"{{user['Display Name'] ?? user.firstName ?? 'there'}}\",\n  \"Preferred Publication\": \"{{['Preferred Publication'] ?? 'none'}}\"\n}\n```\n\nWith data:\n\n```json\n{\n  \"user\": {\n    \"email\": \"alice@example.com\",\n    \"firstName\": \"Alice\",\n    \"active\": true,\n    \"role\": \"editor\",\n    \"notifications\": false,\n    \"tags\": [\"news\", \"sports\"],\n    \"contact\": { \"phone\": \"+1 555 0100\" },\n    \"Display Name\": \"Alice Wonderland\"\n  },\n  \"Preferred Publication\": \"Dagens Nyheter\"\n}\n```\n\nResult:\n\n```json\n{\n  \"to\": \"alice@example.com\",\n  \"subject\": \"Welcome back, Alice!\",\n  \"role\": \"editor\",\n  \"isAdmin\": true,\n  \"optedOut\": true,\n  \"firstTag\": \"news\",\n  \"contact\": { \"phone\": \"+1 555 0100\" },\n  \"contactJson\": \"Contact info: {\\\"phone\\\":\\\"+1 555 0100\\\"}\",\n  \"contactPhone\": \"+1 555 0100\",\n  \"Display Name\": \"Alice Wonderland\",\n  \"Preferred Publication\": \"Dagens Nyheter\"\n}\n```\n\n`isAdmin`, `optedOut`, and `contact` pass through as their raw types (boolean / boolean / object) because they are sole placeholders in an object template.\n\n---\n\n## Placeholder syntax\n\nEvery placeholder is wrapped in `{{ }}`.\n\n```\n{{ expression }}\n```\n\n---\n\n## Expressions\n\n### 1. Variable path\n\n```\n{{name}}\n{{user.address.city}}\n```\n\n### 2. Array indexing — `[n]` _(preferred)_\n\n```\n{{list[0]}}\n{{users[0].tags[1]}}\n{{matrix[0][1].value}}\n```\n\nLegacy dot-index syntax is also supported and can be mixed:\n\n```\n{{users.0.name}}\n{{users[0].tags.1}}\n```\n\n### 3. Bracket notation — `['key']`\n\nRequired for keys containing spaces or other special characters.\n\n```\n{{['Sundsvalls Tidning']}}\n{{['Sundsvalls Tidning'].v1}}\n{{['Sundsvalls Tidning']['Nested Property']}}\n{{items[0]['my key']}}\n```\n\nSimple identifiers still use dot notation: `{{user.name}}`.\n\n### 4. Optional chaining — `?.`\n\nReturns `undefined` silently if any part of the chain is `null` or `undefined` — even in strict mode.\n\n```\n{{user?.name}}              ← undefined if user is missing or null\n{{user?.address?.city}}     ← safe deep access\n{{user?.['my key']}}        ← optional bracket notation\n{{list?.[0]}}               ← optional index access\n```\n\nCombine with `??` to provide a fallback:\n\n```\n{{user?.name ?? 'Guest'}}\n```\n\n### 5. Nullish coalescing — `expr ?? fallback`\n\nReturns the fallback when the value is `null`, `undefined`, or missing. `false`, `0`, and `\"\"` are **not** replaced.\n\nWorks at any depth — no parentheses needed inside a ternary (unlike `:` default).\n\n```\n{{name ?? 'Guest'}}\n{{user.name ?? 'Anonymous'}}\n{{a ? b ?? 'fallback' : 'other'}}   ← works directly inside a ternary branch\n```\n\n| Value of `name` | Result    |\n| --------------- | --------- |\n| `\"Alice\"`       | `\"Alice\"` |\n| `null`          | `\"Guest\"` |\n| `undefined`     | `\"Guest\"` |\n| _(missing)_     | `\"Guest\"` |\n| `\"\"`            | `\"\"`      |\n| `false`         | `\"false\"` |\n| `0`             | `\"0\"`     |\n\n### 6. Default value — `expr:fallback` _(legacy nullish — top-level only)_\n\nSame nullish semantics as `??` but only works at the top level of an expression. To use inside a ternary, wrap in parentheses or use `??` instead.\n\n```\n{{name:'Guest'}}\n{{url:'http://example.com'}}        ← colon inside quoted default is safe\n{{a ? (b:'Guest') : 'other'}}       ← parens required inside ternary\n```\n\n### 7. Ternary — `condition ? truthy : falsy`\n\n`false`, `0`, `\"\"`, `null`, and `undefined` are all **falsy**.\n\n```\n{{isActive ? 'Active' : 'Inactive'}}\n{{user.name ? user.name : 'Guest'}}\n{{flag ? a : b}}\n```\n\nTernaries are right-associative — parentheses are optional but accepted for readability:\n\n```\n{{a ? b ? 'both' : 'a only' : 'neither'}}\n{{a ? (b ? 'both' : 'a only') : 'neither'}}   ← identical result\n```\n\n### 8. Logical operators — `&&`, `||`, `!`\n\nJavaScript-style short-circuit semantics: `&&` and `||` return the actual value, not a boolean. `!` always returns a boolean.\n\n| Operator   | Behaviour                                 |\n| ---------- | ----------------------------------------- |\n| `a && b`   | Returns `a` if falsy, otherwise `b`       |\n| `a \\|\\| b` | Returns `a` if truthy, otherwise `b`      |\n| `!a`       | `true` if `a` is falsy, `false` if truthy |\n\n**Precedence** (highest → lowest): `-x` `!` > `*` `/` `%` > `+` `-` > `<` `>` `<=` `>=` > `==` `===` `!=` `!==` > `&&` > `||` > `??` > ternary `? :` > default `:`\n\n```\n{{a && b}}\n{{a || b}}\n{{!isActive}}\n{{a || b ? 'yes' : 'no'}}\n{{!isActive ? 'off' : 'on'}}\n{{a || b && c}}                 ← parsed as a || (b && c)\n```\n\n### 9. Comparison — `<`, `>`, `<=`, `>=`\n\n```\n{{count > 0 ? 'items' : 'empty'}}\n{{score >= 90 ? 'A' : 'B'}}\n{{a + b > threshold}}\n```\n\n### 10. Equality — `==`, `===`, `!=`, `!==`\n\nStandard JavaScript equality and inequality. `==`/`!=` coerce types; `===`/`!==` do not.\n\n```\n{{status == 'active' ? 'yes' : 'no'}}\n{{role === 'admin' ? 'yes' : 'no'}}\n{{role !== 'admin' ? 'restricted' : 'allowed'}}\n{{a + b === total}}\n```\n\n| Operator  | Behaviour                            |\n| --------- | ------------------------------------ |\n| `a == b`  | Loose equality — coerces types       |\n| `a === b` | Strict equality — no type coercion   |\n| `a != b`  | Loose inequality — coerces types     |\n| `a !== b` | Strict inequality — no type coercion |\n\n### 11. Arithmetic — `+`, `-`, `*`, `/`, `%`\n\nStandard arithmetic with JavaScript semantics. `+` also concatenates strings. `-` can also be used as unary negation.\n\n```\n{{a + b}}\n{{price * quantity}}\n{{total - discount}}\n{{score / count}}\n{{index % 2 === 0 ? 'even' : 'odd'}}\n{{-price}}\n{{(a + b) * c}}\n```\n\n**Precedence** (highest → lowest within arithmetic): `*` `/` `%` > `+` `-`\n\nOperators are left-associative: `8 / 2 / 2 == 2`.\n\nIn **strict mode**, an operation that produces `NaN` (e.g. `'hello' * 2`) throws `ArithmeticError`. Division by zero producing `Infinity` is allowed in both modes.\n\n### 12. Array methods with arrow functions\n\nTransform and query arrays using JavaScript-style array methods with arrow function syntax.\n\n#### Arrow function syntax\n\n```\nx => expression                    ← single parameter\n(a, b) => expression              ← multiple parameters\nx => ({key: value})               ← object literal shorthand\nx => ({[x.id]: x.name})           ← computed/dynamic keys\n```\n\nArrow functions support **expression bodies only** (no `{}` block syntax). The expression result is the return value.\n\n#### Supported array methods\n\n| Method                  | Description                             | Returns                |\n| ----------------------- | --------------------------------------- | ---------------------- |\n| `.map(fn)`              | Transform each element                  | New array              |\n| `.filter(fn)`           | Keep elements matching predicate        | New array              |\n| `.find(fn)`             | Find first element matching predicate   | Element or `undefined` |\n| `.some(fn)`             | Check if any element matches predicate  | Boolean                |\n| `.reduce(fn, initial?)` | Reduce array to single value            | Any value              |\n| `.sort(fn?)`            | Sort array (with optional comparator)   | New array              |\n| `.join(separator?)`     | Join elements into string               | String                 |\n| `.reverse()`            | Reverse array order                     | New array              |\n| `.length`               | Get array length (property, not method) | Number                 |\n\n**Important**: All methods return **new arrays** and do not mutate the originals.\n\n#### Examples\n\n```ts\n// Transform with .map()\nrender(\"{{items.map(x => x.name)}}\", { items: [{ name: \"A\" }, { name: \"B\" }] });\n// → '[\"A\",\"B\"]'\n\n// Object literal shorthand\nrender(\"{{users.map(u => ({id: u.id, name: u.name}))}}\", {\n  users: [\n    { id: 1, name: \"Alice\" },\n    { id: 2, name: \"Bob\" },\n  ],\n});\n// → [{id: 1, name: \"Alice\"}, {id: 2, name: \"Bob\"}]\n\n// Computed keys (dynamic property names)\nrender(\"{{users.map(u => ({[u.id]: u.name}))}}\", {\n  users: [\n    { id: \"user1\", name: \"Alice\" },\n    { id: \"user2\", name: \"Bob\" },\n  ],\n});\n// → [{user1: \"Alice\"}, {user2: \"Bob\"}]\n\n// Filter with predicate\nrender(\"{{items.filter(x => x.active)}}\", {\n  items: [\n    { active: true, name: \"A\" },\n    { active: false, name: \"B\" },\n  ],\n});\n// → [{active: true, name: \"A\"}]\n\n// Filter with comparison\nrender(\"{{scores.filter(s => s > 50)}}\", { scores: [45, 78, 92, 33] });\n// → [78, 92]\n\n// Find first match\nrender(\"{{users.find(u => u.id === 2)}}\", {\n  users: [\n    { id: 1, name: \"Alice\" },\n    { id: 2, name: \"Bob\" },\n  ],\n});\n// → {id: 2, name: \"Bob\"}\n\n// Check if any match\nrender(\"{{items.some(x => x.price > 100)}}\", { items: [{ price: 50 }, { price: 150 }] });\n// → \"true\"\n\n// Reduce to sum\nrender(\"{{numbers.reduce((sum, x) => sum + x, 0)}}\", { numbers: [1, 2, 3, 4] });\n// → \"10\"\n\n// Reduce with index parameter\nrender(\"{{items.reduce((acc, item, i) => acc + item * i, 0)}}\", { items: [5, 10, 15] });\n// → \"40\"\n\n// Sort with comparator (numeric sort)\nrender(\"{{numbers.sort((a, b) => a - b)}}\", { numbers: [10, 2, 33, 4] });\n// → [2, 4, 10, 33]\n\n// Sort objects by property\nrender(\"{{users.sort((a, b) => a.age - b.age)}}\", { users: [{ age: 30 }, { age: 20 }, { age: 25 }] });\n// → [{age: 20}, {age: 25}, {age: 30}]\n\n// Join with separator\nrender(\"{{tags.join(', ')}}\", { tags: [\"js\", \"ts\", \"node\"] });\n// → \"js, ts, node\"\n\n// Reverse array\nrender(\"{{numbers.reverse()}}\", { numbers: [1, 2, 3] });\n// → [3, 2, 1]\n\n// Array length property\nrender(\"{{items.length}}\", { items: [1, 2, 3, 4, 5] });\n// → \"5\"\n```\n\n#### Method chaining\n\nAll array methods can be chained together:\n\n```ts\nrender(\"{{users.filter(u => u.active).map(u => u.name).join(', ')}}\", {\n  users: [\n    { active: true, name: \"Alice\" },\n    { active: false, name: \"Bob\" },\n    { active: true, name: \"Charlie\" },\n  ],\n});\n// → \"Alice, Charlie\"\n\nrender(\"{{numbers.filter(n => n > 2).map(n => n * 2).reduce((a, b) => a + b, 0)}}\", { numbers: [1, 2, 3, 4, 5, 6] });\n// → \"36\"\n```\n\n#### Error handling\n\n**Non-strict mode** (default): Array methods gracefully handle non-array values:\n\n| Method              | Returns for non-array | Example                                          |\n| ------------------- | --------------------- | ------------------------------------------------ |\n| `.map()`            | `[]`                  | `\"{{null.map(x => x)}}\"` → `\"[]\"`                |\n| `.filter()`         | `[]`                  | `\"{{42.filter(x => x)}}\"` → `\"[]\"`               |\n| `.find()`           | `undefined`           | `{v: \"{{obj.find(x => x)}}\"}` → `{v: undefined}` |\n| `.some()`           | `false`               | `\"{{'text'.some(x => x)}}\"` → `\"false\"`          |\n| `.reduce(fn, init)` | `init` value          | `\"{{null.reduce((a,b) => a+b, 10)}}\"` → `\"10\"`   |\n| `.join()`           | `\"\"`                  | `\"{{123.join(',')}}\"` → `\"\"`                     |\n| `.reverse()`        | `[]`                  | `\"{{false.reverse()}}\"` → `\"[]\"`                 |\n| `.sort()`           | `[]`                  | `\"{{'str'.sort()}}\"` → `\"[]\"`                    |\n\n**Strict mode**: Throws `TypeError` with path information:\n\n```ts\nrender(\"{{value.map(x => x)}}\", { value: null }, { strict: true });\n// → throws TypeError: Cannot call .map() on non-array value at path: value.map(...)\n\nrender(\"{{user.items.filter(x => x)}}\", { user: { items: \"not array\" } }, { strict: true });\n// → throws TypeError: Cannot call .filter() on non-array value at path: user.items.filter(...)\n```\n\n#### Property vs method disambiguation\n\nObjects can have properties named like array methods. Properties are accessed without parentheses; methods require parentheses:\n\n```ts\n// Property access (no parentheses)\nrender(\"{{obj.map}}\", { obj: { map: \"property value\" } });\n// → \"property value\"\n\n// Method call (with parentheses)\nrender(\"{{items.map(x => x * 2)}}\", { items: [1, 2, 3] });\n// → [2, 4, 6]\n```\n\n### 13. Template string interpolation — `` `text ${expr} text` ``\n\nUse backtick strings with `${}` to embed expressions inline.\n\n```\n{{`Hello ${name}!`}}\n{{`${first} ${last}`}}\n{{`City: ${user.address.city}`}}\n{{`Status: ${isActive ? statusOn : statusOff}`}}\n```\n\nWorks inside ternary branches:\n\n```\n{{isActive ? `Hello ${name}!` : `Goodbye ${name}`}}\n{{a ? `Both: ${name}` : `Neither`}}\n```\n\n---\n\n## Object and array templates\n\nThe template itself can be an object or array. Each string value is rendered independently.\n\n```ts\nrender({ message: \"Hello {{name}}\", id: \"{{id}}\" }, { name: \"Alice\", id: 42 });\n// → { message: \"Hello Alice\", id: 42 }\n```\n\nWhen a string value in an object or array template is exactly one placeholder and the resolved value is not a string, the **raw value is passed through**:\n\n```ts\nrender({ data: \"{{payload}}\" }, { payload: { id: 1 } });\n// → { data: { id: 1 } }\n```\n\nIn a top-level **string** template, objects are always JSON-stringified:\n\n```ts\nrender(\"{{user}}\", { user: { name: \"Alice\" } });\n// → '{\"name\":\"Alice\"}'\n```\n\n---\n\n## Validation\n\n`validate(template, data?)` checks a template against data using the same evaluation logic as `render`. It returns `{ isValid: boolean, missing: string[], errors: string[] }` and never throws.\n\n```ts\nvalidate(\"Hello {{name}}\", { name: \"Alice\" });\n// → { isValid: true, missing: [], errors: [] }\n\nvalidate(\"Hello {{name}}\", {});\n// → { isValid: false, missing: [\"name\"], errors: [] }\n\nvalidate({ greeting: \"Hi {{name}}\", city: \"{{location.city}}\" }, {});\n// → { isValid: false, missing: [\"name\", \"location.city\"], errors: [] }\n\n// Syntax errors are reported in errors[] instead of throwing\nvalidate(\"{{(name}}\");\n// → { isValid: false, missing: [], errors: ['Syntax error in \"{{(name}}\": Expected RPAREN but got EOF'] }\n```\n\nBecause it uses the same logic as `render`, covered variables are not reported as missing:\n\n```ts\nvalidate(\"{{name ?? 'Guest'}}\", {}); // → { isValid: true, missing: [], errors: [] }\nvalidate(\"{{user?.name}}\", {}); // → { isValid: true, missing: [], errors: [] }\nvalidate(\"{{name : 'Guest'}}\", {}); // → { isValid: true, missing: [], errors: [] }\n```\n\nTernary branches are only checked for the branch actually taken with the given data — consistent with how `render` evaluates them:\n\n```ts\nvalidate(\"{{flag ? name : fallback}}\", { flag: true });\n// → { isValid: false, missing: [\"name\"], errors: [] }  — fallback is not checked\n\nvalidate(\"{{flag ? name : fallback}}\", { flag: false });\n// → { isValid: false, missing: [\"fallback\"], errors: [] }  — name is not checked\n```\n\n---\n\n## Missing variables\n\n| Context                                   | Default result | With `preserveMissing: true` |\n| ----------------------------------------- | -------------- | ---------------------------- |\n| In a string template                      | `\"\"`           | `\"{{expr}}\"` verbatim        |\n| As sole placeholder in an object template | `undefined`    | `\"{{expr}}\"` verbatim        |\n| In a ternary / logical condition          | falsy          | falsy                        |\n| In string interpolation                   | `\"\"`           | `\"{{expr}}\"` verbatim        |\n\n---\n\n## Escape sequences\n\n### In the template string\n\n`\\{{expr}}` prevents rendering and emits `{{expr}}` literally.\n\n```\n\"Hello \\{{name}}\"  →  \"Hello {{name}}\"\n```\n\n### Inside a string literal `\"...\"`\n\n| Write | Produces | Notes                |\n| ----- | -------- | -------------------- |\n| `\\\"`  | `\"`      | Literal double-quote |\n| `\\\\`  | `\\`      | Literal backslash    |\n\n### Unclosed placeholder\n\nA `{{` with no matching `}}` is left as-is:\n\n```\n\"Hello {{name\"   →  \"Hello {{name\"\n```\n\n---\n\n## Complete syntax reference\n\n```\ntemplate    = string | object | array  — any value containing {{ expr }} blocks\n\nexpr        = nullish-expr ( ? expr : expr )?  — ternary (right-associative)\n            | nullish-expr : expr              — nullish default (top-level only)\nnullish-expr= or-expr ( ?? or-expr )*\nor-expr     = and-expr ( || and-expr )*\nand-expr    = eq-expr ( && eq-expr )*\neq-expr     = cmp-expr ( (==|===|!=|!==) cmp-expr )*\ncmp-expr    = add-expr ( (<|>|<=|>=) add-expr )*\nadd-expr    = mul-expr ( (+|-) mul-expr )*\nmul-expr    = unary ( (*|/|%) unary )*\nunary       = (-|!) unary | primary\nprimary     = path\n            | arrow-function\n            | object-literal\n            | 'string literal'           — single quotes preferred (no JSON escaping)\n            | `template literal`\n            | number (integer or float) | true | false | null\n            | ( expr )                         — grouping (resets default depth)\n\npath        = segment ( accessor | opt-accessor )*\naccessor    = .segment | [number] | [\"string\"] | .method-call\nopt-accessor= ?.segment | ?.[number] | ?.[\"string\"] | ?.method-call\nsegment     = identifier | number\nmethod-call = identifier ( arg-list )\narg-list    = ( expr (, expr)* )?\n\narrow-fn    = identifier => expr                      — single parameter\n            | ( identifier (, identifier)* ) => expr  — multiple parameters\nobj-literal = ( { obj-props } )                       — parenthesized for arrow return\nobj-props   = prop (, prop)*\nprop        = identifier : expr                       — static key\n            | [ expr ] : expr                         — computed key\n\ntemplate lit= ` chars `\nchars       = literal text\n            | ${ expr }                        — interpolation\n            | \\`                               — escaped backtick\n            | \\\\                               — escaped backslash\n```\n\n---\n\n## Quick-reference examples\n\n```ts\n// Variable access\nrender(\"Hello {{name}}\", { name: \"Alice\" }); // → \"Hello Alice\"\nrender(\"{{user.address.city}}\", { user: { address: { city: \"X\" } } }); // → \"X\"\nrender(\"{{list[0]}}\", { list: [\"a\", \"b\"] }); // → \"a\"\n\n// Keys with spaces\nrender(\"{{['My Key']}}\", { \"My Key\": \"value\" }); // → \"value\"\n\n// Optional chaining\nrender({ v: \"{{user?.name}}\" }, {}); // → { v: undefined }\nrender(\"{{user?.name ?? 'Guest'}}\", {}); // → \"Guest\"\n\n// Nullish coalescing\nrender(\"{{name ?? 'Guest'}}\", {}); // → \"Guest\"\nrender(\"{{name ?? 'Guest'}}\", { name: \"\" }); // → \"\"\n\n// Legacy default (top-level only)\nrender(\"{{name:'Guest'}}\", {}); // → \"Guest\"\n\n// Ternary\nrender(\"{{on ? 'yes' : 'no'}}\", { on: true }); // → \"yes\"\nrender(\"{{a ? b ?? 'fallback' : 'other'}}\", { a: true }); // → \"fallback\"\n\n// Logical operators\nrender(\"{{a && b ? 'both' : 'no'}}\", { a: true, b: true }); // → \"both\"\nrender(\"{{name || 'Anonymous'}}\", {}); // → \"Anonymous\"\nrender(\"{{!isActive ? 'off' : 'on'}}\", { isActive: false }); // → \"off\"\n\n// Template string interpolation\nrender(\"{{`Hello ${name}!`}}\", { name: \"Alice\" }); // → \"Hello Alice!\"\nrender(\"{{isActive ? `Hi ${name}` : `Bye`}}\", { isActive: true, name: \"Bob\" }); // → \"Hi Bob\"\n\n// Object template — raw value pass-through\nrender({ data: \"{{payload}}\" }, { payload: { id: 1 } }); // → { data: { id: 1 } }\n\n// Arithmetic\nrender(\"{{a + b}}\", { a: 3, b: 4 }); // → \"7\"\nrender(\"{{a + b * c}}\", { a: 1, b: 2, c: 3 }); // → \"7\"  (* before +)\nrender(\"{{(a + b) * c}}\", { a: 1, b: 2, c: 3 }); // → \"9\"\nrender(\"{{1 / 0}}\", {}); // → \"Infinity\"\n\n// Strict mode\nrender(\"{{name}}\", {}, { strict: true }); // → throws MissingVariableError\nrender(\"{{name ?? 'Guest'}}\", {}, { strict: true }); // → \"Guest\"\nrender(\"{{'hello' * 2}}\", {}, { strict: true }); // → throws ArithmeticError\n\n// Escape\nrender(\"Value: \\\\{{x}}\", { x: \"ignored\" }); // → \"Value: {{x}}\"\n\n// Validation\nvalidate(\"{{name}}\", { name: \"Alice\" }); // → { isValid: true, missing: [], errors: [] }\nvalidate(\"{{name}}\", {}); // → { isValid: false, missing: [\"name\"], errors: [] }\nvalidate(\"{{name ?? 'Guest'}}\", {}); // → { isValid: true, missing: [], errors: [] }\n\n// preserveMissing — keep unresolved tokens verbatim\nrender(\"hello {{name}}\", {}, { preserveMissing: true }); // → \"hello {{name}}\"\nrender({ city: \"{{order.city}}\" }, {}, { preserveMissing: true }); // → { city: \"{{order.city}}\" }\nrender(\"{{first}} {{last}}\", { first: \"John\" }, { preserveMissing: true }); // → \"John {{last}}\"\nrender(\"{{name ?? 'Guest'}}\", {}, { preserveMissing: true }); // → \"Guest\"  (fallback applies)\n\n// Array methods with arrow functions\nrender(\"{{items.map(x => x.name)}}\", { items: [{ name: \"A\" }, { name: \"B\" }] }); // → '[\"A\",\"B\"]'\nrender(\"{{numbers.filter(n => n > 5)}}\", { numbers: [3, 7, 2, 9] }); // → [7, 9]\nrender(\"{{users.find(u => u.id === 2)}}\", { users: [{ id: 1 }, { id: 2, name: \"Bob\" }] }); // → {id: 2, name: \"Bob\"}\nrender(\"{{items.some(x => x > 10)}}\", { items: [5, 15, 3] }); // → \"true\"\nrender(\"{{nums.reduce((a, b) => a + b, 0)}}\", { nums: [1, 2, 3] }); // → \"6\"\nrender(\"{{numbers.sort((a, b) => a - b)}}\", { numbers: [3, 1, 2] }); // → [1, 2, 3]\nrender(\"{{tags.join(', ')}}\", { tags: [\"a\", \"b\", \"c\"] }); // → \"a, b, c\"\nrender(\"{{items.length}}\", { items: [1, 2, 3] }); // → \"3\"\n\n// Method chaining\nrender(\"{{users.filter(u => u.active).map(u => u.name).join(', ')}}\", {\n  users: [\n    { active: true, name: \"A\" },\n    { active: false, name: \"B\" },\n  ],\n}); // → \"A\"\n\n// Object literal with computed keys\nrender(\"{{users.map(u => ({[u.id]: u.name}))}}\", {\n  users: [\n    { id: \"a\", name: \"Alice\" },\n    { id: \"b\", name: \"Bob\" },\n  ],\n}); // → [{a: \"Alice\"}, {b: \"Bob\"}]\n```\n\n---\n\n## License\n\n[MIT](./LICENSE)\n","readmeFilename":"README.md"}