# rules/eslint/no-unsafe-switch.eslint.rule.ts

> 46 lines of code and 11 definitions.

Tree: GovLab Extension Host
Language: typescript
Canonical: https://banes-lab.com/anatomy/governance#file-governance-rules-eslint-no-unsafe-switch-eslint-rule-ts
Source text: https://banes-lab.com/source/governance/rules/eslint/no-unsafe-switch.eslint.rule.ts.txt

Listed in [rules/eslint](https://banes-lab.com/api/source/governance/rules/eslint.md), after [rules/eslint/no-undeclared-dependency.eslint.rule.ts](https://banes-lab.com/source/governance/rules/eslint/no-undeclared-dependency.eslint.rule.ts.md) and before [rules/eslint/require-cache-coverage.eslint.rule.ts](https://banes-lab.com/source/governance/rules/eslint/require-cache-coverage.eslint.rule.ts.md).

## Definitions

- `isUnsafeSwitch` (lexical_declaration, line 11)
- `templateLiteral` (method_definition, line 28, exported)
- `create` (method_definition, line 20, exported)
- `literal` (method_definition, line 22, exported)
- `SWITCH_PREFIX` (lexical_declaration, line 6)
- `VALUE_SEPARATOR` (lexical_declaration, line 7)
- `WORD_SEPARATOR` (lexical_declaration, line 8)
- `SAFETY_OFF_WORDS` (lexical_declaration, line 9)
- `[name = ""]` (lexical_declaration, line 15)
- `text` (lexical_declaration, line 23, exported)
- `[head]` (lexical_declaration, line 29, exported)

## Contained in

- [rules/eslint](https://banes-lab.com/anatomy/governance/folder-governance-rules-eslint.md)

## Uses

- [shared/factories/listener.factory.ts](https://banes-lab.com/source/governance/shared/factories/listener.factory.ts.md)
- [shared/selectors/syntax.selector.ts](https://banes-lab.com/source/governance/shared/selectors/syntax.selector.ts.md)

## Enforces

- [Secure by Default](https://banes-lab.com/records/architecture/secure-by-default.md)

## Linked from

- [rules/eslint](https://banes-lab.com/anatomy/governance/folder-governance-rules-eslint.md)
- [shared/factories](https://banes-lab.com/anatomy/governance/folder-governance-shared-factories.md)
- [shared/selectors](https://banes-lab.com/anatomy/governance/folder-governance-shared-selectors.md)

## Source

```typescript
import type { LocalRule, RuleContext, RuleListener } from "../../types/rule.types.ts";
import { literalString, nodesAt, recordAt, stringIn } from "../../shared/selectors/syntax.selector.ts";
import { defineCheck } from "@govlab/context/check";
import { listener } from "../../shared/factories/listener.factory.ts";

const SWITCH_PREFIX = "--";
const VALUE_SEPARATOR = "=";
const WORD_SEPARATOR = "-";
const SAFETY_OFF_WORDS: ReadonlySet<string> = new Set(["unsafe"]);

const isUnsafeSwitch = function isUnsafeSwitch(text: string): boolean {
    if (!text.startsWith(SWITCH_PREFIX)) {
        return false;
    }
    const [name = ""] = text.slice(SWITCH_PREFIX.length).split(VALUE_SEPARATOR);
    return name.split(WORD_SEPARATOR).some((word) => SAFETY_OFF_WORDS.has(word));
};

export default {
    create(context: RuleContext): RuleListener {
        return listener({
            literal(view, node) {
                const text = literalString(view);
                if (text !== null && isUnsafeSwitch(text)) {
                    context.report({ messageId: "unsafeSwitch", node });
                }
            },
            templateLiteral(view, node) {
                const [head] = nodesAt(view, "quasis");
                if (isUnsafeSwitch(stringIn(recordAt(head ?? null, "value"), "cooked"))) {
                    context.report({ messageId: "unsafeSwitch", node });
                }
            },
        });
    },
    meta: {
        docs: {
            checks: defineCheck({ detects: [], enforces: ["architecture:secure-by-default"] }),
            description:
                "A process switch that turns a safety mechanism off is never passed to make something work. A command-line switch whose name carries a safety-off word is reported at the source, so the supported setting that gives the result is found and used instead.",
        },
        messages: {
            unsafeSwitch:
                "This switch turns a safety mechanism off. Measure which supported setting gives the result and pass that; when no supported setting does, the capability is reported as unavailable, never forced.",
        },
        schema: [],
        type: "problem",
    },
} satisfies LocalRule;
```
