diff --git a/README.md b/README.md index ac0a1a8..356c514 100644 --- a/README.md +++ b/README.md @@ -85,13 +85,13 @@ bun add github:moduletrace/bun-mariadb Connection settings are read from the environment (not the config file): -| Variable | Required | Description | -| --------------------------------- | -------- | ------------------------------------ | -| `BUN_MARIADB_SERVER_HOST` | Yes | MariaDB host | -| `BUN_MARIADB_SERVER_USERNAME` | Yes | Database user | -| `BUN_MARIADB_SERVER_PASSWORD` | Yes | Database password | -| `BUN_MARIADB_SERVER_PORT` | No | Port (server default if omitted) | -| `BUN_MARIADB_SERVER_SSL_KEY_PATH` | No | Optional SSL key path (legacy/env) | +| Variable | Required | Description | +| --------------------------------- | -------- | ---------------------------------- | +| `BUN_MARIADB_SERVER_HOST` | Yes | MariaDB host | +| `BUN_MARIADB_SERVER_USERNAME` | Yes | Database user | +| `BUN_MARIADB_SERVER_PASSWORD` | Yes | Database password | +| `BUN_MARIADB_SERVER_PORT` | No | Port (server default if omitted) | +| `BUN_MARIADB_SERVER_SSL_KEY_PATH` | No | Optional SSL key path (legacy/env) | Example `.env`: @@ -135,9 +135,22 @@ const schema: BUN_MARIADB_DatabaseSchemaType = { { tableName: "users", fields: [ - { fieldName: "first_name", dataType: "VARCHAR", integerLength: 255 }, - { fieldName: "last_name", dataType: "VARCHAR", integerLength: 255 }, - { fieldName: "email", dataType: "VARCHAR", integerLength: 255, unique: true }, + { + fieldName: "first_name", + dataType: "VARCHAR", + dataLength: 255, + }, + { + fieldName: "last_name", + dataType: "VARCHAR", + dataLength: 255, + }, + { + fieldName: "email", + dataType: "VARCHAR", + dataLength: 255, + unique: true, + }, { fieldName: "bio", dataType: "LONGTEXT", html: true }, ], }, @@ -187,19 +200,19 @@ await BunMariaDB.delete({ table: "users", targetId: 1 }); The config file must be named `bun-mariadb.config.ts` and placed at the project root. -| Field | Type | Required | Description | -| ------------------- | -------- | -------- | --------------------------------------------------------------------------- | -| `db_name` | `string` | Yes | MariaDB database name | -| `db_dir` | `string` | Yes | Directory for schema, types, and local artifacts (relative to project root) | -| `db_backup_dir` | `string` | No | Backup directory name, relative to `db_dir` (default: `.backups`) | -| `max_backups` | `number` | No | Max backup files to keep (default: `10`) | -| `max_exports` | `number` | No | Max export archives to keep (default: `10`) | -| `typedef_file_path` | `string` | No | Output path for generated TypeScript types (relative to project root) | -| `db_config` | `object` | No | Extra options passed to Bun's `SQL` MariaDB adapter | -| `charset` | `string` | No | Database charset (default: `utf8mb4`) | -| `connection_timeout`| `number` | No | Connection timeout in ms (default: `10000`) | -| `ssl_ca` | `string` | No | Path to SSL CA certificate (relative to project root) | -| `html_sanitize` | `object` | No | Extra HTML sanitizer allowlists (see [HTML Sanitization](#html-sanitization)) | +| Field | Type | Required | Description | +| -------------------- | -------- | -------- | ----------------------------------------------------------------------------- | +| `db_name` | `string` | Yes | MariaDB database name | +| `db_dir` | `string` | Yes | Directory for schema, types, and local artifacts (relative to project root) | +| `db_backup_dir` | `string` | No | Backup directory name, relative to `db_dir` (default: `.backups`) | +| `max_backups` | `number` | No | Max backup files to keep (default: `10`) | +| `max_exports` | `number` | No | Max export archives to keep (default: `10`) | +| `typedef_file_path` | `string` | No | Output path for generated TypeScript types (relative to project root) | +| `db_config` | `object` | No | Extra options passed to Bun's `SQL` MariaDB adapter | +| `charset` | `string` | No | Database charset (default: `utf8mb4`) | +| `connection_timeout` | `number` | No | Connection timeout in ms (default: `10000`) | +| `ssl_ca` | `string` | No | Path to SSL CA certificate (relative to project root) | +| `html_sanitize` | `object` | No | Extra HTML sanitizer allowlists (see [HTML Sanitization](#html-sanitization)) | Schema file path is always: `{db_dir}/schema.ts`. @@ -226,9 +239,9 @@ interface BUN_MARIADB_TableSchemaType { indexes?: BUN_MARIADB_IndexSchemaType[]; uniqueConstraints?: BUN_MARIADB_UniqueConstraintSchemaType[]; parentTableName?: string; // inherit / merge fields from another table - tableNameOld?: string; // rename: old name triggers ALTER TABLE RENAME + tableNameOld?: string; // rename: old name triggers ALTER TABLE RENAME collation?: "utf8mb4_bin" | "utf8mb4_unicode_520_ci"; - isVector?: boolean; // mark as vector-oriented table + isVector?: boolean; // mark as vector-oriented table } ``` @@ -238,12 +251,38 @@ interface BUN_MARIADB_TableSchemaType { type BUN_MARIADB_FieldSchemaType = { fieldName?: string; dataType: - | "CHAR" | "VARCHAR" | "TEXT" | "TINYTEXT" | "MEDIUMTEXT" | "LONGTEXT" - | "TINYINT" | "SMALLINT" | "MEDIUMINT" | "INT" | "BIGINT" - | "FLOAT" | "DOUBLE" | "DECIMAL" - | "BINARY" | "VARBINARY" | "BLOB" | "TINYBLOB" | "MEDIUMBLOB" | "LONGBLOB" - | "DATE" | "TIME" | "DATETIME" | "TIMESTAMP" | "YEAR" - | "BOOLEAN" | "UUID" | "JSON" | "INET6" | "ENUM" | "SET" | "VECTOR"; + | "CHAR" + | "VARCHAR" + | "TEXT" + | "TINYTEXT" + | "MEDIUMTEXT" + | "LONGTEXT" + | "TINYINT" + | "SMALLINT" + | "MEDIUMINT" + | "INT" + | "BIGINT" + | "FLOAT" + | "DOUBLE" + | "DECIMAL" + | "BINARY" + | "VARBINARY" + | "BLOB" + | "TINYBLOB" + | "MEDIUMBLOB" + | "LONGBLOB" + | "DATE" + | "TIME" + | "DATETIME" + | "TIMESTAMP" + | "YEAR" + | "BOOLEAN" + | "UUID" + | "JSON" + | "INET6" + | "ENUM" + | "SET" + | "VECTOR"; primaryKey?: boolean; autoIncrement?: boolean; notNullValue?: boolean; @@ -253,11 +292,11 @@ type BUN_MARIADB_FieldSchemaType = { onUpdate?: string; onUpdateLiteral?: string; foreignKey?: BUN_MARIADB_ForeignKeyType; - integerLength?: string | number; // e.g. VARCHAR length - decimals?: string | number; // DECIMAL scale - options?: (string | number)[]; // ENUM / SET values - isVector?: boolean; // native VECTOR column - vectorSize?: number; // dimensions (default: 1536) + dataLength?: string | number; // e.g. VARCHAR length + decimals?: string | number; // DECIMAL scale + options?: (string | number)[]; // ENUM / SET values + isVector?: boolean; // native VECTOR column + vectorSize?: number; // dimensions (default: 1536) // Content mode flags (editor metadata); only `html: true` affects runtime: html?: boolean; markdown?: boolean; @@ -368,10 +407,10 @@ Requires `mariadb` or `mysql` on `PATH`. bunx bun-mariadb export [options] ``` -| Option | Description | -| ------------------- | --------------------------------------------------------------------------- | -| `-o`, `--output` | Output archive path (`.tar.gz` or `.zip`). Defaults to `{db_dir}/.exports` | -| `-f`, `--format` | When `--output` is omitted: `tar.gz` (default) or `zip` | +| Option | Description | +| ---------------- | -------------------------------------------------------------------------- | +| `-o`, `--output` | Output archive path (`.tar.gz` or `.zip`). Defaults to `{db_dir}/.exports` | +| `-f`, `--format` | When `--output` is omitted: `tar.gz` (default) or `zip` | Creates a portable archive containing: @@ -400,11 +439,11 @@ Requires `mariadb-dump` or `mysqldump` on `PATH`. Zip output also requires `zip` bunx bun-mariadb import [file] [options] ``` -| Option | Description | -| ---------------- | --------------------------------------------------------------------------- | -| `[file]` | Path to a `.sql` dump or export archive (`.tar.gz` / `.tar` / `.zip`) | -| `--sql-only` | Archive only: restore SQL, do not overwrite `schema.ts` | -| `--schema-only` | Archive only: write `schema.ts`, do not restore SQL | +| Option | Description | +| --------------- | --------------------------------------------------------------------- | +| `[file]` | Path to a `.sql` dump or export archive (`.tar.gz` / `.tar` / `.zip`) | +| `--sql-only` | Archive only: restore SQL, do not overwrite `schema.ts` | +| `--schema-only` | Archive only: write `schema.ts`, do not restore SQL | Behavior: @@ -641,26 +680,26 @@ type ServerQueryParam = { ### Equality Operators -| Equality | SQL Equivalent | -| ----------------------- | ------------------------------------------------------ | -| `EQUAL` (default) | `=` | -| `NOT EQUAL` | `!=` | -| `LIKE` | `LIKE '%value%'` | -| `LIKE_RAW` | `LIKE 'value'` | -| `LIKE_LOWER` | `LOWER(field) LIKE '%value%'` | -| `NOT LIKE` | `NOT LIKE '%value%'` | -| `GREATER THAN` | `>` | -| `GREATER THAN OR EQUAL` | `>=` | -| `LESS THAN` | `<` | -| `LESS THAN OR EQUAL` | `<=` | -| `IN` | `IN (...)` | -| `NOT IN` | `NOT IN (...)` | -| `BETWEEN` | `BETWEEN a AND b` | -| `IS NULL` | `IS NULL` | -| `IS NOT NULL` | `IS NOT NULL` | -| `REGEXP` | `REGEXP` | -| `FULLTEXT` | full-text match | -| `MATCH` | vector / specialized match | +| Equality | SQL Equivalent | +| ----------------------- | ----------------------------- | +| `EQUAL` (default) | `=` | +| `NOT EQUAL` | `!=` | +| `LIKE` | `LIKE '%value%'` | +| `LIKE_RAW` | `LIKE 'value'` | +| `LIKE_LOWER` | `LOWER(field) LIKE '%value%'` | +| `NOT LIKE` | `NOT LIKE '%value%'` | +| `GREATER THAN` | `>` | +| `GREATER THAN OR EQUAL` | `>=` | +| `LESS THAN` | `<` | +| `LESS THAN OR EQUAL` | `<=` | +| `IN` | `IN (...)` | +| `NOT IN` | `NOT IN (...)` | +| `BETWEEN` | `BETWEEN a AND b` | +| `IS NULL` | `IS NULL` | +| `IS NOT NULL` | `IS NOT NULL` | +| `REGEXP` | `REGEXP` | +| `FULLTEXT` | full-text match | +| `MATCH` | vector / specialized match | ```ts const res = await BunMariaDB.select({ @@ -715,7 +754,7 @@ MariaDB native `VECTOR(n)` columns and `VECTOR INDEX` are supported (MariaDB 11. { fieldName: "title", dataType: "VARCHAR", - integerLength: 255, + dataLength: 255, }, ], indexes: [ @@ -825,11 +864,11 @@ const res = await BunMariaDB.select({ Every table automatically receives: -| Field | Type | Description | -| ------------ | ------------------------------- | -------------------------------------- | -| `id` | `BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL` | Unique row identifier | -| `created_at` | `BIGINT` | Unix timestamp set on insert | -| `updated_at` | `BIGINT` | Unix timestamp updated on every update | +| Field | Type | Description | +| ------------ | -------------------------------------------- | -------------------------------------- | +| `id` | `BIGINT PRIMARY KEY AUTO_INCREMENT NOT NULL` | Unique row identifier | +| `created_at` | `BIGINT` | Unix timestamp set on insert | +| `updated_at` | `BIGINT` | Unix timestamp updated on every update | You do not need to declare these in your schema. diff --git a/dist/lib/schema/map-data-types.js b/dist/lib/schema/map-data-types.js index 10e6af5..78513d3 100644 --- a/dist/lib/schema/map-data-types.js +++ b/dist/lib/schema/map-data-types.js @@ -7,9 +7,9 @@ export default function mapDataType(field) { } switch (dataType) { case "CHAR": - return `CHAR(${field.integerLength || 255})`; + return `CHAR(${field.dataLength || 255})`; case "VARCHAR": - return `VARCHAR(${field.integerLength || 255})`; + return `VARCHAR(${field.dataLength || 255})`; case "TEXT": return "TEXT"; case "TINYTEXT": @@ -19,36 +19,34 @@ export default function mapDataType(field) { case "LONGTEXT": return "LONGTEXT"; case "TINYINT": - return field.integerLength - ? `TINYINT(${field.integerLength})` + return field.dataLength + ? `TINYINT(${field.dataLength})` : "TINYINT"; case "SMALLINT": - return field.integerLength - ? `SMALLINT(${field.integerLength})` + return field.dataLength + ? `SMALLINT(${field.dataLength})` : "SMALLINT"; case "MEDIUMINT": - return field.integerLength - ? `MEDIUMINT(${field.integerLength})` + return field.dataLength + ? `MEDIUMINT(${field.dataLength})` : "MEDIUMINT"; case "INT": - return field.integerLength ? `INT(${field.integerLength})` : "INT"; + return field.dataLength ? `INT(${field.dataLength})` : "INT"; case "BIGINT": - return field.integerLength - ? `BIGINT(${field.integerLength})` - : "BIGINT"; + return field.dataLength ? `BIGINT(${field.dataLength})` : "BIGINT"; case "FLOAT": return "FLOAT"; case "DOUBLE": return "DOUBLE"; case "DECIMAL": - if (field.integerLength && field.decimals) { - return `DECIMAL(${field.integerLength}, ${field.decimals})`; + if (field.dataLength && field.decimals) { + return `DECIMAL(${field.dataLength}, ${field.decimals})`; } return "DECIMAL(10,2)"; case "BINARY": - return `BINARY(${field.integerLength || 1})`; + return `BINARY(${field.dataLength || 1})`; case "VARBINARY": - return `VARBINARY(${field.integerLength || 255})`; + return `VARBINARY(${field.dataLength || 255})`; case "BLOB": return "BLOB"; case "TINYBLOB": diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts index f89c3a4..d359b2a 100644 --- a/dist/types/index.d.ts +++ b/dist/types/index.d.ts @@ -213,7 +213,10 @@ export type BUN_MARIADB_FieldSchemaType = { onDelete?: string; onDeleteLiteral?: string; cssFiles?: string[]; - integerLength?: string | number; + /** + * Datatype length. Eg 255 for VARCHAR + */ + dataLength?: string | number; decimals?: string | number; code?: boolean; options?: (string | number)[]; diff --git a/package.json b/package.json index 9df18ba..b2c3795 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@moduletrace/bun-mariadb", - "version": "1.0.8", + "version": "1.0.9", "description": "Schema-driven MariaDB manager for Bun", "author": "Benjamin Toby", "license": "MIT", diff --git a/src/lib/schema/map-data-types.ts b/src/lib/schema/map-data-types.ts index 6f2265c..f4cabdb 100644 --- a/src/lib/schema/map-data-types.ts +++ b/src/lib/schema/map-data-types.ts @@ -13,9 +13,9 @@ export default function mapDataType( switch (dataType) { case "CHAR": - return `CHAR(${field.integerLength || 255})`; + return `CHAR(${field.dataLength || 255})`; case "VARCHAR": - return `VARCHAR(${field.integerLength || 255})`; + return `VARCHAR(${field.dataLength || 255})`; case "TEXT": return "TEXT"; case "TINYTEXT": @@ -25,36 +25,34 @@ export default function mapDataType( case "LONGTEXT": return "LONGTEXT"; case "TINYINT": - return field.integerLength - ? `TINYINT(${field.integerLength})` + return field.dataLength + ? `TINYINT(${field.dataLength})` : "TINYINT"; case "SMALLINT": - return field.integerLength - ? `SMALLINT(${field.integerLength})` + return field.dataLength + ? `SMALLINT(${field.dataLength})` : "SMALLINT"; case "MEDIUMINT": - return field.integerLength - ? `MEDIUMINT(${field.integerLength})` + return field.dataLength + ? `MEDIUMINT(${field.dataLength})` : "MEDIUMINT"; case "INT": - return field.integerLength ? `INT(${field.integerLength})` : "INT"; + return field.dataLength ? `INT(${field.dataLength})` : "INT"; case "BIGINT": - return field.integerLength - ? `BIGINT(${field.integerLength})` - : "BIGINT"; + return field.dataLength ? `BIGINT(${field.dataLength})` : "BIGINT"; case "FLOAT": return "FLOAT"; case "DOUBLE": return "DOUBLE"; case "DECIMAL": - if (field.integerLength && field.decimals) { - return `DECIMAL(${field.integerLength}, ${field.decimals})`; + if (field.dataLength && field.decimals) { + return `DECIMAL(${field.dataLength}, ${field.decimals})`; } return "DECIMAL(10,2)"; case "BINARY": - return `BINARY(${field.integerLength || 1})`; + return `BINARY(${field.dataLength || 1})`; case "VARBINARY": - return `VARBINARY(${field.integerLength || 255})`; + return `VARBINARY(${field.dataLength || 255})`; case "BLOB": return "BLOB"; case "TINYBLOB": diff --git a/src/types/index.ts b/src/types/index.ts index 90205ed..aaf7d68 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -202,7 +202,10 @@ export type BUN_MARIADB_FieldSchemaType = { onDelete?: string; onDeleteLiteral?: string; cssFiles?: string[]; - integerLength?: string | number; + /** + * Datatype length. Eg 255 for VARCHAR + */ + dataLength?: string | number; decimals?: string | number; code?: boolean; options?: (string | number)[];