{"_id":"@angsana_consulting/api-core","_rev":"14-13e33ff70a60e9d16546b647f3d67edd","name":"@angsana_consulting/api-core","dist-tags":{"latest":"1.1.1"},"versions":{"1.0.3":{"name":"@angsana_consulting/api-core","version":"1.0.3","_id":"@angsana_consulting/api-core@1.0.3","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"e361d2bcffd8d6cc445e4c68421bc224891b880b","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.3.tgz","fileCount":25,"integrity":"sha512-Qsq0pbTY3iuNId+O9yYHDee8XwMEpHLc5Zd5SSu0AaX3ih0DJmdj/wqLyCxmI8oIoy+FhGRxoiFrxg3BoFyLLg==","signatures":[{"sig":"MEYCIQDOb3A+8S/L9/InsMl4tHfycPwn1T8IhMOUcPFbPBx3UwIhANQVvimBIO7eQAvMezb9Dy/cfpeB2Z752RV0+9u/gMC7","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98997},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"09dcf5db8a47885f9f4fa9c3263127a4af01f85e","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.3_1759410172261_0.5260049564621283","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@angsana_consulting/api-core","version":"1.0.4","_id":"@angsana_consulting/api-core@1.0.4","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"46d2e3a84751ec3467f6bf94f96170f1b8ba61b6","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.4.tgz","fileCount":25,"integrity":"sha512-Xni37cBth4vAimDh2piGSfpy88JbP6O80pUbbGs3HrjXSnoNxEtbbF1uocPDjlXZpYO5F1ImtxUooD5PWdoNmQ==","signatures":[{"sig":"MEQCIFPwaSc8abusc+NqN3DG3MzkIKIpweeVzStZAv4CGzo3AiBXQT15dnUo/TdRjHpWMSs7w1p/j6kVU96BVX2BW5Qt6A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98997},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"1f7617dff0ad2deb990cc2509d8e8077350752dc","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.4_1759413482956_0.9365233897209759","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@angsana_consulting/api-core","version":"1.0.5","_id":"@angsana_consulting/api-core@1.0.5","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"4995b362bf5621a84145ffa34b0be6f90928d326","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.5.tgz","fileCount":25,"integrity":"sha512-tXGqep4O/+haeVZSyFnRjIOnmtb62505agRhFLcaAhQgdS1fr+Z7v9z3z8Vqn9A/eW9DNmN7aFNSOEpPTBG33Q==","signatures":[{"sig":"MEQCIF7JsfX2RxJB4somHLs8cCdjCLSwTOpKFRXmQr6lQca3AiBNobyn9l7BTqd1RPaApAEQvM6v0SMuUPtnuzQsMDfFIQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":100849},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"387c02bae028907ec4fb9c10117bc20c35842bc5","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.5_1759941934377_0.12514479720817206","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@angsana_consulting/api-core","version":"1.0.6","_id":"@angsana_consulting/api-core@1.0.6","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"92606ea33305f5c94dd5a73d4fd231048b315c42","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.6.tgz","fileCount":25,"integrity":"sha512-8ZBsgYVE5Y8FzmWVWKlQMFQaPwE50DUKuFzFM3P5JZ57XwgsSi7iV+BVCQBLZ3exkrvXTpcEtCo1m77HsKI5Ww==","signatures":[{"sig":"MEUCICvurAFXkTV2fRWEQCUjomYlGsmGGU+3lqhS/l3DKaIdAiEAvQAUxblVOQRBv383BszMBFrm6PeV2BbfRV6f2KcgSM8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":104522},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"387c02bae028907ec4fb9c10117bc20c35842bc5","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.6_1760000139113_0.6641908355227792","host":"s3://npm-registry-packages-npm-production"}},"1.0.7":{"name":"@angsana_consulting/api-core","version":"1.0.7","_id":"@angsana_consulting/api-core@1.0.7","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"e733cbc4f4a946123474f70c4da77eba537e7ae3","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.7.tgz","fileCount":25,"integrity":"sha512-11oD09MdU0Yv1q1jQiq9cb52ZF8uiYhta+jwsmowvRu+3xXTohghlYNS4U4ZFr76ApVKqYCcTWEu81s8ymWt2Q==","signatures":[{"sig":"MEYCIQCP/Ec1J6xozJihxHlnPGhRX93NImN1i4XPZ4FZJuH+rAIhAM3P6TuXDuhOdKY6G/6OBRViSCtK20Nk0OUwDyMfcK08","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112957},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"f657952ed5a65d953ec485e2dafda58c40a50721","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.7_1760003128971_0.4075997022844482","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@angsana_consulting/api-core","version":"1.0.8","_id":"@angsana_consulting/api-core@1.0.8","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"07655d641211c352a65bbe0368b759ea2ac048d5","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.8.tgz","fileCount":25,"integrity":"sha512-cBZidn8x4XxXGy3PZ3fVft7giA5tozeI/3RZ6WWrwaDrTqSNIVaf18s1T+iemjxZyngrJSXuA0avhWqriWySzA==","signatures":[{"sig":"MEUCIQCX2n4wwTlb4sg29S9Cx6ge7Ks/KQfLAQ1f5TrQH9NLKAIgSo4sEnOei5rwCnIUQDPzMiB4VKD/q5NhyYKH5L/HA9A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112935},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"ccf2dce1ab3ce0811b4317372bcb710f6b8c72fa","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.8_1760006700344_0.6829207032872557","host":"s3://npm-registry-packages-npm-production"}},"1.0.9":{"name":"@angsana_consulting/api-core","version":"1.0.9","_id":"@angsana_consulting/api-core@1.0.9","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"8e3e296cbc5acc82303cef7054ce7ee063df1e72","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.9.tgz","fileCount":25,"integrity":"sha512-KPLflsqtVsENGAJtu9T/5A4pn8Del3RrdJtdPRK7eZ45L6E5MgEBJ508M33q4FpBBiTzM6dpKPCjgAPT0d4SlQ==","signatures":[{"sig":"MEUCIAdj3wxIt+fKWKZl8ICC3HskiFFs2Uvh4LPIbemULUQAAiEArh3rsxm6tV3667FzDQCzlfp00Z5QPmneehX5kD4frp8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113785},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"4bb8b68fc94cf72f7a2929b73ea12a84d86484a4","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.9_1760075356871_0.14899839330166453","host":"s3://npm-registry-packages-npm-production"}},"1.0.10":{"name":"@angsana_consulting/api-core","version":"1.0.10","_id":"@angsana_consulting/api-core@1.0.10","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"51e85b965e85cfea642ef6fcd92a32493d93d8b5","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.10.tgz","fileCount":25,"integrity":"sha512-5DsSsbkkIaJaUPbwYKY3Lq2ExJDOH0oeeb2yq0WCxwRRWqaZniTQVOyle4SSHCWqOR+5xG71jWnRGoiol0oYbA==","signatures":[{"sig":"MEYCIQC2qlYDQvqWeySyGUMpuGbrn2fHejhopSM2p4mDzUn8QAIhAPE9i34OTvuGq8n+Nie4LajCAZ8K4tTcevFS6EKYniiY","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":114253},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"2ea2f31cce3a025f048acdbcf83a3a17b3379529","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.10_1760077269233_0.3449472298881091","host":"s3://npm-registry-packages-npm-production"}},"1.0.11":{"name":"@angsana_consulting/api-core","version":"1.0.11","_id":"@angsana_consulting/api-core@1.0.11","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"6e9a490ecf9a24012caff2565dfb15a9396c86dc","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.11.tgz","fileCount":25,"integrity":"sha512-r4bysfulIgjFYfxJsT0DIUlv0xw/k3E+oUHt1VO9we3q1giLVLxhr8WShMGU40BI2hld3zh9i5mL/klCj0njdg==","signatures":[{"sig":"MEUCIF3CIbvumFs00t7AhvZAt+GNZ63IF4qsHna7+pFb2JwUAiEAlBrH/jlUKthGNI8TcYJn6V0evb4Ct1t9HoBFSS6L+8U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":115449},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"f7308949ee4f3503f9b9a5b6d978e2cbde1d0553","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.11_1760086508005_0.15451652902418123","host":"s3://npm-registry-packages-npm-production"}},"1.0.12":{"name":"@angsana_consulting/api-core","version":"1.0.12","_id":"@angsana_consulting/api-core@1.0.12","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"0bf902df80057664f5ef4cbfc825cd7634fe9e58","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.12.tgz","fileCount":25,"integrity":"sha512-q9zJM0vzzD/Ia+NkFc8Trl7lQJrBoD1eGgWyDXSaHamytJmeVuwABylFLUsIt7st68FytpoFA9+00sCwnkXKQQ==","signatures":[{"sig":"MEYCIQCNVAHWEcc4YQZ9K9VrkwTTl8hO65xB6IVP8wQwPpWr7QIhAJdDM7uPapqRAzSGMsAQO5hPRABG55bIXeU8NwCJ8vlK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":116007},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"3bb6b56a5b52aeb587439ac69421cf86128f80cd","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.12_1760089850717_0.4980626858044057","host":"s3://npm-registry-packages-npm-production"}},"1.0.13":{"name":"@angsana_consulting/api-core","version":"1.0.13","_id":"@angsana_consulting/api-core@1.0.13","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"360d7cd967f6145ff5578f5ac4c093b18b9edc0e","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.13.tgz","fileCount":25,"integrity":"sha512-5Q1EzVNpaZE+AzXGEK8ujswC/CA35dc6MsdcqvUYGoYhc86xF3EdRiJl+dp1iEgYazpIbFpzahvKEBvLhuXjaA==","signatures":[{"sig":"MEUCIFZTrDOc1wR7nj33lc7F6nPlweVUL8eK4c36R8i/chkqAiEAjEfZz79sBJU3ZJKV2qtCCw/+DMJEPMph7z5C0N+1SmI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113903},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"1ec9f9719cfcb402704f87c49acf2e2a55fb4f9c","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.13_1760176788852_0.10699913854683696","host":"s3://npm-registry-packages-npm-production"}},"1.0.14":{"name":"@angsana_consulting/api-core","version":"1.0.14","_id":"@angsana_consulting/api-core@1.0.14","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"8d6448e1092f81caa9b4cead05032d655694115e","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.0.14.tgz","fileCount":25,"integrity":"sha512-uSVR07E0LYyHQ9fYsNbgR4hC3XCVwMkFWKPdJHdbkBLtSdw6FJIqlUCRm5K9UsW5U43bgRX9TvkqtDzpI/IH8g==","signatures":[{"sig":"MEYCIQCeuRhx0SzAftT8PVvdO4sb677bFAL1APmqpVhilHs+JAIhAJtd9lpMUxrtR2xE2N/aL46zE41zQ5ktwtp5Q1DRDsN5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":113351},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"50fc7847ebfa9e023567ddac33ca63f4ff55f420","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.0.14_1760178894857_0.0959293637483416","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@angsana_consulting/api-core","version":"1.1.0","author":{"name":"Angsana Business Consulting Ltd UK","email":"hello@angsana-uk.com"},"license":"MIT","_id":"@angsana_consulting/api-core@1.1.0","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"dist":{"shasum":"a6100e62ddac2e3599ce1df7d6c573cbc0a397c1","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.1.0.tgz","fileCount":26,"integrity":"sha512-AqvXEzdub7N9Adq2ryIFRKo+oyQPu3GaFSw2pgcExlhsObbD3VIW0mrTs4P0wIUXv3J5uX1G/Tck6bAzIzdvbA==","signatures":[{"sig":"MEUCICxJwblryTwi9sBZoBNeORf7M5mcbaHQoAHXZQN5sc7nAiEAjGT/W1ejPeHW+Ub6vtKbTNqLMqWGO4ytIWmGObVbwvo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":116076},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"8da2f14b5f5e37d14dfb8d03b88239856fde4275","scripts":{"build":"tsc || true","clean":"rm -rf dist .tsbuildinfo","build:watch":"tsc --watch","prepublishOnly":"npm run build"},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"_npmVersion":"10.9.2","description":"Core API utilities for Angsana platform","directories":{},"_nodeVersion":"22.15.1","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"express":"^4.18.0","typescript":"^5.0.0","@types/node":"^20.0.0","@types/express":"^4.17.17","firebase-admin":"^12.0.0"},"peerDependencies":{"express":"^4.18.0","firebase-admin":"^11.0.0 || ^12.0.0"},"_npmOperationalInternal":{"tmp":"tmp/api-core_1.1.0_1765787029031_0.15654555323079067","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@angsana_consulting/api-core","license":"MIT","author":{"name":"Angsana Business Consulting Ltd UK","email":"hello@angsana-uk.com"},"version":"1.1.1","description":"Core API utilities for Angsana platform","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc || true","build:watch":"tsc --watch","clean":"rm -rf dist .tsbuildinfo","prepublishOnly":"npm run build"},"peerDependencies":{"firebase-admin":"^11.0.0 || ^12.0.0","express":"^4.18.0"},"devDependencies":{"firebase-admin":"^12.0.0","express":"^4.18.0","@types/express":"^4.17.17","@types/node":"^20.0.0","typescript":"^5.0.0"},"publishConfig":{"access":"public"},"_id":"@angsana_consulting/api-core@1.1.1","gitHead":"e12f7787d81ac7051c0b20a29506b0c242c7678e","_nodeVersion":"22.15.1","_npmVersion":"10.9.2","dist":{"integrity":"sha512-SPGq/tiAqA8VL90Ozrr0zm0LPn7YXalkoR4QvlcRwZJFuwCdmAoATah5h3sXFiUfa6l+iK2HGaYEG4PaWtWn1w==","shasum":"4dd589b2b67a94de04eab8782da795b27cce29b0","tarball":"https://registry.npmjs.org/@angsana_consulting/api-core/-/api-core-1.1.1.tgz","fileCount":27,"unpackedSize":121949,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDDDXusH22BXajFQu9LzAblmnpofw3ygHmwqifHCsNv4AIgOBzpm/G5iB9KlFqrG5wNPBcVzF1LWBKxod/Ylg+Gh7M="}]},"_npmUser":{"name":"keithnew","email":"keith.new@aboutime.co.uk"},"directories":{},"maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/api-core_1.1.1_1765813756973_0.3377000304133573"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-02T13:02:52.172Z","modified":"2025-12-15T15:49:17.323Z","1.0.3":"2025-10-02T13:02:52.444Z","1.0.4":"2025-10-02T13:58:03.145Z","1.0.5":"2025-10-08T16:45:34.565Z","1.0.6":"2025-10-09T08:55:39.307Z","1.0.7":"2025-10-09T09:45:29.142Z","1.0.8":"2025-10-09T10:45:00.505Z","1.0.9":"2025-10-10T05:49:17.072Z","1.0.10":"2025-10-10T06:21:09.471Z","1.0.11":"2025-10-10T08:55:08.195Z","1.0.12":"2025-10-10T09:50:50.924Z","1.0.13":"2025-10-11T09:59:49.036Z","1.0.14":"2025-10-11T10:34:55.051Z","1.1.0":"2025-12-15T08:23:49.180Z","1.1.1":"2025-12-15T15:49:17.124Z"},"author":{"name":"Angsana Business Consulting Ltd UK","email":"hello@angsana-uk.com"},"license":"MIT","description":"Core API utilities for Angsana platform","maintainers":[{"name":"keithnew","email":"keith.new@aboutime.co.uk"}],"readme":"# @angsana_consulting/api-core\n\nFoundation toolkit for building authenticated Retool APIs on Firestore. Ships a hardened base handler, query parser, and Firestore query builder that match the router’s standards.\n\n---\n\n## 1. Purpose\n\n`@angsana_consulting/api-core` standardises how Retool-powered APIs interact with Firestore:\n\n- **Guard rails** – only registered collections and operations execute.\n- **Declarative querying** – parse complex `where` expressions (AND/OR, parentheses, custom operators).\n- **Efficient pagination** – translates compatible filters to native Firestore queries with automatic client-side fallbacks.\n- **Observability** – pluggable logger hook for duration/error reporting.\n\nUse it inside Cloud Functions, Express handlers, or any service that fronts Firestore collections for Retool.\n\n---\n\n## 2. Architecture Overview\n\n```\n Retool Request ──▶ BaseRetoolApi.handleRequest()\n                      │\n                      ├── validate collection + allowed ops\n                      ├── parse query params → Where AST\n                      ├── build Firestore query (native or hybrid)\n                      ├── run custom hooks (before*/after*)\n                      └── return typed ApiResponse\n```\n\n| Component | Description |\n|-----------|-------------|\n| `BaseRetoolApi` | Main request router, enforces collection policy and HTTP method guards. |\n| `whereParser` | Tokenises/astifies Retool `where` strings (supports `contains`, `startsWith`, nested groups). |\n| `firestoreQueryBuilder` | Converts AST → Firestore queries, falling back to client filtering when necessary. |\n| `types` | Re-export of Firebase/Express types plus shared interfaces. |\n\n---\n\n## 3. Directory Structure\n\n```\napi-core/\n├── src/\n│   ├── handlers/\n│   │   └── baseRetoolApi.ts      # Core handler class\n│   ├── parsers/\n│   │   ├── whereParser.ts        # WHERE clause tokenizer/parser\n│   │   └── firestoreQueryBuilder.ts\n│   ├── index.ts                  # Public exports\n│   └── types/                    # Type aliases + re-exports\n├── dist/                         # Compiled JS/typings\n└── package.json\n```\n\n---\n\n## 4. Installation\n\n```bash\nnpm install @angsana_consulting/api-core\n```\n\nPeer dependencies: `firebase-admin` (v11/v12) and `express`.\n\n---\n\n## 5. Quick Start\n\n```typescript\nimport { BaseRetoolApi, CollectionRegistry } from '@angsana_consulting/api-core';\nimport { db } from 'firebase-admin';\n\nconst collections: CollectionRegistry = {\n  ClientNumbers: {\n    autoId: false,\n    customIdField: 'number',\n    allowedOperations: ['GET', 'POST', 'PUT'],\n    notes: 'Client phone numbers synced from Retool'\n  }\n};\n\nconst handler = new BaseRetoolApi(db(), collections, 'dialer', console);\n\nexport const retoolApi = onRequest((req, res) => handler.handleRequest(req, res));\n```\n\n1. Register every collection with allowed HTTP verbs.\n2. Optionally provide `customHandlers` for lifecycle hooks.\n3. Deploy as an HTTPS/Express handler (e.g., Cloud Functions, Cloud Run).\n\n---\n\n## 6. Advanced Querying\n\n### Supported WHERE Syntax\n\n```\nstatus==active AND (priority>=3 OR country in['GB','US'])\ncreatedAt>=2024-01-01 AND createdAt<2024-02-01\nmessage contains \"callback failed\"\n```\n\n- Logical groups with parentheses.\n- Operators: `==`, `!=`, `<`, `<=`, `>`, `>=`, `in`, `array-contains`, `array-contains-any`, `startsWith`, `contains`.\n- Timestamp hints (`t`, `x`, `createdAt`, etc.) auto-cast to Firestore timestamps.\n\n### Firestore Compatibility\n\n- Automatic detection when filters can run entirely server-side.\n- Mixed inequality fields or OR trees fall back to client filtering with warning messages.\n- Pagination helpers (`limit`, `startAfter`) work alongside the hybrid model.\n\n---\n\n## 7. Custom Hooks\n\nEvery collection entry can declare async hooks:\n\n```typescript\ncustomHandlers: {\n  beforeCreate: async (data, ctx) => ({ ...data, createdAt: Date.now() }),\n  afterCreate: async (docRef, data) => audit(docRef.id, data),\n  beforeDelete: async (docId, ctx) => ctx.userId === 'admin'\n}\n```\n\n- Returning modified data allows sanitisation/enrichment.\n- Throwing an error aborts the request with a 400/500.\n- `beforeDelete` returning `false` denies the deletion.\n\n---\n\n## 8. Responses & Errors\n\nEvery route returns the standard `ApiResponse` interface:\n\n```jsonc\n{\n  \"success\": true,\n  \"count\": 25,\n  \"documents\": [\n    { \"id\": \"abc123\", \"data\": { \"number\": \"+44123...\" } }\n  ],\n  \"nextPageToken\": \"xyz\"\n}\n```\n\nFailures include contextual information:\n\n```jsonc\n{\n  \"error\": \"Operation not allowed\",\n  \"allowed\": [\"GET\", \"POST\"]\n}\n```\n\n---\n\n## 9. Logging Integration\n\nPass any logger with `info`/`error` methods (e.g., `pino`, `@angsana_consulting/utils` logger wrappers). The handler automatically logs request duration and failures for observability parity with the router.\n\n---\n\n## 10. Publishing\n\nThe package ships compiled JS in `dist/`. Run:\n\n```bash\ncd packages/api-core\nnpm run build\nnpm publish --access public\n```\n\nSee `PUBLISHING.md` for the workspace workflow.\n\n","readmeFilename":"README.md"}