{"_id":"@anygpt/rules","name":"@anygpt/rules","dist-tags":{"latest":"0.3.1"},"versions":{"0.3.1":{"name":"@anygpt/rules","version":"0.3.1","description":"Type-safe rule engine for matching and transforming objects","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"publishConfig":{"access":"public"},"keywords":["rules","rule-engine","pattern-matching","typescript","type-safe"],"author":{"name":"AnyGPT"},"license":"MIT","gitHead":"694856d0f9aa5bafc05fbf934367a8add2fddb59","_id":"@anygpt/rules@0.3.1","_nodeVersion":"24.10.0","_npmVersion":"11.6.1","dist":{"integrity":"sha512-UIJrnS/NVjQKKzG5ODsb4uIFV5wj3RfRYCOGRTmOg3VuwXAoRZylUwVglsBmCa5UhYvN9Zv0aOMTh21qQzzo/Q==","shasum":"3268df5ee65fc6dd4d7866d29a9ba72014ae164f","tarball":"https://registry.npmjs.org/@anygpt/rules/-/rules-0.3.1.tgz","fileCount":6,"unpackedSize":22218,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCHpRZ0RSmJS9+xyRbvuXgbSOZqrojfdUh4xVkez6pd3wIgD3TabFiY0fMVr5mJymrhqF2eUAs3rJDTUEb6E3fJvQU="}]},"_npmUser":{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"},"directories":{},"maintainers":[{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rules_0.3.1_1761046502005_0.043553816159660474"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-21T11:35:01.934Z","0.3.1":"2025-10-21T11:35:02.202Z","modified":"2025-10-21T11:35:02.435Z"},"maintainers":[{"name":"theplenkov-npm","email":"petr.plenkov@gmail.com"}],"description":"Type-safe rule engine for matching and transforming objects","keywords":["rules","rule-engine","pattern-matching","typescript","type-safe"],"author":{"name":"AnyGPT"},"license":"MIT","readme":"# @anygpt/rules\n\n> **⚠️ WORK IN PROGRESS**: This package is under active development. Rule engine APIs may change significantly. Use at your own risk in production environments.\n\nA simple, type-safe rule engine for matching and transforming objects.\n\n[![Test Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen.svg)](./coverage)\n\n## Features\n\n- ✅ **Type-safe** - Full TypeScript support\n- ✅ **Shortcut syntax** - Direct values, regex, arrays\n- ✅ **Mixed arrays** - Combine regex and exact matches\n- ✅ **Simple operators** - `eq`, `in`, `match` (regex/glob)\n- ✅ **Logical composition** - `and`, `or`, `not`\n- ✅ **Default values** - Constructor-level defaults\n- ✅ **Array operations** - `push` to append to arrays\n- ✅ **Zero dependencies** - Pure TypeScript implementation\n- ✅ **100% test coverage** - Production ready\n\n## Usage\n\n```typescript\nimport { RuleEngine, type Rule } from '@anygpt/rules';\n\ninterface Server {\n  name: string;\n  tools: string[];\n  tags: string[];\n  enabled?: boolean;\n}\n\nconst engine = new RuleEngine(\n  [\n    {\n      // Shortcut: direct value (eq)\n      when: { name: 'github' },\n      set: { enabled: true, priority: 'high' },\n      push: { tags: ['verified'] },\n    },\n\n    {\n      // Shortcut: regex (match)\n      when: { name: /^github/ },\n      set: { enabled: true },\n      push: { tags: ['safe'] },\n    },\n\n    {\n      // Mixed array: regex OR exact match\n      when: { name: [/^gitlab/, 'bitbucket'] },\n      set: { enabled: true, priority: 'medium' },\n    },\n\n    {\n      // Pattern match: regex or glob\n      when: { name: { match: /^github/ } },\n      set: { enabled: true },\n    },\n  ],\n  // Default values applied to all items\n  { enabled: false, priority: 'low', tags: [] }\n);\n\n// Apply rules\nconst result = engine.apply({\n  name: 'github-official',\n  tools: [],\n  tags: ['fast'],\n});\n\n// Result:\n// {\n//   name: 'github-official',\n//   enabled: true,\n//   priority: 'high',\n//   tags: ['fast', 'verified', 'safe']  // Appended!\n// }\n```\n\n## Operators\n\n### Shortcut Syntax (Recommended)\n\nFor cleaner, more readable rules:\n\n- **Direct value** → `eq` operator\n\n  ```typescript\n  {\n    name: 'github';\n  } // Same as { name: { eq: 'github' } }\n  {\n    count: 5;\n  } // Same as { count: { eq: 5 } }\n  ```\n\n- **RegExp** → `match` operator\n\n  ```typescript\n  {\n    name: /^github/;\n  } // Same as { name: { match: /^github/ } }\n  ```\n\n- **Array** → `in` operator (supports mixed types!)\n  ```typescript\n  {\n    name: ['github', 'gitlab'];\n  } // Exact match any\n  {\n    name: [/^github/, 'gitlab'];\n  } // Regex OR exact match\n  {\n    name: [/^github/, /^gitlab/];\n  } // Multiple regex patterns\n  ```\n\n### Explicit Operators\n\n- **`eq`** - Exact match\n\n  ```typescript\n  {\n    name: {\n      eq: 'github';\n    }\n  }\n  ```\n\n- **`in`** - Value is in array\n\n  ```typescript\n  { name: { in: ['github', 'gitlab'] } }\n  ```\n\n- **`match`** - Regex or glob pattern\n  ```typescript\n  {\n    name: {\n      match: /^github/;\n    }\n  }\n  {\n    name: {\n      match: 'github-*';\n    }\n  }\n  {\n    name: {\n      match: ['github-*', 'gitlab-*'];\n    }\n  }\n  ```\n\n### Logical Operators\n\n- **`and`** - All conditions must match\n\n  ```typescript\n  {\n    and: [{ name: { eq: 'github' } }, { tags: { in: ['safe'] } }];\n  }\n  ```\n\n- **`or`** - Any condition must match\n\n  ```typescript\n  {\n    or: [{ name: { eq: 'github' } }, { name: { eq: 'gitlab' } }];\n  }\n  ```\n\n- **`not`** - Negate condition\n  ```typescript\n  { not: { name: { in: ['docker', 'anygpt'] } } }\n  ```\n\n## Pattern Matching\n\nThe `match` operator supports:\n\n1. **RegExp** - Standard JavaScript regex\n\n   ```typescript\n   {\n     name: {\n       match: /^github/;\n     }\n   }\n   ```\n\n2. **Glob patterns** - Simple wildcard patterns\n\n   - `*` - matches any characters\n   - `?` - matches single character\n\n   ```typescript\n   {\n     name: {\n       match: 'github-*';\n     }\n   }\n   {\n     name: {\n       match: 'github-?';\n     }\n   }\n   ```\n\n3. **Multiple patterns** - Match any of the patterns\n   ```typescript\n   {\n     name: {\n       match: [/^github/, 'gitlab-*'];\n     }\n   }\n   ```\n\n## Type Safety\n\nThe rule engine is fully type-safe:\n\n```typescript\ninterface Server {\n  name: string;\n  count: number;\n}\n\nconst rules: Rule<Server>[] = [\n  {\n    when: { name: { eq: 'github' } }, // ✅ OK\n    set: { count: 10 }, // ✅ OK\n  },\n  {\n    when: { invalid: { eq: 'test' } }, // ❌ Error: 'invalid' not in Server\n    set: { name: 'test' }, // ✅ OK\n  },\n  {\n    when: { name: { eq: 'github' } },\n    set: { invalid: true }, // ❌ Error: 'invalid' not in Server\n  },\n];\n```\n\n## Installation\n\n```bash\nnpm install @anygpt/rules\n```\n\n## Development\n\n```bash\n# Run tests\nnpx nx test rules\n\n# Run tests with coverage (100% coverage required)\nnpx nx test rules --coverage\n\n# Build package\nnpx nx build rules\n\n# Lint\nnpx nx lint rules\n\n# Type check\nnpx nx typecheck rules\n```\n","readmeFilename":"README.md","_rev":"1-830697d1b1bf684fb057d15283721a6e"}