@kernhq/module-quire 0.5.0 → 0.6.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/dist/contract/properties.d.ts +2 -0
- package/dist/contract/properties.d.ts.map +1 -1
- package/dist/contract/properties.js.map +1 -1
- package/dist/contract/router.d.ts +1101 -0
- package/dist/contract/router.d.ts.map +1 -1
- package/dist/contract/router.js +88 -0
- package/dist/contract/router.js.map +1 -1
- package/dist/server/_impl.d.ts +1182 -0
- package/dist/server/_impl.d.ts.map +1 -1
- package/dist/server/_impl.js +113 -0
- package/dist/server/_impl.js.map +1 -1
- package/dist/server/schema.d.ts +51 -0
- package/dist/server/schema.d.ts.map +1 -1
- package/dist/server/schema.js +15 -0
- package/dist/server/schema.js.map +1 -1
- package/dist/server/services/access.d.ts +3 -0
- package/dist/server/services/access.d.ts.map +1 -1
- package/dist/server/services/databases.d.ts +330 -0
- package/dist/server/services/databases.d.ts.map +1 -0
- package/dist/server/services/databases.js +515 -0
- package/dist/server/services/databases.js.map +1 -0
- package/dist/server/services/index.d.ts +3 -0
- package/dist/server/services/index.d.ts.map +1 -1
- package/dist/server/services/index.js +3 -0
- package/dist/server/services/index.js.map +1 -1
- package/dist/server/services/query.d.ts +13 -0
- package/dist/server/services/query.d.ts.map +1 -0
- package/dist/server/services/query.js +154 -0
- package/dist/server/services/query.js.map +1 -0
- package/dist/server/services/versions.d.ts +6 -0
- package/dist/server/services/versions.d.ts.map +1 -1
- package/migrations/0005_rows_are_pages.sql +6 -0
- package/migrations/meta/0004_snapshot.json +1 -1
- package/migrations/meta/0005_snapshot.json +1191 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/src/contract/properties.ts +2 -0
- package/src/contract/router.ts +115 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
import { KernError, uuidv7 } from '@kernhq/kernel';
|
|
2
|
+
import { and, asc, eq, inArray, isNull, sql } from 'drizzle-orm';
|
|
3
|
+
import { initialRank, rankBetween } from '../../client/rank.js';
|
|
4
|
+
import { evaluateFormula, formulaDependencies, parseFormula, } from '../formula.js';
|
|
5
|
+
import { databases, pages, properties, relations, views } from '../schema.js';
|
|
6
|
+
import { filterToSql, propertyFor, sortToSql } from './query.js';
|
|
7
|
+
export const toProperty = (r) => ({
|
|
8
|
+
id: r.id,
|
|
9
|
+
databaseId: r.databaseId,
|
|
10
|
+
key: r.key,
|
|
11
|
+
name: r.name,
|
|
12
|
+
type: r.type,
|
|
13
|
+
config: r.config,
|
|
14
|
+
position: r.position,
|
|
15
|
+
hidden: r.hidden,
|
|
16
|
+
});
|
|
17
|
+
export const toView = (r) => ({
|
|
18
|
+
id: r.id,
|
|
19
|
+
databaseId: r.databaseId,
|
|
20
|
+
name: r.name,
|
|
21
|
+
kind: r.kind,
|
|
22
|
+
config: r.config,
|
|
23
|
+
position: r.position,
|
|
24
|
+
isDefault: r.isDefault,
|
|
25
|
+
});
|
|
26
|
+
export const toRow = (p) => ({
|
|
27
|
+
id: p.id,
|
|
28
|
+
databaseId: p.databaseId ?? '',
|
|
29
|
+
title: p.title,
|
|
30
|
+
icon: p.icon,
|
|
31
|
+
props: (p.props ?? {}),
|
|
32
|
+
computed: (p.computed ?? {}),
|
|
33
|
+
createdBy: p.createdBy,
|
|
34
|
+
updatedBy: p.updatedBy,
|
|
35
|
+
createdAt: p.createdAt.toISOString(),
|
|
36
|
+
updatedAt: p.updatedAt.toISOString(),
|
|
37
|
+
});
|
|
38
|
+
/** A key derived from a name: what `props` is keyed by, so renaming a column keeps its data. */
|
|
39
|
+
function keyFrom(name, taken) {
|
|
40
|
+
const base = name
|
|
41
|
+
.toLowerCase()
|
|
42
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
43
|
+
.replace(/^_+|_+$/g, '')
|
|
44
|
+
.slice(0, 48) || 'field';
|
|
45
|
+
let key = base;
|
|
46
|
+
let n = 2;
|
|
47
|
+
while (taken.has(key))
|
|
48
|
+
key = `${base}_${n++}`;
|
|
49
|
+
return key;
|
|
50
|
+
}
|
|
51
|
+
export function quireDatabases(kernel, access) {
|
|
52
|
+
/** Parsed formulas, keyed by expression. Parsing is pure, so the cache never goes stale. */
|
|
53
|
+
const formulaCache = new Map();
|
|
54
|
+
const astFor = (expression) => {
|
|
55
|
+
const hit = formulaCache.get(expression);
|
|
56
|
+
if (hit)
|
|
57
|
+
return hit;
|
|
58
|
+
const ast = parseFormula(expression);
|
|
59
|
+
formulaCache.set(expression, ast);
|
|
60
|
+
return ast;
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
async get(tx, workspaceId, databaseId) {
|
|
64
|
+
const [db] = await tx
|
|
65
|
+
.select()
|
|
66
|
+
.from(databases)
|
|
67
|
+
.where(and(eq(databases.workspaceId, workspaceId), eq(databases.id, databaseId)))
|
|
68
|
+
.limit(1);
|
|
69
|
+
if (!db)
|
|
70
|
+
throw KernError.notFound('Database');
|
|
71
|
+
const [props, vs] = await Promise.all([
|
|
72
|
+
tx
|
|
73
|
+
.select()
|
|
74
|
+
.from(properties)
|
|
75
|
+
.where(and(eq(properties.workspaceId, workspaceId), eq(properties.databaseId, databaseId)))
|
|
76
|
+
.orderBy(asc(properties.position)),
|
|
77
|
+
tx
|
|
78
|
+
.select()
|
|
79
|
+
.from(views)
|
|
80
|
+
.where(and(eq(views.workspaceId, workspaceId), eq(views.databaseId, databaseId)))
|
|
81
|
+
.orderBy(asc(views.position)),
|
|
82
|
+
]);
|
|
83
|
+
return {
|
|
84
|
+
id: db.id,
|
|
85
|
+
workspaceId: db.workspaceId,
|
|
86
|
+
spaceId: db.spaceId,
|
|
87
|
+
pageId: db.pageId,
|
|
88
|
+
name: db.name,
|
|
89
|
+
description: db.description,
|
|
90
|
+
inline: db.inline,
|
|
91
|
+
properties: props.map(toProperty),
|
|
92
|
+
views: vs.map(toView),
|
|
93
|
+
createdAt: db.createdAt.toISOString(),
|
|
94
|
+
updatedAt: db.updatedAt.toISOString(),
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
/**
|
|
98
|
+
* Create a database on a page.
|
|
99
|
+
*
|
|
100
|
+
* It arrives with a title property and a table view, because a database with no columns and no
|
|
101
|
+
* view is a screen with nothing on it and no obvious way forward.
|
|
102
|
+
*/
|
|
103
|
+
async create(tx, principal, workspaceId, input) {
|
|
104
|
+
const id = uuidv7();
|
|
105
|
+
await tx.insert(databases).values({
|
|
106
|
+
id,
|
|
107
|
+
workspaceId,
|
|
108
|
+
spaceId: input.spaceId,
|
|
109
|
+
pageId: input.pageId,
|
|
110
|
+
name: input.name,
|
|
111
|
+
inline: input.inline,
|
|
112
|
+
});
|
|
113
|
+
await tx.insert(properties).values({
|
|
114
|
+
id: uuidv7(),
|
|
115
|
+
workspaceId,
|
|
116
|
+
databaseId: id,
|
|
117
|
+
key: 'name',
|
|
118
|
+
name: 'Name',
|
|
119
|
+
type: 'text',
|
|
120
|
+
config: {},
|
|
121
|
+
position: initialRank(),
|
|
122
|
+
});
|
|
123
|
+
await tx.insert(views).values({
|
|
124
|
+
id: uuidv7(),
|
|
125
|
+
workspaceId,
|
|
126
|
+
databaseId: id,
|
|
127
|
+
name: 'Table',
|
|
128
|
+
kind: 'table',
|
|
129
|
+
config: {},
|
|
130
|
+
position: initialRank(),
|
|
131
|
+
isDefault: true,
|
|
132
|
+
});
|
|
133
|
+
/**
|
|
134
|
+
* The host page is marked `database`, and deliberately does **not** get `database_id`.
|
|
135
|
+
*
|
|
136
|
+
* That column means "this page is a *row of* that database" and nothing else. Setting it here
|
|
137
|
+
* as well made the database's own page appear as the first row of itself — present in every
|
|
138
|
+
* view, with every cell empty, and impossible to explain.
|
|
139
|
+
*/
|
|
140
|
+
await tx
|
|
141
|
+
.update(pages)
|
|
142
|
+
.set({ kind: 'database', updatedBy: principal.userId, updatedAt: new Date() })
|
|
143
|
+
.where(and(eq(pages.workspaceId, workspaceId), eq(pages.id, input.pageId)));
|
|
144
|
+
return this.get(tx, workspaceId, id);
|
|
145
|
+
},
|
|
146
|
+
async addProperty(tx, workspaceId, databaseId, input) {
|
|
147
|
+
const existing = await tx
|
|
148
|
+
.select({ key: properties.key, position: properties.position })
|
|
149
|
+
.from(properties)
|
|
150
|
+
.where(and(eq(properties.workspaceId, workspaceId), eq(properties.databaseId, databaseId)))
|
|
151
|
+
.orderBy(asc(properties.position));
|
|
152
|
+
const [row] = await tx
|
|
153
|
+
.insert(properties)
|
|
154
|
+
.values({
|
|
155
|
+
id: uuidv7(),
|
|
156
|
+
workspaceId,
|
|
157
|
+
databaseId,
|
|
158
|
+
key: keyFrom(input.name, new Set(existing.map((e) => e.key))),
|
|
159
|
+
name: input.name,
|
|
160
|
+
type: input.type,
|
|
161
|
+
config: (input.config ?? {}),
|
|
162
|
+
position: rankBetween(existing.at(-1)?.position ?? null, null),
|
|
163
|
+
})
|
|
164
|
+
.returning();
|
|
165
|
+
return toProperty(row);
|
|
166
|
+
},
|
|
167
|
+
/**
|
|
168
|
+
* Rename, retype or reconfigure a column.
|
|
169
|
+
*
|
|
170
|
+
* The `key` never changes, because it is what every row's `props` is keyed by — renaming a
|
|
171
|
+
* column must not empty it. That is the whole reason a key exists separately from a name.
|
|
172
|
+
*/
|
|
173
|
+
async updateProperty(tx, workspaceId, propertyId, patch) {
|
|
174
|
+
const [row] = await tx
|
|
175
|
+
.update(properties)
|
|
176
|
+
.set(patch)
|
|
177
|
+
.where(and(eq(properties.workspaceId, workspaceId), eq(properties.id, propertyId)))
|
|
178
|
+
.returning();
|
|
179
|
+
if (!row)
|
|
180
|
+
throw KernError.notFound('Property');
|
|
181
|
+
return toProperty(row);
|
|
182
|
+
},
|
|
183
|
+
async removeProperty(tx, workspaceId, propertyId) {
|
|
184
|
+
const [row] = await tx
|
|
185
|
+
.select()
|
|
186
|
+
.from(properties)
|
|
187
|
+
.where(and(eq(properties.workspaceId, workspaceId), eq(properties.id, propertyId)))
|
|
188
|
+
.limit(1);
|
|
189
|
+
if (!row)
|
|
190
|
+
throw KernError.notFound('Property');
|
|
191
|
+
// The values stay in `props`. Deleting a column by mistake is common, and the data coming
|
|
192
|
+
// back when it is re-added costs one unused key per row.
|
|
193
|
+
await tx
|
|
194
|
+
.delete(properties)
|
|
195
|
+
.where(and(eq(properties.workspaceId, workspaceId), eq(properties.id, propertyId)));
|
|
196
|
+
await tx
|
|
197
|
+
.delete(relations)
|
|
198
|
+
.where(and(eq(relations.workspaceId, workspaceId), eq(relations.propertyId, propertyId)));
|
|
199
|
+
return toProperty(row);
|
|
200
|
+
},
|
|
201
|
+
async addView(tx, workspaceId, databaseId, input) {
|
|
202
|
+
const existing = await tx
|
|
203
|
+
.select({ position: views.position })
|
|
204
|
+
.from(views)
|
|
205
|
+
.where(and(eq(views.workspaceId, workspaceId), eq(views.databaseId, databaseId)))
|
|
206
|
+
.orderBy(asc(views.position));
|
|
207
|
+
const [row] = await tx
|
|
208
|
+
.insert(views)
|
|
209
|
+
.values({
|
|
210
|
+
id: uuidv7(),
|
|
211
|
+
workspaceId,
|
|
212
|
+
databaseId,
|
|
213
|
+
name: input.name,
|
|
214
|
+
kind: input.kind,
|
|
215
|
+
config: (input.config ?? {}),
|
|
216
|
+
position: rankBetween(existing.at(-1)?.position ?? null, null),
|
|
217
|
+
isDefault: existing.length === 0,
|
|
218
|
+
})
|
|
219
|
+
.returning();
|
|
220
|
+
return toView(row);
|
|
221
|
+
},
|
|
222
|
+
async updateView(tx, workspaceId, viewId, patch) {
|
|
223
|
+
const [row] = await tx
|
|
224
|
+
.update(views)
|
|
225
|
+
.set({ ...patch, updatedAt: new Date() })
|
|
226
|
+
.where(and(eq(views.workspaceId, workspaceId), eq(views.id, viewId)))
|
|
227
|
+
.returning();
|
|
228
|
+
if (!row)
|
|
229
|
+
throw KernError.notFound('View');
|
|
230
|
+
return toView(row);
|
|
231
|
+
},
|
|
232
|
+
async removeView(tx, workspaceId, viewId) {
|
|
233
|
+
const [row] = await tx
|
|
234
|
+
.select()
|
|
235
|
+
.from(views)
|
|
236
|
+
.where(and(eq(views.workspaceId, workspaceId), eq(views.id, viewId)))
|
|
237
|
+
.limit(1);
|
|
238
|
+
if (!row)
|
|
239
|
+
throw KernError.notFound('View');
|
|
240
|
+
if (row.isDefault)
|
|
241
|
+
throw KernError.badRequest('A database keeps at least one view');
|
|
242
|
+
await tx.delete(views).where(and(eq(views.workspaceId, workspaceId), eq(views.id, viewId)));
|
|
243
|
+
return toView(row);
|
|
244
|
+
},
|
|
245
|
+
/**
|
|
246
|
+
* The rows of a database, filtered and ordered by a view.
|
|
247
|
+
*
|
|
248
|
+
* Filtering happens in SQL rather than after the fact: a page of fifty rows filtered down to
|
|
249
|
+
* three is not a page of three, and the caller has no way to ask for the rest.
|
|
250
|
+
*/
|
|
251
|
+
async rows(tx, workspaceId, databaseId, opts) {
|
|
252
|
+
const db = await this.get(tx, workspaceId, databaseId);
|
|
253
|
+
const config = opts.view?.config;
|
|
254
|
+
const conditions = [
|
|
255
|
+
eq(pages.workspaceId, workspaceId),
|
|
256
|
+
eq(pages.databaseId, databaseId),
|
|
257
|
+
isNull(pages.deletedAt),
|
|
258
|
+
];
|
|
259
|
+
const filters = (config?.filters ?? [])
|
|
260
|
+
.map((f) => filterToSql(f, propertyFor(db.properties, f.propertyKey)))
|
|
261
|
+
.filter((s) => s !== null);
|
|
262
|
+
if (filters.length > 0) {
|
|
263
|
+
conditions.push(config?.filterMode === 'or'
|
|
264
|
+
? sql `(${sql.join(filters, sql ` or `)})`
|
|
265
|
+
: sql `(${sql.join(filters, sql ` and `)})`);
|
|
266
|
+
}
|
|
267
|
+
if (opts.cursor)
|
|
268
|
+
conditions.push(sql `${pages.id} > ${opts.cursor}`);
|
|
269
|
+
const orderBy = (config?.sorts ?? []).map((s) => sortToSql(s, propertyFor(db.properties, s.propertyKey)));
|
|
270
|
+
// Always last, so ordering is total and the keyset cursor cannot skip or repeat a row.
|
|
271
|
+
orderBy.push(sql `${pages.id} asc`);
|
|
272
|
+
const found = await tx
|
|
273
|
+
.select()
|
|
274
|
+
.from(pages)
|
|
275
|
+
.where(and(...conditions))
|
|
276
|
+
.orderBy(...orderBy)
|
|
277
|
+
.limit(opts.limit + 1);
|
|
278
|
+
const items = found.slice(0, opts.limit).map(toRow);
|
|
279
|
+
return { items, nextCursor: found.length > opts.limit ? (items.at(-1)?.id ?? null) : null };
|
|
280
|
+
},
|
|
281
|
+
/**
|
|
282
|
+
* Recompute the formulas and rollups of one row.
|
|
283
|
+
*
|
|
284
|
+
* Written into `computed` rather than calculated on read, so a view can filter and sort by a
|
|
285
|
+
* formula in SQL like any other column. The cost is that a change has to say what it invalidates
|
|
286
|
+
* — which is what `formulaDependencies` is for.
|
|
287
|
+
*/
|
|
288
|
+
async recompute(tx, workspaceId, pageId) {
|
|
289
|
+
const [row] = await tx
|
|
290
|
+
.select()
|
|
291
|
+
.from(pages)
|
|
292
|
+
.where(and(eq(pages.workspaceId, workspaceId), eq(pages.id, pageId)))
|
|
293
|
+
.limit(1);
|
|
294
|
+
if (!row?.databaseId)
|
|
295
|
+
return null;
|
|
296
|
+
const db = await this.get(tx, workspaceId, row.databaseId);
|
|
297
|
+
const props = (row.props ?? {});
|
|
298
|
+
const byName = new Map(db.properties.map((p) => [p.name, p]));
|
|
299
|
+
const computed = {};
|
|
300
|
+
const rollups = db.properties.filter((p) => p.type === 'rollup');
|
|
301
|
+
for (const property of rollups) {
|
|
302
|
+
computed[property.key] = await this.rollup(tx, workspaceId, pageId, property, db.properties);
|
|
303
|
+
}
|
|
304
|
+
const read = (name) => {
|
|
305
|
+
const property = byName.get(name);
|
|
306
|
+
if (!property)
|
|
307
|
+
return null;
|
|
308
|
+
const raw = property.type === 'rollup' ? computed[property.key] : props[property.key];
|
|
309
|
+
if (raw === undefined || raw === null)
|
|
310
|
+
return null;
|
|
311
|
+
if (typeof raw === 'number' || typeof raw === 'string' || typeof raw === 'boolean')
|
|
312
|
+
return raw;
|
|
313
|
+
if (Array.isArray(raw))
|
|
314
|
+
return raw.length;
|
|
315
|
+
return String(raw);
|
|
316
|
+
};
|
|
317
|
+
for (const property of db.properties) {
|
|
318
|
+
if (property.type !== 'formula')
|
|
319
|
+
continue;
|
|
320
|
+
const expression = property.config.expression;
|
|
321
|
+
if (!expression)
|
|
322
|
+
continue;
|
|
323
|
+
try {
|
|
324
|
+
const value = evaluateFormula(astFor(expression), { prop: read });
|
|
325
|
+
computed[property.key] = value instanceof Date ? value.toISOString() : value;
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
// A broken formula shows as an error in its own cell rather than failing the write that
|
|
329
|
+
// triggered it — somebody mistyping an expression must not stop the row being saved.
|
|
330
|
+
computed[property.key] = { error: err instanceof Error ? err.message : 'Invalid formula' };
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
await tx
|
|
334
|
+
.update(pages)
|
|
335
|
+
.set({ computed })
|
|
336
|
+
.where(and(eq(pages.workspaceId, workspaceId), eq(pages.id, pageId)));
|
|
337
|
+
return computed;
|
|
338
|
+
},
|
|
339
|
+
/** Gather the values on the other side of a relation and reduce them. */
|
|
340
|
+
async rollup(tx, workspaceId, pageId, property, all) {
|
|
341
|
+
const via = property.config.rollupRelationPropertyId;
|
|
342
|
+
const target = property.config.rollupTargetPropertyId;
|
|
343
|
+
const fn = property.config.rollupFunction ?? 'count';
|
|
344
|
+
if (!via)
|
|
345
|
+
return null;
|
|
346
|
+
const linked = await tx
|
|
347
|
+
.select({ id: relations.toPageId })
|
|
348
|
+
.from(relations)
|
|
349
|
+
.where(and(eq(relations.workspaceId, workspaceId), eq(relations.propertyId, via), eq(relations.fromPageId, pageId)));
|
|
350
|
+
const ids = linked.map((l) => l.id);
|
|
351
|
+
if (fn === 'count')
|
|
352
|
+
return ids.length;
|
|
353
|
+
if (ids.length === 0)
|
|
354
|
+
return fn === 'sum' || fn === 'average' ? 0 : null;
|
|
355
|
+
/**
|
|
356
|
+
* The target column belongs to the database on the *other* side of the relation, not to the
|
|
357
|
+
* one holding the rollup — so it is looked up by id rather than searched for among this
|
|
358
|
+
* database's own properties, which is where it will never be. Getting that wrong makes every
|
|
359
|
+
* rollup return zero, which reads as "the data is missing" rather than "the lookup is wrong".
|
|
360
|
+
*/
|
|
361
|
+
const [targetRow] = target
|
|
362
|
+
? await tx
|
|
363
|
+
.select()
|
|
364
|
+
.from(properties)
|
|
365
|
+
.where(and(eq(properties.workspaceId, workspaceId), eq(properties.id, target)))
|
|
366
|
+
.limit(1)
|
|
367
|
+
: [];
|
|
368
|
+
const targetProperty = targetRow ? toProperty(targetRow) : all.find((p) => p.id === target);
|
|
369
|
+
const rows = await tx
|
|
370
|
+
.select({ props: pages.props, computed: pages.computed })
|
|
371
|
+
.from(pages)
|
|
372
|
+
.where(and(eq(pages.workspaceId, workspaceId), inArray(pages.id, ids)));
|
|
373
|
+
const values = rows
|
|
374
|
+
.map((r) => {
|
|
375
|
+
if (!targetProperty)
|
|
376
|
+
return null;
|
|
377
|
+
const source = (targetProperty.type === 'formula' || targetProperty.type === 'rollup' ? r.computed : r.props);
|
|
378
|
+
return source?.[targetProperty.key] ?? null;
|
|
379
|
+
})
|
|
380
|
+
.filter((v) => v !== null && v !== undefined);
|
|
381
|
+
const numbers = values.map(Number).filter((n) => !Number.isNaN(n));
|
|
382
|
+
switch (fn) {
|
|
383
|
+
case 'count_values':
|
|
384
|
+
return values.length;
|
|
385
|
+
case 'count_unique':
|
|
386
|
+
return new Set(values.map((v) => JSON.stringify(v))).size;
|
|
387
|
+
case 'sum':
|
|
388
|
+
return numbers.reduce((t, n) => t + n, 0);
|
|
389
|
+
case 'average':
|
|
390
|
+
return numbers.length ? numbers.reduce((t, n) => t + n, 0) / numbers.length : null;
|
|
391
|
+
case 'min':
|
|
392
|
+
return numbers.length ? Math.min(...numbers) : null;
|
|
393
|
+
case 'max':
|
|
394
|
+
return numbers.length ? Math.max(...numbers) : null;
|
|
395
|
+
case 'range':
|
|
396
|
+
return numbers.length ? Math.max(...numbers) - Math.min(...numbers) : null;
|
|
397
|
+
case 'checked':
|
|
398
|
+
return values.filter((v) => v === true).length;
|
|
399
|
+
case 'unchecked':
|
|
400
|
+
return values.filter((v) => v !== true).length;
|
|
401
|
+
case 'percent_checked':
|
|
402
|
+
return values.length ? (values.filter((v) => v === true).length / values.length) * 100 : null;
|
|
403
|
+
case 'show_original':
|
|
404
|
+
return values;
|
|
405
|
+
default:
|
|
406
|
+
return values.length;
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
/**
|
|
410
|
+
* Set both ends of a relation.
|
|
411
|
+
*
|
|
412
|
+
* Symmetric by construction rather than by convention: a link set from one side that is not
|
|
413
|
+
* visible from the other is the bug people report as "the rollup is wrong".
|
|
414
|
+
*/
|
|
415
|
+
async setRelation(tx, workspaceId, propertyId, fromPageId, toPageIds) {
|
|
416
|
+
const [property] = await tx
|
|
417
|
+
.select()
|
|
418
|
+
.from(properties)
|
|
419
|
+
.where(and(eq(properties.workspaceId, workspaceId), eq(properties.id, propertyId)))
|
|
420
|
+
.limit(1);
|
|
421
|
+
if (!property)
|
|
422
|
+
throw KernError.notFound('Property');
|
|
423
|
+
const inverse = property.config.relationPropertyId ?? null;
|
|
424
|
+
await tx
|
|
425
|
+
.delete(relations)
|
|
426
|
+
.where(and(eq(relations.workspaceId, workspaceId), eq(relations.propertyId, propertyId), eq(relations.fromPageId, fromPageId)));
|
|
427
|
+
if (toPageIds.length > 0) {
|
|
428
|
+
await tx.insert(relations).values(toPageIds.map((toPageId) => ({
|
|
429
|
+
id: uuidv7(),
|
|
430
|
+
workspaceId,
|
|
431
|
+
propertyId,
|
|
432
|
+
fromPageId,
|
|
433
|
+
toPageId,
|
|
434
|
+
})));
|
|
435
|
+
}
|
|
436
|
+
if (inverse) {
|
|
437
|
+
await tx
|
|
438
|
+
.delete(relations)
|
|
439
|
+
.where(and(eq(relations.workspaceId, workspaceId), eq(relations.propertyId, inverse), eq(relations.toPageId, fromPageId)));
|
|
440
|
+
if (toPageIds.length > 0) {
|
|
441
|
+
await tx.insert(relations).values(toPageIds.map((toPageId) => ({
|
|
442
|
+
id: uuidv7(),
|
|
443
|
+
workspaceId,
|
|
444
|
+
propertyId: inverse,
|
|
445
|
+
fromPageId: toPageId,
|
|
446
|
+
toPageId: fromPageId,
|
|
447
|
+
})));
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
// The rows on both sides may carry rollups over this relation.
|
|
451
|
+
await this.recompute(tx, workspaceId, fromPageId);
|
|
452
|
+
for (const id of toPageIds)
|
|
453
|
+
await this.recompute(tx, workspaceId, id);
|
|
454
|
+
},
|
|
455
|
+
/**
|
|
456
|
+
* Which other rows have to be recomputed because this one changed.
|
|
457
|
+
*
|
|
458
|
+
* Only the rows that roll up *through* a relation that reaches this one — recomputing the whole
|
|
459
|
+
* database on every keystroke would be correct and unusable.
|
|
460
|
+
*/
|
|
461
|
+
async dependentsOf(tx, workspaceId, pageId) {
|
|
462
|
+
const rows = await tx
|
|
463
|
+
.select({ id: relations.fromPageId })
|
|
464
|
+
.from(relations)
|
|
465
|
+
.where(and(eq(relations.workspaceId, workspaceId), eq(relations.toPageId, pageId)));
|
|
466
|
+
return [...new Set(rows.map((r) => r.id))];
|
|
467
|
+
},
|
|
468
|
+
/** One row, after it has been written. */
|
|
469
|
+
async rowById(tx, workspaceId, pageId) {
|
|
470
|
+
const [row] = await tx
|
|
471
|
+
.select()
|
|
472
|
+
.from(pages)
|
|
473
|
+
.where(and(eq(pages.workspaceId, workspaceId), eq(pages.id, pageId)))
|
|
474
|
+
.limit(1);
|
|
475
|
+
if (!row)
|
|
476
|
+
throw KernError.notFound('Row');
|
|
477
|
+
return toRow(row);
|
|
478
|
+
},
|
|
479
|
+
/**
|
|
480
|
+
* Write cells, merging rather than replacing.
|
|
481
|
+
*
|
|
482
|
+
* A table sends the cell somebody edited, not the whole row — replacing would blank every
|
|
483
|
+
* column the client happened not to know about, which is every column added since it loaded.
|
|
484
|
+
*/
|
|
485
|
+
async setRowFields(tx, workspaceId, pageId, databaseId, props) {
|
|
486
|
+
const [existing] = await tx
|
|
487
|
+
.select({ props: pages.props, databaseId: pages.databaseId })
|
|
488
|
+
.from(pages)
|
|
489
|
+
.where(and(eq(pages.workspaceId, workspaceId), eq(pages.id, pageId)))
|
|
490
|
+
.limit(1);
|
|
491
|
+
if (!existing)
|
|
492
|
+
throw KernError.notFound('Row');
|
|
493
|
+
const merged = { ...(existing.props ?? {}), ...props };
|
|
494
|
+
await tx
|
|
495
|
+
.update(pages)
|
|
496
|
+
.set({
|
|
497
|
+
props: merged,
|
|
498
|
+
databaseId: databaseId ?? existing.databaseId,
|
|
499
|
+
updatedAt: new Date(),
|
|
500
|
+
})
|
|
501
|
+
.where(and(eq(pages.workspaceId, workspaceId), eq(pages.id, pageId)));
|
|
502
|
+
},
|
|
503
|
+
/** The columns a formula reads, so a property rename can report what it would break. */
|
|
504
|
+
dependenciesOf(expression) {
|
|
505
|
+
try {
|
|
506
|
+
return [...formulaDependencies(astFor(expression))];
|
|
507
|
+
}
|
|
508
|
+
catch {
|
|
509
|
+
return [];
|
|
510
|
+
}
|
|
511
|
+
},
|
|
512
|
+
kernel,
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
//# sourceMappingURL=databases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"databases.js","sourceRoot":"","sources":["../../../src/server/services/databases.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Kernel } from '@kernhq/kernel';
|
|
2
2
|
import { quireAccess } from './access.js';
|
|
3
3
|
import { quireComments } from './comments.js';
|
|
4
|
+
import { quireDatabases } from './databases.js';
|
|
4
5
|
import { quirePages } from './pages.js';
|
|
5
6
|
import { quireSpaces } from './spaces.js';
|
|
6
7
|
import { quireVersions } from './versions.js';
|
|
@@ -10,11 +11,13 @@ export interface QuireServices {
|
|
|
10
11
|
pages: ReturnType<typeof quirePages>;
|
|
11
12
|
versions: ReturnType<typeof quireVersions>;
|
|
12
13
|
comments: ReturnType<typeof quireComments>;
|
|
14
|
+
databases: ReturnType<typeof quireDatabases>;
|
|
13
15
|
}
|
|
14
16
|
/** One set of services per kernel: they are stateless, and rebuilding them per request is waste. */
|
|
15
17
|
export declare function quireServices(kernel: Kernel): QuireServices;
|
|
16
18
|
export * from './access.js';
|
|
17
19
|
export * from './comments.js';
|
|
20
|
+
export * from './databases.js';
|
|
18
21
|
export * from './pages.js';
|
|
19
22
|
export * from './spaces.js';
|
|
20
23
|
export * from './versions.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAA;IACtC,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAA;IACtC,KAAK,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAA;IACpC,QAAQ,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IAC1C,QAAQ,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAA;IACtC,MAAM,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAA;IACtC,KAAK,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,CAAA;IACpC,QAAQ,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IAC1C,QAAQ,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAA;IAC1C,SAAS,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAA;CAC7C;AAID,oGAAoG;AACpG,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,CAc3D;AAED,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { quireAccess } from './access.js';
|
|
2
2
|
import { quireComments } from './comments.js';
|
|
3
|
+
import { quireDatabases } from './databases.js';
|
|
3
4
|
import { quirePages } from './pages.js';
|
|
4
5
|
import { quireSpaces } from './spaces.js';
|
|
5
6
|
import { quireVersions } from './versions.js';
|
|
@@ -16,12 +17,14 @@ export function quireServices(kernel) {
|
|
|
16
17
|
pages: quirePages(access),
|
|
17
18
|
versions: quireVersions(kernel, access),
|
|
18
19
|
comments: quireComments(access),
|
|
20
|
+
databases: quireDatabases(kernel, access),
|
|
19
21
|
};
|
|
20
22
|
cache.set(kernel, services);
|
|
21
23
|
return services;
|
|
22
24
|
}
|
|
23
25
|
export * from './access.js';
|
|
24
26
|
export * from './comments.js';
|
|
27
|
+
export * from './databases.js';
|
|
25
28
|
export * from './pages.js';
|
|
26
29
|
export * from './spaces.js';
|
|
27
30
|
export * from './versions.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/services/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/services/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAW7C,MAAM,KAAK,GAAG,IAAI,OAAO,EAAyB,CAAA;AAElD,oGAAoG;AACpG,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAClC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAA;IAC7B,MAAM,MAAM,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAClC,MAAM,QAAQ,GAAkB;QAC9B,MAAM;QACN,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;QAC3B,KAAK,EAAE,UAAU,CAAC,MAAM,CAAC;QACzB,QAAQ,EAAE,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC;QACvC,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC;QAC/B,SAAS,EAAE,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC;KAC1C,CAAA;IACD,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC3B,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,YAAY,CAAA;AAC1B,cAAc,aAAa,CAAA;AAC3B,cAAc,eAAe,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type SQL } from 'drizzle-orm';
|
|
2
|
+
import type { Filter, Property, Sort } from '../../contract/index.js';
|
|
3
|
+
export declare function filterToSql(filter: Filter, property: Property): SQL | null;
|
|
4
|
+
/**
|
|
5
|
+
* The ordering expression for a sort.
|
|
6
|
+
*
|
|
7
|
+
* Typed rather than lexicographic: `props->>'estimate'` sorts 10 before 9, which is the sort of
|
|
8
|
+
* thing nobody reports as a bug and everybody works around.
|
|
9
|
+
*/
|
|
10
|
+
export declare function sortToSql(sort: Sort, property: Property): SQL;
|
|
11
|
+
/** The property a filter or sort names, or a refusal. Never trust the key that arrived. */
|
|
12
|
+
export declare function propertyFor(properties: Property[], key: string): Property;
|
|
13
|
+
//# sourceMappingURL=query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/server/services/query.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,GAAG,EAAO,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAA;AAuBrE,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,GAAG,IAAI,CA0G1E;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,GAAG,GAAG,CAiB7D;AAED,2FAA2F;AAC3F,wBAAgB,WAAW,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,MAAM,GAAG,QAAQ,CAIzE"}
|