{"id":18039638,"url":"https://github.com/timbokz/ange","last_synced_at":"2026-04-28T11:02:44.767Z","repository":{"id":52116430,"uuid":"132054243","full_name":"TimboKZ/Ange","owner":"TimboKZ","description":"♻️ Compile anything into anything using EJS templates.","archived":false,"fork":false,"pushed_at":"2022-12-04T06:56:14.000Z","size":127,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-04T10:56:26.923Z","etag":null,"topics":["automation","cli","compiler","es6","generator","javascript","nodejs"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/ange","language":"JavaScript","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/TimboKZ.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":"2018-05-03T22:02:25.000Z","updated_at":"2023-01-25T23:28:21.000Z","dependencies_parsed_at":"2022-08-30T06:31:35.310Z","dependency_job_id":null,"html_url":"https://github.com/TimboKZ/Ange","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/TimboKZ/Ange","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimboKZ%2FAnge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimboKZ%2FAnge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimboKZ%2FAnge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimboKZ%2FAnge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TimboKZ","download_url":"https://codeload.github.com/TimboKZ/Ange/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TimboKZ%2FAnge/sbom","scorecard":{"id":141837,"data":{"date":"2025-08-11","repo":{"name":"github.com/TimboKZ/Ange","commit":"d30c316b723064e55d10ae5256253b1e491821a5"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/14 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":"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":"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":"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":"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":"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":"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":"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":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":"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":0,"reason":"32 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-6chw-6frg-f759","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-257v-vj4p-3w2h","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-phwq-j96m-2c2q","Warn: Project is vulnerable to: GHSA-ghr5-ch3p-vcr6","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6"],"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-16T08:19:44.499Z","repository_id":52116430,"created_at":"2025-08-16T08:19:44.500Z","updated_at":"2025-08-16T08:19:44.500Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32377599,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-28T09:24:15.638Z","status":"ssl_error","status_checked_at":"2026-04-28T09:24:15.071Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: 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":["automation","cli","compiler","es6","generator","javascript","nodejs"],"created_at":"2024-10-30T14:09:56.320Z","updated_at":"2026-04-28T11:02:44.710Z","avatar_url":"https://github.com/TimboKZ.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ange\n\nCompile anything into anything using [EJS templates](http://ejs.co/).\n\n# Philosophy\n\nThere are times when you want to automate some part of text (or documentation) generation, but that part is either too\nspecific or too small to justify using tools like [apiDoc](http://apidocjs.com/) or [JSDoc](https://github.com/jsdoc3/jsdoc).\nAnge addresses this exact issue - it lets you insert small JavaScript snippets into any  text file using the\n[EJS templating engine](http://ejs.co/). These snippets will then be evaluated to print out the final result - letting\nyou automatically generate content for text files.\n\nAnge doesn't stop at documentation - it works with any text file format. You can use it for anything you want - for\nexample, you can use Ange to generate a config file for continuous integration (using Ange to print environment\nvariables into the config).\n\nAnge was meant to be very simple to use - it requires no configuration and uses\n[default EJS syntax](http://ejs.co/#docs), yet it is still a very powerful tool. That said, if you're working on a large\nproject that requires complex compilation logic, you should probably go for a real documentation/static site generator.\n\n# Usage\n\nMake sure you have [Node.js v6+](https://nodejs.org/) installed. Below you can see an example command line workflow for\nAnge. You can view help using the `ange help` command.\n\n```bash\n# Install Ange globally\nnpm install -g ange\n\n# Create a new folder\nmkdir ange-demo\ncd ange-demo\n\n# Create a template file for Ange\necho 'Current date is \u003c%- new Date().toLocaleDateString() %\u003e.' \u003e date.ange.txt\n# The command above will create the file `date.ange.txt`\n\n# Compile the template - Ange will automatically discover it\nange\n# `date.ange.txt` -\u003e `data.txt`\n\n# View the contents of the generated file\ncat date.txt\n\n# You can also use Glob patterns:\nange './**/*.ange.txt'\n\n# Add `-w` or `--watch` flag to watch files for changes\nange './**/*.ange.txt' -w\n```\n\nYou can run `ange` on a single file (`ange my-file.txt`) or on a directory (`ange my-folder/`). Running `ange` without\nany arguments will make it use the current directory. If you want Ange to scan folder recursively, you need to use the\n`-r` flag.\n\n### EJS templates\n\nThe basic idea is that you first need to create a template file that has\n`.ange` in its name. For example: `api-docs.ange.md`, `style.ange.css`,\n`config.ange.ini`, etc. You can use [EJS syntax](http://ejs.co/#docs) in this\nfile. That is, you can insert JavaScript snippets directly into the file,\nlike so:\n\n```\n... you should get this response: \u003c%- JSON.stringify({operationStatus: 'success'}) %\u003e.\n```\n\nAnge will compile the line from above into this:\n\n\n```\n... you should get this response: {\"operationStatus\":\"success\"}.\n```\n\nFiles with `.ange` in their names are recognised automatically. You can still compile files without `.ange` by targeting\nthem directly: `ange my-file.txt my-output.txt`. You can use `require(...)`, `__dirname` and `__filename` inside your\ntemplates.\n\nAs you can see below, EJS supports different types of tags/template strings. Make sure to check out the Examples section\nbelow and [EJS docs](http://ejs.co/#docs) to see what else is posisble.\n\n```\n\u003c%- 'This string will be printed out unescaped: \u0026\u003c\u003e' %\u003e\n\u003c%= 'This string will be escaped: \u0026\u003c\u003e' %\u003e\n```\n\n### Output path\n\nThere are several ways to specify the output path. By default, Ange will just remove the `.ange` part from the filename\nand write the output into the resultant path. You can also add the following line to the top of your file to specify\na custom output path:\n\n```\n\u003c%# output: ./custom-output.txt -%\u003e\n```\n\nAdditionally, you can specify the output in the command line using `ange \u003cinput-path\u003e \u003coutput-path\u003e`, but this only\nworks when `\u003cinput-path\u003e` is a single file (and not a directory).\n\n### Note about `require(...)`\n\nThe `require()` method is passed to your templates as an EJS property. This lets you import different Node modules and\nother JS files in your templates. To make relative paths work, Ange actually uses a wrapper that looks like this:\n\n```javascript\nconst specialRequire = requirePath =\u003e {\n    if (!requirePath.startsWith('.')) return require(requirePath);\n    return require(path.resolve(templateDir, requirePath));\n};\n```\n\nIf you're getting some unexpected behaviour with `require(...)`, definition above should probably explain why. Make sure\nto [create an issue](https://github.com/TimboKZ/Ange/issues) if you encounter a bug.\n\n# Examples\n\nExamples can be found in the `examples/` folder. You can run `ange -r` in that folder to rebuild all of the examples.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimbokz%2Fange","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimbokz%2Fange","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimbokz%2Fange/lists"}