{"id":16542516,"url":"https://github.com/tada5hi/continu","last_synced_at":"2026-02-05T09:39:34.102Z","repository":{"id":64870517,"uuid":"579114016","full_name":"tada5hi/continu","owner":"tada5hi","description":"Continu is a powerful tool for managing key-value pairs in an application. Its simple and lightweight design makes it easy to use. Besides, defining default values it is also possible to execute transformations \u0026 validations before setting any value.","archived":false,"fork":false,"pushed_at":"2024-03-28T17:16:17.000Z","size":1267,"stargazers_count":1,"open_issues_count":8,"forks_count":0,"subscribers_count":2,"default_branch":"develop","last_synced_at":"2025-09-05T01:42:08.377Z","etag":null,"topics":["container","key-path","key-value","nested-objects","object","option","transformation","transformer","validation","validator"],"latest_commit_sha":null,"homepage":"","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/tada5hi.png","metadata":{"files":{"readme":"README.MD","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","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":"2022-12-16T17:38:36.000Z","updated_at":"2023-04-07T19:53:37.000Z","dependencies_parsed_at":"2024-06-19T13:26:41.312Z","dependency_job_id":"19c1b7c8-dd8e-41db-9358-db920d3d9c41","html_url":"https://github.com/tada5hi/continu","commit_stats":{"total_commits":62,"total_committers":3,"mean_commits":"20.666666666666668","dds":0.3870967741935484,"last_synced_commit":"5d298ce9372264acc317ecd818445c16a68acab8"},"previous_names":["tada5hi/opticon"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/tada5hi/continu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fcontinu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fcontinu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fcontinu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fcontinu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tada5hi","download_url":"https://codeload.github.com/tada5hi/continu/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tada5hi%2Fcontinu/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29118624,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T05:31:32.482Z","status":"ssl_error","status_checked_at":"2026-02-05T05:31:29.075Z","response_time":65,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["container","key-path","key-value","nested-objects","object","option","transformation","transformer","validation","validator"],"created_at":"2024-10-11T18:57:47.102Z","updated_at":"2026-02-05T09:39:34.065Z","avatar_url":"https://github.com/tada5hi.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Continu 🐯\n\n[![npm version](https://badge.fury.io/js/continu.svg)](https://badge.fury.io/js/continu)\n[![main](https://github.com/tada5hi/continu/actions/workflows/main.yml/badge.svg)](https://github.com/tada5hi/continu/actions/workflows/main.yml)\n[![codecov](https://codecov.io/gh/tada5hi/continu/branch/master/graph/badge.svg?token=L65RSE7BT1)](https://codecov.io/gh/tada5hi/continu)\n[![Known Vulnerabilities](https://snyk.io/test/github/Tada5hi/continu/badge.svg?targetFile=package.json)](https://snyk.io/test/github/Tada5hi/continu?targetFile=package.json)\n[![semantic-release: angular](https://img.shields.io/badge/semantic--release-angular-e10079?logo=semantic-release)](https://github.com/semantic-release/semantic-release)\n\n**Continu** is a powerful tool for managing key-value pairs in an application.\nIts simple and lightweight design makes it easy to use.\nBesides, defining default values it is also possible to execute transformations \u0026 validations before setting any value.\n\n**Table of Contents**\n\n- [Installation](#installation)\n- [Usage](#usage)\n  - [Basic](#basic)\n  - [Defaults](#defaults)\n  - [Transformation](#transformation)\n  - [Validation](#validation)\n  - [Nesting](#nesting)\n  - [Getters](#getters)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Installation\n\n```bash\nnpm install continu --save\n```\n\n## Usage\n\n### Basic\n\nOn the basic level, this library can be used as container for arbitrary key value pairs.\n\n```typescript\nimport { Continu } from 'continu';\n\ntype Options = {\n    foo: string\n}\n\nconst continu = new Continu\u003cOptions\u003e();\n\nconsole.log(continu.has('foo'));\n// false\nconsole.log(continu.get('foo'));\n// undefined\n\ncontinu.set('foo', 'bar');\n\nconsole.log(continu.has('foo'));\n// true\nconsole.log(continu.get('foo'));\n// bar\n\ncontinu.reset('foo');\n\nconsole.log(continu.has('foo'));\n// false\n```\n\n### Defaults\nIt is also possible to define default values which are returned if a given value is not set.\n\n```typescript\nimport { Continu } from 'continu';\n\ntype Options = {\n    foo: string\n}\n\nconst continu = new Continu\u003cOptions\u003e({\n    defaults: {\n        foo: 'bar'\n    }\n});\n\nconsole.log(continu.has('foo'));\n// false\nconsole.log(continu.get('foo'));\n// 'bar'\n\ncontinu.set('foo', 'baz');\n\nconsole.log(continu.has('foo'));\n// true\nconsole.log(continu.get('foo'));\n// 'baz'\n\n```\n\n### Transformation\n\nTransformers can be used to accept multiple input formats.\nThe data can than be converted to the appropriate format before setting.\nTherefore, the `setRaw` method must be used.\n\n```typescript\nimport { Continu } from 'continu';\n\ntype Options = {\n    foo: string\n}\n\nconst continu = new Continu\u003cOptions\u003e({\n    transformers: {\n        foo: (value) =\u003e {\n            if(typeof value === 'number') {\n                return `${value}`;\n            }\n\n            if(typeof value === 'string') {\n                return value;\n            }\n\n            throw new Error('Option could not be transformed.')\n        }\n    }\n});\n\ncontinu.set('foo', '123');\n\nconsole.log(continu.get('foo'));\n// '123'\n\ncontinu.set('foo', 456);\n\nconsole.log(continu.get('foo'));\n// '456'\n\ncontinu.set('foo', {bar: 'baz'});\n// this statement will throw an error!\n```\n\n### Validation\n\nValidators can be useful for defining constraints and prevent values from being set,\nif they don't match specific criteria.\n\n```typescript\nimport { Continu } from 'continu';\n\ntype Options = {\n    foo: string\n}\n\nconst continu = new Continu\u003cOptions\u003e({\n    validators: {\n        foo: (value) =\u003e typeof value === 'string' \u0026\u0026 value.length \u003e 3,\n    }\n});\n\ncontinu.set('foo', 'bar');\n\nconsole.log(continu.get('foo'));\n// undefined\n\ncontinu.set('foo', 'bar-baz');\n\nconsole.log(continu.get('foo'));\n// 'bar-baz'\n\n```\n\n### Nesting\n\nWhen using nested object types, it is also possible to use key paths (separated by `.`) to\naccess properties in depth.\n\n```typescript\nimport { Continu } from 'continu';\n\ntype Options = {\n    nested: {\n        foo: string\n    }\n}\n\nconst continu = new Continu\u003cOptions\u003e();\n\nconsole.log(continu.has('nested.foo'));\n// false\nconsole.log(continu.get('nested.foo'));\n// undefined\n\ncontinu.set('nested.foo', 'bar');\n\nconsole.log(continu.has('nested.foo'));\n// true\nconsole.log(continu.get('nested.foo'));\n// 'bar'\n\nconsole.log(continu.has('nested'));\n// true;\nconsole.log(continu.get('nested'));\n// { foo: 'bar' }\n```\n\n### Getters\n\nIt is also possible to define dynamic getters for specific key (paths).\n\n```typescript\nimport { Continu } from 'continu';\n\ntype Options = {\n    foo: string,\n    nested: {\n        baz: string\n    }\n}\n\nconst continu = new Continu\u003cOptions\u003e({\n    defaults: {\n        foo: 'bar'\n    },\n    getters: {\n        nested: (context) =\u003e {\n            return {\n                baz: context.getDefault('foo')\n            }\n        }\n    }\n});\n\n// always evaluates to false,\n// since a key path may not be accessible until a getter has been evaluated.\nconsole.log(continu.has('nested'));\n\nconsole.log(continu.get('nested'));\n// { foo: 'bar' }\n\nconsole.log(continu.get('nested.baz'));\n// 'bar'\n```\n\n## Contributing\n\nBefore starting to work on a pull request, it is important to review the guidelines for\n[contributing](./CONTRIBUTING.md) and the [code of conduct](./CODE_OF_CONDUCT.md).\nThese guidelines will help to ensure that contributions are made effectively and are accepted.\n\n## License\n\nMade with 💚\n\nPublished under [MIT License](./LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftada5hi%2Fcontinu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftada5hi%2Fcontinu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftada5hi%2Fcontinu/lists"}