{"id":23626008,"url":"https://github.com/brundonsmith/monch","last_synced_at":"2025-08-31T01:31:47.606Z","repository":{"id":159479351,"uuid":"634648069","full_name":"brundonsmith/monch","owner":"brundonsmith","description":"A tasty TypeScript parser-combinators library","archived":false,"fork":false,"pushed_at":"2023-05-05T22:11:44.000Z","size":17,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-16T23:52:57.369Z","etag":null,"topics":["deno","nodejs","parser-combinators","parsing","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/brundonsmith.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":"2023-04-30T19:55:34.000Z","updated_at":"2024-06-08T12:36:05.000Z","dependencies_parsed_at":"2023-07-06T14:00:35.513Z","dependency_job_id":null,"html_url":"https://github.com/brundonsmith/monch","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/brundonsmith/monch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brundonsmith%2Fmonch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brundonsmith%2Fmonch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brundonsmith%2Fmonch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brundonsmith%2Fmonch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brundonsmith","download_url":"https://codeload.github.com/brundonsmith/monch/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brundonsmith%2Fmonch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272929996,"owners_count":25017057,"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-08-30T02:00:09.474Z","response_time":77,"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":["deno","nodejs","parser-combinators","parsing","typescript"],"created_at":"2024-12-27T22:29:30.297Z","updated_at":"2025-08-31T01:31:47.112Z","avatar_url":"https://github.com/brundonsmith.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Monch\n\nA tasty TypeScript parser-combinator library, inspired by Rust's\n[nom crate](https://github.com/rust-bakery/nom)\n\n## Features\n- Small and practical (but easy to extend!)\n- Zero dependencies\n- Rich type inference for parsed value types and error types\n- Works on Node, Deno, Bun, and even the browser\n  \n## Installation\n```\nnpm install monch-parse\n```\nor\n\n```\nimport { } from 'https://deno.land/x/monch@v1.0.2/index.ts'\n```\n\n## Usage\n\n```typescript\n// JSON parser\nconst nil = map(\n    exact('null'),\n    () =\u003e null\n)\n\nconst boolean = map(\n    oneOf(\n        exact('true'),\n        exact('false')\n    ),\n    s =\u003e s === 'true'\n)\n\nconst number = map(\n    tuple(\n        take1(numericChar),\n        optional(\n            tuple(\n                exact(\".\"),\n                required(take1(numericChar), () =\u003e `Expected numbers after decimal point`)\n            )\n        ),\n    ),\n    ([front, back]) =\u003e {\n        let numberString = front\n\n        if (back != null) {\n            const [_decimal, fractionDigits] = back\n            numberString += `.${fractionDigits}`\n        }\n\n        return Number(numberString)\n    }\n)\n\nconst string = map(\n    tuple(\n        exact('\"'),\n        take0(filter(char, ch =\u003e ch !== '\"')),\n        required(exact('\"'), () =\u003e `Expected closing quote '\"'`)\n    ),\n    ([_0, contents, _1]) =\u003e contents\n)\n\nconst commaWithWhitespace = tuple(\n    whitespace,\n    exact(','),\n    whitespace\n)\n\nconst array: Parser\u003cunknown[], string\u003e = input =\u003e map(\n    tuple(\n        exact('['),\n        whitespace,\n        manySep0(\n            jsonValue,\n            commaWithWhitespace\n        ),\n        whitespace,\n        required(exact(']'), () =\u003e `Expected closing bracket ']'`)\n    ),\n    ([_0, _1, elements, _2, _3]) =\u003e elements\n)(input)\n\nconst object: Parser\u003cRecord\u003cstring, unknown\u003e, string\u003e = input =\u003e map(\n    tuple(\n        exact('{'),\n        whitespace,\n        manySep0(\n            map(\n                tuple(\n                    string,\n                    whitespace,\n                    required(exact(':'), () =\u003e `Expected ':' after object key`),\n                    whitespace,\n                    required(jsonValue, () =\u003e `Expected value after ':'`)\n                ),\n                ([key, _0, _1, _2, value]) =\u003e [key, value] as const\n            ),\n            commaWithWhitespace\n        ),\n        whitespace,\n        required(exact('}'), () =\u003e `Expected closing curly brace '}'`)\n    ),\n    ([_0, _1, entries, _2, _3]) =\u003e Object.fromEntries(entries)\n)(input)\n\nconst jsonValue: Parser\u003cunknown, string\u003e = input =\u003e oneOf(\n    nil,\n    boolean,\n    number,\n    string,\n    array,\n    object\n)(input)\n```\n\n```typescript\n// Calling the parser\nconst json = {\n    \"foo\": \"bar\",\n    \"blah\": 123.4,\n    \"stuff\": true,\n    \"other\": [\n        1,\n        2,\n        null,\n        false\n    ]\n}\nconst jsonString = JSON.stringify(json)\nconst parserInput = input(jsonString)\n\nassertEquals(\n    jsonValue(parserInput),\n    {\n        kind: 'success',\n        input: { code: jsonString, index: jsonString.length },\n        src: { code: jsonString, start: 0, end: jsonString.length },\n        parsed: json\n    }\n)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrundonsmith%2Fmonch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrundonsmith%2Fmonch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrundonsmith%2Fmonch/lists"}