@rwillians/exto 0.1.2 → 0.2.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 +207 -153
- package/dist/cjs/bun-postgres.js +36 -11
- package/dist/cjs/bun-sqlite.js +9 -3
- package/dist/cjs/index.js +418 -159
- package/dist/cjs/standard-schema.js +10 -1
- package/dist/esm/bun-postgres.js +36 -11
- package/dist/esm/bun-sqlite.js +9 -3
- package/dist/esm/index.js +414 -159
- package/dist/esm/standard-schema.js +8 -0
- package/dist/types/bun-postgres.d.ts +1 -0
- package/dist/types/bun-sqlite.d.ts +1 -0
- package/dist/types/index.d.ts +205 -82
- package/dist/types/standard-schema.d.ts +6 -0
- package/package.json +9 -8
|
@@ -184,6 +184,14 @@ export const number = () => define((input) => Number.isFinite(input)
|
|
|
184
184
|
export const optional = (schema) => define((input) => input === undefined
|
|
185
185
|
? { value: undefined }
|
|
186
186
|
: parse(schema, input));
|
|
187
|
+
/**
|
|
188
|
+
* @public Defines a standard schema for plain objects with string keys.
|
|
189
|
+
* @since 0.2.0
|
|
190
|
+
* @version 1
|
|
191
|
+
*/
|
|
192
|
+
export const record = () => define((input) => typeof input === 'object' && input !== null && Object.getPrototypeOf(input) === Object.prototype
|
|
193
|
+
? { value: input }
|
|
194
|
+
: fail('must be a plain object'));
|
|
187
195
|
/**
|
|
188
196
|
* @public Defines a standard schema for strings, optionally limited in
|
|
189
197
|
* length.
|
|
@@ -8,6 +8,7 @@ declare class BunPostgres implements IDatabase {
|
|
|
8
8
|
readonly dialect: Dialect;
|
|
9
9
|
constructor(sql: SQL, loggers?: ILogger[], inTransaction?: boolean);
|
|
10
10
|
execute(sql: string, params: unknown[]): Promise<Row[] & SQL.ResultMetadata>;
|
|
11
|
+
close(): Promise<void>;
|
|
11
12
|
transaction<T>(fn: (tx: IDatabase) => Promise<T>): Promise<T>;
|
|
12
13
|
}
|
|
13
14
|
declare const connect: (url: string, { loggers }?: {
|
|
@@ -8,6 +8,7 @@ declare class BunSQLite implements IDatabase {
|
|
|
8
8
|
readonly dialect: Dialect;
|
|
9
9
|
constructor(conn: Database, loggers?: ILogger[], depth?: number);
|
|
10
10
|
execute(sql: string, params: unknown[]): Promise<Row[]>;
|
|
11
|
+
close(): Promise<void>;
|
|
11
12
|
transaction<T>(fn: (tx: IDatabase) => Promise<T>): Promise<T>;
|
|
12
13
|
}
|
|
13
14
|
declare const connect: (filename?: string, { loggers }?: {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as std from './standard-schema';
|
|
2
2
|
import { ValidationError } from './standard-schema';
|
|
3
|
-
import { type
|
|
4
|
-
type Primitive = 'BIGINT' | 'BINARY' | 'BOOLEAN' | 'CITEXT' | 'DATE' | '
|
|
3
|
+
import { type Expand } from './utils';
|
|
4
|
+
type Primitive = 'BIGINT' | 'BINARY' | 'BOOLEAN' | 'CITEXT' | 'DATE' | 'DECIMAL' | 'FLOAT' | 'INTEGER' | 'JSON' | 'SEQUENCE' | 'STRING' | 'TEXT' | 'TIMESTAMP' | 'UUID';
|
|
5
|
+
type NumericType = 'BIGINT' | 'DECIMAL' | 'FLOAT' | 'INTEGER' | 'SEQUENCE';
|
|
5
6
|
type ColumnProps<S extends std.Schema = std.Schema> = {
|
|
6
7
|
type: Primitive;
|
|
7
8
|
schema: S;
|
|
@@ -13,6 +14,8 @@ type ColumnProps<S extends std.Schema = std.Schema> = {
|
|
|
13
14
|
nullable?: true;
|
|
14
15
|
primaryKey?: true;
|
|
15
16
|
unique?: true;
|
|
17
|
+
fields?: Columns;
|
|
18
|
+
many?: true;
|
|
16
19
|
};
|
|
17
20
|
type Column<K extends string = string, P extends ColumnProps = ColumnProps> = P & {
|
|
18
21
|
key: K;
|
|
@@ -20,6 +23,7 @@ type Column<K extends string = string, P extends ColumnProps = ColumnProps> = P
|
|
|
20
23
|
input: std.input<P['schema']>;
|
|
21
24
|
output: std.output<P['schema']>;
|
|
22
25
|
};
|
|
26
|
+
type Columns = Record<string, Column>;
|
|
23
27
|
declare class ColumnBuilder<P extends ColumnProps> {
|
|
24
28
|
readonly props: P;
|
|
25
29
|
constructor(props: P);
|
|
@@ -29,7 +33,7 @@ declare class ColumnBuilder<P extends ColumnProps> {
|
|
|
29
33
|
generated(): ColumnBuilder<Expand<P & {
|
|
30
34
|
generated: true;
|
|
31
35
|
}>>;
|
|
32
|
-
|
|
36
|
+
optional(): ColumnBuilder<Expand<Omit<P, "schema"> & {
|
|
33
37
|
nullable: true;
|
|
34
38
|
schema: std.Schema<std.input<P['schema']> | null, std.output<P['schema']> | null>;
|
|
35
39
|
}>>;
|
|
@@ -39,8 +43,35 @@ declare class ColumnBuilder<P extends ColumnProps> {
|
|
|
39
43
|
unique(): ColumnBuilder<Expand<P & {
|
|
40
44
|
unique: true;
|
|
41
45
|
}>>;
|
|
46
|
+
unsigned(this: ColumnBuilder<P & {
|
|
47
|
+
type: 'INTEGER';
|
|
48
|
+
}>): ColumnBuilder<P>;
|
|
42
49
|
}
|
|
43
50
|
declare const column: <P extends ColumnProps>(props: P) => ColumnBuilder<P>;
|
|
51
|
+
type Shape = Record<string, ColumnBuilder<ColumnProps>>;
|
|
52
|
+
type ColumnsOfShape<S extends Shape> = {
|
|
53
|
+
[K in keyof S & string]: Column<K, S[K]['props']>;
|
|
54
|
+
};
|
|
55
|
+
declare const embedded: {
|
|
56
|
+
one: <S extends Shape>(shape: S) => ColumnBuilder<{
|
|
57
|
+
type: "JSON";
|
|
58
|
+
schema: std.Schema<Expand<(ColumnsOfShape<S> extends infer T_3 extends Columns ? { [K in keyof T_3 as ColumnsOfShape<S>[K] extends OmitOnInsert | OptionalOnInsert ? never : K]: T_3[K]["input"]; } : never) & (ColumnsOfShape<S> extends infer T_4 extends Columns ? { [K in keyof T_4 as ColumnsOfShape<S>[K] extends OmitOnInsert ? never : ColumnsOfShape<S>[K] extends OptionalOnInsert ? K : never]?: T_4[K]["input"] | undefined; } : never)>, Expand<ColumnsOfShape<S> extends infer T_5 extends Columns ? { [K in keyof T_5]: T_5[K]["output"]; } : never>>;
|
|
59
|
+
fields: ColumnsOfShape<S>;
|
|
60
|
+
}>;
|
|
61
|
+
many: <S extends Shape>(shape: S) => ColumnBuilder<{
|
|
62
|
+
type: "JSON";
|
|
63
|
+
schema: std.Schema<Expand<(ColumnsOfShape<S> extends infer T extends Columns ? { [K in keyof T as ColumnsOfShape<S>[K] extends OmitOnInsert | OptionalOnInsert ? never : K]: T[K]["input"]; } : never) & (ColumnsOfShape<S> extends infer T_1 extends Columns ? { [K in keyof T_1 as ColumnsOfShape<S>[K] extends OmitOnInsert ? never : ColumnsOfShape<S>[K] extends OptionalOnInsert ? K : never]?: T_1[K]["input"] | undefined; } : never)>[], Expand<ColumnsOfShape<S> extends infer T_2 extends Columns ? { [K in keyof T_2]: T_2[K]["output"]; } : never>[]>;
|
|
64
|
+
fields: ColumnsOfShape<S>;
|
|
65
|
+
many: true;
|
|
66
|
+
}>;
|
|
67
|
+
};
|
|
68
|
+
declare const defineType: <S extends std.Schema>({ primitive, schema }: {
|
|
69
|
+
primitive: Exclude<Primitive, 'JSON'>;
|
|
70
|
+
schema: S;
|
|
71
|
+
}) => ColumnBuilder<{
|
|
72
|
+
type: "BIGINT" | "BINARY" | "BOOLEAN" | "CITEXT" | "DATE" | "DECIMAL" | "FLOAT" | "INTEGER" | "SEQUENCE" | "STRING" | "TEXT" | "TIMESTAMP" | "UUID";
|
|
73
|
+
schema: S;
|
|
74
|
+
}>;
|
|
44
75
|
declare const types: {
|
|
45
76
|
bigint: () => ColumnBuilder<{
|
|
46
77
|
type: "BIGINT";
|
|
@@ -62,10 +93,6 @@ declare const types: {
|
|
|
62
93
|
type: "DATE";
|
|
63
94
|
schema: std.Schema<string, string>;
|
|
64
95
|
}>;
|
|
65
|
-
datetime: () => ColumnBuilder<{
|
|
66
|
-
type: "DATETIME";
|
|
67
|
-
schema: std.Schema<string | number | Date, Date>;
|
|
68
|
-
}>;
|
|
69
96
|
decimal: (options?: {
|
|
70
97
|
precision: number;
|
|
71
98
|
scale: number;
|
|
@@ -92,6 +119,10 @@ declare const types: {
|
|
|
92
119
|
type: "JSON";
|
|
93
120
|
schema: S;
|
|
94
121
|
}>;
|
|
122
|
+
record: () => ColumnBuilder<{
|
|
123
|
+
type: "JSON";
|
|
124
|
+
schema: std.Schema<Record<string, unknown>, Record<string, unknown>>;
|
|
125
|
+
}>;
|
|
95
126
|
sequence: () => ColumnBuilder<{
|
|
96
127
|
type: "SEQUENCE";
|
|
97
128
|
schema: std.Schema<number, number>;
|
|
@@ -108,17 +139,75 @@ declare const types: {
|
|
|
108
139
|
type: "TEXT";
|
|
109
140
|
schema: std.Schema<string, string>;
|
|
110
141
|
}>;
|
|
111
|
-
|
|
142
|
+
timestamp: () => ColumnBuilder<{
|
|
143
|
+
type: "TIMESTAMP";
|
|
144
|
+
schema: std.Schema<string | number | Date, Date>;
|
|
145
|
+
}>;
|
|
146
|
+
uuidv7: () => ColumnBuilder<{
|
|
112
147
|
type: "UUID";
|
|
113
148
|
schema: std.Schema<string, string>;
|
|
114
149
|
}>;
|
|
115
150
|
};
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
151
|
+
declare const NAME: unique symbol;
|
|
152
|
+
declare const ALIAS: unique symbol;
|
|
153
|
+
declare const NODE: unique symbol;
|
|
154
|
+
declare const COLUMNS: unique symbol;
|
|
155
|
+
declare const OPERAND: unique symbol;
|
|
156
|
+
declare const KEY: unique symbol;
|
|
157
|
+
type Op = '=' | '!=' | '<' | '<=' | '>' | '>=' | 'is' | 'is not';
|
|
158
|
+
type Node = {
|
|
159
|
+
kind: 'ref';
|
|
119
160
|
alias: string;
|
|
120
|
-
|
|
161
|
+
col: Column;
|
|
162
|
+
path: Column[];
|
|
163
|
+
} | {
|
|
164
|
+
kind: 'fragment';
|
|
165
|
+
strings: readonly string[];
|
|
166
|
+
values: unknown[];
|
|
167
|
+
} | {
|
|
168
|
+
kind: 'call';
|
|
169
|
+
fn: 'COUNT' | 'SUM';
|
|
170
|
+
arg: Node;
|
|
171
|
+
} | {
|
|
172
|
+
kind: 'compare';
|
|
173
|
+
lhs: Node;
|
|
174
|
+
op: Op;
|
|
175
|
+
rhs: Node | {
|
|
176
|
+
kind: 'value';
|
|
177
|
+
value: unknown;
|
|
178
|
+
};
|
|
179
|
+
} | {
|
|
180
|
+
kind: 'group';
|
|
181
|
+
op: 'AND' | 'OR';
|
|
182
|
+
nodes: Node[];
|
|
183
|
+
};
|
|
184
|
+
type Operand<A extends string = string, V = unknown, N extends string = string> = {
|
|
185
|
+
readonly [NODE]: Node;
|
|
186
|
+
readonly [OPERAND]: {
|
|
187
|
+
aliases: A;
|
|
188
|
+
value: V;
|
|
189
|
+
nulls: N;
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
type ColumnRef<A extends string = string, K extends string = string, V = unknown> = Operand<A, V, A> & {
|
|
193
|
+
readonly [KEY]: K;
|
|
194
|
+
};
|
|
195
|
+
type FieldRefs<A extends string, C extends Column> = C extends {
|
|
196
|
+
fields: infer F extends Columns;
|
|
197
|
+
} ? C extends {
|
|
198
|
+
many: true;
|
|
199
|
+
} ? {} : {
|
|
200
|
+
readonly [K in keyof F & string]: Operand<A, F[K]['output'], A> & FieldRefs<A, F[K]>;
|
|
201
|
+
} : {};
|
|
202
|
+
type RefTo<A extends string, K extends string, C extends Column> = ColumnRef<A, K, C['output']> & FieldRefs<A, C>;
|
|
203
|
+
type Table<N extends string = string, A extends string = string, C extends Columns = Columns> = {
|
|
204
|
+
readonly [NAME]: N;
|
|
205
|
+
readonly [ALIAS]: A;
|
|
206
|
+
readonly [COLUMNS]: C;
|
|
121
207
|
};
|
|
208
|
+
type ColumnsOf<T extends Table> = T[typeof COLUMNS];
|
|
209
|
+
type AliasOf<T extends Table> = T[typeof ALIAS];
|
|
210
|
+
type Keys<T extends Table> = keyof ColumnsOf<T> & string;
|
|
122
211
|
type OmitOnInsert = {
|
|
123
212
|
generated: true;
|
|
124
213
|
};
|
|
@@ -132,8 +221,7 @@ type OmitOnUpdate = {
|
|
|
132
221
|
} | {
|
|
133
222
|
primaryKey: true;
|
|
134
223
|
};
|
|
135
|
-
type
|
|
136
|
-
type Infer<C extends Columns> = Expand<{
|
|
224
|
+
type InferForSelect<C extends Columns> = Expand<{
|
|
137
225
|
[K in keyof C]: C[K]['output'];
|
|
138
226
|
}>;
|
|
139
227
|
type InferForInsert<C extends Columns> = Expand<{
|
|
@@ -144,20 +232,31 @@ type InferForInsert<C extends Columns> = Expand<{
|
|
|
144
232
|
type InferForUpdate<C extends Columns> = Expand<{
|
|
145
233
|
[K in keyof C as C[K] extends OmitOnUpdate ? never : K]?: C[K]['input'];
|
|
146
234
|
}>;
|
|
235
|
+
type Infer<M extends 'select' | 'insert' | 'update', T extends Table> = {
|
|
236
|
+
select: InferForSelect<ColumnsOf<T>>;
|
|
237
|
+
insert: InferForInsert<ColumnsOf<T>>;
|
|
238
|
+
update: InferForUpdate<ColumnsOf<T>>;
|
|
239
|
+
}[M];
|
|
147
240
|
type NumericKeys<C extends Columns> = {
|
|
148
241
|
[K in keyof C]: C[K] extends OmitOnUpdate ? never : C[K]['type'] extends NumericType ? K : never;
|
|
149
242
|
}[keyof C];
|
|
150
|
-
|
|
151
|
-
as
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
243
|
+
declare class Aliasable<N extends string, C extends Columns> {
|
|
244
|
+
as<B extends string>(alias: B): DefinedTable<N, B, C>;
|
|
245
|
+
}
|
|
246
|
+
type DefinedTable<N extends string, A extends string, C extends Columns> = Table<N, A, C> & {
|
|
247
|
+
readonly [K in keyof C & string]: RefTo<A, K, C[K]>;
|
|
248
|
+
} & Aliasable<N, C>;
|
|
249
|
+
declare const RESERVED: readonly ['as'];
|
|
250
|
+
type Reserved<S> = {
|
|
251
|
+
[K in keyof S & typeof RESERVED[number]]: never;
|
|
155
252
|
};
|
|
156
|
-
declare const defineTable: <N extends string, S extends
|
|
253
|
+
declare const defineTable: <N extends string, S extends Shape>(name: N, shape: S & NoInfer<Reserved<S>>) => DefinedTable<N, N, ColumnsOfShape<S>>;
|
|
254
|
+
declare const parse: <T extends Table>(table: T, input: unknown) => Infer<'insert', T>;
|
|
157
255
|
type Codec = {
|
|
158
256
|
encode: (value: any) => unknown;
|
|
159
257
|
decode: (value: any) => unknown;
|
|
160
258
|
};
|
|
259
|
+
type DialectName = 'postgres' | 'sqlite' | (string & {});
|
|
161
260
|
/**
|
|
162
261
|
* Everything that differs between database engines. SQL generation, param
|
|
163
262
|
* collection, validation and encoding/decoding all live in the core.
|
|
@@ -165,13 +264,17 @@ type Codec = {
|
|
|
165
264
|
* `generated` returns the DDL that makes the database generate the column's
|
|
166
265
|
* value, or `undefined` when the database can't natively, in which case the
|
|
167
266
|
* value is generated client-side on insert.
|
|
267
|
+
*
|
|
268
|
+
* `json` extracts a field nested in a JSON column, as an SQL value of the
|
|
269
|
+
* field's type: a JSON document itself when the field is a JSON one (a
|
|
270
|
+
* record, or embedded fields).
|
|
168
271
|
*/
|
|
169
|
-
type DialectName = 'postgres' | 'sqlite' | (string & {});
|
|
170
272
|
interface Dialect {
|
|
171
273
|
name: DialectName;
|
|
172
274
|
placeholder(index: number): string;
|
|
173
275
|
type(column: Column): string;
|
|
174
276
|
generated(column: Column): string | undefined;
|
|
277
|
+
json(sql: string, path: string[], type: Primitive): string;
|
|
175
278
|
codecs: Record<Primitive, Codec>;
|
|
176
279
|
}
|
|
177
280
|
interface ILogger {
|
|
@@ -186,32 +289,43 @@ interface IDatabase {
|
|
|
186
289
|
transaction<T>(fn: (tx: IDatabase) => Promise<T>): Promise<T>;
|
|
187
290
|
}
|
|
188
291
|
declare const exec: (db: IDatabase, sql: string, params?: unknown[]) => Promise<void>;
|
|
189
|
-
type
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
};
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
292
|
+
type ValueOf<O> = O extends {
|
|
293
|
+
readonly [OPERAND]: {
|
|
294
|
+
value: infer V;
|
|
295
|
+
};
|
|
296
|
+
} ? V : never;
|
|
297
|
+
type AliasesOf<O> = O extends {
|
|
298
|
+
readonly [OPERAND]: {
|
|
299
|
+
aliases: infer A extends string;
|
|
300
|
+
};
|
|
301
|
+
} ? A : never;
|
|
302
|
+
type NullsOf<O> = O extends {
|
|
303
|
+
readonly [OPERAND]: {
|
|
304
|
+
nulls: infer N extends string;
|
|
305
|
+
};
|
|
306
|
+
} ? N : never;
|
|
307
|
+
type ValueIn<O, N extends string> = [NullsOf<O> & N] extends [never] ? ValueOf<O> : ValueOf<O> | null;
|
|
308
|
+
type ComparisonOp = '=' | '!=' | '<' | '<=' | '>' | '>=';
|
|
309
|
+
type ValueFor<V, O extends Op> = O extends 'is' | 'is not' ? null extends V ? null : never : NonNullable<V>;
|
|
310
|
+
type RhsFor<V, O extends Op, A extends string = string> = ValueFor<V, O> | (O extends ComparisonOp ? Operand<A, NonNullable<V> | null> : never);
|
|
311
|
+
type Condition<A extends string = string> = Operand<A, boolean, never>;
|
|
312
|
+
type ExprOf = {
|
|
313
|
+
<L extends Operand, O extends Op>(lhs: L, op: O, rhs: ValueFor<ValueOf<L>, O>): Condition<AliasesOf<L>>;
|
|
314
|
+
<L extends Operand, O extends ComparisonOp, R extends Operand<string, NonNullable<ValueOf<L>> | null>>(lhs: L, op: O, rhs: R): Condition<AliasesOf<L> | AliasesOf<R>>;
|
|
206
315
|
};
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
group: 'AND' | 'OR';
|
|
213
|
-
conditions: Condition[];
|
|
316
|
+
declare const expr: ExprOf & {
|
|
317
|
+
and: <E extends Condition>(exprs: E[]) => Condition<AliasesOf<E>>;
|
|
318
|
+
or: <E extends Condition>(exprs: E[]) => Condition<AliasesOf<E>>;
|
|
319
|
+
count: <O extends Operand>(arg: O) => Operand<AliasesOf<O>, number, never>;
|
|
320
|
+
sum: <O extends Operand<string, number | null>>(arg: O) => Operand<AliasesOf<O>, number, never>;
|
|
214
321
|
};
|
|
322
|
+
declare const f: <V extends unknown[]>(strings: TemplateStringsArray, ...values: V) => Operand<AliasesOf<V[number]>, unknown, never>;
|
|
323
|
+
type Scope = Map<string, Table>;
|
|
324
|
+
type Returnable<T extends Table> = Keys<T> | ColumnRef<AliasOf<T>, Keys<T>>;
|
|
325
|
+
type ReturnedKey<R> = R extends string ? R : R extends {
|
|
326
|
+
readonly [KEY]: infer K extends string;
|
|
327
|
+
} ? K : never;
|
|
328
|
+
type Returned<T extends Table, R> = Pick<InferForSelect<ColumnsOf<T>>, ReturnedKey<R> & Keys<T>>;
|
|
215
329
|
type Changes<C extends Columns> = {
|
|
216
330
|
set?: InferForUpdate<C>;
|
|
217
331
|
inc?: {
|
|
@@ -230,71 +344,80 @@ type InsertOptions<C extends Columns> = {
|
|
|
230
344
|
declare class InsertBuilder<T extends Table> {
|
|
231
345
|
private readonly table;
|
|
232
346
|
private readonly rows;
|
|
233
|
-
constructor(table: T, rows?: InferForInsert<T[
|
|
234
|
-
values(rows: InferForInsert<T
|
|
235
|
-
insert(db: IDatabase, options?: InsertOptions<T
|
|
347
|
+
constructor(table: T, rows?: InferForInsert<ColumnsOf<T>>[]);
|
|
348
|
+
values(rows: InferForInsert<ColumnsOf<T>> | InferForInsert<ColumnsOf<T>>[]): InsertBuilder<T>;
|
|
349
|
+
insert(db: IDatabase, options?: InsertOptions<ColumnsOf<T>> & {
|
|
236
350
|
returning?: true;
|
|
237
|
-
}): Promise<
|
|
238
|
-
insert(db: IDatabase, options: InsertOptions<T
|
|
351
|
+
}): Promise<InferForSelect<ColumnsOf<T>>[]>;
|
|
352
|
+
insert(db: IDatabase, options: InsertOptions<ColumnsOf<T>> & {
|
|
239
353
|
returning: false;
|
|
240
354
|
}): Promise<undefined>;
|
|
241
|
-
insert<
|
|
242
|
-
returning:
|
|
243
|
-
}): Promise<
|
|
355
|
+
insert<R extends Returnable<T>>(db: IDatabase, options: InsertOptions<ColumnsOf<T>> & {
|
|
356
|
+
returning: R[];
|
|
357
|
+
}): Promise<Returned<T, R>[]>;
|
|
244
358
|
private renderConflict;
|
|
245
359
|
}
|
|
246
360
|
declare const into: <T extends Table>(table: T) => InsertBuilder<T>;
|
|
247
361
|
type Direction = 'ASC' | 'DESC';
|
|
248
|
-
type
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
362
|
+
type Field = [key: string, node: Node];
|
|
363
|
+
type Query = {
|
|
364
|
+
table: Table;
|
|
365
|
+
scope: Scope;
|
|
366
|
+
joins: {
|
|
367
|
+
table: Table;
|
|
368
|
+
on: Node;
|
|
369
|
+
}[];
|
|
370
|
+
select?: Field[];
|
|
371
|
+
where: Node[];
|
|
372
|
+
groupBy: Node[];
|
|
373
|
+
orderBy: [Node, Direction][];
|
|
253
374
|
limit?: number;
|
|
254
375
|
offset?: number;
|
|
255
376
|
};
|
|
256
|
-
|
|
257
|
-
declare class QueryBuilder<T extends Table, S extends Keys<T> = Keys<T>> {
|
|
377
|
+
declare class QueryBuilder<T extends Table, A extends string = AliasOf<T>, N extends string = never, R = InferForSelect<ColumnsOf<T>>> {
|
|
258
378
|
private readonly query;
|
|
259
|
-
constructor(query: Query
|
|
260
|
-
select<
|
|
261
|
-
where<
|
|
262
|
-
where(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
379
|
+
constructor(query: Query);
|
|
380
|
+
select<P extends Record<string, Operand<A>>>(projection: P): QueryBuilder<T, A, N, Expand<{ [K in keyof P & string]: ValueIn<P[K], N>; }>>;
|
|
381
|
+
where<L extends Operand<A>, O extends Op>(lhs: L, op: O, rhs: RhsFor<ValueIn<L, N>, O, A>): QueryBuilder<T, A, N, R>;
|
|
382
|
+
where(condition: Condition<A>): QueryBuilder<T, A, N, R>;
|
|
383
|
+
leftJoin<J extends Table>(table: J, on: Condition<A | AliasOf<J>>): QueryBuilder<T, A | AliasOf<J>, N | AliasOf<J>, R>;
|
|
384
|
+
groupBy(operands: Operand<A>[]): QueryBuilder<T, A, N, R>;
|
|
385
|
+
orderBy(operands: (Operand<A> | [Operand<A>, Direction])[]): QueryBuilder<T, A, N, R>;
|
|
386
|
+
limit(n: number): QueryBuilder<T, A, N, R>;
|
|
387
|
+
offset(n: number): QueryBuilder<T, A, N, R>;
|
|
388
|
+
all(db: IDatabase): Promise<R[]>;
|
|
389
|
+
one(db: IDatabase): Promise<NonNullable<R> | null>;
|
|
268
390
|
exists(db: IDatabase): Promise<boolean>;
|
|
269
391
|
count(db: IDatabase): Promise<number>;
|
|
270
|
-
update(db: IDatabase, changes: Changes<T
|
|
392
|
+
update(db: IDatabase, changes: Changes<ColumnsOf<T>> & {
|
|
271
393
|
returning: false;
|
|
272
394
|
}): Promise<undefined>;
|
|
273
|
-
update<K extends
|
|
395
|
+
update<K extends Returnable<T>>(db: IDatabase, changes: Changes<ColumnsOf<T>> & {
|
|
274
396
|
returning: K[];
|
|
275
|
-
}): Promise<
|
|
276
|
-
update(db: IDatabase, changes: Changes<T
|
|
397
|
+
}): Promise<Returned<T, K>[]>;
|
|
398
|
+
update(db: IDatabase, changes: Changes<ColumnsOf<T>> & {
|
|
277
399
|
returning?: true;
|
|
278
|
-
}): Promise<
|
|
400
|
+
}): Promise<InferForSelect<ColumnsOf<T>>[]>;
|
|
279
401
|
delete(db: IDatabase, options: {
|
|
280
402
|
returning: true;
|
|
281
|
-
}): Promise<
|
|
282
|
-
delete<K extends
|
|
403
|
+
}): Promise<InferForSelect<ColumnsOf<T>>[]>;
|
|
404
|
+
delete<K extends Returnable<T>>(db: IDatabase, options: {
|
|
283
405
|
returning: K[];
|
|
284
|
-
}): Promise<
|
|
406
|
+
}): Promise<Returned<T, K>[]>;
|
|
285
407
|
delete(db: IDatabase, options?: {
|
|
286
408
|
returning?: false;
|
|
287
409
|
}): Promise<undefined>;
|
|
410
|
+
private fields;
|
|
288
411
|
private renderSelect;
|
|
289
412
|
private top;
|
|
290
|
-
private
|
|
413
|
+
private assertPlain;
|
|
291
414
|
}
|
|
292
|
-
declare const from: <T extends Table>(table: T) => QueryBuilder<T,
|
|
415
|
+
declare const from: <T extends Table>(table: T) => QueryBuilder<T, AliasOf<T>, never, Expand<ColumnsOf<T> extends infer T_1 extends Columns ? { [K in keyof T_1]: T_1[K]["output"]; } : never>>;
|
|
293
416
|
type IndexOptions = {
|
|
294
417
|
ifNotExists?: boolean;
|
|
295
418
|
name?: string;
|
|
296
419
|
};
|
|
297
|
-
declare const createIndex: <T extends Table>(table: T, keys:
|
|
420
|
+
declare const createIndex: <T extends Table>(table: T, keys: Keys<T>[], { ifNotExists, name, unique, }?: IndexOptions & {
|
|
298
421
|
unique?: boolean;
|
|
299
422
|
}) => {
|
|
300
423
|
onto: (db: IDatabase) => Promise<void>;
|
|
@@ -306,10 +429,10 @@ declare const create: {
|
|
|
306
429
|
onto: (db: IDatabase) => Promise<void>;
|
|
307
430
|
};
|
|
308
431
|
index: typeof createIndex;
|
|
309
|
-
uniqueIndex: <T extends Table>(table: T, keys:
|
|
432
|
+
uniqueIndex: <T extends Table>(table: T, keys: Keys<T>[], options?: IndexOptions) => {
|
|
310
433
|
onto: (db: IDatabase) => Promise<void>;
|
|
311
434
|
};
|
|
312
435
|
};
|
|
313
436
|
type Migration = (db: IDatabase) => Promise<void>;
|
|
314
437
|
declare const defineMigrations: (migrations: Record<string, Migration>) => (db: IDatabase) => Promise<void>;
|
|
315
|
-
export { type Codec, type Column, type ColumnProps, type
|
|
438
|
+
export { type Codec, type Column, type ColumnProps, type ColumnRef, type Dialect, type DialectName, type IDatabase, type ILogger, type Infer, type Migration, type Operand, type Primitive, type Row, type Table, ValidationError, column, create, defineMigrations, defineTable as table, defineType, embedded, exec, expr, f, from, into, parse, types as t, };
|
|
@@ -143,6 +143,12 @@ export declare const number: () => StandardSchemaV1<number, number>;
|
|
|
143
143
|
* @version 1
|
|
144
144
|
*/
|
|
145
145
|
export declare const optional: <T extends StandardSchemaV1>(schema: T) => StandardSchemaV1<input<T> | undefined, output<T> | undefined>;
|
|
146
|
+
/**
|
|
147
|
+
* @public Defines a standard schema for plain objects with string keys.
|
|
148
|
+
* @since 0.2.0
|
|
149
|
+
* @version 1
|
|
150
|
+
*/
|
|
151
|
+
export declare const record: () => StandardSchemaV1<Record<string, unknown>, Record<string, unknown>>;
|
|
146
152
|
/**
|
|
147
153
|
* @public Defines a standard schema for strings, optionally limited in
|
|
148
154
|
* length.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rwillians/exto",
|
|
3
|
-
"description": "A
|
|
4
|
-
"version": "0.
|
|
3
|
+
"description": "A teeny tiny, type-safe query builder for Bun, with adapters for SQLite and PostgreSQL.",
|
|
4
|
+
"version": "0.2.0",
|
|
5
5
|
"author": "Rafael Willians <me@rwillians.com>",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"publishConfig": {
|
|
@@ -12,12 +12,9 @@
|
|
|
12
12
|
"url": "git://github.com/rwillians/exto.git"
|
|
13
13
|
},
|
|
14
14
|
"keywords": [
|
|
15
|
-
"builder",
|
|
16
15
|
"bun",
|
|
17
|
-
"
|
|
16
|
+
"migrations",
|
|
18
17
|
"postgres",
|
|
19
|
-
"query builder",
|
|
20
|
-
"query",
|
|
21
18
|
"sql",
|
|
22
19
|
"sqlite",
|
|
23
20
|
"type-safe",
|
|
@@ -27,7 +24,10 @@
|
|
|
27
24
|
"type": "module",
|
|
28
25
|
"module": "dist/esm/index.js",
|
|
29
26
|
"main": "dist/cjs/index.js",
|
|
30
|
-
"files": [
|
|
27
|
+
"files": [
|
|
28
|
+
"dist/",
|
|
29
|
+
"LICENSE"
|
|
30
|
+
],
|
|
31
31
|
"exports": {
|
|
32
32
|
".": {
|
|
33
33
|
"types": "./dist/types/index.d.ts",
|
|
@@ -57,9 +57,10 @@
|
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"@types/bun": "latest",
|
|
60
|
+
"typescript": "^7.1.0-dev.20261114.1",
|
|
60
61
|
"zod": "^4.6.7"
|
|
61
62
|
},
|
|
62
63
|
"peerDependencies": {
|
|
63
|
-
"typescript": "^7"
|
|
64
|
+
"typescript": "^7.1.0-0"
|
|
64
65
|
}
|
|
65
66
|
}
|