{"id":23366722,"url":"https://github.com/d8corp/jap","last_synced_at":"2026-06-18T16:31:39.007Z","repository":{"id":34915529,"uuid":"189819566","full_name":"d8corp/jap","owner":"d8corp","description":"JSON Action Protocol","archived":false,"fork":false,"pushed_at":"2023-01-04T21:47:28.000Z","size":1168,"stargazers_count":2,"open_issues_count":14,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-25T18:27:45.042Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/d8corp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-02T07:57:17.000Z","updated_at":"2020-10-08T13:58:54.000Z","dependencies_parsed_at":"2023-01-15T10:20:24.640Z","dependency_job_id":null,"html_url":"https://github.com/d8corp/jap","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/d8corp/jap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d8corp%2Fjap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d8corp%2Fjap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d8corp%2Fjap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d8corp%2Fjap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/d8corp","download_url":"https://codeload.github.com/d8corp/jap/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/d8corp%2Fjap/sbom","scorecard":{"id":315949,"data":{"date":"2025-08-11","repo":{"name":"github.com/d8corp/jap","commit":"15acd96d3d1837d4d63215c80d75120d3ce58faf"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 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":-1,"reason":"No tokens found","details":null,"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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"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":"Dangerous-Workflow","score":-1,"reason":"no workflows found","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":"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":"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":"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":"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":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"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":"Vulnerabilities","score":0,"reason":"52 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","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-w8qv-6jwh-64r5","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"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-18T00:11:11.120Z","repository_id":34915529,"created_at":"2025-08-18T00:11:11.120Z","updated_at":"2025-08-18T00:11:11.120Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34499404,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":[],"created_at":"2024-12-21T14:17:25.428Z","updated_at":"2026-06-18T16:31:38.989Z","avatar_url":"https://github.com/d8corp.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSON Action Protocol\n### An idea\n*You may use it on server and browser side or native apps, anywhere.  \nThis is just an idea how we can run actions of other apps from our.  \nJ.A.P. provides you running of all actions you need in one request via json.*\n####Request example\n```json\n{\n  \"user\": {\n    \"icon\": \"small\",\n    \"balance\": \"all\",\n    \"properties\": [\"name\", \"age\"],\n    \"test\": false\n  },\n  \"payment\": {\n    \"methods\": [0, 2]\n  },\n  \"cart\": {\n    \"count\": null,\n    \"items\": 4\n  }\n}\n```\n#### Response for the example\n```json\n{\n  \"user\": {\n    \"icon\": {\n      \"success\": true,\n      \"data\": \"/img/...jpg\"\n    },\n    \"balance\": {\n      \"success\": true,\n      \"data\": {\n        \"cash\": 420,\n        \"points\": 13\n      }\n    },\n    \"properties\": {\n      \"success\": true,\n      \"data\": {\n        \"name\": \"Mike\",\n        \"age\": 42\n      }\n    },\n    \"test\": {\n      \"error\": \"Undeclared handler\",\n      \"data\": false\n    }\n  },\n  \"payment\": {\n    \"methods\": {\n      \"success\": true,\n      \"data\": [\n        {\"id\": 7, \"type\": \"html\"},\n        {\"id\": 12, \"type\": \"iframe\"}\n      ]\n    }\n  },\n  \"cart\": {\n    \"count\": {\n      \"success\": true,\n      \"data\": 4\n    },\n    \"items\": {\n      \"error\": \"The item is not found\",\n      \"data\": 4\n    }\n  }\n}\n```\n### About `jap` function\n*The function helps you handle any J.A.P. request.*  \n`jap (`  \n1. \\[ [primitiveHandler](#japprimitivehandler): json primitive | [handler](#japhandler): function | [handlerCollection](#japhandlercollection-request-resolve): array | [handlerList](#japhandlerlist-requestlist): object \\]: parsed JSON with functions\n2. \\[, [request](#japhandler-request): json primitive | [requestCollection](#japhandler-requestCollection): array | [requestList](#japhandlerlist-requestlist): object \\]: parsed JSON  \n3. \\[, [resolve](#resolve): function \\]\n4. \\[, [reject](#reject): function \\]\n5. \\[, [promises](#promises): array \\]\n6. \\[, [context](#context): any \\]\n\n`)`\n## Resolve\nIf all rules are followed and handler is finished without errors then the result will go\nthrough resolve callback function.\nYou will see all rules in this section.\n### jap(`primitiveHandler`)\n`primitiveHandler` is any primitive value of json `null`, `boolean`, `number` or `string`.  \n`jap` with `primitiveHandler` always returns the handler.\n```javascript\njap(null) // returns {success: true, data: null}\njap(false) // returns {success: true, data: false}\njap(1) // returns {success: true, data: 1}\njap(1.1) // returns {success: true, data: 1.1}\njap('string') // returns {success: true, data: 'string'}\n``` \n### jap(`handler`)\n`handler` is a function.  \n`jap` with `handler` always returns result of `handler`'s call.\n```javascript\njap(() =\u003e 1) // returns {success: true, data: 1}\njap(() =\u003e {}) // returns {success: true, data: null}\n``` \n### jap(handler, `request`)\n`request` is a parsed json from another app.  \nYou may handle `request` by `handler`.  \n`handler` gets `request` as the first argument.\n```javascript\njap(x =\u003e x + x, 1) // returns {success: true, data: 2}\njap(x =\u003e !x, true) // returns {success: true, data: false}\njap(x =\u003e x.test, {test: 1}) // returns {success: true, data: 1}\n```\n### jap(handler, `requestCollection`)\nYou may provide any count of arguments to `handler` by `requestCollection`.  \n`requestCollection` just is an array of arguments.\n```javascript\nconst sum = (x, y) =\u003e x + y\n\njap(sum, [1, 2]) // returns {success: true, data: 3}\njap(sum, [3, 5]) // returns {success: true, data: 8}\n```\n### jap(handler, request, `resolve`)\nDefault `resolve` is `data =\u003e ({success: true, data})`.  \nBut you can change it as you wish\n```javascript\nconst sum = (x, y) =\u003e x + y\n\njap(sum, [1, 2], data =\u003e data) // returns 3\n```\nYou may use `true` if you want to set default `resolve` function and `false` if you want to return only request data\n```javascript\nconst sum = (x, y) =\u003e x + y\n\njap(sum, [1, 2], true) // returns {success: true, data: 3}\njap(sum, [1, 2], false) // returns 3\n```\n### jap(`handlerCollection`, request, resolve)\nYou may use an array of any handlers type as `handlerCollection`.  \nEach next handler gets result of handle before.\n```javascript\nconst sum = (x, y) =\u003e x + y\nconst square = x =\u003e x * x\n\njap([sum, square], [1, 2]) // returns {success: true, data: 9}\n```\n### jap(`handlerList`, `requestList`)\n`handlerList` works only with `requestList`. They booth are objects.  \nYou may see whats happen if `handlerList` runs without `requestList` [here](#wrong-request)  \nFields of `handlerList` are any handler type and fields of `requestList` are any request type.\n```javascript\nconst sum = (x, y) =\u003e x + y\nconst square = x =\u003e x * x\nconst math = {sum, square}\n\njap(math, {square: 4}, false) // returns {square: 16}\njap(math, {square: 3, sum: [3, 4]}, false) // returns {square: 9, sum: 7}\n\nconst core = {math, version: '1.0.0'}\n\njap(core, {math: {square: 5}}, false) // returns {math: {square: 25}}\njap(core, {math: {sum: [5, 7]}, version: null}, false) // returns {math: {sum: 12}, version: '1.0.0'}\n```\n[resolve](#resolve) is using only for `primitiveHandler` or `handler`\n\n```javascript\nconst response = JSON.stringify(jap(core, {math: {sum: [5, 7]}, version: null}))\n```\nreturns\n```json\n{\n  \"math\": {\n    \"sum\": {\n      \"success\": true,\n      \"data\": 12\n    }\n  },\n  \"version\": {\n    \"success\": true,\n    \"data\": \"1.0.0\"\n  }\n}\n```\nYou may pass it to response and handle the response on client by `jap`\n```javascript\njap({\n  math: {\n    sum ({success, data}) {\n      if (success) {\n        console.log('set sum and update this information on the page', data)\n      }\n    }\n  },\n  version ({success, data}) {\n    if (success) {\n      console.log('update version and run all actions you need', data)\n    }\n  }\n}, JSON.parse(response))\n```\n\n\u003e `jap` does not create new object, it changes `requestList`\n\n\u003e all keys starts from `_` or `$` are private and unavailable outside\n\n## Reject\nIf any rules are failed or handler is finished with an error then the result will go\nthrough reject callback function.\nYou will see all rules for that in this section.  \nDefault reject callback function is `(data, error, handler) =\u003e ({error: error.message, data})`.  \n`data` is data from request  \n`error` is an instance of Error\n`handler` is a handler which threw the error\n### Wrong handler\nIf your handler is not matched with [primitiveHandler](#primitiveHandler), [handler](#handler), [handlerCollection](#handlerCollection) or [handlerList](#handlerList)\nThen `jap` returns `reject` (`null` is default request)  \nAnd you get an error with message `Undeclared handler` \n```javascript\njap() // returns {error: 'Undeclared handler', data: null}\njap(undefined) // returns {error: 'Undeclared handler', data: null}\njap(Symbol()) // returns {error: 'Undeclared handler', data: null}\njap(NaN, 'test') // returns {error: 'Undeclared handler', data: 'test'}\n``` \n### Wrong request\nIf your `handler` is `handlerList` and `request` is not `requestList` then you get an error with message `Undeclared request`\n```javascript\njap({}) // returns {error: 'Undeclared request', data: null}\n```\n### Wrong handlerCollection\nIf [handlerCollection](#handlerCollection) contains wrong handler then `jap` stops handling on wrong element and returns request or the last result of success [handlerCollection](#handlerCollection)'s element as `request`\n```javascript\njap([1, undefined], 2, true, (data, error, handler) =\u003e ({data, error, handler}))\n// returns {data: 1, error: Error('Undeclared handler'), handler: undefined}\n```\n\u003e empty `handlerCollection` is legal handler which goes through [resolve](#resolve)\n### Promises\nYou may use async handlers, all promises returned the handlers will be added to the `promises` argument of `jap`\n```javascript\nconst handler = {\n  test1: async e =\u003e {\n      await new Promise(resolve =\u003e setTimeout(resolve, 10))\n      return e\n    },\n  test2: async () =\u003e {\n    throw Error('test')\n  }\n}\n\nconst promises = []\n\nconst result = jap(handler, {test1: 1, test2: 2}, true, true, promises)\n\n// promises.length equals 2\n// result.test1 is promise\n// result.test1 === promises[0]\n\nPromise.all(promises).then(() =\u003e {\n  // result.test1 is {success: true, data: 1}\n  // result.test2 is {error: 'test', data: 2}\n})\n```\n\n## TODO example\nYou may look at real example with:\n```bash\ngit clone https://github.com/d8corp/jap.git\ncd jap\nnpm i\nnpm start\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd8corp%2Fjap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fd8corp%2Fjap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd8corp%2Fjap/lists"}