{"_id":"@ciderjs/city-gas","_rev":"13-909b60380768ce24e06b7e436516130c","name":"@ciderjs/city-gas","dist-tags":{"latest":"1.1.1"},"versions":{"0.1.0":{"name":"@ciderjs/city-gas","version":"0.1.0","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.1.0","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"993bf457d2b2a0fbc6ff78ebce84290452e96fc4","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.1.0.tgz","fileCount":25,"integrity":"sha512-vms0lWG11fLyF8NRl4VT/wrzS8hXqyPT/BSICPztrVvDdw8y33oRnypg9XvbBsY5WzszjANpO3krUUTnPpZSRg==","signatures":[{"sig":"MEUCIES67N9xrEmUJHmStgc25+ZX68OwK5zOerHCpAOfkmQsAiEAvoyTcrX4Ym+PLk2Mu6FugKJpFOnAyXy0qkPntJ8cRl8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41262},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"ce8396a4956141c7aa5dd00d4dba93ee55ff0521","scripts":{"tsc":"tsgo --noEmit","test":"vitest run","build":"unbuild","check":"biome check --write","dev:r":"vite playground/react","dev:v":"vite playground/vue3"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"[![README-ja](https://img.shields.io/badge/日本語-blue?logo=ReadMe)](./README.ja.md) <!-- [![Test Coverage](https://img.shields.io/badge/test%20coverage-95.1%25-brightgreen)](https://github.com/luthpg/city-gas) --> [![License](https://img.shields.io/badge/li","directories":{},"_nodeVersion":"20.19.5","dependencies":{"vue":"^3.5.22","react":"^19.2.0","fast-glob":"^3.3.3","react-dom":"^19.2.0","typescript":"^5.9.3"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"jiti":"^2.6.1","vite":"^7.1.10","jsdom":"^27.0.1","vitest":"^3.2.4","unbuild":"^3.6.1","@types/node":"^24.8.1","@types/react":"^19.2.2","@biomejs/biome":"^2.2.6","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"3.2.4","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.0.4","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251019.1"},"peerDependencies":{"vue":"^3","vite":"^7","react":"^19","react-dom":"^19"},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.1.0_1761101422731_0.3669114504068902","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@ciderjs/city-gas","version":"0.1.1","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.1.1","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"80a904030c1cd0687f72b5e6d87e603cccd1ff19","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.1.1.tgz","fileCount":25,"integrity":"sha512-GYLjlL0IAuGaFDBf6m8AMxQIYW7FCzJL1VqqWzAbHp+PkS5XNBJJ1PtJG5332Qha7dpHGKV3dIglAnZnaDj4CQ==","signatures":[{"sig":"MEUCIEJPKSHBf/0bMobt3RGL7pSeObu9kHvUH2HNDPRsDwRvAiEA69CiqftmW3JucczRUObrk99qvFZJC0pH/502HGuQvzM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":50423},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"1ef0e2b7eec015ed3fe7170471388762b6ef7409","scripts":{"tsc":"tsgo --noEmit","test":"vitest run","build":"unbuild","check":"biome check --write","dev:r":"vite playground/react","dev:v":"vite playground/vue3"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"[![README-ja](https://img.shields.io/badge/日本語-blue?logo=ReadMe)](./README.ja.md) <!-- [![Test Coverage](https://img.shields.io/badge/test%20coverage-95.1%25-brightgreen)](https://github.com/luthpg/city-gas) --> [![License](https://img.shields.io/badge/li","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","vite":"^7.1.12","jsdom":"^27.0.1","react":"^19.2.0","vitest":"^4.0.3","unbuild":"^3.6.1","react-dom":"^19.2.0","@types/node":"^24.9.1","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.0","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.3","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251024.1"},"peerDependencies":{"vue":">=3","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.1.1_1761625728276_0.7919688121979795","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@ciderjs/city-gas","version":"0.1.2","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.1.2","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"3ba9de060b5d6e6bb1cbd54c437b80fc11345f1a","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.1.2.tgz","fileCount":25,"integrity":"sha512-PZ3nvI4JVTFUrabnP9Ip7MLYVl4gwxb03/t7clkuorm0nqQqkDu1iivyC1C0a1rMqv+MLc4ZJdj22xtpJzjdFQ==","signatures":[{"sig":"MEYCIQCGDDS41AB0Ydve5Z+xg9kvIba40asbJLeoXwiScJQIvQIhAL6v/YfT9amtZHozLts8YdTzwjGZX3nhYv1IFlV/Wp4F","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53402},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"f130aab0232c561f8749e57556528a0b3e7b2a3d","scripts":{"tsc":"tsgo --noEmit","test":"vitest run","build":"unbuild","check":"biome check --write","dev:r":"vite playground/react","dev:v":"vite playground/vue3"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"[![README-ja](https://img.shields.io/badge/日本語-blue?logo=ReadMe)](./README.ja.md) <!-- [![Test Coverage](https://img.shields.io/badge/test%20coverage-95.1%25-brightgreen)](https://github.com/luthpg/city-gas) --> [![License](https://img.shields.io/badge/li","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","vite":"^7.1.12","jsdom":"^27.0.1","react":"^19.2.0","vitest":"^4.0.3","unbuild":"^3.6.1","react-dom":"^19.2.0","@types/node":"^24.9.1","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.0","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.3","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251024.1"},"peerDependencies":{"vue":">=3","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.1.2_1761823878936_0.8351773737622388","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@ciderjs/city-gas","version":"0.1.3","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.1.3","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"ae82f105493a590f3ce2c156fd7037477f3bd155","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.1.3.tgz","fileCount":25,"integrity":"sha512-bIfPysBQg09gIoIMkXbQ1jwyn1vvCHDQ1F719Jg819EtTrnvSRAlWxBiDJWuArtdDJneKUhSu5JJ0fcUa2YF7w==","signatures":[{"sig":"MEYCIQDqNvlWM80LrCWx4MHYcRtDN8lvL9A5+xM35suTqMEyuwIhAJC3HhTyv1FXUdWCV+ummp+6NvCxR1owx9S/py2rWZPu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54616},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"fb128a138d539d5631b12c11ab9a1ac138f76023","scripts":{"tsc":"tsgo --noEmit","test":"vitest run","build":"unbuild","check":"biome check --write","dev:r":"vite playground/react","dev:v":"vite playground/vue3"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"[![README-ja](https://img.shields.io/badge/日本語-blue?logo=ReadMe)](./README.ja.md) <!-- [![Test Coverage](https://img.shields.io/badge/test%20coverage-95.1%25-brightgreen)](https://github.com/luthpg/city-gas) --> [![License](https://img.shields.io/badge/li","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","vite":"^7.1.12","jsdom":"^27.0.1","react":"^19.2.0","vitest":"^4.0.3","unbuild":"^3.6.1","react-dom":"^19.2.0","@types/node":"^24.9.1","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.0","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.3","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251024.1"},"peerDependencies":{"vue":">=3","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.1.3_1761924218320_0.8453239463980413","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@ciderjs/city-gas","version":"0.2.0","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.2.0","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"c23eaf7d020666d16d1c07ea5b7be80228d13f9d","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.2.0.tgz","fileCount":25,"integrity":"sha512-WIMvcg/QF9IwxInij1Y66dxPhyHD10GFcRtrccoFmOSO5+xLuVMfQTi3ygBBQkjq7idVL+7ABUyIm9pQd0CKCQ==","signatures":[{"sig":"MEQCICY7w926m+xFoQAZ5E5178DQxfVWJgKOr1m4YG78FJH/AiBKVhdBNMvM2wVlsDMqvl6492e4XWIm+x/YuFw/4vmFig==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70394},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"7b58141b260f4f0fa007ff06ecdf5e8a2dcf76ac","scripts":{"tsc":"tsgo --noEmit","test":"vitest run --coverage","build":"unbuild","check":"biome check --write","dev:r":"pnpm run build && vite playground/react","dev:v":"pnpm run build && vite playground/vue3"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"Router for Single Page App on Google Apps Script","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","vite":"^7.1.12","jsdom":"^27.1.0","react":"^19.2.0","vitest":"^4.0.6","unbuild":"^3.6.1","react-dom":"^19.2.0","@types/node":"^24.9.2","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.2","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.6","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251101.1"},"peerDependencies":{"vue":">=3","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.2.0_1762012550838_0.5080572025554391","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@ciderjs/city-gas","version":"0.2.1","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.2.1","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"818c3a45f6c1a409630f315343f0da6b802cc4bc","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.2.1.tgz","fileCount":25,"integrity":"sha512-VMNyNVU0/0AlCTxdW+0lKElTdD4+w32Yj95m2lN/k1rtGQ9OOggOcrjLdhaFF7/E2PoJuT9kZCwuvMtmzm2BdQ==","signatures":[{"sig":"MEYCIQCvjD/Dd1Mofcg2ffwBvrOQfgq0iqNrySqQiWMdZircQQIhAJs3laSeG577xHgy6EAyuOZLMLKHt1dr+SIDeIsFNkgl","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":71301},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"57efb65e023b464a2bd96c346f51b649c05d775e","scripts":{"tsc":"tsgo --noEmit","test":"vitest run --coverage","build":"unbuild","check":"biome check --write","dev:r":"pnpm run build && vite playground/react","dev:v":"pnpm run build && vite playground/vue3"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"Router for Single Page App on Google Apps Script","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","vite":"^7.1.12","jsdom":"^27.1.0","react":"^19.2.0","vitest":"^4.0.6","unbuild":"^3.6.1","react-dom":"^19.2.0","@types/node":"^24.9.2","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.2","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.6","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251101.1"},"peerDependencies":{"vue":">=3","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.2.1_1762961699063_0.4910917620223032","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@ciderjs/city-gas","version":"0.2.2","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.2.2","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"354c6c652c3542316f377ab36d0bfc2ea231aae1","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.2.2.tgz","fileCount":25,"integrity":"sha512-kl7g8dhMrRXKyHjBMr98Wix26EIyJ+nXYLaUY5aiIXu4Cbb5u2fXvRD6lX5UsJNUJJHO3p9l6NrSv8zO5kOdOQ==","signatures":[{"sig":"MEUCIQCxDhXm37g9i0X1Ud4o2cDRWz6IEOCdOGu25DvZFxUe5AIgfSrrlEHs8GkRFyMrjxRnQsovsGO7bcYN8CZitsx375s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":72515},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"047063b7bca5c7a2be608253e0063e8ee8c2ddc9","scripts":{"tsc":"tsgo --noEmit","test":"vitest run --coverage","build":"unbuild","check":"biome check --write","dev:r":"pnpm run build && vite playground/react","dev:v":"pnpm run build && vite playground/vue3"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"Router for Single Page App on Google Apps Script","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","vite":"^7.1.12","jsdom":"^27.1.0","react":"^19.2.0","vitest":"^4.0.6","unbuild":"^3.6.1","react-dom":"^19.2.0","@types/node":"^24.9.2","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.2","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.6","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251101.1"},"peerDependencies":{"vue":">=3","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.2.2_1763133706740_0.11456988284096403","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@ciderjs/city-gas","version":"0.3.0","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.3.0","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"eaa623e0b244547dd18115ae956b305c74bb6197","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.3.0.tgz","fileCount":25,"integrity":"sha512-0qE8bZefYxyE93JYJm7MTRcKEWW2vSYLkJoNEYHFW1T0CSwNDec8f1st/nnZCmjT/WPaYMsKIhHI8MxUb2PhJQ==","signatures":[{"sig":"MEUCIHE0nWpaJp5dgEpA5+m09mu7XPuouDoFWAHPT3Ne5O3nAiEAlyiJacYF8vVGhoM56PYgkdq9vge/DsGfM3hyShXM0YI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":88830},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"7a3f7515aa1d4d37f603a361d7322134149d1151","scripts":{"tsc":"tsgo --noEmit","test":"vitest run --coverage","build":"unbuild","check":"biome check --write","dev:r":"pnpm run build && vite playground/react","dev:v":"pnpm run build && vite playground/vue3"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"Router for Single Page App on Google Apps Script","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","vite":"^7.1.12","jsdom":"^27.1.0","react":"^19.2.0","vitest":"^4.0.6","unbuild":"^3.6.1","react-dom":"^19.2.0","@vitest/ui":"^4.0.9","@types/node":"^24.9.2","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.2","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.6","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251101.1"},"peerDependencies":{"vue":">=3","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.3.0_1763862818894_0.828039887627319","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@ciderjs/city-gas","version":"0.3.1","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.3.1","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"8dc6433227649662ffec2027a54b6070b6b4d033","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.3.1.tgz","fileCount":25,"integrity":"sha512-jOcC0TLC2jOKjWffIMMzZ4pL8+HJdrTvvaPjJ/1YVJsfKM2qfc9MYZTj4/pKEmX6AY1K7IlwIFKbWCuEnNIGOw==","signatures":[{"sig":"MEUCIFtIYZpfuHu/L3tsOa7X9Pnkkbc9alXVo1WKNRPyaREAAiEA4AujBwnjds8hfJ29PQMgv9uolUH4aLDRKD1iMDmhoYE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":89352},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"e65199a6f93946208cefb55fc77538bec329c4b2","scripts":{"tsc":"tsgo --noEmit","test":"vitest run --coverage","build":"unbuild","check":"biome check --write","dev:r":"pnpm run build && vite playground/react","dev:v":"pnpm run build && vite playground/vue3"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"Router for Single Page App on Google Apps Script","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","vite":"^7.1.12","jsdom":"^27.1.0","react":"^19.2.0","vitest":"^4.0.6","unbuild":"^3.6.1","react-dom":"^19.2.0","@vitest/ui":"^4.0.9","@types/node":"^24.9.2","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.2","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.6","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251101.1"},"peerDependencies":{"vue":">=3","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.3.1_1763936512600_0.19035398787951396","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@ciderjs/city-gas","version":"0.4.0","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@0.4.0","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"08047d87ccac2e4abe84a5dce9250988d3b691ca","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-0.4.0.tgz","fileCount":25,"integrity":"sha512-VWR7g20vudXuqfDJQTN+14tEWxbKDkwVGuJQJt1bUcNCJY5hSijY6NfoP9ujD9S133MXTlM1t03A2zW9Dp2Qxw==","signatures":[{"sig":"MEUCIHQILonUN25a2HQTJheP0JVMBCOcvbATdHW20EH7p1bBAiEAxtQ3kbZepzTj0Sah8fOEmeDvhnBO+9T5qoMODxi8irk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":117957},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"40644d9c4be803b1ba16de3cbd3d227b97de482e","scripts":{"tsc":"tsgo --noEmit","test":"vitest run --coverage","build":"unbuild","check":"biome check --write","dev:r":"vite playground/react","dev:v":"vite playground/vue3","dev:r:b":"pnpm run build && pnpm run dev:r","dev:v:b":"pnpm run build && pnpm run dev:v"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"Router for Single Page App on Google Apps Script","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","zod":"^4.1.12","vite":"^7.1.12","jsdom":"^27.1.0","react":"^19.2.0","vitest":"^4.0.6","unbuild":"^3.6.1","react-dom":"^19.2.0","@vitest/ui":"^4.0.9","@types/node":"^24.9.2","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.2","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.6","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251101.1"},"peerDependencies":{"vue":">=3","zod":">=4","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_0.4.0_1764057917286_0.5017741366352793","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@ciderjs/city-gas","version":"1.0.0","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@1.0.0","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"e3ca8e6ca75a035af61a3c68884795c4ab85e5c2","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-1.0.0.tgz","fileCount":25,"integrity":"sha512-qJJxF+bUN09GYJGay6TnBXdC7qPN5aCKOs3vqdDw2GIuBSOfr2g4bWXIxBK8WXUbnArhZn1k7UiZ26yA1jYPAg==","signatures":[{"sig":"MEUCIQCajLM+VNhS0Otk1qeTA2fuMI9OXFX7QhwYNCM0etk7agIgXrs8sqDsbvj/AZTQNxZR0TRE7inLJSEsy8+hyT928qM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":128333},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"bda59096f82681d9954c768aceefb3535cef8daa","scripts":{"tsc":"tsgo --noEmit","test":"vitest run --coverage","build":"unbuild","check":"biome check --write","dev:r":"vite playground/react","dev:v":"vite playground/vue3","dev:r:b":"pnpm run build && pnpm run dev:r","dev:v:b":"pnpm run build && pnpm run dev:v"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"Router for Single Page App on Google Apps Script","directories":{},"_nodeVersion":"20.19.5","dependencies":{"fast-glob":"^3.3.3","typescript":"^5.9.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","zod":"^4.1.12","vite":"^7.1.12","jsdom":"^27.1.0","react":"^19.2.0","vitest":"^4.0.6","unbuild":"^3.6.1","react-dom":"^19.2.0","@vitest/ui":"^4.0.9","@types/node":"^24.9.2","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.2","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.6","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251101.1"},"peerDependencies":{"vue":">=3","zod":">=4","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_1.0.0_1764386978652_0.65156264905795","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@ciderjs/city-gas","version":"1.1.0","keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","_id":"@ciderjs/city-gas@1.1.0","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"dist":{"shasum":"78ae88e1bd8dcc3fe4ffcb4590f2117a0daf64b3","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-1.1.0.tgz","fileCount":25,"integrity":"sha512-ZasqydixPuA8Cq3QVH4IrfWdmFU0dhejoEa7dMRIBrI6wyxSEvDcG9088IOwU1fRLNGhKChs3lRGG4P/tyAlRA==","signatures":[{"sig":"MEQCID8c0PuN6IGN6llVA/nkLxU/cc82igmvclKtI4RusW9/AiA4msY8xd9XUpCkneeYi3TjoaavdkkvP/urvvmHua5vgw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":127899},"main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"}},"gitHead":"42c9fdc1de1273e5444bac0156c80ecaba17d5ec","scripts":{"tsc":"tsgo --noEmit","test":"vitest run --coverage","build":"unbuild","check":"biome check --write","dev:r":"vite playground/react","dev:v":"vite playground/vue3","dev:r:b":"pnpm run build && pnpm run dev:r","dev:v:b":"pnpm run build && pnpm run dev:v"},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"_npmVersion":"10.8.2","description":"Router for Single Page App on Google Apps Script","directories":{},"_nodeVersion":"20.19.6","dependencies":{"ts-morph":"^27.0.2","fast-glob":"^3.3.3","@vue/compiler-sfc":"^3.5.22"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.18.3","devDependencies":{"vue":"^3.5.22","zod":"^4.1.12","vite":"^7.1.12","jsdom":"^27.1.0","react":"^19.2.0","vitest":"^4.0.6","unbuild":"^3.6.1","react-dom":"^19.2.0","@vitest/ui":"^4.0.9","typescript":"^5.9.3","@types/node":"^24.9.2","@types/react":"^19.2.2","@vue/tsconfig":"^0.8.1","@biomejs/biome":"^2.3.2","@vue/test-utils":"^2.4.6","@types/react-dom":"^19.2.2","@vitejs/plugin-vue":"^6.0.1","@vitest/coverage-v8":"4.0.6","vite-tsconfig-paths":"^5.1.4","@vitejs/plugin-react":"^5.1.0","@testing-library/react":"^16.3.0","@testing-library/jest-dom":"^6.9.1","@typescript/native-preview":"7.0.0-dev.20251101.1"},"peerDependencies":{"vue":">=3","zod":">=4","vite":">=7","react":">=18","react-dom":">=18"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/city-gas_1.1.0_1764775942002_0.52411513657954","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@ciderjs/city-gas","version":"1.1.1","description":"Router for Single Page App on Google Apps Script","main":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.cjs"},"./plugin":{"types":"./dist/plugin.d.ts","import":"./dist/plugin.mjs","require":"./dist/plugin.cjs"},"./react":{"types":"./dist/react.d.ts","import":"./dist/react.mjs","require":"./dist/react.cjs"},"./vue":{"types":"./dist/vue.d.ts","import":"./dist/vue.mjs","require":"./dist/vue.cjs"}},"scripts":{"dev:r":"vite playground/react","dev:v":"vite playground/vue3","dev:r:b":"pnpm run build && pnpm run dev:r","dev:v:b":"pnpm run build && pnpm run dev:v","tsc":"tsgo --noEmit","check":"biome check --write","build":"unbuild","test":"vitest run --coverage"},"keywords":["gas","google-apps-script","react","vue","router"],"author":{"name":"ciderjs/luth"},"license":"MIT","packageManager":"pnpm@10.18.3","dependencies":{"@vue/compiler-sfc":"^3.5.32","fast-glob":"^3.3.3","glob":"^13.0.6","ts-morph":"^28.0.0"},"devDependencies":{"@biomejs/biome":"^2.4.12","@testing-library/jest-dom":"^6.9.1","@testing-library/react":"^16.3.2","@types/node":"^25.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@typescript/native-preview":"7.0.0-dev.20260419.1","@vitejs/plugin-react":"^6.0.1","@vitejs/plugin-vue":"^6.0.6","@vitest/coverage-v8":"4.1.4","@vitest/ui":"^4.1.4","@vue/test-utils":"^2.4.6","@vue/tsconfig":"^0.9.1","jsdom":"^29.0.2","react":"^19.2.5","react-dom":"^19.2.5","typescript":"^6.0.3","unbuild":"^3.6.1","vite":"^8.0.9","vitest":"^4.1.4","vue":"^3.5.32","zod":"^4.3.6"},"peerDependencies":{"react":">=18","react-dom":">=18","vite":">=7","vue":">=3","zod":">=4"},"peerDependenciesMeta":{"react-dom":{"optional":true}},"overrides":{"axios":"1.14.0"},"pnpm":{"overrides":{"axios":"1.14.0"}},"_id":"@ciderjs/city-gas@1.1.1","gitHead":"29defe4b558b9e81f8d49b320d66ce5c5d55d043","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-zdBppiuehNVZ7XWY/UNga4PSMi/b301f+YJ5JlqU/AjUUoPx/Dct5/x9w0jJPF2EeuSMP3W2F8+mQFWUhCbpLA==","shasum":"88bcd80269ce544303f1ca60682fa95bc214afb0","tarball":"https://registry.npmjs.org/@ciderjs/city-gas/-/city-gas-1.1.1.tgz","fileCount":25,"unpackedSize":129380,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIGVW6u/HOJcA5Zd50dFHUR87nLf+tx8ssXdY9qHexDHVAiEAke/AB62SX6UsrIHRW8tYkRoh2hZ1yY+u/CQrJjyek/k="}]},"_npmUser":{"name":"luth","email":"cider6482+npm@gmail.com"},"directories":{},"maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/city-gas_1.1.1_1776869697390_0.18905361665977272"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-22T02:50:22.627Z","modified":"2026-04-22T14:54:57.662Z","0.1.0":"2025-10-22T02:50:22.908Z","0.1.1":"2025-10-28T04:28:48.462Z","0.1.2":"2025-10-30T11:31:19.119Z","0.1.3":"2025-10-31T15:23:38.518Z","0.2.0":"2025-11-01T15:55:51.023Z","0.2.1":"2025-11-12T15:34:59.240Z","0.2.2":"2025-11-14T15:21:46.943Z","0.3.0":"2025-11-23T01:53:39.094Z","0.3.1":"2025-11-23T22:21:52.797Z","0.4.0":"2025-11-25T08:05:17.483Z","1.0.0":"2025-11-29T03:29:38.876Z","1.1.0":"2025-12-03T15:32:22.176Z","1.1.1":"2026-04-22T14:54:57.538Z"},"author":{"name":"ciderjs/luth"},"license":"MIT","keywords":["gas","google-apps-script","react","vue","router"],"description":"Router for Single Page App on Google Apps Script","maintainers":[{"name":"luth","email":"cider6482+npm@gmail.com"}],"readme":"# @ciderjs/city-gas\n\n[![README-ja](https://img.shields.io/badge/日本語-blue?logo=ReadMe)](README.ja.md)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n[![npm version](https://img.shields.io/npm/v/@ciderjs/city-gas.svg)](https://www.npmjs.com/package/@ciderjs/city-gas)\n[![GitHub issues](https://img.shields.io/github/issues/luthpg/city-gas.svg)](https://github.com/luthpg/city-gas/issues)\n\n**@ciderjs/city-gas** is a type-safe, file-based router for **React** and **Vue 3** that operates seamlessly in both **Google Apps Script (GAS)** and **modern browser** environments.\n\n## ✨ Features\n\n* 🚀 **Universal**: Works in both browser (`window.history`) and GAS (`google.script.history`) environments, automatically switching adapters.\n* 📂 **File-based Routing**: Routes are automatically generated based on the structure of your `src/pages` directory. Internally, it uses the `?page=...` query parameter to simulate path routing, conforming to the constraints of the GAS environment.\n* 🛡️ **Type Safety**: Use **Zod schemas** to define query parameters, providing strict type checking and runtime validation for both path and query parameters.\n* 🤖 **Auto Generation**: A Vite plugin automatically generates route definitions and type declarations (`.d.ts`), enabling powerful autocomplete for `Maps` and `useParams`.\n* 🧩 **Nested Layouts**: Flexible layout system using special files like `_layout` and `_root`.\n\n---\n\n## 📦 Installation\n\nThis package requires `react` / `vue`, `vite`, and `zod`.\n\n```bash\n# npm\nnpm install @ciderjs/city-gas zod\n\n# pnpm\npnpm add @ciderjs/city-gas zod\n\n# yarn\nyarn add @ciderjs/city-gas zod\n```\n\n---\n\n## 📖 General Routing Guide\n\n### Directory Structure and Mapping\n\nFiles under `src/pages` (configurable) become your routes.\n\n```text\nsrc/pages/\n├── index.tsx           -> \"/\"\n├── about.tsx           -> \"/about\"\n├── users/\n│   ├── index.tsx       -> \"/users\"\n│   └── show.tsx        -> \"/users/show\"\n└── posts/\n    └── [postId].tsx    -> \"/posts/[postId]\" (Dynamic Route)\n```\n\n> [!NOTE]\n> **Priority between index and same-name files**\n> If both `src/pages/users.tsx` and `src/pages/users/index.tsx` exist, the child directory's `index.tsx` (`/users`) takes priority and is registered as the route. The file in the parent directory is ignored.\n\n### Dynamic Routes and Path Parameters\n\nUse the naming convention `[paramName].tsx` to create dynamic routes and access path parameters.\n\n> [!TIP]\n> **Path Parameter Schema Definition**\n> Path parameters (e.g., `[id]`) are treated as `z.string()` by default, even if you do not explicitly declare them in your schema.\n> If you explicitly define them in the schema (e.g., `id: z.coerce.number()`), your custom definition takes priority.\n\n### Nested Layouts\n\nSpecial filenames are used to achieve hierarchical layouts.\n\n* **`_root.tsx`**: The highest-level layout wrapping the entire application.\n* **`_layout.tsx`**: A layout applied to all routes within the directory it is placed in.\n* **`_404.tsx`**: The component displayed when an undefined route is accessed.\n* **`_loading.tsx`**: The component displayed during page transitions or initialization.\n\n---\n\n## ⚛️ React Guide\n\n### 1. Vite Configuration\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite';\nimport { cityGasRouter } from '@ciderjs/city-gas/plugin';\nimport react from '@vitejs/plugin-react';\n\nexport default defineConfig({\n  plugins: [\n    react(),\n    cityGasRouter(),\n  ],\n});\n```\n\n### 2. Application Entry Point (`src/main.tsx`)\n\n```tsx\nimport React from 'react';\nimport ReactDOM from 'react-dom/client';\nimport { createRouter } from '@ciderjs/city-gas';\nimport { RouterProvider } from '@ciderjs/city-gas/react';\nimport { pages, specialPages, dynamicRoutes } from './generated/routes';\n\nconst router = createRouter(pages, { specialPages, dynamicRoutes });\n\nReactDOM.createRoot(document.getElementById('root')!).render(\n  <React.StrictMode>\n    <RouterProvider router={router} />\n  </React.StrictMode>,\n);\n```\n\n### 3. Page Component and Schema Definition\n\nA page component must be defined as the `default export`.\nBy exporting a `schema` from your page component file, you can define the expected parameters.\n\n```tsx\n// src/pages/search/[categoryId].tsx\nimport { z } from 'zod';\nimport { useParams, useNavigate } from '@ciderjs/city-gas/react';\n\n// Schema definition\nexport const schema = z.object({\n  q: z.string(),\n  pageIndex: z.coerce.number().optional(), // 'page' is reserved and cannot be used\n});\n\nexport default function SearchPage() {\n  // Path parameter (categoryId) and query parameters (q, pageIndex) are inferred\n  const params = useParams('/search/[categoryId]');\n  const navigate = useNavigate();\n\n  return (\n    <div>\n      <h1>Category: {params.categoryId}</h1>\n      <p>Search: {params.q}</p>\n      <button onClick={() => navigate('/search/[categoryId]', { categoryId: '1', q: 'react' })}>\n        Search\n      </button>\n    </div>\n  );\n}\n```\n\n---\n\n## 💚 Vue Guide\n\n### 1. Vite Configuration\n\n```ts\n// vite.config.ts\nimport { defineConfig } from 'vite';\nimport { cityGasRouter } from '@ciderjs/city-gas/plugin';\nimport vue from '@vitejs/plugin-vue';\n\nexport default defineConfig({\n  plugins: [\n    vue(),\n    cityGasRouter(),\n  ],\n});\n```\n\n### 2. Application Entry Point (`src/main.ts`)\n\n```ts\nimport { createApp } from 'vue';\nimport { createRouter } from '@ciderjs/city-gas';\nimport { createRouterPlugin, RouterOutlet } from '@ciderjs/city-gas/vue';\nimport { pages, specialPages, dynamicRoutes } from './generated/routes';\n\nconst router = createRouter(pages, { specialPages, dynamicRoutes });\nconst app = createApp(RouterOutlet);\n\napp.use(createRouterPlugin(router));\napp.mount('#app');\n```\n\n### 3. Page Component and Schema Definition\n\nSince `export` statements are not strictly supported within Vue's `<script setup>` syntax for this purpose, you must define and export the `schema` within a separate, standard `<script>` block.\n\n```vue\n<script setup lang=\"ts\">\nimport { useParams, useNavigate } from '@ciderjs/city-gas/vue';\n\nconst params = useParams('/search/[categoryId]');\nconst navigate = useNavigate();\n\nconst handleClick = () => {\n  navigate('/search/[categoryId]', { categoryId: '1', q: 'vue' });\n};\n</script>\n\n<script lang=\"ts\">\nimport { z } from 'zod';\n\nexport const schema = z.object({\n  q: z.string(),\n  pageIndex: z.coerce.number().optional(), // 'page' is reserved and cannot be used\n});\n</script>\n\n<template>\n  <div>\n    <h1>Category: {{ params.categoryId }}</h1>\n    <p>Search: {{ params.q }}</p>\n    <button @click=\"handleClick\">Search</button>\n  </div>\n</template>\n```\n\n---\n\n## ⚙️ API Reference (General)\n\n### `createRouter(pages, options)`\n\nCreates the router instance.\n\n* `pages`: The page definitions imported from `.generated/routes.ts`.\n* `options`:\n    * `specialPages`: Definitions for special pages like `_root`, `_layout`, etc.\n    * `dynamicRoutes`: Definitions used for dynamic route matching.\n    * `defaultRouteName`: The default route (usually `'/'`).\n\n### `router` Instance\n\n* `router.navigate(name, params, options)`: Navigates to the specified route.\n* `router.subscribe(listener)`: Subscribes to route changes.\n* `router.getCurrentRoute()`: Gets the current route information.\n* `router.beforeEach(guard)`: Registers a navigation guard.\n\n#### Navigation Guard\n\n```ts\nrouter.beforeEach((to, from, next) => {\n  if (to.name === '/admin' && !isAdmin) {\n    // Redirect to login page\n    next('/login');\n  } else {\n    // Allow transition\n    next();\n    // Alternatively, next(false) to cancel the transition\n  }\n});\n```\n\n### Hooks / Composables\n\n* `useParams(routeName)`: Retrieves parameters for the current route. Passing a `routeName` narrows the type.\n* `useNavigate()`: Returns the navigation function.\n* `useRoute()`: Returns the entire current route object, including name and parameters.\n\n---\n\n## ⚠️ Known Limitations\n\n### Schema Definition\nThe `schema` export for parameters must be defined **within the same file** as the page component.\nImporting schemas from external files is not supported because the Vite plugin uses static AST analysis to generate types.\n\n### The Reserved Word `page`\nThis library internally uses the `?page=...` query parameter in the URL to resolve file-based routes.\nTherefore, you cannot use the key `page` as a parameter name in your schema definitions. If you need pagination, please use a different name such as `pageIndex`.\n\n### URL Length Limitations in GAS\nGoogle Apps Script (GAS) environments have strict URL length limits (approximately 2KB).\nSince this library serializes object parameters into JSON strings within the URL, passing large data structures may cause errors.\nFor large datasets, consider using `PropertiesService`, `CacheService`, or a global state management library instead of passing them as route parameters.\n\n### Global Side Effects and Cleanup\nFor static analysis and type generation, this library evaluates (imports) all page files at application startup. Please be aware of the following:\n\n* **Avoid Top-Level Side Effects**: Do not write `console.log`, API calls, or event listener registrations outside of your component function (at the file's top level). These will execute immediately when the application starts, even if the user never navigates to that page. Always place initialization logic inside `useEffect` (React) or `onMounted` (Vue).\n* **Always Clean Up**: Because it's a Single Page Application (SPA), JavaScript state persists across page transitions. If you register a `setInterval` or an event listener inside `useEffect` or `onMounted`, you must return a cleanup function to prevent memory leaks and unintended background execution on other pages.\n\n---\n\n## 🤝 Contribution Guide\n\nThank you for considering contributing to `city-gas`!\n\n### Setting up the Development Environment\n\n```bash\n# Clone the repository\ngit clone https://github.com/luthpg/city-gas.git\ncd city-gas\n\n# Install dependencies (please use pnpm)\npnpm install\n\n# Build the packages\npnpm build\n```\n\n### Running the Playground\n\nThe repository includes playgrounds for both React and Vue to test changes.\n\n```bash\n# Start the React playground\npnpm run dev:r\n\n# Start the Vue playground\npnpm run dev:v\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npnpm test\n\n# Run type checks\npnpm run check\n```\n\n### Pull Request Guidelines\n\n1.  Create a branch for each feature or bug fix.\n2.  Add tests corresponding to your changes.\n3.  Write clear and concise commit messages.\n4.  Ensure that `pnpm test` and `pnpm run check` pass before creating a PR.\n\n---\n\n## 📝 License\n\nMIT License\n","readmeFilename":"README.md"}