@type32/tauri-sqlite-orm 0.3.0 → 0.4.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.
Files changed (41) hide show
  1. package/dist/aggregates.d.ts +12 -0
  2. package/dist/aggregates.js +9 -0
  3. package/dist/builders/delete.d.ts +23 -0
  4. package/dist/builders/delete.js +73 -0
  5. package/dist/builders/index.d.ts +7 -0
  6. package/dist/builders/index.js +7 -0
  7. package/dist/builders/insert.d.ts +31 -0
  8. package/dist/builders/insert.js +141 -0
  9. package/dist/builders/query-base.d.ts +1 -0
  10. package/dist/builders/query-base.js +1 -0
  11. package/dist/builders/relations.d.ts +11 -0
  12. package/dist/builders/relations.js +1 -0
  13. package/dist/builders/select.d.ts +54 -0
  14. package/dist/builders/select.js +427 -0
  15. package/dist/builders/update.d.ts +30 -0
  16. package/dist/builders/update.js +124 -0
  17. package/dist/builders/with.d.ts +17 -0
  18. package/dist/builders/with.js +34 -0
  19. package/dist/column-helpers.d.ts +22 -0
  20. package/dist/column-helpers.js +17 -0
  21. package/dist/dialect.d.ts +21 -0
  22. package/dist/dialect.js +67 -0
  23. package/dist/errors.d.ts +30 -0
  24. package/dist/errors.js +66 -0
  25. package/dist/index.d.mts +11 -6
  26. package/dist/index.d.ts +11 -6
  27. package/dist/operators.d.ts +30 -0
  28. package/dist/operators.js +84 -0
  29. package/dist/orm.d.ts +180 -0
  30. package/dist/orm.js +556 -0
  31. package/dist/relational-types.d.ts +87 -0
  32. package/dist/relational-types.js +1 -0
  33. package/dist/relations-v2.d.ts +77 -0
  34. package/dist/relations-v2.js +157 -0
  35. package/dist/serialization.d.ts +14 -0
  36. package/dist/serialization.js +135 -0
  37. package/dist/subquery.d.ts +5 -0
  38. package/dist/subquery.js +6 -0
  39. package/dist/types.d.ts +58 -0
  40. package/dist/types.js +1 -0
  41. package/package.json +2 -1
