@roc-db/test-utils 0.2.0-pre.10 → 0.2.0-pre.100
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/index.js +1210 -303
- package/dist/types/entities/BlockImageEntity.d.ts +7 -0
- package/dist/types/entities/BlockParagraph.d.ts +7 -0
- package/dist/types/entities/BlockRow.d.ts +7 -0
- package/dist/types/entities/Draft.d.ts +8 -0
- package/dist/types/entities/OrgSettingsEntity.d.ts +10 -0
- package/dist/types/entities/PostEntity.d.ts +12 -0
- package/dist/types/entities/PostVersion.d.ts +8 -0
- package/dist/types/entities/UserEntity.d.ts +5 -0
- package/dist/types/entities/index.d.ts +41 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/operations/applyDraft.d.ts +1 -0
- package/dist/types/operations/createBlockImage.d.ts +5 -15
- package/dist/types/operations/createBlockParagraph.d.ts +5 -15
- package/dist/types/operations/createBlockRow.d.ts +4 -15
- package/dist/types/operations/createBlockRowReadingRoot.d.ts +13 -0
- package/dist/types/operations/createBlockTitle.d.ts +4 -15
- package/dist/types/operations/createDraft.d.ts +4 -15
- package/dist/types/operations/createOrgSettings.d.ts +6 -0
- package/dist/types/operations/createPost.d.ts +6 -19
- package/dist/types/operations/createUnknownRef.d.ts +2 -0
- package/dist/types/operations/createUser.d.ts +4 -0
- package/dist/types/operations/crudBySlug.d.ts +5 -0
- package/dist/types/operations/deleteBlocks.d.ts +2 -0
- package/dist/types/operations/deleteDraft.d.ts +1 -0
- package/dist/types/operations/deleteOrgSettings.d.ts +2 -0
- package/dist/types/operations/deletePost.d.ts +1 -9
- package/dist/types/operations/duplicateDraft.d.ts +10 -0
- package/dist/types/operations/index.d.ts +1 -157
- package/dist/types/operations/moveBlocks.d.ts +5 -0
- package/dist/types/operations/pageBlocks.d.ts +1 -0
- package/dist/types/operations/pageEmptyEntitiesArray.d.ts +1 -0
- package/dist/types/operations/pagePosts.d.ts +1 -0
- package/dist/types/operations/pagePostsByTag.d.ts +1 -0
- package/dist/types/operations/pageSplat.d.ts +1 -0
- package/dist/types/operations/readMutation.d.ts +1 -0
- package/dist/types/operations/readOrgSettings.d.ts +2 -0
- package/dist/types/operations/readPostBySlug.d.ts +1 -0
- package/dist/types/operations/testTransactionalEdits.d.ts +6 -0
- package/dist/types/operations/updateBlockParagraph.d.ts +5 -15
- package/dist/types/operations/updateOrgSettingsName.d.ts +4 -0
- package/dist/types/operations/updatePost.d.ts +7 -21
- package/dist/types/operations/updatePostDescription.d.ts +5 -0
- package/dist/types/operations/updatePostSlug.d.ts +5 -0
- package/dist/types/operations/updatePostTags.d.ts +5 -0
- package/dist/types/operations/updatePostTitle.d.ts +5 -17
- package/dist/types/schemas/BlockImageRefSchema.d.ts +1 -1
- package/dist/types/schemas/BlockImageSchema.d.ts +20 -31
- package/dist/types/schemas/BlockParagraphRefSchema.d.ts +1 -1
- package/dist/types/schemas/BlockParagraphSchema.d.ts +20 -31
- package/dist/types/schemas/BlockRefSchema.d.ts +1 -1
- package/dist/types/schemas/BlockRowRefSchema.d.ts +1 -1
- package/dist/types/schemas/BlockRowSchema.d.ts +21 -31
- package/dist/types/schemas/BlockTitleSchema.d.ts +20 -31
- package/dist/types/schemas/CreatePostMutationSchema.d.ts +14 -44
- package/dist/types/schemas/CreateUserMutationSchema.d.ts +13 -35
- package/dist/types/schemas/DraftRefSchema.d.ts +1 -1
- package/dist/types/schemas/DraftSchema.d.ts +18 -31
- package/dist/types/schemas/PostRefSchema.d.ts +1 -1
- package/dist/types/schemas/PostSchema.d.ts +25 -31
- package/dist/types/schemas/PostVersionRefSchema.d.ts +1 -0
- package/dist/types/schemas/UpdatePostMutationSchema.d.ts +16 -50
- package/dist/types/schemas/UpdatePostTitleMutationSchema.d.ts +14 -40
- package/dist/types/schemas/UserRefSchema.d.ts +1 -1
- package/dist/types/schemas/index.d.ts +0 -31
- package/dist/types/setup/index.d.ts +11 -0
- package/dist/types/testAdapterImplementation.d.ts +1 -1
- package/package.json +8 -4
- package/dist/types/operations/deleteBlock.d.ts +0 -11
- package/dist/types/schemas/BlockTitleRefSchema.d.ts +0 -1
- package/dist/types/schemas/CreateBlockImageMutationSchema.d.ts +0 -40
- package/dist/types/schemas/CreateBlockParagraphMutationSchema.d.ts +0 -40
- package/dist/types/schemas/CreateBlockRowMutationSchema.d.ts +0 -40
- package/dist/types/schemas/CreateBlockTitleMutationSchema.d.ts +0 -40
- package/dist/types/schemas/CreateDraftMutationSchema.d.ts +0 -40
- package/dist/types/schemas/DeleteBlockMutationSchema.d.ts +0 -30
- package/dist/types/schemas/DeletePostMutationSchema.d.ts +0 -29
- package/dist/types/schemas/UpdateBlockParagraphMutationSchema.d.ts +0 -45
package/dist/index.js
CHANGED
|
@@ -2,17 +2,12 @@
|
|
|
2
2
|
import { entitySchemaGenerator } from "roc-db";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
|
-
// src/schemas/BlockImageRefSchema.ts
|
|
6
|
-
import { refSchemaGenerator } from "roc-db";
|
|
7
|
-
var BlockImageRefSchema = refSchemaGenerator("BlockImage");
|
|
8
|
-
|
|
9
5
|
// src/schemas/PostRefSchema.ts
|
|
10
|
-
import { refSchemaGenerator
|
|
11
|
-
var PostRefSchema =
|
|
6
|
+
import { refSchemaGenerator } from "roc-db";
|
|
7
|
+
var PostRefSchema = refSchemaGenerator("Post");
|
|
12
8
|
|
|
13
9
|
// src/schemas/BlockImageSchema.ts
|
|
14
10
|
var BlockImageSchema = entitySchemaGenerator("BlockImage", {
|
|
15
|
-
ref: BlockImageRefSchema,
|
|
16
11
|
data: z.object({
|
|
17
12
|
url: z.string().url()
|
|
18
13
|
}),
|
|
@@ -24,14 +19,7 @@ var BlockImageSchema = entitySchemaGenerator("BlockImage", {
|
|
|
24
19
|
// src/schemas/BlockParagraphSchema.ts
|
|
25
20
|
import { entitySchemaGenerator as entitySchemaGenerator2 } from "roc-db";
|
|
26
21
|
import { z as z2 } from "zod";
|
|
27
|
-
|
|
28
|
-
// src/schemas/BlockParagraphRefSchema.ts
|
|
29
|
-
import { refSchemaGenerator as refSchemaGenerator3 } from "roc-db";
|
|
30
|
-
var BlockParagraphRefSchema = refSchemaGenerator3("BlockParagraph");
|
|
31
|
-
|
|
32
|
-
// src/schemas/BlockParagraphSchema.ts
|
|
33
22
|
var BlockParagraphSchema = entitySchemaGenerator2("BlockParagraph", {
|
|
34
|
-
ref: BlockParagraphRefSchema,
|
|
35
23
|
data: z2.object({
|
|
36
24
|
content: z2.string().optional()
|
|
37
25
|
}),
|
|
@@ -43,14 +31,7 @@ var BlockParagraphSchema = entitySchemaGenerator2("BlockParagraph", {
|
|
|
43
31
|
// src/schemas/BlockTitleSchema.ts
|
|
44
32
|
import { entitySchemaGenerator as entitySchemaGenerator3 } from "roc-db";
|
|
45
33
|
import { z as z3 } from "zod";
|
|
46
|
-
|
|
47
|
-
// src/schemas/BlockTitleRefSchema.ts
|
|
48
|
-
import { refSchemaGenerator as refSchemaGenerator4 } from "roc-db";
|
|
49
|
-
var BlockTitleRefSchema = refSchemaGenerator4("BlockTitle");
|
|
50
|
-
|
|
51
|
-
// src/schemas/BlockTitleSchema.ts
|
|
52
34
|
var BlockTitleSchema = entitySchemaGenerator3("BlockTitle", {
|
|
53
|
-
ref: BlockTitleRefSchema,
|
|
54
35
|
data: z3.object({
|
|
55
36
|
content: z3.string()
|
|
56
37
|
}),
|
|
@@ -62,16 +43,9 @@ var BlockTitleSchema = entitySchemaGenerator3("BlockTitle", {
|
|
|
62
43
|
// src/schemas/DraftSchema.ts
|
|
63
44
|
import { entitySchemaGenerator as entitySchemaGenerator4 } from "roc-db";
|
|
64
45
|
import { z as z4 } from "zod";
|
|
65
|
-
|
|
66
|
-
// src/schemas/DraftRefSchema.ts
|
|
67
|
-
import { refSchemaGenerator as refSchemaGenerator5 } from "roc-db";
|
|
68
|
-
var DraftRefSchema = refSchemaGenerator5("Draft");
|
|
69
|
-
|
|
70
|
-
// src/schemas/DraftSchema.ts
|
|
71
46
|
var DraftSchema = entitySchemaGenerator4("Draft", {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
postRef: PostRefSchema
|
|
47
|
+
parents: z4.object({
|
|
48
|
+
post: PostRefSchema
|
|
75
49
|
})
|
|
76
50
|
});
|
|
77
51
|
|
|
@@ -80,12 +54,11 @@ import { entitySchemaGenerator as entitySchemaGenerator5 } from "roc-db";
|
|
|
80
54
|
import { z as z5 } from "zod";
|
|
81
55
|
|
|
82
56
|
// src/schemas/UserRefSchema.ts
|
|
83
|
-
import { refSchemaGenerator as
|
|
84
|
-
var UserRefSchema =
|
|
57
|
+
import { refSchemaGenerator as refSchemaGenerator2 } from "roc-db";
|
|
58
|
+
var UserRefSchema = refSchemaGenerator2("User");
|
|
85
59
|
|
|
86
60
|
// src/schemas/PostSchema.ts
|
|
87
61
|
var PostSchema = entitySchemaGenerator5("Post", {
|
|
88
|
-
ref: PostRefSchema,
|
|
89
62
|
data: z5.object({
|
|
90
63
|
title: z5.string(),
|
|
91
64
|
text: z5.string().optional(),
|
|
@@ -95,414 +68,1348 @@ var PostSchema = entitySchemaGenerator5("Post", {
|
|
|
95
68
|
parents: z5.object({ author: UserRefSchema.optional() }),
|
|
96
69
|
children: z5.object({ blocks: z5.array(z5.string()) })
|
|
97
70
|
});
|
|
71
|
+
|
|
72
|
+
// src/entities/Draft.ts
|
|
73
|
+
import { Entity } from "roc-db";
|
|
74
|
+
import { z as z6 } from "zod";
|
|
75
|
+
|
|
76
|
+
// src/schemas/PostVersionRefSchema.ts
|
|
77
|
+
import { refSchemaGenerator as refSchemaGenerator3 } from "roc-db";
|
|
78
|
+
var PostVersionRefSchema = refSchemaGenerator3("PostVersion");
|
|
79
|
+
|
|
80
|
+
// src/entities/Draft.ts
|
|
81
|
+
var Draft = new Entity("Draft", {
|
|
82
|
+
changeSet: true,
|
|
83
|
+
data: z6.object({
|
|
84
|
+
appliedAt: z6.string().optional()
|
|
85
|
+
}),
|
|
86
|
+
parents: z6.object({
|
|
87
|
+
post: PostRefSchema,
|
|
88
|
+
version: PostVersionRefSchema.optional()
|
|
89
|
+
})
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// src/schemas/DraftRefSchema.ts
|
|
93
|
+
var DraftRefSchema = Draft.refSchema;
|
|
98
94
|
// src/schemas/CreatePostMutationSchema.ts
|
|
99
95
|
import { mutationSchemaGenerator } from "roc-db";
|
|
100
|
-
import { z as
|
|
101
|
-
var CreatePostMutationSchema = mutationSchemaGenerator("createPost",
|
|
102
|
-
title:
|
|
103
|
-
slug:
|
|
104
|
-
tags:
|
|
96
|
+
import { z as z7 } from "zod";
|
|
97
|
+
var CreatePostMutationSchema = mutationSchemaGenerator("createPost", z7.object({
|
|
98
|
+
title: z7.string(),
|
|
99
|
+
slug: z7.string().optional(),
|
|
100
|
+
tags: z7.array(z7.string()).default([])
|
|
105
101
|
}).strict());
|
|
106
102
|
// src/schemas/CreateUserMutationSchema.ts
|
|
107
103
|
import { mutationSchemaGenerator as mutationSchemaGenerator2 } from "roc-db";
|
|
108
|
-
import { z as
|
|
109
|
-
var CreateUserMutationSchema = mutationSchemaGenerator2("createUser",
|
|
104
|
+
import { z as z8 } from "zod";
|
|
105
|
+
var CreateUserMutationSchema = mutationSchemaGenerator2("createUser", z8.object({ email: z8.string() }));
|
|
110
106
|
// src/schemas/UpdatePostMutationSchema.ts
|
|
111
107
|
import { mutationSchemaGenerator as mutationSchemaGenerator3 } from "roc-db";
|
|
112
|
-
import { z as
|
|
113
|
-
var UpdatePostMutationSchema = mutationSchemaGenerator3("updatePost",
|
|
108
|
+
import { z as z9 } from "zod";
|
|
109
|
+
var UpdatePostMutationSchema = mutationSchemaGenerator3("updatePost", z9.object({
|
|
114
110
|
ref: PostRefSchema,
|
|
115
|
-
title:
|
|
116
|
-
tags:
|
|
117
|
-
authorRef: UserRefSchema.optional()
|
|
111
|
+
title: z9.string().optional(),
|
|
112
|
+
tags: z9.array(z9.string()).optional().default([]),
|
|
113
|
+
authorRef: UserRefSchema.optional()
|
|
118
114
|
}));
|
|
119
115
|
// src/schemas/UpdatePostTitleMutationSchema.ts
|
|
120
116
|
import { mutationSchemaGenerator as mutationSchemaGenerator4 } from "roc-db";
|
|
121
|
-
import { z as z9 } from "zod";
|
|
122
|
-
var UpdatePostTitleMutationSchema = mutationSchemaGenerator4("updatePostTitle", z9.object({ ref: PostRefSchema, title: z9.string() }));
|
|
123
|
-
// src/schemas/index.ts
|
|
124
|
-
var entities = [
|
|
125
|
-
BlockImageSchema,
|
|
126
|
-
BlockParagraphSchema,
|
|
127
|
-
BlockTitleSchema,
|
|
128
|
-
DraftSchema,
|
|
129
|
-
PostSchema
|
|
130
|
-
];
|
|
131
|
-
// src/operations/createBlockImage.ts
|
|
132
|
-
import { Query, writeOperation } from "roc-db";
|
|
133
|
-
|
|
134
|
-
// src/schemas/CreateBlockImageMutationSchema.ts
|
|
135
|
-
import { mutationSchemaGenerator as mutationSchemaGenerator5 } from "roc-db";
|
|
136
117
|
import { z as z10 } from "zod";
|
|
137
|
-
var
|
|
118
|
+
var UpdatePostTitleMutationSchema = mutationSchemaGenerator4("updatePostTitle", z10.object({ ref: PostRefSchema, title: z10.string() }));
|
|
119
|
+
// src/entities/BlockImageEntity.ts
|
|
120
|
+
import { Entity as Entity2 } from "roc-db";
|
|
121
|
+
import { z as z11 } from "zod";
|
|
122
|
+
var BlockImageEntity = new Entity2("BlockImage", {
|
|
123
|
+
data: z11.object({
|
|
124
|
+
url: z11.string().url()
|
|
125
|
+
}),
|
|
126
|
+
parents: z11.object({
|
|
127
|
+
parent: PostRefSchema
|
|
128
|
+
})
|
|
129
|
+
});
|
|
138
130
|
|
|
139
|
-
// src/
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const { postRef } = txn.payload;
|
|
143
|
-
return Query(() => txn.createEntity(ref, { parents: { post: postRef } }));
|
|
144
|
-
}, { changeSetOnly: true });
|
|
131
|
+
// src/entities/BlockParagraph.ts
|
|
132
|
+
import { Entity as Entity4 } from "roc-db";
|
|
133
|
+
import { z as z14 } from "zod";
|
|
145
134
|
|
|
146
|
-
// src/
|
|
147
|
-
import {
|
|
135
|
+
// src/entities/PostEntity.ts
|
|
136
|
+
import { Entity as Entity3 } from "roc-db";
|
|
137
|
+
import { z as z12 } from "zod";
|
|
138
|
+
var PostEntity = new Entity3("Post", {
|
|
139
|
+
data: z12.object({
|
|
140
|
+
title: z12.string(),
|
|
141
|
+
text: z12.string().optional(),
|
|
142
|
+
tags: z12.array(z12.string()),
|
|
143
|
+
slug: z12.string().optional()
|
|
144
|
+
}),
|
|
145
|
+
parents: z12.object({ author: UserRefSchema.optional() }),
|
|
146
|
+
children: z12.object({ blocks: z12.array(z12.string()) }),
|
|
147
|
+
indexedDataKeys: ["tags", "slug"],
|
|
148
|
+
uniqueDataKeys: ["slug"]
|
|
149
|
+
});
|
|
148
150
|
|
|
149
|
-
// src/schemas/
|
|
150
|
-
import {
|
|
151
|
-
|
|
151
|
+
// src/schemas/BlockRefSchema.ts
|
|
152
|
+
import { z as z13 } from "zod";
|
|
153
|
+
|
|
154
|
+
// src/schemas/BlockParagraphRefSchema.ts
|
|
155
|
+
import { refSchemaGenerator as refSchemaGenerator4 } from "roc-db";
|
|
156
|
+
var BlockParagraphRefSchema = refSchemaGenerator4("BlockParagraph");
|
|
152
157
|
|
|
153
158
|
// src/schemas/BlockRowRefSchema.ts
|
|
154
|
-
import { refSchemaGenerator as
|
|
155
|
-
var BlockRowRefSchema =
|
|
159
|
+
import { refSchemaGenerator as refSchemaGenerator5 } from "roc-db";
|
|
160
|
+
var BlockRowRefSchema = refSchemaGenerator5("BlockRow");
|
|
156
161
|
|
|
157
|
-
// src/schemas/
|
|
158
|
-
var
|
|
162
|
+
// src/schemas/BlockRefSchema.ts
|
|
163
|
+
var BlockRefSchema = z13.union([
|
|
164
|
+
BlockParagraphRefSchema,
|
|
165
|
+
BlockRowRefSchema
|
|
166
|
+
]);
|
|
159
167
|
|
|
160
|
-
// src/
|
|
161
|
-
var
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
168
|
+
// src/entities/BlockParagraph.ts
|
|
169
|
+
var BlockParagraph = new Entity4("BlockParagraph", {
|
|
170
|
+
data: z14.object({
|
|
171
|
+
content: z14.string().optional()
|
|
172
|
+
}),
|
|
173
|
+
parents: z14.object({
|
|
174
|
+
parent: z14.union([PostEntity.refSchema, BlockRefSchema])
|
|
175
|
+
})
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// src/entities/BlockRow.ts
|
|
179
|
+
import { Entity as Entity5 } from "roc-db";
|
|
180
|
+
import { z as z15 } from "zod";
|
|
181
|
+
var BlockRow = new Entity5("BlockRow", {
|
|
182
|
+
children: z15.object({
|
|
183
|
+
blocks: z15.array(BlockRefSchema)
|
|
184
|
+
}),
|
|
185
|
+
parents: z15.object({
|
|
186
|
+
parent: z15.union([PostEntity.refSchema, BlockRefSchema])
|
|
187
|
+
})
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
// src/entities/OrgSettingsEntity.ts
|
|
191
|
+
import { Entity as Entity6 } from "roc-db";
|
|
192
|
+
import { z as z16 } from "zod";
|
|
193
|
+
var OrgSettingsEntity = new Entity6("OrgSettings", {
|
|
194
|
+
singleton: true,
|
|
195
|
+
data: z16.object({
|
|
196
|
+
name: z16.string(),
|
|
197
|
+
theme: z16.string().optional()
|
|
198
|
+
}),
|
|
199
|
+
parents: z16.object({ primaryAdmin: UserRefSchema.optional() }),
|
|
200
|
+
children: z16.object({ featuredPosts: z16.array(z16.string()) })
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
// src/entities/PostVersion.ts
|
|
204
|
+
import { Entity as Entity7 } from "roc-db";
|
|
205
|
+
import { z as z17 } from "zod";
|
|
206
|
+
var PostVersion = new Entity7("PostVersion", {
|
|
207
|
+
version: true,
|
|
208
|
+
data: z17.object({
|
|
209
|
+
version: z17.number(),
|
|
210
|
+
snapshot: z17.array(z17.any())
|
|
211
|
+
}),
|
|
212
|
+
parents: z17.object({ post: PostRefSchema }),
|
|
213
|
+
indexedDataKeys: ["version"],
|
|
214
|
+
uniqueDataKeys: ["slug"]
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
// src/entities/UserEntity.ts
|
|
218
|
+
import { Entity as Entity8 } from "roc-db";
|
|
219
|
+
import { z as z18 } from "zod";
|
|
220
|
+
var UserEntity = new Entity8("User", {
|
|
221
|
+
data: z18.object({
|
|
222
|
+
email: z18.string().email()
|
|
223
|
+
}),
|
|
224
|
+
uniqueDataKeys: ["email"]
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// src/entities/index.ts
|
|
228
|
+
var entities = [
|
|
229
|
+
BlockImageEntity,
|
|
230
|
+
BlockParagraph,
|
|
231
|
+
BlockRow,
|
|
232
|
+
Draft,
|
|
233
|
+
OrgSettingsEntity,
|
|
234
|
+
PostEntity,
|
|
235
|
+
PostVersion,
|
|
236
|
+
UserEntity
|
|
237
|
+
];
|
|
238
|
+
// src/operations/applyDraft.ts
|
|
239
|
+
import { Query, QueryChain, writeOperation } from "roc-db";
|
|
240
|
+
var applyDraft = writeOperation("applyDraft", DraftRefSchema, (txn) => {
|
|
241
|
+
const ref = txn.payload;
|
|
242
|
+
const versionRef = txn.createRef("PostVersion");
|
|
243
|
+
return QueryChain(Query(() => txn.applyChangeSet(ref)), Query(() => txn.patchEntity(ref, {
|
|
244
|
+
data: { appliedAt: txn.timestamp }
|
|
245
|
+
})), Query((draft) => txn.childRefsOf(draft.parents.post, true)), Query((childRefs, draft) => txn.batchReadEntities([draft.parents.post, ...childRefs])), Query((childEntities, _, draft) => txn.createEntity(versionRef, {
|
|
246
|
+
data: {
|
|
247
|
+
version: 1,
|
|
248
|
+
snapshot: childEntities
|
|
249
|
+
},
|
|
250
|
+
parents: {
|
|
251
|
+
post: draft.parents.post
|
|
252
|
+
}
|
|
253
|
+
})));
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// src/operations/createBlockImage.ts
|
|
257
|
+
import { Query as Query2, writeOperation as writeOperation2 } from "roc-db";
|
|
258
|
+
import { z as z19 } from "zod";
|
|
259
|
+
var createBlockImage = writeOperation2("createBlockImage", z19.object({ parentRef: PostRefSchema, url: z19.string().url() }).strict(), (txn) => {
|
|
260
|
+
const ref = txn.createRef("BlockImage");
|
|
261
|
+
const { parentRef, url } = txn.payload;
|
|
262
|
+
return Query2(() => txn.createEntity(ref, {
|
|
263
|
+
data: { url },
|
|
264
|
+
parents: { parent: parentRef }
|
|
265
|
+
}));
|
|
167
266
|
}, { changeSetOnly: true });
|
|
168
267
|
|
|
169
|
-
// src/operations/
|
|
268
|
+
// src/operations/createBlockParagraph.ts
|
|
170
269
|
import { Query as Query3, QueryChain as QueryChain2, writeOperation as writeOperation3 } from "roc-db";
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
270
|
+
import { z as z20 } from "zod";
|
|
271
|
+
var createBlockParagrah = writeOperation3("createBlockParagraph", z20.object({
|
|
272
|
+
parentRef: z20.union([PostRefSchema, BlockRowRefSchema]),
|
|
273
|
+
content: z20.string().optional()
|
|
274
|
+
}).strict(), (txn) => {
|
|
275
|
+
const ref = txn.createRef("BlockParagraph");
|
|
276
|
+
const { parentRef, content } = txn.payload;
|
|
277
|
+
return QueryChain2(Query3(() => txn.readEntity(parentRef, true)), Query3((parent) => txn.patchEntity(parentRef, {
|
|
278
|
+
children: { blocks: [...parent.children.blocks, ref] }
|
|
279
|
+
})), Query3(() => txn.createEntity(ref, {
|
|
280
|
+
parents: { parent: parentRef },
|
|
281
|
+
data: { content }
|
|
282
|
+
})), Query3((block, updatedParent) => ({ block, updatedParent })));
|
|
283
|
+
}, {
|
|
284
|
+
changeSetOnly: true,
|
|
285
|
+
outputSchema: z20.object({
|
|
286
|
+
block: z20.any(),
|
|
287
|
+
updatedParent: z20.any()
|
|
288
|
+
})
|
|
289
|
+
});
|
|
176
290
|
|
|
177
291
|
// src/operations/createBlockRow.ts
|
|
178
|
-
|
|
292
|
+
import { Query as Query4, QueryChain as QueryChain3, writeOperation as writeOperation4 } from "roc-db";
|
|
293
|
+
import { z as z21 } from "zod";
|
|
294
|
+
var createBlockRow = writeOperation4("createBlockRow", z21.object({ parentRef: z21.union([PostRefSchema, BlockRowRefSchema]) }).strict(), (txn) => {
|
|
179
295
|
const ref = txn.createRef("BlockRow");
|
|
180
296
|
const { parentRef } = txn.payload;
|
|
181
|
-
return
|
|
297
|
+
return QueryChain3(Query4(() => txn.readEntity(parentRef)), Query4((parent) => {
|
|
182
298
|
return txn.patchEntity(parentRef, {
|
|
183
299
|
children: { blocks: [...parent.children.blocks, ref] }
|
|
184
300
|
});
|
|
185
|
-
}),
|
|
301
|
+
}), Query4(() => txn.createEntity(ref, {
|
|
186
302
|
children: { blocks: [] },
|
|
187
303
|
parents: { parent: parentRef }
|
|
188
|
-
})),
|
|
189
|
-
}, {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
304
|
+
})), Query4((block, updatedParent) => ({ block, updatedParent })));
|
|
305
|
+
}, {
|
|
306
|
+
changeSetOnly: true,
|
|
307
|
+
outputSchema: z21.object({
|
|
308
|
+
block: z21.any(),
|
|
309
|
+
updatedParent: z21.any()
|
|
310
|
+
})
|
|
311
|
+
});
|
|
193
312
|
|
|
194
|
-
// src/
|
|
195
|
-
import {
|
|
196
|
-
import { z as
|
|
197
|
-
var
|
|
313
|
+
// src/operations/createBlockRowReadingRoot.ts
|
|
314
|
+
import { Query as Query5, QueryChain as QueryChain4, writeOperation as writeOperation5 } from "roc-db";
|
|
315
|
+
import { z as z22 } from "zod";
|
|
316
|
+
var createBlockRowReadingRoot = writeOperation5("createBlockRowReadingRoot", z22.object({ parentRef: z22.union([PostRefSchema, BlockRowRefSchema]) }).strict(), (txn) => {
|
|
317
|
+
const ref = txn.createRef("BlockRow");
|
|
318
|
+
const { parentRef } = txn.payload;
|
|
319
|
+
return QueryChain4(Query5(() => {
|
|
320
|
+
if (txn.changeSetRef)
|
|
321
|
+
txn.readEntity(txn.changeSetRef);
|
|
322
|
+
}), Query5(() => txn.readEntity(parentRef)), Query5((parent) => txn.patchEntity(parentRef, {
|
|
323
|
+
children: { blocks: [...parent.children.blocks, ref] }
|
|
324
|
+
})), Query5(() => txn.createEntity(ref, {
|
|
325
|
+
children: { blocks: [] },
|
|
326
|
+
parents: { parent: parentRef }
|
|
327
|
+
})), Query5((block) => ({ block })));
|
|
328
|
+
}, {
|
|
329
|
+
changeSetOnly: true,
|
|
330
|
+
outputSchema: z22.object({ block: z22.any() })
|
|
331
|
+
});
|
|
198
332
|
|
|
199
333
|
// src/operations/createBlockTitle.ts
|
|
200
|
-
|
|
334
|
+
import { Query as Query6, writeOperation as writeOperation6 } from "roc-db";
|
|
335
|
+
import { z as z23 } from "zod";
|
|
336
|
+
var PayloadSchema = z23.object({ parentRef: z23.union([PostRefSchema, BlockRowRefSchema]) }).strict();
|
|
337
|
+
var createBlockTitle = writeOperation6("createBlockTitle", PayloadSchema, (txn) => {
|
|
201
338
|
const ref = txn.createRef("BlockTitle");
|
|
202
|
-
const {
|
|
203
|
-
return
|
|
204
|
-
}, { changeSetOnly: true });
|
|
205
|
-
|
|
206
|
-
// src/operations/createDraft.ts
|
|
207
|
-
import { Query as Query5, writeOperation as writeOperation5 } from "roc-db";
|
|
208
|
-
|
|
209
|
-
// src/schemas/CreateDraftMutationSchema.ts
|
|
210
|
-
import { mutationSchemaGenerator as mutationSchemaGenerator9 } from "roc-db";
|
|
211
|
-
import { z as z14 } from "zod";
|
|
212
|
-
var CreateDraftMutationSchema = mutationSchemaGenerator9("createDraft", z14.object({ postRef: PostRefSchema }).strict());
|
|
339
|
+
const { parentRef } = txn.payload;
|
|
340
|
+
return Query6(() => txn.createEntity(ref, { parents: { post: parentRef } }));
|
|
341
|
+
}, { changeSetOnly: true, outputSchema: BlockTitleSchema });
|
|
213
342
|
|
|
214
343
|
// src/operations/createDraft.ts
|
|
215
|
-
|
|
344
|
+
import { Query as Query7, writeOperation as writeOperation7 } from "roc-db";
|
|
345
|
+
import { z as z24 } from "zod";
|
|
346
|
+
var createDraft = writeOperation7("createDraft", z24.object({ postRef: PostRefSchema }).strict(), (txn) => {
|
|
216
347
|
const ref = txn.createRef("Draft");
|
|
217
348
|
const { postRef } = txn.payload;
|
|
218
|
-
return
|
|
349
|
+
return Query7(() => txn.createEntity(ref, {
|
|
219
350
|
parents: {
|
|
220
351
|
post: postRef
|
|
221
352
|
}
|
|
222
353
|
}));
|
|
354
|
+
}, { outputSchema: DraftSchema });
|
|
355
|
+
|
|
356
|
+
// src/operations/createOrgSettings.ts
|
|
357
|
+
import { Query as Query8, writeOperation as writeOperation8 } from "roc-db";
|
|
358
|
+
import { z as z25 } from "zod";
|
|
359
|
+
var createOrgSettings = writeOperation8("createOrgSettings", z25.object({
|
|
360
|
+
name: z25.string(),
|
|
361
|
+
theme: z25.string().optional(),
|
|
362
|
+
primaryAdmin: UserRefSchema.optional()
|
|
363
|
+
}), (txn) => {
|
|
364
|
+
const ref = txn.createRef("OrgSettings");
|
|
365
|
+
const { name, theme, primaryAdmin } = txn.payload;
|
|
366
|
+
return Query8(() => txn.createEntity(ref, {
|
|
367
|
+
data: { name, theme },
|
|
368
|
+
parents: { primaryAdmin },
|
|
369
|
+
children: { featuredPosts: [] }
|
|
370
|
+
}));
|
|
223
371
|
});
|
|
224
372
|
|
|
225
373
|
// src/operations/createPost.ts
|
|
226
|
-
import { Query as
|
|
227
|
-
|
|
374
|
+
import { Query as Query9, writeOperation as writeOperation9 } from "roc-db";
|
|
375
|
+
import { z as z26 } from "zod";
|
|
376
|
+
var PayloadSchema2 = z26.object({
|
|
377
|
+
title: z26.string(),
|
|
378
|
+
slug: z26.string().optional(),
|
|
379
|
+
tags: z26.array(z26.string()).default([])
|
|
380
|
+
}).strict();
|
|
381
|
+
var createPost = writeOperation9("createPost", PayloadSchema2, (txn) => {
|
|
228
382
|
const ref = txn.createRef("Post");
|
|
229
383
|
const { title, slug, tags } = txn.payload;
|
|
230
|
-
return
|
|
384
|
+
return Query9(() => txn.createEntity(ref, {
|
|
231
385
|
data: { title, tags, slug },
|
|
232
386
|
children: { blocks: [] }
|
|
233
387
|
}));
|
|
234
388
|
});
|
|
235
389
|
|
|
236
|
-
// src/operations/
|
|
237
|
-
import { Query as
|
|
390
|
+
// src/operations/createUnknownRef.ts
|
|
391
|
+
import { Query as Query10, writeOperation as writeOperation10 } from "roc-db";
|
|
392
|
+
import { z as z27 } from "zod";
|
|
393
|
+
var createUnknownRef = writeOperation10("createUnknownRef", z27.object({}).optional(), (txn) => Query10(() => txn.createRef("NotARegisteredEntity")));
|
|
238
394
|
|
|
239
|
-
// src/
|
|
240
|
-
import {
|
|
241
|
-
import { z as
|
|
242
|
-
var
|
|
395
|
+
// src/operations/createUser.ts
|
|
396
|
+
import { Query as Query11, writeOperation as writeOperation11 } from "roc-db";
|
|
397
|
+
import { z as z28 } from "zod";
|
|
398
|
+
var createUser = writeOperation11("createUser", z28.object({ email: z28.string() }), (txn) => {
|
|
399
|
+
const ref = txn.createRef("User");
|
|
400
|
+
const { email } = txn.payload;
|
|
401
|
+
return Query11(() => txn.createEntity(ref, { data: { email } }));
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// src/operations/deleteBlocks.ts
|
|
405
|
+
import { Query as Query12, QueryChain as QueryChain5, writeOperation as writeOperation12 } from "roc-db";
|
|
406
|
+
import { z as z29 } from "zod";
|
|
407
|
+
|
|
408
|
+
// src/schemas/BlockImageRefSchema.ts
|
|
409
|
+
import { refSchemaGenerator as refSchemaGenerator6 } from "roc-db";
|
|
410
|
+
var BlockImageRefSchema = refSchemaGenerator6("BlockImage");
|
|
243
411
|
|
|
244
|
-
// src/operations/
|
|
245
|
-
var
|
|
246
|
-
|
|
247
|
-
|
|
412
|
+
// src/operations/deleteBlocks.ts
|
|
413
|
+
var DeleteBlockQuery = (txn, blockRef) => {
|
|
414
|
+
return QueryChain5(Query12(() => txn.readEntity(blockRef)), Query12((block) => {
|
|
415
|
+
return txn.readEntity(block.parents.parent, true);
|
|
416
|
+
}), Query12((post) => {
|
|
248
417
|
return txn.patchEntity(post.ref, {
|
|
249
|
-
|
|
250
|
-
|
|
418
|
+
children: {
|
|
419
|
+
blocks: post.children.blocks.filter((ref) => ref !== blockRef)
|
|
251
420
|
}
|
|
252
421
|
});
|
|
253
|
-
}),
|
|
254
|
-
|
|
255
|
-
|
|
422
|
+
}), Query12(() => txn.deleteEntity(blockRef)));
|
|
423
|
+
};
|
|
424
|
+
var deleteBlocks = writeOperation12("deleteBlocks", z29.array(z29.union([
|
|
425
|
+
BlockParagraphRefSchema,
|
|
426
|
+
BlockImageRefSchema,
|
|
427
|
+
BlockRowRefSchema
|
|
428
|
+
])), (txn) => {
|
|
429
|
+
const refs = txn.payload;
|
|
430
|
+
return QueryChain5(...refs.map((ref) => DeleteBlockQuery(txn, ref)));
|
|
256
431
|
}, { changeSetOnly: true });
|
|
257
432
|
|
|
258
|
-
// src/operations/
|
|
259
|
-
import { Query as
|
|
433
|
+
// src/operations/deleteDraft.ts
|
|
434
|
+
import { Query as Query13, QueryChain as QueryChain6, writeOperation as writeOperation13 } from "roc-db";
|
|
435
|
+
var deleteDraft = writeOperation13("deleteDraft", DraftRefSchema, (txn) => {
|
|
436
|
+
const ref = txn.payload;
|
|
437
|
+
return QueryChain6(Query13(() => txn.deleteEntity(ref, true)), Query13(() => txn.deleteChangeSet(ref)));
|
|
438
|
+
});
|
|
260
439
|
|
|
261
|
-
// src/
|
|
262
|
-
import {
|
|
263
|
-
|
|
440
|
+
// src/operations/deleteOrgSettings.ts
|
|
441
|
+
import { Query as Query14, writeOperation as writeOperation14 } from "roc-db";
|
|
442
|
+
import { z as z30 } from "zod";
|
|
443
|
+
var deleteOrgSettings = writeOperation14("deleteOrgSettings", z30.object({}).optional(), (txn) => Query14(() => txn.deleteEntity("OrgSettings")));
|
|
264
444
|
|
|
265
445
|
// src/operations/deletePost.ts
|
|
266
|
-
|
|
446
|
+
import { Query as Query15, writeOperation as writeOperation15 } from "roc-db";
|
|
447
|
+
var deletePost = writeOperation15("deletePost", PostRefSchema, (txn) => {
|
|
267
448
|
const ref = txn.payload;
|
|
268
|
-
return
|
|
449
|
+
return Query15(() => txn.deleteEntity(ref, true));
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
// src/operations/duplicateDraft.ts
|
|
453
|
+
import {
|
|
454
|
+
Query as Query16,
|
|
455
|
+
QueryChain as QueryChain7,
|
|
456
|
+
writeOperation as writeOperation16
|
|
457
|
+
} from "roc-db";
|
|
458
|
+
import { z as z31 } from "zod";
|
|
459
|
+
var duplicateDraft = writeOperation16("duplicateDraft", z31.object({ sourceRef: DraftRefSchema, postRef: PostRefSchema }).strict(), (txn) => {
|
|
460
|
+
const newDraftRef = txn.createRef("Draft");
|
|
461
|
+
const { sourceRef, postRef } = txn.payload;
|
|
462
|
+
return QueryChain7(Query16(() => txn.createEntity(newDraftRef, { parents: { post: postRef } })), Query16(() => txn.duplicateChangeSetMutations(sourceRef, newDraftRef)), Query16((dup) => {
|
|
463
|
+
const result = dup;
|
|
464
|
+
return {
|
|
465
|
+
draftRef: newDraftRef,
|
|
466
|
+
mutations: result.mutations,
|
|
467
|
+
refMap: result.refMap
|
|
468
|
+
};
|
|
469
|
+
}));
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// src/operations/moveBlocks.ts
|
|
473
|
+
import { Query as Query17, QueryChain as QueryChain8, writeOperation as writeOperation17 } from "roc-db";
|
|
474
|
+
import { z as z32 } from "zod";
|
|
475
|
+
var PayloadSchema3 = z32.object({
|
|
476
|
+
refs: z32.array(z32.union([BlockParagraphRefSchema, BlockRowRefSchema])),
|
|
477
|
+
targetPosition: z32.number().min(0)
|
|
478
|
+
}).strict();
|
|
479
|
+
var moveBlocks = writeOperation17("moveBlocks", PayloadSchema3, (txn) => {
|
|
480
|
+
const { refs } = txn.payload;
|
|
481
|
+
return QueryChain8(Query17(() => txn.batchReadEntities(refs)), Query17((items) => {
|
|
482
|
+
return "todo";
|
|
483
|
+
}));
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
// src/operations/pageBlocks.ts
|
|
487
|
+
import { Query as Query18, readOperation } from "roc-db";
|
|
488
|
+
import { z as z33 } from "zod";
|
|
489
|
+
var pageBlocks = readOperation("pageBlocks", z33.object({
|
|
490
|
+
size: z33.number().default(100),
|
|
491
|
+
parentRef: z33.string().optional()
|
|
492
|
+
}), (txn) => {
|
|
493
|
+
const { size, parentRef } = txn.payload;
|
|
494
|
+
return Query18(() => txn.pageEntities({
|
|
495
|
+
entities: ["BlockImage", "BlockParagraph"],
|
|
496
|
+
size,
|
|
497
|
+
childrenOf: parentRef ? [parentRef] : []
|
|
498
|
+
}));
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
// src/operations/pageEmptyEntitiesArray.ts
|
|
502
|
+
import { Query as Query19, readOperation as readOperation2 } from "roc-db";
|
|
503
|
+
import { z as z34 } from "zod";
|
|
504
|
+
var pageEmptyEntitiesArray = readOperation2("pageEmptyEntitiesArray", z34.object({ size: z34.number().default(100) }), (txn) => {
|
|
505
|
+
const { size } = txn.payload;
|
|
506
|
+
return Query19(() => txn.pageEntities({ entities: [], size }));
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
// src/operations/pagePosts.ts
|
|
510
|
+
import { Query as Query20, readOperation as readOperation3 } from "roc-db";
|
|
511
|
+
import { z as z35 } from "zod";
|
|
512
|
+
var pagePosts = readOperation3("pagePosts", z35.object({ size: z35.number().default(100) }).default({}), (txn) => {
|
|
513
|
+
const { size } = txn.payload;
|
|
514
|
+
return Query20(() => txn.pageEntities({ entities: ["Post"], size }));
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
// src/operations/pageSplat.ts
|
|
518
|
+
import { Query as Query21, readOperation as readOperation4 } from "roc-db";
|
|
519
|
+
import { z as z36 } from "zod";
|
|
520
|
+
var pageSplat = readOperation4("pageSplat", z36.object({ size: z36.number().default(100) }), (txn) => {
|
|
521
|
+
const { size } = txn.payload;
|
|
522
|
+
return Query21(() => txn.pageEntities({ entities: "*", size }));
|
|
523
|
+
});
|
|
524
|
+
|
|
525
|
+
// src/operations/pagePostsByTag.ts
|
|
526
|
+
import { Query as Query22, readOperation as readOperation5 } from "roc-db";
|
|
527
|
+
import { z as z37 } from "zod";
|
|
528
|
+
var pagePostsByTag = readOperation5("pagePostsByTag", z37.string(), (txn) => {
|
|
529
|
+
const tag = txn.payload;
|
|
530
|
+
return Query22(() => txn.pageEntitiesByIndex("Post", "tags", tag));
|
|
269
531
|
});
|
|
270
532
|
|
|
271
533
|
// src/operations/readEntity.ts
|
|
272
|
-
import { NotFoundError, Query as
|
|
273
|
-
import { z as
|
|
274
|
-
var readEntity =
|
|
534
|
+
import { NotFoundError, Query as Query23, QueryChain as QueryChain9, readOperation as readOperation6 } from "roc-db";
|
|
535
|
+
import { z as z38 } from "zod";
|
|
536
|
+
var readEntity = readOperation6("readEntity", z38.string(), (txn) => {
|
|
275
537
|
const ref = txn.payload;
|
|
276
|
-
return
|
|
538
|
+
return QueryChain9(Query23(() => txn.readEntity(ref)), Query23((entity) => {
|
|
277
539
|
if (!entity) {
|
|
278
540
|
throw new NotFoundError(ref);
|
|
279
541
|
}
|
|
280
542
|
return entity;
|
|
281
543
|
}));
|
|
544
|
+
}, {
|
|
545
|
+
outputSchema: z38.union([
|
|
546
|
+
PostSchema,
|
|
547
|
+
BlockImageSchema,
|
|
548
|
+
BlockParagraphSchema
|
|
549
|
+
])
|
|
282
550
|
});
|
|
283
551
|
|
|
284
|
-
// src/operations/
|
|
285
|
-
import { Query as
|
|
286
|
-
|
|
552
|
+
// src/operations/readMutation.ts
|
|
553
|
+
import { NotFoundError as NotFoundError2, Query as Query24, QueryChain as QueryChain10, readOperation as readOperation7 } from "roc-db";
|
|
554
|
+
import { z as z39 } from "zod";
|
|
555
|
+
var readMutation = readOperation7("readMutation", z39.string(), (txn) => {
|
|
287
556
|
const ref = txn.payload;
|
|
288
|
-
return
|
|
557
|
+
return QueryChain10(Query24(() => txn.readMutation(ref)), Query24((entity) => {
|
|
558
|
+
if (!entity) {
|
|
559
|
+
throw new NotFoundError2(ref);
|
|
560
|
+
}
|
|
561
|
+
return entity;
|
|
562
|
+
}));
|
|
289
563
|
});
|
|
290
564
|
|
|
291
|
-
// src/operations/
|
|
292
|
-
import { Query as
|
|
565
|
+
// src/operations/readOrgSettings.ts
|
|
566
|
+
import { Query as Query25, readOperation as readOperation8 } from "roc-db";
|
|
567
|
+
import { z as z40 } from "zod";
|
|
568
|
+
var readOrgSettings = readOperation8("readOrgSettings", z40.object({}).optional(), (txn) => Query25(() => txn.readEntity("OrgSettings", true)));
|
|
293
569
|
|
|
294
|
-
// src/
|
|
295
|
-
import {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
ref
|
|
299
|
-
|
|
300
|
-
|
|
570
|
+
// src/operations/readPost.ts
|
|
571
|
+
import { Query as Query26, readOperation as readOperation9 } from "roc-db";
|
|
572
|
+
var readPost = readOperation9("readPost", PostRefSchema, (txn) => {
|
|
573
|
+
const ref = txn.payload;
|
|
574
|
+
return Query26(() => txn.readEntity(ref, true));
|
|
575
|
+
}, { outputSchema: PostSchema });
|
|
576
|
+
|
|
577
|
+
// src/operations/readPostBySlug.ts
|
|
578
|
+
import { Query as Query27, readOperation as readOperation10 } from "roc-db";
|
|
579
|
+
import { z as z41 } from "zod";
|
|
580
|
+
var readPostBySlug = readOperation10("readPostBySlug", z41.string(), (txn) => {
|
|
581
|
+
const slug = txn.payload;
|
|
582
|
+
return Query27(() => txn.readEntityByUniqueField("Post", "slug", slug));
|
|
583
|
+
}, { outputSchema: PostSchema });
|
|
584
|
+
|
|
585
|
+
// src/operations/testTransactionalEdits.ts
|
|
586
|
+
import { expect } from "bun:test";
|
|
587
|
+
import { Query as Query28, QueryChain as QueryChain11, writeOperation as writeOperation18 } from "roc-db";
|
|
588
|
+
import { z as z42 } from "zod";
|
|
589
|
+
var TestCreatePatchDeleteInSameTransaction = (txn, title) => {
|
|
590
|
+
const postRef = txn.createRef("Post");
|
|
591
|
+
return QueryChain11(Query28(() => txn.createEntity(postRef, {
|
|
592
|
+
data: { title, tags: [] },
|
|
593
|
+
children: { blocks: [] }
|
|
594
|
+
})), Query28(() => txn.patchEntity(postRef, { data: { foo: "bar" } })), Query28((post) => {
|
|
595
|
+
expect(post.data.title).toBe(title);
|
|
596
|
+
expect(post.data.foo).toBe("bar");
|
|
597
|
+
}), Query28(() => txn.patchEntity(postRef, { data: { foo: null, bar: "foo" } })), Query28((post) => {
|
|
598
|
+
expect(post.data.title).toBe(title);
|
|
599
|
+
expect(post.data.foo).toBeUndefined();
|
|
600
|
+
expect(post.data.bar).toBe("foo");
|
|
601
|
+
expect(txn.log).toHaveLength(1);
|
|
602
|
+
expect(txn.log.get(postRef)?.[0]).toBe("create");
|
|
603
|
+
}), Query28((post) => txn.deleteEntity(postRef)), Query28((res) => {
|
|
604
|
+
expect(res).toBe(1);
|
|
605
|
+
expect(txn.log).toHaveLength(0);
|
|
606
|
+
}));
|
|
607
|
+
};
|
|
608
|
+
var TestUpdateAndDeleteInSameTransaction = (txn, ref) => {
|
|
609
|
+
return QueryChain11(Query28(() => txn.patchEntity(ref, { data: { foo: "bar" } })), Query28((post) => {
|
|
610
|
+
expect(post.data.foo).toBe("bar");
|
|
611
|
+
}), Query28(() => txn.patchEntity(ref, { data: { foo: null, bar: "foo" } })), Query28((post) => {
|
|
612
|
+
expect(post.data.foo).toBeUndefined();
|
|
613
|
+
expect(post.data.bar).toBe("foo");
|
|
614
|
+
expect(txn.log).toHaveLength(1);
|
|
615
|
+
expect(txn.log.get(ref)?.[0]).toBe("update");
|
|
616
|
+
}), Query28((post) => txn.deleteEntity(ref)), Query28((res) => {
|
|
617
|
+
expect(res).toBe(1);
|
|
618
|
+
expect(txn.log).toHaveLength(1);
|
|
619
|
+
expect(txn.log.get(ref)?.[0]).toBe("delete");
|
|
620
|
+
}));
|
|
621
|
+
};
|
|
622
|
+
var TestCreateOnExistingRef = (txn) => {
|
|
623
|
+
const ref = txn.createRef("Post");
|
|
624
|
+
return QueryChain11(Query28(() => txn.createEntity(ref, { data: { foo: "bar" } })), Query28(() => txn.createEntity(ref, { data: { foo: "bar" } })));
|
|
625
|
+
};
|
|
626
|
+
var PayloadSchema4 = z42.object({
|
|
627
|
+
name: z42.string().optional(),
|
|
628
|
+
post1ref: PostRefSchema.optional(),
|
|
629
|
+
post2ref: PostRefSchema.optional()
|
|
630
|
+
}).strict();
|
|
631
|
+
var testTransactionalEdits = writeOperation18("testTransactionalEdits", PayloadSchema4, (txn) => {
|
|
632
|
+
const { name, post1ref, post2ref } = txn.payload;
|
|
633
|
+
if (name)
|
|
634
|
+
return TestCreatePatchDeleteInSameTransaction(txn, name);
|
|
635
|
+
if (post1ref)
|
|
636
|
+
return TestUpdateAndDeleteInSameTransaction(txn, post1ref);
|
|
637
|
+
if (post2ref)
|
|
638
|
+
return TestCreateOnExistingRef(txn);
|
|
639
|
+
}, {});
|
|
301
640
|
|
|
302
641
|
// src/operations/updateBlockParagraph.ts
|
|
303
|
-
|
|
642
|
+
import { Query as Query29, writeOperation as writeOperation19 } from "roc-db";
|
|
643
|
+
import { z as z43 } from "zod";
|
|
644
|
+
var updateBlockParagraph = writeOperation19("updateBlockParagraph", z43.object({
|
|
645
|
+
ref: BlockParagraphRefSchema,
|
|
646
|
+
content: z43.string()
|
|
647
|
+
}), (txn) => {
|
|
304
648
|
const { ref, content } = txn.payload;
|
|
305
|
-
return
|
|
649
|
+
return Query29(() => txn.patchEntity(ref, {
|
|
306
650
|
data: { content }
|
|
307
651
|
}));
|
|
308
|
-
});
|
|
652
|
+
}, { outputSchema: BlockParagraphSchema });
|
|
653
|
+
|
|
654
|
+
// src/operations/updateOrgSettingsName.ts
|
|
655
|
+
import { Query as Query30, writeOperation as writeOperation20 } from "roc-db";
|
|
656
|
+
import { z as z44 } from "zod";
|
|
657
|
+
var updateOrgSettingsName = writeOperation20("updateOrgSettingsName", z44.object({ name: z44.string() }), (txn) => {
|
|
658
|
+
const { name } = txn.payload;
|
|
659
|
+
return Query30(() => txn.patchEntity("OrgSettings", { data: { name } }));
|
|
660
|
+
}, { debounce: 10 });
|
|
309
661
|
|
|
310
662
|
// src/operations/updatePost.ts
|
|
311
|
-
import { Query as
|
|
312
|
-
|
|
663
|
+
import { Query as Query31, writeOperation as writeOperation21 } from "roc-db";
|
|
664
|
+
import { z as z45 } from "zod";
|
|
665
|
+
var PayloadSchema5 = z45.object({
|
|
666
|
+
ref: PostRefSchema,
|
|
667
|
+
title: z45.string().optional(),
|
|
668
|
+
tags: z45.array(z45.string()).optional().default([]),
|
|
669
|
+
authorRef: UserRefSchema.optional()
|
|
670
|
+
});
|
|
671
|
+
var updatePost = writeOperation21("updatePost", PayloadSchema5, (txn) => {
|
|
313
672
|
const { ref, authorRef, ...data } = txn.payload;
|
|
314
|
-
return
|
|
673
|
+
return Query31(() => txn.updateEntity(ref, {
|
|
315
674
|
data,
|
|
316
675
|
parents: { author: authorRef },
|
|
317
676
|
children: { blocks: [] }
|
|
318
677
|
}));
|
|
319
|
-
});
|
|
678
|
+
}, { outputSchema: PostSchema });
|
|
679
|
+
|
|
680
|
+
// src/operations/updatePostDescription.ts
|
|
681
|
+
import { Query as Query32, writeOperation as writeOperation22 } from "roc-db";
|
|
682
|
+
import { z as z46 } from "zod";
|
|
683
|
+
var updatePostDescription = writeOperation22("updatePostDescription", z46.object({ ref: PostRefSchema, description: z46.string() }), (txn) => {
|
|
684
|
+
const { ref, description } = txn.payload;
|
|
685
|
+
return Query32(() => txn.patchEntity(ref, { data: { description } }));
|
|
686
|
+
}, { debounce: 10, changeSetOnly: true, outputSchema: PostSchema });
|
|
687
|
+
|
|
688
|
+
// src/operations/updatePostSlug.ts
|
|
689
|
+
import { Query as Query33, writeOperation as writeOperation23 } from "roc-db";
|
|
690
|
+
import { z as z47 } from "zod";
|
|
691
|
+
var updatePostSlug = writeOperation23("updatePostSlug", z47.object({ ref: PostRefSchema, slug: z47.string() }), (txn) => {
|
|
692
|
+
const { ref, slug } = txn.payload;
|
|
693
|
+
return Query33(() => txn.patchEntity(ref, { data: { slug } }));
|
|
694
|
+
}, { debounce: 10, outputSchema: PostSchema });
|
|
695
|
+
|
|
696
|
+
// src/operations/updatePostTags.ts
|
|
697
|
+
import { Query as Query34, writeOperation as writeOperation24 } from "roc-db";
|
|
698
|
+
import { z as z48 } from "zod";
|
|
699
|
+
var updatePostTags = writeOperation24("updatePostTags", z48.object({ ref: PostRefSchema, tags: z48.array(z48.string()) }), (txn) => {
|
|
700
|
+
const { ref, tags } = txn.payload;
|
|
701
|
+
return Query34(() => txn.patchEntity(ref, { data: { tags } }));
|
|
702
|
+
}, { debounce: 10, outputSchema: PostSchema });
|
|
320
703
|
|
|
321
704
|
// src/operations/updatePostTitle.ts
|
|
322
|
-
import { Query as
|
|
323
|
-
|
|
705
|
+
import { Query as Query35, writeOperation as writeOperation25 } from "roc-db";
|
|
706
|
+
import { z as z49 } from "zod";
|
|
707
|
+
var updatePostTitle = writeOperation25("updatePostTitle", z49.object({ ref: PostRefSchema, title: z49.string() }), (txn) => {
|
|
324
708
|
const { ref, title } = txn.payload;
|
|
325
|
-
return
|
|
326
|
-
}, { debounce: 10 });
|
|
709
|
+
return Query35(() => txn.patchEntity(ref, { data: { title } }));
|
|
710
|
+
}, { debounce: 10, outputSchema: PostSchema });
|
|
711
|
+
|
|
712
|
+
// src/operations/crudBySlug.ts
|
|
713
|
+
import { Query as Query36, QueryChain as QueryChain12, writeOperation as writeOperation26 } from "roc-db";
|
|
714
|
+
import { z as z50 } from "zod";
|
|
715
|
+
var crudBySlug = writeOperation26("crudBySlug", z50.object({ slug: z50.string(), newSlug: z50.string() }), (txn) => {
|
|
716
|
+
const { slug, newSlug } = txn.payload;
|
|
717
|
+
return QueryChain12(Query36(() => txn.readEntityByUniqueField("Post", "slug", slug)), Query36((post) => txn.patchEntity(post.ref, { data: { slug: newSlug } })), Query36(() => txn.readEntityByUniqueField("Post", "slug", newSlug)), Query36((post) => txn.deleteEntity(post.ref)), Query36(() => {
|
|
718
|
+
return [
|
|
719
|
+
txn.readEntityByUniqueField("Post", "slug", slug, false),
|
|
720
|
+
txn.readEntityByUniqueField("Post", "slug", newSlug, false)
|
|
721
|
+
];
|
|
722
|
+
}));
|
|
723
|
+
});
|
|
327
724
|
|
|
328
725
|
// src/operations/index.ts
|
|
329
726
|
var operations = [
|
|
727
|
+
applyDraft,
|
|
330
728
|
createBlockImage,
|
|
331
729
|
createBlockTitle,
|
|
332
730
|
createBlockParagrah,
|
|
333
731
|
createBlockRow,
|
|
732
|
+
createBlockRowReadingRoot,
|
|
334
733
|
createDraft,
|
|
734
|
+
createOrgSettings,
|
|
335
735
|
createPost,
|
|
336
|
-
|
|
736
|
+
createUnknownRef,
|
|
737
|
+
createUser,
|
|
738
|
+
crudBySlug,
|
|
739
|
+
deleteBlocks,
|
|
740
|
+
deleteDraft,
|
|
741
|
+
deleteOrgSettings,
|
|
337
742
|
deletePost,
|
|
743
|
+
duplicateDraft,
|
|
744
|
+
readPostBySlug,
|
|
745
|
+
moveBlocks,
|
|
746
|
+
pagePostsByTag,
|
|
747
|
+
pageBlocks,
|
|
338
748
|
readEntity,
|
|
749
|
+
readMutation,
|
|
750
|
+
readOrgSettings,
|
|
339
751
|
readPost,
|
|
752
|
+
pageEmptyEntitiesArray,
|
|
753
|
+
pagePosts,
|
|
754
|
+
pageSplat,
|
|
755
|
+
testTransactionalEdits,
|
|
340
756
|
updateBlockParagraph,
|
|
757
|
+
updateOrgSettingsName,
|
|
341
758
|
updatePost,
|
|
759
|
+
updatePostDescription,
|
|
760
|
+
updatePostSlug,
|
|
761
|
+
updatePostTags,
|
|
342
762
|
updatePostTitle
|
|
343
763
|
];
|
|
344
764
|
// src/testAdapterImplementation.ts
|
|
345
|
-
import { beforeAll, describe, expect, test } from "bun:test";
|
|
346
|
-
import {
|
|
347
|
-
|
|
348
|
-
|
|
765
|
+
import { beforeAll, describe, expect as expect2, test } from "bun:test";
|
|
766
|
+
import {
|
|
767
|
+
BadRequestError,
|
|
768
|
+
ConflictError,
|
|
769
|
+
Entity as Entity9,
|
|
770
|
+
NotFoundError as NotFoundError3,
|
|
771
|
+
Snowflake
|
|
772
|
+
} from "roc-db";
|
|
773
|
+
import { z as z51 } from "zod";
|
|
774
|
+
import { faker } from "@faker-js/faker";
|
|
775
|
+
var snowflake = new Snowflake(10, 10);
|
|
776
|
+
var prepareChangeSetTest = async (adapter, adapter2) => {
|
|
777
|
+
const [post, createPostMutation] = await adapter.createPost({
|
|
349
778
|
title: "Title 1",
|
|
350
|
-
slug:
|
|
779
|
+
slug: faker.lorem.slug(5),
|
|
351
780
|
tags: ["Foo", "Bar"]
|
|
352
781
|
});
|
|
353
|
-
|
|
782
|
+
expect2(createPostMutation.log).toStrictEqual([[post.ref, "create"]]);
|
|
783
|
+
const [draft, createDraftMutation] = await adapter.createDraft({
|
|
354
784
|
postRef: post.ref
|
|
355
785
|
});
|
|
786
|
+
expect2(createDraftMutation.log).toStrictEqual([[draft.ref, "create"]]);
|
|
356
787
|
const changeSetAdapter = adapter.changeSet(draft.ref);
|
|
357
|
-
const [
|
|
788
|
+
const [
|
|
789
|
+
{ block: blockParagraph1, updatedParent: updatedPost },
|
|
790
|
+
createBlockParagraphMutation
|
|
791
|
+
] = await changeSetAdapter.createBlockParagraph({
|
|
358
792
|
parentRef: post.ref
|
|
359
793
|
});
|
|
360
|
-
|
|
794
|
+
expect2(updatedPost.children.blocks).toStrictEqual([blockParagraph1.ref]);
|
|
795
|
+
expect2(updatedPost.children.blocks).toHaveLength(1);
|
|
796
|
+
expect2(createBlockParagraphMutation.log[1][2].children.blocks).toStrictEqual([]);
|
|
797
|
+
const readPost1 = await changeSetAdapter.readEntity(post.ref);
|
|
798
|
+
expect2(readPost1.children.blocks).toHaveLength(1);
|
|
799
|
+
const [{ block: blockRow, updatedParent: updatedPost2 }, mutation] = await changeSetAdapter.createBlockRow({
|
|
361
800
|
parentRef: post.ref
|
|
362
801
|
});
|
|
363
|
-
|
|
802
|
+
expect2(updatedPost2.children.blocks).toHaveLength(2);
|
|
803
|
+
const readPost2 = await changeSetAdapter.readEntity(post.ref);
|
|
804
|
+
expect2(readPost2.children.blocks).toHaveLength(2);
|
|
805
|
+
const [{ block: blockParagraph2, updatedParent: updatedBlockRow }] = await changeSetAdapter.createBlockParagraph({
|
|
364
806
|
parentRef: blockRow.ref
|
|
365
807
|
});
|
|
808
|
+
const readPost3 = await changeSetAdapter.readEntity(post.ref);
|
|
809
|
+
expect2(readPost3.children.blocks).toHaveLength(2);
|
|
366
810
|
return {
|
|
367
811
|
postRef: post.ref,
|
|
368
812
|
draftRef: draft.ref,
|
|
369
813
|
changeSetAdapter,
|
|
370
814
|
blockParagraph1,
|
|
371
815
|
blockParagraph2,
|
|
372
|
-
blockRow,
|
|
373
|
-
|
|
816
|
+
blockRow: updatedBlockRow,
|
|
817
|
+
draft,
|
|
818
|
+
post: readPost3
|
|
374
819
|
};
|
|
375
820
|
};
|
|
376
|
-
var testAdapterImplementation = (adapterConstructor,
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
});
|
|
390
|
-
post = createPostRes[0];
|
|
391
|
-
postRef = createPostRes[0].ref;
|
|
392
|
-
createPostMutation = createPostRes[1];
|
|
393
|
-
});
|
|
394
|
-
test("create (createEntity function)", async () => {
|
|
395
|
-
expect(post).toMatchZodSchema(PostSchema);
|
|
396
|
-
expect(post.data.title).toBe("Title 1");
|
|
397
|
-
expect(post.data.tags).toStrictEqual(["Foo", "Bar"]);
|
|
398
|
-
});
|
|
399
|
-
test("read (readEntity function)", async () => {
|
|
400
|
-
const readPostRes = await adapter1.readPost(postRef);
|
|
401
|
-
expect(readPostRes.data.title).toStrictEqual("Title 1");
|
|
402
|
-
expect(readPostRes.data.tags).toStrictEqual(["Foo", "Bar"]);
|
|
403
|
-
expect(readPostRes).toMatchZodSchema(PostSchema);
|
|
404
|
-
});
|
|
405
|
-
test("update (updateEntity function)", async () => {
|
|
406
|
-
const [post2] = await adapter1.updatePost({
|
|
407
|
-
ref: postRef,
|
|
408
|
-
title: "Title 2",
|
|
409
|
-
tags: ["Foo"]
|
|
410
|
-
});
|
|
411
|
-
expect(post2.data.tags).toStrictEqual(["Foo"]);
|
|
412
|
-
expect(post2.data.title).toBe("Title 2");
|
|
413
|
-
expect(post2).toMatchZodSchema(PostSchema);
|
|
414
|
-
});
|
|
415
|
-
test("updateTitle (patchEntity function + debounce)", async () => {
|
|
416
|
-
const updatePostTitleRes1 = await adapter1.updatePostTitle({
|
|
417
|
-
ref: postRef,
|
|
418
|
-
title: "Title 3"
|
|
419
|
-
});
|
|
420
|
-
expect(updatePostTitleRes1[0]).toMatchZodSchema(PostSchema);
|
|
421
|
-
const updatePostTitleRes2 = await adapter1.updatePostTitle({
|
|
422
|
-
ref: postRef,
|
|
423
|
-
title: "Title 4"
|
|
424
|
-
});
|
|
425
|
-
expect(updatePostTitleRes2[0]).toMatchZodSchema(PostSchema);
|
|
426
|
-
expect(updatePostTitleRes2[1].ref).toBe(updatePostTitleRes1[1].ref);
|
|
427
|
-
expect(updatePostTitleRes2[1].timestamp >= updatePostTitleRes1[1].timestamp).toBeTrue();
|
|
428
|
-
});
|
|
429
|
-
test("delete (deleteEntity function)", async () => {
|
|
430
|
-
const [count, mutation] = await adapter1.deletePost(postRef);
|
|
431
|
-
expect(count).toBe(1);
|
|
432
|
-
expect(mutation.log).toStrictEqual([[postRef, "delete", null]]);
|
|
433
|
-
});
|
|
434
|
-
test("sync mutation", async () => {
|
|
435
|
-
const res = await adapter2.syncOptimisticMutation(createPostMutation);
|
|
436
|
-
expect(res[0]).toStrictEqual(post);
|
|
437
|
-
expect(res[1]).toStrictEqual(createPostMutation);
|
|
438
|
-
expect(() => adapter2.syncOptimisticMutation(createPostMutation)).toThrowError(BadRequestError);
|
|
439
|
-
});
|
|
440
|
-
});
|
|
441
|
-
describe("changeSet", async () => {
|
|
442
|
-
let postRef, draftRef, changeSetAdapter, blockParagraph1, post, blockRow, blockParagraph2;
|
|
443
|
-
beforeAll(async () => {
|
|
444
|
-
({
|
|
445
|
-
postRef,
|
|
446
|
-
draftRef,
|
|
447
|
-
changeSetAdapter,
|
|
448
|
-
blockParagraph1,
|
|
449
|
-
post,
|
|
450
|
-
blockRow,
|
|
451
|
-
blockParagraph2
|
|
452
|
-
} = await prepareChangeSetTest(adapter1));
|
|
453
|
-
});
|
|
454
|
-
test("create (createEntity function w/changeSetRef)", async () => {
|
|
455
|
-
expect(blockParagraph1).toMatchZodSchema(BlockParagraphSchema);
|
|
456
|
-
expect(post).toMatchZodSchema(PostSchema);
|
|
457
|
-
});
|
|
458
|
-
test("read (readEntity function w/changeSetRef)", async () => {
|
|
459
|
-
const read = await changeSetAdapter.readEntity(blockParagraph1.ref);
|
|
460
|
-
expect(read).toMatchZodSchema(BlockParagraphSchema);
|
|
461
|
-
});
|
|
462
|
-
test("update (patchEntity function w/changeSetRef)", async () => {
|
|
463
|
-
const [updatedBlock] = await changeSetAdapter.updateBlockParagraph({
|
|
464
|
-
ref: blockParagraph1.ref,
|
|
465
|
-
content: "Hello, world!"
|
|
466
|
-
});
|
|
467
|
-
expect(updatedBlock).toMatchZodSchema(BlockParagraphSchema);
|
|
468
|
-
});
|
|
469
|
-
test("delete (with cascade delete)", async () => {
|
|
470
|
-
const [count, mutation] = await changeSetAdapter.deletePost(postRef);
|
|
471
|
-
expect(count).toBe(4);
|
|
472
|
-
expect(mutation.log).toStrictEqual([
|
|
473
|
-
[blockParagraph1.ref, "delete", draftRef],
|
|
474
|
-
[blockRow.ref, "delete", draftRef],
|
|
475
|
-
[blockParagraph2.ref, "delete", draftRef],
|
|
476
|
-
[postRef, "delete", draftRef]
|
|
477
|
-
]);
|
|
478
|
-
await expect(() => changeSetAdapter.readEntity(blockParagraph1.ref)).toThrow(NotFoundError2);
|
|
479
|
-
await expect(() => changeSetAdapter.updateBlockParagraph({
|
|
480
|
-
ref: blockParagraph1.ref,
|
|
481
|
-
content: "Foo"
|
|
482
|
-
})).toThrow(NotFoundError2);
|
|
483
|
-
});
|
|
484
|
-
test("pageMutations", async () => {
|
|
485
|
-
const res = await changeSetAdapter.pageMutations({
|
|
486
|
-
changeSetRef: draftRef
|
|
487
|
-
});
|
|
488
|
-
expect(res.length).toBeGreaterThan(0);
|
|
489
|
-
expect(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
|
|
490
|
-
});
|
|
491
|
-
test("pageMutations2", async () => {
|
|
492
|
-
const res = await changeSetAdapter.pageMutations({
|
|
493
|
-
changeSetRef: draftRef
|
|
494
|
-
});
|
|
495
|
-
expect(res.length).toBeGreaterThan(0);
|
|
496
|
-
expect(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
|
|
497
|
-
});
|
|
821
|
+
var testAdapterImplementation = async (adapterConstructor, generateArgs) => {
|
|
822
|
+
let createAdapter = async ({
|
|
823
|
+
optimistic = false,
|
|
824
|
+
session = { identityRef: "User/42" },
|
|
825
|
+
engineArgs
|
|
826
|
+
} = {}) => {
|
|
827
|
+
return adapterConstructor({
|
|
828
|
+
operations,
|
|
829
|
+
entities,
|
|
830
|
+
session,
|
|
831
|
+
snowflake,
|
|
832
|
+
optimistic,
|
|
833
|
+
...engineArgs ?? await generateArgs()
|
|
498
834
|
});
|
|
499
835
|
};
|
|
836
|
+
let adapter1, adapter2;
|
|
837
|
+
beforeAll(async () => {
|
|
838
|
+
adapter1 = await createAdapter();
|
|
839
|
+
adapter2 = await createAdapter();
|
|
840
|
+
});
|
|
841
|
+
describe("Post CRUD", () => {
|
|
842
|
+
let postRef;
|
|
843
|
+
let post;
|
|
844
|
+
let createPostMutation;
|
|
845
|
+
beforeAll(async () => {
|
|
846
|
+
const createPostRes = await adapter1.createPost({
|
|
847
|
+
title: "Title 1",
|
|
848
|
+
slug: faker.lorem.slug(5),
|
|
849
|
+
tags: ["Foo", "Bar"]
|
|
850
|
+
});
|
|
851
|
+
post = createPostRes[0];
|
|
852
|
+
postRef = createPostRes[0].ref;
|
|
853
|
+
createPostMutation = createPostRes[1];
|
|
854
|
+
});
|
|
855
|
+
test("create (createEntity function)", async () => {
|
|
856
|
+
expect2(post).toMatchZodSchema(PostEntity.schema);
|
|
857
|
+
expect2(post.data.title).toBe("Title 1");
|
|
858
|
+
expect2(post.data.tags).toStrictEqual(["Foo", "Bar"]);
|
|
859
|
+
expect2(createPostMutation).toMatchZodSchema(CreatePostMutationSchema);
|
|
860
|
+
});
|
|
861
|
+
test("read (readEntity function)", async () => {
|
|
862
|
+
const readPostRes = await adapter1.readPost(postRef);
|
|
863
|
+
expect2(readPostRes.data.title).toStrictEqual("Title 1");
|
|
864
|
+
expect2(readPostRes.data.tags).toStrictEqual(["Foo", "Bar"]);
|
|
865
|
+
expect2(readPostRes).toMatchZodSchema(PostEntity.schema);
|
|
866
|
+
});
|
|
867
|
+
test("read by unique", async () => {
|
|
868
|
+
const readPostRes = await adapter1.readPostBySlug(post.data.slug);
|
|
869
|
+
expect2(readPostRes.data.title).toStrictEqual("Title 1");
|
|
870
|
+
expect2(readPostRes.data.tags).toStrictEqual(["Foo", "Bar"]);
|
|
871
|
+
expect2(readPostRes.data.slug).toStrictEqual(post.data.slug);
|
|
872
|
+
});
|
|
873
|
+
test("create with same slug", async () => {
|
|
874
|
+
expect2(() => adapter1.createPost({
|
|
875
|
+
title: "Title 2",
|
|
876
|
+
slug: post.data.slug,
|
|
877
|
+
tags: ["Foo", "Bar"]
|
|
878
|
+
})).toThrow(ConflictError);
|
|
879
|
+
});
|
|
880
|
+
test("update unique slug", async () => {
|
|
881
|
+
const slug1 = faker.lorem.slug(5);
|
|
882
|
+
const slug2 = faker.lorem.slug(5);
|
|
883
|
+
const [post2] = await adapter1.createPost({
|
|
884
|
+
title: "Title 1",
|
|
885
|
+
slug: slug1
|
|
886
|
+
});
|
|
887
|
+
const readPostRes1 = await adapter1.readPostBySlug(slug1);
|
|
888
|
+
expect2(readPostRes1.data.slug).toStrictEqual(slug1);
|
|
889
|
+
const [updateRes] = await adapter1.updatePostSlug({
|
|
890
|
+
ref: post2.ref,
|
|
891
|
+
slug: slug2
|
|
892
|
+
});
|
|
893
|
+
expect2(updateRes.data.slug).toStrictEqual(slug2);
|
|
894
|
+
expect2(() => adapter1.readPostBySlug(slug1)).toThrow(NotFoundError3);
|
|
895
|
+
const readPostRes2 = await adapter1.readPostBySlug(slug2);
|
|
896
|
+
expect2(readPostRes2.data.slug).toStrictEqual(slug2);
|
|
897
|
+
});
|
|
898
|
+
test("update and delete post by slug", async () => {
|
|
899
|
+
const slug1 = faker.lorem.slug(5);
|
|
900
|
+
const slug2 = faker.lorem.slug(5);
|
|
901
|
+
const [post2] = await adapter1.createPost({
|
|
902
|
+
title: "Title 1",
|
|
903
|
+
slug: slug1
|
|
904
|
+
});
|
|
905
|
+
const [res] = await adapter1.crudBySlug({
|
|
906
|
+
slug: slug1,
|
|
907
|
+
newSlug: slug2
|
|
908
|
+
});
|
|
909
|
+
expect2(res).toStrictEqual([null, null]);
|
|
910
|
+
});
|
|
911
|
+
test("update index entries", async () => {
|
|
912
|
+
const [post2] = await adapter1.createPost({
|
|
913
|
+
title: "Title 1",
|
|
914
|
+
tags: ["foo"]
|
|
915
|
+
});
|
|
916
|
+
const pageTagFoo1 = await adapter1.pagePostsByTag("foo");
|
|
917
|
+
expect2(pageTagFoo1.length).toBe(1);
|
|
918
|
+
expect2(pageTagFoo1[0].ref).toBe(post2.ref);
|
|
919
|
+
const [updatedRes] = await adapter1.updatePostTags({
|
|
920
|
+
ref: post2.ref,
|
|
921
|
+
tags: ["bar"]
|
|
922
|
+
});
|
|
923
|
+
const pageTagFoo2 = await adapter1.pagePostsByTag("foo");
|
|
924
|
+
expect2(pageTagFoo2.length).toBe(0);
|
|
925
|
+
const pageTagBar1 = await adapter1.pagePostsByTag("bar");
|
|
926
|
+
expect2(pageTagBar1.length).toBe(1);
|
|
927
|
+
await adapter1.deletePost(post2.ref);
|
|
928
|
+
const pageTagBar2 = await adapter1.pagePostsByTag("bar");
|
|
929
|
+
expect2(pageTagBar2.length).toBe(0);
|
|
930
|
+
});
|
|
931
|
+
test("read not found (readEntity function)", async () => {
|
|
932
|
+
expect2(() => adapter1.readPost("Post/999")).toThrow(NotFoundError3);
|
|
933
|
+
});
|
|
934
|
+
test.todo("update (updateEntity function)", async () => {
|
|
935
|
+
const [post2] = await adapter1.updatePost({
|
|
936
|
+
ref: postRef,
|
|
937
|
+
title: "Title 2",
|
|
938
|
+
tags: ["Foo"]
|
|
939
|
+
});
|
|
940
|
+
expect2(post2.data.tags).toStrictEqual(["Foo"]);
|
|
941
|
+
expect2(post2.data.title).toBe("Title 2");
|
|
942
|
+
expect2(post2).toMatchZodSchema(PostEntity.schema);
|
|
943
|
+
});
|
|
944
|
+
test("updateTitle (patchEntity function + debounce)", async () => {
|
|
945
|
+
const [update1, mutation1] = await adapter1.updatePostTitle({
|
|
946
|
+
ref: postRef,
|
|
947
|
+
title: "Title 3"
|
|
948
|
+
});
|
|
949
|
+
expect2(update1).toMatchZodSchema(PostEntity.schema);
|
|
950
|
+
expect2(mutation1).toMatchZodSchema(UpdatePostTitleMutationSchema);
|
|
951
|
+
const [update2, mutation2] = await adapter1.updatePostTitle({
|
|
952
|
+
ref: postRef,
|
|
953
|
+
title: "Title 4"
|
|
954
|
+
});
|
|
955
|
+
expect2(update2).toMatchZodSchema(PostEntity.schema);
|
|
956
|
+
expect2(mutation2).toMatchZodSchema(UpdatePostTitleMutationSchema);
|
|
957
|
+
expect2(mutation1.ref).toBe(mutation2.ref);
|
|
958
|
+
expect2(mutation2.timestamp >= mutation1.timestamp).toBeTrue();
|
|
959
|
+
});
|
|
960
|
+
test("updatePostDescription without changeSetAdapter fails with BadRequestError", async () => {
|
|
961
|
+
expect2(() => adapter1.updatePostDescription({
|
|
962
|
+
ref: postRef,
|
|
963
|
+
description: "Description 1"
|
|
964
|
+
})).toThrow(BadRequestError);
|
|
965
|
+
});
|
|
966
|
+
test("delete (deleteEntity function)", async () => {
|
|
967
|
+
const currentPost = await adapter1.readPost(postRef);
|
|
968
|
+
expect2(currentPost.ref).toBe(postRef);
|
|
969
|
+
const [count, mutation] = await adapter1.deletePost(postRef);
|
|
970
|
+
expect2(count).toBe(1);
|
|
971
|
+
expect2(mutation.log).toStrictEqual([
|
|
972
|
+
[postRef, "delete", currentPost]
|
|
973
|
+
]);
|
|
974
|
+
expect2(() => adapter1.readPost(postRef)).toThrow(NotFoundError3);
|
|
975
|
+
});
|
|
976
|
+
test("sync mutation", async () => {
|
|
977
|
+
const {
|
|
978
|
+
persistedAt: ignore,
|
|
979
|
+
...createPostMutationWithoutPersistedAt
|
|
980
|
+
} = createPostMutation;
|
|
981
|
+
const [{ persistedAt, ...mutation }] = await adapter2.persistOptimisticMutations([createPostMutation]);
|
|
982
|
+
expect2(mutation).toStrictEqual(createPostMutationWithoutPersistedAt);
|
|
983
|
+
});
|
|
984
|
+
test("sync mutation with debounce > 0", async () => {
|
|
985
|
+
const [post2, createPostMutation2] = await adapter1.createPost({
|
|
986
|
+
title: "Foo"
|
|
987
|
+
});
|
|
988
|
+
const [{ persistedAt, ...mutation }] = await adapter2.persistOptimisticMutations([createPostMutation2]);
|
|
989
|
+
const {
|
|
990
|
+
persistedAt: ignore,
|
|
991
|
+
...createPostMutationWithoutPersistedAt
|
|
992
|
+
} = createPostMutation2;
|
|
993
|
+
expect2(mutation).toStrictEqual(createPostMutationWithoutPersistedAt);
|
|
994
|
+
const res = await adapter1.updatePostTitle({
|
|
995
|
+
ref: post2.ref,
|
|
996
|
+
title: "A"
|
|
997
|
+
});
|
|
998
|
+
const [, debounceMutation] = await adapter1.updatePostTitle({
|
|
999
|
+
ref: post2.ref,
|
|
1000
|
+
title: "A"
|
|
1001
|
+
});
|
|
1002
|
+
expect2(debounceMutation.debounceCount).toBe(1);
|
|
1003
|
+
const [debounceMutationPersist] = await adapter2.persistOptimisticMutations([debounceMutation]);
|
|
1004
|
+
expect2(debounceMutationPersist.debounceCount).toBe(1);
|
|
1005
|
+
expect2(debounceMutationPersist.persistedAt).toBeDefined();
|
|
1006
|
+
});
|
|
1007
|
+
test("create, patch and delete the same item within the same transaction", async () => {
|
|
1008
|
+
const [post1] = await adapter1.createPost({ title: "Post 1" });
|
|
1009
|
+
const [post2] = await adapter1.createPost({ title: "Post 1" });
|
|
1010
|
+
const [currentPost, mutation] = await adapter1.testTransactionalEdits({
|
|
1011
|
+
name: "Test"
|
|
1012
|
+
});
|
|
1013
|
+
expect2(mutation.log).toHaveLength(0);
|
|
1014
|
+
const [, mutation2] = await adapter1.testTransactionalEdits({
|
|
1015
|
+
post1ref: post1.ref
|
|
1016
|
+
});
|
|
1017
|
+
expect2(mutation2.log).toHaveLength(1);
|
|
1018
|
+
expect2(mutation2.log[0][1]).toBe("delete");
|
|
1019
|
+
expect2(() => adapter1.testTransactionalEdits({
|
|
1020
|
+
post2ref: post2.ref
|
|
1021
|
+
})).toThrow(BadRequestError);
|
|
1022
|
+
});
|
|
1023
|
+
});
|
|
1024
|
+
describe("OrgSettings singleton", () => {
|
|
1025
|
+
let adapter;
|
|
1026
|
+
beforeAll(async () => {
|
|
1027
|
+
adapter = await createAdapter();
|
|
1028
|
+
});
|
|
1029
|
+
test("create returns bare-name ref", async () => {
|
|
1030
|
+
const [orgSettings] = await adapter.createOrgSettings({
|
|
1031
|
+
name: "Acme",
|
|
1032
|
+
theme: "dark",
|
|
1033
|
+
primaryAdmin: "User/42"
|
|
1034
|
+
});
|
|
1035
|
+
expect2(orgSettings.ref).toBe("OrgSettings");
|
|
1036
|
+
expect2(orgSettings.entity).toBe("OrgSettings");
|
|
1037
|
+
expect2(orgSettings.data.name).toBe("Acme");
|
|
1038
|
+
expect2(orgSettings.parents.primaryAdmin).toBe("User/42");
|
|
1039
|
+
expect2(orgSettings.children.featuredPosts).toStrictEqual([]);
|
|
1040
|
+
});
|
|
1041
|
+
test("read by bare-name ref", async () => {
|
|
1042
|
+
const orgSettings = await adapter.readOrgSettings();
|
|
1043
|
+
expect2(orgSettings.ref).toBe("OrgSettings");
|
|
1044
|
+
expect2(orgSettings.data.name).toBe("Acme");
|
|
1045
|
+
});
|
|
1046
|
+
test("second create throws ConflictError", async () => {
|
|
1047
|
+
expect2(() => adapter.createOrgSettings({ name: "Other" })).toThrow(ConflictError);
|
|
1048
|
+
});
|
|
1049
|
+
test("patch + debounce collapses mutations", async () => {
|
|
1050
|
+
const [, mutation1] = await adapter.updateOrgSettingsName({
|
|
1051
|
+
name: "Acme Co"
|
|
1052
|
+
});
|
|
1053
|
+
const [updated, mutation2] = await adapter.updateOrgSettingsName({
|
|
1054
|
+
name: "Acme Inc"
|
|
1055
|
+
});
|
|
1056
|
+
expect2(updated.data.name).toBe("Acme Inc");
|
|
1057
|
+
expect2(mutation1.ref).toBe(mutation2.ref);
|
|
1058
|
+
expect2(mutation2.debounceCount).toBeGreaterThanOrEqual(1);
|
|
1059
|
+
});
|
|
1060
|
+
test("debounce does not collapse across identities", async () => {
|
|
1061
|
+
const sharedEngineArgs = await generateArgs();
|
|
1062
|
+
const adapterA = await createAdapter({
|
|
1063
|
+
session: { identityRef: "User/A" },
|
|
1064
|
+
engineArgs: sharedEngineArgs
|
|
1065
|
+
});
|
|
1066
|
+
const adapterB = await createAdapter({
|
|
1067
|
+
session: { identityRef: "User/B" },
|
|
1068
|
+
engineArgs: sharedEngineArgs
|
|
1069
|
+
});
|
|
1070
|
+
await adapterA.createOrgSettings({ name: "Acme" });
|
|
1071
|
+
const [, mutationA] = await adapterA.updateOrgSettingsName({
|
|
1072
|
+
name: "From A"
|
|
1073
|
+
});
|
|
1074
|
+
const [, mutationB] = await adapterB.updateOrgSettingsName({
|
|
1075
|
+
name: "From B"
|
|
1076
|
+
});
|
|
1077
|
+
expect2(mutationA.ref).not.toBe(mutationB.ref);
|
|
1078
|
+
expect2(mutationA.identityRef).toBe("User/A");
|
|
1079
|
+
expect2(mutationB.identityRef).toBe("User/B");
|
|
1080
|
+
await adapterA.deleteOrgSettings();
|
|
1081
|
+
});
|
|
1082
|
+
test("delete removes the singleton", async () => {
|
|
1083
|
+
const [count] = await adapter.deleteOrgSettings();
|
|
1084
|
+
expect2(count).toBe(1);
|
|
1085
|
+
expect2(() => adapter.readOrgSettings()).toThrow(NotFoundError3);
|
|
1086
|
+
});
|
|
1087
|
+
test("recreate after delete works", async () => {
|
|
1088
|
+
const [orgSettings] = await adapter.createOrgSettings({
|
|
1089
|
+
name: "NewOrg"
|
|
1090
|
+
});
|
|
1091
|
+
expect2(orgSettings.ref).toBe("OrgSettings");
|
|
1092
|
+
expect2(orgSettings.data.name).toBe("NewOrg");
|
|
1093
|
+
});
|
|
1094
|
+
test("constructor rejects singleton + uniqueDataKeys", () => {
|
|
1095
|
+
expect2(() => new Entity9("Bad", {
|
|
1096
|
+
singleton: true,
|
|
1097
|
+
data: z51.object({ name: z51.string() }),
|
|
1098
|
+
uniqueDataKeys: ["name"]
|
|
1099
|
+
})).toThrow(/singleton/);
|
|
1100
|
+
});
|
|
1101
|
+
test("createRef throws on unregistered entity", async () => {
|
|
1102
|
+
expect2(() => adapter.createUnknownRef()).toThrow(BadRequestError);
|
|
1103
|
+
});
|
|
1104
|
+
});
|
|
1105
|
+
describe("paging", () => {
|
|
1106
|
+
let adapter;
|
|
1107
|
+
let post1ref;
|
|
1108
|
+
beforeAll(async () => {
|
|
1109
|
+
adapter = await createAdapter();
|
|
1110
|
+
const [post1] = await adapter.createPost({ title: "Post 1" });
|
|
1111
|
+
post1ref = post1.ref;
|
|
1112
|
+
const [user] = await adapter.createUser({ email: "foo@bar.com" });
|
|
1113
|
+
const [draft1] = await adapter.createDraft({
|
|
1114
|
+
postRef: post1.ref
|
|
1115
|
+
});
|
|
1116
|
+
const [post2] = await adapter.createPost({ title: "Post 2" });
|
|
1117
|
+
const [draft2] = await adapter.createDraft({
|
|
1118
|
+
postRef: post2.ref
|
|
1119
|
+
});
|
|
1120
|
+
const draft1adapter = adapter.changeSet(draft1.ref);
|
|
1121
|
+
await draft1adapter.createBlockImage({
|
|
1122
|
+
parentRef: post1.ref,
|
|
1123
|
+
url: "https://example.com/image.png"
|
|
1124
|
+
});
|
|
1125
|
+
await draft1adapter.createBlockParagraph({
|
|
1126
|
+
parentRef: post1.ref
|
|
1127
|
+
});
|
|
1128
|
+
await adapter.applyDraft(draft1.ref);
|
|
1129
|
+
const draft2adapter = adapter.changeSet(draft2.ref);
|
|
1130
|
+
await draft2adapter.createBlockImage({
|
|
1131
|
+
parentRef: post2.ref,
|
|
1132
|
+
url: "https://example.com/image.png"
|
|
1133
|
+
});
|
|
1134
|
+
await draft2adapter.createBlockParagraph({
|
|
1135
|
+
parentRef: post2.ref
|
|
1136
|
+
});
|
|
1137
|
+
await adapter.applyDraft(draft2.ref);
|
|
1138
|
+
});
|
|
1139
|
+
test("limited to given collection", async () => {
|
|
1140
|
+
const res = await adapter.pagePosts();
|
|
1141
|
+
expect2(res).toHaveLength(2);
|
|
1142
|
+
});
|
|
1143
|
+
test("limit", async () => {
|
|
1144
|
+
const res = await adapter.pagePosts({ size: 1 });
|
|
1145
|
+
expect2(res).toHaveLength(1);
|
|
1146
|
+
});
|
|
1147
|
+
test("pageSplat", async () => {
|
|
1148
|
+
const res = await adapter.pageSplat({});
|
|
1149
|
+
expect2(res).toHaveLength(11);
|
|
1150
|
+
});
|
|
1151
|
+
test("pageEmptyEntitiesArray", async () => {
|
|
1152
|
+
const res = await adapter.pageEmptyEntitiesArray({});
|
|
1153
|
+
expect2(res).toHaveLength(0);
|
|
1154
|
+
});
|
|
1155
|
+
test("pageBlocks", async () => {
|
|
1156
|
+
const res = await adapter.pageBlocks({});
|
|
1157
|
+
expect2(res).toHaveLength(4);
|
|
1158
|
+
});
|
|
1159
|
+
test("pageBlocks with parent ref", async () => {
|
|
1160
|
+
const res = await adapter.pageBlocks({ parentRef: post1ref });
|
|
1161
|
+
expect2(res).toHaveLength(2);
|
|
1162
|
+
expect2(res[0].parents.parent).toBe(post1ref);
|
|
1163
|
+
expect2(res[1].parents.parent).toBe(post1ref);
|
|
1164
|
+
});
|
|
1165
|
+
});
|
|
1166
|
+
describe("changeSet", () => {
|
|
1167
|
+
let postRef, draftRef, changeSetAdapter, blockParagraph1, post, blockRow, blockParagraph2, draft;
|
|
1168
|
+
beforeAll(async () => {
|
|
1169
|
+
({
|
|
1170
|
+
postRef,
|
|
1171
|
+
draftRef,
|
|
1172
|
+
changeSetAdapter,
|
|
1173
|
+
blockParagraph1,
|
|
1174
|
+
post,
|
|
1175
|
+
blockRow,
|
|
1176
|
+
blockParagraph2,
|
|
1177
|
+
draft
|
|
1178
|
+
} = await prepareChangeSetTest(adapter1, adapter2));
|
|
1179
|
+
});
|
|
1180
|
+
test("create (createEntity function w/changeSetRef)", async () => {
|
|
1181
|
+
expect2(blockParagraph1).toMatchZodSchema(BlockParagraph.schema);
|
|
1182
|
+
expect2(post).toMatchZodSchema(PostEntity.schema);
|
|
1183
|
+
});
|
|
1184
|
+
test("read (readEntity function w/changeSetRef)", async () => {
|
|
1185
|
+
const read = await changeSetAdapter.readEntity(blockParagraph1.ref);
|
|
1186
|
+
expect2(read).toMatchZodSchema(BlockParagraph.schema);
|
|
1187
|
+
});
|
|
1188
|
+
test("update (patchEntity function w/changeSetRef)", async () => {
|
|
1189
|
+
const [updatedBlock] = await changeSetAdapter.updateBlockParagraph({
|
|
1190
|
+
ref: blockParagraph1.ref,
|
|
1191
|
+
content: "Hello, world!"
|
|
1192
|
+
});
|
|
1193
|
+
expect2(updatedBlock).toMatchZodSchema(BlockParagraph.schema);
|
|
1194
|
+
});
|
|
1195
|
+
test("move (batchReadEntities function)", async () => {
|
|
1196
|
+
const res = await changeSetAdapter.moveBlocks({
|
|
1197
|
+
refs: [blockParagraph1.ref],
|
|
1198
|
+
targetPosition: 1
|
|
1199
|
+
});
|
|
1200
|
+
});
|
|
1201
|
+
test("delete (with cascade delete)", async () => {
|
|
1202
|
+
const postUpdated = await changeSetAdapter.readEntity(postRef);
|
|
1203
|
+
const blockParagraph1Update = await changeSetAdapter.readEntity(blockParagraph1.ref);
|
|
1204
|
+
const blockRowUpdated = await changeSetAdapter.readEntity(blockRow.ref);
|
|
1205
|
+
const [count, mutation] = await changeSetAdapter.deletePost(postRef);
|
|
1206
|
+
expect2(count).toBe(4);
|
|
1207
|
+
expect2(mutation.log).toStrictEqual([
|
|
1208
|
+
[blockParagraph1.ref, "delete", blockParagraph1Update],
|
|
1209
|
+
[blockParagraph2.ref, "delete", blockParagraph2],
|
|
1210
|
+
[blockRow.ref, "delete", blockRowUpdated],
|
|
1211
|
+
[postRef, "delete", postUpdated]
|
|
1212
|
+
]);
|
|
1213
|
+
await expect2(() => changeSetAdapter.readEntity(blockParagraph1.ref)).toThrow(NotFoundError3);
|
|
1214
|
+
await expect2(() => changeSetAdapter.updateBlockParagraph({
|
|
1215
|
+
ref: blockParagraph1.ref,
|
|
1216
|
+
content: "Foo"
|
|
1217
|
+
})).toThrow(NotFoundError3);
|
|
1218
|
+
});
|
|
1219
|
+
test("pageMutations", async () => {
|
|
1220
|
+
const res = await changeSetAdapter.pageMutations({
|
|
1221
|
+
changeSetRef: draftRef
|
|
1222
|
+
});
|
|
1223
|
+
expect2(res.length).toBeGreaterThan(0);
|
|
1224
|
+
expect2(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
|
|
1225
|
+
});
|
|
1226
|
+
test("pageMutations run again", async () => {
|
|
1227
|
+
const res = await changeSetAdapter.pageMutations({
|
|
1228
|
+
changeSetRef: draftRef
|
|
1229
|
+
});
|
|
1230
|
+
expect2(res.length).toBeGreaterThan(0);
|
|
1231
|
+
expect2(res.every((m) => m.changeSetRef === draftRef)).toBeTrue();
|
|
1232
|
+
});
|
|
1233
|
+
test("invalid changeSetRef throws error", async () => {
|
|
1234
|
+
const changeSetAdapter2 = adapter1.changeSet("Draft/123");
|
|
1235
|
+
expect2(() => changeSetAdapter2.createPost({ title: "Title 1" })).toThrow(BadRequestError);
|
|
1236
|
+
});
|
|
1237
|
+
test("duplicateDraft (txn.duplicateChangeSetMutations) produces an independent copy with remapped refs", async () => {
|
|
1238
|
+
const [post2] = await adapter1.createPost({
|
|
1239
|
+
title: "Title 1",
|
|
1240
|
+
slug: faker.lorem.slug(5)
|
|
1241
|
+
});
|
|
1242
|
+
const [sourceDraft] = await adapter1.createDraft({
|
|
1243
|
+
postRef: post2.ref
|
|
1244
|
+
});
|
|
1245
|
+
const sourceCs = adapter1.changeSet(sourceDraft.ref);
|
|
1246
|
+
const [{ block: row }] = await sourceCs.createBlockRow({
|
|
1247
|
+
parentRef: post2.ref
|
|
1248
|
+
});
|
|
1249
|
+
const [{ block: para }] = await sourceCs.createBlockParagraph({
|
|
1250
|
+
parentRef: row.ref,
|
|
1251
|
+
content: "Hello"
|
|
1252
|
+
});
|
|
1253
|
+
const [{ draftRef: newDraftRef, mutations, refMap }] = await adapter1.duplicateDraft({
|
|
1254
|
+
sourceRef: sourceDraft.ref,
|
|
1255
|
+
postRef: post2.ref
|
|
1256
|
+
});
|
|
1257
|
+
expect2(mutations).toHaveLength(2);
|
|
1258
|
+
const newRow = refMap.get(row.ref);
|
|
1259
|
+
const newPara = refMap.get(para.ref);
|
|
1260
|
+
expect2(newRow).toBeDefined();
|
|
1261
|
+
expect2(newPara).toBeDefined();
|
|
1262
|
+
expect2(newRow).not.toBe(row.ref);
|
|
1263
|
+
expect2(newPara).not.toBe(para.ref);
|
|
1264
|
+
expect2([...refMap.values()]).not.toContain(row.ref);
|
|
1265
|
+
expect2([...refMap.values()]).not.toContain(para.ref);
|
|
1266
|
+
const targetCs = adapter1.changeSet(newDraftRef);
|
|
1267
|
+
expect2((await targetCs.readEntity(newRow)).ref).toBe(newRow);
|
|
1268
|
+
expect2((await targetCs.readEntity(newPara)).parents.parent).toBe(newRow);
|
|
1269
|
+
expect2((await sourceCs.readEntity(para.ref)).parents.parent).toBe(row.ref);
|
|
1270
|
+
});
|
|
1271
|
+
test("duplicateDraft when a source op reads the changeSet root (one-transaction, pending target root)", async () => {
|
|
1272
|
+
const [post2] = await adapter1.createPost({
|
|
1273
|
+
title: "Title 1",
|
|
1274
|
+
slug: faker.lorem.slug(5)
|
|
1275
|
+
});
|
|
1276
|
+
const [sourceDraft] = await adapter1.createDraft({
|
|
1277
|
+
postRef: post2.ref
|
|
1278
|
+
});
|
|
1279
|
+
await adapter1.changeSet(sourceDraft.ref).createBlockRowReadingRoot({ parentRef: post2.ref });
|
|
1280
|
+
const [{ draftRef: newDraftRef, mutations, refMap }] = await adapter1.duplicateDraft({
|
|
1281
|
+
sourceRef: sourceDraft.ref,
|
|
1282
|
+
postRef: post2.ref
|
|
1283
|
+
});
|
|
1284
|
+
expect2(mutations).toHaveLength(1);
|
|
1285
|
+
expect2(mutations[0].operation.name).toBe("createBlockRowReadingRoot");
|
|
1286
|
+
const newRow = [...refMap.values()][0];
|
|
1287
|
+
expect2(newRow).toBeDefined();
|
|
1288
|
+
const targetCs = adapter1.changeSet(newDraftRef);
|
|
1289
|
+
expect2((await targetCs.readEntity(newRow)).ref).toBe(newRow);
|
|
1290
|
+
});
|
|
1291
|
+
test("deleteBlocks (patch running 2 times removing on array element every time)", async () => {
|
|
1292
|
+
const [post2, createPostMutation] = await adapter1.createPost({
|
|
1293
|
+
title: "Title 1",
|
|
1294
|
+
slug: faker.lorem.slug(5),
|
|
1295
|
+
tags: ["Foo", "Bar"]
|
|
1296
|
+
});
|
|
1297
|
+
const [draft2, createDraftMutation] = await adapter1.createDraft({
|
|
1298
|
+
postRef: post2.ref
|
|
1299
|
+
});
|
|
1300
|
+
const changeSetAdapter2 = adapter1.changeSet(draft2.ref);
|
|
1301
|
+
const [{ block: blockParagraph12 }, createBlockParagraph1Mutation] = await changeSetAdapter2.createBlockParagraph({
|
|
1302
|
+
parentRef: post2.ref
|
|
1303
|
+
});
|
|
1304
|
+
const [{ block: blockParagraph22 }, createBlockParagraph2Mutation] = await changeSetAdapter2.createBlockParagraph({
|
|
1305
|
+
parentRef: post2.ref
|
|
1306
|
+
});
|
|
1307
|
+
const readPost2 = await changeSetAdapter2.readEntity(post2.ref);
|
|
1308
|
+
expect2(readPost2.children.blocks).toEqual([
|
|
1309
|
+
blockParagraph12.ref,
|
|
1310
|
+
blockParagraph22.ref
|
|
1311
|
+
]);
|
|
1312
|
+
const [, deleteMutation] = await changeSetAdapter2.deleteBlocks([
|
|
1313
|
+
blockParagraph12.ref,
|
|
1314
|
+
blockParagraph22.ref
|
|
1315
|
+
]);
|
|
1316
|
+
expect2(deleteMutation.log[0][2].children.blocks).toEqual([
|
|
1317
|
+
blockParagraph12.ref,
|
|
1318
|
+
blockParagraph22.ref
|
|
1319
|
+
]);
|
|
1320
|
+
expect2(deleteMutation.log[0][2].updated.mutationRef).toBe(createBlockParagraph2Mutation.ref);
|
|
1321
|
+
const readPost22 = await changeSetAdapter2.readEntity(post2.ref);
|
|
1322
|
+
expect2(readPost22.updated.mutationRef).toEqual(deleteMutation.ref);
|
|
1323
|
+
});
|
|
1324
|
+
test("applyDraft", async () => {
|
|
1325
|
+
const { draftRef: draftRef2, post: post2, changeSetAdapter: changeSetAdapter2 } = await prepareChangeSetTest(adapter1);
|
|
1326
|
+
const [version, mutation] = await adapter1.applyDraft(draftRef2);
|
|
1327
|
+
expect2(() => changeSetAdapter2.createBlockImage({
|
|
1328
|
+
parentRef: post2.ref,
|
|
1329
|
+
url: "https://example.com/image.png"
|
|
1330
|
+
})).toThrowError("The provided changeSetRef has already been applied");
|
|
1331
|
+
});
|
|
1332
|
+
test("deleteDraft", async () => {
|
|
1333
|
+
const { draftRef: draftRef2 } = await prepareChangeSetTest(adapter1);
|
|
1334
|
+
const mutationsBefore = await adapter1.pageMutations({
|
|
1335
|
+
changeSetRef: draftRef2
|
|
1336
|
+
});
|
|
1337
|
+
const [, mutation] = await adapter1.deleteDraft(draftRef2);
|
|
1338
|
+
expect2(mutation.log).toHaveLength(mutationsBefore.length + 1);
|
|
1339
|
+
const mutationsAfter = await adapter1.pageMutations({
|
|
1340
|
+
changeSetRef: draftRef2
|
|
1341
|
+
});
|
|
1342
|
+
expect2(mutationsAfter).toHaveLength(0);
|
|
1343
|
+
});
|
|
1344
|
+
test("init adapter2", async () => {
|
|
1345
|
+
const adapterA = await createAdapter({ optimistic: true });
|
|
1346
|
+
const adapterB = await createAdapter({ optimistic: true });
|
|
1347
|
+
const { draftRef: draftRef2 } = await prepareChangeSetTest(adapterA, adapterB);
|
|
1348
|
+
const mutations = await adapterA.pageMutations({
|
|
1349
|
+
changeSetRef: draftRef2
|
|
1350
|
+
});
|
|
1351
|
+
const allMutationsAdapter1 = await adapterA.pageMutations({});
|
|
1352
|
+
const allMutationsAdapter2 = await adapterB.pageMutations({});
|
|
1353
|
+
expect2(allMutationsAdapter1).not.toBeEmpty();
|
|
1354
|
+
expect2(allMutationsAdapter2).toBeEmpty();
|
|
1355
|
+
const res = await adapterB.loadMutations(allMutationsAdapter1);
|
|
1356
|
+
const allMutationsAdapter2after = await adapterB.pageMutations({});
|
|
1357
|
+
expect2(allMutationsAdapter2after.length).toBe(allMutationsAdapter1.length);
|
|
1358
|
+
const res2 = await adapterB.loadMutations(allMutationsAdapter1);
|
|
1359
|
+
});
|
|
1360
|
+
test("persisted at", async () => {
|
|
1361
|
+
const adapterA = await createAdapter({ optimistic: false });
|
|
1362
|
+
const adapterB = await createAdapter({ optimistic: true });
|
|
1363
|
+
const [, mutationNonOptimistic] = await adapterA.createPost({
|
|
1364
|
+
title: "Foo"
|
|
1365
|
+
});
|
|
1366
|
+
expect2(mutationNonOptimistic.persistedAt).toBeDefined();
|
|
1367
|
+
expect2(mutationNonOptimistic.persistedAt).toBe(mutationNonOptimistic.timestamp);
|
|
1368
|
+
const [, mutationOptimistic] = await adapterB.createPost({
|
|
1369
|
+
title: "Foo"
|
|
1370
|
+
});
|
|
1371
|
+
expect2(mutationOptimistic.persistedAt).toBeNull();
|
|
1372
|
+
const [mutationOptimisticPersisted] = await adapterA.persistOptimisticMutations([mutationOptimistic]);
|
|
1373
|
+
expect2(mutationOptimisticPersisted.persistedAt).toBeString();
|
|
1374
|
+
});
|
|
1375
|
+
test("persistOptimisticMutations", async () => {
|
|
1376
|
+
const persistedAdapter = await createAdapter({ optimistic: false });
|
|
1377
|
+
const optimisticAdapter = await createAdapter({ optimistic: true });
|
|
1378
|
+
expect2(persistedAdapter.persistOptimisticMutations).toBeDefined();
|
|
1379
|
+
expect2(optimisticAdapter.loadMutations).toBeDefined();
|
|
1380
|
+
const [post2, createPostMutation] = await optimisticAdapter.createPost({
|
|
1381
|
+
title: "Foo",
|
|
1382
|
+
slug: faker.lorem.slug(5),
|
|
1383
|
+
tags: []
|
|
1384
|
+
});
|
|
1385
|
+
const [persistCratePostMutation] = await persistedAdapter.persistOptimisticMutations([
|
|
1386
|
+
createPostMutation
|
|
1387
|
+
]);
|
|
1388
|
+
expect2(persistCratePostMutation.persistedAt >= createPostMutation.timestamp).toBeTrue();
|
|
1389
|
+
const readMutation2 = await persistedAdapter.readMutation(persistCratePostMutation.ref);
|
|
1390
|
+
expect2(readMutation2).toStrictEqual(persistCratePostMutation);
|
|
1391
|
+
const [draft2, { persistedAt: ignore, ...createDraftMutation }] = await optimisticAdapter.createDraft({
|
|
1392
|
+
postRef: post2.ref
|
|
1393
|
+
});
|
|
1394
|
+
const [{ persistedAt, ...persistedCreateDraftMutation }] = await persistedAdapter.persistOptimisticMutations([
|
|
1395
|
+
createDraftMutation
|
|
1396
|
+
]);
|
|
1397
|
+
expect2(persistedCreateDraftMutation).toStrictEqual(createDraftMutation);
|
|
1398
|
+
const changeSetAdapter2 = optimisticAdapter.changeSet(draft2.ref);
|
|
1399
|
+
const [res] = await changeSetAdapter2.createBlockParagraph({
|
|
1400
|
+
parentRef: post2.ref
|
|
1401
|
+
});
|
|
1402
|
+
});
|
|
1403
|
+
});
|
|
500
1404
|
};
|
|
501
1405
|
// src/inMemoryAdapter.ts
|
|
502
1406
|
import { createInMemoryAdapter } from "@roc-db/in-memory";
|
|
503
1407
|
var inMemoryAdapter = createInMemoryAdapter({
|
|
504
1408
|
operations,
|
|
505
|
-
entities
|
|
1409
|
+
entities,
|
|
1410
|
+
session: {
|
|
1411
|
+
identityRef: "User/42"
|
|
1412
|
+
}
|
|
506
1413
|
});
|
|
507
1414
|
export {
|
|
508
1415
|
testAdapterImplementation,
|