{"id":23893288,"url":"https://github.com/CodeDynasty-dev/SQLiteBruv","last_synced_at":"2025-09-10T00:32:35.127Z","repository":{"id":258794151,"uuid":"875274170","full_name":"Uiedbook/SQLiteBruv","owner":"Uiedbook","description":"💃 A type-safe, secure SQLite query builder with D1/Turso support with built-in migrations and security features.","archived":false,"fork":false,"pushed_at":"2024-12-29T01:28:56.000Z","size":2495,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-29T02:23:54.698Z","etag":null,"topics":["cloudflare-d1","d1","database","sql","sqlite","sqlite3","sqlitebruv","turso","turso-db"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Uiedbook.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2024-10-19T14:50:00.000Z","updated_at":"2024-12-29T01:28:59.000Z","dependencies_parsed_at":"2024-12-07T19:22:08.900Z","dependency_job_id":"1c317299-090a-4fe4-8a6b-ef8a2b34608b","html_url":"https://github.com/Uiedbook/SQLiteBruv","commit_stats":null,"previous_names":["fridaycandour/sqlitebruv","uiedbook/sqlitebruv"],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uiedbook%2FSQLiteBruv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uiedbook%2FSQLiteBruv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uiedbook%2FSQLiteBruv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Uiedbook%2FSQLiteBruv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Uiedbook","download_url":"https://codeload.github.com/Uiedbook/SQLiteBruv/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232473987,"owners_count":18529087,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["cloudflare-d1","d1","database","sql","sqlite","sqlite3","sqlitebruv","turso","turso-db"],"created_at":"2025-01-04T14:17:20.912Z","updated_at":"2025-09-10T00:32:29.735Z","avatar_url":"https://github.com/Uiedbook.png","language":"TypeScript","readme":"# SQLiteBruv Query Builder\n\nA Tiny Type-Safe, Secure SQLite Query Builder with D1/Turso support with built-in migrations and security features.\n\n[![npm version](https://badge.fury.io/js/sqlitebruv.svg)](https://www.npmjs.com/package/sqlitebruv)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm](https://img.shields.io/npm/dm/sqlitebruv.svg)](https://www.npmjs.com/package/sqlitebruv) [![TypeScript](https://img.shields.io/badge/Typescript-%3E%3D4.0-blue.svg)](https://www.typescriptlang.org/)\n\n## Features\n\n- 🛡️ Security-first design with SQL injection prevention\n- 📡 JSON interface for http no sql queries\n- 🔄 Automatic schema migrations\n- 🏃‍♂️ In-memory caching\n- 🌐 Cloudflare D1 \u0026 Turso support\n- 📝 Type-safe queries\n- 🔍 Query validation \u0026 sanitization\n- 📊 Schema management\n- 🌠 Bunjs Support 100%\n\n\u003ccenter\u003e\n\u003cimg src=\"https://github.com/FridayCandour/SQLiteBruv/blob/main/icon.png?raw=true\" style=\"width: 320px; margin: auto;\" /\u003e\n\u003c/center\u003e\n## Installation\n\n```bash\nnpm install sqlite-bruv\n```\n\n## 🚀 Updates\n\n- **Light weight**: Zero dependency and small size.\n- **Bun-Ready**: built for Bunjs\n- **Platform Support**:\n  - Cloudflare D1\n  - Turso\n  - Local SQLite\n  - raw query output\n- **Security**: SQL injection prevention, query validation, parameter sanitization\n- **Type Safety**: Full TypeScript support with inferred types\n- **Migrations**: Automatic schema diff detection and migration generation\n- **Caching**: Built-in memory caching with invalidation\n- **Relations**: Support for one-to-one and one-to-many relationships\n\n## 📦 Installation\n\n```bash\n# bun\nbun add sqlite-bruv\n\n# npm\nnpm install sqlite-bruv\n```\n\n## Usage/Examples\n\n```typescript\nimport { SqliteBruv, Schema } from \"sqlite-bruv\";\n\n// Define your schema\nconst UserSchema = new Schema\u003c{\n  name: string;\n  email: string;\n  role: \"admin\" | \"user\";\n  createdAt: Date;\n}\u003e({\n  name: \"users\",\n  columns: {\n    name: { type: \"TEXT\", required: true },\n    email: { type: \"TEXT\", unique: true },\n    role: { type: \"TEXT\", default: () =\u003e \"user\" },\n    createdAt: { type: \"DATETIME\", default: () =\u003e new Date() },\n  },\n});\n\nconst PostSchema = new Schema({\n  name: \"posts\",\n  columns: {\n    title: { type: \"TEXT\", required: true },\n    content: { type: \"TEXT\" },\n    userId: {\n      type: \"TEXT\",\n      target: \"users\",\n      relationType: \"ONE\",\n    },\n  },\n});\n\nconst CommentSchema = new Schema({\n  name: \"comments\",\n  columns: {\n    content: { type: \"TEXT\", required: true },\n    postId: {\n      type: \"TEXT\",\n      target: \"posts\",\n      relationType: \"MANY\",\n    },\n  },\n});\n\n// Initialize database\n\nconst db = new SqliteBruv({\n  schema: [UserSchema],\n});\n```\n\nPlatform-Specific Setup\nCloudflare D1\n\n```typescript\nconst db = new SqliteBruv({\n  D1: {\n    accountId: process.env.CF_ACCOUNT_ID,\n    databaseId: process.env.D1_DATABASE_ID,\n    apiKey: process.env.CF_API_KEY,\n  },\n  schema: [UserSchema, PostSchema, CommentSchema],\n});\n```\n\nTurso;\n\n```typescript\nconst db = new SqliteBruv({\n  turso: {\n    url: process.env.TURSO_URL,\n    authToken: process.env.TURSO_AUTH_TOKEN,\n  },\n  schema: [UserSchema, PostSchema, CommentSchema],\n});\n```\n\n## Example usage:\n\n```typescript\nconst queryBuilder = new SqliteBruv({\n  schema: [UserSchema, PostSchema, CommentSchema],\n});\n\n// Insert\nawait queryBuilder\n  .from(\"users\")\n  .insert({ name: \"John Doe\", email: \"john@example.com\" })\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// Update\nawait queryBuilder\n  .from(\"users\")\n  .where(\"id = ?\", 1)\n  .update({ name: \"Jane Doe\" })\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// Search\nawait queryBuilder\n  .from(\"users\")\n  .where(\"id = ?\", 1)\n  .andWhere(\"name LIKE ?\", `%oh%`)\n  .get()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// Delete\nawait queryBuilder\n  .from(\"users\")\n  .where(\"id = ?\", 1)\n  .delete()\n  .then((changes) =\u003e {\n    console.log({ changes });\n  });\n\n// Get all users\nqueryBuilder\n  .from(\"users\")\n  .get()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// Get one user\nawait queryBuilder\n  .from(\"users\")\n  .where(\"id = ?\", 1)\n  .getOne()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// Select specific columns\nawait queryBuilder\n  .from(\"users\")\n  .select(\"id\", \"name\")\n  .get()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// Where conditions\nawait queryBuilder\n  .from(\"users\")\n  .where(\"age \u003e ?\", 18)\n  .get()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// AndWhere conditions\nawait queryBuilder\n  .from(\"users\")\n  .where(\"age \u003e ?\", 18)\n  .andWhere(\"country = ?\", \"USA\")\n  .get()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// OrWhere conditions\nawait queryBuilder\n  .from(\"users\")\n  .where(\"age \u003e ?\", 18)\n  .orWhere(\"country = ?\", \"Canada\")\n  .get()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// Limit and Offset\nawait queryBuilder\n  .from(\"users\")\n  .limit(10)\n  .offset(5)\n  .get()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\n// OrderBy\nawait queryBuilder\n  .from(\"users\")\n  .orderBy(\"name\", \"ASC\")\n  .get()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n\nawait queryBuilder\n  .from(\"users\")\n  .orderBy(\"name\", \"ASC\")\n  .get()\n  .then((changes) =\u003e {\n    // console.log({ changes });\n  });\n```\n\n## 💡 Advanced Usage\n\nComplex Queries\n\n```ts\n// Relations and joins\nconst posts = await db\n  .from(\"posts\")\n  .select(\"posts.*\", \"users.name as author\")\n  .where(\"posts.published = ?\", true)\n  .andWhere(\"posts.views \u003e ?\", 1000)\n  .orderBy(\"posts.createdAt\", \"DESC\")\n  .limit(10)\n  .get();\n\n// Raw queries with safety\nawait db.raw(\"SELECT * FROM users WHERE id = ?\", [userId]);\n\n// Cache usage\nconst users = await db\n  .from(\"users\")\n  .select(\"*\")\n  .where(\"active = ?\", true)\n  .cacheAs(\"active-users\")\n  .get();\n\n// Cache invalidation\ndb.invalidateCache(\"active-users\");\n```\n\n## Using from over the network via JSON interface\n\n```typescript\n//  JSON interface structure\ninterface Query {\n  from: string;\n  select?: string[];\n  where?: {\n    condition: string;\n    params: any[];\n  }[];\n  andWhere?: {\n    condition: string;\n    params: any[];\n  }[];\n  orWhere?: {\n    condition: string;\n    params: any[];\n  }[];\n  orderBy?: {\n    column: string;\n    direction: \"ASC\" | \"DESC\";\n  };\n  limit?: number;\n  offset?: number;\n  cacheAs?: string;\n  invalidateCache?: string;\n  action?: \"get\" | \"getOne\" | \"insert\" | \"update\" | \"delete\" | \"count\";\n  /**\n  ### For insert and update only\n  */\n  data?: any;\n}\n// Example usage in an Express.js route\nimport express from \"express\";\nconst app = express();\napp.use(express.json());\n\napp.post(\"/execute-query\", async (req, res) =\u003e {\n  try {\n    const queryInput = req.body;\n    // do your role authentication here,\n    // use query.from to know the table being accessed\n    const result = await qb.executeJsonQuery(queryInput);\n    res.json(result);\n  } catch (error) {\n    res.status(500).json({ error: error.message });\n  }\n});\n```\n\n## 🔄 Migrations\n\nMigrations are automatically generated when schema changes are detected:\n\n```sql\n-- Generated in ./Bruv-migrations/timestamp_add_user_role.sql:\n-- Up\nALTER TABLE users ADD COLUMN role TEXT DEFAULT 'user';\n\n-- Down\nALTER TABLE users DROP COLUMN role;\n```\n\n### Setting up your schema\n\nThis if your DB is new and your are not using any orm, just call toString\nand query your db with the queryBuilder.raw() method.\n\nNote: raw is not secured, it can be used to apply migrations too.\nbe careful what you do with queryBuilder.raw().\n\n```ts\nconsole.log(user.toString());\nconst raw = await qb.raw(user.toString());\nconsole.log({ raw });\n```\n\n## 🛡️ Security Features\n\nThe query builder implements several security measures to prevent SQL injection and malicious queries:\n\n- Parameter validation (max 100 params)\n- SQL injection prevention\n- Query timeout limits\n- Rate limiting\n- String length validation\n- Dangerous pattern detection\n- Allowed parameter types: string, number, boolean, null\n\n#### Condition Validation\n\n- Whitelisted operators: `=, \u003e, \u003c, \u003e=, \u003c=, LIKE, IN, BETWEEN, IS NULL, IS NOT NULL`\n- Blocked dangerous patterns: `; DROP, DELETE, UPDATE, INSERT, ALTER, EXEC, UNION`\n- Parameterized queries enforced\n\n### Security Examples\n\n```typescript\n// ✅ Safe queries\ndb.from(\"users\")\n  .where(\"email LIKE ?\", \"%@example.com\") // ✅ Safe\n  .andWhere(\"role = ?\", \"admin\") // ✅ Safe\n  .get();\ndb.from(\"users\")\n  .where(\"age \u003e ?\", 18)\n  .andWhere(\"status = ?\", \"active\")\n  .orWhere(\"role IN (?)\", [\"admin\", \"mod\"]);\n\n// ❌ These will throw security errors:\ndb.where(\"1=1; DROP TABLE users;\"); // Dangerous pattern\ndb.where(\"col = (SELECT ...)\"); // Complex subqueries blocked\ndb.where(\"name = ?\", \"a\".repeat(1001)); // String too long\n```\n\n## 🎮 Features\n\n**Cloudflare D1**\n\n- D1 API integration\n\n**Turso**\n\n- HTTP API support\n\n**📊 Performance**\n\n- Prepared statements\n- Connection pooling\n- Built-in Query caching\n\n**🚔 Security**\n\n- Block dangerous patterns\n- Block Complex subqueries\n- Block very long string parameters\n\n**🤝 Contributing**\n\n1. Fork the repository\n2. Create feature branch (git checkout -b feature/amazing)\n3. Commit changes (git commit -am 'Add amazing feature')\n4. Push branch (git push origin feature/amazing)\n5. Open a Pull Request\n\n## 📝 License\n\n[MIT License](https://choosealicense.com/licenses/mit/) - see LICENSE file\n\n### 🆘 Support\n\nContributions are always welcome! creates issues and pull requests.\nDocumentation\nGitHub Issues\nDiscord Community\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCodeDynasty-dev%2FSQLiteBruv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FCodeDynasty-dev%2FSQLiteBruv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FCodeDynasty-dev%2FSQLiteBruv/lists"}