@@ -0,0 +1,21 @@
1
+ import { DatabaseIntrospector, Dialect, DialectAdapter, Driver, Kysely, QueryCompiler } from 'kysely';
2
+ /**
3
+ * Minimal interface that any SQLite-over-Tauri (or compatible mock) database must satisfy.
4
+ * Using this instead of the concrete `@tauri-apps/plugin-sql` type keeps the dialect
5
+ * portable and testable outside a Tauri runtime.
6
+ */
7
+ export interface DatabaseLike {
8
+ select<T>(query: string, params?: any[]): Promise<T>;
9
+ execute(query: string, params?: any[]): Promise<{
10
+ lastInsertId: number;
11
+ rowsAffected: number;
12
+ }>;
13
+ }
14
+ export declare class TauriDialect implements Dialect {
15
+ private readonly db;
16
+ constructor(db: DatabaseLike);
17
+ createAdapter(): DialectAdapter;
18
+ createDriver(): Driver;
19
+ createIntrospector(db: Kysely<any>): DatabaseIntrospector;
20
+ createQueryCompiler(): QueryCompiler;
21
+ }
@@ -0,0 +1,67 @@
1
+ import { CompiledQuery, SqliteAdapter, SqliteIntrospector, SqliteQueryCompiler, } from 'kysely';
2
+ class TauriConnection {
3
+ db;
4
+ constructor(db) {
5
+ this.db = db;
6
+ }
7
+ async executeQuery(compiledQuery) {
8
+ const { sql, parameters } = compiledQuery;
9
+ const params = parameters;
10
+ const trimmed = sql.trimStart();
11
+ const isSelect = /^\s*(SELECT|WITH|PRAGMA)/i.test(trimmed);
12
+ const hasReturning = /\bRETURNING\b/i.test(sql);
13
+ // INSERT/UPDATE/DELETE with RETURNING returns rows; use select() not execute()
14
+ if (isSelect || hasReturning) {
15
+ const rows = await this.db.select(sql, params);
16
+ return { rows };
17
+ }
18
+ const result = await this.db.execute(sql, params);
19
+ return {
20
+ rows: [],
21
+ insertId: BigInt(Math.round(result.lastInsertId ?? 0)),
22
+ numAffectedRows: BigInt(result.rowsAffected ?? 0),
23
+ };
24
+ }
25
+ async *streamQuery(_compiledQuery) {
26
+ throw new Error('Streaming queries are not supported by @tauri-apps/plugin-sql');
27
+ }
28
+ }
29
+ class TauriDriver {
30
+ db;
31
+ constructor(db) {
32
+ this.db = db;
33
+ }
34
+ async init() { }
35
+ async acquireConnection() {
36
+ return new TauriConnection(this.db);
37
+ }
38
+ async beginTransaction(conn, _settings) {
39
+ await conn.executeQuery(CompiledQuery.raw('BEGIN'));
40
+ }
41
+ async commitTransaction(conn) {
42
+ await conn.executeQuery(CompiledQuery.raw('COMMIT'));
43
+ }
44
+ async rollbackTransaction(conn) {
45
+ await conn.executeQuery(CompiledQuery.raw('ROLLBACK'));
46
+ }
47
+ async releaseConnection(_conn) { }
48
+ async destroy() { }
49
+ }
50
+ export class TauriDialect {
51
+ db;
52
+ constructor(db) {
53
+ this.db = db;
54
+ }
55
+ createAdapter() {
56
+ return new SqliteAdapter();
57
+ }
58
+ createDriver() {
59
+ return new TauriDriver(this.db);
60
+ }
61
+ createIntrospector(db) {
62
+ return new SqliteIntrospector(db);
63
+ }
64
+ createQueryCompiler() {
65
+ return new SqliteQueryCompiler();
66
+ }
67
+ }
@@ -0,0 +1,30 @@
1
+ export declare class TauriORMError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export declare class QueryBuilderError extends TauriORMError {
5
+ constructor(message: string);
6
+ }
7
+ export declare class MissingWhereClauseError extends QueryBuilderError {
8
+ constructor(operation: 'UPDATE' | 'DELETE', tableName: string);
9
+ }
10
+ export declare class ValidationError extends TauriORMError {
11
+ constructor(message: string);
12
+ }
13
+ export declare class InsertValidationError extends ValidationError {
14
+ constructor(message: string);
15
+ }
16
+ export declare class UpdateValidationError extends ValidationError {
17
+ constructor(message: string);
18
+ }
19
+ export declare class MigrationError extends TauriORMError {
20
+ constructor(message: string);
21
+ }
22
+ export declare class RelationError extends TauriORMError {
23
+ constructor(message: string);
24
+ }
25
+ export declare class ColumnNotFoundError extends TauriORMError {
26
+ constructor(columnName: string, tableName: string);
27
+ }
28
+ export declare class TableNotFoundError extends TauriORMError {
29
+ constructor(tableName: string);
30
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,66 @@
1
+ // Custom error classes for better error handling
2
+ export class TauriORMError extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = 'TauriORMError';
6
+ // Maintains proper stack trace for where our error was thrown (only available on V8)
7
+ if (Error.captureStackTrace) {
8
+ Error.captureStackTrace(this, this.constructor);
9
+ }
10
+ }
11
+ }
12
+ export class QueryBuilderError extends TauriORMError {
13
+ constructor(message) {
14
+ super(message);
15
+ this.name = 'QueryBuilderError';
16
+ }
17
+ }
18
+ export class MissingWhereClauseError extends QueryBuilderError {
19
+ constructor(operation, tableName) {
20
+ super(`${operation} operation on table "${tableName}" requires a WHERE clause to prevent accidental data loss. ` +
21
+ `Use .where() to specify conditions, or use .allowGlobalOperation() to explicitly allow operations without WHERE.`);
22
+ this.name = 'MissingWhereClauseError';
23
+ }
24
+ }
25
+ export class ValidationError extends TauriORMError {
26
+ constructor(message) {
27
+ super(message);
28
+ this.name = 'ValidationError';
29
+ }
30
+ }
31
+ export class InsertValidationError extends ValidationError {
32
+ constructor(message) {
33
+ super(message);
34
+ this.name = 'InsertValidationError';
35
+ }
36
+ }
37
+ export class UpdateValidationError extends ValidationError {
38
+ constructor(message) {
39
+ super(message);
40
+ this.name = 'UpdateValidationError';
41
+ }
42
+ }
43
+ export class MigrationError extends TauriORMError {
44
+ constructor(message) {
45
+ super(message);
46
+ this.name = 'MigrationError';
47
+ }
48
+ }
49
+ export class RelationError extends TauriORMError {
50
+ constructor(message) {
51
+ super(message);
52
+ this.name = 'RelationError';
53
+ }
54
+ }
55
+ export class ColumnNotFoundError extends TauriORMError {
56
+ constructor(columnName, tableName) {
57
+ super(`Column "${columnName}" does not exist on table "${tableName}"`);
58
+ this.name = 'ColumnNotFoundError';
59
+ }
60
+ }
61
+ export class TableNotFoundError extends TauriORMError {
62
+ constructor(tableName) {
63
+ super(`Table "${tableName}" not found in schema`);
64
+ this.name = 'TableNotFoundError';
65
+ }
66
+ }
package/dist/index.d.mts CHANGED
@@ -584,9 +584,14 @@ interface ManyRelationOptions {
584
584
  /** Predefined filter: (alias) => Condition. Applied to the joined relation table. */
585
585
  where?: (alias: string) => Condition;
586
586
  }
