{"_id":"@bupkis/from-chai","_rev":"4-4f9bbebde27cf772656cf0a96554a2dc","name":"@bupkis/from-chai","dist-tags":{"latest":"1.0.0"},"versions":{"0.1.0":{"name":"@bupkis/from-chai","version":"0.1.0","keywords":["bupkis","chai","codemod","migration","assertions"],"author":{"name":"Christopher Hiller","email":"boneskull@boneskull.com"},"license":"BlueOak-1.0.0","_id":"@bupkis/from-chai@0.1.0","maintainers":[{"name":"boneskull","email":"boneskull@boneskull.com"}],"homepage":"https://bupkis.zip","bugs":{"url":"https://github.com/boneskull/bupkis/issues"},"bin":{"bupkis-from-chai":"dist/cli.js"},"dist":{"shasum":"98ad5f88012806bace9a718279a2a2d421831dcc","tarball":"https://registry.npmjs.org/@bupkis/from-chai/-/from-chai-0.1.0.tgz","fileCount":59,"integrity":"sha512-zTWOp1DJd9RoiOkeEHCVzq2Dtcvccq5P6/+v1vhViKmryaWELvdJ5VIffV1tm6w85/VqR9UA1vYVThj/yD5gvQ==","signatures":[{"sig":"MEQCIAmeu2jtzslUv8WBy5cQkY3gNmBitaCGpUBcZFNiLN6JAiAeFQphl1KDHURiGmqYaXo75zsNYos77xqgv84/9u60VA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":232581},"type":"module","engines":{"node":"^20.19.0 || ^22.12.0 || >=23"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"f09ff1cfb21ceb03dee850971611a3d1e98086b4","scripts":{"test":"npm run test:base -- \"test/**/*.test.ts\"","build":"tsc","test:dev":"npm run test:base -- --watch \"test/**/*.test.ts\"","test:base":"node --test --test-reporter=spec --import tsx","test:node20":"npm run test:base -- test/**/*.test.ts"},"_npmUser":{"name":"boneskull","email":"boneskull@boneskull.com"},"prettier":{"tsdoc":true,"plugins":["prettier-plugin-jsdoc","prettier-plugin-pkg"],"singleQuote":true,"jsdocPreferCodeFences":true,"jsdocCommentLineStrategy":"keep"},"repository":{"url":"git+https://github.com/boneskull/bupkis.git","type":"git","directory":"packages/from-chai"},"_npmVersion":"11.6.2","description":"Migrate Chai assertions to bupkis","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ts-morph":"^25.0.0","@boneskull/bargs":"4.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"chai":"^5.0.0","chai-as-promised":"^8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/from-chai_0.1.0_1768604256546_0.04051275367546281","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@bupkis/from-chai","version":"0.1.2","keywords":["bupkis","chai","codemod","migration","assertions"],"author":{"name":"Christopher Hiller","email":"boneskull@boneskull.com"},"license":"BlueOak-1.0.0","_id":"@bupkis/from-chai@0.1.2","maintainers":[{"name":"boneskull","email":"boneskull@boneskull.com"}],"homepage":"https://bupkis.zip","bugs":{"url":"https://github.com/boneskull/bupkis/issues"},"bin":{"bupkis-from-chai":"dist/cli.js"},"dist":{"shasum":"7a1fac4d684f453f39a0dbbe6bc707fcba1a02e3","tarball":"https://registry.npmjs.org/@bupkis/from-chai/-/from-chai-0.1.2.tgz","fileCount":59,"integrity":"sha512-Reg2qPLl7MOabCPu+Qczei+QDXdNxPe7M5rocWoVsgWv8wAEVderp6Mrtf85Ka477jvjeAuhSHdTwaABPqutng==","signatures":[{"sig":"MEUCIQCyTbnL9A7RZ3DZ2V4CN7qm4xnlhqFzsasRzUe6BudjfQIgGkFVpyodqxaFN4s3Ms7Cd0FtKIti55TXTt28uVxetB8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":207663},"type":"module","engines":{"node":"^20.19.0 || ^22.12.0 || >=23"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"cb086f3b4bd6d657892e325e2984a073afaa57c9","scripts":{"test":"npm run test:base -- \"test/**/*.test.ts\"","build":"tsc","test:dev":"npm run test:base -- --watch \"test/**/*.test.ts\"","test:base":"node --test --test-reporter=spec --import tsx","test:node20":"npm run test:base -- test/**/*.test.ts"},"_npmUser":{"name":"boneskull","email":"boneskull@boneskull.com"},"prettier":{"tsdoc":true,"plugins":["prettier-plugin-jsdoc","prettier-plugin-pkg"],"singleQuote":true,"jsdocPreferCodeFences":true,"jsdocCommentLineStrategy":"keep"},"repository":{"url":"git+https://github.com/boneskull/bupkis.git","type":"git","directory":"packages/from-chai"},"_npmVersion":"11.6.2","description":"Migrate Chai assertions to bupkis","directories":{},"_nodeVersion":"24.12.0","dependencies":{"ts-morph":"^25.0.0","@boneskull/bargs":"4.0.0","@bupkis/codemod-core":"^0.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"chai":"^5.0.0","chai-as-promised":"^8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/from-chai_0.1.2_1771466550503_0.45448079534392294","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@bupkis/from-chai","version":"0.1.3","keywords":["bupkis","chai","codemod","migration","assertions"],"author":{"name":"Christopher Hiller","email":"boneskull@boneskull.com"},"license":"BlueOak-1.0.0","_id":"@bupkis/from-chai@0.1.3","maintainers":[{"name":"boneskull","email":"boneskull@boneskull.com"}],"homepage":"https://bupkis.zip","bugs":{"url":"https://github.com/boneskull/bupkis/issues"},"bin":{"bupkis-from-chai":"dist/cli.js"},"dist":{"shasum":"07130e96d42a79b737e571894473380f14271de3","tarball":"https://registry.npmjs.org/@bupkis/from-chai/-/from-chai-0.1.3.tgz","fileCount":15,"integrity":"sha512-sdNbKh0UInAAy3O2d1i/OnvLusGALcYv80WanrTV1rXNmSRLBjoVgGt0I9k4LT2ruTPWJLjzlhBecmSmzEYkCw==","signatures":[{"sig":"MEUCIHr1g4bFOV24CWJItx54C20LyTZBm1/DeKr7wzHW/dfwAiEApc57n+/XvUnZfFhFysrwOGrRFRDyFWFmdEXO5ms7y/Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78111},"type":"module","engines":{"node":"^20.19.0 || ^22.12.0 || >=23"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./package.json":"./package.json"},"gitHead":"64ef732a58e91cc6c0808149500c8eb3de56c4e1","scripts":{"test":"npm run test:base -- \"test/**/*.test.ts\"","build":"tsc","test:dev":"npm run test:base -- --watch \"test/**/*.test.ts\"","test:base":"node --test --test-reporter=spec --import tsx","test:node20":"npm run test:base -- test/**/*.test.ts"},"_npmUser":{"name":"boneskull","email":"boneskull@boneskull.com"},"prettier":{"tsdoc":true,"plugins":["prettier-plugin-jsdoc","prettier-plugin-pkg"],"singleQuote":true,"jsdocPreferCodeFences":true,"jsdocCommentLineStrategy":"keep"},"repository":{"url":"git+https://github.com/boneskull/bupkis.git","type":"git","directory":"packages/from-chai"},"_npmVersion":"11.16.0","description":"Migrate Chai assertions to bupkis","directories":{},"_nodeVersion":"24.18.0","dependencies":{"ts-morph":"^28.0.0","@boneskull/bargs":"4.1.0","@bupkis/codemod-core":"^0.1.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"chai":"6.2.2","chai-as-promised":"8.0.2"},"_npmOperationalInternal":{"tmp":"tmp/from-chai_0.1.3_1782785759435_0.3246684777676869","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@bupkis/from-chai","version":"1.0.0","type":"module","description":"Migrate Chai assertions to bupkis","repository":{"directory":"packages/from-chai","type":"git","url":"git+https://github.com/boneskull/bupkis.git"},"homepage":"https://bupkis.zip","author":{"name":"Christopher Hiller","email":"boneskull@boneskull.com"},"license":"BlueOak-1.0.0","engines":{"node":"^22.13.0 || >=24.0.0"},"bin":{"bupkis-from-chai":"dist/cli.js"},"exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./package.json":"./package.json"},"keywords":["bupkis","chai","codemod","migration","assertions"],"scripts":{"build":"tsc","test":"npm run test:base -- \"test/**/*.test.ts\"","test:base":"node --test --test-reporter=spec --import tsx","test:ci":"npm run test -- --test-reporter=node-test-github-reporter","test:coverage":"c8 --reporter=lcov --reporter=text npm test","test:dev":"npm run test -- --watch"},"dependencies":{"@boneskull/bargs":"4.1.0","@bupkis/codemod-core":"^1.0.0","ts-morph":"^28.0.0"},"devDependencies":{"chai":"6.2.2","chai-as-promised":"8.0.2"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"prettier":{"jsdocCommentLineStrategy":"keep","jsdocPreferCodeFences":true,"plugins":["prettier-plugin-jsdoc","prettier-plugin-pkg"],"singleQuote":true,"tsdoc":true},"gitHead":"c0f3fcd74ca0f7e307d2a68ce12bba81b4059eb5","_id":"@bupkis/from-chai@1.0.0","bugs":{"url":"https://github.com/boneskull/bupkis/issues"},"_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-O8E+nS8jj6C8uCRdgYRiFhKar07oZ95R0Iy4f0AsJz5Uf/F9fJBD5JxTRiOgAZydTsOKn4rTWGVyDB5i9nBAfg==","shasum":"768c12ba49d197cca0f11492688b85499d96c716","tarball":"https://registry.npmjs.org/@bupkis/from-chai/-/from-chai-1.0.0.tgz","fileCount":59,"unpackedSize":208586,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGPbv/Z5ba/BgsQFAfl04wWqJPCyzoy5ZP6Y9D2Z8M6kAiBDq2fZK+wp4HeC3W+2zhpUPfZANjfMCv8VeCnw3Yh51g=="}]},"_npmUser":{"name":"boneskull","email":"boneskull@boneskull.com"},"directories":{},"maintainers":[{"name":"boneskull","email":"boneskull@boneskull.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/from-chai_1.0.0_1783650178612_0.26099781947970335"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-16T22:57:36.427Z","modified":"2026-07-10T02:22:58.908Z","0.1.0":"2026-01-16T22:57:36.689Z","0.1.2":"2026-02-19T02:02:30.657Z","0.1.3":"2026-06-30T02:15:59.564Z","1.0.0":"2026-07-10T02:22:58.763Z"},"bugs":{"url":"https://github.com/boneskull/bupkis/issues"},"author":{"name":"Christopher Hiller","email":"boneskull@boneskull.com"},"license":"BlueOak-1.0.0","homepage":"https://bupkis.zip","keywords":["bupkis","chai","codemod","migration","assertions"],"repository":{"directory":"packages/from-chai","type":"git","url":"git+https://github.com/boneskull/bupkis.git"},"description":"Migrate Chai assertions to bupkis","maintainers":[{"name":"boneskull","email":"boneskull@boneskull.com"}],"readme":"# @bupkis/from-chai\n\nMigrate Chai assertions to [bupkis](https://github.com/boneskull/bupkis) with a single command.\n\nSupports both **BDD style** (`expect/should`) and **TDD style** (`assert`) assertions.\n\n## Installation\n\n```bash\nnpx @bupkis/from-chai\n```\n\nOr install locally:\n\n```bash\nnpm install -D @bupkis/from-chai\n```\n\n## Usage\n\n### CLI\n\n```bash\n# Transform all test files in current directory\nnpx bupkis-from-chai\n\n# Transform specific patterns\nnpx bupkis-from-chai \"src/**/*.test.ts\" \"test/**/*.spec.ts\"\n\n# Dry run (see what would change without writing)\nnpx bupkis-from-chai --dry-run\n\n# Exclude patterns\nnpx bupkis-from-chai --exclude \"**/fixtures/**\"\n\n# Strict mode (fail on any unsupported assertion)\nnpx bupkis-from-chai --strict\n```\n\n### Programmatic API\n\n```typescript\nimport { transform, transformCode } from '@bupkis/from-chai';\n\n// Transform a code string\nconst { code, transformCount, warnings } = await transformCode(`\n  import { expect } from 'chai';\n  expect(foo).to.equal(bar);\n`);\n// Result: \"import { expect } from 'bupkis';\\nexpect(foo, 'to be', bar);\"\n\n// Transform files\nconst result = await transform({\n  include: ['**/*.test.ts'],\n  exclude: ['**/node_modules/**'],\n  mode: 'best-effort',\n  write: true,\n});\n```\n\n## Transformations\n\n### BDD Style (expect)\n\n| Chai                              | bupkis                                           |\n| --------------------------------- | ------------------------------------------------ |\n| `expect(x).to.equal(y)`           | `expect(x, 'to be', y)`                          |\n| `expect(x).to.deep.equal(y)`      | `expect(x, 'to deep equal', y)`                  |\n| `expect(x).to.be.true`            | `expect(x, 'to be true')`                        |\n| `expect(x).to.be.false`           | `expect(x, 'to be false')`                       |\n| `expect(x).to.be.null`            | `expect(x, 'to be null')`                        |\n| `expect(x).to.be.undefined`       | `expect(x, 'to be undefined')`                   |\n| `expect(x).to.be.ok`              | `expect(x, 'to be truthy')`                      |\n| `expect(x).to.exist`              | `expect(x, 'to be defined')`                     |\n| `expect(x).to.be.a('string')`     | `expect(x, 'to be a', 'string')`                 |\n| `expect(x).to.be.instanceof(Y)`   | `expect(x, 'to be an instance of', Y)`           |\n| `expect(x).to.have.property('y')` | `expect(x, 'to have property', 'y')`             |\n| `expect(x).to.have.length(3)`     | `expect(x, 'to have length', 3)`                 |\n| `expect(x).to.contain(y)`         | `expect(x, 'to contain', y)`                     |\n| `expect(x).to.match(/foo/)`       | `expect(x, 'to match', /foo/)`                   |\n| `expect(x).to.be.above(5)`        | `expect(x, 'to be greater than', 5)`             |\n| `expect(x).to.be.below(10)`       | `expect(x, 'to be less than', 10)`               |\n| `expect(x).to.be.at.least(5)`     | `expect(x, 'to be greater than or equal to', 5)` |\n| `expect(x).to.be.at.most(10)`     | `expect(x, 'to be less than or equal to', 10)`   |\n| `expect(fn).to.throw()`           | `expect(fn, 'to throw')`                         |\n| `expect(fn).to.throw(Error)`      | `expect(fn, 'to throw', Error)`                  |\n| `expect(x).to.be.empty`           | `expect(x, 'to be empty')`                       |\n\nNegation is supported:\n\n| Chai                        | bupkis                      |\n| --------------------------- | --------------------------- |\n| `expect(x).to.not.equal(y)` | `expect(x, 'not to be', y)` |\n| `expect(x).not.to.equal(y)` | `expect(x, 'not to be', y)` |\n\n### TDD Style (assert)\n\n| Chai                         | bupkis                                 |\n| ---------------------------- | -------------------------------------- |\n| `assert.equal(x, y)`         | `expect(x, 'to be', y)`                |\n| `assert.strictEqual(x, y)`   | `expect(x, 'to be', y)`                |\n| `assert.deepEqual(x, y)`     | `expect(x, 'to deep equal', y)`        |\n| `assert.isTrue(x)`           | `expect(x, 'to be true')`              |\n| `assert.isFalse(x)`          | `expect(x, 'to be false')`             |\n| `assert.isNull(x)`           | `expect(x, 'to be null')`              |\n| `assert.isUndefined(x)`      | `expect(x, 'to be undefined')`         |\n| `assert.isOk(x)`             | `expect(x, 'to be truthy')`            |\n| `assert.isArray(x)`          | `expect(x, 'to be a', 'array')`        |\n| `assert.isString(x)`         | `expect(x, 'to be a', 'string')`       |\n| `assert.typeOf(x, 'string')` | `expect(x, 'to be a', 'string')`       |\n| `assert.instanceOf(x, Y)`    | `expect(x, 'to be an instance of', Y)` |\n| `assert.property(x, 'y')`    | `expect(x, 'to have property', 'y')`   |\n| `assert.lengthOf(x, 3)`      | `expect(x, 'to have length', 3)`       |\n| `assert.include(x, y)`       | `expect(x, 'to contain', y)`           |\n| `assert.match(x, /foo/)`     | `expect(x, 'to match', /foo/)`         |\n| `assert.isAbove(x, 5)`       | `expect(x, 'to be greater than', 5)`   |\n| `assert.isBelow(x, 10)`      | `expect(x, 'to be less than', 10)`     |\n| `assert.throws(fn)`          | `expect(fn, 'to throw')`               |\n| `assert.isEmpty(x)`          | `expect(x, 'to be empty')`             |\n\nNegated assertions (`assert.notEqual`, `assert.isNotTrue`, etc.) are also supported.\n\n### Chai Plugins\n\nThe following plugins are supported:\n\n**chai-as-promised**:\n\n| Chai                               | bupkis                                 |\n| ---------------------------------- | -------------------------------------- |\n| `expect(p).to.eventually.equal(y)` | `expect(p, 'to be fulfilled with', y)` |\n| `expect(p).to.be.fulfilled`        | `expect(p, 'to be fulfilled')`         |\n| `expect(p).to.be.rejected`         | `expect(p, 'to be rejected')`          |\n| `expect(p).to.be.rejectedWith(E)`  | `expect(p, 'to be rejected with', E)`  |\n\n**chai-string**:\n\n| Chai                          | bupkis                            |\n| ----------------------------- | --------------------------------- |\n| `expect(s).to.startWith('x')` | `expect(s, 'to start with', 'x')` |\n| `expect(s).to.endWith('x')`   | `expect(s, 'to end with', 'x')`   |\n\n**chai-subset**:\n\n| Chai                            | bupkis                       |\n| ------------------------------- | ---------------------------- |\n| `expect(x).to.containSubset(y)` | `expect(x, 'to satisfy', y)` |\n\nPlugin imports and `chai.use()` calls are automatically removed.\n\n## Import Handling\n\nThe transformer automatically:\n\n- Replaces `import { expect } from 'chai'` with `import { expect } from 'bupkis'`\n- Removes `import { assert } from 'chai'` (TDD assertions become `expect()` calls)\n- Removes all `chai-*` plugin imports\n- Removes all `chai.use()` calls\n- Warns about unrecognized plugins passed to `chai.use()`\n\n## Options\n\n| Option            | Description                                                        |\n| ----------------- | ------------------------------------------------------------------ |\n| `--dry-run`       | Show what would change without writing files                       |\n| `--strict`        | Fail on any unsupported assertion                                  |\n| `--best-effort`   | Transform what we can, add TODO comments for unsupported (default) |\n| `--exclude`, `-e` | Patterns to exclude (default: `**/node_modules/**`)                |\n\n## Handling Unsupported Assertions\n\nIn `best-effort` mode (default), unsupported assertions are preserved with a TODO comment:\n\n```typescript\n// TODO: Manual migration needed - unsupported matcher 'someObscureMatcher'\nexpect(x).to.someObscureMatcher(y);\n```\n\nSearch for `\"TODO: Manual migration needed\"` in your codebase after running the transform to find items requiring manual review.\n\n## License\n\n[Blue Oak Model License 1.0.0](https://blueoakcouncil.org/license/1.0.0)\n","readmeFilename":"README.md"}