{"id":31996770,"url":"https://github.com/alexandrucancescu/node-config-schema","last_synced_at":"2025-10-15T13:27:36.062Z","repository":{"id":34296860,"uuid":"175287333","full_name":"alexandrucancescu/node-config-schema","owner":"alexandrucancescu","description":"Type checking for configuration files","archived":false,"fork":false,"pushed_at":"2023-03-04T03:19:47.000Z","size":37,"stargazers_count":4,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-10-09T21:59:26.238Z","etag":null,"topics":["config-management","configuration","configuration-files","configuration-management","node","nodejs","schema","schema-validation","ts","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","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/alexandrucancescu.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":"2019-03-12T19:59:19.000Z","updated_at":"2024-02-27T22:47:29.000Z","dependencies_parsed_at":"2023-01-15T06:01:59.527Z","dependency_job_id":null,"html_url":"https://github.com/alexandrucancescu/node-config-schema","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alexandrucancescu/node-config-schema","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrucancescu%2Fnode-config-schema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrucancescu%2Fnode-config-schema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrucancescu%2Fnode-config-schema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrucancescu%2Fnode-config-schema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexandrucancescu","download_url":"https://codeload.github.com/alexandrucancescu/node-config-schema/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexandrucancescu%2Fnode-config-schema/sbom","scorecard":{"id":180709,"data":{"date":"2025-08-11","repo":{"name":"github.com/alexandrucancescu/node-config-schema","commit":"a836119a13bc4a044ec2d5508698e24bf3278ad5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.7,"checks":[{"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":"Code-Review","score":0,"reason":"Found 0/19 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":"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":"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":"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":"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":"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":"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":"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"}},{"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":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h"],"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-16T18:49:00.338Z","repository_id":34296860,"created_at":"2025-08-16T18:49:00.339Z","updated_at":"2025-08-16T18:49:00.339Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279082829,"owners_count":26099498,"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-10-15T02:00:07.814Z","response_time":56,"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":["config-management","configuration","configuration-files","configuration-management","node","nodejs","schema","schema-validation","ts","typescript"],"created_at":"2025-10-15T13:27:29.503Z","updated_at":"2025-10-15T13:27:36.049Z","avatar_url":"https://github.com/alexandrucancescu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# node-config-schema\n\n## Features\n\n*   Define schema for configuration files\n*   Validate configuration files for type errors\n*   Recursive check, allowing any nested level\n*   Generates type declaration for typescript and injects them into your code\n*   Typescript definitions included\n\n## Install\n\n```shell\n$ npm install --save node-config-schema\n```\n\n## Introduction\n\n**node-config-schema** lets you define a schema for your configuration files.\nThis ensures that you have no surprises in your application during runtime, any property with the wrong\ntype is caught during the initialization of the app.\n\nFurthermore **node-config-schema** can **generate** typescript type definitions for your schema and even \n**inject** them into your code, keeping them up to date.\n\nIt wraps around the popular node package [config](https://www.npmjs.com/package/config) so\nit offers all the customization of it such as:\n* Merging multiple config files\n* Loading config files based on the environment\n* Config files written in **.yml .yaml .xml .coffee .cson .properties .json, .json5 .hjson .ts .js**\n\n## Quick Start\n\nThis guide assumes you are already familiar with [config](https://www.npmjs.com/package/config)\npackage and know how it works. If not, you should read their quick guide first.\n\nThis guide is also written in typescript, but can be easily adjusted for js.\n\n```javascript\nimport  TConfig,{TBoolean, TNumber, TObject, TString,TAny} from \"node-config-schema\"\n\nTConfig.create({\n    admins:TObject,\n    conf:TAny,\n    database: {\n        hosts: [TString],\n        credentials: {\n            auth: TBoolean,\n            user: TString,\n            pass: TString,\n        }\n    },\n    //Array of objects with a property 'x' that is an array of arrays of numbers\n    matrix: [{x:[[TNumber]]}],\n});\n\nconst config=TConfig.instance.parseConfig();\n```\n##### Import JS:\n\n```javascript\nconst {TConfig,TNumber,TBoolean,TAny}=require(\"node-config-schema\");\n```\n\n#### How:\n1. First you need to initialize TConfig by calling ```TConfig.create``` and passing it your schema.\n2. Retrieve the singleton instance using `TConfig.instance`\n3. Start the parsing process with `parseConfig()`\n4. `parseConfig()` returns your configuration object, just as **config** would have, type checked and\nvalidated. No surprises!\n\nTConfig will parse the config files using **config** package and\ncheck each property of each object and each item of each array, making\nsure they fulfill the schema defined by you.\n\n#### How to define a schema:\n\nA schema is defined using a combination of nested objects and `TTypes`.\n\nTTypes include:\n`TNumber,TBoolean,TString,TArray,TObject,TAny`\n\nThese `TTypes` are functions that can be passed to the schema as they are such as:\n\n```javascript\n{\n    x: TNumber,\n}\n```\nOr pass the result of the function.\n```javascript\n{\n    x: TNumber(),\n    y: TString(true),\n}\n```\n\nEvery `TType` function has an optional `optional` parameter.\nIf this parameter is set to true, `TConfig` will treat the config\nproperty as optional, and will not throw an error if left\nundefined.\n\nFor simplicity `TArray` can be passed to the schema as an\narray ```[]```, with the only item being the optional nested\nschema ```[TSchema]```.\n\n\n```javascript\n{\n    x: TString,\n    same as\n    x: TString(),\n    same as\n    x: TString(false),\n    \n    y: Array,\n    same as\n    y: [],\n    same as \n    y: Array()\n   \n   z:Array(false,TNumber),\n   same as\n   z:[TNumber]\n}\n```\n\n**Read API Documentation** for more examples.\n\n---\n#### NOTE:\n\n**node-config-schema** is designed using the singleton design, meaning there can only be\none instance of it, that will be created using the `create` method.\nThis design choice has been made due to the nature of the **config** package.\n\n## API DOCUMENTATION\n\n### TConfig\n\nThis is the base singleton class.\n\n##### Methods:\n\n`create(schema: TSchema, configDir?: string)`\n\nThis method initializes the TConfig class with the given `schema`.\nOptionally you can pass the path to the dir of the configuration files.\nIt will be passed to the **config** package using `process.env`.\n\n`parseConfig()`\n\nParses and returns the configurations object. Will throw an error on the first\noccurrence of a property that does not fulfill the schema.\n\n`instance`\n\nRetrieve the TConfig instance. This is a getter.\n\n### TSchema\n\nDefinition of schema type. \n\n### TNumber,TBoolean,TString\n\n`TType(optional?: boolean)`\n\nFunctions describing the type of the key they are assigned to.\n\nCan be passed as functions, or the result of their call can be passed.\n\nEvery `TType` function has an optional `optional` parameter.\nIf this parameter is set to true, `TConfig` will treat the config\nproperty as optional, and will not trow an error if this is\nleft undefined.\n\n### TObject,TAny\n\nSame as the other `TTypes`.\n\n`TObject` can be any object, including an array or an empty object `{}`.\n\n`TAny` can be anything except null and undefined\n### TArray\n\n`TArray(optional?: boolean,nestedSchema?: TSchema)`\n\nSame as the other `TTypes` except this type has an additional\noptional parameter describing its nested schema. Every member of the array\nis checked to fulfill this schema. If `nestedSchema` is omitted, TConfig\nwill only check that this is an array.\n\nFor simplicity `TArray` can be passed to the schema as an\narray, with the only item of this array being the optional nested\nschema.\n\n```javascript\n{\n    x:TArray(false,TNumber),\n    \n    //Same as:\n    \n    x:[TNumber]\n    \n    \n    x:TArray(false,TArray(false,{x:TString})),\n    \n    //same as\n    \n    x:[[{x:TString}]]\n}\n```  \n\n## Injecting type definitions for typescript \n\n**node-config-schema** can also generate type definitions for your\nschema and inject them into your code. This is important\nfor typescript developers, as they can benefit from\nIDE functions when the IDE can understand the types your schema\nreturns.\n\nSetting this up is straight-forward.\n\nFile `src/Config.ts`\n```javascript\nimport  TConfig,{TBoolean, TNumber, TObject, TString,TAny} from \"node-config-schema\"\n\n//config_types\n\nTConfig.create({\n\tdatabase: {\n\t\thosts: [TString],\n\t\tcredentials: {\n\t\t\tauth: TBoolean,\n\t\t\tuser: TString,\n\t\t\tpass: TString,\n\t\t}\n\t}\n});\n\nTConfig.instance.parseConfig();\n```\n\nFile `package.json`\n```json\n{\n  \"name\": \"your-project\",\n  \"scripts\": {\n    \"inject-types\": \"tconfig-inject inject ./src/Config.ts\",\n    \"print-types\": \"tconfig-inject print ./src/Config.ts\"\n  },\n  ....\n}\n```\n\nTerminal:\n```shell\n$ npm run inject-types\n```\n\nThe lib will attempt to find your schema, interpret it and\ninject it bellow `//config_types` comment as follows:\n\n```javascript\n//config_types\ntype ConfigType={\n\tdatabase: {\n\t\thosts: [string],\n\t\tcredentials: {\n\t\t\tauth: boolean,\n\t\t\tuser: string,\n\t\t\tpass: string,\n\t\t},\n\t},\n};\n...\n```\n\nThe script attempts to replace a previous version of the types\nfirst. If it cannot find one, it will inject the new types bellow the\n`//config_types` comment. If the comment is absent, it will inject the types\nat the end of the file.\n\n### API\n`tconfig-inject cmd filePath`\n\n**cmd**\n*   `print` only prints type definitions\n*   `inject` attempts to inject them\n\n**filePath** can be relative to the project root using `./relative-path`\nor absolute.\n\n### NOTICE\n\nIn order to find your schema declaration, the script tries to find\nthe string sequence `TConfig.create(`. If you import `TConfig` under\na different name, the parser will not be able to find your declaration.\n\nAlso the parser finds the old version of your type declaration\nby searching for `type ConfigType=` so don't modify it either.\n\n### LICENSE\n\n#### MIT\n\n\n\n\n\n\n\n\n \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandrucancescu%2Fnode-config-schema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexandrucancescu%2Fnode-config-schema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexandrucancescu%2Fnode-config-schema/lists"}