587
- /** Build the r object passed to defineRelations callback */
588
- declare function buildR<Tables extends Record<string, AnyTable>>(tables: Tables): {
589
- [K in keyof Tables]: Record<string, AnySQLiteColumn>;
587
+ /** Extract table keys from schema (values that extend AnyTable) */
588
+ type ExtractTableKeys<T> = {
589
+ [K in keyof T]: T[K] extends AnyTable ? K : never;
590
+ }[keyof T];
591
+ type ExtractTables<T extends Record<string, unknown>> = Pick<T, Extract<ExtractTableKeys<T>, keyof T>> extends infer R ? R extends Record<string, AnyTable> ? R : Record<string, AnyTable> : Record<string, AnyTable>;
592
+ /** Build the r object passed to defineRelations callback - all properties required to avoid TS2722 */
593
+ type BuildR<Tables extends Record<string, AnyTable>> = {
594
+ [K in keyof Tables]: Tables[K]['_']['columns'];
590
595
  } & {
591
596
  one: {
592
597
  [K in keyof Tables]: (opts: OneRelationOptions) => OneRelation<Tables[K]>;
@@ -595,7 +600,7 @@ declare function buildR<Tables extends Record<string, AnyTable>>(tables: Tables)
595
600
  [K in keyof Tables]: (opts?: ManyRelationOptions) => ManyRelation<Tables[K]>;
596
601
  };
597
602
  };
598
- type DefineRelationsCallback<Tables extends Record<string, AnyTable>> = (r: ReturnType<typeof buildR>) => {
603
+ type DefineRelationsCallback<Tables extends Record<string, AnyTable>> = (r: BuildR<Tables>) => {
599
604
  [K in keyof Tables]?: Record<string, OneRelation | ManyRelation>;
600
605
  };
601
606
  /**
@@ -618,7 +623,7 @@ type DefineRelationsCallback<Tables extends Record<string, AnyTable>> = (r: Retu
618
623
  * }))
619
624
  * ```
620
625
  */
621
- declare function defineRelations<TSchema extends Record<string, unknown>>(schema: TSchema, callback: DefineRelationsCallback<Record<string, AnyTable>>): Record<string, Record<string, OneRelation | ManyRelation>>;
626
+ declare function defineRelations<TSchema extends Record<string, unknown>>(schema: TSchema, callback: DefineRelationsCallback<ExtractTables<TSchema>>): Record<string, Record<string, OneRelation | ManyRelation>>;
622
627
  /**
623
628
  * Define a part of relations - merge multiple parts when passing to TauriORM.
624
629
  * Useful for splitting large schema definitions.
@@ -656,4 +661,4 @@ declare class TableNotFoundError extends TauriORMError {
656
661
  constructor(tableName: string);
657
662
  }
658
663
 
659
- export { type AnySQLiteColumn, type AnyTable, type ColumnDataType, ColumnNotFoundError, type ColumnOptions, type ColumnValueTypes, type Condition, type DatabaseLike, type DefineRelationsCallback, DeleteQueryBuilder, type ExtractColumnType, type InferInsertModel, type InferRelationalSelectModel, type InferRelationsMap, type InferSelectModel, InsertQueryBuilder, InsertValidationError, ManyRelation, type ManyRelationOptions, MigrationError, MissingWhereClauseError, type Mode, OneRelation, type OneRelationOptions, QueryBuilderError, Relation, type RelationConfig, RelationError, type RelationType, type RelationsBuilder, type SQLAggregate, type SQLCondition, type SQLSubquery, SQLiteColumn, SelectQueryBuilder, Table, TableNotFoundError, TauriDialect, TauriORM, TauriORMError, type ThroughRef, UpdateQueryBuilder, UpdateValidationError, ValidationError, WithQueryBuilder, alias, and, as, asc, avg, between, blob, boolean, contains, count, countDistinct, defineRelations, defineRelationsPart, desc, endsWith, enumType, eq, eqSubquery, exists, getTableColumns, groupConcat, gt, gtSubquery, gte, gteSubquery, ilike, inArray, integer, isNotNull, isNull, like, lt, ltSubquery, lte, lteSubquery, max, min, ne, neSubquery, not, notExists, notIn, numeric, or, real, relations, scalarSubquery, sqliteTable, startsWith, subquery, sum, text, through };
664
+ export { type AnySQLiteColumn, type AnyTable, type BuildR, type ColumnDataType, ColumnNotFoundError, type ColumnOptions, type ColumnValueTypes, type Condition, type DatabaseLike, type DefineRelationsCallback, DeleteQueryBuilder, type ExtractColumnType, type InferInsertModel, type InferRelationalSelectModel, type InferRelationsMap, type InferSelectModel, InsertQueryBuilder, InsertValidationError, ManyRelation, type ManyRelationOptions, MigrationError, MissingWhereClauseError, type Mode, OneRelation, type OneRelationOptions, QueryBuilderError, Relation, type RelationConfig, RelationError, type RelationType, type RelationsBuilder, type SQLAggregate, type SQLCondition, type SQLSubquery, SQLiteColumn, SelectQueryBuilder, Table, TableNotFoundError, TauriDialect, TauriORM, TauriORMError, type ThroughRef, UpdateQueryBuilder, UpdateValidationError, ValidationError, WithQueryBuilder, alias, and, as, asc, avg, between, blob, boolean, contains, count, countDistinct, defineRelations, defineRelationsPart, desc, endsWith, enumType, eq, eqSubquery, exists, getTableColumns, groupConcat, gt, gtSubquery, gte, gteSubquery, ilike, inArray, integer, isNotNull, isNull, like, lt, ltSubquery, lte, lteSubquery, max, min, ne, neSubquery, not, notExists, notIn, numeric, or, real, relations, scalarSubquery, sqliteTable, startsWith, subquery, sum, text, through };
package/dist/index.d.ts CHANGED
@@ -584,9 +584,14 @@ interface ManyRelationOptions {
584
584
  /** Predefined filter: (alias) => Condition. Applied to the joined relation table. */
585
585
  where?: (alias: string) => Condition;
586
586
  }
587
- /** Build the r object passed to defineRelations callback */
588
- declare function buildR<Tables extends Record<string, AnyTable>>(tables: Tables): {
589
- [K in keyof Tables]: Record<string, AnySQLiteColumn>;
587
+ /** Extract table keys from schema (values that extend AnyTable) */
588
+ type ExtractTableKeys<T> = {
589
+ [K in keyof T]: T[K] extends AnyTable ? K : never;
590
+ }[keyof T];
591
+ type ExtractTables<T extends Record<string, unknown>> = Pick<T, Extract<ExtractTableKeys<T>, keyof T>> extends infer R ? R extends Record<string, AnyTable> ? R : Record<string, AnyTable> : Record<string, AnyTable>;
592
+ /** Build the r object passed to defineRelations callback - all properties required to avoid TS2722 */
593
+ type BuildR<Tables extends Record<string, AnyTable>> = {
594
+ [K in keyof Tables]: Tables[K]['_']['columns'];
590
595
  } & {
591
596
  one: {
592
597
  [K in keyof Tables]: (opts: OneRelationOptions) => OneRelation<Tables[K]>;
@@ -595,7 +600,7 @@ declare function buildR<Tables extends Record<string, AnyTable>>(tables: Tables)
595
600
  [K in keyof Tables]: (opts?: ManyRelationOptions) => ManyRelation<Tables[K]>;
596
601
  };
597
602
  };
598
- type DefineRelationsCallback<Tables extends Record<string, AnyTable>> = (r: ReturnType<typeof buildR>) => {
603
+ type DefineRelationsCallback<Tables extends Record<string, AnyTable>> = (r: BuildR<Tables>) => {
599
604
  [K in keyof Tables]?: Record<string, OneRelation | ManyRelation>;
600
605
  };
601
606
  /**
@@ -618,7 +623,7 @@ type DefineRelationsCallback<Tables extends Record<string, AnyTable>> = (r: Retu
618
623
  * }))
619
624
  * ```
620
625
  */
621
- declare function defineRelations<TSchema extends Record<string, unknown>>(schema: TSchema, callback: DefineRelationsCallback<Record<string, AnyTable>>): Record<string, Record<string, OneRelation | ManyRelation>>;
626
+ declare function defineRelations<TSchema extends Record<string, unknown>>(schema: TSchema, callback: DefineRelationsCallback<ExtractTables<TSchema>>): Record<string, Record<string, OneRelation | ManyRelation>>;
622
627
  /**
623
628
  * Define a part of relations - merge multiple parts when passing to TauriORM.
624
629
  * Useful for splitting large schema definitions.
@@ -656,4 +661,4 @@ declare class TableNotFoundError extends TauriORMError {
656
661
  constructor(tableName: string);
657
662
  }
658
663
 
659
- export { type AnySQLiteColumn, type AnyTable, type ColumnDataType, ColumnNotFoundError, type ColumnOptions, type ColumnValueTypes, type Condition, type DatabaseLike, type DefineRelationsCallback, DeleteQueryBuilder, type ExtractColumnType, type InferInsertModel, type InferRelationalSelectModel, type InferRelationsMap, type InferSelectModel, InsertQueryBuilder, InsertValidationError, ManyRelation, type ManyRelationOptions, MigrationError, MissingWhereClauseError, type Mode, OneRelation, type OneRelationOptions, QueryBuilderError, Relation, type RelationConfig, RelationError, type RelationType, type RelationsBuilder, type SQLAggregate, type SQLCondition, type SQLSubquery, SQLiteColumn, SelectQueryBuilder, Table, TableNotFoundError, TauriDialect, TauriORM, TauriORMError, type ThroughRef, UpdateQueryBuilder, UpdateValidationError, ValidationError, WithQueryBuilder, alias, and, as, asc, avg, between, blob, boolean, contains, count, countDistinct, defineRelations, defineRelationsPart, desc, endsWith, enumType, eq, eqSubquery, exists, getTableColumns, groupConcat, gt, gtSubquery, gte, gteSubquery, ilike, inArray, integer, isNotNull, isNull, like, lt, ltSubquery, lte, lteSubquery, max, min, ne, neSubquery, not, notExists, notIn, numeric, or, real, relations, scalarSubquery, sqliteTable, startsWith, subquery, sum, text, through };
664
+ export { type AnySQLiteColumn, type AnyTable, type BuildR, type ColumnDataType, ColumnNotFoundError, type ColumnOptions, type ColumnValueTypes, type Condition, type DatabaseLike, type DefineRelationsCallback, DeleteQueryBuilder, type ExtractColumnType, type InferInsertModel, type InferRelationalSelectModel, type InferRelationsMap, type InferSelectModel, InsertQueryBuilder, InsertValidationError, ManyRelation, type ManyRelationOptions, MigrationError, MissingWhereClauseError, type Mode, OneRelation, type OneRelationOptions, QueryBuilderError, Relation, type RelationConfig, RelationError, type RelationType, type RelationsBuilder, type SQLAggregate, type SQLCondition, type SQLSubquery, SQLiteColumn, SelectQueryBuilder, Table, TableNotFoundError, TauriDialect, TauriORM, TauriORMError, type ThroughRef, UpdateQueryBuilder, UpdateValidationError, ValidationError, WithQueryBuilder, alias, and, as, asc, avg, between, blob, boolean, contains, count, countDistinct, defineRelations, defineRelationsPart, desc, endsWith, enumType, eq, eqSubquery, exists, getTableColumns, groupConcat, gt, gtSubquery, gte, gteSubquery, ilike, inArray, integer, isNotNull, isNull, like, lt, ltSubquery, lte, lteSubquery, max, min, ne, neSubquery, not, notExists, notIn, numeric, or, real, relations, scalarSubquery, sqliteTable, startsWith, subquery, sum, text, through };
@@ -0,0 +1,30 @@
1
+ import { Expression, SqlBool } from 'kysely';
2
+ import { AnySQLiteColumn } from './types';
3
+ export type Condition = Expression<SqlBool>;
4
+ export declare const eq: <T>(column: AnySQLiteColumn, value: T, tableAlias?: string) => Condition;
5
+ export declare const ne: <T>(column: AnySQLiteColumn, value: T, tableAlias?: string) => Condition;
6
+ export declare const and: (...conditions: Condition[]) => Condition;
7
+ export declare const or: (...conditions: Condition[]) => Condition;
8
+ export declare const not: (condition: Condition) => Condition;
9
+ export declare const gt: <T>(column: AnySQLiteColumn, value: T) => Condition;
10
+ export declare const gte: <T>(column: AnySQLiteColumn, value: T) => Condition;
11
+ export declare const lt: <T>(column: AnySQLiteColumn, value: T) => Condition;
12
+ export declare const lte: <T>(column: AnySQLiteColumn, value: T) => Condition;
13
+ export declare const like: (column: AnySQLiteColumn, pattern: string) => Condition;
14
+ export declare const ilike: (column: AnySQLiteColumn, pattern: string) => Condition;
15
+ export declare const startsWith: (column: AnySQLiteColumn, value: string) => Condition;
16
+ export declare const endsWith: (column: AnySQLiteColumn, value: string) => Condition;
17
+ export declare const contains: (column: AnySQLiteColumn, value: string) => Condition;
18
+ export declare const isNull: (column: AnySQLiteColumn) => Condition;
19
+ export declare const isNotNull: (column: AnySQLiteColumn) => Condition;
20
+ export declare const exists: (subquery: Expression<any>) => Condition;
21
+ export declare const notExists: (subquery: Expression<any>) => Condition;
22
+ export declare const eqSubquery: (column: AnySQLiteColumn, subquery: Expression<any>) => Condition;
23
+ export declare const neSubquery: (column: AnySQLiteColumn, subquery: Expression<any>) => Condition;
24
+ export declare const gtSubquery: (column: AnySQLiteColumn, subquery: Expression<any>) => Condition;
25
+ export declare const gteSubquery: (column: AnySQLiteColumn, subquery: Expression<any>) => Condition;
26
+ export declare const ltSubquery: (column: AnySQLiteColumn, subquery: Expression<any>) => Condition;
27
+ export declare const lteSubquery: (column: AnySQLiteColumn, subquery: Expression<any>) => Condition;
28
+ export declare const inArray: <T>(column: AnySQLiteColumn, values: T[] | Expression<any>) => Condition;
29
+ export declare const notIn: <T>(column: AnySQLiteColumn, values: T[] | Expression<any>) => Condition;
30
+ export declare const between: <T>(column: AnySQLiteColumn, min: T, max: T) => Condition;
@@ -0,0 +1,84 @@
1
+ import { isExpression, sql } from 'kysely';
2
+ import { serializeValue } from './serialization';
3
+ export const eq = (column, value, tableAlias) => {
4
+ const colRef = tableAlias ? `${tableAlias}.${column._.name}` : column._.name;
5
+ const serialized = serializeValue(value, column);
6
+ return sql `${sql.ref(colRef)} = ${sql.val(serialized)}`;
7
+ };
8
+ export const ne = (column, value, tableAlias) => {
9
+ const colRef = tableAlias ? `${tableAlias}.${column._.name}` : column._.name;
10
+ const serialized = serializeValue(value, column);
11
+ return sql `${sql.ref(colRef)} != ${sql.val(serialized)}`;
12
+ };
13
+ export const and = (...conditions) => {
14
+ if (conditions.length === 0)
15
+ return sql `1 = 1`;
16
+ if (conditions.length === 1)
17
+ return conditions[0];
18
+ return sql `(${sql.join(conditions.map(c => sql `(${c})`), sql ` AND `)})`;
19
+ };
20
+ export const or = (...conditions) => {
21
+ if (conditions.length === 0)
22
+ return sql `1 = 1`;
23
+ if (conditions.length === 1)
24
+ return conditions[0];
25
+ return sql `(${sql.join(conditions.map(c => sql `(${c})`), sql ` OR `)})`;
26
+ };
27
+ export const not = (condition) => sql `NOT (${condition})`;
28
+ export const gt = (column, value) => {
29
+ const serialized = serializeValue(value, column);
30
+ return sql `${sql.ref(column._.name)} > ${sql.val(serialized)}`;
31
+ };
32
+ export const gte = (column, value) => {
33
+ const serialized = serializeValue(value, column);
34
+ return sql `${sql.ref(column._.name)} >= ${sql.val(serialized)}`;
35
+ };
36
+ export const lt = (column, value) => {
37
+ const serialized = serializeValue(value, column);
38
+ return sql `${sql.ref(column._.name)} < ${sql.val(serialized)}`;
39
+ };
40
+ export const lte = (column, value) => {
41
+ const serialized = serializeValue(value, column);
42
+ return sql `${sql.ref(column._.name)} <= ${sql.val(serialized)}`;
43
+ };
44
+ export const like = (column, pattern) => sql `${sql.ref(column._.name)} LIKE ${sql.val(pattern)}`;
45
+ export const ilike = (column, pattern) => sql `${sql.ref(column._.name)} LIKE ${sql.val(pattern)} COLLATE NOCASE`;
46
+ export const startsWith = (column, value) => sql `${sql.ref(column._.name)} LIKE ${sql.val(`${value}%`)}`;
47
+ export const endsWith = (column, value) => sql `${sql.ref(column._.name)} LIKE ${sql.val(`%${value}`)}`;
48
+ export const contains = (column, value) => sql `${sql.ref(column._.name)} LIKE ${sql.val(`%${value}%`)}`;
49
+ export const isNull = (column) => sql `${sql.ref(column._.name)} IS NULL`;
50
+ export const isNotNull = (column) => sql `${sql.ref(column._.name)} IS NOT NULL`;
51
+ // SQLite rejects EXISTS ((subquery)); use single paren level
52
+ export const exists = (subquery) => sql `EXISTS ${subquery}`;
53
+ export const notExists = (subquery) => sql `NOT EXISTS ${subquery}`;
54
+ export const eqSubquery = (column, subquery) => sql `${sql.ref(column._.name)} = (${subquery})`;
55
+ export const neSubquery = (column, subquery) => sql `${sql.ref(column._.name)} != (${subquery})`;
56
+ export const gtSubquery = (column, subquery) => sql `${sql.ref(column._.name)} > (${subquery})`;
57
+ export const gteSubquery = (column, subquery) => sql `${sql.ref(column._.name)} >= (${subquery})`;
58
+ export const ltSubquery = (column, subquery) => sql `${sql.ref(column._.name)} < (${subquery})`;
59
+ export const lteSubquery = (column, subquery) => sql `${sql.ref(column._.name)} <= (${subquery})`;
60
+ export const inArray = (column, values) => {
61
+ if (isExpression(values)) {
62
+ return sql `${sql.ref(column._.name)} IN (${values})`;
63
+ }
64
+ const arr = values;
65
+ if (arr.length === 0)
66
+ return sql `1 = 0`;
67
+ const serialized = arr.map(v => sql.val(serializeValue(v, column)));
68
+ return sql `${sql.ref(column._.name)} IN (${sql.join(serialized)})`;
69
+ };
70
+ export const notIn = (column, values) => {
71
+ if (isExpression(values)) {
72
+ return sql `${sql.ref(column._.name)} NOT IN (${values})`;
73
+ }
74
+ const arr = values;
75
+ if (arr.length === 0)
76
+ return sql `1 = 1`;
77
+ const serialized = arr.map(v => sql.val(serializeValue(v, column)));
78
+ return sql `${sql.ref(column._.name)} NOT IN (${sql.join(serialized)})`;
79
+ };
80
+ export const between = (column, min, max) => {
81
+ const serializedMin = serializeValue(min, column);
82
+ const serializedMax = serializeValue(max, column);
83
+ return sql `${sql.ref(column._.name)} BETWEEN ${sql.val(serializedMin)} AND ${sql.val(serializedMax)}`;
84
+ };
package/dist/orm.d.ts ADDED
@@ -0,0 +1,180 @@
1
+ import { Expression, SqlBool } from 'kysely';
2
+ import { DatabaseLike } from './dialect';
3
+ import { SelectQueryBuilder, InsertQueryBuilder, UpdateQueryBuilder, DeleteQueryBuilder, WithQueryBuilder, RelationsBuilder } from './builders';
4
+ import { AnySQLiteColumn, AnyTable, ColumnDataType, ColumnOptions, ColumnValueTypes, Mode, RelationConfig } from './types';
5
+ export declare class SQLiteColumn<TName extends string = string, TType extends ColumnDataType = ColumnDataType, TMode extends Mode = 'default', TNotNull extends boolean = false, THasDefault extends boolean = false, TAutoincrement extends boolean = false, TEnum extends readonly string[] = never, TCustomType = never> {
6
+ type: TType;
7
+ options: ColumnOptions<ColumnValueTypes<TType, TMode>, TEnum>;
8
+ _: {
9
+ name: TName;
10
+ dataType: TType;
11
+ mode: TMode;
12
+ notNull: TNotNull;
13
+ hasDefault: THasDefault;
14
+ autoincrement: TAutoincrement;
15
+ enum: TEnum;
16
+ customType: TCustomType;
17
+ };
18
+ constructor(name: TName, type: TType, options?: ColumnOptions<ColumnValueTypes<TType, TMode>, TEnum>);
19
+ notNull(): SQLiteColumn<TName, TType, TMode, true, THasDefault, TAutoincrement, TEnum, TCustomType>;
20
+ default(value: ColumnValueTypes<TType, TMode>): SQLiteColumn<TName, TType, TMode, TNotNull, true, TAutoincrement, TEnum, TCustomType>;
21
+ $defaultFn(fn: () => ColumnValueTypes<TType, TMode>): SQLiteColumn<TName, TType, TMode, TNotNull, true, TAutoincrement, TEnum, TCustomType>;
22
+ primaryKey(): SQLiteColumn<TName, TType, TMode, true, THasDefault, TAutoincrement, TEnum, TCustomType>;
23
+ autoincrement(): SQLiteColumn<TName, TType, TMode, TNotNull, THasDefault, true, TEnum, TCustomType>;
24
+ unique(): SQLiteColumn<TName, TType, TMode, TNotNull, THasDefault, TAutoincrement, TEnum, TCustomType>;
25
+ references<T extends AnyTable, K extends keyof T['_']['columns'] & string>(ref: T, column: K | T['_']['columns'][K], options?: {
26
+ onDelete?: 'cascade' | 'set null' | 'set default' | 'restrict' | 'no action';
27
+ onUpdate?: 'cascade' | 'set null' | 'set default' | 'restrict' | 'no action';
28
+ }): SQLiteColumn<TName, TType, TMode, TNotNull, THasDefault, TAutoincrement, TEnum, TCustomType>;
29
+ $onUpdateFn(fn: () => ColumnValueTypes<TType, TMode>): SQLiteColumn<TName, TType, TMode, TNotNull, THasDefault, TAutoincrement, TEnum, TCustomType>;
30
+ $type<T>(): SQLiteColumn<TName, TType, TMode, TNotNull, THasDefault, TAutoincrement, TEnum, T>;
31
+ as(alias: string): SQLiteColumn<TName, TType, TMode, TNotNull, THasDefault, TAutoincrement, TEnum, TCustomType>;
32
+ }
33
+ type IsOptionalOnInsert<C extends AnySQLiteColumn> = C['_']['notNull'] extends false ? true : C['_']['hasDefault'] extends true ? true : C['_']['autoincrement'] extends true ? true : false;
34
+ type OptionalColumns<TColumns extends Record<string, AnySQLiteColumn>> = {
35
+ [K in keyof TColumns]: IsOptionalOnInsert<TColumns[K]> extends true ? K : never;
36
+ }[keyof TColumns];
37
+ type RequiredColumns<TColumns extends Record<string, AnySQLiteColumn>> = {
38
+ [K in keyof TColumns]: IsOptionalOnInsert<TColumns[K]> extends true ? never : K;
39
+ }[keyof TColumns];
40
+ type ExtractInsertColumnType<T extends AnySQLiteColumn> = T extends SQLiteColumn<infer _, infer TType, infer TMode, infer TNotNull, infer THasDefault, infer TAutoincrement, infer TEnum, infer TCustomType> ? [
41
+ TCustomType
42
+ ] extends [never] ? [
43
+ TEnum
44
+ ] extends [never] ? TNotNull extends true ? ColumnValueTypes<TType, TMode> : ColumnValueTypes<TType, TMode> | null : TNotNull extends true ? TEnum[number] : TEnum[number] | null : TNotNull extends true ? TCustomType : TCustomType | null : never;
45
+ export type InferInsertModel<T extends AnyTable> = {
46
+ [K in RequiredColumns<T['_']['columns']>]: ExtractInsertColumnType<T['_']['columns'][K]>;
47
+ } & {
48
+ [K in OptionalColumns<T['_']['columns']>]?: ExtractInsertColumnType<T['_']['columns'][K]>;
49
+ };
50
+ export declare class Table<TColumns extends Record<string, AnySQLiteColumn>, TTableName extends string> {
51
+ _: {
52
+ name: TTableName;
53
+ columns: TColumns;
54
+ };
55
+ relations: Record<string, RelationConfig>;
56
+ constructor(name: TTableName, columns: TColumns);
57
+ }
58
+ export declare const sqliteTable: <TTableName extends string, TColumns extends Record<string, AnySQLiteColumn>>(tableName: TTableName, columns: TColumns) => Table<TColumns, TTableName>;
59
+ export type SQLCondition = Expression<SqlBool>;
60
+ export type SQLAggregate<T = number> = Expression<T>;
61
+ export type SQLSubquery = Expression<any>;
62
+ export declare const asc: (column: AnySQLiteColumn) => Expression<any>;
63
+ export declare const desc: (column: AnySQLiteColumn) => Expression<any>;
64
+ export declare class TauriORM {
65
+ private db;
66
+ private tables;
67
+ private kysely;
68
+ constructor(db: DatabaseLike, schema?: Record<string, AnyTable | Record<string, Relation>> | undefined);
69
+ private buildColumnDefinition;
70
+ checkMigration(): Promise<{
71
+ safe: boolean;
72
+ changes: {
73
+ tablesToCreate: string[];
74
+ tablesToRecreate: string[];
75
+ tablesToDrop: string[];
76
+ columnsToAdd: Array<{
77
+ table: string;
78
+ column: string;
79
+ }>;
80
+ };
81
+ }>;
82
+ migrate(options?: {
83
+ performDestructiveActions?: boolean;
84
+ dryRun?: boolean;
85
+ }): Promise<void>;
86
+ private canAddColumnWithAlter;
87
+ private hasColumnDefinitionChanged;
88
+ private recreateTable;
89
+ select<T extends AnyTable, C extends (keyof T['_']['columns'])[] | undefined = undefined>(table: T, columns?: C): SelectQueryBuilder<T, C>;
90
+ insert<T extends AnyTable>(table: T): InsertQueryBuilder<T>;
91
+ update<T extends AnyTable>(table: T): UpdateQueryBuilder<T>;
92
+ delete<T extends AnyTable>(table: T): DeleteQueryBuilder<T>;
93
+ upsert<T extends AnyTable>(table: T, data: InferInsertModel<T>, conflictTarget: (keyof T['_']['columns'])[]): Promise<T extends AnyTable ? {
94
+ lastInsertId: number;
95
+ rowsAffected: number;
96
+ }[] : never>;
97
+ $with(alias: string): {
98
+ as: (query: SelectQueryBuilder<any, any>) => WithQueryBuilder;
99
+ };
100
+ transaction<T>(callback: (tx: TauriORM) => Promise<T>): Promise<T>;
101
+ rollback(): never;
102
+ private ensureSchemaMeta;
103
+ private getSchemaMeta;
104
+ private setSchemaMeta;
105
+ private normalizeColumn;
106
+ private computeModelSignature;
107
+ getSchemaSignature(): string;
108
+ isSchemaDirty(): Promise<{
109
+ dirty: boolean;
110
+ current: string;
111
+ stored: string | null;
112
+ }>;
113
+ migrateIfDirty(): Promise<boolean>;
114
+ doesTableExist(tableName: string): Promise<boolean>;
115
+ dropTable(tableName: string): Promise<void>;
116
+ doesColumnExist(tableName: string, columnName: string): Promise<boolean>;
117
+ renameTable(from: string, to: string): Promise<void>;
118
+ dropColumn(tableName: string, columnName: string): Promise<void>;
119
+ renameColumn(tableName: string, from: string, to: string): Promise<void>;
120
+ }
121
+ export declare class Relation<T extends AnyTable = AnyTable> {
122
+ foreignTable: T;
123
+ constructor(foreignTable: T);
124
+ }
125
+ export declare class OneRelation<T extends AnyTable = AnyTable> extends Relation<T> {
126
+ config?: {
127
+ fields: AnySQLiteColumn[];
128
+ references: AnySQLiteColumn[];
129
+ optional?: boolean;
130
+ alias?: string;
131
+ } | undefined;
132
+ constructor(foreignTable: T, config?: {
133
+ fields: AnySQLiteColumn[];
134
+ references: AnySQLiteColumn[];
135
+ optional?: boolean;
136
+ alias?: string;
137
+ } | undefined);
138
+ }
139
+ export declare class ManyRelation<T extends AnyTable = AnyTable> extends Relation<T> {
140
+ config?: {
141
+ from?: AnySQLiteColumn[];
142
+ to?: AnySQLiteColumn[];
143
+ through?: {
144
+ junctionTable: AnyTable;
145
+ fromRef: {
146
+ column: AnySQLiteColumn;
147
+ junctionColumn: AnySQLiteColumn;
148
+ };
149
+ toRef: {
150
+ column: AnySQLiteColumn;
151
+ junctionColumn: AnySQLiteColumn;
152
+ };
153
+ };
154
+ optional?: boolean;
155
+ alias?: string;
156
+ where?: (alias: string) => unknown;
157
+ } | undefined;
158
+ constructor(foreignTable: T, config?: {
159
+ from?: AnySQLiteColumn[];
160
+ to?: AnySQLiteColumn[];
161
+ through?: {
162
+ junctionTable: AnyTable;
163
+ fromRef: {
164
+ column: AnySQLiteColumn;
165
+ junctionColumn: AnySQLiteColumn;
166
+ };
167
+ toRef: {
168
+ column: AnySQLiteColumn;
169
+ junctionColumn: AnySQLiteColumn;
170
+ };
171
+ };
172
+ optional?: boolean;
173
+ alias?: string;
174
+ where?: (alias: string) => unknown;
175
+ } | undefined);
176
+ }
177
+ export declare const relations: <T extends AnyTable, R extends Record<string, Relation>>(table: T, relationsCallback: (helpers: RelationsBuilder) => R) => R;
178
+ export declare const getTableColumns: <T extends AnyTable>(table: T) => Record<string, AnySQLiteColumn>;
179
+ export declare const alias: <T extends AnyTable>(table: T, alias: string) => Table<T["_"]["columns"], T["_"]["name"]>;
180
+ export {};