rado 1.0.14 → 1.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.
Files changed (81) hide show
  1. package/dist/compat.d.ts +3 -3
  2. package/dist/compat.js +2 -0
  3. package/dist/core/Builder.d.ts +14 -9
  4. package/dist/core/Builder.js +24 -32
  5. package/dist/core/Column.d.ts +13 -4
  6. package/dist/core/Column.js +43 -8
  7. package/dist/core/Constraint.d.ts +16 -5
  8. package/dist/core/Constraint.js +17 -6
  9. package/dist/core/Database.d.ts +11 -4
  10. package/dist/core/Database.js +20 -4
  11. package/dist/core/Dialect.js +2 -2
  12. package/dist/core/Driver.d.ts +3 -3
  13. package/dist/core/Emitter.d.ts +7 -29
  14. package/dist/core/Emitter.js +31 -139
  15. package/dist/core/Index.d.ts +1 -1
  16. package/dist/core/Internal.d.ts +5 -4
  17. package/dist/core/Queries.d.ts +46 -0
  18. package/dist/core/{Query.js → Queries.js} +10 -8
  19. package/dist/core/Resolver.d.ts +2 -2
  20. package/dist/core/Selection.d.ts +7 -10
  21. package/dist/core/Selection.js +21 -22
  22. package/dist/core/Sql.d.ts +8 -29
  23. package/dist/core/Sql.js +67 -118
  24. package/dist/core/Table.d.ts +7 -3
  25. package/dist/core/Table.js +24 -8
  26. package/dist/core/Virtual.d.ts +1 -1
  27. package/dist/core/Virtual.js +15 -14
  28. package/dist/core/expr/Conditions.d.ts +4 -4
  29. package/dist/core/expr/Conditions.js +18 -8
  30. package/dist/core/expr/Field.d.ts +8 -6
  31. package/dist/core/expr/Field.js +3 -3
  32. package/dist/core/expr/Include.d.ts +10 -7
  33. package/dist/core/expr/Include.js +29 -12
  34. package/dist/core/expr/Input.d.ts +3 -1
  35. package/dist/core/expr/Input.js +24 -7
  36. package/dist/core/expr/Json.js +2 -2
  37. package/dist/core/query/CTE.d.ts +8 -0
  38. package/dist/core/query/CTE.js +33 -0
  39. package/dist/core/query/Delete.d.ts +14 -13
  40. package/dist/core/query/Delete.js +32 -6
  41. package/dist/core/query/Insert.d.ts +17 -36
  42. package/dist/core/query/Insert.js +121 -72
  43. package/dist/core/query/Query.d.ts +124 -0
  44. package/dist/core/query/Select.d.ts +74 -33
  45. package/dist/core/query/Select.js +255 -57
  46. package/dist/core/query/Shared.d.ts +3 -0
  47. package/dist/core/query/Shared.js +23 -0
  48. package/dist/core/query/Update.d.ts +13 -13
  49. package/dist/core/query/Update.js +51 -22
  50. package/dist/driver/d1.d.ts +2 -2
  51. package/dist/driver/libsql.d.ts +2 -2
  52. package/dist/driver/mysql2.d.ts +2 -2
  53. package/dist/driver/pg.d.ts +2 -2
  54. package/dist/driver/pglite.d.ts +2 -2
  55. package/dist/index.d.ts +7 -7
  56. package/dist/index.js +7 -7
  57. package/dist/mysql/columns.d.ts +37 -37
  58. package/dist/mysql/columns.js +32 -15
  59. package/dist/mysql/dialect.js +6 -7
  60. package/dist/mysql/diff.js +2 -1
  61. package/dist/mysql.d.ts +3 -2
  62. package/dist/mysql.js +11 -2
  63. package/dist/postgres/columns.d.ts +13 -13
  64. package/dist/postgres/columns.js +15 -6
  65. package/dist/postgres/dialect.js +6 -7
  66. package/dist/postgres/diff.js +2 -1
  67. package/dist/postgres.d.ts +3 -2
  68. package/dist/postgres.js +11 -2
  69. package/dist/sqlite/columns.d.ts +16 -1
  70. package/dist/sqlite/columns.js +36 -3
  71. package/dist/sqlite/dialect.js +6 -6
  72. package/dist/sqlite/diff.js +3 -5
  73. package/dist/sqlite.d.ts +3 -2
  74. package/dist/sqlite.js +11 -2
  75. package/dist/universal/functions.js +4 -1
  76. package/package.json +4 -4
  77. package/dist/core/Join.d.ts +0 -1
  78. package/dist/core/Query.d.ts +0 -46
  79. package/dist/core/query/Union.d.ts +0 -35
  80. package/dist/core/query/Union.js +0 -107
  81. /package/dist/core/{Join.js → query/Query.js} +0 -0
