@ultimabase/postgres 0.0.0-stage → 0.1.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/CHANGELOG.md +12 -0
- package/README.md +4 -2
- package/dist/adapter.d.ts +26 -0
- package/dist/adapter.d.ts.map +1 -0
- package/dist/adapter.js +254 -0
- package/dist/aggregate.d.ts +8 -0
- package/dist/aggregate.d.ts.map +1 -0
- package/dist/aggregate.js +138 -0
- package/dist/decode.d.ts +5 -0
- package/dist/decode.d.ts.map +1 -0
- package/dist/decode.js +30 -0
- package/dist/fills.d.ts +16 -0
- package/dist/fills.d.ts.map +1 -0
- package/dist/fills.js +37 -0
- package/dist/filter.d.ts +50 -0
- package/dist/filter.d.ts.map +1 -0
- package/dist/filter.js +247 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/json-filter.d.ts +12 -0
- package/dist/json-filter.d.ts.map +1 -0
- package/dist/json-filter.js +65 -0
- package/dist/listen.d.ts +10 -0
- package/dist/listen.d.ts.map +1 -0
- package/dist/listen.js +92 -0
- package/dist/logic.d.ts +7 -0
- package/dist/logic.d.ts.map +1 -0
- package/dist/logic.js +18 -0
- package/dist/migrations.d.ts +23 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +217 -0
- package/dist/names.d.ts +66 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +175 -0
- package/dist/notify.d.ts +19 -0
- package/dist/notify.d.ts.map +1 -0
- package/dist/notify.js +75 -0
- package/dist/numbers.d.ts +13 -0
- package/dist/numbers.d.ts.map +1 -0
- package/dist/numbers.js +49 -0
- package/dist/parts.d.ts +36 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/parts.js +99 -0
- package/dist/plan-indexes.d.ts +12 -0
- package/dist/plan-indexes.d.ts.map +1 -0
- package/dist/plan-indexes.js +49 -0
- package/dist/plan-parts.d.ts +16 -0
- package/dist/plan-parts.d.ts.map +1 -0
- package/dist/plan-parts.js +9 -0
- package/dist/plan.d.ts +6 -0
- package/dist/plan.d.ts.map +1 -0
- package/dist/plan.js +278 -0
- package/dist/pool.d.ts +5 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +41 -0
- package/dist/read.d.ts +47 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/read.js +227 -0
- package/dist/scratch.d.ts +22 -0
- package/dist/scratch.d.ts.map +1 -0
- package/dist/scratch.js +77 -0
- package/dist/snapshot.d.ts +66 -0
- package/dist/snapshot.d.ts.map +1 -0
- package/dist/snapshot.js +272 -0
- package/dist/write.d.ts +17 -0
- package/dist/write.d.ts.map +1 -0
- package/dist/write.js +296 -0
- package/package.json +45 -3
- package/src/adapter.ts +349 -0
- package/src/aggregate.ts +168 -0
- package/src/decode.ts +46 -0
- package/src/fills.ts +52 -0
- package/src/filter.ts +306 -0
- package/src/index.ts +20 -0
- package/src/json-filter.ts +74 -0
- package/src/listen.ts +97 -0
- package/src/logic.ts +28 -0
- package/src/migrations.ts +275 -0
- package/src/names.ts +217 -0
- package/src/notify.ts +101 -0
- package/src/numbers.ts +64 -0
- package/src/parts.ts +143 -0
- package/src/plan-indexes.ts +100 -0
- package/src/plan-parts.ts +35 -0
- package/src/plan.ts +389 -0
- package/src/pool.ts +63 -0
- package/src/read.ts +287 -0
- package/src/scratch.ts +92 -0
- package/src/snapshot.ts +390 -0
- package/src/write.ts +384 -0
package/dist/write.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RawBuilder } from 'kysely';
|
|
2
|
+
import type { Write } from 'ultimabase';
|
|
3
|
+
import type { Catalog } from './names.ts';
|
|
4
|
+
/** A statement of a write: how many checks its result carries, `c0`… */
|
|
5
|
+
export type Statement = {
|
|
6
|
+
readonly sql: RawBuilder<{
|
|
7
|
+
readonly [column: string]: unknown;
|
|
8
|
+
}>;
|
|
9
|
+
readonly checks: number;
|
|
10
|
+
};
|
|
11
|
+
/** The statements of a write, in the order they run. */
|
|
12
|
+
export declare function compileWrite(catalog: Catalog, write: Write,
|
|
13
|
+
/** Where the feed's notifications go, when it has a taker (D-154). */
|
|
14
|
+
channel?: string): Statement[];
|
|
15
|
+
/** A constraint's refusal as the kernel's error; any other as is. */
|
|
16
|
+
export declare function translate(catalog: Catalog, error: unknown): unknown;
|
|
17
|
+
//# sourceMappingURL=write.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../src/write.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AAExC,OAAO,KAAK,EAAoC,KAAK,EAAE,MAAM,YAAY,CAAA;AAIzE,OAAO,KAAK,EAAE,OAAO,EAAS,MAAM,YAAY,CAAA;AAOhD,wEAAwE;AACxE,MAAM,MAAM,SAAS,GAAG;IACvB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;QAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAC,CAAA;IAChE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACvB,CAAA;AAyMD,wDAAwD;AACxD,wBAAgB,YAAY,CAC3B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,KAAK;AACZ,sEAAsE;AACtE,OAAO,CAAC,EAAE,MAAM,GACd,SAAS,EAAE,CAsHb;AAkBD,qEAAqE;AACrE,wBAAgB,SAAS,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAenE"}
|
package/dist/write.js
ADDED
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { sql } from 'kysely';
|
|
2
|
+
import { RelationViolation, UniqueViolation } from 'ultimabase';
|
|
3
|
+
import { Filters, uuid, value } from './filter.js';
|
|
4
|
+
import { computed } from './numbers.js';
|
|
5
|
+
import { fieldsOf, grouped, inserted, sizeOf } from './parts.js';
|
|
6
|
+
import { notifying, pairs as linked, rows as noted } from './notify.js';
|
|
7
|
+
import { compileRows } from './read.js';
|
|
8
|
+
function assignments(catalog, table, values) {
|
|
9
|
+
return Object.entries(values)
|
|
10
|
+
.filter(([, item]) => item !== undefined)
|
|
11
|
+
.map(([name, item]) => [
|
|
12
|
+
catalog.column(table, name),
|
|
13
|
+
value(catalog.kind(table, name), item),
|
|
14
|
+
]);
|
|
15
|
+
}
|
|
16
|
+
const and = (gate) => gate === undefined ? sql `` : sql ` and ${gate}`;
|
|
17
|
+
/** The id a filter selects by `{ id: { equals } }` alone, if any. */
|
|
18
|
+
function idOf(where) {
|
|
19
|
+
if (where === undefined || Object.keys(where).length !== 1)
|
|
20
|
+
return undefined;
|
|
21
|
+
const id = where['id'];
|
|
22
|
+
if (typeof id !== 'object' || id === null || Object.keys(id).length !== 1) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return 'equals' in id && typeof id.equals === 'string' ? id.equals : undefined;
|
|
26
|
+
}
|
|
27
|
+
/** The CTE of a change, `undefined` when it changes nothing. */
|
|
28
|
+
function part(catalog, change, removed) {
|
|
29
|
+
if (change.kind !== 'update' && change.kind !== 'delete') {
|
|
30
|
+
return links(catalog, change);
|
|
31
|
+
}
|
|
32
|
+
const table = catalog.table(change.model);
|
|
33
|
+
const name = sql.id(table.name);
|
|
34
|
+
const base = { table: table.name, key: ['id'] };
|
|
35
|
+
const filters = new Filters(catalog, removed);
|
|
36
|
+
const named = filters.alias();
|
|
37
|
+
const alias = sql.id(named);
|
|
38
|
+
const where = filters.where(change.model, named, change.where);
|
|
39
|
+
const reads = new Set([table.name, ...filters.tables]);
|
|
40
|
+
if (change.kind === 'update') {
|
|
41
|
+
const fields = [
|
|
42
|
+
...Object.keys(change.set),
|
|
43
|
+
...Object.keys(change.compute ?? {}),
|
|
44
|
+
];
|
|
45
|
+
const set = sql.join([
|
|
46
|
+
...assignments(catalog, table, change.set).map(([column, item]) => sql `${sql.id(column)} = ${item}`),
|
|
47
|
+
...computed(catalog, table, change.compute),
|
|
48
|
+
]);
|
|
49
|
+
const row = idOf(change.where);
|
|
50
|
+
return {
|
|
51
|
+
...base,
|
|
52
|
+
...(row === undefined ? {} : { row }),
|
|
53
|
+
build: (gate) => sql `update ${name} as ${alias} set ${set} where ${where}${and(gate)} returning ${alias}.*`,
|
|
54
|
+
inserts: false,
|
|
55
|
+
removes: true,
|
|
56
|
+
adds: true,
|
|
57
|
+
reads,
|
|
58
|
+
noted: noted('update', change.model, fields),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
...base,
|
|
63
|
+
build: (gate) => sql `delete from ${name} as ${alias} where ${where}${and(gate)} returning ${alias}.*`,
|
|
64
|
+
inserts: false,
|
|
65
|
+
removes: true,
|
|
66
|
+
adds: false,
|
|
67
|
+
reads,
|
|
68
|
+
noted: noted('delete', change.model),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** A link or unlink of nothing, or of ids no row has, changes nothing. */
|
|
72
|
+
function links(catalog, change) {
|
|
73
|
+
const join = catalog.join(change.model, change.field);
|
|
74
|
+
const name = sql.id(join.table);
|
|
75
|
+
const self = sql.id(join.self);
|
|
76
|
+
const other = sql.id(join.other);
|
|
77
|
+
const key = [join.self, join.other].toSorted();
|
|
78
|
+
const id = sql `cast(${change.id} as uuid)`;
|
|
79
|
+
// The same pair, whichever side names it.
|
|
80
|
+
const pairOf = (target) => key[0] === join.self ? `${change.id}:${target}` : `${target}:${change.id}`;
|
|
81
|
+
const pairs = (targets) => ({
|
|
82
|
+
table: join.table,
|
|
83
|
+
key,
|
|
84
|
+
reads: new Set(),
|
|
85
|
+
pairs: new Set(targets.map(pairOf)),
|
|
86
|
+
noted: linked(change.kind, change.model, change.field, join.self, join.other),
|
|
87
|
+
});
|
|
88
|
+
if (change.kind === 'unlink') {
|
|
89
|
+
const targets = change.targets.filter((target) => uuid.test(target));
|
|
90
|
+
if (targets.length === 0)
|
|
91
|
+
return undefined;
|
|
92
|
+
const list = sql.join(targets.map((target) => sql `cast(${target} as uuid)`));
|
|
93
|
+
return {
|
|
94
|
+
...pairs(targets),
|
|
95
|
+
build: (gate) => sql `delete from ${name} where ${self} = ${id} and ${other} in (${list})${and(gate)} returning *`,
|
|
96
|
+
inserts: false,
|
|
97
|
+
removes: true,
|
|
98
|
+
adds: false,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
if (change.targets.length === 0)
|
|
102
|
+
return undefined;
|
|
103
|
+
const rows = sql.join(change.targets.map((target) => sql `(${id}, cast(${target} as uuid))`));
|
|
104
|
+
return {
|
|
105
|
+
...pairs(change.targets),
|
|
106
|
+
build: (gate) => {
|
|
107
|
+
const source = gate === undefined
|
|
108
|
+
? sql `values ${rows}`
|
|
109
|
+
: sql `select * from (values ${rows}) as "v" where ${gate}`;
|
|
110
|
+
return sql `insert into ${name} (${self}, ${other}) ${source} on conflict do nothing returning *`;
|
|
111
|
+
},
|
|
112
|
+
inserts: true,
|
|
113
|
+
removes: false,
|
|
114
|
+
adds: true,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function checking(catalog, checks) {
|
|
118
|
+
const filters = new Filters(catalog);
|
|
119
|
+
const columns = checks.map((check, at) => {
|
|
120
|
+
const table = sql.id(catalog.table(check.model).name);
|
|
121
|
+
const alias = filters.alias();
|
|
122
|
+
const where = filters.where(check.model, alias, check.where);
|
|
123
|
+
// A locked row is counted as it is after any wait for its lock.
|
|
124
|
+
const rows = sql `${table} as ${sql.id(alias)} where ${where}`;
|
|
125
|
+
const from = check.lock ? sql `(select from ${rows} for update) as t` : rows;
|
|
126
|
+
return sql `(select count(*) from ${from}) = ${check.count} as ${sql.id(`c${at}`)}`;
|
|
127
|
+
});
|
|
128
|
+
return sql `select ${sql.join(columns)}`;
|
|
129
|
+
}
|
|
130
|
+
const cteName = (at) => `#w${at}`;
|
|
131
|
+
const cte = (at) => sql.id(cteName(at));
|
|
132
|
+
/** Each written table as the read sees it: the changed rows in place. */
|
|
133
|
+
function views(parts) {
|
|
134
|
+
const tables = new Map();
|
|
135
|
+
for (const [at, each] of parts) {
|
|
136
|
+
tables.set(each.table, [...(tables.get(each.table) ?? []), [at, each]]);
|
|
137
|
+
}
|
|
138
|
+
return [...tables].map(([table, written]) => {
|
|
139
|
+
const name = sql.id(table);
|
|
140
|
+
const key = written[0]?.[1].key ?? [];
|
|
141
|
+
const keys = sql.join(key.map((column) => sql.id(column)));
|
|
142
|
+
const removed = written
|
|
143
|
+
.filter(([, each]) => each.removes)
|
|
144
|
+
.map(([at]) => sql `select ${keys} from ${cte(at)}`);
|
|
145
|
+
const kept = removed.length === 0
|
|
146
|
+
? sql `select * from ${name}`
|
|
147
|
+
: sql `select * from ${name} where (${keys}) not in (${sql.join(removed, sql ` union all `)})`;
|
|
148
|
+
const added = written
|
|
149
|
+
.filter(([, each]) => each.adds)
|
|
150
|
+
.map(([at]) => sql `select * from ${cte(at)}`);
|
|
151
|
+
const body = sql.join([kept, ...added], sql ` union all `);
|
|
152
|
+
return sql `${name} as not materialized (${body})`;
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The change of a statement that writes the one row `read` selects, when no
|
|
157
|
+
* other change of it writes that table: the read takes the row from its
|
|
158
|
+
* RETURNING rather than from the table's view (D-103).
|
|
159
|
+
*/
|
|
160
|
+
function sourceOf(catalog, read, parts) {
|
|
161
|
+
const id = idOf(read.where);
|
|
162
|
+
const table = catalog.table(read.model).name;
|
|
163
|
+
const written = [...parts].filter(([, each]) => each.table === table);
|
|
164
|
+
const [only] = written;
|
|
165
|
+
return id !== undefined && written.length === 1 && only?.[1].row === id
|
|
166
|
+
? only[0]
|
|
167
|
+
: undefined;
|
|
168
|
+
}
|
|
169
|
+
/** The statements of a write, in the order they run. */
|
|
170
|
+
export function compileWrite(catalog, write,
|
|
171
|
+
/** Where the feed's notifications go, when it has a taker (D-154). */
|
|
172
|
+
channel) {
|
|
173
|
+
const checks = write.checks ?? [];
|
|
174
|
+
// Each statement stays within PostgreSQL's 65,535 parameters, its checks
|
|
175
|
+
// and its read's aside.
|
|
176
|
+
const room = 65_535 -
|
|
177
|
+
sizeOf(checking(catalog, checks)) -
|
|
178
|
+
(write.read === undefined
|
|
179
|
+
? 0
|
|
180
|
+
: sizeOf(compileRows(catalog, write.read, undefined).rows));
|
|
181
|
+
const parts = [];
|
|
182
|
+
const removed = new Map();
|
|
183
|
+
// Consecutive rows of a table, setting the same fields, go in one insert.
|
|
184
|
+
let batch;
|
|
185
|
+
const flush = () => {
|
|
186
|
+
if (batch !== undefined) {
|
|
187
|
+
parts.push(inserted(catalog, batch.model, batch.rows));
|
|
188
|
+
}
|
|
189
|
+
batch = undefined;
|
|
190
|
+
};
|
|
191
|
+
for (const [index, change] of write.changes.entries()) {
|
|
192
|
+
if (change.kind === 'insert') {
|
|
193
|
+
const fields = fieldsOf(change.row);
|
|
194
|
+
const joins = batch?.model === change.model &&
|
|
195
|
+
fieldsOf(batch.rows[0] ?? {})
|
|
196
|
+
.toSorted()
|
|
197
|
+
.join() === fields.toSorted().join() &&
|
|
198
|
+
(batch.rows.length + 1) * fields.length <= room;
|
|
199
|
+
if (!joins) {
|
|
200
|
+
flush();
|
|
201
|
+
batch = { model: change.model, rows: [] };
|
|
202
|
+
}
|
|
203
|
+
batch?.rows.push(change.row);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
flush();
|
|
207
|
+
const each = part(catalog, change, removed);
|
|
208
|
+
if (each === undefined)
|
|
209
|
+
continue;
|
|
210
|
+
if (change.kind === 'delete')
|
|
211
|
+
removed.set(index, cteName(parts.length));
|
|
212
|
+
parts.push(each);
|
|
213
|
+
}
|
|
214
|
+
flush();
|
|
215
|
+
if (parts.length === 0 && checks.length === 0 && write.read === undefined) {
|
|
216
|
+
return [];
|
|
217
|
+
}
|
|
218
|
+
const columns = checks.map((_, at) => sql.id(`c${at}`));
|
|
219
|
+
const gate = checks.length === 0
|
|
220
|
+
? undefined
|
|
221
|
+
: sql `(select ${sql.join(columns, sql ` and `)} from "#checks")`;
|
|
222
|
+
const groups = grouped(parts, room);
|
|
223
|
+
const before = write.before === true;
|
|
224
|
+
const table = write.read && catalog.table(write.read.model).name;
|
|
225
|
+
// With `before`, the read runs beside its model's delete (D-104), or,
|
|
226
|
+
// when the write deletes nothing of it, its update (D-133).
|
|
227
|
+
const of = (adds) => parts.findIndex((each) => before && each.table === table && each.removes && each.adds === adds);
|
|
228
|
+
const deleted = of(false);
|
|
229
|
+
const removal = deleted === -1 ? of(true) : deleted;
|
|
230
|
+
let next = 0;
|
|
231
|
+
return groups.map((group, index) => {
|
|
232
|
+
const first = index === 0 && checks.length > 0;
|
|
233
|
+
const numbered = new Map(group.map((each) => [next++, each]));
|
|
234
|
+
const ctes = [...numbered].map(([at, each]) => sql `${cte(at)} as (${each.build(first ? gate : undefined)})`);
|
|
235
|
+
const reads = before ? numbered.has(removal) : index === groups.length - 1;
|
|
236
|
+
const read = reads ? write.read : undefined;
|
|
237
|
+
const seen = read !== undefined && !before;
|
|
238
|
+
const source = seen ? sourceOf(catalog, read, numbered) : removal;
|
|
239
|
+
const compiled = read === undefined
|
|
240
|
+
? undefined
|
|
241
|
+
: compileRows(catalog, read, source === undefined ? undefined : cte(source));
|
|
242
|
+
const fed = channel !== undefined && numbered.size > 0;
|
|
243
|
+
const selected = [
|
|
244
|
+
...(first ? columns : []),
|
|
245
|
+
...(compiled === undefined ? [] : [sql `${compiled.rows} as "rows"`]),
|
|
246
|
+
// Referenced, the CTE runs.
|
|
247
|
+
...(fed ? [sql `(select count(*) from "#feed") as "fed"`] : []),
|
|
248
|
+
];
|
|
249
|
+
// The root's table needs no view when only its RETURNING is read.
|
|
250
|
+
const root = read === undefined ? '' : catalog.table(read.model).name;
|
|
251
|
+
const viewed = [...numbered].filter(([, each]) => source === undefined ||
|
|
252
|
+
each.table !== root ||
|
|
253
|
+
compiled?.tables.has(root) === true);
|
|
254
|
+
const all = [
|
|
255
|
+
...(first ? [sql `"#checks" as (${checking(catalog, checks)})`] : []),
|
|
256
|
+
...ctes,
|
|
257
|
+
...(seen ? views(new Map(viewed)) : []),
|
|
258
|
+
...(fed
|
|
259
|
+
? [
|
|
260
|
+
notifying(channel, [...numbered].map(([at, each]) => [cte(at), each.noted])),
|
|
261
|
+
]
|
|
262
|
+
: []),
|
|
263
|
+
];
|
|
264
|
+
const list = selected.length === 0 ? sql `1 as "one"` : sql.join(selected);
|
|
265
|
+
const body = sql `select ${list}${first ? sql ` from "#checks"` : sql ``}`;
|
|
266
|
+
return {
|
|
267
|
+
sql: all.length === 0 ? sql `${body}` : sql `with ${sql.join(all)} ${body}`,
|
|
268
|
+
checks: first ? checks.length : 0,
|
|
269
|
+
};
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
function isRefusal(error) {
|
|
273
|
+
return (error instanceof Error &&
|
|
274
|
+
'code' in error &&
|
|
275
|
+
typeof error.code === 'string' &&
|
|
276
|
+
'constraint' in error &&
|
|
277
|
+
typeof error.constraint === 'string');
|
|
278
|
+
}
|
|
279
|
+
/** A constraint's refusal as the kernel's error; any other as is. */
|
|
280
|
+
export function translate(catalog, error) {
|
|
281
|
+
if (!isRefusal(error))
|
|
282
|
+
return error;
|
|
283
|
+
if (error.code === '23505') {
|
|
284
|
+
const unique = catalog.uniques.get(error.constraint);
|
|
285
|
+
if (unique !== undefined) {
|
|
286
|
+
return new UniqueViolation(unique.model, unique.fields);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const key = catalog.foreignKeys.get(error.constraint);
|
|
290
|
+
if (error.code === '23503' && key !== undefined) {
|
|
291
|
+
// Only the message tells the deleting side from the linking one.
|
|
292
|
+
const restricted = error.message.startsWith('update or delete');
|
|
293
|
+
return new RelationViolation(key.model, key.field, key.target, restricted);
|
|
294
|
+
}
|
|
295
|
+
return error;
|
|
296
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimabase/postgres",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The PostgreSQL adapter for UltimaBase.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"homepage": "https://ultimabase.dev/docs/postgres",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/MrEkinox/ultimabase.git",
|
|
11
|
+
"directory": "packages/postgres"
|
|
12
|
+
},
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=24.7.0"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"files": [
|
|
20
|
+
"dist",
|
|
21
|
+
"src",
|
|
22
|
+
"!src/**/*.test.ts",
|
|
23
|
+
"!src/test"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"prepack": "rm -rf dist && yarn run -T tsc --project tsconfig.build.json"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"exports": {
|
|
30
|
+
".": "./dist/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"kysely": "0.29.6",
|
|
35
|
+
"pg": "8.23.1",
|
|
36
|
+
"pg-connection-string": "2.14.1"
|
|
37
|
+
},
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"ultimabase": "^0.1.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/pg": "8.23.1",
|
|
43
|
+
"@ultimabase/testing": "0.1.0",
|
|
44
|
+
"ultimabase": "0.1.0",
|
|
45
|
+
"vite": "8.3.4",
|
|
46
|
+
"vitest": "5.0.5"
|
|
47
|
+
}
|
|
6
48
|
}
|