Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
export type {
BunDriverOptions,
MigrationRunnerOptions,
SqliteAdapterOptions,
WasmDriverOptions,
} from "./schemas.js";
export {
BunDriverOptionsSchema,
MigrationRunnerOptionsSchema,
SqliteAdapterOptionsSchema,
WasmDriverOptionsSchema,
} from "./schemas.js";

View File

@@ -0,0 +1,71 @@
# schemas
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Zod schemas and inferred TypeScript types for all `@suaveplan/db-sqlite` configuration objects. Centralising validation in one module ensures that every entry point — `createBunDriver`, `createWasmDriver`, `SqliteAdapter`, `MigrationRunner` — applies the same rules with the same error messages, rather than duplicating ad-hoc checks across modules.
All schemas use `.strict()` where applicable so extra unknown properties are rejected at runtime, preventing silent misconfiguration from typos in option objects.
## Features
- `BunDriverOptionsSchema` — validates `filename` (optional string) and `readonly` (optional boolean, default `false`)
- `WasmDriverOptionsSchema` — validates `filename` (optional string) for OPFS persistence
- `SqliteAdapterOptionsSchema` — alias for `BunDriverOptionsSchema`; adapter and driver share the same shape
- `MigrationRunnerOptionsSchema` — validates `migrationsFolder` (default `"./migrations"`), `migrationsTable` (default `"__sqlite_migrations"`), `dryRun` (default `false`)
- Inferred TypeScript types exported for all four schemas
## Usage: Basic Example
```ts
import { BunDriverOptionsSchema } from "@suaveplan/db-sqlite/schemas";
const opts = BunDriverOptionsSchema.parse({ filename: ":memory:" });
// opts.readonly === false (default applied)
```
## Usage: Advanced Example
```ts
import { MigrationRunnerOptionsSchema } from "@suaveplan/db-sqlite/schemas";
const opts = MigrationRunnerOptionsSchema.parse({
migrationsFolder: "./db/migrations",
dryRun: true,
});
// opts.migrationsTable === "__sqlite_migrations" (default applied)
// opts.dryRun === true
```
## API Reference
### `BunDriverOptionsSchema`
`z.object({ filename?: string, readonly?: boolean }).strict()` — `readonly` defaults to `false`.
### `WasmDriverOptionsSchema`
`z.object({ filename?: string }).strict()` — no defaults; absence means in-memory.
### `SqliteAdapterOptionsSchema`
Alias for `BunDriverOptionsSchema`. Both driver and adapter accept the same option shape.
### `MigrationRunnerOptionsSchema`
`z.object({ migrationsFolder?: string, migrationsTable?: string, dryRun?: boolean }).strict()`.
Defaults: `migrationsFolder = "./migrations"`, `migrationsTable = "__sqlite_migrations"`, `dryRun = false`.
### Type aliases
- `BunDriverOptions = z.infer<typeof BunDriverOptionsSchema>`
- `WasmDriverOptions = z.infer<typeof WasmDriverOptionsSchema>`
- `SqliteAdapterOptions = BunDriverOptions`
- `MigrationRunnerOptions = z.infer<typeof MigrationRunnerOptionsSchema>`
## Implementation Notes
`SqliteAdapterOptions` is deliberately an alias for `BunDriverOptions` rather than a separate schema so that passing an `SqliteAdapterOptions` object to `createBunDriver` is type-safe without casting. If the WASM adapter ever gains `readonly` support the alias can be split without a breaking change to the option names callers already use.

View File

@@ -0,0 +1,86 @@
import { describe, expect, it } from "@suaveplan/testing/runner";
import {
BunDriverOptionsSchema,
MigrationRunnerOptionsSchema,
SqliteAdapterOptionsSchema,
WasmDriverOptionsSchema,
} from "./schemas.js";
describe("BunDriverOptionsSchema", () => {
it("accepts empty object and applies defaults", { timeout: 5000 }, () => {
const result = BunDriverOptionsSchema.parse({});
expect(result.readonly).toBe(false);
expect(result.filename).toBeUndefined();
});
it("accepts filename and readonly", { timeout: 5000 }, () => {
const result = BunDriverOptionsSchema.parse({
filename: ":memory:",
readonly: true,
});
expect(result.filename).toBe(":memory:");
expect(result.readonly).toBe(true);
});
it("rejects unknown keys (strict)", { timeout: 5000 }, () => {
expect(() =>
BunDriverOptionsSchema.parse({ filename: ":memory:", extra: true })
).toThrow();
});
});
describe("WasmDriverOptionsSchema", () => {
it("accepts empty object", { timeout: 5000 }, () => {
const result = WasmDriverOptionsSchema.parse({});
expect(result.filename).toBeUndefined();
});
it("accepts filename", { timeout: 5000 }, () => {
const result = WasmDriverOptionsSchema.parse({ filename: "app.db" });
expect(result.filename).toBe("app.db");
});
it("rejects unknown keys (strict)", { timeout: 5000 }, () => {
expect(() =>
WasmDriverOptionsSchema.parse({ filename: "a", extra: 1 })
).toThrow();
});
});
describe("SqliteAdapterOptionsSchema", () => {
it("is structurally identical to BunDriverOptionsSchema", {
timeout: 5000,
}, () => {
const result = SqliteAdapterOptionsSchema.parse({
filename: "test.db",
});
expect(result.filename).toBe("test.db");
expect(result.readonly).toBe(false);
});
});
describe("MigrationRunnerOptionsSchema", () => {
it("applies all defaults", { timeout: 5000 }, () => {
const result = MigrationRunnerOptionsSchema.parse({});
expect(result.migrationsFolder).toBe("./migrations");
expect(result.migrationsTable).toBe("__sqlite_migrations");
expect(result.dryRun).toBe(false);
});
it("accepts custom values", { timeout: 5000 }, () => {
const result = MigrationRunnerOptionsSchema.parse({
migrationsFolder: "./db/migrations",
migrationsTable: "custom_migrations",
dryRun: true,
});
expect(result.migrationsFolder).toBe("./db/migrations");
expect(result.migrationsTable).toBe("custom_migrations");
expect(result.dryRun).toBe(true);
});
it("rejects unknown keys (strict)", { timeout: 5000 }, () => {
expect(() =>
MigrationRunnerOptionsSchema.parse({ unknown: "value" })
).toThrow();
});
});

View File

@@ -0,0 +1,34 @@
import z from "zod";
export const BunDriverOptionsSchema = z
.object({
filename: z.string().optional(),
readonly: z.boolean().optional().default(false),
})
.strict();
export type BunDriverOptions = z.infer<typeof BunDriverOptionsSchema>;
export const WasmDriverOptionsSchema = z
.object({
filename: z.string().optional(),
})
.strict();
export type WasmDriverOptions = z.infer<typeof WasmDriverOptionsSchema>;
export const SqliteAdapterOptionsSchema = BunDriverOptionsSchema;
export type SqliteAdapterOptions = BunDriverOptions;
export const MigrationRunnerOptionsSchema = z
.object({
migrationsFolder: z.string().optional().default("./migrations"),
migrationsTable: z.string().optional().default("__sqlite_migrations"),
dryRun: z.boolean().optional().default(false),
})
.strict();
export type MigrationRunnerOptions = z.infer<
typeof MigrationRunnerOptionsSchema
>;