on-zero 0.9.7 → 0.10.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/cjs/generate-helpers.test.cjs +0 -38
- package/dist/cjs/generate-helpers.test.native.js +0 -38
- package/dist/cjs/generate-helpers.test.native.js.map +1 -1
- package/dist/cjs/generate-lite.test.cjs +0 -522
- package/dist/cjs/generate-lite.test.native.js +0 -525
- package/dist/cjs/generate-lite.test.native.js.map +1 -1
- package/dist/cjs/generate.test.cjs +0 -691
- package/dist/cjs/generate.test.native.js +0 -691
- package/dist/cjs/generate.test.native.js.map +1 -1
- package/dist/cjs/mutations.test.cjs +0 -11
- package/dist/cjs/mutations.test.native.js +0 -18
- package/dist/cjs/mutations.test.native.js.map +1 -1
- package/dist/cjs/server.test.cjs +0 -93
- package/dist/cjs/server.test.native.js +0 -101
- package/dist/cjs/server.test.native.js.map +1 -1
- package/dist/cjs/serverWhere.test.cjs +0 -45
- package/dist/cjs/serverWhere.test.native.js +0 -51
- package/dist/cjs/serverWhere.test.native.js.map +1 -1
- package/dist/esm/generate-helpers.test.mjs +1 -39
- package/dist/esm/generate-helpers.test.mjs.map +1 -1
- package/dist/esm/generate-helpers.test.native.js +1 -39
- package/dist/esm/generate-helpers.test.native.js.map +1 -1
- package/dist/esm/generate-lite.test.mjs +0 -522
- package/dist/esm/generate-lite.test.mjs.map +1 -1
- package/dist/esm/generate-lite.test.native.js +0 -525
- package/dist/esm/generate-lite.test.native.js.map +1 -1
- package/dist/esm/generate.test.mjs +2 -668
- package/dist/esm/generate.test.mjs.map +1 -1
- package/dist/esm/generate.test.native.js +2 -668
- package/dist/esm/generate.test.native.js.map +1 -1
- package/dist/esm/mutations.test.mjs +0 -11
- package/dist/esm/mutations.test.mjs.map +1 -1
- package/dist/esm/mutations.test.native.js +0 -18
- package/dist/esm/mutations.test.native.js.map +1 -1
- package/dist/esm/server.test.mjs +0 -93
- package/dist/esm/server.test.mjs.map +1 -1
- package/dist/esm/server.test.native.js +0 -101
- package/dist/esm/server.test.native.js.map +1 -1
- package/dist/esm/serverWhere.test.mjs +0 -45
- package/dist/esm/serverWhere.test.mjs.map +1 -1
- package/dist/esm/serverWhere.test.native.js +0 -51
- package/dist/esm/serverWhere.test.native.js.map +1 -1
- package/package.json +1 -1
- package/src/generate-helpers.test.ts +0 -40
- package/src/generate-lite.test.ts +0 -586
- package/src/generate.test.ts +0 -844
- package/src/mutations.test.ts +0 -21
- package/src/server.test.ts +0 -75
- package/src/serverWhere.test.ts +0 -42
|
@@ -1,35 +1,9 @@
|
|
|
1
|
-
var __create = Object.create;
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
-
var __copyProps = (to, from, except, desc) => {
|
|
8
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
9
|
-
for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
10
|
-
get: () => from[key],
|
|
11
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
return to;
|
|
15
|
-
};
|
|
16
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
22
|
-
value: mod,
|
|
23
|
-
enumerable: true
|
|
24
|
-
}) : target, mod));
|
|
25
1
|
var import_node_fs = require("node:fs");
|
|
26
2
|
var import_node_os = require("node:os");
|
|
27
3
|
var import_node_path = require("node:path");
|
|
28
4
|
var import_node_vm = require("node:vm");
|
|
29
|
-
var zero = __toESM(require("@rocicorp/zero"), 1);
|
|
30
5
|
var import_vitest = require("vitest");
|
|
31
6
|
var import_generate = require("./generate.cjs");
|
|
32
|
-
const import_meta = {};
|
|
33
7
|
const testDir = (0, import_node_path.join)((0, import_node_os.tmpdir)(), "on-zero-test-" + Date.now());
|
|
34
8
|
function writeFileSync(path, content) {
|
|
35
9
|
(0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(path), {
|
|
@@ -50,105 +24,6 @@ function writeFileSync(path, content) {
|
|
|
50
24
|
});
|
|
51
25
|
});
|
|
52
26
|
(0, import_vitest.describe)("generate", () => {
|
|
53
|
-
(0, import_vitest.test)("generates models.ts, types.ts, tables.ts from model files", async () => {
|
|
54
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/mutations.ts"), `
|
|
55
|
-
import { table, string, boolean } from 'on-zero'
|
|
56
|
-
|
|
57
|
-
export const schema = table('post', {
|
|
58
|
-
id: string(),
|
|
59
|
-
title: string(),
|
|
60
|
-
published: boolean(),
|
|
61
|
-
})
|
|
62
|
-
`);
|
|
63
|
-
writeFileSync((0, import_node_path.join)(testDir, "comment/mutations.ts"), `
|
|
64
|
-
import { table, string } from 'on-zero'
|
|
65
|
-
|
|
66
|
-
export const schema = table('comment', {
|
|
67
|
-
id: string(),
|
|
68
|
-
postId: string(),
|
|
69
|
-
body: string(),
|
|
70
|
-
})
|
|
71
|
-
`);
|
|
72
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/post.test.ts"), `throw new Error('test files must not be generated as models')`);
|
|
73
|
-
writeFileSync((0, import_node_path.join)(testDir, "comment/comment.spec.ts"), `throw new Error('spec files must not be generated as queries')`);
|
|
74
|
-
const result = await (0, import_generate.generate)({
|
|
75
|
-
dir: testDir,
|
|
76
|
-
silent: true
|
|
77
|
-
});
|
|
78
|
-
(0, import_vitest.expect)(result.modelCount).toBe(2);
|
|
79
|
-
(0, import_vitest.expect)(result.schemaCount).toBe(2);
|
|
80
|
-
(0, import_vitest.expect)(result.filesChanged).toBeGreaterThan(0);
|
|
81
|
-
(0, import_vitest.expect)((0, import_node_fs.existsSync)((0, import_node_path.join)(testDir, "generated/models.ts"))).toBe(true);
|
|
82
|
-
(0, import_vitest.expect)((0, import_node_fs.existsSync)((0, import_node_path.join)(testDir, "generated/types.ts"))).toBe(true);
|
|
83
|
-
(0, import_vitest.expect)((0, import_node_fs.existsSync)((0, import_node_path.join)(testDir, "generated/tables.ts"))).toBe(true);
|
|
84
|
-
const modelsContent = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/models.ts"), "utf-8");
|
|
85
|
-
(0, import_vitest.expect)(modelsContent).toContain("import * as comment from '../comment/mutations'");
|
|
86
|
-
(0, import_vitest.expect)(modelsContent).toContain("import * as post from '../post/mutations'");
|
|
87
|
-
(0, import_vitest.expect)(modelsContent).not.toContain("post.test");
|
|
88
|
-
(0, import_vitest.expect)(modelsContent).toContain("export const models = {");
|
|
89
|
-
const typesContent = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/types.ts"), "utf-8");
|
|
90
|
-
(0, import_vitest.expect)(typesContent).toContain("export type Post = TableInsertRow<typeof schema.post>");
|
|
91
|
-
(0, import_vitest.expect)(typesContent).toContain("export type Comment = TableInsertRow<typeof schema.comment>");
|
|
92
|
-
const tablesContent = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/tables.ts"), "utf-8");
|
|
93
|
-
(0, import_vitest.expect)(tablesContent).toContain("export { schema as post } from '../post/mutations'");
|
|
94
|
-
(0, import_vitest.expect)(tablesContent).toContain("export { schema as comment } from '../comment/mutations'");
|
|
95
|
-
});
|
|
96
|
-
(0, import_vitest.test)("generates query validators from query files", async () => {
|
|
97
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/mutations.ts"), `export const schema = table('post', { id: string() })`);
|
|
98
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/queries.ts"), `
|
|
99
|
-
import { zero } from '../zero'
|
|
100
|
-
|
|
101
|
-
export const allPosts = () => zero.query.post
|
|
102
|
-
|
|
103
|
-
export const postById = ({ id }: { id: string }) => zero.query.post.where('id', id)
|
|
104
|
-
|
|
105
|
-
export const postsByAuthor = ({ authorId, limit }: { authorId: string; limit?: number }) =>
|
|
106
|
-
zero.query.post.where('authorId', authorId).limit(limit ?? 10)
|
|
107
|
-
`);
|
|
108
|
-
const result = await (0, import_generate.generate)({
|
|
109
|
-
dir: testDir,
|
|
110
|
-
silent: true
|
|
111
|
-
});
|
|
112
|
-
(0, import_vitest.expect)(result.queryCount).toBe(3);
|
|
113
|
-
(0, import_vitest.expect)((0, import_node_fs.existsSync)((0, import_node_path.join)(testDir, "generated/groupedQueries.ts"))).toBe(true);
|
|
114
|
-
(0, import_vitest.expect)((0, import_node_fs.existsSync)((0, import_node_path.join)(testDir, "generated/syncedQueries.ts"))).toBe(true);
|
|
115
|
-
const groupedContent = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/groupedQueries.ts"), "utf-8");
|
|
116
|
-
(0, import_vitest.expect)(groupedContent).toContain("import * as postSource from '../post/queries'");
|
|
117
|
-
(0, import_vitest.expect)(groupedContent).toContain("postById: postSource.postById");
|
|
118
|
-
const syncedContent = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedQueries.ts"), "utf-8");
|
|
119
|
-
(0, import_vitest.expect)(syncedContent).toContain("allPosts: defineQuery");
|
|
120
|
-
(0, import_vitest.expect)(syncedContent).toContain("postById: defineQuery");
|
|
121
|
-
(0, import_vitest.expect)(syncedContent).toContain("postsByAuthor: defineQuery");
|
|
122
|
-
(0, import_vitest.expect)(syncedContent).toContain("v.object");
|
|
123
|
-
});
|
|
124
|
-
(0, import_vitest.test)("skips permission exports in queries", async () => {
|
|
125
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/mutations.ts"), `export const schema = table('post', { id: string() })`);
|
|
126
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/queries.ts"), `
|
|
127
|
-
export const permission = () => ({ canRead: true })
|
|
128
|
-
export const allPosts = () => zero.query.post
|
|
129
|
-
`);
|
|
130
|
-
const result = await (0, import_generate.generate)({
|
|
131
|
-
dir: testDir,
|
|
132
|
-
silent: true
|
|
133
|
-
});
|
|
134
|
-
(0, import_vitest.expect)(result.queryCount).toBe(1);
|
|
135
|
-
const syncedContent = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedQueries.ts"), "utf-8");
|
|
136
|
-
(0, import_vitest.expect)(syncedContent).toContain("allPosts");
|
|
137
|
-
(0, import_vitest.expect)(syncedContent).not.toContain("permission:");
|
|
138
|
-
});
|
|
139
|
-
(0, import_vitest.test)("aliases user import without changing the model key", async () => {
|
|
140
|
-
writeFileSync((0, import_node_path.join)(testDir, "user/mutations.ts"), `export const schema = table('user', { id: string(), name: string() })`);
|
|
141
|
-
await (0, import_generate.generate)({
|
|
142
|
-
dir: testDir,
|
|
143
|
-
silent: true
|
|
144
|
-
});
|
|
145
|
-
const modelsContent = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/models.ts"), "utf-8");
|
|
146
|
-
(0, import_vitest.expect)(modelsContent).toContain("import * as userPublic from '../user/mutations'");
|
|
147
|
-
(0, import_vitest.expect)(modelsContent).toContain("user: userPublic,");
|
|
148
|
-
(0, import_vitest.expect)(modelsContent).not.toContain("\n userPublic,");
|
|
149
|
-
const typesContent = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/types.ts"), "utf-8");
|
|
150
|
-
(0, import_vitest.expect)(typesContent).toContain("typeof schema.userPublic");
|
|
151
|
-
});
|
|
152
27
|
(0, import_vitest.test)("runs after command when files change", async () => {
|
|
153
28
|
writeFileSync((0, import_node_path.join)(testDir, "post/mutations.ts"), `export const schema = table('post', { id: string() })`);
|
|
154
29
|
const markerFile = (0, import_node_path.join)(testDir, "after-ran");
|
|
@@ -192,51 +67,6 @@ export const allPosts = () => zero.query.post
|
|
|
192
67
|
});
|
|
193
68
|
(0, import_vitest.describe)("instance layout", () => {
|
|
194
69
|
const dataDir = () => (0, import_node_path.join)(testDir, "src/data");
|
|
195
|
-
(0, import_vitest.test)("discovers file and folder namespaces and emits related sync closure", async () => {
|
|
196
|
-
writeFileSync((0, import_node_path.join)(dataDir(), "control/reaction.ts"), `export const allReactions = () => zql.reaction`);
|
|
197
|
-
writeFileSync((0, import_node_path.join)(dataDir(), "on-zero.config.ts"), `export default defineConfig({ instances: { control: {}, project: { scope: 'projectId' } } })`);
|
|
198
|
-
writeFileSync((0, import_node_path.join)(dataDir(), "project/message/queries.ts"), `
|
|
199
|
-
const unused = () => zql.message.related('notARealRelation')
|
|
200
|
-
const withComments = () => zql.message.related('comments', (q) => q.related('author'))
|
|
201
|
-
export const messages = () => withComments()
|
|
202
|
-
`);
|
|
203
|
-
writeFileSync((0, import_node_path.join)(dataDir(), "project/message/mutations.ts"), `export const schema = table('message').columns({ id: string(), projectId: string() })`);
|
|
204
|
-
writeFileSync((0, import_node_path.join)(dataDir(), "project/message/helpers.ts"), `export const privateHelper = () => 'ignored'`);
|
|
205
|
-
writeFileSync((0, import_node_path.join)(testDir, "src/database/relations.ts"), `
|
|
206
|
-
export const relations = defineRelations(schema, (r) => ({
|
|
207
|
-
message: { comments: r.many.comment({}) },
|
|
208
|
-
comment: { author: r.one.userPublic({}) },
|
|
209
|
-
}))
|
|
210
|
-
`);
|
|
211
|
-
writeFileSync((0, import_node_path.join)(testDir, "src/database/schema.ts"), `
|
|
212
|
-
export const comment = sqliteTable('comment', { id: text(), projectId: text() })
|
|
213
|
-
export const userPublic = sqliteTable('user_public', { id: text(), projectId: text() })
|
|
214
|
-
`);
|
|
215
|
-
const membership = await (0, import_generate.deriveDataMembership)({
|
|
216
|
-
dir: dataDir()
|
|
217
|
-
});
|
|
218
|
-
(0, import_vitest.expect)(membership.allTables).toEqual(["comment", "message", "reaction", "userPublic"]);
|
|
219
|
-
(0, import_vitest.expect)(membership.instances.project).toEqual({
|
|
220
|
-
tables: ["message"],
|
|
221
|
-
syncTables: ["comment", "message", "userPublic"],
|
|
222
|
-
supportTables: [],
|
|
223
|
-
scope: "projectId"
|
|
224
|
-
});
|
|
225
|
-
await (0, import_generate.generate)({
|
|
226
|
-
dir: dataDir(),
|
|
227
|
-
silent: true
|
|
228
|
-
});
|
|
229
|
-
const grouped = (0, import_node_fs.readFileSync)((0, import_node_path.join)(dataDir(), "generated/groupedQueries.ts"), "utf8");
|
|
230
|
-
(0, import_vitest.expect)(grouped).toContain("from '../control/reaction'");
|
|
231
|
-
(0, import_vitest.expect)(grouped).toContain("from '../project/message/queries'");
|
|
232
|
-
(0, import_vitest.expect)(grouped).not.toContain("privateHelper");
|
|
233
|
-
const manifest = (0, import_node_fs.readFileSync)((0, import_node_path.join)(dataDir(), "generated/instances.ts"), "utf8");
|
|
234
|
-
(0, import_vitest.expect)(manifest).toContain("control: {");
|
|
235
|
-
(0, import_vitest.expect)(manifest).toContain("project: {");
|
|
236
|
-
(0, import_vitest.expect)(manifest).toContain('tables: ["message"]');
|
|
237
|
-
(0, import_vitest.expect)(manifest).toContain('syncTables: ["comment","message","userPublic"]');
|
|
238
|
-
(0, import_vitest.expect)(manifest).toContain(`defaultVisibility: (value: string) => ({ column: "projectId", value })`);
|
|
239
|
-
});
|
|
240
70
|
(0, import_vitest.test)("derives query membership from the returned query root", async () => {
|
|
241
71
|
writeFileSync((0, import_node_path.join)(dataDir(), "category/mutations.ts"), `export const schema = table('category').columns({ id: string() })`);
|
|
242
72
|
writeFileSync((0, import_node_path.join)(dataDir(), "dashboard/queries.ts"), `export const monthSummary = () => zql.category.related('expenses')`);
|
|
@@ -445,42 +275,6 @@ export const messages = () => zql.message.related('author')
|
|
|
445
275
|
silent: true
|
|
446
276
|
})).rejects.toThrow(/namespace 'message'.*instances 'control' and 'project'/);
|
|
447
277
|
});
|
|
448
|
-
(0, import_vitest.test)("resolves configured instance directories relative to the config file", async () => {
|
|
449
|
-
writeFileSync((0, import_node_path.join)(dataDir(), "on-zero.config.ts"), `export default defineConfig({ instances: { control: { dir: './planes/control-data', supportTables: ['audit'] }, project: { dir: '../project-data', scope: 'projectId' } } })`);
|
|
450
|
-
writeFileSync((0, import_node_path.join)(dataDir(), "planes/control-data/account.ts"), `export const accounts = () => zql.account`);
|
|
451
|
-
writeFileSync((0, import_node_path.join)(testDir, "src/project-data/message.ts"), `export const schema = table('message').columns({ id: string(), projectId: string() })`);
|
|
452
|
-
await (0, import_vitest.expect)((0, import_generate.deriveDataMembership)({
|
|
453
|
-
dir: dataDir(),
|
|
454
|
-
config: (0, import_node_path.join)(dataDir(), "on-zero.config.ts")
|
|
455
|
-
})).resolves.toEqual({
|
|
456
|
-
instances: {
|
|
457
|
-
control: {
|
|
458
|
-
tables: ["account"],
|
|
459
|
-
syncTables: ["account"],
|
|
460
|
-
supportTables: ["audit"],
|
|
461
|
-
scope: null
|
|
462
|
-
},
|
|
463
|
-
project: {
|
|
464
|
-
tables: ["message"],
|
|
465
|
-
syncTables: ["message"],
|
|
466
|
-
supportTables: [],
|
|
467
|
-
scope: "projectId"
|
|
468
|
-
}
|
|
469
|
-
},
|
|
470
|
-
allTables: ["account", "audit", "message"]
|
|
471
|
-
});
|
|
472
|
-
await (0, import_vitest.expect)((0, import_generate.generate)({
|
|
473
|
-
dir: dataDir(),
|
|
474
|
-
config: (0, import_node_path.join)(dataDir(), "on-zero.config.ts"),
|
|
475
|
-
silent: true
|
|
476
|
-
})).resolves.toMatchObject({
|
|
477
|
-
modelCount: 1,
|
|
478
|
-
schemaCount: 1
|
|
479
|
-
});
|
|
480
|
-
const models = (0, import_node_fs.readFileSync)((0, import_node_path.join)(dataDir(), "generated/models.ts"), "utf8");
|
|
481
|
-
(0, import_vitest.expect)(models).toContain("from '../../project-data/message'");
|
|
482
|
-
(0, import_vitest.expect)(models).not.toContain("account");
|
|
483
|
-
});
|
|
484
278
|
(0, import_vitest.test)("rejects missing configured instance directories", async () => {
|
|
485
279
|
writeFileSync((0, import_node_path.join)(dataDir(), "on-zero.config.ts"), `export default defineConfig({ instances: { project: { dir: './missing' } } })`);
|
|
486
280
|
await (0, import_vitest.expect)((0, import_generate.deriveDataMembership)({
|
|
@@ -525,253 +319,6 @@ export const messages = () => zql.message.related('author')
|
|
|
525
319
|
});
|
|
526
320
|
});
|
|
527
321
|
(0, import_vitest.describe)("mutations", () => {
|
|
528
|
-
(0, import_vitest.test)("generates validators for inline mutation param types", async () => {
|
|
529
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/mutations.ts"), `
|
|
530
|
-
import { table, string } from 'on-zero'
|
|
531
|
-
import { mutations, serverWhere } from 'on-zero'
|
|
532
|
-
|
|
533
|
-
export const schema = table('post').columns({
|
|
534
|
-
id: string(),
|
|
535
|
-
title: string(),
|
|
536
|
-
}).primaryKey('id')
|
|
537
|
-
|
|
538
|
-
const perm = serverWhere('post', () => true)
|
|
539
|
-
|
|
540
|
-
export const mutate = mutations(schema, perm, {
|
|
541
|
-
archive: async ({ tx }, { id, reason }: { id: string; reason: string }) => {
|
|
542
|
-
await tx.mutate.post.update({ id, archived: true })
|
|
543
|
-
},
|
|
544
|
-
})
|
|
545
|
-
`);
|
|
546
|
-
const result = await (0, import_generate.generate)({
|
|
547
|
-
dir: testDir,
|
|
548
|
-
silent: true
|
|
549
|
-
});
|
|
550
|
-
(0, import_vitest.expect)(result.mutationCount).toBeGreaterThan(0);
|
|
551
|
-
(0, import_vitest.expect)((0, import_node_fs.existsSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"))).toBe(true);
|
|
552
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
553
|
-
(0, import_vitest.expect)(content).toContain("archive");
|
|
554
|
-
(0, import_vitest.expect)(content).toContain("v.object");
|
|
555
|
-
(0, import_vitest.expect)(content).toContain("v.string()");
|
|
556
|
-
});
|
|
557
|
-
(0, import_vitest.test)("generates CRUD validators from schema columns", async () => {
|
|
558
|
-
writeFileSync((0, import_node_path.join)(testDir, "task/mutations.ts"), `
|
|
559
|
-
import { table, string, number, boolean } from 'on-zero'
|
|
560
|
-
import { mutations, serverWhere } from 'on-zero'
|
|
561
|
-
|
|
562
|
-
export const schema = table('task').columns({
|
|
563
|
-
id: string(),
|
|
564
|
-
title: string(),
|
|
565
|
-
priority: number(),
|
|
566
|
-
done: boolean(),
|
|
567
|
-
note: string().optional(),
|
|
568
|
-
}).primaryKey('id')
|
|
569
|
-
|
|
570
|
-
const perm = serverWhere('task', () => true)
|
|
571
|
-
|
|
572
|
-
export const mutate = mutations(schema, perm)
|
|
573
|
-
`);
|
|
574
|
-
const result = await (0, import_generate.generate)({
|
|
575
|
-
dir: testDir,
|
|
576
|
-
silent: true
|
|
577
|
-
});
|
|
578
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
579
|
-
(0, import_vitest.expect)(content).toContain("insert:");
|
|
580
|
-
(0, import_vitest.expect)(content).toMatch(/insert:.*v\.object/);
|
|
581
|
-
(0, import_vitest.expect)(content).toContain("update:");
|
|
582
|
-
(0, import_vitest.expect)(content).toContain("delete:");
|
|
583
|
-
});
|
|
584
|
-
(0, import_vitest.test)("treats models without export const mutate as empty mutations", async () => {
|
|
585
|
-
writeFileSync((0, import_node_path.join)(testDir, "readonly/mutations.ts"), `
|
|
586
|
-
import { table, string } from 'on-zero'
|
|
587
|
-
|
|
588
|
-
export const schema = table('readonly').columns({
|
|
589
|
-
id: string(),
|
|
590
|
-
name: string(),
|
|
591
|
-
}).primaryKey('id')
|
|
592
|
-
`);
|
|
593
|
-
const result = await (0, import_generate.generate)({
|
|
594
|
-
dir: testDir,
|
|
595
|
-
silent: true
|
|
596
|
-
});
|
|
597
|
-
(0, import_vitest.expect)(result.mutationCount).toBe(0);
|
|
598
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
599
|
-
(0, import_vitest.expect)(content).toContain("readonly: {");
|
|
600
|
-
});
|
|
601
|
-
(0, import_vitest.test)("extracts custom mutations from bare mutations({})", async () => {
|
|
602
|
-
writeFileSync((0, import_node_path.join)(testDir, "admin/mutations.ts"), `
|
|
603
|
-
import { mutations } from 'on-zero'
|
|
604
|
-
|
|
605
|
-
export const mutate = mutations({
|
|
606
|
-
reset: async ({ tx }, { targetId }: { targetId: string }) => {
|
|
607
|
-
await tx.mutate.admin.delete({ id: targetId })
|
|
608
|
-
},
|
|
609
|
-
})
|
|
610
|
-
`);
|
|
611
|
-
const result = await (0, import_generate.generate)({
|
|
612
|
-
dir: testDir,
|
|
613
|
-
silent: true
|
|
614
|
-
});
|
|
615
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
616
|
-
(0, import_vitest.expect)(content).toContain("reset");
|
|
617
|
-
(0, import_vitest.expect)(content).toContain("v.string()");
|
|
618
|
-
});
|
|
619
|
-
(0, import_vitest.test)("generates validators for string-model multiline mutation params", async () => {
|
|
620
|
-
writeFileSync((0, import_node_path.join)(testDir, "agentEvent/mutations.ts"), `
|
|
621
|
-
import { mutations, serverWhere } from 'on-zero'
|
|
622
|
-
|
|
623
|
-
const perm = serverWhere('agentEvent', () => true)
|
|
624
|
-
|
|
625
|
-
export const mutate = mutations('agentEvent', perm, {
|
|
626
|
-
claimReviewLease: async (
|
|
627
|
-
{ tx },
|
|
628
|
-
props: {
|
|
629
|
-
id: string
|
|
630
|
-
projectId: string
|
|
631
|
-
agentId: string
|
|
632
|
-
userId: string
|
|
633
|
-
taskId: string
|
|
634
|
-
reviewKey: string
|
|
635
|
-
runnerId: string
|
|
636
|
-
createdAt: number
|
|
637
|
-
},
|
|
638
|
-
) => {
|
|
639
|
-
await tx.mutate.agentEvent.insert(props)
|
|
640
|
-
},
|
|
641
|
-
})
|
|
642
|
-
`);
|
|
643
|
-
await (0, import_generate.generate)({
|
|
644
|
-
dir: testDir,
|
|
645
|
-
silent: true
|
|
646
|
-
});
|
|
647
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
648
|
-
(0, import_vitest.expect)(content).toContain("claimReviewLease");
|
|
649
|
-
(0, import_vitest.expect)(content).toContain("projectId: v.string()");
|
|
650
|
-
(0, import_vitest.expect)(content).toContain("createdAt: v.number()");
|
|
651
|
-
(0, import_vitest.expect)(content).not.toContain("claimReviewLease: v.object({})");
|
|
652
|
-
});
|
|
653
|
-
(0, import_vitest.test)("generates validators for object intersections", async () => {
|
|
654
|
-
writeFileSync((0, import_node_path.join)(testDir, "agent/mutations.ts"), `
|
|
655
|
-
import { mutations, serverWhere } from 'on-zero'
|
|
656
|
-
|
|
657
|
-
const perm = serverWhere('agent', () => true)
|
|
658
|
-
|
|
659
|
-
export const mutate = mutations('agent', perm, {
|
|
660
|
-
update: async (
|
|
661
|
-
{ tx },
|
|
662
|
-
props: {
|
|
663
|
-
id: string
|
|
664
|
-
} & {
|
|
665
|
-
status?: string
|
|
666
|
-
currentTaskId?: string
|
|
667
|
-
[key: string]: unknown
|
|
668
|
-
},
|
|
669
|
-
) => {
|
|
670
|
-
await tx.mutate.agent.update(props)
|
|
671
|
-
},
|
|
672
|
-
})
|
|
673
|
-
`);
|
|
674
|
-
await (0, import_generate.generate)({
|
|
675
|
-
dir: testDir,
|
|
676
|
-
silent: true
|
|
677
|
-
});
|
|
678
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
679
|
-
(0, import_vitest.expect)(content).toContain("update");
|
|
680
|
-
(0, import_vitest.expect)(content).toContain("id: v.string()");
|
|
681
|
-
(0, import_vitest.expect)(content).toContain("status: v.optional(v.string())");
|
|
682
|
-
(0, import_vitest.expect)(content).toContain("currentTaskId: v.optional(v.string())");
|
|
683
|
-
(0, import_vitest.expect)(content).not.toContain("update: v.object({})");
|
|
684
|
-
(0, import_vitest.expect)(content).not.toContain("[key");
|
|
685
|
-
});
|
|
686
|
-
(0, import_vitest.test)("uses v.unknown for untyped mutation payloads", async () => {
|
|
687
|
-
writeFileSync((0, import_node_path.join)(testDir, "project/mutations.ts"), `
|
|
688
|
-
import { mutations, serverWhere } from 'on-zero'
|
|
689
|
-
|
|
690
|
-
const perm = serverWhere('project', () => true)
|
|
691
|
-
|
|
692
|
-
export const mutate = mutations('project', perm, {
|
|
693
|
-
insert: async ({ tx }, project) => {
|
|
694
|
-
await tx.mutate.project.insert(project)
|
|
695
|
-
},
|
|
696
|
-
})
|
|
697
|
-
`);
|
|
698
|
-
await (0, import_generate.generate)({
|
|
699
|
-
dir: testDir,
|
|
700
|
-
silent: true
|
|
701
|
-
});
|
|
702
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
703
|
-
(0, import_vitest.expect)(content).toContain("insert: v.unknown()");
|
|
704
|
-
(0, import_vitest.expect)(content).not.toContain("insert: v.void_()");
|
|
705
|
-
});
|
|
706
|
-
(0, import_vitest.test)("handles mutations with only context param (void)", async () => {
|
|
707
|
-
writeFileSync((0, import_node_path.join)(testDir, "user/mutations.ts"), `
|
|
708
|
-
import { table, string } from 'on-zero'
|
|
709
|
-
import { mutations, serverWhere } from 'on-zero'
|
|
710
|
-
|
|
711
|
-
export const schema = table('user').columns({
|
|
712
|
-
id: string(),
|
|
713
|
-
name: string(),
|
|
714
|
-
}).primaryKey('id')
|
|
715
|
-
|
|
716
|
-
const perm = serverWhere('user', () => true)
|
|
717
|
-
|
|
718
|
-
export const mutate = mutations(schema, perm, {
|
|
719
|
-
finishOnboarding: async ({ tx }) => {
|
|
720
|
-
// no second param
|
|
721
|
-
},
|
|
722
|
-
})
|
|
723
|
-
`);
|
|
724
|
-
const result = await (0, import_generate.generate)({
|
|
725
|
-
dir: testDir,
|
|
726
|
-
silent: true
|
|
727
|
-
});
|
|
728
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
729
|
-
(0, import_vitest.expect)(content).toContain("finishOnboarding");
|
|
730
|
-
});
|
|
731
|
-
(0, import_vitest.test)("handles primitive param type", async () => {
|
|
732
|
-
writeFileSync((0, import_node_path.join)(testDir, "user/mutations.ts"), `
|
|
733
|
-
import { table, string } from 'on-zero'
|
|
734
|
-
import { mutations, serverWhere } from 'on-zero'
|
|
735
|
-
|
|
736
|
-
export const schema = table('user').columns({
|
|
737
|
-
id: string(),
|
|
738
|
-
name: string(),
|
|
739
|
-
}).primaryKey('id')
|
|
740
|
-
|
|
741
|
-
const perm = serverWhere('user', () => true)
|
|
742
|
-
|
|
743
|
-
export const mutate = mutations(schema, perm, {
|
|
744
|
-
completeSignup: async ({ tx }, userId: string) => {
|
|
745
|
-
await tx.mutate.user.update({ id: userId })
|
|
746
|
-
},
|
|
747
|
-
})
|
|
748
|
-
`);
|
|
749
|
-
const result = await (0, import_generate.generate)({
|
|
750
|
-
dir: testDir,
|
|
751
|
-
silent: true
|
|
752
|
-
});
|
|
753
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
754
|
-
(0, import_vitest.expect)(content).toContain("completeSignup");
|
|
755
|
-
(0, import_vitest.expect)(content).toContain("v.string()");
|
|
756
|
-
});
|
|
757
|
-
(0, import_vitest.test)("handles array param type", async () => {
|
|
758
|
-
writeFileSync((0, import_node_path.join)(testDir, "batch/mutations.ts"), `
|
|
759
|
-
import { mutations } from 'on-zero'
|
|
760
|
-
|
|
761
|
-
export const mutate = mutations({
|
|
762
|
-
bulkDelete: async ({ tx }, ids: Array<{ id: string }>) => {
|
|
763
|
-
for (const { id } of ids) await tx.mutate.batch.delete({ id })
|
|
764
|
-
},
|
|
765
|
-
})
|
|
766
|
-
`);
|
|
767
|
-
const result = await (0, import_generate.generate)({
|
|
768
|
-
dir: testDir,
|
|
769
|
-
silent: true
|
|
770
|
-
});
|
|
771
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
772
|
-
(0, import_vitest.expect)(content).toContain("bulkDelete");
|
|
773
|
-
(0, import_vitest.expect)(content).toContain("v.array");
|
|
774
|
-
});
|
|
775
322
|
(0, import_vitest.test)("populates mutationCount and caching works", async () => {
|
|
776
323
|
writeFileSync((0, import_node_path.join)(testDir, "item/mutations.ts"), `
|
|
777
324
|
import { table, string } from 'on-zero'
|
|
@@ -802,242 +349,4 @@ export const mutate = mutations(schema, perm, {
|
|
|
802
349
|
(0, import_vitest.expect)(second.filesChanged).toBe(0);
|
|
803
350
|
(0, import_vitest.expect)(second.mutationCount).toBe(first.mutationCount);
|
|
804
351
|
});
|
|
805
|
-
});
|
|
806
|
-
(0, import_vitest.describe)("type resolution", () => {
|
|
807
|
-
(0, import_vitest.test)("resolves imported type references for mutations", async () => {
|
|
808
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/types.ts"), `
|
|
809
|
-
export type ArchiveParams = {
|
|
810
|
-
id: string
|
|
811
|
-
reason: string
|
|
812
|
-
archived: boolean
|
|
813
|
-
}
|
|
814
|
-
`);
|
|
815
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/mutations.ts"), `
|
|
816
|
-
import { table, string, boolean } from 'on-zero'
|
|
817
|
-
import { mutations } from 'on-zero'
|
|
818
|
-
import type { ArchiveParams } from './types'
|
|
819
|
-
|
|
820
|
-
export const mutate = mutations({
|
|
821
|
-
archive: async ({ tx }, params: ArchiveParams) => {
|
|
822
|
-
await tx.mutate.post.update(params)
|
|
823
|
-
},
|
|
824
|
-
})
|
|
825
|
-
`);
|
|
826
|
-
const result = await (0, import_generate.generate)({
|
|
827
|
-
dir: testDir,
|
|
828
|
-
silent: true
|
|
829
|
-
});
|
|
830
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
831
|
-
(0, import_vitest.expect)(content).toContain("v.string()");
|
|
832
|
-
(0, import_vitest.expect)(content).toContain("v.boolean()");
|
|
833
|
-
(0, import_vitest.expect)(content).toContain("reason");
|
|
834
|
-
(0, import_vitest.expect)(content).toContain("archived");
|
|
835
|
-
});
|
|
836
|
-
(0, import_vitest.test)("resolves utility types like Pick", async () => {
|
|
837
|
-
writeFileSync((0, import_node_path.join)(testDir, "item/types.ts"), `
|
|
838
|
-
export type Item = {
|
|
839
|
-
id: string
|
|
840
|
-
name: string
|
|
841
|
-
description: string
|
|
842
|
-
count: number
|
|
843
|
-
}
|
|
844
|
-
`);
|
|
845
|
-
writeFileSync((0, import_node_path.join)(testDir, "item/mutations.ts"), `
|
|
846
|
-
import { table, string, number } from 'on-zero'
|
|
847
|
-
import { mutations, serverWhere } from 'on-zero'
|
|
848
|
-
import type { Item } from './types'
|
|
849
|
-
|
|
850
|
-
export const schema = table('item').columns({
|
|
851
|
-
id: string(),
|
|
852
|
-
name: string(),
|
|
853
|
-
description: string(),
|
|
854
|
-
count: number(),
|
|
855
|
-
}).primaryKey('id')
|
|
856
|
-
|
|
857
|
-
const perm = serverWhere('item', () => true)
|
|
858
|
-
|
|
859
|
-
export const mutate = mutations(schema, perm, {
|
|
860
|
-
rename: async ({ tx }, updates: Pick<Item, 'id' | 'name'>) => {
|
|
861
|
-
await tx.mutate.item.update(updates)
|
|
862
|
-
},
|
|
863
|
-
})
|
|
864
|
-
`);
|
|
865
|
-
const result = await (0, import_generate.generate)({
|
|
866
|
-
dir: testDir,
|
|
867
|
-
silent: true
|
|
868
|
-
});
|
|
869
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
870
|
-
(0, import_vitest.expect)(content).toContain("id");
|
|
871
|
-
(0, import_vitest.expect)(content).toContain("name");
|
|
872
|
-
(0, import_vitest.expect)(content).not.toMatch(/rename:[\s\S]*description/);
|
|
873
|
-
(0, import_vitest.expect)(content).not.toMatch(/rename:[\s\S]*count/);
|
|
874
|
-
});
|
|
875
|
-
(0, import_vitest.test)("resolves instantiated Zero row fields through Partial and Omit", async () => {
|
|
876
|
-
(0, import_node_fs.symlinkSync)((0, import_node_path.join)(import_meta.dirname, "../node_modules"), (0, import_node_path.join)(testDir, "node_modules"), "dir");
|
|
877
|
-
writeFileSync((0, import_node_path.join)(testDir, "item/types.ts"), `
|
|
878
|
-
import type { Row } from '@rocicorp/zero'
|
|
879
|
-
import { drizzleZeroConfig } from 'drizzle-zero-sqlite'
|
|
880
|
-
import { sqliteTable, text } from 'drizzle-orm/sqlite-core'
|
|
881
|
-
|
|
882
|
-
const item = sqliteTable('item', {
|
|
883
|
-
id: text().primaryKey(),
|
|
884
|
-
name: text().notNull(),
|
|
885
|
-
description: text().notNull(),
|
|
886
|
-
})
|
|
887
|
-
const schema = drizzleZeroConfig({ item })
|
|
888
|
-
|
|
889
|
-
export type Item = Row<(typeof schema)['tables']['item']>
|
|
890
|
-
`);
|
|
891
|
-
writeFileSync((0, import_node_path.join)(testDir, "item/mutations.ts"), `
|
|
892
|
-
import { mutations } from 'on-zero'
|
|
893
|
-
import type { Item } from './types'
|
|
894
|
-
|
|
895
|
-
type ItemUpdate = { id: string } & Partial<Omit<Item, 'id'>>
|
|
896
|
-
|
|
897
|
-
export const mutate = mutations('item', {
|
|
898
|
-
update: async ({ tx }, props: ItemUpdate) => {
|
|
899
|
-
await tx.mutate.item.update(props)
|
|
900
|
-
},
|
|
901
|
-
})
|
|
902
|
-
`);
|
|
903
|
-
await (0, import_generate.generate)({
|
|
904
|
-
dir: testDir,
|
|
905
|
-
silent: true
|
|
906
|
-
});
|
|
907
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
908
|
-
(0, import_vitest.expect)(content).toContain("name: v.optional(v.string())");
|
|
909
|
-
(0, import_vitest.expect)(content).toContain("description: v.optional(v.string())");
|
|
910
|
-
(0, import_vitest.expect)(content).not.toContain("name: v.optional(v.unknown())");
|
|
911
|
-
(0, import_vitest.expect)(content).not.toContain("description: v.optional(v.unknown())");
|
|
912
|
-
});
|
|
913
|
-
(0, import_vitest.test)("skips symbol-keyed properties when resolving imported mutation param types", async () => {
|
|
914
|
-
writeFileSync((0, import_node_path.join)(testDir, "item/types.ts"), `
|
|
915
|
-
export type WeirdParams = {
|
|
916
|
-
id: string
|
|
917
|
-
[Symbol.iterator]?: () => Iterator<string>
|
|
918
|
-
}
|
|
919
|
-
`);
|
|
920
|
-
writeFileSync((0, import_node_path.join)(testDir, "item/mutations.ts"), `
|
|
921
|
-
import { mutations } from 'on-zero'
|
|
922
|
-
import type { WeirdParams } from './types'
|
|
923
|
-
|
|
924
|
-
export const mutate = mutations({
|
|
925
|
-
run: async ({ tx }, params: WeirdParams) => {
|
|
926
|
-
await tx.mutate.item.delete({ id: params.id })
|
|
927
|
-
},
|
|
928
|
-
})
|
|
929
|
-
`);
|
|
930
|
-
await (0, import_generate.generate)({
|
|
931
|
-
dir: testDir,
|
|
932
|
-
silent: true
|
|
933
|
-
});
|
|
934
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedMutations.ts"), "utf-8");
|
|
935
|
-
(0, import_vitest.expect)(content).toContain("run");
|
|
936
|
-
(0, import_vitest.expect)(content).toContain("id: v.string()");
|
|
937
|
-
(0, import_vitest.expect)(content).not.toContain("__@iterator");
|
|
938
|
-
});
|
|
939
|
-
(0, import_vitest.test)("resolves imported types in query params", async () => {
|
|
940
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/mutations.ts"), `export const schema = table('post', { id: string() })`);
|
|
941
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/types.ts"), `
|
|
942
|
-
export type PostFilter = {
|
|
943
|
-
authorId: string
|
|
944
|
-
published: boolean
|
|
945
|
-
}
|
|
946
|
-
`);
|
|
947
|
-
writeFileSync((0, import_node_path.join)(testDir, "post/queries.ts"), `
|
|
948
|
-
import type { PostFilter } from './types'
|
|
949
|
-
|
|
950
|
-
export const filteredPosts = (filter: PostFilter) => zero.query.post
|
|
951
|
-
`);
|
|
952
|
-
const result = await (0, import_generate.generate)({
|
|
953
|
-
dir: testDir,
|
|
954
|
-
silent: true
|
|
955
|
-
});
|
|
956
|
-
const content = (0, import_node_fs.readFileSync)((0, import_node_path.join)(testDir, "generated/syncedQueries.ts"), "utf-8");
|
|
957
|
-
(0, import_vitest.expect)(content).toContain("filteredPosts");
|
|
958
|
-
(0, import_vitest.expect)(content).toContain("v.object");
|
|
959
|
-
(0, import_vitest.expect)(content).toContain("authorId");
|
|
960
|
-
(0, import_vitest.expect)(content).toContain("v.boolean()");
|
|
961
|
-
});
|
|
962
|
-
});
|
|
963
|
-
(0, import_vitest.describe)("generateDrizzleSchemaFile", () => {
|
|
964
|
-
(0, import_vitest.test)("preserves table server names and executable two-hop relationships", () => {
|
|
965
|
-
const schema = {
|
|
966
|
-
tables: {
|
|
967
|
-
users: {
|
|
968
|
-
name: "users",
|
|
969
|
-
serverName: "user_records",
|
|
970
|
-
primaryKey: ["id"],
|
|
971
|
-
columns: {
|
|
972
|
-
id: {
|
|
973
|
-
type: "string",
|
|
974
|
-
optional: false,
|
|
975
|
-
customType: null
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
},
|
|
979
|
-
groups: {
|
|
980
|
-
name: "groups",
|
|
981
|
-
primaryKey: ["id"],
|
|
982
|
-
columns: {
|
|
983
|
-
id: {
|
|
984
|
-
type: "string",
|
|
985
|
-
optional: false,
|
|
986
|
-
customType: null
|
|
987
|
-
}
|
|
988
|
-
}
|
|
989
|
-
},
|
|
990
|
-
memberships: {
|
|
991
|
-
name: "memberships",
|
|
992
|
-
primaryKey: ["userId", "groupId"],
|
|
993
|
-
columns: {
|
|
994
|
-
userId: {
|
|
995
|
-
type: "string",
|
|
996
|
-
optional: false,
|
|
997
|
-
customType: null
|
|
998
|
-
},
|
|
999
|
-
groupId: {
|
|
1000
|
-
type: "string",
|
|
1001
|
-
optional: false,
|
|
1002
|
-
customType: null
|
|
1003
|
-
}
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
},
|
|
1007
|
-
relationships: {
|
|
1008
|
-
users: {
|
|
1009
|
-
groups: [{
|
|
1010
|
-
sourceField: ["id"],
|
|
1011
|
-
destField: ["userId"],
|
|
1012
|
-
destSchema: "memberships",
|
|
1013
|
-
cardinality: "many"
|
|
1014
|
-
}, {
|
|
1015
|
-
sourceField: ["groupId"],
|
|
1016
|
-
destField: ["id"],
|
|
1017
|
-
destSchema: "groups",
|
|
1018
|
-
cardinality: "many"
|
|
1019
|
-
}]
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
};
|
|
1023
|
-
const source = (0, import_generate.generateDrizzleSchemaFile)(schema);
|
|
1024
|
-
const executableSource = source.replace("import { boolean, createSchema, json, number, relationships, string, table } from '@rocicorp/zero'", "").replace("export const schema =", "globalThis.generatedSchema =");
|
|
1025
|
-
const context = {
|
|
1026
|
-
...zero
|
|
1027
|
-
};
|
|
1028
|
-
(0, import_node_vm.runInNewContext)(executableSource, context);
|
|
1029
|
-
(0, import_vitest.expect)(source).toContain('const usersTable = table("users").from("user_records")');
|
|
1030
|
-
(0, import_vitest.expect)(context.generatedSchema).toMatchObject({
|
|
1031
|
-
tables: {
|
|
1032
|
-
users: {
|
|
1033
|
-
serverName: "user_records"
|
|
1034
|
-
}
|
|
1035
|
-
},
|
|
1036
|
-
relationships: {
|
|
1037
|
-
users: {
|
|
1038
|
-
groups: schema.relationships.users.groups
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
});
|
|
1042
|
-
});
|
|
1043
352
|
});
|