stitchdb 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # StitchDB
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ npm install stitchdb
7
+ ```
8
+
9
+ ## Setup
10
+
11
+ ```ts
12
+ import { createClient } from 'stitchdb'
13
+
14
+ const db = createClient({
15
+ apiKey: process.env.STITCHDB_API_KEY,
16
+ })
17
+ ```
18
+
19
+ ## Query
20
+
21
+ ```ts
22
+ // Raw SQL with parameters
23
+ const { results } = await db.query('SELECT * FROM users WHERE active = ?', [1])
24
+
25
+ // Shorthands
26
+ await db.insert('users', { name: 'Alice', email: 'alice@example.com' })
27
+ await db.update('users', { active: false }, 'id = ?', [5])
28
+ await db.remove('users', 'id = ?', [5])
29
+ const user = await db.find('users', 1)
30
+ const users = await db.select('users', 'active = ?', [1], { orderBy: 'created_at DESC', limit: 20 })
31
+
32
+ // DDL
33
+ await db.run('CREATE TABLE IF NOT EXISTS posts (id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT)')
34
+
35
+ // Batch (atomic)
36
+ await db.batch([
37
+ { sql: 'INSERT INTO users (name) VALUES (?)', params: ['Alice'] },
38
+ { sql: 'INSERT INTO users (name) VALUES (?)', params: ['Bob'] },
39
+ ])
40
+ ```
41
+
42
+ Works with Node.js, Bun, Deno, Next.js, Nuxt, SvelteKit, Remix, Astro, and any runtime that supports `fetch`.
@@ -0,0 +1,67 @@
1
+ interface StitchDBConfig {
2
+ url?: string;
3
+ apiKey: string;
4
+ }
5
+ interface QueryResult<T = Record<string, unknown>> {
6
+ results: T[];
7
+ meta: {
8
+ rows_read: number;
9
+ rows_written: number;
10
+ last_row_id?: number | null;
11
+ duration_ms: number;
12
+ cached?: boolean;
13
+ };
14
+ }
15
+ interface BatchResult {
16
+ results: Record<string, unknown>[][];
17
+ meta: {
18
+ rows_read: number;
19
+ rows_written: number;
20
+ duration_ms: number;
21
+ queries_count: number;
22
+ };
23
+ }
24
+ interface ExecResult {
25
+ meta: {
26
+ rows_read: number;
27
+ rows_written: number;
28
+ duration_ms: number;
29
+ };
30
+ }
31
+ declare class StitchDBError extends Error {
32
+ status: number;
33
+ constructor(message: string, status: number);
34
+ }
35
+ declare class StitchDB {
36
+ private url;
37
+ private apiKey;
38
+ constructor(config: StitchDBConfig);
39
+ /** Run a SQL query with parameterized bindings. */
40
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
41
+ /** Run multiple queries atomically in a single batch. */
42
+ batch(queries: {
43
+ sql: string;
44
+ params?: unknown[];
45
+ }[]): Promise<BatchResult>;
46
+ /** Run a DDL statement (CREATE TABLE, ALTER TABLE, DROP TABLE, etc.) */
47
+ run(sql: string): Promise<ExecResult>;
48
+ /** Insert a row. */
49
+ insert(table: string, data: Record<string, unknown>): Promise<QueryResult>;
50
+ /** Update rows matching a WHERE clause. */
51
+ update(table: string, data: Record<string, unknown>, where: string, whereParams?: unknown[]): Promise<QueryResult>;
52
+ /** Delete rows matching a WHERE clause. */
53
+ remove(table: string, where: string, whereParams?: unknown[]): Promise<QueryResult>;
54
+ /** Find one row by ID. */
55
+ find<T = Record<string, unknown>>(table: string, id: unknown, idColumn?: string): Promise<T | null>;
56
+ /** Select rows with optional WHERE, ORDER BY, LIMIT, OFFSET. */
57
+ select<T = Record<string, unknown>>(table: string, where?: string, params?: unknown[], opts?: {
58
+ orderBy?: string;
59
+ limit?: number;
60
+ offset?: number;
61
+ }): Promise<T[]>;
62
+ private post;
63
+ }
64
+ /** Create a StitchDB client. */
65
+ declare function createClient(config: StitchDBConfig): StitchDB;
66
+
67
+ export { type BatchResult, type ExecResult, type QueryResult, StitchDB, type StitchDBConfig, StitchDBError, createClient, StitchDB as default };
@@ -0,0 +1,67 @@
1
+ interface StitchDBConfig {
2
+ url?: string;
3
+ apiKey: string;
4
+ }
5
+ interface QueryResult<T = Record<string, unknown>> {
6
+ results: T[];
7
+ meta: {
8
+ rows_read: number;
9
+ rows_written: number;
10
+ last_row_id?: number | null;
11
+ duration_ms: number;
12
+ cached?: boolean;
13
+ };
14
+ }
15
+ interface BatchResult {
16
+ results: Record<string, unknown>[][];
17
+ meta: {
18
+ rows_read: number;
19
+ rows_written: number;
20
+ duration_ms: number;
21
+ queries_count: number;
22
+ };
23
+ }
24
+ interface ExecResult {
25
+ meta: {
26
+ rows_read: number;
27
+ rows_written: number;
28
+ duration_ms: number;
29
+ };
30
+ }
31
+ declare class StitchDBError extends Error {
32
+ status: number;
33
+ constructor(message: string, status: number);
34
+ }
35
+ declare class StitchDB {
36
+ private url;
37
+ private apiKey;
38
+ constructor(config: StitchDBConfig);
39
+ /** Run a SQL query with parameterized bindings. */
40
+ query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<QueryResult<T>>;
41
+ /** Run multiple queries atomically in a single batch. */
42
+ batch(queries: {
43
+ sql: string;
44
+ params?: unknown[];
45
+ }[]): Promise<BatchResult>;
46
+ /** Run a DDL statement (CREATE TABLE, ALTER TABLE, DROP TABLE, etc.) */
47
+ run(sql: string): Promise<ExecResult>;
48
+ /** Insert a row. */
49
+ insert(table: string, data: Record<string, unknown>): Promise<QueryResult>;
50
+ /** Update rows matching a WHERE clause. */
51
+ update(table: string, data: Record<string, unknown>, where: string, whereParams?: unknown[]): Promise<QueryResult>;
52
+ /** Delete rows matching a WHERE clause. */
53
+ remove(table: string, where: string, whereParams?: unknown[]): Promise<QueryResult>;
54
+ /** Find one row by ID. */
55
+ find<T = Record<string, unknown>>(table: string, id: unknown, idColumn?: string): Promise<T | null>;
56
+ /** Select rows with optional WHERE, ORDER BY, LIMIT, OFFSET. */
57
+ select<T = Record<string, unknown>>(table: string, where?: string, params?: unknown[], opts?: {
58
+ orderBy?: string;
59
+ limit?: number;
60
+ offset?: number;
61
+ }): Promise<T[]>;
62
+ private post;
63
+ }
64
+ /** Create a StitchDB client. */
65
+ declare function createClient(config: StitchDBConfig): StitchDB;
66
+
67
+ export { type BatchResult, type ExecResult, type QueryResult, StitchDB, type StitchDBConfig, StitchDBError, createClient, StitchDB as default };
package/dist/index.js ADDED
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ StitchDB: () => StitchDB,
24
+ StitchDBError: () => StitchDBError,
25
+ createClient: () => createClient,
26
+ default: () => index_default
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+ var StitchDBError = class extends Error {
30
+ constructor(message, status) {
31
+ super(message);
32
+ this.name = "StitchDBError";
33
+ this.status = status;
34
+ }
35
+ };
36
+ var StitchDB = class {
37
+ constructor(config) {
38
+ this.url = (config.url || "https://db.stitchdb.com").replace(/\/$/, "");
39
+ this.apiKey = config.apiKey;
40
+ }
41
+ /** Run a SQL query with parameterized bindings. */
42
+ async query(sql, params) {
43
+ return this.post("/v1/query", { sql, params });
44
+ }
45
+ /** Run multiple queries atomically in a single batch. */
46
+ async batch(queries) {
47
+ return this.post("/v1/batch", { queries });
48
+ }
49
+ /** Run a DDL statement (CREATE TABLE, ALTER TABLE, DROP TABLE, etc.) */
50
+ async run(sql) {
51
+ return this.post("/v1/exec", { sql });
52
+ }
53
+ /** Insert a row. */
54
+ async insert(table, data) {
55
+ const cols = Object.keys(data);
56
+ const sql = `INSERT INTO "${table}" (${cols.map((c) => `"${c}"`).join(", ")}) VALUES (${cols.map(() => "?").join(", ")})`;
57
+ return this.query(sql, Object.values(data));
58
+ }
59
+ /** Update rows matching a WHERE clause. */
60
+ async update(table, data, where, whereParams) {
61
+ const set = Object.keys(data).map((c) => `"${c}" = ?`).join(", ");
62
+ return this.query(`UPDATE "${table}" SET ${set} WHERE ${where}`, [...Object.values(data), ...whereParams || []]);
63
+ }
64
+ /** Delete rows matching a WHERE clause. */
65
+ async remove(table, where, whereParams) {
66
+ return this.query(`DELETE FROM "${table}" WHERE ${where}`, whereParams);
67
+ }
68
+ /** Find one row by ID. */
69
+ async find(table, id, idColumn = "id") {
70
+ const { results } = await this.query(`SELECT * FROM "${table}" WHERE "${idColumn}" = ? LIMIT 1`, [id]);
71
+ return results[0] || null;
72
+ }
73
+ /** Select rows with optional WHERE, ORDER BY, LIMIT, OFFSET. */
74
+ async select(table, where, params, opts) {
75
+ let sql = `SELECT * FROM "${table}"`;
76
+ if (where) sql += ` WHERE ${where}`;
77
+ if (opts?.orderBy) sql += ` ORDER BY ${opts.orderBy}`;
78
+ if (opts?.limit) sql += ` LIMIT ${opts.limit}`;
79
+ if (opts?.offset) sql += ` OFFSET ${opts.offset}`;
80
+ const { results } = await this.query(sql, params);
81
+ return results;
82
+ }
83
+ async post(path, body) {
84
+ const res = await fetch(`${this.url}${path}`, {
85
+ method: "POST",
86
+ headers: {
87
+ "Authorization": `Bearer ${this.apiKey}`,
88
+ "Content-Type": "application/json"
89
+ },
90
+ body: JSON.stringify(body)
91
+ });
92
+ const data = await res.json();
93
+ if (!res.ok || data.error) {
94
+ throw new StitchDBError(data.error || `Request failed: ${res.status}`, res.status);
95
+ }
96
+ return data;
97
+ }
98
+ };
99
+ function createClient(config) {
100
+ return new StitchDB(config);
101
+ }
102
+ var index_default = StitchDB;
103
+ // Annotate the CommonJS export names for ESM import in node:
104
+ 0 && (module.exports = {
105
+ StitchDB,
106
+ StitchDBError,
107
+ createClient
108
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,81 @@
1
+ // src/index.ts
2
+ var StitchDBError = class extends Error {
3
+ constructor(message, status) {
4
+ super(message);
5
+ this.name = "StitchDBError";
6
+ this.status = status;
7
+ }
8
+ };
9
+ var StitchDB = class {
10
+ constructor(config) {
11
+ this.url = (config.url || "https://db.stitchdb.com").replace(/\/$/, "");
12
+ this.apiKey = config.apiKey;
13
+ }
14
+ /** Run a SQL query with parameterized bindings. */
15
+ async query(sql, params) {
16
+ return this.post("/v1/query", { sql, params });
17
+ }
18
+ /** Run multiple queries atomically in a single batch. */
19
+ async batch(queries) {
20
+ return this.post("/v1/batch", { queries });
21
+ }
22
+ /** Run a DDL statement (CREATE TABLE, ALTER TABLE, DROP TABLE, etc.) */
23
+ async run(sql) {
24
+ return this.post("/v1/exec", { sql });
25
+ }
26
+ /** Insert a row. */
27
+ async insert(table, data) {
28
+ const cols = Object.keys(data);
29
+ const sql = `INSERT INTO "${table}" (${cols.map((c) => `"${c}"`).join(", ")}) VALUES (${cols.map(() => "?").join(", ")})`;
30
+ return this.query(sql, Object.values(data));
31
+ }
32
+ /** Update rows matching a WHERE clause. */
33
+ async update(table, data, where, whereParams) {
34
+ const set = Object.keys(data).map((c) => `"${c}" = ?`).join(", ");
35
+ return this.query(`UPDATE "${table}" SET ${set} WHERE ${where}`, [...Object.values(data), ...whereParams || []]);
36
+ }
37
+ /** Delete rows matching a WHERE clause. */
38
+ async remove(table, where, whereParams) {
39
+ return this.query(`DELETE FROM "${table}" WHERE ${where}`, whereParams);
40
+ }
41
+ /** Find one row by ID. */
42
+ async find(table, id, idColumn = "id") {
43
+ const { results } = await this.query(`SELECT * FROM "${table}" WHERE "${idColumn}" = ? LIMIT 1`, [id]);
44
+ return results[0] || null;
45
+ }
46
+ /** Select rows with optional WHERE, ORDER BY, LIMIT, OFFSET. */
47
+ async select(table, where, params, opts) {
48
+ let sql = `SELECT * FROM "${table}"`;
49
+ if (where) sql += ` WHERE ${where}`;
50
+ if (opts?.orderBy) sql += ` ORDER BY ${opts.orderBy}`;
51
+ if (opts?.limit) sql += ` LIMIT ${opts.limit}`;
52
+ if (opts?.offset) sql += ` OFFSET ${opts.offset}`;
53
+ const { results } = await this.query(sql, params);
54
+ return results;
55
+ }
56
+ async post(path, body) {
57
+ const res = await fetch(`${this.url}${path}`, {
58
+ method: "POST",
59
+ headers: {
60
+ "Authorization": `Bearer ${this.apiKey}`,
61
+ "Content-Type": "application/json"
62
+ },
63
+ body: JSON.stringify(body)
64
+ });
65
+ const data = await res.json();
66
+ if (!res.ok || data.error) {
67
+ throw new StitchDBError(data.error || `Request failed: ${res.status}`, res.status);
68
+ }
69
+ return data;
70
+ }
71
+ };
72
+ function createClient(config) {
73
+ return new StitchDB(config);
74
+ }
75
+ var index_default = StitchDB;
76
+ export {
77
+ StitchDB,
78
+ StitchDBError,
79
+ createClient,
80
+ index_default as default
81
+ };
package/package.json ADDED
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "stitchdb",
3
+ "version": "1.0.0",
4
+ "description": "StitchDB client for JavaScript and TypeScript",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsup src/index.ts --format cjs,esm --dts",
20
+ "prepublishOnly": "npm run build"
21
+ },
22
+ "keywords": ["stitchdb", "database", "sql", "edge", "serverless"],
23
+ "license": "MIT",
24
+ "author": {
25
+ "name": "StitchDB",
26
+ "email": "support@stitchdb.com",
27
+ "url": "https://stitchdb.com"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/stitchdb/js.git"
32
+ },
33
+ "homepage": "https://stitchdb.com/docs",
34
+ "devDependencies": {
35
+ "tsup": "^8.0.0",
36
+ "typescript": "^5.0.0"
37
+ }
38
+ }