@rwillians/exto 0.1.1 → 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.
@@ -0,0 +1,438 @@
1
+ import * as std from './standard-schema';
2
+ import { ValidationError } from './standard-schema';
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';
6
+ type ColumnProps<S extends std.Schema = std.Schema> = {
7
+ type: Primitive;
8
+ schema: S;
9
+ default?: unknown;
10
+ generated?: true;
11
+ length?: number;
12
+ precision?: number;
13
+ scale?: number;
14
+ nullable?: true;
15
+ primaryKey?: true;
16
+ unique?: true;
17
+ fields?: Columns;
18
+ many?: true;
19
+ };
20
+ type Column<K extends string = string, P extends ColumnProps = ColumnProps> = P & {
21
+ key: K;
22
+ name: string;
23
+ input: std.input<P['schema']>;
24
+ output: std.output<P['schema']>;
25
+ };
26
+ type Columns = Record<string, Column>;
27
+ declare class ColumnBuilder<P extends ColumnProps> {
28
+ readonly props: P;
29
+ constructor(props: P);
30
+ default(value: std.output<P['schema']> | (() => std.output<P['schema']>)): ColumnBuilder<Expand<P & {
31
+ default: typeof value;
32
+ }>>;
33
+ generated(): ColumnBuilder<Expand<P & {
34
+ generated: true;
35
+ }>>;
36
+ optional(): ColumnBuilder<Expand<Omit<P, "schema"> & {
37
+ nullable: true;
38
+ schema: std.Schema<std.input<P['schema']> | null, std.output<P['schema']> | null>;
39
+ }>>;
40
+ primaryKey(): ColumnBuilder<Expand<P & {
41
+ primaryKey: true;
42
+ }>>;
43
+ unique(): ColumnBuilder<Expand<P & {
44
+ unique: true;
45
+ }>>;
46
+ unsigned(this: ColumnBuilder<P & {
47
+ type: 'INTEGER';
48
+ }>): ColumnBuilder<P>;
49
+ }
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
+ }>;
75
+ declare const types: {
76
+ bigint: () => ColumnBuilder<{
77
+ type: "BIGINT";
78
+ schema: std.Schema<bigint, bigint>;
79
+ }>;
80
+ binary: () => ColumnBuilder<{
81
+ type: "BINARY";
82
+ schema: std.Schema<Uint8Array<ArrayBuffer>, Uint8Array<ArrayBuffer>>;
83
+ }>;
84
+ boolean: () => ColumnBuilder<{
85
+ type: "BOOLEAN";
86
+ schema: std.Schema<boolean, boolean>;
87
+ }>;
88
+ citext: () => ColumnBuilder<{
89
+ type: "CITEXT";
90
+ schema: std.Schema<string, string>;
91
+ }>;
92
+ date: () => ColumnBuilder<{
93
+ type: "DATE";
94
+ schema: std.Schema<string, string>;
95
+ }>;
96
+ decimal: (options?: {
97
+ precision: number;
98
+ scale: number;
99
+ }) => ColumnBuilder<{
100
+ precision?: number | undefined;
101
+ scale?: number | undefined;
102
+ type: "DECIMAL";
103
+ schema: std.Schema<number, number>;
104
+ }>;
105
+ enum: <const T extends readonly [string, ...string[]]>(values: T) => ColumnBuilder<{
106
+ type: "STRING";
107
+ schema: std.Schema<T[number], T[number]>;
108
+ length: number;
109
+ }>;
110
+ float: () => ColumnBuilder<{
111
+ type: "FLOAT";
112
+ schema: std.Schema<number, number>;
113
+ }>;
114
+ integer: () => ColumnBuilder<{
115
+ type: "INTEGER";
116
+ schema: std.Schema<number, number>;
117
+ }>;
118
+ json: <S extends std.Schema>(schema: S) => ColumnBuilder<{
119
+ type: "JSON";
120
+ schema: S;
121
+ }>;
122
+ record: () => ColumnBuilder<{
123
+ type: "JSON";
124
+ schema: std.Schema<Record<string, unknown>, Record<string, unknown>>;
125
+ }>;
126
+ sequence: () => ColumnBuilder<{
127
+ type: "SEQUENCE";
128
+ schema: std.Schema<number, number>;
129
+ generated: true;
130
+ }>;
131
+ string: ({ size }?: {
132
+ size?: number;
133
+ }) => ColumnBuilder<{
134
+ type: "STRING";
135
+ schema: std.Schema<string, string>;
136
+ length: number;
137
+ }>;
138
+ text: () => ColumnBuilder<{
139
+ type: "TEXT";
140
+ schema: std.Schema<string, string>;
141
+ }>;
142
+ timestamp: () => ColumnBuilder<{
143
+ type: "TIMESTAMP";
144
+ schema: std.Schema<string | number | Date, Date>;
145
+ }>;
146
+ uuidv7: () => ColumnBuilder<{
147
+ type: "UUID";
148
+ schema: std.Schema<string, string>;
149
+ }>;
150
+ };
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';
160
+ alias: string;
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;
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;
211
+ type OmitOnInsert = {
212
+ generated: true;
213
+ };
214
+ type OptionalOnInsert = {
215
+ default: unknown;
216
+ } | {
217
+ nullable: true;
218
+ };
219
+ type OmitOnUpdate = {
220
+ generated: true;
221
+ } | {
222
+ primaryKey: true;
223
+ };
224
+ type InferForSelect<C extends Columns> = Expand<{
225
+ [K in keyof C]: C[K]['output'];
226
+ }>;
227
+ type InferForInsert<C extends Columns> = Expand<{
228
+ [K in keyof C as C[K] extends OmitOnInsert | OptionalOnInsert ? never : K]: C[K]['input'];
229
+ } & {
230
+ [K in keyof C as C[K] extends OmitOnInsert ? never : C[K] extends OptionalOnInsert ? K : never]?: C[K]['input'];
231
+ }>;
232
+ type InferForUpdate<C extends Columns> = Expand<{
233
+ [K in keyof C as C[K] extends OmitOnUpdate ? never : K]?: C[K]['input'];
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];
240
+ type NumericKeys<C extends Columns> = {
241
+ [K in keyof C]: C[K] extends OmitOnUpdate ? never : C[K]['type'] extends NumericType ? K : never;
242
+ }[keyof C];
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;
252
+ };
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>;
255
+ type Codec = {
256
+ encode: (value: any) => unknown;
257
+ decode: (value: any) => unknown;
258
+ };
259
+ type DialectName = 'postgres' | 'sqlite' | (string & {});
260
+ /**
261
+ * Everything that differs between database engines. SQL generation, param
262
+ * collection, validation and encoding/decoding all live in the core.
263
+ *
264
+ * `generated` returns the DDL that makes the database generate the column's
265
+ * value, or `undefined` when the database can't natively, in which case the
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).
271
+ */
272
+ interface Dialect {
273
+ name: DialectName;
274
+ placeholder(index: number): string;
275
+ type(column: Column): string;
276
+ generated(column: Column): string | undefined;
277
+ json(sql: string, path: string[], type: Primitive): string;
278
+ codecs: Record<Primitive, Codec>;
279
+ }
280
+ interface ILogger {
281
+ debug(sql: string, params: unknown[]): void;
282
+ error(sql: string, params: unknown[], error: unknown): void;
283
+ }
284
+ type Row = Record<string, unknown>;
285
+ interface IDatabase {
286
+ readonly dialect: Dialect;
287
+ readonly loggers: ILogger[];
288
+ execute(sql: string, params: unknown[]): Promise<Row[]>;
289
+ transaction<T>(fn: (tx: IDatabase) => Promise<T>): Promise<T>;
290
+ }
291
+ declare const exec: (db: IDatabase, sql: string, params?: unknown[]) => Promise<void>;
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>>;
315
+ };
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>;
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>>;
329
+ type Changes<C extends Columns> = {
330
+ set?: InferForUpdate<C>;
331
+ inc?: {
332
+ [K in NumericKeys<C>]?: number;
333
+ };
334
+ };
335
+ type Conflict<C extends Columns> = {
336
+ on: (keyof C & string)[];
337
+ do: 'nothing' | 'throw' | (Changes<C> & {
338
+ replace?: (keyof InferForUpdate<C> & string)[];
339
+ });
340
+ };
341
+ type InsertOptions<C extends Columns> = {
342
+ conflict?: Conflict<C>;
343
+ };
344
+ declare class InsertBuilder<T extends Table> {
345
+ private readonly table;
346
+ private readonly rows;
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>> & {
350
+ returning?: true;
351
+ }): Promise<InferForSelect<ColumnsOf<T>>[]>;
352
+ insert(db: IDatabase, options: InsertOptions<ColumnsOf<T>> & {
353
+ returning: false;
354
+ }): Promise<undefined>;
355
+ insert<R extends Returnable<T>>(db: IDatabase, options: InsertOptions<ColumnsOf<T>> & {
356
+ returning: R[];
357
+ }): Promise<Returned<T, R>[]>;
358
+ private renderConflict;
359
+ }
360
+ declare const into: <T extends Table>(table: T) => InsertBuilder<T>;
361
+ type Direction = 'ASC' | 'DESC';
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][];
374
+ limit?: number;
375
+ offset?: number;
376
+ };
377
+ declare class QueryBuilder<T extends Table, A extends string = AliasOf<T>, N extends string = never, R = InferForSelect<ColumnsOf<T>>> {
378
+ private readonly query;
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>;
390
+ exists(db: IDatabase): Promise<boolean>;
391
+ count(db: IDatabase): Promise<number>;
392
+ update(db: IDatabase, changes: Changes<ColumnsOf<T>> & {
393
+ returning: false;
394
+ }): Promise<undefined>;
395
+ update<K extends Returnable<T>>(db: IDatabase, changes: Changes<ColumnsOf<T>> & {
396
+ returning: K[];
397
+ }): Promise<Returned<T, K>[]>;
398
+ update(db: IDatabase, changes: Changes<ColumnsOf<T>> & {
399
+ returning?: true;
400
+ }): Promise<InferForSelect<ColumnsOf<T>>[]>;
401
+ delete(db: IDatabase, options: {
402
+ returning: true;
403
+ }): Promise<InferForSelect<ColumnsOf<T>>[]>;
404
+ delete<K extends Returnable<T>>(db: IDatabase, options: {
405
+ returning: K[];
406
+ }): Promise<Returned<T, K>[]>;
407
+ delete(db: IDatabase, options?: {
408
+ returning?: false;
409
+ }): Promise<undefined>;
410
+ private fields;
411
+ private renderSelect;
412
+ private top;
413
+ private assertPlain;
414
+ }
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>>;
416
+ type IndexOptions = {
417
+ ifNotExists?: boolean;
418
+ name?: string;
419
+ };
420
+ declare const createIndex: <T extends Table>(table: T, keys: Keys<T>[], { ifNotExists, name, unique, }?: IndexOptions & {
421
+ unique?: boolean;
422
+ }) => {
423
+ onto: (db: IDatabase) => Promise<void>;
424
+ };
425
+ declare const create: {
426
+ table: (table: Table, { ifNotExists }?: {
427
+ ifNotExists?: boolean;
428
+ }) => {
429
+ onto: (db: IDatabase) => Promise<void>;
430
+ };
431
+ index: typeof createIndex;
432
+ uniqueIndex: <T extends Table>(table: T, keys: Keys<T>[], options?: IndexOptions) => {
433
+ onto: (db: IDatabase) => Promise<void>;
434
+ };
435
+ };
436
+ type Migration = (db: IDatabase) => Promise<void>;
437
+ declare const defineMigrations: (migrations: Record<string, Migration>) => (db: IDatabase) => Promise<void>;
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, };
@@ -0,0 +1,180 @@
1
+ interface StandardSchemaV1<Input = unknown, Output = Input> {
2
+ readonly "~standard": StandardSchemaV1.Props<Input, Output>;
3
+ }
4
+ declare namespace StandardSchemaV1 {
5
+ export interface Props<Input = unknown, Output = Input> {
6
+ readonly version: 1;
7
+ readonly vendor: string;
8
+ readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
9
+ readonly types?: Types<Input, Output> | undefined;
10
+ }
11
+ export type Result<Output> = SuccessResult<Output> | FailureResult;
12
+ export interface SuccessResult<Output> {
13
+ readonly value: Output;
14
+ readonly issues?: undefined;
15
+ }
16
+ export interface FailureResult {
17
+ readonly issues: ReadonlyArray<Issue>;
18
+ }
19
+ export interface Issue {
20
+ readonly message: string;
21
+ readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
22
+ }
23
+ export interface PathSegment {
24
+ readonly key: PropertyKey;
25
+ }
26
+ export interface Types<Input = unknown, Output = Input> {
27
+ readonly input: Input;
28
+ readonly output: Output;
29
+ }
30
+ export type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
31
+ export type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
32
+ export {};
33
+ }
34
+ /**
35
+ * @public The Standard Schema interface.
36
+ * @since 0.1.0
37
+ * @version 1
38
+ */
39
+ export { type StandardSchemaV1 as Schema };
40
+ /**
41
+ * @public Infers the input type of a Standard Schema.
42
+ * @since 0.1.0
43
+ * @version 1
44
+ */
45
+ export type input<T extends StandardSchemaV1> = StandardSchemaV1.InferInput<T>;
46
+ /**
47
+ * @public Infers the output type of a Standard Schema.
48
+ * @since 0.1.0
49
+ * @version 1
50
+ */
51
+ export type output<T extends StandardSchemaV1> = StandardSchemaV1.InferOutput<T>;
52
+ /**
53
+ * @public Thrown when a value fails validation, carrying every issue found.
54
+ * @since 0.1.0
55
+ * @version 1
56
+ */
57
+ export declare class ValidationError extends Error {
58
+ readonly issues: ReadonlyArray<StandardSchemaV1.Issue>;
59
+ constructor(issues: ReadonlyArray<StandardSchemaV1.Issue>);
60
+ }
61
+ /**
62
+ * @public Use any standard schema to parse a value.
63
+ * @since 0.1.0
64
+ * @version 1
65
+ */
66
+ export declare const parse: <T extends StandardSchemaV1>(schema: T, value: unknown) => StandardSchemaV1.Result<output<T>>;
67
+ /**
68
+ * @public Like {@link parse}, but returns the value or throws a
69
+ * {@link ValidationError}.
70
+ * @since 0.1.0
71
+ * @version 1
72
+ */
73
+ export declare const parseOrThrow: <T extends StandardSchemaV1>(schema: T, value: unknown) => output<T>;
74
+ /**
75
+ * @public Defines an array of a given standard schema.
76
+ * @since 0.1.0
77
+ * @version 1
78
+ */
79
+ export declare const array: <T extends StandardSchemaV1>(schema: T) => StandardSchemaV1<input<T>[], output<T>[]>;
80
+ /**
81
+ * @public Defines a standard schema for bigints.
82
+ * @since 0.1.0
83
+ * @version 1
84
+ */
85
+ export declare const bigint: () => StandardSchemaV1<bigint, bigint>;
86
+ /**
87
+ * @public Defines a standard schema for boolean values.
88
+ * @since 0.1.0
89
+ * @version 1
90
+ */
91
+ export declare const boolean: () => StandardSchemaV1<boolean, boolean>;
92
+ /**
93
+ * @public Defines a standard schema for dates, coercing ISO 8601 strings
94
+ * and epoch timestamps (in milliseconds) into `Date`.
95
+ * @since 0.1.0
96
+ * @version 1
97
+ */
98
+ export declare const date: () => StandardSchemaV1<string | number | Date, Date>;
99
+ /**
100
+ * @public Defines a standard schema for one of the given string values.
101
+ * @since 0.1.0
102
+ * @version 1
103
+ */
104
+ export declare const enumOf: <const T extends readonly string[]>(values: T) => StandardSchemaV1<T[number], T[number]>;
105
+ /**
106
+ * @public Defines a standard schema for instances of a given class.
107
+ * @since 0.1.0
108
+ * @version 1
109
+ */
110
+ export declare const instanceOf: <T>(ctor: new (...args: any[]) => T) => StandardSchemaV1<T, T>;
111
+ /**
112
+ * @public Defines a standard schema for integers, within the safe integer
113
+ * range by default.
114
+ * @since 0.1.0
115
+ * @version 1
116
+ */
117
+ export declare const integer: ({ min, max }?: {
118
+ max?: number | undefined;
119
+ min?: number | undefined;
120
+ }) => StandardSchemaV1<number, number>;
121
+ /**
122
+ * @public Defines a standard schema for calendar dates as `YYYY-MM-DD`
123
+ * strings.
124
+ * @since 0.1.0
125
+ * @version 1
126
+ */
127
+ export declare const isoDate: () => StandardSchemaV1<string, string>;
128
+ /**
129
+ * @public Makes a given standard schema accept `null`.
130
+ * @since 0.1.0
131
+ * @version 1
132
+ */
133
+ export declare const nullable: <T extends StandardSchemaV1>(schema: T) => StandardSchemaV1<input<T> | null, output<T> | null>;
134
+ /**
135
+ * @public Defines a standard schema for finite numbers.
136
+ * @since 0.1.0
137
+ * @version 1
138
+ */
139
+ export declare const number: () => StandardSchemaV1<number, number>;
140
+ /**
141
+ * @public Makes a given standard schema accept `undefined`.
142
+ * @since 0.1.0
143
+ * @version 1
144
+ */
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>>;
152
+ /**
153
+ * @public Defines a standard schema for strings, optionally limited in
154
+ * length.
155
+ * @since 0.1.0
156
+ * @version 1
157
+ */
158
+ export declare const string: ({ max }?: {
159
+ max?: number;
160
+ }) => StandardSchemaV1<string, string>;
161
+ /**
162
+ * @public Defines a standard schema for objects of a given shape. Keys
163
+ * missing from the shape are rejected, keys missing from the input
164
+ * are validated as `undefined`.
165
+ * @since 0.1.0
166
+ * @version 1
167
+ */
168
+ type Expand<T> = T extends object ? {
169
+ [K in keyof T]: T[K];
170
+ } : never;
171
+ type OptionalKeys<T extends Record<string, StandardSchemaV1>> = {
172
+ [K in keyof T]: undefined extends input<T[K]> ? K : never;
173
+ }[keyof T];
174
+ export declare const strictObject: <T extends Record<string, StandardSchemaV1>>(shape: T) => StandardSchemaV1<Expand<{ [K in Exclude<keyof T, OptionalKeys<T>>]: input<T[K]>; } & { [K in OptionalKeys<T>]?: input<T[K]> | undefined; }>, Expand<{ [K in Exclude<keyof T, OptionalKeys<T>>]: output<T[K]>; } & { [K in OptionalKeys<T>]?: output<T[K]> | undefined; }>>;
175
+ /**
176
+ * @public Defines a standard schema for UUID strings (any version).
177
+ * @since 0.1.0
178
+ * @version 1
179
+ */
180
+ export declare const uuid: () => StandardSchemaV1<string, string>;
@@ -0,0 +1,11 @@
1
+ type Ctor<T> = new (...args: any[]) => T;
2
+ export type Expand<T> = T extends object ? {
3
+ [K in keyof T]: T[K];
4
+ } : never;
5
+ export type CamelCase<S extends string> = S extends `${infer T}_${infer U}` ? `${T}${Capitalize<CamelCase<U>>}` : S;
6
+ export declare const camelCase: <T extends string>(str: T) => CamelCase<T>;
7
+ export declare const snakeCase: (str: string) => string;
8
+ export declare const wrap: <T>(value: T | T[]) => T[];
9
+ export declare function raise(message: string, cause?: Error): never;
10
+ export declare function raise(ctor: Ctor<Error>, message: string, cause?: Error): never;
11
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rwillians/exto",
3
- "description": "A zero-dependencies teeny tiny ORM for SQL databases.",
4
- "version": "0.1.1",
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
- "orm",
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": ["dist/", "LICENSE"],
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
  }
package/dist/.gitignore DELETED
@@ -1,2 +0,0 @@
1
- *
2
- !.gitignore