{"id":13491814,"url":"https://github.com/sonyseng/json-caching-proxy","last_synced_at":"2026-01-26T21:24:14.531Z","repository":{"id":20576715,"uuid":"90311573","full_name":"sonyseng/json-caching-proxy","owner":"sonyseng","description":"Node caching HTTP proxy built on top of express-http-proxy. Persists requests and responses to an in-memory HAR-like data structure based on HAR1.2 . Caches JSON content-type responses by default with the ability to cache an entire site; including content-types describing images. Useful for testing front end code, mocking api, and saving the cache to a HAR file which can be used for further tests.","archived":false,"fork":false,"pushed_at":"2024-06-16T15:37:03.000Z","size":4373,"stargazers_count":44,"open_issues_count":2,"forks_count":9,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-19T09:03:45.736Z","etag":null,"topics":["cache","cache-storage","caching-library","cors-proxy","express","har","json-api","middleware","nodejs","proxy","proxy-server","reverse-proxy","testing"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sonyseng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-04T21:34:28.000Z","updated_at":"2025-09-11T01:05:32.000Z","dependencies_parsed_at":"2024-06-19T13:26:20.643Z","dependency_job_id":"73bf6993-461f-4a74-aff7-c85a46e1f1b3","html_url":"https://github.com/sonyseng/json-caching-proxy","commit_stats":{"total_commits":81,"total_committers":6,"mean_commits":13.5,"dds":"0.14814814814814814","last_synced_commit":"2b4df2f4bd5f01ce026cd5ae01c07f2842042a81"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"purl":"pkg:github/sonyseng/json-caching-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sonyseng%2Fjson-caching-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sonyseng%2Fjson-caching-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sonyseng%2Fjson-caching-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sonyseng%2Fjson-caching-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sonyseng","download_url":"https://codeload.github.com/sonyseng/json-caching-proxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sonyseng%2Fjson-caching-proxy/sbom","scorecard":{"id":838188,"data":{"date":"2025-08-11","repo":{"name":"github.com/sonyseng/json-caching-proxy","commit":"2b4df2f4bd5f01ce026cd5ae01c07f2842042a81"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.4,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 1/11 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/node.js.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":3,"reason":"dependency not pinned by hash detected -- score normalized to 3","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.js.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/sonyseng/json-caching-proxy/node.js.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node.js.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/sonyseng/json-caching-proxy/node.js.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   1 out of   1 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 27 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"12 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-76p7-773f-r4q5","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T19:44:40.112Z","repository_id":20576715,"created_at":"2025-08-23T19:44:40.112Z","updated_at":"2025-08-23T19:44:40.112Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28788369,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-26T21:13:08.818Z","status":"ssl_error","status_checked_at":"2026-01-26T21:13:08.448Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","cache-storage","caching-library","cors-proxy","express","har","json-api","middleware","nodejs","proxy","proxy-server","reverse-proxy","testing"],"created_at":"2024-07-31T19:01:00.482Z","updated_at":"2026-01-26T21:24:14.513Z","avatar_url":"https://github.com/sonyseng.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# json-caching-proxy ![Build Status](https://github.com/sonyseng/json-caching-proxy/actions/workflows/node.js.yml/badge.svg) [![NPM Version](http://img.shields.io/npm/v/json-caching-proxy.svg?style=flat)](https://www.npmjs.org/package/json-caching-proxy) [![NPM Downloads](https://img.shields.io/npm/dm/json-caching-proxy.svg?style=flat)](https://www.npmjs.org/package/json-caching-proxy)\r\n\r\nNode caching HTTP proxy built on top of [express-http-proxy](https://github.com/villadora/express-http-proxy). Persists requests and responses to an in-memory HAR-like data structure based on [HAR1.2](http://www.softwareishard.com/blog/har-12-spec/) . Caches JSON content-type responses by default with the ability to cache an entire site; including content-types describing images. Useful for testing front end code, mocking api, and saving the cache to a HAR file which can be used for further tests.\r\n\r\n## Installation\r\n\r\nRequires Node \u003e= 14\r\n\r\nCommand line tool:\r\n```\r\n$ npm install -g json-caching-proxy\r\n```\r\n\r\nProgrammatic:\r\n```\r\n$ npm install -D json-caching-proxy\r\n```\r\n\r\n## Command line usage\r\n\r\n```\r\n  Usage: json-caching-proxy [options]\r\n\r\n  Options:\r\n\r\n    -h, --help                   output usage information\r\n    -V, --version                output the version number\r\n    -c, --config [path]          load a config file of options. Command line args will be overridden\r\n    -u, --url [url]              remote server (e.g. https://network:8080)\r\n    -p, --port [number]          port for the local proxy server\r\n    -H, --har [path]             load entries from a HAR file and hydrate the cache\r\n    -b, --bust [list]            a list of cache busting query params to ignore. (e.g. --bust _:cacheSlayer:time:dc)\r\n    -e, --exclude [regex]        exclude specific routes from cache, (e.g. --exclude \"GET /api/keep-alive/.*\")\r\n    -S, --excludeStatus [regex]  exclude specific status from cache, (e.g. --excludeStatus \"503|404\")\r\n    -a, --all                    cache everything from the remote server (Default is to cache just JSON responses)\r\n    -P, --disablePlayback        disables cache playback\r\n    -R, --disableRecord          disables recording to cache\r\n    -C, --cmdPrefix [prefix]     change the prefix for the proxy's web admin endpoints\r\n    -I, --header [header]        change the response header property for identifying cached responses\r\n    -l, --log                    print log output to console\r\n    -t, --timeout                change the timeout for proxy server\r\n    -d, --deleteCookieDomain     remove the Domain portion of all cookies\r\n    -o, --overrideCors [url]     override Access-Control-Allow-Origin\r\n    -z, --useCorsCredentials     set Access-Control-Allow-Credentials to true\r\n\r\n```\r\n\r\n#### Example - basic JSON caching with output\r\n```\r\n$ json-caching-proxy -u http://remote:8080 -l\r\n```\r\n\r\n#### Example - bypassing CORS when proxying to a 3rd party api server\r\n```\r\n$ json-caching-proxy -u http://cors-api.example.com -o localhost:9000 -z\r\n```\r\nThis use case occurs when developing a browser application against an api server on a different host with CORS restrictions.\r\nIn this example we might be running a dev server that's hosting a frontend application on http://localhost:9000 and there is\r\nbrowser javascript that needs to fetch from http://cors-api.example.com. The `-z` option tells the proxy to set up auth headers\r\nin case the code uses cookies or tokens (e.g. Bearer tokens)\r\n\r\n#### Example - hydrating the cache\r\n```\r\n$ json-caching-proxy -u http://remote:8080 -p 3001 -H chromeDevTools.har -l\r\n```\r\nYou may have a HAR file that was generated elsewhere (e.g. Chrome Developer tools). You can load this file and initialize the cache\r\n\r\n#### Example - advanced arguments\r\n```\r\n$ json-caching-proxy -u http://remote:8080 -p 3001 -b time:dc -e '/keepalive' -H hydrate.har -a -l\r\n```\r\n\r\n* Routes requests to `http://remote:8080`\r\n* Runs the proxy on port `3001` on the host machine\r\n* Removes matching query parameters `time` or `dc`. (e.g. /rest/status?time=1234567). `:` is the delimiter\r\n* Excludes any `/keepalive` requests from the proxy. Any valid js regular expression works here\r\n* Loads an existing HAR file and hydrates the cache. Supports any HAR file that conforms to HAR spec 1.2\r\n* Caches everything. This includes JSON as well as other content-types such as images. It's essentially a site backup.\r\n* Logs output to the console\r\n\r\n#### Example - loading options from a config file\r\n\r\n```js\r\n/* Complete list of config.json options for the caching proxy */\r\n\r\n{\r\n  \"remoteServerUrl\": \"http://wikimapia.org\",\r\n  \"proxyPort\": 3001,\r\n  \"inputHarFile\": \"./test/test.har\",\r\n  \"cacheEverything\": true,\r\n  \"cacheBustingParams\": [\"_\", \"dc\", \"cacheSlayer\"],\r\n  \"excludedRouteMatchers\": [\"/*.js\", \"/*.png\"],\r\n  \"excludedStatusMatchers\": [\"503\", \"404\"],\r\n  \"showConsoleOutput\": true,\r\n  \"dataPlayback\": true,\r\n  \"dataRecord\": true,\r\n  \"commandPrefix\": \"proxy\",\r\n  \"proxyHeaderIdentifier\": \"proxy-cache-playback\",\r\n  \"proxyTimeout\": 500000,\r\n  \"deleteCookieDomain\": true,\r\n  \"overrideCors\": \"localhost:8080\",\r\n  \"useCorsCredentials\": true\r\n}\r\n```\r\n```\r\n$ json-caching-proxy --config config.json\r\n```\r\n\r\n## Programmatic Usage\r\n\r\n```js\r\nimport JsonCachingProxy from 'json-caching-proxy';\r\n\r\n// Complete list of options\r\nlet jsonCachingProxy = new JsonCachingProxy({\r\n    remoteServerUrl: 'http://localhost:8080',\r\n    proxyPort: 3001,\r\n    harObject: null,\r\n    commandPrefix: 'proxy',\r\n    proxyHeaderIdentifier: 'caching-proxy-playback',\r\n    middlewareList: [{ route: '/browser-sync', handle: (req, res, next) =\u003e res.send('bypass proxy')}],\r\n    excludedRouteMatchers: [new RegExp('/site/*.js')],\r\n    excludedStatusMatchers: [new RegExp('503|404')],\r\n    cacheBustingParams: ['time', 'dc'],\r\n    cacheEverything: false,\r\n    dataPlayback: true,\r\n    dataRecord: true,\r\n    showConsoleOutput: false,\r\n    proxyTimeout: 500000,\r\n    deleteCookieDomain: true,\r\n    overrideCors: \"localhost:8080\",\r\n    useCorsCredentials: true\r\n});\r\n\r\njsonCachingProxy.start();\r\n```\r\n\r\n#### Example - passing in a HAR object\r\nIf you have a method of generating a HAR object, the proxy can load the HAR entries and hydrate the cache. The proxy has a commandline\r\nutility for loading HAR files but you may want to load your own or modify the objects before passing them into the proxy. More info can be found\r\nhere: [HAR 1.2 spec](http://www.softwareishard.com/blog/har-12-spec/)\r\n\r\n```js\r\n// Example HAR object\r\nlet harObject = {\r\n  log: {\r\n    version: '1.2',\r\n    creator: {\r\n      name: npmPackage.name,\r\n      version: npmPackage.version\r\n    },\r\n    entries: [{\r\n      request: {\r\n        startedDateTime: '',\r\n        method: 'GET',\r\n        url: '/test',\r\n        cookies: [],\r\n        headers: [],\r\n        queryString: [],\r\n        headersSize: -1,\r\n        bodySize: -1\r\n      },\r\n      response: {\r\n        status: 200,\r\n        cookies: [],\r\n        headers: [],\r\n        content: {\r\n          size: -1,\r\n          mimeType: 'application/json; charset=utf-8',\r\n          text: '{\"a\":1,\"b\":\"Some Value\"}',\r\n          encoding: 'utf8'\r\n        },\r\n        headersSize: -1,\r\n        bodySize: -1\r\n      }\r\n    },\r\n      {\r\n        request: {\r\n          startedDateTime: '',\r\n          method: 'GET',\r\n          url: '/another',\r\n          cookies: [],\r\n          headers: [],\r\n          queryString: [],\r\n          headersSize: -1,\r\n          bodySize: -1\r\n        },\r\n        response: {\r\n          status: 200,\r\n          cookies: [],\r\n          headers: [],\r\n          content: {\r\n            size: -1,\r\n            mimeType: 'application/json; charset=utf-8',\r\n            text: '{\"a\":1,\"b\":\"Some Value\"}',\r\n            encoding: 'utf8'\r\n          },\r\n          headersSize: -1,\r\n          bodySize: -1\r\n        }\r\n      }]\r\n  }\r\n};\r\n```\r\n\r\n#### Example - using special middleware\r\nBypasses the remote server and allows your own middleware to be executed:\r\n```js\r\nlet middlewareList = [\r\n  { route: '/what', handle: (req, res, next) =\u003e res.send('what') },\r\n  { route: '/hello', handle: (req, res, next) =\u003e res.send('hello') }\r\n];\r\n```\r\n\r\n#### Example - excluding specific routes\r\nYou can specify a list of regular expressions to match against. Currently supports matching against the `method` and `uri`:\r\n```js\r\nexcludedRouteMatchers: [new RegExp('/site/*.js'), new RegExp('GET /site/*.gif'), new RegExp('POST /account/666')]\r\n```\r\n\r\n#### Example - cache busting\r\nMany times, there are cache busting query strings that are appended to GET requests, you may specify a list of these\r\nquery string names. The proxy will ignore these parameters when building the cache. Otherwise every request will be\r\ndifferent\r\n```js\r\ncacheBustingParams: ['time', 'dc', 'cacheSlayer', '_']\r\n```\r\n\r\n## Controlling the Proxy\r\nOnce the proxy has started on a port (e.g. 3001), you may point your browser to the following urls to affect the state of the proxy:\r\n```\r\nhttp://localhost:3001/proxy/playback?enabled=[true|false] - Start/Stop replaying cached requests.\r\nhttp://localhost:3001/proxy/record?enabled=[true|false] - Start/Stop recording request/responses to the cache.\r\nhttp://localhost:3001/proxy/har - Download cache to json-caching-proxy.har\r\nhttp://localhost:3001/proxy/clear - Empty the in-memory cache.\r\n```\r\n\r\n## License\r\n\r\nMIT\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsonyseng%2Fjson-caching-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsonyseng%2Fjson-caching-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsonyseng%2Fjson-caching-proxy/lists"}