{"id":51319304,"url":"https://github.com/echecsjs/san","last_synced_at":"2026-07-01T11:02:37.901Z","repository":{"id":346000560,"uuid":"1184706682","full_name":"echecsjs/san","owner":"echecsjs","description":"Parse, resolve, and stringify SAN (Standard Algebraic Notation) chess moves. Strict TypeScript.","archived":false,"fork":false,"pushed_at":"2026-06-29T14:08:18.000Z","size":524,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-29T15:25:28.209Z","etag":null,"topics":["chess","notation","parser","san","typescript"],"latest_commit_sha":null,"homepage":"https://github.com/echecsjs/san#readme","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/echecsjs.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-03-17T21:17:19.000Z","updated_at":"2026-06-29T14:09:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/echecsjs/san","commit_stats":null,"previous_names":["mormubis/san","echecsjs/san"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/echecsjs/san","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/echecsjs%2Fsan","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/echecsjs%2Fsan/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/echecsjs%2Fsan/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/echecsjs%2Fsan/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/echecsjs","download_url":"https://codeload.github.com/echecsjs/san/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/echecsjs%2Fsan/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35003464,"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-07-01T02:00:05.325Z","response_time":130,"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":["chess","notation","parser","san","typescript"],"created_at":"2026-07-01T11:02:37.238Z","updated_at":"2026-07-01T11:02:37.895Z","avatar_url":"https://github.com/echecsjs.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @echecs/san\n\n[![Spec](https://img.shields.io/badge/Spec-FIDE-green.svg)](SPEC.md)\n\nParse, resolve, and stringify SAN (Standard Algebraic Notation) chess moves.\nStrict TypeScript. Implements the notation defined in\n[FIDE Laws of Chess, Appendix C](https://handbook.fide.com/chapter/E012023).\n\n## Installation\n\n```bash\nnpm install @echecs/san\n```\n\n## Usage\n\n```typescript\nimport { parse, resolve, stringify } from '@echecs/san';\n\n// Parse SAN syntax only — returns a SanMove (no position needed)\nconst sanMove = parse('Nf3');\n\n// Parse and resolve in one call — returns a Move with from/to squares\nconst move = parse('Nf3', position);\n\n// Resolve a SanMove to a Move (find the from square)\nconst move = resolve(sanMove, position);\n\n// Convert a Move back to a SAN string\nconst san = stringify(move, position);\n```\n\n## API\n\n### `parse(san: string): SAN`\n\nParses a SAN string and returns a `SAN` object describing the move's syntax.\nDoes not require a position. Throws `RangeError` for empty or invalid input.\n\n### `parse(san: string, position: Position): Move`\n\nParses and resolves a SAN string against a position in one call. Equivalent to\ncalling `parse` then `resolve`. Throws `RangeError` for empty, invalid, or\nillegal input.\n\n### `resolve(move: SAN, position: Position): Move`\n\nFinds the source square for a `SAN` move in the given position. Throws\n`RangeError` if no legal move matches or if the move is ambiguous.\n\n### `stringify(move: Move, position: Position): string`\n\nReturns the SAN string for a `Move` in the given position, including\ndisambiguation, capture marker, check, and checkmate symbols. Throws\n`RangeError` if no piece occupies the source square.\n\n## Types\n\n```typescript\ninterface SAN {\n  capture: boolean;\n  castling: boolean;\n  check: boolean;\n  checkmate: boolean;\n  from: Disambiguation | undefined;\n  long: boolean;\n  piece: Piece;\n  promotion: PromotionPiece | undefined;\n  to: Square | undefined;\n}\n```\n\n`from` is the disambiguation hint from the SAN string (a file, rank, or full\nsquare), not the origin square. `to` is `undefined` for castling moves.\n\n`Move` and `PromotionPieceType` are re-exported from `@echecs/position`.\n`PromotionPiece` is an alias for `PromotionPieceType`.\n\n```typescript\ninterface Move {\n  from: Square;\n  promotion?: PromotionPieceType;\n  to: Square;\n}\n```\n\n```typescript\nimport type { Move, Position, PromotionPieceType, SAN } from '@echecs/san';\n```\n\n## Errors\n\nAll functions throw `RangeError` for domain violations:\n\n| Situation                 | Message                        |\n| ------------------------- | ------------------------------ |\n| Empty SAN string          | `Empty SAN string`             |\n| Invalid SAN syntax        | `Invalid SAN: \"\u003cinput\u003e\"`       |\n| No legal move found       | Describes the move             |\n| Ambiguous move            | Lists the number of candidates |\n| No piece on source square | Describes the square           |\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fechecsjs%2Fsan","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fechecsjs%2Fsan","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fechecsjs%2Fsan/lists"}