{"id":15390178,"url":"https://github.com/gajus/crack-json","last_synced_at":"2025-09-19T12:21:54.822Z","repository":{"id":57210525,"uuid":"163696110","full_name":"gajus/crack-json","owner":"gajus","description":"Extracts all JSON objects from an arbitrary text document.","archived":false,"fork":false,"pushed_at":"2020-01-29T07:00:25.000Z","size":15,"stargazers_count":30,"open_issues_count":0,"forks_count":3,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-08-16T08:21:25.878Z","etag":null,"topics":["extract","json"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gajus.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":"2018-12-31T20:36:17.000Z","updated_at":"2024-09-30T02:47:53.000Z","dependencies_parsed_at":"2022-08-31T05:02:30.953Z","dependency_job_id":null,"html_url":"https://github.com/gajus/crack-json","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/gajus/crack-json","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gajus%2Fcrack-json","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gajus%2Fcrack-json/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gajus%2Fcrack-json/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gajus%2Fcrack-json/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gajus","download_url":"https://codeload.github.com/gajus/crack-json/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gajus%2Fcrack-json/sbom","scorecard":{"id":417288,"data":{"date":"2025-08-11","repo":{"name":"github.com/gajus/crack-json","commit":"3dad2398fd1d2f1d046d4c0f84001feb785e7d18"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"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":"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":"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":"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":"Code-Review","score":0,"reason":"Found 0/14 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":"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":"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"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":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"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":"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"}}]},"last_synced_at":"2025-08-19T00:14:47.056Z","repository_id":57210525,"created_at":"2025-08-19T00:14:47.056Z","updated_at":"2025-08-19T00:14:47.056Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275935149,"owners_count":25555526,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-19T02:00:09.700Z","response_time":108,"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":["extract","json"],"created_at":"2024-10-01T15:04:45.151Z","updated_at":"2025-09-19T12:21:54.729Z","avatar_url":"https://github.com/gajus.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# crack-json 🥊\n\n[![Travis build status](http://img.shields.io/travis/gajus/crack-json/master.svg?style=flat-square)](https://travis-ci.org/gajus/crack-json)\n[![Coveralls](https://img.shields.io/coveralls/gajus/crack-json.svg?style=flat-square)](https://coveralls.io/github/gajus/crack-json)\n[![NPM version](http://img.shields.io/npm/v/crack-json.svg?style=flat-square)](https://www.npmjs.org/package/crack-json)\n[![Canonical Code Style](https://img.shields.io/badge/code%20style-canonical-blue.svg?style=flat-square)](https://github.com/gajus/canonical)\n[![Twitter Follow](https://img.shields.io/twitter/follow/kuizinas.svg?style=social\u0026label=Follow)](https://twitter.com/kuizinas)\n\nExtracts all JSON objects from an arbitrary text document.\n\n* [Use case](#use-case)\n* [Implementation](#implementation)\n* [API](#api)\n  * [`extractJson` API](#extractjson-api)\n* [Usage](#usage)\n  * [Filtering out matches](#filtering-out-matches)\n\n## Use case\n\nThe primary use-case is extracting structured data from non-structured documents, e.g. when scraping websites, it is common that HTML embeds JSON or JSON-like data structures.\n\n```html\n\u003cscript\u003e\n$(document).on('BookingApp:SeatingPlan:Ready', () =\u003e {\n  $(document).trigger('BookingApp:StartSeatingPlanOnly', {\n    \"sessionId\": \"438a8373-5fab-4d36-ac92-053ae2d04e9c\"\n  });\n});\n\u003c/script\u003e\n\n```\n\nThe way that the `crack-json` is intended to be used is that the scraper must narrow down the document to the HTML containing the subject JSON data and then `crack-json` is used to extract all JSON-like objects. If in the above example we are interested in extracting the `sessionId`, then it would be sufficient to get `innerHTML` of the `script` tag, use `crack-json` to extract all JSON-like objects, and search for the matching object, e.g.\n\n```js\nconst session = extractJson(document.querySelector('script').innerHTML)\n  .find((maybeTargetSubject) =\u003e {\n    return maybeTargetSubject.sessionId;\n  });\n\nsession;\n// {\n//   \"sessionId\": \"438a8373-5fab-4d36-ac92-053ae2d04e9c\"\n// }\n\n```\n\n## Implementation\n\n`crack-json` iterates through the input text by searching for characters that indicate the start of a JSON object, array or text entity, and attempts to match the closing character and parse the resulting string. `crack-json` iterates through document this way until it finds all text entities that can be parsed as JSON.\n\n## API\n\n`crack-json` extracts a single function: `extractJson`.\n\n```js\nimport {\n  extractJson\n} from 'crack-json';\n\n```\n\n### `extractJson` API\n\n```js\n/**\n * @property filter Used to filter out strings before attempting to decode them.\n * @property parser A parser used to extract JSON from the suspected strings. Default: `JSON.parse`.\n */\ntype ExtractJsonConfigurationType = {|\n  +filter?: (input: string) =\u003e boolean,\n  +parser?: (input: string) =\u003e any,\n|};\n\ntype ExtractJsonType = (subject: string, configuration?: ExtractJsonConfigurationType) =\u003e any;\n\nextractJson: ExtractJsonType;\n\n```\n\n## Usage\n\n```js\nimport {\n  extractJson\n} from 'crack-json';\n\nconst payload = `\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ultricies laoreet malesuada. In feugiat augue non tristique pharetra. Duis nisl odio, vulputate maximus suscipit sit amet, ultrices vel lacus.\n\n{\"foo\": \"bar\"}\n\nSuspendisse volutpat risus id nibh lacinia, in placerat urna luctus. Phasellus condimentum nec ipsum ut tincidunt. Nullam aliquam euismod ante, vitae accumsan leo egestas a. Aliquam sed lacus nisl. Pellentesque nec hendrerit sem.\n\n[{\"baz\": \"qux\"}]\n\nPhasellus iaculis dui nec purus imperdiet placerat non sit amet odio. Donec pretium, arcu ac suscipit imperdiet, tellus orci convallis leo, non laoreet tortor lectus at dolor. Aenean tellus diam, imperdiet nec eleifend at, fermentum sit amet tellus. Vestibulum id purus ac mauris eleifend iaculis.\n\n\"quux\"\n\nVestibulum sit amet quam tellus. Nulla facilisi.\n\n`;\n\nconsole.log(extractJson(payload));\n\n```\n\nOutput:\n\n```js\n[\n  {\n    foo: 'bar'\n  },\n  [\n    {\n      baz: 'qux'\n    }\n  ],\n  'quux'\n]\n\n```\n\n### Filtering out matches\n\nYou can use `filter` to exclude strings before they are parsed using an arbitrary condition. This will improve performance and reduce output only to the desirable objects, e.g.\n\n```html\nimport {\n  extractJson\n} from 'crack-json';\n\nconst payload = `\n  \u003cscript\u003e\n  const foo = {\n    cinemaId: '1',\n  };\n  const bar = {\n    venueId: '1',\n  };\n  const baz = {\n    userId: '1',\n  };\n  \u003c/script\u003e\n`;\n\nconsole.log(extractJson(payload, {\n  filter: (input) =\u003e {\n    return input.includes('userId')\n  },\n}));\n\n```\n\nOutput:\n\n```js\n[\n  {\n    userId: '1',\n  },\n]\n\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgajus%2Fcrack-json","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgajus%2Fcrack-json","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgajus%2Fcrack-json/lists"}