{"id":50094238,"url":"https://github.com/h-dong/serina","last_synced_at":"2026-05-23T02:13:20.767Z","repository":{"id":42363262,"uuid":"108762250","full_name":"h-dong/serina","owner":"h-dong","description":"Natural Language Parser for date and time in Javascript","archived":false,"fork":false,"pushed_at":"2026-05-13T12:37:01.000Z","size":680,"stargazers_count":10,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-14T09:28:04.397Z","etag":null,"topics":["date-parser","javascript","javascript-library","natural-language-processing","time-parsing","typescript"],"latest_commit_sha":null,"homepage":"https://serina.netlify.com","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/h-dong.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-10-29T19:00:29.000Z","updated_at":"2026-05-13T12:37:12.000Z","dependencies_parsed_at":"2025-08-19T10:51:40.774Z","dependency_job_id":"3e6604d3-8833-44ce-90ef-30ebdfd4c920","html_url":"https://github.com/h-dong/serina","commit_stats":null,"previous_names":["hdong92/serina"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/h-dong/serina","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h-dong%2Fserina","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h-dong%2Fserina/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h-dong%2Fserina/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h-dong%2Fserina/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/h-dong","download_url":"https://codeload.github.com/h-dong/serina/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h-dong%2Fserina/sbom","scorecard":{"id":451406,"data":{"date":"2025-08-11","repo":{"name":"github.com/h-dong/serina","commit":"ed6f594738e4f39b8bf9e400fd2103c2f3510b2c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/29 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":"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":"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":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/npm-publish.yml:1","Warn: no topLevel permission defined: .github/workflows/pull-request-validate.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":"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":"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":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/npm-publish.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/h-dong/serina/npm-publish.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/npm-publish.yml:15: update your workflow using https://app.stepsecurity.io/secureworkflow/h-dong/serina/npm-publish.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pull-request-validate.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/h-dong/serina/pull-request-validate.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/pull-request-validate.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/h-dong/serina/pull-request-validate.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction 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":"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":"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":"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":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact 1.0.1 not signed: https://api.github.com/repos/h-dong/serina/releases/20650760","Warn: release artifact 1.0.1 does not have provenance: https://api.github.com/repos/h-dong/serina/releases/20650760"],"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":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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 6 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":"26 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-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-ghr5-ch3p-vcr6","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-353f-5xf4-qw67","Warn: Project is vulnerable to: GHSA-c24v-8rfc-w8vw","Warn: Project is vulnerable to: GHSA-8jhw-289h-jh2g","Warn: Project is vulnerable to: GHSA-64vr-g452-qvp3","Warn: Project is vulnerable to: GHSA-9cwx-2883-4wfx","Warn: Project is vulnerable to: GHSA-vg6x-rcgg-rjx6","Warn: Project is vulnerable to: GHSA-x574-m823-4x7w","Warn: Project is vulnerable to: GHSA-4r4m-qw57-chr8","Warn: Project is vulnerable to: GHSA-xcj6-pq6g-qj4x","Warn: Project is vulnerable to: GHSA-356w-63v5-8wf4","Warn: Project is vulnerable to: GHSA-859w-5945-r5v3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7"],"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-19T08:16:49.532Z","repository_id":42363262,"created_at":"2025-08-19T08:16:49.532Z","updated_at":"2025-08-19T08:16:49.532Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33379722,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T01:21:08.577Z","status":"online","status_checked_at":"2026-05-23T02:00:05.530Z","response_time":53,"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":["date-parser","javascript","javascript-library","natural-language-processing","time-parsing","typescript"],"created_at":"2026-05-23T02:13:17.751Z","updated_at":"2026-05-23T02:13:20.761Z","avatar_url":"https://github.com/h-dong.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Serina\n\n\u003e Serina is being actively modernized and maintained again. Current stable usage remains `v1` while the modernization work for new version is in progress.\n\n---\n\n![GitHub Release](https://img.shields.io/github/release/h-dong/serina.svg)\n![GitHub Issues Open](https://img.shields.io/github/issues-raw/h-dong/serina.svg)\n![GitHub Last Commit](https://img.shields.io/github/last-commit/h-dong/serina.svg)\n[![GitHub License](https://img.shields.io/github/license/h-dong/serina.svg)](./LICENSE)\n\n[![Netlify Build Status](https://api.netlify.com/api/v1/badges/debe4f89-718a-43de-b3b7-0b791ae709fe/deploy-status)](https://app.netlify.com/sites/serina/deploys)\n\nNatural Language Parser (NLP) for date and time in Javascript.\n\nSerina Demo: [serina.netlify.com](https://serina.netlify.com)\n\n## Introduction\n\nSerina can parse English phrases and return an object that is easier to work. The name comes from the Xbox Game \"Halo wars\", where she was the Artificial Intelligence of the UNSC navy ship - Spirit of Fire.\n\n## Why Serina\n\nI started this project wanting to experiment with this idea of writing a NLP for data and time. This project was inspired by [Sherlock](!\u003chttps://github.com/neilgupta/Sherlock\u003e) project at the time. After v1 was stable, I wasn't sure which direction to take this project further. For most people, [crono](https://github.com/wanasit/chrono) is a much better solution. The main advantages for Serina are the small bundle size over `crono` and first-class TS support compared to `Sherlock`, which arguably are weak reasons to pick Serina over.\n\nWith the upcoming [Temporal API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal) release, maybe there are more reasons to move this project forward. The current goal is to build a TypeScript first, Temporal API native, and extensible parser-based NLP library. Which just happens to do Date and Time parsing.\n\n## Modernisation Roadmap\n\nUpdated on 2026/04/23.\n\nSerina has gone through a long inactive period, so this roadmap focuses first on reliability and maintainability before adding major new capabilities.\n\n### Goals\n\n- Refresh and update dev dependencies and configs to prepare for the upcoming changes.\n- Reposition library to take advantage of the upcoming [Temporal API](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal).\n- Regex-only path is a dead-end, will be shifting to parser-based approach.\n- Make the parser extensible so users can add custom grammar safely.\n\n### Phase 1: Tooling Modernisation\n\nBefore adding new features, ensure the current codebase runs cleanly in a modern environment.\n\n- [x] Modernize tooling by migrating build pipeline to `tsup` and move to ESM-only bundle output.\n- [x] Bump dev-dependencies to the latest versions.\n- [x] Move to OXC for linting and formatting.\n\n### Phase 2: Core Modernisation\n\nThis phase is focused on technical debt reduction, not feature expansion.\n\n- [ ] Abandon current v2 rewrite, and start from scratch.\n- [ ] Remove DayLite logic and move to Temporal APIs to handle dates. This will provide timezone support out of the box.\n- [ ] Move from monolithic regex parsing toward a custom parser combinator architecture like `Parsimmon` (which is unmaintained now) for modularity and testability.\n- [ ] Bump library version to v2.0.0\n\n### Phase 3: Extensibility and Registry\n\nDifferentiate Serina by making parser customization a first-class feature.\n\n- [ ] Define a stable TypeScript parser interface for built-in and user-provided parsers.\n- [ ] Build a `SerinaEngine` registry model so users can register parser plugins (e.g. `engine.registerParser(myCustomParser)`).\n- [ ] Export and document parser primitives (`digit`, `word`, `whitespace`, etc.) to simplify custom parser development.\n\n## Installation\n\nSimply run `npm install serina`\n\n### Basic browser setup\n\nSerina is now distributed as ESM. Import it from your bundler entry, or directly in a module script.\n\n```html\n\u003cscript type=\"module\"\u003e\n  import serina from 'https://unpkg.com/serina/dist/serina.module.js';\n  const parsed = serina('Remind me to buy milk tomorrow 3pm');\n\u003c/script\u003e\n```\n\n### Node\n\nInstall via NPM:\n\n```bash\nnpm i --save serina\n```\n\n```js\nimport serina from 'serina';\n\nconst parsed = serina('Remind me to buy milk tomorrow 3pm');\n```\n\n`require('serina')` is not supported in this ESM-only output.\n\n## Usage of Library\n\n```ts\nconst parsed = serina('Remind me to buy milk tomorrow 3pm'); // assuming it is currently 29th Oct 2017\n\n// assuming current time is 2019/09/10 1pm\nconsole.log(parsed);\n```\n\n```json\n// console output\n{\n  \"original\": \"Remind me to buy milk tomorrow 3pm\",\n  \"isValid\": true,\n  \"matches\": [\n    {\n      \"text\": \"Remind me to buy milk tomorrow\",\n      \"dateTime\": \"2019-09-10T15:00:00.000Z\",\n      \"matched\": \"3pm\"\n    },\n    {\n      \"text\": \"Remind me to buy milk 3pm\",\n      \"dateTime\": \"2019-09-11T00:00:00.000Z\",\n      \"matched\": \"tomorrow\"\n    },\n    {\n      \"text\": \"Remind me to buy milk\",\n      \"dateTime\": \"2019-09-11T15:00:00.000Z\",\n      \"matched\": \"tomorrow 3pm\"\n    }\n  ]\n}\n```\n\n## Publish\n\nThe recommended way is to publish using Github Actions, by\n\n1. Changing version in package.json to x.y.z\n2. Push a commit with message \"Release x.y.z\", this will then generate tag as well as publish to npm.\n\nHere's an example:\n\n\u003e Now, when someone changes the version in package.json to 1.2.3 and pushes a commit with the message Release 1.2.3, the npm-publish action will create a new tag v1.2.3 and publish the package to the npm registry.\n\nOr publish locally if all else fails.\n\n```bash\nnpm run publish\n```\n\n## Edge cases / Limitations\n\nPeople could express dates \u0026 time in many different ways, and sometimes there's no one clear logical choice. In these situations, I'll try to list them here so everyone's aware about these edge cases and what the expected outcome should be. If people have any suggestions for these decisions feel free to raise an issue about it where we can discuss it in more detail. I'm happy for any of these to be challenged!\n\n### Resolve \"Next 31st\" when the current/next month doesn't have 31 days\n\nGiven current date is 20th February, the logical month for \"next\" in this case should be February itself since 31st is greater than 20th. However, February only has 28 or 29 days depending on if it is a leap year. The current logic is to skip Feb and look for \"next month which has 31 days\". So in this case Serina will resolve \"next 31st\" to be 31st March.\n\n### Week day v.s. day of the week\n\nWeek day normally refers to Mon - Fri and excludes weekends, but for the sake of simplicity (and looking at other libs) I decided it is much easier to just refer to \"day of the week\" as \"week day\" in the code.\n\n### Only match year 1000 - 9999\n\nCurrently the library only find matched YEAR between (1000 - 9999). This could be a limitation for some people, so we may need to come back and address this. Please raise an issue if this is an problem for you.\n\n### Multiple identical matches in the same string\n\nIt was decided to always prioritize the first match in these situations e.g. \"catch the 2:20pm bus at 2:20pm\". This decision was made due to the primary function of the library being time and date conversion. By utilizing the first match, the resulting date object will always be consistent. Allowing for multiple matches would result in duplicate suggestions, potentially leading to a poor user experience.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh-dong%2Fserina","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fh-dong%2Fserina","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh-dong%2Fserina/lists"}