@kernhq/module-quire 0.2.0 → 0.3.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/events.d.ts +11 -0
- package/dist/contract/events.d.ts.map +1 -1
- package/dist/contract/events.js +2 -0
- package/dist/contract/events.js.map +1 -1
- package/dist/contract/models.d.ts +29 -0
- package/dist/contract/models.d.ts.map +1 -1
- package/dist/contract/models.js +19 -0
- package/dist/contract/models.js.map +1 -1
- package/dist/contract/permissions.d.ts +7 -0
- package/dist/contract/permissions.d.ts.map +1 -1
- package/dist/contract/permissions.js +8 -0
- package/dist/contract/permissions.js.map +1 -1
- package/dist/contract/router.d.ts +285 -0
- package/dist/contract/router.d.ts.map +1 -1
- package/dist/contract/router.js +37 -1
- package/dist/contract/router.js.map +1 -1
- package/dist/server/_impl.d.ts +319 -0
- package/dist/server/_impl.d.ts.map +1 -1
- package/dist/server/_impl.js +90 -16
- package/dist/server/_impl.js.map +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +63 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/schema.d.ts +206 -1
- package/dist/server/schema.d.ts.map +1 -1
- package/dist/server/schema.js +38 -2
- package/dist/server/schema.js.map +1 -1
- 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/versions.d.ts +124 -0
- package/dist/server/services/versions.d.ts.map +1 -0
- package/dist/server/services/versions.js +182 -0
- package/dist/server/services/versions.js.map +1 -0
- package/migrations/0002_page_versions.sql +25 -0
- package/migrations/meta/0002_snapshot.json +491 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/src/client/index.ts +18 -1
- package/src/contract/events.ts +5 -0
- package/src/contract/models.ts +23 -0
- package/src/contract/permissions.ts +8 -0
- package/src/contract/router.ts +39 -1
|
@@ -0,0 +1,491 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "09606cee-18e2-41eb-b1a6-44a2bf9856cb",
|
|
3
|
+
"prevId": "73e5ffbb-8a14-4b41-bdfd-776e51bec7d7",
|
|
4
|
+
"version": "7",
|
|
5
|
+
"dialect": "postgresql",
|
|
6
|
+
"tables": {
|
|
7
|
+
"mod_quire.page_versions": {
|
|
8
|
+
"name": "page_versions",
|
|
9
|
+
"schema": "mod_quire",
|
|
10
|
+
"columns": {
|
|
11
|
+
"id": {
|
|
12
|
+
"name": "id",
|
|
13
|
+
"type": "uuid",
|
|
14
|
+
"primaryKey": true,
|
|
15
|
+
"notNull": true,
|
|
16
|
+
"default": "uuidv7()"
|
|
17
|
+
},
|
|
18
|
+
"workspace_id": {
|
|
19
|
+
"name": "workspace_id",
|
|
20
|
+
"type": "uuid",
|
|
21
|
+
"primaryKey": false,
|
|
22
|
+
"notNull": true
|
|
23
|
+
},
|
|
24
|
+
"page_id": {
|
|
25
|
+
"name": "page_id",
|
|
26
|
+
"type": "uuid",
|
|
27
|
+
"primaryKey": false,
|
|
28
|
+
"notNull": true
|
|
29
|
+
},
|
|
30
|
+
"kind": {
|
|
31
|
+
"name": "kind",
|
|
32
|
+
"type": "text",
|
|
33
|
+
"primaryKey": false,
|
|
34
|
+
"notNull": true,
|
|
35
|
+
"default": "'auto'"
|
|
36
|
+
},
|
|
37
|
+
"label": {
|
|
38
|
+
"name": "label",
|
|
39
|
+
"type": "text",
|
|
40
|
+
"primaryKey": false,
|
|
41
|
+
"notNull": false
|
|
42
|
+
},
|
|
43
|
+
"state": {
|
|
44
|
+
"name": "state",
|
|
45
|
+
"type": "bytea",
|
|
46
|
+
"primaryKey": false,
|
|
47
|
+
"notNull": true
|
|
48
|
+
},
|
|
49
|
+
"snapshot": {
|
|
50
|
+
"name": "snapshot",
|
|
51
|
+
"type": "bytea",
|
|
52
|
+
"primaryKey": false,
|
|
53
|
+
"notNull": false
|
|
54
|
+
},
|
|
55
|
+
"text": {
|
|
56
|
+
"name": "text",
|
|
57
|
+
"type": "text",
|
|
58
|
+
"primaryKey": false,
|
|
59
|
+
"notNull": true,
|
|
60
|
+
"default": "''"
|
|
61
|
+
},
|
|
62
|
+
"size": {
|
|
63
|
+
"name": "size",
|
|
64
|
+
"type": "integer",
|
|
65
|
+
"primaryKey": false,
|
|
66
|
+
"notNull": true,
|
|
67
|
+
"default": 0
|
|
68
|
+
},
|
|
69
|
+
"author_id": {
|
|
70
|
+
"name": "author_id",
|
|
71
|
+
"type": "uuid",
|
|
72
|
+
"primaryKey": false,
|
|
73
|
+
"notNull": false
|
|
74
|
+
},
|
|
75
|
+
"created_at": {
|
|
76
|
+
"name": "created_at",
|
|
77
|
+
"type": "timestamp with time zone",
|
|
78
|
+
"primaryKey": false,
|
|
79
|
+
"notNull": true,
|
|
80
|
+
"default": "now()"
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"indexes": {
|
|
84
|
+
"page_versions_ws_page_idx": {
|
|
85
|
+
"name": "page_versions_ws_page_idx",
|
|
86
|
+
"columns": [
|
|
87
|
+
{
|
|
88
|
+
"expression": "workspace_id",
|
|
89
|
+
"isExpression": false,
|
|
90
|
+
"asc": true,
|
|
91
|
+
"nulls": "last"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"expression": "page_id",
|
|
95
|
+
"isExpression": false,
|
|
96
|
+
"asc": true,
|
|
97
|
+
"nulls": "last"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"expression": "created_at",
|
|
101
|
+
"isExpression": false,
|
|
102
|
+
"asc": true,
|
|
103
|
+
"nulls": "last"
|
|
104
|
+
}
|
|
105
|
+
],
|
|
106
|
+
"isUnique": false,
|
|
107
|
+
"concurrently": false,
|
|
108
|
+
"method": "btree",
|
|
109
|
+
"with": {}
|
|
110
|
+
},
|
|
111
|
+
"page_versions_ws_created_idx": {
|
|
112
|
+
"name": "page_versions_ws_created_idx",
|
|
113
|
+
"columns": [
|
|
114
|
+
{
|
|
115
|
+
"expression": "workspace_id",
|
|
116
|
+
"isExpression": false,
|
|
117
|
+
"asc": true,
|
|
118
|
+
"nulls": "last"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"expression": "created_at",
|
|
122
|
+
"isExpression": false,
|
|
123
|
+
"asc": true,
|
|
124
|
+
"nulls": "last"
|
|
125
|
+
}
|
|
126
|
+
],
|
|
127
|
+
"isUnique": false,
|
|
128
|
+
"concurrently": false,
|
|
129
|
+
"method": "btree",
|
|
130
|
+
"with": {}
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"foreignKeys": {},
|
|
134
|
+
"compositePrimaryKeys": {},
|
|
135
|
+
"uniqueConstraints": {},
|
|
136
|
+
"policies": {},
|
|
137
|
+
"checkConstraints": {},
|
|
138
|
+
"isRLSEnabled": false
|
|
139
|
+
},
|
|
140
|
+
"mod_quire.pages": {
|
|
141
|
+
"name": "pages",
|
|
142
|
+
"schema": "mod_quire",
|
|
143
|
+
"columns": {
|
|
144
|
+
"id": {
|
|
145
|
+
"name": "id",
|
|
146
|
+
"type": "uuid",
|
|
147
|
+
"primaryKey": true,
|
|
148
|
+
"notNull": true,
|
|
149
|
+
"default": "uuidv7()"
|
|
150
|
+
},
|
|
151
|
+
"workspace_id": {
|
|
152
|
+
"name": "workspace_id",
|
|
153
|
+
"type": "uuid",
|
|
154
|
+
"primaryKey": false,
|
|
155
|
+
"notNull": true
|
|
156
|
+
},
|
|
157
|
+
"space_id": {
|
|
158
|
+
"name": "space_id",
|
|
159
|
+
"type": "uuid",
|
|
160
|
+
"primaryKey": false,
|
|
161
|
+
"notNull": true
|
|
162
|
+
},
|
|
163
|
+
"parent_id": {
|
|
164
|
+
"name": "parent_id",
|
|
165
|
+
"type": "uuid",
|
|
166
|
+
"primaryKey": false,
|
|
167
|
+
"notNull": false
|
|
168
|
+
},
|
|
169
|
+
"position": {
|
|
170
|
+
"name": "position",
|
|
171
|
+
"type": "text",
|
|
172
|
+
"primaryKey": false,
|
|
173
|
+
"notNull": true
|
|
174
|
+
},
|
|
175
|
+
"kind": {
|
|
176
|
+
"name": "kind",
|
|
177
|
+
"type": "text",
|
|
178
|
+
"primaryKey": false,
|
|
179
|
+
"notNull": true,
|
|
180
|
+
"default": "'page'"
|
|
181
|
+
},
|
|
182
|
+
"title": {
|
|
183
|
+
"name": "title",
|
|
184
|
+
"type": "text",
|
|
185
|
+
"primaryKey": false,
|
|
186
|
+
"notNull": true,
|
|
187
|
+
"default": "''"
|
|
188
|
+
},
|
|
189
|
+
"icon": {
|
|
190
|
+
"name": "icon",
|
|
191
|
+
"type": "text",
|
|
192
|
+
"primaryKey": false,
|
|
193
|
+
"notNull": false
|
|
194
|
+
},
|
|
195
|
+
"cover_url": {
|
|
196
|
+
"name": "cover_url",
|
|
197
|
+
"type": "text",
|
|
198
|
+
"primaryKey": false,
|
|
199
|
+
"notNull": false
|
|
200
|
+
},
|
|
201
|
+
"published_version_id": {
|
|
202
|
+
"name": "published_version_id",
|
|
203
|
+
"type": "uuid",
|
|
204
|
+
"primaryKey": false,
|
|
205
|
+
"notNull": false
|
|
206
|
+
},
|
|
207
|
+
"has_unpublished_changes": {
|
|
208
|
+
"name": "has_unpublished_changes",
|
|
209
|
+
"type": "boolean",
|
|
210
|
+
"primaryKey": false,
|
|
211
|
+
"notNull": true,
|
|
212
|
+
"default": false
|
|
213
|
+
},
|
|
214
|
+
"text": {
|
|
215
|
+
"name": "text",
|
|
216
|
+
"type": "text",
|
|
217
|
+
"primaryKey": false,
|
|
218
|
+
"notNull": true,
|
|
219
|
+
"default": "''"
|
|
220
|
+
},
|
|
221
|
+
"created_by": {
|
|
222
|
+
"name": "created_by",
|
|
223
|
+
"type": "uuid",
|
|
224
|
+
"primaryKey": false,
|
|
225
|
+
"notNull": false
|
|
226
|
+
},
|
|
227
|
+
"updated_by": {
|
|
228
|
+
"name": "updated_by",
|
|
229
|
+
"type": "uuid",
|
|
230
|
+
"primaryKey": false,
|
|
231
|
+
"notNull": false
|
|
232
|
+
},
|
|
233
|
+
"created_at": {
|
|
234
|
+
"name": "created_at",
|
|
235
|
+
"type": "timestamp with time zone",
|
|
236
|
+
"primaryKey": false,
|
|
237
|
+
"notNull": true,
|
|
238
|
+
"default": "now()"
|
|
239
|
+
},
|
|
240
|
+
"updated_at": {
|
|
241
|
+
"name": "updated_at",
|
|
242
|
+
"type": "timestamp with time zone",
|
|
243
|
+
"primaryKey": false,
|
|
244
|
+
"notNull": true,
|
|
245
|
+
"default": "now()"
|
|
246
|
+
},
|
|
247
|
+
"archived_at": {
|
|
248
|
+
"name": "archived_at",
|
|
249
|
+
"type": "timestamp with time zone",
|
|
250
|
+
"primaryKey": false,
|
|
251
|
+
"notNull": false
|
|
252
|
+
},
|
|
253
|
+
"deleted_at": {
|
|
254
|
+
"name": "deleted_at",
|
|
255
|
+
"type": "timestamp with time zone",
|
|
256
|
+
"primaryKey": false,
|
|
257
|
+
"notNull": false
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
"indexes": {
|
|
261
|
+
"pages_ws_space_idx": {
|
|
262
|
+
"name": "pages_ws_space_idx",
|
|
263
|
+
"columns": [
|
|
264
|
+
{
|
|
265
|
+
"expression": "workspace_id",
|
|
266
|
+
"isExpression": false,
|
|
267
|
+
"asc": true,
|
|
268
|
+
"nulls": "last"
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
"expression": "space_id",
|
|
272
|
+
"isExpression": false,
|
|
273
|
+
"asc": true,
|
|
274
|
+
"nulls": "last"
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"expression": "position",
|
|
278
|
+
"isExpression": false,
|
|
279
|
+
"asc": true,
|
|
280
|
+
"nulls": "last"
|
|
281
|
+
}
|
|
282
|
+
],
|
|
283
|
+
"isUnique": false,
|
|
284
|
+
"concurrently": false,
|
|
285
|
+
"method": "btree",
|
|
286
|
+
"with": {}
|
|
287
|
+
},
|
|
288
|
+
"pages_ws_parent_idx": {
|
|
289
|
+
"name": "pages_ws_parent_idx",
|
|
290
|
+
"columns": [
|
|
291
|
+
{
|
|
292
|
+
"expression": "workspace_id",
|
|
293
|
+
"isExpression": false,
|
|
294
|
+
"asc": true,
|
|
295
|
+
"nulls": "last"
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"expression": "parent_id",
|
|
299
|
+
"isExpression": false,
|
|
300
|
+
"asc": true,
|
|
301
|
+
"nulls": "last"
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
"expression": "position",
|
|
305
|
+
"isExpression": false,
|
|
306
|
+
"asc": true,
|
|
307
|
+
"nulls": "last"
|
|
308
|
+
}
|
|
309
|
+
],
|
|
310
|
+
"isUnique": false,
|
|
311
|
+
"concurrently": false,
|
|
312
|
+
"method": "btree",
|
|
313
|
+
"with": {}
|
|
314
|
+
},
|
|
315
|
+
"pages_ws_updated_idx": {
|
|
316
|
+
"name": "pages_ws_updated_idx",
|
|
317
|
+
"columns": [
|
|
318
|
+
{
|
|
319
|
+
"expression": "workspace_id",
|
|
320
|
+
"isExpression": false,
|
|
321
|
+
"asc": true,
|
|
322
|
+
"nulls": "last"
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
"expression": "updated_at",
|
|
326
|
+
"isExpression": false,
|
|
327
|
+
"asc": true,
|
|
328
|
+
"nulls": "last"
|
|
329
|
+
}
|
|
330
|
+
],
|
|
331
|
+
"isUnique": false,
|
|
332
|
+
"concurrently": false,
|
|
333
|
+
"method": "btree",
|
|
334
|
+
"with": {}
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
"foreignKeys": {},
|
|
338
|
+
"compositePrimaryKeys": {},
|
|
339
|
+
"uniqueConstraints": {},
|
|
340
|
+
"policies": {},
|
|
341
|
+
"checkConstraints": {},
|
|
342
|
+
"isRLSEnabled": false
|
|
343
|
+
},
|
|
344
|
+
"mod_quire.spaces": {
|
|
345
|
+
"name": "spaces",
|
|
346
|
+
"schema": "mod_quire",
|
|
347
|
+
"columns": {
|
|
348
|
+
"id": {
|
|
349
|
+
"name": "id",
|
|
350
|
+
"type": "uuid",
|
|
351
|
+
"primaryKey": true,
|
|
352
|
+
"notNull": true,
|
|
353
|
+
"default": "uuidv7()"
|
|
354
|
+
},
|
|
355
|
+
"workspace_id": {
|
|
356
|
+
"name": "workspace_id",
|
|
357
|
+
"type": "uuid",
|
|
358
|
+
"primaryKey": false,
|
|
359
|
+
"notNull": true
|
|
360
|
+
},
|
|
361
|
+
"key": {
|
|
362
|
+
"name": "key",
|
|
363
|
+
"type": "text",
|
|
364
|
+
"primaryKey": false,
|
|
365
|
+
"notNull": true
|
|
366
|
+
},
|
|
367
|
+
"name": {
|
|
368
|
+
"name": "name",
|
|
369
|
+
"type": "text",
|
|
370
|
+
"primaryKey": false,
|
|
371
|
+
"notNull": true
|
|
372
|
+
},
|
|
373
|
+
"description": {
|
|
374
|
+
"name": "description",
|
|
375
|
+
"type": "text",
|
|
376
|
+
"primaryKey": false,
|
|
377
|
+
"notNull": true,
|
|
378
|
+
"default": "''"
|
|
379
|
+
},
|
|
380
|
+
"icon": {
|
|
381
|
+
"name": "icon",
|
|
382
|
+
"type": "text",
|
|
383
|
+
"primaryKey": false,
|
|
384
|
+
"notNull": false
|
|
385
|
+
},
|
|
386
|
+
"visibility": {
|
|
387
|
+
"name": "visibility",
|
|
388
|
+
"type": "text",
|
|
389
|
+
"primaryKey": false,
|
|
390
|
+
"notNull": true,
|
|
391
|
+
"default": "'open'"
|
|
392
|
+
},
|
|
393
|
+
"homepage_id": {
|
|
394
|
+
"name": "homepage_id",
|
|
395
|
+
"type": "uuid",
|
|
396
|
+
"primaryKey": false,
|
|
397
|
+
"notNull": false
|
|
398
|
+
},
|
|
399
|
+
"created_by": {
|
|
400
|
+
"name": "created_by",
|
|
401
|
+
"type": "uuid",
|
|
402
|
+
"primaryKey": false,
|
|
403
|
+
"notNull": false
|
|
404
|
+
},
|
|
405
|
+
"created_at": {
|
|
406
|
+
"name": "created_at",
|
|
407
|
+
"type": "timestamp with time zone",
|
|
408
|
+
"primaryKey": false,
|
|
409
|
+
"notNull": true,
|
|
410
|
+
"default": "now()"
|
|
411
|
+
},
|
|
412
|
+
"updated_at": {
|
|
413
|
+
"name": "updated_at",
|
|
414
|
+
"type": "timestamp with time zone",
|
|
415
|
+
"primaryKey": false,
|
|
416
|
+
"notNull": true,
|
|
417
|
+
"default": "now()"
|
|
418
|
+
},
|
|
419
|
+
"archived_at": {
|
|
420
|
+
"name": "archived_at",
|
|
421
|
+
"type": "timestamp with time zone",
|
|
422
|
+
"primaryKey": false,
|
|
423
|
+
"notNull": false
|
|
424
|
+
}
|
|
425
|
+
},
|
|
426
|
+
"indexes": {
|
|
427
|
+
"spaces_ws_key_uq": {
|
|
428
|
+
"name": "spaces_ws_key_uq",
|
|
429
|
+
"columns": [
|
|
430
|
+
{
|
|
431
|
+
"expression": "workspace_id",
|
|
432
|
+
"isExpression": false,
|
|
433
|
+
"asc": true,
|
|
434
|
+
"nulls": "last"
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
"expression": "key",
|
|
438
|
+
"isExpression": false,
|
|
439
|
+
"asc": true,
|
|
440
|
+
"nulls": "last"
|
|
441
|
+
}
|
|
442
|
+
],
|
|
443
|
+
"isUnique": true,
|
|
444
|
+
"concurrently": false,
|
|
445
|
+
"method": "btree",
|
|
446
|
+
"with": {}
|
|
447
|
+
},
|
|
448
|
+
"spaces_ws_idx": {
|
|
449
|
+
"name": "spaces_ws_idx",
|
|
450
|
+
"columns": [
|
|
451
|
+
{
|
|
452
|
+
"expression": "workspace_id",
|
|
453
|
+
"isExpression": false,
|
|
454
|
+
"asc": true,
|
|
455
|
+
"nulls": "last"
|
|
456
|
+
},
|
|
457
|
+
{
|
|
458
|
+
"expression": "created_at",
|
|
459
|
+
"isExpression": false,
|
|
460
|
+
"asc": true,
|
|
461
|
+
"nulls": "last"
|
|
462
|
+
}
|
|
463
|
+
],
|
|
464
|
+
"isUnique": false,
|
|
465
|
+
"concurrently": false,
|
|
466
|
+
"method": "btree",
|
|
467
|
+
"with": {}
|
|
468
|
+
}
|
|
469
|
+
},
|
|
470
|
+
"foreignKeys": {},
|
|
471
|
+
"compositePrimaryKeys": {},
|
|
472
|
+
"uniqueConstraints": {},
|
|
473
|
+
"policies": {},
|
|
474
|
+
"checkConstraints": {},
|
|
475
|
+
"isRLSEnabled": false
|
|
476
|
+
}
|
|
477
|
+
},
|
|
478
|
+
"enums": {},
|
|
479
|
+
"schemas": {
|
|
480
|
+
"mod_quire": "mod_quire"
|
|
481
|
+
},
|
|
482
|
+
"sequences": {},
|
|
483
|
+
"roles": {},
|
|
484
|
+
"policies": {},
|
|
485
|
+
"views": {},
|
|
486
|
+
"_meta": {
|
|
487
|
+
"columns": {},
|
|
488
|
+
"schemas": {},
|
|
489
|
+
"tables": {}
|
|
490
|
+
}
|
|
491
|
+
}
|
package/package.json
CHANGED
package/src/client/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { formatCollabDocument } from '@kernhq/contracts'
|
|
1
2
|
import { createModuleClient, type KernClientOptions } from '@kernhq/sdk'
|
|
2
3
|
import type { ContractRouterClient } from '@orpc/contract'
|
|
3
|
-
import type
|
|
4
|
+
import { MODULE_ID, type Page, type PageNode, type QuireContract } from '../contract/index.js'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* The client half.
|
|
@@ -33,6 +34,22 @@ export {
|
|
|
33
34
|
} from '../contract/index.js'
|
|
34
35
|
export * from './rank.js'
|
|
35
36
|
|
|
37
|
+
/**
|
|
38
|
+
* The name this page's prose is synchronised under, on the collab service.
|
|
39
|
+
*
|
|
40
|
+
* Exported here rather than left to the caller because the gateway parses it with the matching
|
|
41
|
+
* function from `@kernhq/contracts`, and a name it cannot parse is a rejected connection with no
|
|
42
|
+
* useful error. The module owns the naming of its own objects.
|
|
43
|
+
*/
|
|
44
|
+
export function pageDocumentName(page: { workspaceId: Page['workspaceId']; id: string }): string {
|
|
45
|
+
return formatCollabDocument({
|
|
46
|
+
workspaceId: page.workspaceId,
|
|
47
|
+
module: MODULE_ID,
|
|
48
|
+
type: 'page',
|
|
49
|
+
objectId: page.id,
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
|
|
36
53
|
/** The permission keys, so the app gates on a constant rather than a string it retyped. */
|
|
37
54
|
export const QUIRE_PERMISSIONS = {
|
|
38
55
|
spaceView: 'quire.space.view',
|
package/src/contract/events.ts
CHANGED
|
@@ -17,6 +17,11 @@ export const quireEvents = {
|
|
|
17
17
|
pageArchived: defineEvent('quire.page.archived', page.extend({ archived: z.boolean() })),
|
|
18
18
|
pageTrashed: defineEvent('quire.page.trashed', page.extend({ count: z.number().int().nonnegative() })),
|
|
19
19
|
pageRestored: defineEvent('quire.page.restored', page),
|
|
20
|
+
pagePublished: defineEvent('quire.page.published', page.extend({ versionId: Id })),
|
|
21
|
+
pageRestoredVersion: defineEvent(
|
|
22
|
+
'quire.page.restored_version',
|
|
23
|
+
z.object({ pageId: Id, workspaceId: WorkspaceId, versionId: Id }),
|
|
24
|
+
),
|
|
20
25
|
/** The page and its descendants are gone; anything holding a reference should drop it. */
|
|
21
26
|
pageDeleted: defineEvent('quire.page.deleted', page.extend({ pageIds: z.array(Id) })),
|
|
22
27
|
} as const
|
package/src/contract/models.ts
CHANGED
|
@@ -90,4 +90,27 @@ export const PageNode = z.object({
|
|
|
90
90
|
})
|
|
91
91
|
export type PageNode = z.infer<typeof PageNode>
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* How a version came to exist. `restore` matters: putting an older version back writes a new
|
|
95
|
+
* version rather than rewinding, so restoring is never itself the thing that loses work.
|
|
96
|
+
*/
|
|
97
|
+
export const VersionKind = z.enum(['auto', 'publish', 'restore', 'import'])
|
|
98
|
+
export type VersionKind = z.infer<typeof VersionKind>
|
|
99
|
+
|
|
100
|
+
export const PageVersion = z.object({
|
|
101
|
+
id: Id,
|
|
102
|
+
workspaceId: WorkspaceId,
|
|
103
|
+
pageId: Id,
|
|
104
|
+
kind: VersionKind,
|
|
105
|
+
label: z.string().max(120).nullable(),
|
|
106
|
+
/** the first line or so of the prose, so a list reads without loading a document */
|
|
107
|
+
preview: z.string(),
|
|
108
|
+
size: z.number().int().nonnegative(),
|
|
109
|
+
authorId: UserId.nullable(),
|
|
110
|
+
createdAt: Timestamp,
|
|
111
|
+
/** whether this is the version a reader is currently served */
|
|
112
|
+
published: z.boolean(),
|
|
113
|
+
})
|
|
114
|
+
export type PageVersion = z.infer<typeof PageVersion>
|
|
115
|
+
|
|
93
116
|
export const Ok = z.object({ ok: z.literal(true) })
|
|
@@ -48,6 +48,14 @@ export const quirePermissions = definePermissions([
|
|
|
48
48
|
defaultRoles: ['owner', 'admin', 'member'],
|
|
49
49
|
dangerous: false,
|
|
50
50
|
},
|
|
51
|
+
{
|
|
52
|
+
key: 'quire.page.publish',
|
|
53
|
+
label: 'Publish pages',
|
|
54
|
+
description: 'Decide which version readers and any public site are served',
|
|
55
|
+
scope: 'space',
|
|
56
|
+
defaultRoles: ['owner', 'admin', 'member'],
|
|
57
|
+
dangerous: false,
|
|
58
|
+
},
|
|
51
59
|
{
|
|
52
60
|
key: 'quire.page.delete',
|
|
53
61
|
label: 'Delete pages permanently',
|
package/src/contract/router.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { baseContract, Id, PageInput, page, WorkspaceId } from '@kernhq/contracts'
|
|
2
2
|
import { z } from 'zod'
|
|
3
|
-
import { Ok, Page, PageKind, PageNode, Space, SpaceVisibility } from './models.js'
|
|
3
|
+
import { Ok, Page, PageKind, PageNode, PageVersion, Space, SpaceVisibility } from './models.js'
|
|
4
4
|
|
|
5
5
|
const ws = z.object({ workspaceId: WorkspaceId })
|
|
6
6
|
const t = (...tags: string[]) => ({ tags })
|
|
@@ -115,6 +115,44 @@ export const quireContract = {
|
|
|
115
115
|
.input(ws.extend({ pageId: Id }))
|
|
116
116
|
.output(z.object({ ok: z.literal(true), count: z.number().int().nonnegative() })),
|
|
117
117
|
},
|
|
118
|
+
|
|
119
|
+
versions: {
|
|
120
|
+
list: baseContract
|
|
121
|
+
.route({ method: 'GET', path: '/pages/{pageId}/versions', ...t('versions') })
|
|
122
|
+
.input(ws.extend({ pageId: Id }).extend(PageInput.shape))
|
|
123
|
+
.output(page(PageVersion)),
|
|
124
|
+
/** The prose of one version, rendered as text — enough to read it and to diff it. */
|
|
125
|
+
get: baseContract
|
|
126
|
+
.route({ method: 'GET', path: '/versions/{versionId}', ...t('versions') })
|
|
127
|
+
.input(ws.extend({ versionId: Id }))
|
|
128
|
+
.output(PageVersion.extend({ text: z.string() })),
|
|
129
|
+
/** Take one now, and give it a name. */
|
|
130
|
+
create: baseContract
|
|
131
|
+
.route({ method: 'POST', path: '/pages/{pageId}/versions', ...t('versions') })
|
|
132
|
+
.input(ws.extend({ pageId: Id, label: z.string().min(1).max(120).nullable().default(null) }))
|
|
133
|
+
.output(PageVersion),
|
|
134
|
+
/**
|
|
135
|
+
* Put an older version back. It is applied to the live document rather than written behind the
|
|
136
|
+
* people editing it, and the state it replaced is kept as a version of its own first.
|
|
137
|
+
*/
|
|
138
|
+
restore: baseContract
|
|
139
|
+
.route({ method: 'POST', path: '/versions/{versionId}/restore', ...t('versions') })
|
|
140
|
+
.input(ws.extend({ versionId: Id }))
|
|
141
|
+
.output(PageVersion),
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
publishing: {
|
|
145
|
+
/** Make what is written now the version readers are served. Only meaningful for a `page`. */
|
|
146
|
+
publish: baseContract
|
|
147
|
+
.route({ method: 'POST', path: '/pages/{pageId}/publish', ...t('publishing') })
|
|
148
|
+
.input(ws.extend({ pageId: Id, label: z.string().min(1).max(120).nullable().default(null) }))
|
|
149
|
+
.output(Page),
|
|
150
|
+
/** Throw the draft away and go back to what readers can already see. */
|
|
151
|
+
revert: baseContract
|
|
152
|
+
.route({ method: 'POST', path: '/pages/{pageId}/revert', ...t('publishing') })
|
|
153
|
+
.input(ws.extend({ pageId: Id }))
|
|
154
|
+
.output(Page),
|
|
155
|
+
},
|
|
118
156
|
} as const
|
|
119
157
|
export type QuireContract = typeof quireContract
|
|
120
158
|
|