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
|
@@ -19,36 +19,6 @@ function expectNoDuplicates(source) {
|
|
|
19
19
|
return names;
|
|
20
20
|
}
|
|
21
21
|
(0, import_vitest.describe)("generated module identifiers", () => {
|
|
22
|
-
(0, import_vitest.test)("grouped queries keep distinct aliases when one namespace is another plus Source", () => {
|
|
23
|
-
const source = (0, import_generate_helpers.generateGroupedQueriesFile)([{
|
|
24
|
-
name: "appById",
|
|
25
|
-
sourceFile: "app",
|
|
26
|
-
importPath: "../app/queries"
|
|
27
|
-
}, {
|
|
28
|
-
name: "appSourceByAppId",
|
|
29
|
-
sourceFile: "appSource",
|
|
30
|
-
importPath: "../appSource/queries"
|
|
31
|
-
}]);
|
|
32
|
-
expectNoDuplicates(source);
|
|
33
|
-
const appExport = source.match(/export const app = \{([^}]*)\}/)[1];
|
|
34
|
-
const appSourceExport = source.match(/export const appSource = \{([^}]*)\}/)[1];
|
|
35
|
-
(0, import_vitest.expect)(appExport).toContain("appById");
|
|
36
|
-
(0, import_vitest.expect)(appSourceExport).toContain("appSourceByAppId");
|
|
37
|
-
(0, import_vitest.expect)(appExport).not.toContain("appSourceByAppId");
|
|
38
|
-
});
|
|
39
|
-
(0, import_vitest.test)("models keep distinct aliases when user and userPublic both exist", () => {
|
|
40
|
-
const source = (0, import_generate_helpers.generateModelsFile)([{
|
|
41
|
-
name: "user",
|
|
42
|
-
importPath: "../user"
|
|
43
|
-
}, {
|
|
44
|
-
name: "userPublic",
|
|
45
|
-
importPath: "../userPublic"
|
|
46
|
-
}]);
|
|
47
|
-
expectNoDuplicates(source);
|
|
48
|
-
const modelsObject = source.match(/export const models = \{([\s\S]*)\}/)[1];
|
|
49
|
-
(0, import_vitest.expect)(modelsObject).toMatch(/\buser:/);
|
|
50
|
-
(0, import_vitest.expect)(modelsObject).toMatch(/\buserPublic\b/);
|
|
51
|
-
});
|
|
52
22
|
(0, import_vitest.test)("table re-exports keep distinct names when user and userPublic both exist", () => {
|
|
53
23
|
const source = (0, import_generate_helpers.generateTablesFile)([{
|
|
54
24
|
name: "user",
|
|
@@ -59,12 +29,4 @@ function expectNoDuplicates(source) {
|
|
|
59
29
|
}]);
|
|
60
30
|
expectNoDuplicates(source);
|
|
61
31
|
});
|
|
62
|
-
(0, import_vitest.test)("a namespace with no collision keeps its plain alias", () => {
|
|
63
|
-
const source = (0, import_generate_helpers.generateGroupedQueriesFile)([{
|
|
64
|
-
name: "todoById",
|
|
65
|
-
sourceFile: "todo",
|
|
66
|
-
importPath: "../todo/queries"
|
|
67
|
-
}]);
|
|
68
|
-
(0, import_vitest.expect)(source).toContain(`import * as todoSource from '../todo/queries'`);
|
|
69
|
-
});
|
|
70
32
|
});
|
|
@@ -42,36 +42,6 @@ function expectNoDuplicates(source) {
|
|
|
42
42
|
return names;
|
|
43
43
|
}
|
|
44
44
|
(0, import_vitest.describe)("generated module identifiers", function () {
|
|
45
|
-
(0, import_vitest.test)("grouped queries keep distinct aliases when one namespace is another plus Source", function () {
|
|
46
|
-
var source = (0, import_generate_helpers.generateGroupedQueriesFile)([{
|
|
47
|
-
name: "appById",
|
|
48
|
-
sourceFile: "app",
|
|
49
|
-
importPath: "../app/queries"
|
|
50
|
-
}, {
|
|
51
|
-
name: "appSourceByAppId",
|
|
52
|
-
sourceFile: "appSource",
|
|
53
|
-
importPath: "../appSource/queries"
|
|
54
|
-
}]);
|
|
55
|
-
expectNoDuplicates(source);
|
|
56
|
-
var appExport = source.match(/export const app = \{([^}]*)\}/)[1];
|
|
57
|
-
var appSourceExport = source.match(/export const appSource = \{([^}]*)\}/)[1];
|
|
58
|
-
(0, import_vitest.expect)(appExport).toContain("appById");
|
|
59
|
-
(0, import_vitest.expect)(appSourceExport).toContain("appSourceByAppId");
|
|
60
|
-
(0, import_vitest.expect)(appExport).not.toContain("appSourceByAppId");
|
|
61
|
-
});
|
|
62
|
-
(0, import_vitest.test)("models keep distinct aliases when user and userPublic both exist", function () {
|
|
63
|
-
var source = (0, import_generate_helpers.generateModelsFile)([{
|
|
64
|
-
name: "user",
|
|
65
|
-
importPath: "../user"
|
|
66
|
-
}, {
|
|
67
|
-
name: "userPublic",
|
|
68
|
-
importPath: "../userPublic"
|
|
69
|
-
}]);
|
|
70
|
-
expectNoDuplicates(source);
|
|
71
|
-
var modelsObject = source.match(/export const models = \{([\s\S]*)\}/)[1];
|
|
72
|
-
(0, import_vitest.expect)(modelsObject).toMatch(/\buser:/);
|
|
73
|
-
(0, import_vitest.expect)(modelsObject).toMatch(/\buserPublic\b/);
|
|
74
|
-
});
|
|
75
45
|
(0, import_vitest.test)("table re-exports keep distinct names when user and userPublic both exist", function () {
|
|
76
46
|
var source = (0, import_generate_helpers.generateTablesFile)([{
|
|
77
47
|
name: "user",
|
|
@@ -82,13 +52,5 @@ function expectNoDuplicates(source) {
|
|
|
82
52
|
}]);
|
|
83
53
|
expectNoDuplicates(source);
|
|
84
54
|
});
|
|
85
|
-
(0, import_vitest.test)("a namespace with no collision keeps its plain alias", function () {
|
|
86
|
-
var source = (0, import_generate_helpers.generateGroupedQueriesFile)([{
|
|
87
|
-
name: "todoById",
|
|
88
|
-
sourceFile: "todo",
|
|
89
|
-
importPath: "../todo/queries"
|
|
90
|
-
}]);
|
|
91
|
-
(0, import_vitest.expect)(source).toContain(`import * as todoSource from '../todo/queries'`);
|
|
92
|
-
});
|
|
93
55
|
});
|
|
94
56
|
//# sourceMappingURL=generate-helpers.test.native.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["import_vitest","require","import_generate_helpers","declaredIdentifiers","source","names","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_iterator","split","Symbol","iterator","_step","next","done","line","value","imported","match","push","declared","reexported","err","return"
|
|
1
|
+
{"version":3,"names":["import_vitest","require","import_generate_helpers","declaredIdentifiers","source","names","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_iterator","split","Symbol","iterator","_step","next","done","line","value","imported","match","push","declared","reexported","err","return"],"sources":["../../src/generate-helpers.test.ts"],"sourcesContent":[null],"mappings":"AAAA;;AAEA,IAAAA,aAAA,GAAAC,OAAA,SAIO;AAKP,IAAAC,uBAAS,GAAoBD,OAA0B;AACrD,SAAME,mBAAmBA,CAAAC,MAAA;EACzB,IAAAC,KAAA,GAAW;EACT,IAAAC,yBAAsB,GAAM;IAAAC,iBAAA,QAA8B;IAAAC,cAAA;EAC1D;IACA,SAAMC,SAAW,GAAAL,MAAK,CAAMM,KAAA,OAAAC,MAAA,CAAAC,QAA2B,KAAAC,KAAA,IAAAP,yBAAA,IAAAO,KAAA,GAAAJ,SAAA,CAAAK,IAAA,IAAAC,IAAA,GAAAT,yBAAA;MACvD,IAAIU,IAAA,GAAUH,KAAA,CAAAI,KAAM;MACpB,IAAMC,QAAA,GAAAF,IAAa,CAAAG,KAAK,+BAAM;MAC9B,IAAID,QAAA,EAAYb,KAAA,CAAMe,IAAA,CAAKF,QAAA,GAAW,CAAC;MACzC,IAAAG,QAAA,GAAAL,IAAA,CAAAG,KAAA;MACA,IAAOE,QAAA,EAAAhB,KAAA,CAAAe,IAAA,CAAAC,QAAA;MACT,IAAAC,UAAA,GAAAN,IAAA,CAAAG,KAAA;MAEA,IAASG,UAAA,EAAAjB,KAAA,CAAmBe,IAAA,CAAAE,UAAgB;IAC1C;EACA,SAAMC,GAAA;IACNhB,iBAAA,OAAO;IACPC,cAAO,GAAAe,GAAA;EACT;IAEA;MACE,KAAAjB,yBAAK,IAAAG,SAAA,CAAAe,MAAA;QACHf,SAAM,CAAAe,MAAS;MACb;IAAsC,UAC9B;MACmC,IAAAjB,iBAAA;QAE7C,MAAAC,cAAmB;MACpB;IACF","ignoreList":[]}
|
|
@@ -15,391 +15,6 @@ const DIR = "/proj/src/data";
|
|
|
15
15
|
import_vitest.vi.restoreAllMocks();
|
|
16
16
|
});
|
|
17
17
|
(0, import_vitest.describe)("generateLite", () => {
|
|
18
|
-
(0, import_vitest.test)("emits models.ts, syncedMutations.ts, and README.md from inline types", () => {
|
|
19
|
-
const files = {
|
|
20
|
-
[`${DIR}/todo.ts`]: "// fake source, parser returns fixture",
|
|
21
|
-
[`${DIR}/user.ts`]: "// fake source, parser returns fixture"
|
|
22
|
-
};
|
|
23
|
-
const fixtures = {
|
|
24
|
-
[`${DIR}/todo.ts`]: {
|
|
25
|
-
mutations: [{
|
|
26
|
-
modelName: "todo",
|
|
27
|
-
handlers: [{
|
|
28
|
-
name: "toggle",
|
|
29
|
-
paramTypeText: "{ id: string; isActive: boolean }"
|
|
30
|
-
}, {
|
|
31
|
-
name: "rename",
|
|
32
|
-
paramTypeText: "{ id: string; title: string }"
|
|
33
|
-
}],
|
|
34
|
-
schema: null
|
|
35
|
-
}],
|
|
36
|
-
queries: []
|
|
37
|
-
},
|
|
38
|
-
[`${DIR}/user.ts`]: {
|
|
39
|
-
mutations: [{
|
|
40
|
-
modelName: "user",
|
|
41
|
-
handlers: [{
|
|
42
|
-
name: "finishOnboarding",
|
|
43
|
-
// null = no second param / void
|
|
44
|
-
paramTypeText: null
|
|
45
|
-
}],
|
|
46
|
-
schema: null
|
|
47
|
-
}],
|
|
48
|
-
queries: []
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
52
|
-
files,
|
|
53
|
-
dir: DIR,
|
|
54
|
-
parse: makeParse(fixtures)
|
|
55
|
-
});
|
|
56
|
-
(0, import_vitest.expect)(Object.keys(result.files).sort()).toEqual(["README.md", "groupedQueries.ts", "instances.ts", "models.ts", "syncedMutations.ts", "syncedQueries.ts"]);
|
|
57
|
-
const models = result.files["models.ts"];
|
|
58
|
-
(0, import_vitest.expect)(models).toContain("import * as todo from '../todo'");
|
|
59
|
-
(0, import_vitest.expect)(models).toContain("import * as userPublic from '../user'");
|
|
60
|
-
(0, import_vitest.expect)(models).toContain("user: userPublic,");
|
|
61
|
-
(0, import_vitest.expect)(models).not.toContain("\n userPublic,");
|
|
62
|
-
(0, import_vitest.expect)(models).toContain("export const models = {");
|
|
63
|
-
const syncedMutations = result.files["syncedMutations.ts"];
|
|
64
|
-
(0, import_vitest.expect)(syncedMutations).toContain("toggle:");
|
|
65
|
-
(0, import_vitest.expect)(syncedMutations).toContain("v.object({");
|
|
66
|
-
(0, import_vitest.expect)(syncedMutations).toContain("id: v.string()");
|
|
67
|
-
(0, import_vitest.expect)(syncedMutations).toContain("isActive: v.boolean()");
|
|
68
|
-
(0, import_vitest.expect)(syncedMutations).toContain("rename:");
|
|
69
|
-
(0, import_vitest.expect)(syncedMutations).toContain("title: v.string()");
|
|
70
|
-
(0, import_vitest.expect)(syncedMutations).toContain("finishOnboarding: v.void_()");
|
|
71
|
-
(0, import_vitest.expect)(result.modelCount).toBe(2);
|
|
72
|
-
(0, import_vitest.expect)(result.schemaCount).toBe(0);
|
|
73
|
-
(0, import_vitest.expect)(result.mutationCount).toBe(3);
|
|
74
|
-
});
|
|
75
|
-
(0, import_vitest.test)("parses newline-separated mutation object types", () => {
|
|
76
|
-
const files = {
|
|
77
|
-
[`${DIR}/agentEvent.ts`]: "// fake",
|
|
78
|
-
[`${DIR}/deployment.ts`]: "// fake"
|
|
79
|
-
};
|
|
80
|
-
const fixtures = {
|
|
81
|
-
[`${DIR}/agentEvent.ts`]: {
|
|
82
|
-
mutations: [{
|
|
83
|
-
modelName: "agentEvent",
|
|
84
|
-
handlers: [{
|
|
85
|
-
name: "claimReviewLease",
|
|
86
|
-
paramTypeText: `{
|
|
87
|
-
id: string
|
|
88
|
-
projectId: string
|
|
89
|
-
createdAt: number
|
|
90
|
-
}`
|
|
91
|
-
}],
|
|
92
|
-
schema: null
|
|
93
|
-
}],
|
|
94
|
-
queries: []
|
|
95
|
-
},
|
|
96
|
-
[`${DIR}/deployment.ts`]: {
|
|
97
|
-
mutations: [{
|
|
98
|
-
modelName: "deployment",
|
|
99
|
-
handlers: [{
|
|
100
|
-
name: "deploy",
|
|
101
|
-
paramTypeText: `{
|
|
102
|
-
id: string
|
|
103
|
-
platform?: string // 'web' | 'ios'
|
|
104
|
-
buildTier?: string // 'dev' | 'testflight' | 'production'
|
|
105
|
-
}`
|
|
106
|
-
}],
|
|
107
|
-
schema: null
|
|
108
|
-
}],
|
|
109
|
-
queries: []
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
113
|
-
files,
|
|
114
|
-
dir: DIR,
|
|
115
|
-
parse: makeParse(fixtures)
|
|
116
|
-
});
|
|
117
|
-
const synced = result.files["syncedMutations.ts"];
|
|
118
|
-
(0, import_vitest.expect)(synced).toContain("claimReviewLease:");
|
|
119
|
-
(0, import_vitest.expect)(synced).toContain("projectId: v.string()");
|
|
120
|
-
(0, import_vitest.expect)(synced).toContain("createdAt: v.number()");
|
|
121
|
-
(0, import_vitest.expect)(synced).toContain("deploy:");
|
|
122
|
-
(0, import_vitest.expect)(synced).toContain("platform: v.optional(v.string())");
|
|
123
|
-
(0, import_vitest.expect)(synced).toContain("buildTier: v.optional(v.string())");
|
|
124
|
-
(0, import_vitest.expect)(synced).not.toContain("claimReviewLease: v.object({})");
|
|
125
|
-
(0, import_vitest.expect)(synced).not.toContain("deploy: v.object({})");
|
|
126
|
-
});
|
|
127
|
-
(0, import_vitest.test)("parses object intersections and skips index signatures", () => {
|
|
128
|
-
const files = {
|
|
129
|
-
[`${DIR}/agent.ts`]: "// fake"
|
|
130
|
-
};
|
|
131
|
-
const fixtures = {
|
|
132
|
-
[`${DIR}/agent.ts`]: {
|
|
133
|
-
mutations: [{
|
|
134
|
-
modelName: "agent",
|
|
135
|
-
handlers: [{
|
|
136
|
-
name: "update",
|
|
137
|
-
paramTypeText: `{
|
|
138
|
-
id: string
|
|
139
|
-
} & {
|
|
140
|
-
status?: string
|
|
141
|
-
currentTaskId?: string
|
|
142
|
-
[key: string]: unknown
|
|
143
|
-
}`
|
|
144
|
-
}],
|
|
145
|
-
schema: null
|
|
146
|
-
}],
|
|
147
|
-
queries: []
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
151
|
-
files,
|
|
152
|
-
dir: DIR,
|
|
153
|
-
parse: makeParse(fixtures)
|
|
154
|
-
});
|
|
155
|
-
const synced = result.files["syncedMutations.ts"];
|
|
156
|
-
(0, import_vitest.expect)(synced).toContain("update:");
|
|
157
|
-
(0, import_vitest.expect)(synced).toContain("id: v.string()");
|
|
158
|
-
(0, import_vitest.expect)(synced).toContain("status: v.optional(v.string())");
|
|
159
|
-
(0, import_vitest.expect)(synced).toContain("currentTaskId: v.optional(v.string())");
|
|
160
|
-
(0, import_vitest.expect)(synced).not.toContain("[key");
|
|
161
|
-
(0, import_vitest.expect)(synced).not.toContain("update: v.object({})");
|
|
162
|
-
});
|
|
163
|
-
(0, import_vitest.test)("falls back to v.unknown() for type references", () => {
|
|
164
|
-
const files = {
|
|
165
|
-
[`${DIR}/post.ts`]: `export const allPosts = () => zql.post`
|
|
166
|
-
};
|
|
167
|
-
const fixtures = {
|
|
168
|
-
[`${DIR}/post.ts`]: {
|
|
169
|
-
mutations: [{
|
|
170
|
-
modelName: "post",
|
|
171
|
-
handlers: [{
|
|
172
|
-
name: "archive",
|
|
173
|
-
// bare type reference — parseTypeString returns null, so
|
|
174
|
-
// generate-lite should fall back to v.unknown() rather than
|
|
175
|
-
// attempting cross-file type resolution.
|
|
176
|
-
paramTypeText: "ArchiveParams"
|
|
177
|
-
}, {
|
|
178
|
-
name: "publish",
|
|
179
|
-
// primitive, should resolve
|
|
180
|
-
paramTypeText: "string"
|
|
181
|
-
}],
|
|
182
|
-
schema: null
|
|
183
|
-
}],
|
|
184
|
-
queries: []
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
188
|
-
files,
|
|
189
|
-
dir: DIR,
|
|
190
|
-
parse: makeParse(fixtures)
|
|
191
|
-
});
|
|
192
|
-
const synced = result.files["syncedMutations.ts"];
|
|
193
|
-
(0, import_vitest.expect)(synced).toContain("archive: v.unknown()");
|
|
194
|
-
(0, import_vitest.expect)(synced).toContain("publish: v.string()");
|
|
195
|
-
});
|
|
196
|
-
(0, import_vitest.test)("uses v.unknown() for explicitly unknown mutation params", () => {
|
|
197
|
-
const files = {
|
|
198
|
-
[`${DIR}/project.ts`]: "// fake"
|
|
199
|
-
};
|
|
200
|
-
const fixtures = {
|
|
201
|
-
[`${DIR}/project.ts`]: {
|
|
202
|
-
mutations: [{
|
|
203
|
-
modelName: "project",
|
|
204
|
-
handlers: [{
|
|
205
|
-
name: "insert",
|
|
206
|
-
paramTypeText: "unknown"
|
|
207
|
-
}],
|
|
208
|
-
schema: null
|
|
209
|
-
}],
|
|
210
|
-
queries: []
|
|
211
|
-
}
|
|
212
|
-
};
|
|
213
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
214
|
-
files,
|
|
215
|
-
dir: DIR,
|
|
216
|
-
parse: makeParse(fixtures)
|
|
217
|
-
});
|
|
218
|
-
(0, import_vitest.expect)(result.files["syncedMutations.ts"]).toContain("insert: v.unknown()");
|
|
219
|
-
});
|
|
220
|
-
(0, import_vitest.test)("emits query files with v.unknown() fallback for references", () => {
|
|
221
|
-
const files = {
|
|
222
|
-
[`${DIR}/post.ts`]: "// fake"
|
|
223
|
-
};
|
|
224
|
-
const fixtures = {
|
|
225
|
-
[`${DIR}/post.ts`]: {
|
|
226
|
-
mutations: [],
|
|
227
|
-
queries: [
|
|
228
|
-
// no-arg query → void
|
|
229
|
-
{
|
|
230
|
-
name: "allPosts",
|
|
231
|
-
rootTable: "post",
|
|
232
|
-
paramTypeText: null,
|
|
233
|
-
relatedPaths: []
|
|
234
|
-
},
|
|
235
|
-
// inline object → real validator
|
|
236
|
-
{
|
|
237
|
-
name: "postById",
|
|
238
|
-
rootTable: "post",
|
|
239
|
-
paramTypeText: "{ id: string }",
|
|
240
|
-
relatedPaths: []
|
|
241
|
-
},
|
|
242
|
-
// primitive
|
|
243
|
-
{
|
|
244
|
-
name: "byAuthorId",
|
|
245
|
-
rootTable: "post",
|
|
246
|
-
paramTypeText: "string",
|
|
247
|
-
relatedPaths: []
|
|
248
|
-
},
|
|
249
|
-
// optional nullable inline object
|
|
250
|
-
{
|
|
251
|
-
name: "paged",
|
|
252
|
-
rootTable: "post",
|
|
253
|
-
paramTypeText: "{ pageSize: number; cursor?: { id: string; createdAt: number } | null }",
|
|
254
|
-
relatedPaths: []
|
|
255
|
-
},
|
|
256
|
-
// type reference → fallback
|
|
257
|
-
{
|
|
258
|
-
name: "filtered",
|
|
259
|
-
rootTable: "post",
|
|
260
|
-
paramTypeText: "PostFilter",
|
|
261
|
-
relatedPaths: []
|
|
262
|
-
},
|
|
263
|
-
// permission should be skipped
|
|
264
|
-
{
|
|
265
|
-
name: "permission",
|
|
266
|
-
rootTable: "post",
|
|
267
|
-
paramTypeText: null,
|
|
268
|
-
relatedPaths: []
|
|
269
|
-
}]
|
|
270
|
-
}
|
|
271
|
-
};
|
|
272
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
273
|
-
files,
|
|
274
|
-
dir: DIR,
|
|
275
|
-
parse: makeParse(fixtures)
|
|
276
|
-
});
|
|
277
|
-
(0, import_vitest.expect)(result.files["groupedQueries.ts"]).toBeDefined();
|
|
278
|
-
(0, import_vitest.expect)(result.files["syncedQueries.ts"]).toBeDefined();
|
|
279
|
-
const grouped = result.files["groupedQueries.ts"];
|
|
280
|
-
(0, import_vitest.expect)(grouped).toContain("import * as postSource from '../post'");
|
|
281
|
-
(0, import_vitest.expect)(grouped).toContain("postById: postSource.postById");
|
|
282
|
-
const synced = result.files["syncedQueries.ts"];
|
|
283
|
-
(0, import_vitest.expect)(synced).toContain("allPosts: defineQuery(() => Queries.post.allPosts())");
|
|
284
|
-
(0, import_vitest.expect)(synced).toContain("postById: defineQuery(");
|
|
285
|
-
(0, import_vitest.expect)(synced).toContain("id: v.string()");
|
|
286
|
-
(0, import_vitest.expect)(synced).toContain("byAuthorId: defineQuery(");
|
|
287
|
-
(0, import_vitest.expect)(synced).toMatch(/byAuthorId: defineQuery\(\s*v\.string\(\)/);
|
|
288
|
-
(0, import_vitest.expect)(synced).toContain("paged: defineQuery(");
|
|
289
|
-
(0, import_vitest.expect)(synced).toContain("cursor: v.optional(v.nullable(v.object({");
|
|
290
|
-
(0, import_vitest.expect)(synced).toContain("filtered: defineQuery(");
|
|
291
|
-
(0, import_vitest.expect)(synced).toMatch(/filtered: defineQuery\(\s*v\.unknown\(\)/);
|
|
292
|
-
(0, import_vitest.expect)(synced).not.toContain("permission: defineQuery");
|
|
293
|
-
(0, import_vitest.expect)(result.queryCount).toBe(5);
|
|
294
|
-
});
|
|
295
|
-
(0, import_vitest.test)("emits types.ts and tables.ts when a model declares a schema inline", () => {
|
|
296
|
-
const files = {
|
|
297
|
-
[`${DIR}/task.ts`]: "// fake"
|
|
298
|
-
};
|
|
299
|
-
const fixtures = {
|
|
300
|
-
[`${DIR}/task.ts`]: {
|
|
301
|
-
mutations: [{
|
|
302
|
-
modelName: "task",
|
|
303
|
-
handlers: [],
|
|
304
|
-
schema: {
|
|
305
|
-
tableName: "task",
|
|
306
|
-
primaryKeys: ["id"],
|
|
307
|
-
columns: [{
|
|
308
|
-
name: "id",
|
|
309
|
-
builderText: "string()"
|
|
310
|
-
}, {
|
|
311
|
-
name: "title",
|
|
312
|
-
builderText: "string()"
|
|
313
|
-
}, {
|
|
314
|
-
name: "priority",
|
|
315
|
-
builderText: "number()"
|
|
316
|
-
}, {
|
|
317
|
-
name: "done",
|
|
318
|
-
builderText: "boolean()"
|
|
319
|
-
}, {
|
|
320
|
-
name: "note",
|
|
321
|
-
builderText: "string().optional()"
|
|
322
|
-
}]
|
|
323
|
-
}
|
|
324
|
-
}],
|
|
325
|
-
queries: []
|
|
326
|
-
}
|
|
327
|
-
};
|
|
328
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
329
|
-
files,
|
|
330
|
-
dir: DIR,
|
|
331
|
-
parse: makeParse(fixtures)
|
|
332
|
-
});
|
|
333
|
-
(0, import_vitest.expect)(result.schemaCount).toBe(1);
|
|
334
|
-
(0, import_vitest.expect)(result.files["types.ts"]).toBeDefined();
|
|
335
|
-
(0, import_vitest.expect)(result.files["tables.ts"]).toBeDefined();
|
|
336
|
-
const types = result.files["types.ts"];
|
|
337
|
-
(0, import_vitest.expect)(types).toContain("export type Task = TableInsertRow<typeof schema.task>");
|
|
338
|
-
const tables = result.files["tables.ts"];
|
|
339
|
-
(0, import_vitest.expect)(tables).toContain("export { schema as task } from '../task'");
|
|
340
|
-
const synced = result.files["syncedMutations.ts"];
|
|
341
|
-
(0, import_vitest.expect)(synced).toContain("insert:");
|
|
342
|
-
(0, import_vitest.expect)(synced).toContain("update:");
|
|
343
|
-
(0, import_vitest.expect)(synced).toContain("delete:");
|
|
344
|
-
(0, import_vitest.expect)(result.mutationCount).toBe(3);
|
|
345
|
-
});
|
|
346
|
-
(0, import_vitest.test)("ignores private files inside a namespace folder", () => {
|
|
347
|
-
const files = {
|
|
348
|
-
[`${DIR}/post/mutations.ts`]: "// fake",
|
|
349
|
-
[`${DIR}/post/README.md`]: "not a model",
|
|
350
|
-
[`${DIR}/post/helpers/util.ts`]: "private helper, ignored",
|
|
351
|
-
[`${DIR}/post/post.d.ts`]: "declaration file, ignored",
|
|
352
|
-
[`${DIR}/post/post.test.ts`]: "test file, ignored",
|
|
353
|
-
[`${DIR}/post/post.spec.ts`]: "spec file, ignored"
|
|
354
|
-
};
|
|
355
|
-
const fixtures = {
|
|
356
|
-
[`${DIR}/post/mutations.ts`]: {
|
|
357
|
-
mutations: [{
|
|
358
|
-
modelName: "post",
|
|
359
|
-
handlers: [],
|
|
360
|
-
schema: null
|
|
361
|
-
}],
|
|
362
|
-
queries: []
|
|
363
|
-
}
|
|
364
|
-
};
|
|
365
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
366
|
-
files,
|
|
367
|
-
dir: DIR,
|
|
368
|
-
parse: makeParse(fixtures)
|
|
369
|
-
});
|
|
370
|
-
(0, import_vitest.expect)(result.modelCount).toBe(1);
|
|
371
|
-
const models = result.files["models.ts"];
|
|
372
|
-
(0, import_vitest.expect)(models).toContain("import * as post from '../post/mutations'");
|
|
373
|
-
(0, import_vitest.expect)(models).not.toContain("util");
|
|
374
|
-
(0, import_vitest.expect)(models).not.toContain("README");
|
|
375
|
-
(0, import_vitest.expect)(models).not.toContain("post.test");
|
|
376
|
-
(0, import_vitest.expect)(models).not.toContain("post.spec");
|
|
377
|
-
});
|
|
378
|
-
(0, import_vitest.test)("supports a split namespace folder", () => {
|
|
379
|
-
const files = {
|
|
380
|
-
[`${DIR}/post/mutations.ts`]: "// fake"
|
|
381
|
-
};
|
|
382
|
-
const fixtures = {
|
|
383
|
-
[`${DIR}/post/mutations.ts`]: {
|
|
384
|
-
mutations: [{
|
|
385
|
-
modelName: "post",
|
|
386
|
-
handlers: [{
|
|
387
|
-
name: "publish",
|
|
388
|
-
paramTypeText: "{ id: string }"
|
|
389
|
-
}],
|
|
390
|
-
schema: null
|
|
391
|
-
}],
|
|
392
|
-
queries: []
|
|
393
|
-
}
|
|
394
|
-
};
|
|
395
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
396
|
-
files,
|
|
397
|
-
dir: DIR,
|
|
398
|
-
parse: makeParse(fixtures)
|
|
399
|
-
});
|
|
400
|
-
const models = result.files["models.ts"];
|
|
401
|
-
(0, import_vitest.expect)(models).toContain("from '../post/mutations'");
|
|
402
|
-
});
|
|
403
18
|
(0, import_vitest.test)("derives single-file namespaces from data exports", () => {
|
|
404
19
|
const files = {
|
|
405
20
|
[`${DIR}/server.ts`]: `export const serverRows = () => zql.server`,
|
|
@@ -462,143 +77,6 @@ const DIR = "/proj/src/data";
|
|
|
462
77
|
parse: makeParse({})
|
|
463
78
|
})).toThrow(/removed top-level queries\/ layout/);
|
|
464
79
|
});
|
|
465
|
-
(0, import_vitest.test)("derives scoped related-table closure from lite metadata", () => {
|
|
466
|
-
const files = {
|
|
467
|
-
[`${DIR}/on-zero.config.ts`]: `export default defineConfig({ instances: { project: { scope: 'projectId' } } })`,
|
|
468
|
-
[`${DIR}/project/message/queries.ts`]: `export const messages = () => zql.message.related('comments')`,
|
|
469
|
-
[`${DIR}/project/message/mutations.ts`]: "// fake mutation",
|
|
470
|
-
["/proj/src/database/relations.ts"]: "// fake relations",
|
|
471
|
-
["/proj/src/database/schema.ts"]: "// fake tables"
|
|
472
|
-
};
|
|
473
|
-
const empty = {
|
|
474
|
-
mutations: [],
|
|
475
|
-
queries: []
|
|
476
|
-
};
|
|
477
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
478
|
-
files,
|
|
479
|
-
dir: DIR,
|
|
480
|
-
parse: makeParse({
|
|
481
|
-
[`${DIR}/on-zero.config.ts`]: {
|
|
482
|
-
...empty,
|
|
483
|
-
dataConfig: {
|
|
484
|
-
instances: {
|
|
485
|
-
project: {
|
|
486
|
-
scope: "projectId"
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
},
|
|
491
|
-
[`${DIR}/project/message/queries.ts`]: {
|
|
492
|
-
...empty,
|
|
493
|
-
queries: [{
|
|
494
|
-
name: "messages",
|
|
495
|
-
rootTable: "message",
|
|
496
|
-
paramTypeText: null,
|
|
497
|
-
relatedPaths: [["comments", "author"]]
|
|
498
|
-
}]
|
|
499
|
-
},
|
|
500
|
-
[`${DIR}/project/message/mutations.ts`]: {
|
|
501
|
-
...empty,
|
|
502
|
-
mutations: [{
|
|
503
|
-
modelName: "message",
|
|
504
|
-
handlers: [],
|
|
505
|
-
schema: {
|
|
506
|
-
tableName: "message",
|
|
507
|
-
primaryKeys: ["id"],
|
|
508
|
-
columns: [{
|
|
509
|
-
name: "id",
|
|
510
|
-
builderText: "string()"
|
|
511
|
-
}, {
|
|
512
|
-
name: "projectId",
|
|
513
|
-
builderText: "string()"
|
|
514
|
-
}]
|
|
515
|
-
}
|
|
516
|
-
}]
|
|
517
|
-
},
|
|
518
|
-
"/proj/src/database/relations.ts": {
|
|
519
|
-
...empty,
|
|
520
|
-
relations: [{
|
|
521
|
-
sourceTable: "message",
|
|
522
|
-
name: "comments",
|
|
523
|
-
targetTable: "comment"
|
|
524
|
-
}, {
|
|
525
|
-
sourceTable: "comment",
|
|
526
|
-
name: "author",
|
|
527
|
-
targetTable: "userPublic"
|
|
528
|
-
}]
|
|
529
|
-
},
|
|
530
|
-
"/proj/src/database/schema.ts": {
|
|
531
|
-
...empty,
|
|
532
|
-
tables: [{
|
|
533
|
-
name: "comment",
|
|
534
|
-
columns: ["id", "projectId"]
|
|
535
|
-
}, {
|
|
536
|
-
name: "userPublic",
|
|
537
|
-
columns: ["id", "projectId"]
|
|
538
|
-
}]
|
|
539
|
-
}
|
|
540
|
-
})
|
|
541
|
-
});
|
|
542
|
-
(0, import_vitest.expect)(result.files["instances.ts"]).toContain('syncTables: ["comment","message","userPublic"]');
|
|
543
|
-
const instance = result.instances.find(entry => entry.name === "project");
|
|
544
|
-
(0, import_vitest.expect)(instance?.syncTables).toEqual(["comment", "message", "userPublic"]);
|
|
545
|
-
(0, import_vitest.expect)(instance?.supportTables).toEqual([]);
|
|
546
|
-
});
|
|
547
|
-
(0, import_vitest.test)("derives query membership from the query root instead of its namespace", () => {
|
|
548
|
-
const files = {
|
|
549
|
-
[`${DIR}/category/mutations.ts`]: "// fake category model",
|
|
550
|
-
[`${DIR}/dashboard/queries.ts`]: `export const monthSummary = () => zql.category.related('expenses')`,
|
|
551
|
-
["/proj/src/database/relations.ts"]: "// fake relations",
|
|
552
|
-
["/proj/src/database/schema.ts"]: "// fake tables"
|
|
553
|
-
};
|
|
554
|
-
const empty = {
|
|
555
|
-
mutations: [],
|
|
556
|
-
queries: []
|
|
557
|
-
};
|
|
558
|
-
const result = (0, import_generate_lite.generateLite)({
|
|
559
|
-
files,
|
|
560
|
-
dir: DIR,
|
|
561
|
-
parse: makeParse({
|
|
562
|
-
[`${DIR}/category/mutations.ts`]: {
|
|
563
|
-
...empty,
|
|
564
|
-
mutations: [{
|
|
565
|
-
modelName: "category",
|
|
566
|
-
handlers: [],
|
|
567
|
-
schema: null
|
|
568
|
-
}]
|
|
569
|
-
},
|
|
570
|
-
[`${DIR}/dashboard/queries.ts`]: {
|
|
571
|
-
...empty,
|
|
572
|
-
queries: [{
|
|
573
|
-
name: "monthSummary",
|
|
574
|
-
rootTable: "category",
|
|
575
|
-
paramTypeText: null,
|
|
576
|
-
relatedPaths: [["expenses"]]
|
|
577
|
-
}]
|
|
578
|
-
},
|
|
579
|
-
"/proj/src/database/relations.ts": {
|
|
580
|
-
...empty,
|
|
581
|
-
relations: [{
|
|
582
|
-
sourceTable: "category",
|
|
583
|
-
name: "expenses",
|
|
584
|
-
targetTable: "expense"
|
|
585
|
-
}]
|
|
586
|
-
},
|
|
587
|
-
"/proj/src/database/schema.ts": {
|
|
588
|
-
...empty,
|
|
589
|
-
tables: [{
|
|
590
|
-
name: "category",
|
|
591
|
-
columns: ["id"]
|
|
592
|
-
}, {
|
|
593
|
-
name: "expense",
|
|
594
|
-
columns: ["id", "categoryId"]
|
|
595
|
-
}]
|
|
596
|
-
}
|
|
597
|
-
})
|
|
598
|
-
});
|
|
599
|
-
(0, import_vitest.expect)(result.instances[0]?.syncTables).toEqual(["category", "expense"]);
|
|
600
|
-
(0, import_vitest.expect)(result.instances[0]?.syncTables).not.toContain("dashboard");
|
|
601
|
-
});
|
|
602
80
|
(0, import_vitest.test)("ignores related syntax mentioned only in a query-file comment", () => {
|
|
603
81
|
const files = {
|
|
604
82
|
[`${DIR}/dashboard/queries.ts`]: `// monthSummary moved to category/queries.ts because it uses .related()`
|