{"_id":"@9aia/castor","_rev":"5-a2dc172484b1eb011cf60aef79b19714","name":"@9aia/castor","dist-tags":{"latest":"0.2.3"},"versions":{"0.1.0":{"name":"@9aia/castor","version":"0.1.0","keywords":["cli","database","d1","cloudflare","developer-tool","open-source"],"author":{"name":"Luis Emidio"},"license":"MIT","_id":"@9aia/castor@0.1.0","maintainers":[{"name":"luisfuturist","email":"luisfuturist@gmail.com"}],"homepage":"https://github.com/9aia/castor#readme","bugs":{"url":"https://github.com/9aia/castor/issues"},"bin":{"castor":"dist/castor-bin.es.js"},"dist":{"shasum":"0029bdffd3ed99c79bad6c6cac7daf46519f4b6a","tarball":"https://registry.npmjs.org/@9aia/castor/-/castor-0.1.0.tgz","fileCount":10,"integrity":"sha512-gCKkTjhOGqwdFkGj+uX1nMv124To4oEiPo1iWIvLHX7f4Z6Yh7HfjVkS1roV3R9+VHTuDQwmJcjl/n8OFPslHw==","signatures":[{"sig":"MEUCIQCNVPY45PfbJLC++5bYw21R4CJMjZJCJjk3rZOFdBY5qgIgfqzfsokZf5Vp1g67ptm7B1Q8NG9MFB8weCjpdnThUVM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":110383},"main":"dist/castor-cli.es.js","type":"module","exports":{".":{"types":"./dist/castor-sdk.d.ts","import":"./dist/castor-sdk.es.js"}},"gitHead":"6b1492f6d296818e309aeab892245e5e057dfcc0","private":false,"scripts":{"link":"pnpm build && pnpm link --global","lint":"eslint","pack":"pnpm build && pnpm pack","build":"tsc && vite build","unlink":"pnpm unlink --global","release":"release-it","lint:fix":"eslint --fix"},"_npmUser":{"name":"luisfuturist","email":"luisfuturist@gmail.com"},"repository":{"url":"git+https://github.com/9aia/castor.git","type":"git"},"_npmVersion":"10.9.2","description":"CLI tool to connect, explore, and query SQL databases using JavaScript-defined blocks.","directories":{},"_nodeVersion":"23.8.0","dependencies":{"tsx":"^4.19.4","zod":"^3.24.4","enquirer":"^2.4.1","wrangler":"^4.14.1","fast-glob":"^3.3.3","drizzle-orm":"^0.43.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.3.5","eslint":"^9.26.0","release-it":"^19.0.2","typescript":"^5.8.3","@types/node":"^22.15.11","vite-plugin-dts":"^4.5.3","@antfu/eslint-config":"^4.12.1"},"_npmOperationalInternal":{"tmp":"tmp/castor_0.1.0_1746510057797_0.3986192902520016","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@9aia/castor","version":"0.2.0","keywords":["cli","database","d1","cloudflare","developer-tool","open-source"],"author":{"name":"Luis Emidio"},"license":"MIT","_id":"@9aia/castor@0.2.0","maintainers":[{"name":"luisfuturist","email":"luisfuturist@gmail.com"}],"homepage":"https://github.com/9aia/castor#readme","bugs":{"url":"https://github.com/9aia/castor/issues"},"bin":{"castor":"dist/castor-bin.es.js"},"dist":{"shasum":"e94b406bea8913ec38d3eceefc53eaea2df5f1ca","tarball":"https://registry.npmjs.org/@9aia/castor/-/castor-0.2.0.tgz","fileCount":10,"integrity":"sha512-wH55Ey5OKWhkm+12e5G+kE0WnAQui5mgknaArb7JxetasGSOTEqgUzpG+6zAzfJiDlYFclkNAeN/bMzrg9K65w==","signatures":[{"sig":"MEUCIEWXkgd+rjxsFPbJxCi0OxTEKsgdur5qFFzJQNU83mvOAiEAu9f9lkJ8LHEkRgawp0BJX3JjZWx7EPmeE8aH5c6Mv8U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":114661},"main":"dist/castor-cli.es.js","type":"module","exports":{".":{"types":"./dist/castor-sdk.d.ts","import":"./dist/castor-sdk.es.js"}},"gitHead":"fe9b458f6a9e3caf26f5cc3e26d539549e04d8a6","private":false,"scripts":{"link":"pnpm build && pnpm link --global","lint":"eslint","pack":"pnpm build && pnpm pack","build":"tsc && vite build","unlink":"pnpm unlink --global","release":"release-it","lint:fix":"eslint --fix"},"_npmUser":{"name":"luisfuturist","email":"luisfuturist@gmail.com"},"repository":{"url":"git+https://github.com/9aia/castor.git","type":"git"},"_npmVersion":"10.9.2","description":"CLI tool to connect, explore, and query SQL databases using JavaScript-defined blocks.","directories":{},"_nodeVersion":"23.8.0","dependencies":{"tsx":"^4.19.4","zod":"^3.24.4","enquirer":"^2.4.1","wrangler":"^4.14.1","fast-glob":"^3.3.3","drizzle-orm":"^0.43.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.3.5","eslint":"^9.26.0","release-it":"^19.0.2","typescript":"^5.8.3","@types/node":"^22.15.11","vite-plugin-dts":"^4.5.3","@antfu/eslint-config":"^4.12.1"},"_npmOperationalInternal":{"tmp":"tmp/castor_0.2.0_1747340651069_0.8618432754952818","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@9aia/castor","version":"0.2.1","keywords":["cli","database","d1","cloudflare","developer-tool","open-source"],"author":{"name":"Luis Emidio"},"license":"MIT","_id":"@9aia/castor@0.2.1","maintainers":[{"name":"luisfuturist","email":"luisfuturist@gmail.com"}],"homepage":"https://github.com/9aia/castor#readme","bugs":{"url":"https://github.com/9aia/castor/issues"},"bin":{"castor":"dist/castor-bin.es.js"},"dist":{"shasum":"6fde2e2dafa1a26010634fb08438646a8bc2feac","tarball":"https://registry.npmjs.org/@9aia/castor/-/castor-0.2.1.tgz","fileCount":10,"integrity":"sha512-o14FyIpTzNn8WNBlKzA9s0f0vmDPaYlRTzO5CorPG3mAWq64YC6HpSW9nD9TC5HlH9GgQ07Nxwg9hq5f0OWwFQ==","signatures":[{"sig":"MEUCIAsIO4aArVJpe0f8CrwUUZ8W/Ysg3a4aDRvkXKRV1TD8AiEA8sDxbk2p/NgZnv3eGoLKSUp7rYxpquehRzh0ee8Chfc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":23016},"main":"dist/castor-cli.es.js","type":"module","exports":{".":{"types":"./dist/castor-sdk.d.ts","import":"./dist/castor-sdk.es.js"}},"gitHead":"822baf81264c082399f2b7ce130052160593c4a8","private":false,"scripts":{"link":"pnpm build && pnpm link --global","lint":"eslint","pack":"pnpm build && pnpm pack","build":"tsc && vite build","unlink":"pnpm unlink --global","release":"release-it","lint:fix":"eslint --fix"},"_npmUser":{"name":"luisfuturist","email":"luisfuturist@gmail.com"},"repository":{"url":"git+https://github.com/9aia/castor.git","type":"git"},"_npmVersion":"10.9.2","description":"CLI tool to connect, explore, and query SQL databases using JavaScript-defined blocks.","directories":{},"_nodeVersion":"23.8.0","dependencies":{"tsx":"^4.19.4","zod":"^3.24.4","enquirer":"^2.4.1","wrangler":"^4.14.1","fast-glob":"^3.3.3","drizzle-orm":"^0.43.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.3.5","eslint":"^9.26.0","release-it":"^19.0.2","typescript":"^5.8.3","@types/node":"^22.15.11","vite-plugin-dts":"^4.5.3","@antfu/eslint-config":"^4.12.1"},"_npmOperationalInternal":{"tmp":"tmp/castor_0.2.1_1747343996978_0.08757886566786599","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@9aia/castor","version":"0.2.2","keywords":["cli","database","d1","cloudflare","developer-tool","open-source"],"author":{"name":"Luis Emidio"},"license":"MIT","_id":"@9aia/castor@0.2.2","maintainers":[{"name":"luisfuturist","email":"luisfuturist@gmail.com"}],"homepage":"https://github.com/9aia/castor#readme","bugs":{"url":"https://github.com/9aia/castor/issues"},"bin":{"castor":"dist/castor-bin.es.js"},"dist":{"shasum":"1ea2fff946bd3a6c21fd163be560e4b72fbf5974","tarball":"https://registry.npmjs.org/@9aia/castor/-/castor-0.2.2.tgz","fileCount":10,"integrity":"sha512-ZQeG6FrW5b4RS0Zrq/RwG8in/aViJdsTAgEEP8DdP5yS750euk6LNzQhnH/SxUQGElYP9MUfArRo81lRhHcyhQ==","signatures":[{"sig":"MEUCIBRisKSBRD9S12e4cEnrdziqTlb/A0VfBBYpoatmctdLAiEA8DD81BcSYxCtQV0bNe8WtS0fibI7vwFbHR/gxj/WtVE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24065},"main":"dist/castor-cli.es.js","type":"module","exports":{".":{"types":"./dist/castor-sdk.d.ts","import":"./dist/castor-sdk.es.js"}},"gitHead":"3e2ffb2fd977512dedbf267a74e9b4d4f27ec439","private":false,"scripts":{"link":"pnpm build && pnpm link --global","lint":"eslint","pack":"pnpm build && pnpm pack","build":"tsc && vite build","unlink":"pnpm unlink --global","release":"release-it","lint:fix":"eslint --fix"},"_npmUser":{"name":"luisfuturist","email":"luisfuturist@gmail.com"},"repository":{"url":"git+https://github.com/9aia/castor.git","type":"git"},"_npmVersion":"10.9.2","description":"CLI tool to connect, explore, and query SQL databases using JavaScript-defined blocks.","directories":{},"_nodeVersion":"23.8.0","dependencies":{"tsx":"^4.19.4","zod":"^3.24.4","enquirer":"^2.4.1","wrangler":"^4.14.1","fast-glob":"^3.3.3","drizzle-orm":"^0.43.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^6.3.5","eslint":"^9.26.0","release-it":"^19.0.2","typescript":"^5.8.3","@types/node":"^22.15.11","vite-plugin-dts":"^4.5.3","@antfu/eslint-config":"^4.12.1"},"_npmOperationalInternal":{"tmp":"tmp/castor_0.2.2_1747354258266_0.06724982097202448","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@9aia/castor","type":"module","version":"0.2.3","private":false,"publishConfig":{"access":"public"},"description":"CLI tool to connect, explore, and query SQL databases using JavaScript-defined blocks.","author":{"name":"Luis Emidio"},"license":"MIT","homepage":"https://github.com/9aia/castor#readme","repository":{"type":"git","url":"git+https://github.com/9aia/castor.git"},"bugs":{"url":"https://github.com/9aia/castor/issues"},"keywords":["cli","database","d1","cloudflare","developer-tool","open-source"],"exports":{".":{"types":"./dist/castor-sdk.d.ts","import":"./dist/castor-sdk.es.js"}},"main":"dist/castor-cli.es.js","bin":{"castor":"dist/castor-bin.es.js"},"scripts":{"build":"tsc && vite build","link":"pnpm build && pnpm link --global","unlink":"pnpm unlink --global","pack":"pnpm build && pnpm pack","lint":"eslint","lint:fix":"eslint --fix","release":"release-it"},"peerDependencies":{"drizzle-orm":"^0.43.1","enquirer":"^2.4.1","fast-glob":"^3.3.3","tsx":"^4.19.4","wrangler":"^4.14.1","zod":"^3.24.4"},"devDependencies":{"@antfu/eslint-config":"^4.12.1","@types/node":"^22.15.11","eslint":"^9.26.0","release-it":"^19.0.2","typescript":"^5.8.3","vite":"^6.3.5","vite-plugin-dts":"^4.5.3","zod":"^3.24.4"},"_id":"@9aia/castor@0.2.3","gitHead":"34a350ecb5851c654fef0620f3d37143a2ebf3e4","_nodeVersion":"23.8.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-SlWE1W0f/LhUv7ggaWCPEW5RGsZYwCTTPSlekHWC2SznBLNvYj2jkwh3owt86VwUItxXahpcYD3O+EE2n+ce1g==","shasum":"596a4162eebf098342b12b51d5122b98c84a9569","tarball":"https://registry.npmjs.org/@9aia/castor/-/castor-0.2.3.tgz","fileCount":10,"unpackedSize":24211,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBCXJO4N2yeZ5q/g0VaHo9e4Fa4qpP5iv/MTOSwv3JL/AiEA1z3DIBRz8Lq6NLF37d0VmZo2XgV2P7ZSavorVvg6XIc="}]},"_npmUser":{"name":"luisfuturist","email":"luisfuturist@gmail.com"},"directories":{},"maintainers":[{"name":"luisfuturist","email":"luisfuturist@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/castor_0.2.3_1747361891184_0.7763519373781456"},"_hasShrinkwrap":false}},"time":{"created":"2025-05-06T05:40:57.658Z","modified":"2025-05-16T02:18:11.616Z","0.1.0":"2025-05-06T05:40:57.992Z","0.2.0":"2025-05-15T20:24:11.303Z","0.2.1":"2025-05-15T21:19:57.157Z","0.2.2":"2025-05-16T00:10:58.486Z","0.2.3":"2025-05-16T02:18:11.381Z"},"bugs":{"url":"https://github.com/9aia/castor/issues"},"author":{"name":"Luis Emidio"},"license":"MIT","homepage":"https://github.com/9aia/castor#readme","keywords":["cli","database","d1","cloudflare","developer-tool","open-source"],"repository":{"type":"git","url":"git+https://github.com/9aia/castor.git"},"description":"CLI tool to connect, explore, and query SQL databases using JavaScript-defined blocks.","maintainers":[{"name":"luisfuturist","email":"luisfuturist@gmail.com"}],"readme":"# 🦫 Castor — Interactive CLI for Database Blocks\n\n**Castor** is a free, open-source, dev-focused database management tool written in Node.js with TypeScript designed for the command line. Think of it as a minimal, scriptable SQL client — built from the ground up for developers who live in the terminal.\n\nIt supports a wide range of databases — like MySQL, PostgreSQL and SQLite — but the current prototype focuses on [Cloudflare D1](https://developers.cloudflare.com/d1/) support.\n\n> [!WARNING]\n> ⚗️ Experimental — This project is in early stages and under active development. Expect rough edges, missing features, and possibly fast iteration.\n\n## Goals\n\n- 📜 Make database querying scriptable and trackable via source code\n- 🔒 Provide type-safe and schema-aware query \"blocks\" (powered by `zod` and `typescript`)\n- ⚡ Load automatically structured query \"blocks\" from `js`/`ts` files\n- 💬 Generate automatically and type-aware prompts in the terminal for input\n- 🗂️ Allow the developer to organize queries in folders, version them, track changes with `git`\n- 💾 Provide first-class support for `Cloudflare D1` (but with support for providing custom adapters)\n\n## Scope\n\nCastor enables you to:\n\n* 🔌 Connect to your database directly from the terminal\n* ✍️ Provide query *block* definition utilities in `.ts`/`.js` files\n* 🧠 Run blocks interactively in the terminal, with input prompts\n\n**Out of scope:**\n\n* ❌ GUI or Web UI\n* ❌ Query editors or ER diagram tools\n* ❌ Export/import utilities\n* ❌ Block versioning or saving queries outside source code (use `git` for that)\n* ❌ Agnostic data validation (use `zod` for now)\n\n## Features\n\n* ✅ Block discovery from file system\n* ✅ Typed CLI prompts using `zod` schemas\n* ✅ `Cloudflare D1` + `drizzle-orm` integration\n* ⚠️ Danger mode prompts\n* 📄 Custom configs\n* 📝 Run with saved or new input\n\n## Installing\n\nTo install Castor, use NPM:\n\n```bash\nnpm install -D @9aia/castor\n```\n\nOr with other package managers like PNPM or Yarn!\n\n> [!WARNING]\n> `zod` and `drizzle` are peer dependencies and must be up to date with the version used by this package.\n\n### Adding the database type to Castor\n\nCastor needs to know the type of your database. You can do this by adding a `types.d.ts` file to your project:\n\n```ts\n// types.d.ts\nimport { Database } from '~/lib/db'\n\ndeclare module '@9aia/castor' {\n  interface Register {\n    database: Database\n  }\n}\n\nexport {}\n```\n\n### Adding the Script to your `package.json` (Recommended)\n\nAdd the `db:client` script to your `package.json`:\n\n```json\n// package.json\n{\n  \"scripts\": {\n    \"db:client\": \"castor --config path/to/config.ts\"\n  }\n}\n```\n\n## Documentation\n\n### Configuring\n\nYou can define your own config file using `defineConfig()`:\n\n```ts\nimport type { Database } from '~/'\n// castor.config.ts\nimport { defineConfig } from '@9aia/castor'\nexport default defineConfig({\n  rootDir: './db-client', // the directory Castor will explore\n  source: defaultSource => [...defaultSource, '!**.md'], // exclude MD files\n  drizzle: { // DrizzleOptions\n    logger: true,\n  },\n  dbProvider: 'd1',\n  d1: {\n    binding: 'DB',\n  },\n  wrangler: { // GetPlatformProxyOptions\n    persist: true,\n  },\n})\n```\n\nSupports:\n\n* `d1` binding from Wrangler\n* Custom `dbProvider` function\n* File filters using `fast-glob` patterns\n\n### Defining Sessions\n\nCreate files in `db-client/`, like `user.ts`, and export your query blocks there.\n\n### Defining Blocks\n\nBlocks are typed and named operations. They can query or mutate your database:\n\n```ts\n// ./db-client/user.ts\nimport { block } from '@9aia/castor'\nimport { eq } from 'drizzle-orm'\nimport { z } from 'zod'\nimport { users } from '~/db/schema'\n\nblock('List all users', {\n  query: db => db.select().from(users)\n})\n\nblock('Get user by id', {\n  schema: z.object({ id: z.string() }),\n  query: (db, input) => (\n    db.select().from(users).where(eq(users.id, input.id))\n  ),\n})\n\nblock('Delete all users', {\n  danger: true, // will ask for confirmation\n  query: (db, input) => (\n    db.delete(users)\n  ),\n})\n```\n\nBlock config signature:\n\n```ts\ninterface BlockConfig<S extends Schema | undefined = undefined> {\n  // Mark block as destructive (will ask for confirmation)\n  danger?: boolean\n  // Zod schema for validating input\n  schema?: S\n  // Async function to return or mutate data\n  query?: (db: ProvidedDatabase, input: InferBlockFnInput<S>) => Promise<any> | any\n  // Async function for operations with side-effects\n  run?: (db: ProvidedDatabase, input: InferBlockFnInput<S>) => Promise<any> | any\n}\n```\n\n### Running Castor\n\nJust run it:\n\n```bash\ncastor\n\n# or with config\ncastor --config path/to/config.ts\n\n# or with a script (recommended)\npnpm db:client\n```\n\nYou'll see a menu to select and run blocks.\n\nSample output:\n\n```bash\n🦫  Castor DB Client\n\nConfig file not found at `castor.config.ts`. Using default config.\n6 blocks loaded. 2 namespaces loaded. 🔗\n\n✔ Select a namespace to open · user\nOpening namespace: user (5 blocks)\n\n✔ Select a block to run · List all users\nPage 1 of 30\nShowing rows 1-5 of 150\n┌─────────┬───────────────┬──────────┐\n│ (index) │ id            │ name     │\n├─────────┼───────────────┼──────────┤\n│ 0       │ 'dj2bh08yf2s' │ 'User 1' │\n│ 1       │ 'xizda46r5m8' │ 'User 2' │\n│ 2       │ 'il6qpw38j6'  │ 'User 3' │\n│ 3       │ 'l3uoalp72o8' │ 'User 4' │\n│ 4       │ 'eprfnwls63g' │ 'User 5' │\n└─────────┴───────────────┴──────────┘\n? Navigation: …\n▸ [>]\n  [30]\n  Go to specific page\n  Query menu\n```\n\n### How It Works\n\nCastor scans your codebase for \"blocks\" — reusable JS/TS query definitions — and lets you execute them through a guided CLI interface.\n\nEach block can:\n\n* Define a `schema` (input form, type-validated)\n* Contain a `query()` and/or `run()` function using `drizzle-orm`\n* Be marked as `danger` (destructive and will ask for confirmation)\n\nIt connects to a database (D1 or custom), prompts the user for any necessary input, runs the logic and prints the result.\n\n## FAQ\n\n**Q: What databases are supported?**\nA: Currently Cloudflare D1 (via `wrangler`). You can plug in any db via a `dbProvider()`.\n\n**Q: Can I organize blocks in folders?**\nA: Yep. Just drop them anywhere inside `rootDir`, unless excluded via glob.\n\n**Q: What happens when I run a block?**\nA: You're prompted for inputs (based on its schema), then Castor runs the logic and prints a table.\n\n## Contribute\n\nGot feedback, ideas, or just want to help shape Castor? Open an issue or send a PR. Contributions are welcome at any stage.\n\nCheck out the [contributing guide](./CONTRIBUTING.md) for details.\n\n## Roadmap\n\nIf you're curious about Castor's upcoming features or brainstorming sessions, take a look at the comments in the source code.\n","readmeFilename":"README.md"}