{"id":26009957,"url":"https://github.com/byu-oit/node-enforcer-exception","last_synced_at":"2026-04-19T00:34:54.905Z","repository":{"id":44208308,"uuid":"162622762","full_name":"byu-oit/node-enforcer-exception","owner":"byu-oit","description":"Generate detailed reports about what problems exist and where","archived":false,"fork":false,"pushed_at":"2023-04-30T02:45:44.000Z","size":30,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-08-09T05:36:23.566Z","etag":null,"topics":["investigate-possible-retirement"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/byu-oit.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}},"created_at":"2018-12-20T19:25:56.000Z","updated_at":"2023-07-13T16:03:34.000Z","dependencies_parsed_at":"2024-10-31T11:33:37.947Z","dependency_job_id":"5f00397d-c812-4b1d-891a-22a69bea5141","html_url":"https://github.com/byu-oit/node-enforcer-exception","commit_stats":{"total_commits":7,"total_committers":2,"mean_commits":3.5,"dds":0.1428571428571429,"last_synced_commit":"108678578a5900b9a3005a719bca0f77b5e385d2"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/byu-oit/node-enforcer-exception","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byu-oit%2Fnode-enforcer-exception","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byu-oit%2Fnode-enforcer-exception/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byu-oit%2Fnode-enforcer-exception/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byu-oit%2Fnode-enforcer-exception/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/byu-oit","download_url":"https://codeload.github.com/byu-oit/node-enforcer-exception/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/byu-oit%2Fnode-enforcer-exception/sbom","scorecard":{"id":260512,"data":{"date":"2025-08-11","repo":{"name":"github.com/byu-oit/node-enforcer-exception","commit":"108678578a5900b9a3005a719bca0f77b5e385d2"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/7 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":"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":"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":"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":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql-analysis.yml:28","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql-analysis.yml:29","Warn: no topLevel permission defined: .github/workflows/codeql-analysis.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":"SAST","score":10,"reason":"SAST tool detected: CodeQL","details":["Info: SAST configuration detected: CodeQL","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":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/byu-oit/node-enforcer-exception/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:45: update your workflow using https://app.stepsecurity.io/secureworkflow/byu-oit/node-enforcer-exception/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:59: update your workflow using https://app.stepsecurity.io/secureworkflow/byu-oit/node-enforcer-exception/codeql-analysis.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql-analysis.yml:72: update your workflow using https://app.stepsecurity.io/secureworkflow/byu-oit/node-enforcer-exception/codeql-analysis.yml/master?enable=pin","Info:   0 out of   4 GitHub-owned 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":"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: Apache License 2.0: 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":4,"reason":"6 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-4q6p-r6v2-jvc5","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-g6ww-v8xp-vmwg"],"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-17T10:44:08.553Z","repository_id":44208308,"created_at":"2025-08-17T10:44:08.553Z","updated_at":"2025-08-17T10:44:08.553Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31989852,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"ssl_error","status_checked_at":"2026-04-18T20:23:29.375Z","response_time":103,"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":["investigate-possible-retirement"],"created_at":"2025-03-05T22:26:38.051Z","updated_at":"2026-04-19T00:34:54.844Z","avatar_url":"https://github.com/byu-oit.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Enforcer Exception\n\nGenerate detailed reports about what problems exist and where. Take this example.\n\n```js\nconst { Exception } = require('enforcer-exception')\n\nconst exception = new Exception('Header 1')\nconst subException = exception.at('one').at('two')\nsubException.at('a').message('Error 1');\nsubException.at('b').at(0).message('Error 2');\n\nconsole.log(exception)\n// Header 1\n//   at: one \u003e two\n//     at: a\n//       Error 1\n//     at: b \u003e 0\n//       Error 2\n```\n\n## Examples\n\n#### Create an EnforcerException Instance\n\n```js\nconst { Exception } = require('enforcer-exception')\nconst exception = new Exception('Header 1')\n```\n\n#### Create a Sub Path for an EnforcerException\n\nUse the [`EnforcerException.prototype.at`](#enforcerexceptionprototypeat) function to create a child EnforcerException instance.\n\n```js\nconst { Exception } = require('enforcer-exception')\nconst exception = new Exception('Header 1')\n\nconst subPathException = exception.at('some path')\nsubPathException.message('No soup for you')\n\nconsole.log(exception)\n// Header 1\n//   at: some path\n//     No soup for you\n```\n\n#### Create a Nested Exception\n\nThis method for creating a child exception does not indicate a new path, but rather a new grouping of exceptions.\n\nUse [`EnforcerException.prototype.nest`](#enforcerexceptionprototypenest).\n\n```js\nconst { Exception } = require('enforcer-exception')\nconst exception = new Exception('There was an error')\n\nconst subException = exception.nest('Could not do action X')\nsubException.message(\"I'm a teapot\")\nsubException.message('Too busy to comply')\n\nconsole.log(exception)\n// There was an error\n//   Could not do action X\n//     I'm a teapot\n//     Too busy to comply\n```\n\n## API\n\n- Instance Properties\n\n  - [EnforcerException.count](#enforcerexceptioncount)\n\n  - [EnforcerException.hasException](#enforcerexceptionhasexception)\n\n- Instance Methods\n\n  - [EnforcerException.prototype.at()](#enforcerexceptionprototypeat)\n\n  - [EnforcerException.prototype.clearCache()](#enforcerexceptionprototypeclearcache)\n\n  - [EnforcerException.prototype.nest()](#enforcerexceptionprototypenest)\n\n  - [EnforcerException.prototype.merge()](#enforcerexceptionprototypemerge)\n\n  - [EnforcerException.prototype.message()](#enforcerexceptionprototypemessage)\n\n  - [EnforcerException.prototype.push()](#enforcerexceptionprototypepush)\n\n### EnforcerException.count\n\nThe number of *messages* added to an EnforcerException, including those added to any child EnforcerException instances.\n\n```js\nconst { Exception } = require('enforcer-exception')\n\nconst parent = new Exception('Header 1')\nparent.message('Parent message')\n\nconst child = parent.at('x')\nchild.message('Child message')\n\nconsole.log(parent.count) // 2\nconsole.log(child.count)  // 1\n```\n\n### EnforcerException.hasException\n\nWhether an EnforcerException instance has any messages or not.\n\n```js\nconst { Exception } = require('enforcer-exception')\n\nconst exception = new Exception('Header 1')\nconsole.log(exception.hasException) // false\n\nexception.message('Failed to compute')\nconsole.log(exception.hasException) // true\n```\n\n### EnforcerException.prototype.at\n\nUse this method to create a child exception that indicates a followed path.\n\n**Parameters:**\n\n- *path* - The label for the path being followed.\n\n**Returns:** The child EnforcerException instance\n\n```js\nconst { Exception } = require('enforcer-exception')\nconst exception = new Exception('Header 1')\n\nconst subPathException = exception.at('some path')\nsubPathException.message('No soup for you')\n\nconsole.log(exception)\n// Header 1\n//   at: some path\n//     No soup for you\n```\n\n### EnforcerException.prototype.clearCache\n\nYou probably won't need to call this method as it is used internally, but if you care to know more then keep reading.\n\nSeveral properties are cached when creating, modifying, and reading EnforcerException instances. Obviously this is for performance enhancements, but caching can lead to stale data. Whenever a modification is made to an EnforcerException instance it clears it's own cache and notifies its parent EnforcerException objects. (That plural indicator is not a typo, an EnforcerException instance may have several parents.)\n\n**Parameters:** None\n\n**Returns:** The EnforcerException instance who's cache was just cleared\n\n```js\nconst { Exception } = require('enforcer-exception')\nconst exception = new Exception('There was an error')\nexception.clearCache()\n```\n\n### EnforcerException.prototype.nest\n\nThis method for creating a child exception does not indicate a new path, but rather a new grouping of exceptions.\n\n**Parameters:**\n\n- *header* - The label for the next EnforcerException instance\n\n**Returns:** The child EnforcerException instance\n\n```js\nconst { Exception } = require('enforcer-exception')\nconst exception = new Exception('There was an error')\n\nconst subException = exception.nest('Could not do action X')\nsubException.message(\"I'm a teapot\")\nsubException.message('Too busy to comply')\n\nconsole.log(exception)\n// There was an error\n//   Could not do action X\n//     I'm a teapot\n//     Too busy to comply\n```\n\n### EnforcerException.prototype.merge\n\nCopy the child EnforcerInstances and messages from one EnforcerInstance into another.\n\n**Parameters:**\n\n- *exception* - The EnforcerException instance to copy from\n\n**Returns:** The EnforcerException instance that was copied into\n\n```js\nconst { Exception } = require('enforcer-exception')\n\nconst exceptionA = new Exception('Header A')\nexceptionA.message('Message a')\n\nconst exceptionB = new Exception('Header B')\nexceptionB.message('Message b')\n\nexceptionA.merge(exceptionB)\n\nconsole.log(exceptionA)\n// Header A\n//   Message a\n//   Message b\n```\n\n### EnforcerException.prototype.message\n\nAdd a message to the EnforcerException instance. Once a message is added then the EnforcerException instance is considered to have an exception.\n\n**Parameters:**\n\n- *message* - The message to add\n\n**Returns:** The EnforcerException instance that the message was added to\n\n```js\nconst { Exception } = require('enforcer-exception')\n\nconst exception = new Exception('Header 1')\nexception.message('Message 1')\n\nconsole.log(exception)\n// Header 1\n//   Message 1\n```\n\n### EnforcerException.prototype.push\n\nThis method can be used to add a message (`string`) or an EnforcerInstance object to another EnforcerInstance.\n\n**Parameters:**\n\n- *value* - The message or EnforcerInstance to add\n\n**Returns:** The EnforcerException instance that the value was added to\n\n```js\nconst { Exception } = require('enforcer-exception')\n\nconst child = new Exception('Header 2')\nchild.message('Message 2')\n\nconst parent = new Exception('Header 1')\nparent.push('Message 1')\nparent.push(child)\n\nconsole.log(exception)\n// Header 1\n//   Header 2\n//     Message 2\n//   Message 1\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyu-oit%2Fnode-enforcer-exception","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbyu-oit%2Fnode-enforcer-exception","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbyu-oit%2Fnode-enforcer-exception/lists"}