@@ -1,14 +1,7 @@
1
1
  // src/core/Emitter.ts
2
- import {
3
- getData,
4
- getQuery,
5
- getTable,
6
- getTarget
7
- } from "./Internal.js";
2
+ import { getSql } from "./Internal.js";
8
3
  import { ValueParam } from "./Param.js";
9
- import { Sql, sql } from "./Sql.js";
10
- import { callFunction } from "./expr/Functions.js";
11
- import { jsonAggregateArray, jsonArray } from "./expr/Json.js";
4
+ import { Sql } from "./Sql.js";
12
5
  var Emitter = class {
13
6
  #runtime;
14
7
  sql = "";
@@ -32,150 +25,49 @@ var Emitter = class {
32
25
  }
33
26
  emitIdentifierOrSelf(value) {
34
27
  if (value === Sql.SELF_TARGET) {
35
- if (!this.selfName) throw new Error("Self target not defined");
36
- this.emitIdentifier(this.selfName);
28
+ if (!this.#selfName) throw new Error("Self target not defined");
29
+ this.emitIdentifier(this.#selfName);
37
30
  } else {
38
31
  this.emitIdentifier(value);
39
32
  }
40
33
  }
41
- selfName;
42
- emitSelf({ name, inner }) {
43
- this.selfName = name;
44
- inner.emitTo(this);
45
- this.selfName = void 0;
46
- }
47
34
  emitUnsafe(value) {
48
35
  this.sql += value;
49
36
  }
37
+ #selfName;
38
+ emitSelf(inner, name) {
39
+ this.#selfName = name;
40
+ inner.emit(this);
41
+ this.#selfName = void 0;
42
+ }
43
+ #inlineFields = false;
44
+ inlineFields(inner, withTableName) {
45
+ const previous = this.#inlineFields;
46
+ this.#inlineFields = !withTableName;
47
+ inner.emit(this);
48
+ this.#inlineFields = previous;
49
+ }
50
+ #inlineValues = false;
51
+ inlineValues(inner) {
52
+ const previous = this.#inlineValues;
53
+ this.#inlineValues = true;
54
+ inner.emit(this);
55
+ this.#inlineValues = previous;
56
+ }
50
57
  emitField({ targetName, fieldName }) {
58
+ if (this.#inlineFields) return this.emitIdentifier(fieldName);
51
59
  this.emitIdentifierOrSelf(targetName);
52
60
  this.emitUnsafe(".");
53
61
  this.emitIdentifier(fieldName);
54
62
  }
55
- emitCreateTable(tableApi) {
56
- sql.join([
57
- sql`create table`,
58
- //ifNotExists ? sql`if not exists` : undefined,
59
- tableApi.target(),
60
- sql`(${tableApi.createDefinition()})`
61
- ]).emitTo(this);
62
- }
63
- emitColumn(column) {
64
- sql.join([
65
- column.type,
66
- column.primary && sql`primary key`,
67
- column.notNull && sql`not null`,
68
- column.isUnique && sql`unique`,
69
- column.autoIncrement && sql`autoincrement`,
70
- column.defaultValue && sql`default ${column.defaultValue}`,
71
- column.references && sql`references ${sql.chunk("emitReferences", [column.references()])}`,
72
- column.onUpdate && sql`on update ${column.onUpdate}`
73
- ]).emitTo(this);
74
- }
75
- emitReferences(fields) {
76
- callFunction(
77
- sql.identifier(fields[0].targetName),
78
- fields.map((field) => sql.identifier(field.fieldName))
79
- ).emitTo(this);
80
- }
81
- emitDelete(deleteOp) {
82
- const { cte, from, where, returning } = getData(deleteOp);
83
- if (cte) this.emitWith(cte);
84
- const table = getTable(from);
85
- sql.query({
86
- deleteFrom: sql.identifier(table.name),
87
- where,
88
- returning
89
- }).emitTo(this);
90
- }
91
- emitInsert(insert) {
92
- const {
93
- cte,
94
- into,
95
- values,
96
- select,
97
- onConflict,
98
- onDuplicateKeyUpdate,
99
- returning
100
- } = getData(insert);
101
- if (cte) this.emitWith(cte);
102
- const table = getTable(into);
103
- const tableName = sql.identifier(table.name);
104
- sql.query({
105
- insertInto: sql`${tableName}(${table.listColumns()})`,
106
- ...values ? { values } : { "": select },
107
- onConflict,
108
- onDuplicateKeyUpdate,
109
- returning
110
- }).inlineFields(false).emitTo(this);
111
- }
112
- emitSelect({
113
- select,
114
- cte,
115
- from,
116
- distinct,
117
- distinctOn,
118
- where,
119
- groupBy,
120
- orderBy,
121
- having,
122
- limit,
123
- offset
124
- }) {
125
- if (cte) this.emitWith(cte);
126
- const prefix = distinctOn ? sql`distinct on (${sql.join(distinctOn, sql`, `)})` : distinct && sql`distinct`;
127
- sql.query({
128
- select: sql.join([prefix, select]),
129
- from,
130
- where,
131
- groupBy,
132
- orderBy,
133
- having,
134
- limit,
135
- offset
136
- }).emitTo(this);
137
- }
138
- emitUnion({ left, operator, right }) {
139
- sql.join([getQuery(left), operator, getQuery(right)]).emitTo(this);
140
- }
141
- emitUpdate(update) {
142
- const { cte, table, set, where, returning } = getData(update);
143
- const tableApi = getTable(table);
144
- if (cte) this.emitWith(cte);
145
- sql.query({
146
- update: sql.identifier(tableApi.name),
147
- set,
148
- where,
149
- returning
150
- }).inlineFields(false).emitTo(this);
151
- }
152
- emitWith(cte) {
153
- sql.query({
154
- [cte.recursive ? "withRecursive" : "with"]: sql.join(
155
- cte.definitions.map((cte2) => {
156
- const query = getQuery(cte2);
157
- const target = getTarget(cte2);
158
- return sql`${target} as (${query})`;
159
- }),
160
- sql`, `
161
- )
162
- }).add(sql` `).emitTo(this);
163
- }
164
- emitInclude(data) {
165
- const wrapQuery = Boolean(data.limit || data.offset || data.orderBy);
166
- const innerQuery = sql.chunk("emitSelect", data);
167
- const inner = wrapQuery ? sql`select * from (${innerQuery})` : innerQuery;
168
- if (!data.select) throw new Error("No selection defined");
169
- const fields = data.select.fieldNames();
170
- const subject = jsonArray(
171
- ...fields.map((name) => sql`_.${sql.identifier(name)}`)
172
- );
173
- sql`(select ${data.first ? subject : jsonAggregateArray(subject)} from (${inner}) as _)`.emitTo(this);
63
+ emitValueOrInline(value) {
64
+ if (this.#inlineValues) this.emitInline(value);
65
+ else this.emitValue(value);
174
66
  }
175
67
  emitUniversal(runtimes) {
176
- const sql2 = runtimes[this.#runtime] ?? runtimes.default;
177
- if (!sql2) throw new Error("Unsupported runtime");
178
- sql2.emitTo(this);
68
+ const sql = runtimes[this.#runtime] ?? runtimes.default;
69
+ if (!sql) throw new Error("Unsupported runtime");
70
+ getSql(sql).emit(this);
179
71
  }
180
72
  };
181
73
  export {
@@ -1,4 +1,4 @@
1
- import { internalData, type HasData, type HasSql } from './Internal.js';
1
+ import { type HasData, type HasSql, internalData } from './Internal.js';
2
2
  import { type Sql } from './Sql.js';
3
3
  import type { Field } from './expr/Field.js';
4
4
  declare class IndexData {
@@ -24,16 +24,17 @@ export declare class HasSql<Value = unknown> {
24
24
  export declare class HasSelection {
25
25
  get [internalSelection](): Selection;
26
26
  }
27
- export declare class HasTarget {
27
+ export declare class HasTarget<Name extends string = string> {
28
28
  get [internalTarget](): Sql;
29
+ private brand?;
29
30
  }
30
- export declare class HasQuery {
31
- get [internalQuery](): Sql;
31
+ export declare class HasQuery<Result = unknown> {
32
+ get [internalQuery](): Sql<Result>;
32
33
  }
33
34
  export declare class HasBatch {
34
35
  get [internalBatch](): Array<Sql>;
35
36
  }
36
- export declare class HasTable<Definition extends TableDefinition = TableDefinition, Name extends string = string> {
37
+ export declare class HasTable<Definition extends TableDefinition = TableDefinition, Name extends string = string> extends HasTarget<Name> {
37
38
  get [internalTable](): TableApi<Definition, Name>;
38
39
  }
39
40
  export declare class HasField {
@@ -0,0 +1,46 @@
1
+ import { type HasQuery, type HasResolver, type HasSql, internalData, internalQuery } from './Internal.js';
2
+ import type { Deliver, QueryMeta } from './MetaData.js';
3
+ import type { PreparedStatement, Resolver } from './Resolver.js';
4
+ import type { Sql } from './Sql.js';
5
+ export declare class QueryData<Meta extends QueryMeta> {
6
+ resolver?: Resolver<Meta>;
7
+ first?: boolean;
8
+ }
9
+ type Exec = Function;
10
+ declare class Executable<Result, Meta extends QueryMeta> implements PromiseLike<Result> {
11
+ #private;
12
+ private brand;
13
+ constructor(exec: Exec);
14
+ [Symbol.iterator](): Generator<Promise<unknown>, Result, unknown>;
15
+ run(): Deliver<Meta, void>;
16
+ then<TResult1 = Result, TResult2 = never>(onfulfilled?: ((value: Result) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
17
+ catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | undefined | null): Promise<Result | TResult>;
18
+ finally(onfinally?: (() => void) | undefined | null): Promise<Result>;
19
+ }
20
+ export declare class BatchQuery<Results, Meta extends QueryMeta> extends Executable<Array<Results>, Meta> {
21
+ constructor(queryResolver: Resolver, queries: Array<HasSql | HasQuery>);
22
+ }
23
+ export declare abstract class SingleQuery<Result, Meta extends QueryMeta> extends Executable<Result, Meta> {
24
+ #private;
25
+ readonly [internalData]: QueryData<Meta>;
26
+ abstract [internalQuery]: Sql;
27
+ constructor(data: QueryData<Meta>);
28
+ all<Result extends Array<unknown>>(this: SingleQuery<Result, Meta>, db?: HasResolver): Deliver<Meta, Result>;
29
+ get<Result extends Array<unknown>>(this: SingleQuery<Result, Meta>, db?: HasResolver): Deliver<Meta, Result[number] | null>;
30
+ get(db?: HasResolver): Deliver<Meta, Result | null>;
31
+ run(db?: HasResolver): Deliver<Meta, void>;
32
+ prepare<Inputs extends Record<string, unknown>>(name?: string): PreparedQuery<Result, Inputs, Meta>;
33
+ toSQL(db?: HasResolver): {
34
+ sql: string;
35
+ params: Array<unknown>;
36
+ };
37
+ }
38
+ export interface PreparedQuery<Result, Inputs extends Record<string, unknown>, Meta extends QueryMeta> extends PreparedStatement<Meta> {
39
+ all<Result extends Array<unknown>>(this: PreparedQuery<Result, Inputs, Meta>, inputs?: Inputs): Deliver<Meta, Result>;
40
+ get(inputs?: Inputs): Deliver<Meta, Result>;
41
+ get<Result extends Array<unknown>>(this: PreparedQuery<Result, Inputs, Meta>, inputs?: Inputs): Deliver<Meta, Result[number] | null>;
42
+ run(inputs?: Inputs): Deliver<Meta, void>;
43
+ execute(inputs?: Inputs): Promise<Result>;
44
+ free(): void;
45
+ }
46
+ export {};
@@ -1,4 +1,4 @@
1
- // src/core/Query.ts
1
+ // src/core/Queries.ts
2
2
  import {
3
3
  getData,
4
4
  getResolver,
@@ -7,7 +7,7 @@ import {
7
7
  } from "./Internal.js";
8
8
  var QueryData = class {
9
9
  resolver;
10
- cte;
10
+ first;
11
11
  };
12
12
  var Executable = class {
13
13
  #execute;
@@ -41,14 +41,14 @@ var Executable = class {
41
41
  return this.then().finally(onfinally);
42
42
  }
43
43
  };
44
- var QueryBatch = class extends Executable {
44
+ var BatchQuery = class extends Executable {
45
45
  constructor(queryResolver, queries) {
46
46
  super(() => {
47
47
  return queryResolver.batch(queries).execute();
48
48
  });
49
49
  }
50
50
  };
51
- var Query = class extends Executable {
51
+ var SingleQuery = class extends Executable {
52
52
  [internalData];
53
53
  constructor(data) {
54
54
  super(() => this.#exec(void 0));
@@ -57,9 +57,11 @@ var Query = class extends Executable {
57
57
  #exec(method, db) {
58
58
  const data = getData(this);
59
59
  const resolver = db ? getResolver(db) : data.resolver;
60
+ if (!resolver) throw new Error("Query has no resolver");
60
61
  const isSelection = hasSelection(this);
62
+ const isFirst = data.first;
61
63
  const prepared = resolver.prepare(this, "");
62
- const resultType = method ?? (isSelection ? "all" : "run");
64
+ const resultType = method ?? (isSelection ? isFirst ? "get" : "all" : "run");
63
65
  try {
64
66
  const result = prepared[resultType]();
65
67
  if (result instanceof Promise)
@@ -90,7 +92,7 @@ var Query = class extends Executable {
90
92
  }
91
93
  };
92
94
  export {
93
- Query,
94
- QueryBatch,
95
- QueryData
95
+ BatchQuery,
96
+ QueryData,
97
+ SingleQuery
96
98
  };
@@ -1,5 +1,5 @@
1
1
  import type { Dialect } from './Dialect.js';
2
- import type { BatchQuery, Driver, DriverSpecs, Statement } from './Driver.js';
2
+ import type { BatchedQuery, Driver, DriverSpecs, Statement } from './Driver.js';
3
3
  import type { Emitter } from './Emitter.js';
4
4
  import { type HasQuery, type HasSql } from './Internal.js';
5
5
  import type { QueryMeta } from './MetaData.js';
@@ -16,7 +16,7 @@ export declare class Resolver<Meta extends QueryMeta = QueryMeta> {
16
16
  batch(queries: Array<HasSql | HasQuery>): Batch<Meta>;
17
17
  }
18
18
  type RowMapper = ((ctx: MapRowContext) => unknown) | undefined;
19
- interface QueryWithMapRow extends BatchQuery {
19
+ interface QueryWithMapRow extends BatchedQuery {
20
20
  mapRow: RowMapper;
21
21
  }
22
22
  export declare class Batch<Meta extends QueryMeta> {
@@ -1,10 +1,10 @@
1
1
  import type { DriverSpecs } from './Driver.js';
2
2
  import { type HasSql, type HasTable, type HasTarget, internalSql } from './Internal.js';
3
- import type { JoinOperator } from './Join.js';
4
3
  import { type Sql } from './Sql.js';
5
4
  import type { Table, TableRow } from './Table.js';
6
5
  import type { Expand } from './Types.js';
7
6
  import type { Include } from './expr/Include.js';
7
+ import type { JoinOp } from './query/Query.js';
8
8
  declare const nullable: unique symbol;
9
9
  export interface SelectionRecord extends Record<string, SelectionInput> {
10
10
  }
@@ -14,7 +14,7 @@ export type IsNullable = {
14
14
  export type MakeNullable<T> = Expand<{
15
15
  [K in keyof T]: T[K] & IsNullable;
16
16
  }>;
17
- export type SelectionInput = HasSql | HasTable | SelectionRecord | Include<unknown>;
17
+ export type SelectionInput = HasSql | HasTable | HasTarget | SelectionRecord | Include<unknown>;
18
18
  export type RowOfRecord<Input> = Expand<{
19
19
  [Key in keyof Input as Key extends string ? Key : never]: SelectionRow<Input[Key]>;
20
20
  }>;
@@ -29,24 +29,21 @@ export declare class Selection implements HasSql {
29
29
  input: SelectionInput;
30
30
  nullable: Set<string>;
31
31
  mapRow: (ctx: MapRowContext) => unknown;
32
- constructor(input: SelectionInput, nullable: Set<string>);
32
+ constructor(input: SelectionInput, nullable?: Set<string>);
33
33
  makeVirtual<Input>(name: string): Input & HasTarget;
34
34
  fieldNames(): Array<string>;
35
35
  get [internalSql](): Sql;
36
- join(right: HasTable, operator: JoinOperator): Selection;
36
+ join(right: HasTarget | Sql, operator: JoinOp): Selection;
37
37
  }
38
38
  export declare class TableSelection extends Selection {
39
39
  table: HasTable;
40
40
  constructor(table: HasTable);
41
- join(right: HasTable, operator: JoinOperator): Selection;
41
+ join(right: HasTarget | Sql, operator: JoinOp): Selection;
42
42
  }
43
43
  export declare class JoinSelection extends Selection {
44
44
  tables: Array<HasTable>;
45
45
  constructor(tables: Array<HasTable>, nullable: Set<string>);
46
- join(right: HasTable, operator: JoinOperator): Selection;
47
- }
48
- export declare function selection(input: SelectionInput, nullable?: Array<string>): Selection;
49
- export declare namespace selection {
50
- function table(table: HasTable): TableSelection;
46
+ join(right: HasTarget | Sql, operator: JoinOp): Selection;
51
47
  }
48
+ export declare function selection(input: SelectionInput): Selection;
52
49
  export {};
@@ -4,6 +4,7 @@ import {
4
4
  getSql,
5
5
  getTable,
6
6
  hasField,
7
+ hasTable,
7
8
  internalSql
8
9
  } from "./Internal.js";
9
10
  import { sql } from "./Sql.js";
@@ -46,7 +47,7 @@ var ObjectColumn = class {
46
47
  }
47
48
  };
48
49
  var Selection = class {
49
- constructor(input, nullable) {
50
+ constructor(input, nullable = /* @__PURE__ */ new Set()) {
50
51
  this.input = input;
51
52
  this.nullable = nullable;
52
53
  const root = this.#defineColumn(nullable, input);
@@ -91,21 +92,18 @@ var Selection = class {
91
92
  names.add(exprName);
92
93
  if (hasField(input)) {
93
94
  const field = getField(input);
94
- if (field.fieldName === exprName) return expr;
95
+ if (field.fieldName === exprName) return [expr];
95
96
  }
96
- return sql`${expr.forSelection()} as ${sql.identifier(exprName)}`;
97
+ return [sql`${expr.forSelection()} as ${sql.identifier(exprName)}`];
97
98
  }
98
- return expr;
99
+ return [expr];
99
100
  }
100
- return sql.join(
101
- Object.entries(input).map(
102
- ([name2, value]) => this.#selectionToSql(value, names, name2)
103
- ),
104
- sql`, `
101
+ return Object.entries(input).flatMap(
102
+ ([name2, value]) => this.#selectionToSql(value, names, name2)
105
103
  );
106
104
  }
107
105
  get [internalSql]() {
108
- return this.#selectionToSql(this.input, /* @__PURE__ */ new Set());
106
+ return sql.join(this.#selectionToSql(this.input, /* @__PURE__ */ new Set()), sql`, `);
109
107
  }
110
108
  join(right, operator) {
111
109
  return this;
@@ -118,11 +116,12 @@ var TableSelection = class extends Selection {
118
116
  }
119
117
  join(right, operator) {
120
118
  const leftTable = getTable(this.table);
119
+ if (!hasTable(right)) return this;
121
120
  const rightTable = getTable(right);
122
121
  const nullable = new Set(this.nullable);
123
- if (operator === "right" || operator === "full")
122
+ if (operator === "rightJoin" || operator === "fullJoin")
124
123
  nullable.add(leftTable.aliased);
125
- if (operator === "left" || operator === "full")
124
+ if (operator === "leftJoin" || operator === "fullJoin")
126
125
  nullable.add(rightTable.aliased);
127
126
  return new JoinSelection([this.table, right], nullable);
128
127
  }
@@ -136,24 +135,24 @@ var JoinSelection = class _JoinSelection extends Selection {
136
135
  this.tables = tables;
137
136
  }
138
137
  join(right, operator) {
138
+ if (!hasTable(right)) return this;
139
139
  const rightTable = getTable(right);
140
140
  const nullable = new Set(this.nullable);
141
- if (operator === "right" || operator === "full")
141
+ if (operator === "rightJoin" || operator === "fullJoin")
142
142
  this.tables.map((table) => getTable(table).aliased).forEach(nullable.add, nullable);
143
- if (operator === "left" || operator === "full")
143
+ if (operator === "leftJoin" || operator === "fullJoin")
144
144
  nullable.add(rightTable.aliased);
145
145
  return new _JoinSelection([...this.tables, right], nullable);
146
146
  }
147
147
  };
148
- function selection(input, nullable = []) {
149
- return new Selection(input, new Set(nullable));
148
+ var selected = /* @__PURE__ */ new WeakMap();
149
+ function selection(input) {
150
+ if (input instanceof Selection) return input;
151
+ if (selected.has(input)) return selected.get(input);
152
+ const selection2 = hasTable(input) ? new TableSelection(input) : new Selection(input);
153
+ selected.set(input, selection2);
154
+ return selection2;
150
155
  }
151
- ((selection2) => {
152
- function table(table2) {
153
- return new TableSelection(table2);
154
- }
155
- selection2.table = table;
156
- })(selection || (selection = {}));
157
156
  export {
158
157
  JoinSelection,
159
158
  Selection,
@@ -4,42 +4,23 @@ import { type HasSql, internalSql } from './Internal.js';
4
4
  import type { Runtime } from './MetaData.js';
5
5
  import type { FieldData } from './expr/Field.js';
6
6
  import type { JsonPath } from './expr/Json.js';
7
- type EmitMethods = {
8
- [K in keyof Emitter as K extends `emit${string}` ? K : never]: Emitter[K];
9
- };
10
- declare class Chunk<Type = keyof EmitMethods, Inner = unknown> {
11
- type: Type;
12
- inner: Inner;
13
- constructor(type: Type, inner: Inner);
14
- }
15
- export type Decoder<T> = ((value: unknown) => T) | {
7
+ export type Decoder<T = unknown> = ((value: unknown) => T) | {
16
8
  mapFromDriverValue?(value: unknown, specs: DriverSpecs): T;
17
9
  };
18
10
  export declare class Sql<Value = unknown> implements HasSql<Value> {
19
- #private;
11
+ emit: (emitter: Emitter) => void;
20
12
  static SELF_TARGET: string;
21
13
  private brand;
22
14
  alias?: string;
23
15
  mapFromDriverValue?: (input: unknown, specs: DriverSpecs) => Value;
24
16
  readonly [internalSql]: this;
25
- constructor(chunks?: Array<Chunk>);
17
+ constructor(emit?: (emitter: Emitter) => void);
26
18
  as(name: string): Sql<Value>;
27
19
  mapWith<T = Value>(decoder: Decoder<T>): Sql<T>;
28
- chunk<Type extends keyof EmitMethods>(type: Type, inner: Parameters<EmitMethods[Type]>[0]): Sql<Value>;
29
- unsafe(sql: string): Sql<Value>;
30
- field(field: FieldData): Sql<Value>;
31
- add(sql: HasSql): Sql<Value>;
32
- value(value: unknown): Sql<Value>;
33
- getValue(): Value | undefined;
34
- inline(value: unknown): Sql<Value>;
35
- jsonPath(path: JsonPath): Sql<Value>;
36
- forSelection(): Sql<Value>;
37
- placeholder(name: string): Sql<Value>;
38
- identifier(identifier: string): Sql<Value>;
39
- inlineValues(): Sql<Value>;
40
20
  inlineFields(withTableName: boolean): Sql<Value>;
41
- nameSelf(name: string): Sql;
42
- emitTo(emitter: Emitter): void;
21
+ inlineValues(): Sql<Value>;
22
+ nameSelf(name: string): Sql<Value>;
23
+ forSelection(): Sql<Value>;
43
24
  }
44
25
  export declare function sql<T>(strings: TemplateStringsArray, ...inner: Array<HasSql | unknown>): Sql<T>;
45
26
  export declare namespace sql {
@@ -51,11 +32,9 @@ export declare namespace sql {
51
32
  export function identifier<T>(identifier: string): Sql<T>;
52
33
  export function field<T>(field: FieldData): Sql<T>;
53
34
  export function jsonPath<T>(path: JsonPath): Sql<T>;
54
- export function chunk<Type extends keyof EmitMethods>(type: Type, inner: Parameters<EmitMethods[Type]>[0]): Sql;
55
- export function universal<T>(runtimes: Partial<Record<Runtime | 'default', Sql<T>>>): Sql<T>;
35
+ export function universal<T>(runtimes: Partial<Record<Runtime | 'default', HasSql<T>>>): Sql<T>;
56
36
  type QueryChunk = HasSql | undefined;
57
- export function query(ast: Record<string, boolean | QueryChunk | Array<QueryChunk>>): Sql;
37
+ export function query(...chunks: Array<QueryChunk | Record<string, boolean | QueryChunk | Array<QueryChunk>>>): Sql;
58
38
  export function join<T>(items: Array<Sql | HasSql | undefined | false>, separator?: Sql): Sql<T>;
59
39
  export {};
60
40
  }
61
- export {};