over-zero 0.0.32 → 0.0.33
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/cli.cjs +3 -0
- package/dist/cjs/cli.cjs +228 -190
- package/dist/cjs/cli.js +60 -27
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/cli.native.js +277 -228
- package/dist/cjs/cli.native.js.map +1 -1
- package/dist/cjs/createPermissions.js.map +1 -1
- package/dist/cjs/createPermissions.native.js.map +1 -1
- package/dist/cjs/createZeroClient.cjs +6 -3
- package/dist/cjs/createZeroClient.js +11 -4
- package/dist/cjs/createZeroClient.js.map +1 -1
- package/dist/cjs/createZeroClient.native.js +40 -5
- package/dist/cjs/createZeroClient.native.js.map +1 -1
- package/dist/cjs/createZeroServer.cjs +3 -2
- package/dist/cjs/createZeroServer.js +2 -2
- package/dist/cjs/createZeroServer.js.map +1 -1
- package/dist/cjs/createZeroServer.native.js +4 -2
- package/dist/cjs/createZeroServer.native.js.map +1 -1
- package/dist/cjs/helpers/batchQuery.js.map +1 -1
- package/dist/cjs/helpers/batchQuery.native.js.map +1 -1
- package/dist/cjs/helpers/createMutators.js.map +1 -1
- package/dist/cjs/helpers/createMutators.native.js.map +1 -1
- package/dist/cjs/helpers/didRunPermissionCheck.js.map +1 -1
- package/dist/cjs/helpers/didRunPermissionCheck.native.js.map +1 -1
- package/dist/cjs/helpers/ensureLoggedIn.js.map +1 -1
- package/dist/cjs/helpers/ensureLoggedIn.native.js.map +1 -1
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.js.map +1 -1
- package/dist/cjs/helpers/getQueryOrMutatorAuthData.native.js.map +1 -1
- package/dist/cjs/helpers/mutatorContext.js.map +1 -1
- package/dist/cjs/helpers/mutatorContext.native.js.map +1 -1
- package/dist/cjs/helpers/prettyFormatZeroQuery.js.map +1 -1
- package/dist/cjs/helpers/prettyFormatZeroQuery.native.js.map +1 -1
- package/dist/cjs/helpers/useZeroDebug.js.map +1 -1
- package/dist/cjs/helpers/useZeroDebug.native.js.map +1 -1
- package/dist/cjs/index.cjs +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/index.native.js +1 -0
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/mutations.js.map +1 -1
- package/dist/cjs/mutations.native.js.map +1 -1
- package/dist/cjs/{builder.cjs → queryRegistry.cjs} +12 -10
- package/dist/cjs/{queryBuilder.js → queryRegistry.js} +13 -11
- package/dist/cjs/queryRegistry.js.map +6 -0
- package/dist/cjs/{queryBuilder.native.js → queryRegistry.native.js} +13 -12
- package/dist/cjs/queryRegistry.native.js.map +1 -0
- package/dist/cjs/serverWhere.js.map +1 -1
- package/dist/cjs/serverWhere.native.js.map +1 -1
- package/dist/cjs/state.cjs +1 -4
- package/dist/cjs/state.js +1 -4
- package/dist/cjs/state.js.map +1 -1
- package/dist/cjs/state.native.js +1 -2
- package/dist/cjs/state.native.js.map +1 -1
- package/dist/cjs/where.js.map +1 -1
- package/dist/cjs/where.native.js.map +1 -1
- package/dist/cjs/zql.js.map +1 -1
- package/dist/cjs/zql.native.js.map +1 -1
- package/dist/esm/cli.js +61 -28
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/cli.mjs +227 -189
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/cli.native.js +276 -227
- package/dist/esm/cli.native.js.map +1 -1
- package/dist/esm/createPermissions.js.map +1 -1
- package/dist/esm/createPermissions.mjs.map +1 -1
- package/dist/esm/createPermissions.native.js.map +1 -1
- package/dist/esm/createZeroClient.js +11 -3
- package/dist/esm/createZeroClient.js.map +1 -1
- package/dist/esm/createZeroClient.mjs +6 -3
- package/dist/esm/createZeroClient.mjs.map +1 -1
- package/dist/esm/createZeroClient.native.js +40 -5
- package/dist/esm/createZeroClient.native.js.map +1 -1
- package/dist/esm/createZeroServer.js +2 -2
- package/dist/esm/createZeroServer.js.map +1 -1
- package/dist/esm/createZeroServer.mjs +3 -2
- package/dist/esm/createZeroServer.mjs.map +1 -1
- package/dist/esm/createZeroServer.native.js +4 -2
- package/dist/esm/createZeroServer.native.js.map +1 -1
- package/dist/esm/helpers/batchQuery.js.map +1 -1
- package/dist/esm/helpers/batchQuery.mjs.map +1 -1
- package/dist/esm/helpers/batchQuery.native.js.map +1 -1
- package/dist/esm/helpers/createMutators.js.map +1 -1
- package/dist/esm/helpers/createMutators.mjs.map +1 -1
- package/dist/esm/helpers/createMutators.native.js.map +1 -1
- package/dist/esm/helpers/didRunPermissionCheck.js.map +1 -1
- package/dist/esm/helpers/didRunPermissionCheck.mjs.map +1 -1
- package/dist/esm/helpers/didRunPermissionCheck.native.js.map +1 -1
- package/dist/esm/helpers/ensureLoggedIn.js.map +1 -1
- package/dist/esm/helpers/ensureLoggedIn.mjs.map +1 -1
- package/dist/esm/helpers/ensureLoggedIn.native.js.map +1 -1
- package/dist/esm/helpers/getQueryOrMutatorAuthData.js.map +1 -1
- package/dist/esm/helpers/getQueryOrMutatorAuthData.mjs.map +1 -1
- package/dist/esm/helpers/getQueryOrMutatorAuthData.native.js.map +1 -1
- package/dist/esm/helpers/mutatorContext.js.map +1 -1
- package/dist/esm/helpers/mutatorContext.mjs.map +1 -1
- package/dist/esm/helpers/mutatorContext.native.js.map +1 -1
- package/dist/esm/helpers/prettyFormatZeroQuery.js.map +1 -1
- package/dist/esm/helpers/prettyFormatZeroQuery.mjs.map +1 -1
- package/dist/esm/helpers/prettyFormatZeroQuery.native.js.map +1 -1
- package/dist/esm/helpers/useZeroDebug.js.map +1 -1
- package/dist/esm/helpers/useZeroDebug.mjs.map +1 -1
- package/dist/esm/helpers/useZeroDebug.native.js.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/index.mjs +1 -0
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +1 -0
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/mutations.js.map +1 -1
- package/dist/esm/mutations.mjs.map +1 -1
- package/dist/esm/mutations.native.js.map +1 -1
- package/dist/esm/queryRegistry.js +12 -0
- package/dist/esm/queryRegistry.js.map +6 -0
- package/dist/esm/queryRegistry.mjs +9 -0
- package/dist/esm/queryRegistry.mjs.map +1 -0
- package/dist/esm/queryRegistry.native.js +9 -0
- package/dist/esm/queryRegistry.native.js.map +1 -0
- package/dist/esm/serverWhere.js.map +1 -1
- package/dist/esm/serverWhere.mjs.map +1 -1
- package/dist/esm/serverWhere.native.js.map +1 -1
- package/dist/esm/state.js +1 -4
- package/dist/esm/state.js.map +1 -1
- package/dist/esm/state.mjs +1 -4
- package/dist/esm/state.mjs.map +1 -1
- package/dist/esm/state.native.js +1 -2
- package/dist/esm/state.native.js.map +1 -1
- package/dist/esm/where.js.map +1 -1
- package/dist/esm/where.mjs.map +1 -1
- package/dist/esm/where.native.js.map +1 -1
- package/dist/esm/zql.js.map +1 -1
- package/dist/esm/zql.mjs.map +1 -1
- package/dist/esm/zql.native.js.map +1 -1
- package/package.json +4 -4
- package/src/cli.ts +99 -79
- package/src/createPermissions.ts +8 -6
- package/src/createZeroClient.tsx +36 -15
- package/src/createZeroServer.ts +21 -15
- package/src/helpers/batchQuery.ts +2 -1
- package/src/helpers/createMutators.ts +3 -1
- package/src/helpers/didRunPermissionCheck.ts +1 -0
- package/src/helpers/ensureLoggedIn.ts +3 -1
- package/src/helpers/getQueryOrMutatorAuthData.ts +2 -1
- package/src/helpers/mutatorContext.ts +1 -0
- package/src/helpers/prettyFormatZeroQuery.ts +2 -1
- package/src/helpers/useZeroDebug.ts +3 -1
- package/src/index.ts +1 -0
- package/src/mutations.ts +2 -1
- package/src/queryRegistry.ts +12 -0
- package/src/serverWhere.ts +3 -2
- package/src/state.ts +2 -2
- package/src/types.ts +10 -9
- package/src/where.ts +3 -1
- package/src/zql.ts +1 -0
- package/types/createPermissions.d.ts +1 -1
- package/types/createPermissions.d.ts.map +1 -1
- package/types/createZeroClient.d.ts +5 -3
- package/types/createZeroClient.d.ts.map +1 -1
- package/types/createZeroServer.d.ts +4 -3
- package/types/createZeroServer.d.ts.map +1 -1
- package/types/helpers/batchQuery.d.ts.map +1 -1
- package/types/helpers/createMutators.d.ts.map +1 -1
- package/types/helpers/didRunPermissionCheck.d.ts.map +1 -1
- package/types/helpers/ensureLoggedIn.d.ts.map +1 -1
- package/types/helpers/getQueryOrMutatorAuthData.d.ts.map +1 -1
- package/types/helpers/mutatorContext.d.ts.map +1 -1
- package/types/helpers/prettyFormatZeroQuery.d.ts.map +1 -1
- package/types/helpers/useZeroDebug.d.ts.map +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.d.ts.map +1 -1
- package/types/mutations.d.ts +1 -1
- package/types/mutations.d.ts.map +1 -1
- package/types/queryRegistry.d.ts +3 -0
- package/types/queryRegistry.d.ts.map +1 -0
- package/types/serverWhere.d.ts +1 -1
- package/types/serverWhere.d.ts.map +1 -1
- package/types/state.d.ts.map +1 -1
- package/types/types.d.ts.map +1 -1
- package/types/where.d.ts +1 -1
- package/types/where.d.ts.map +1 -1
- package/types/zql.d.ts.map +1 -1
- package/dist/cjs/builder.js +0 -26
- package/dist/cjs/builder.js.map +0 -6
- package/dist/cjs/builder.native.js +0 -35
- package/dist/cjs/builder.native.js.map +0 -1
- package/dist/cjs/helpers/context.cjs +0 -40
- package/dist/cjs/helpers/context.js +0 -36
- package/dist/cjs/helpers/context.js.map +0 -6
- package/dist/cjs/helpers/context.native.js +0 -43
- package/dist/cjs/helpers/context.native.js.map +0 -1
- package/dist/cjs/helpers/queryContext.cjs +0 -40
- package/dist/cjs/helpers/queryContext.js +0 -36
- package/dist/cjs/helpers/queryContext.js.map +0 -6
- package/dist/cjs/helpers/queryContext.native.js +0 -43
- package/dist/cjs/helpers/queryContext.native.js.map +0 -1
- package/dist/cjs/helpers/queryOrMutatorAuthData.cjs +0 -0
- package/dist/cjs/helpers/queryOrMutatorAuthData.js +0 -1
- package/dist/cjs/helpers/queryOrMutatorAuthData.js.map +0 -6
- package/dist/cjs/helpers/queryOrMutatorAuthData.native.js +0 -2
- package/dist/cjs/helpers/queryOrMutatorAuthData.native.js.map +0 -1
- package/dist/cjs/helpers/queryOrMutatorContext.cjs +0 -0
- package/dist/cjs/helpers/queryOrMutatorContext.js +0 -1
- package/dist/cjs/helpers/queryOrMutatorContext.js.map +0 -6
- package/dist/cjs/helpers/queryOrMutatorContext.native.js +0 -2
- package/dist/cjs/helpers/queryOrMutatorContext.native.js.map +0 -1
- package/dist/cjs/query.cjs +0 -34
- package/dist/cjs/query.js +0 -28
- package/dist/cjs/query.js.map +0 -6
- package/dist/cjs/query.native.js +0 -39
- package/dist/cjs/query.native.js.map +0 -1
- package/dist/cjs/queryBuilder.cjs +0 -31
- package/dist/cjs/queryBuilder.js.map +0 -6
- package/dist/cjs/queryBuilder.native.js.map +0 -1
- package/dist/esm/builder.js +0 -10
- package/dist/esm/builder.js.map +0 -6
- package/dist/esm/builder.mjs +0 -8
- package/dist/esm/builder.mjs.map +0 -1
- package/dist/esm/builder.native.js +0 -9
- package/dist/esm/builder.native.js.map +0 -1
- package/dist/esm/helpers/context.js +0 -20
- package/dist/esm/helpers/context.js.map +0 -6
- package/dist/esm/helpers/context.mjs +0 -15
- package/dist/esm/helpers/context.mjs.map +0 -1
- package/dist/esm/helpers/context.native.js +0 -15
- package/dist/esm/helpers/context.native.js.map +0 -1
- package/dist/esm/helpers/queryContext.js +0 -20
- package/dist/esm/helpers/queryContext.js.map +0 -6
- package/dist/esm/helpers/queryContext.mjs +0 -15
- package/dist/esm/helpers/queryContext.mjs.map +0 -1
- package/dist/esm/helpers/queryContext.native.js +0 -15
- package/dist/esm/helpers/queryContext.native.js.map +0 -1
- package/dist/esm/helpers/queryOrMutatorAuthData.js +0 -1
- package/dist/esm/helpers/queryOrMutatorAuthData.js.map +0 -6
- package/dist/esm/helpers/queryOrMutatorAuthData.mjs +0 -2
- package/dist/esm/helpers/queryOrMutatorAuthData.mjs.map +0 -1
- package/dist/esm/helpers/queryOrMutatorAuthData.native.js +0 -2
- package/dist/esm/helpers/queryOrMutatorAuthData.native.js.map +0 -1
- package/dist/esm/helpers/queryOrMutatorContext.js +0 -1
- package/dist/esm/helpers/queryOrMutatorContext.js.map +0 -6
- package/dist/esm/helpers/queryOrMutatorContext.mjs +0 -2
- package/dist/esm/helpers/queryOrMutatorContext.mjs.map +0 -1
- package/dist/esm/helpers/queryOrMutatorContext.native.js +0 -2
- package/dist/esm/helpers/queryOrMutatorContext.native.js.map +0 -1
- package/dist/esm/query.js +0 -13
- package/dist/esm/query.js.map +0 -6
- package/dist/esm/query.mjs +0 -11
- package/dist/esm/query.mjs.map +0 -1
- package/dist/esm/query.native.js +0 -13
- package/dist/esm/query.native.js.map +0 -1
- package/dist/esm/queryBuilder.js +0 -10
- package/dist/esm/queryBuilder.js.map +0 -6
- package/dist/esm/queryBuilder.mjs +0 -8
- package/dist/esm/queryBuilder.mjs.map +0 -1
- package/dist/esm/queryBuilder.native.js +0 -9
- package/dist/esm/queryBuilder.native.js.map +0 -1
package/src/cli.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs'
|
|
3
|
+
import { basename, resolve } from 'node:path'
|
|
4
|
+
|
|
2
5
|
import { ModelToValibot } from '@sinclair/typebox-codegen/model'
|
|
3
6
|
import { TypeScriptToModel } from '@sinclair/typebox-codegen/typescript'
|
|
4
7
|
import { defineCommand, runMain } from 'citty'
|
|
5
|
-
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs'
|
|
6
|
-
import { basename, resolve } from 'node:path'
|
|
7
8
|
import * as ts from 'typescript'
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -113,56 +114,6 @@ const generateQueries = defineCommand({
|
|
|
113
114
|
},
|
|
114
115
|
})
|
|
115
116
|
|
|
116
|
-
function generateServerQueriesFile(
|
|
117
|
-
queries: Array<{ name: string; params: string; valibotCode: string }>
|
|
118
|
-
) {
|
|
119
|
-
const imports = `import * as v from 'valibot'\nimport * as queries from './queries'\n`
|
|
120
|
-
|
|
121
|
-
const validators = queries
|
|
122
|
-
.map((q) => {
|
|
123
|
-
// extract just the schema definition (without import and type export)
|
|
124
|
-
const lines = q.valibotCode.split('\n').filter((l) => l.trim())
|
|
125
|
-
// find line starting with "export const QueryParams"
|
|
126
|
-
const schemaLineIndex = lines.findIndex((l) =>
|
|
127
|
-
l.startsWith('export const QueryParams')
|
|
128
|
-
)
|
|
129
|
-
if (schemaLineIndex === -1) {
|
|
130
|
-
return `export const ${q.name}Schema = v.void()`
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// get the full schema (might be multiline)
|
|
134
|
-
const schemaLines: string[] = []
|
|
135
|
-
let openBraces = 0
|
|
136
|
-
let started = false
|
|
137
|
-
|
|
138
|
-
for (let i = schemaLineIndex; i < lines.length; i++) {
|
|
139
|
-
const line = lines[i]!
|
|
140
|
-
const cleaned = started ? line : line.replace('export const QueryParams = ', '')
|
|
141
|
-
schemaLines.push(cleaned)
|
|
142
|
-
started = true
|
|
143
|
-
|
|
144
|
-
// count braces to know when we're done
|
|
145
|
-
openBraces += (cleaned.match(/\{/g) || []).length
|
|
146
|
-
openBraces -= (cleaned.match(/\}/g) || []).length
|
|
147
|
-
openBraces += (cleaned.match(/\(/g) || []).length
|
|
148
|
-
openBraces -= (cleaned.match(/\)/g) || []).length
|
|
149
|
-
|
|
150
|
-
// done when braces are balanced and we have at least one line
|
|
151
|
-
if (openBraces === 0 && schemaLines.length > 0) {
|
|
152
|
-
break
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const schemaDef = schemaLines.join('\n')
|
|
157
|
-
return `export const ${q.name}Schema = ${schemaDef}`
|
|
158
|
-
})
|
|
159
|
-
.join('\n\n')
|
|
160
|
-
|
|
161
|
-
const queryMap = `\nexport const queryValidators = {\n${queries.map((q) => ` ${q.name}: ${q.name}Schema,`).join('\n')}\n} as const\n`
|
|
162
|
-
|
|
163
|
-
return imports + '\n' + validators + '\n' + queryMap
|
|
164
|
-
}
|
|
165
|
-
|
|
166
117
|
const generate = defineCommand({
|
|
167
118
|
meta: {
|
|
168
119
|
name: 'generate',
|
|
@@ -323,14 +274,23 @@ const generate = defineCommand({
|
|
|
323
274
|
)
|
|
324
275
|
|
|
325
276
|
const allQueries = queryResults.flat()
|
|
326
|
-
const
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
277
|
+
const clientQueriesOutput = generateClientQueriesFile(allQueries)
|
|
278
|
+
const serverQueriesOutput = generateServerQueriesFile(allQueries)
|
|
279
|
+
|
|
280
|
+
const clientChanged = writeFileIfChanged(
|
|
281
|
+
resolve(generatedDir, 'queries.client.ts'),
|
|
282
|
+
clientQueriesOutput
|
|
283
|
+
)
|
|
284
|
+
const serverChanged = writeFileIfChanged(
|
|
285
|
+
resolve(generatedDir, 'queries.server.ts'),
|
|
286
|
+
serverQueriesOutput
|
|
330
287
|
)
|
|
331
288
|
|
|
332
|
-
if (
|
|
333
|
-
console.info(` 📝 Updated queries.ts`)
|
|
289
|
+
if (clientChanged) {
|
|
290
|
+
console.info(` 📝 Updated queries.client.ts`)
|
|
291
|
+
}
|
|
292
|
+
if (serverChanged) {
|
|
293
|
+
console.info(` 📝 Updated queries.server.ts`)
|
|
334
294
|
}
|
|
335
295
|
|
|
336
296
|
console.info(
|
|
@@ -445,7 +405,7 @@ function generateTablesFile(modelFiles: string[]) {
|
|
|
445
405
|
return `// auto-generated by: over-zero generate\n// this is separate from models as otherwise you end up with circular types :/\n\n${exports}\n`
|
|
446
406
|
}
|
|
447
407
|
|
|
448
|
-
function
|
|
408
|
+
function generateClientQueriesFile(
|
|
449
409
|
queries: Array<{
|
|
450
410
|
name: string
|
|
451
411
|
params: string
|
|
@@ -453,30 +413,68 @@ function generateQueriesFile(
|
|
|
453
413
|
sourceFile: string
|
|
454
414
|
}>
|
|
455
415
|
) {
|
|
456
|
-
//
|
|
457
|
-
const
|
|
416
|
+
// get unique source files sorted
|
|
417
|
+
const sortedFiles = [...new Set(queries.map((q) => q.sourceFile))].sort()
|
|
418
|
+
|
|
419
|
+
// generate imports
|
|
420
|
+
const imports = sortedFiles
|
|
421
|
+
.map((file) => `import * as ${file}Queries from '../queries/${file}'`)
|
|
422
|
+
.join('\n')
|
|
423
|
+
|
|
424
|
+
// generate namespaced export object
|
|
425
|
+
const namespaces = sortedFiles.map((file) => ` ${file}: ${file}Queries,`).join('\n')
|
|
426
|
+
|
|
427
|
+
return `/**
|
|
428
|
+
* auto-generated by: over-zero generate
|
|
429
|
+
*
|
|
430
|
+
* client-side query references for minification-safe query identity.
|
|
431
|
+
* this file re-exports all query modules - while this breaks tree-shaking,
|
|
432
|
+
* queries are typically small and few in number even in larger apps.
|
|
433
|
+
*/
|
|
434
|
+
${imports}
|
|
458
435
|
|
|
459
|
-
|
|
436
|
+
export const clientQueries = {
|
|
437
|
+
${namespaces}
|
|
438
|
+
}
|
|
439
|
+
`
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function generateServerQueriesFile(
|
|
443
|
+
queries: Array<{
|
|
444
|
+
name: string
|
|
445
|
+
params: string
|
|
446
|
+
valibotCode: string
|
|
447
|
+
sourceFile: string
|
|
448
|
+
}>
|
|
449
|
+
) {
|
|
450
|
+
// group queries by source file
|
|
460
451
|
const queryByFile = new Map<string, typeof queries>()
|
|
461
|
-
for (const q of
|
|
452
|
+
for (const q of queries) {
|
|
462
453
|
if (!queryByFile.has(q.sourceFile)) {
|
|
463
454
|
queryByFile.set(q.sourceFile, [])
|
|
464
455
|
}
|
|
465
456
|
queryByFile.get(q.sourceFile)!.push(q)
|
|
466
457
|
}
|
|
467
458
|
|
|
468
|
-
//
|
|
469
|
-
const
|
|
470
|
-
|
|
459
|
+
// sort file names for consistent output
|
|
460
|
+
const sortedFiles = Array.from(queryByFile.keys()).sort()
|
|
461
|
+
|
|
462
|
+
// generate imports
|
|
463
|
+
const queryImports = sortedFiles
|
|
471
464
|
.map((file) => `import * as ${file}Queries from '../queries/${file}'`)
|
|
472
465
|
.join('\n')
|
|
473
466
|
|
|
474
|
-
const imports =
|
|
467
|
+
const imports = `// auto-generated by: over-zero generate
|
|
468
|
+
// server-side syncedQuery wrappers with validators
|
|
475
469
|
import { syncedQuery } from '@rocicorp/zero'
|
|
470
|
+
import * as v from 'valibot'
|
|
476
471
|
${queryImports}
|
|
477
472
|
`
|
|
478
473
|
|
|
479
|
-
|
|
474
|
+
// generate synced queries grouped by namespace
|
|
475
|
+
const sortedQueries = [...queries].sort((a, b) => a.name.localeCompare(b.name))
|
|
476
|
+
|
|
477
|
+
const syncedQueryDefs = sortedQueries
|
|
480
478
|
.map((q) => {
|
|
481
479
|
// extract validator schema
|
|
482
480
|
const lines = q.valibotCode.split('\n').filter((l) => l.trim())
|
|
@@ -514,21 +512,43 @@ ${queryImports}
|
|
|
514
512
|
? 'v.parser(v.tuple([]))'
|
|
515
513
|
: `v.parser(v.tuple([${validatorDef}]))`
|
|
516
514
|
|
|
515
|
+
// namespaced query name: file.queryName
|
|
516
|
+
const namespacedName = `${q.sourceFile}.${q.name}`
|
|
517
|
+
|
|
517
518
|
// for void queries, no arg parameter
|
|
518
519
|
const queryFn =
|
|
519
520
|
validatorDef === 'v.void()'
|
|
520
521
|
? `() => {
|
|
521
|
-
|
|
522
|
-
}`
|
|
522
|
+
return ${q.sourceFile}Queries.${q.name}()
|
|
523
|
+
}`
|
|
523
524
|
: `(arg) => {
|
|
524
|
-
|
|
525
|
-
}`
|
|
525
|
+
return ${q.sourceFile}Queries.${q.name}(arg)
|
|
526
|
+
}`
|
|
526
527
|
|
|
527
|
-
return `
|
|
528
|
+
return `const ${q.name}Synced = syncedQuery('${namespacedName}', ${wrappedValidator}, ${queryFn})`
|
|
528
529
|
})
|
|
529
530
|
.join('\n\n')
|
|
530
531
|
|
|
531
|
-
|
|
532
|
+
// generate namespaced export object
|
|
533
|
+
const namespaces = sortedFiles
|
|
534
|
+
.map((file) => {
|
|
535
|
+
const fileQueries = queryByFile
|
|
536
|
+
.get(file)!
|
|
537
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
538
|
+
const queryEntries = fileQueries
|
|
539
|
+
.map((q) => ` ${q.name}: ${q.name}Synced,`)
|
|
540
|
+
.join('\n')
|
|
541
|
+
return ` ${file}: {\n${queryEntries}\n },`
|
|
542
|
+
})
|
|
543
|
+
.join('\n')
|
|
544
|
+
|
|
545
|
+
return `${imports}
|
|
546
|
+
${syncedQueryDefs}
|
|
547
|
+
|
|
548
|
+
export const serverQueries = {
|
|
549
|
+
${namespaces}
|
|
550
|
+
}
|
|
551
|
+
`
|
|
532
552
|
}
|
|
533
553
|
|
|
534
554
|
function generateReadmeFile() {
|
|
@@ -541,7 +561,8 @@ this folder is auto-generated by over-zero. do not edit files here directly.
|
|
|
541
561
|
- \`models.ts\` - exports all models from ../models
|
|
542
562
|
- \`types.ts\` - typescript types derived from table schemas
|
|
543
563
|
- \`tables.ts\` - exports table schemas for type inference
|
|
544
|
-
- \`queries.ts\` -
|
|
564
|
+
- \`queries.client.ts\` - namespaced query references for client setup
|
|
565
|
+
- \`queries.server.ts\` - namespaced syncedQuery wrappers for server setup
|
|
545
566
|
|
|
546
567
|
## usage guidelines
|
|
547
568
|
|
|
@@ -549,16 +570,15 @@ this folder is auto-generated by over-zero. do not edit files here directly.
|
|
|
549
570
|
|
|
550
571
|
### queries
|
|
551
572
|
|
|
552
|
-
|
|
573
|
+
write your queries as plain functions in \`../queries/\` and import them directly:
|
|
553
574
|
|
|
554
575
|
\`\`\`ts
|
|
555
|
-
// ❌ bad - don't import from generated
|
|
556
|
-
import { channelMessages } from '~/data/generated/queries'
|
|
557
|
-
|
|
558
576
|
// ✅ good - import from queries
|
|
559
577
|
import { channelMessages } from '~/data/queries/message'
|
|
560
578
|
\`\`\`
|
|
561
579
|
|
|
580
|
+
the generated query files are only used internally by zero client/server setup.
|
|
581
|
+
|
|
562
582
|
### types
|
|
563
583
|
|
|
564
584
|
you can import types from this folder, but prefer re-exporting from \`../types.ts\`:
|
package/src/createPermissions.ts
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
|
+
import { ensure, EnsureError } from '@vxrn/helpers'
|
|
2
|
+
|
|
3
|
+
import { setDidRunPermissionCheck } from './helpers/didRunPermissionCheck'
|
|
4
|
+
import { mutatorContext } from './helpers/mutatorContext'
|
|
5
|
+
import { prettyFormatZeroQuery } from './helpers/prettyFormatZeroQuery'
|
|
6
|
+
import { getWhereTableName } from './where'
|
|
7
|
+
|
|
8
|
+
import type { AuthData, Can, TableName, Transaction, Where } from './types'
|
|
1
9
|
import type {
|
|
2
10
|
Condition,
|
|
3
11
|
ExpressionBuilder,
|
|
4
12
|
Query,
|
|
5
13
|
Schema as ZeroSchema,
|
|
6
14
|
} from '@rocicorp/zero'
|
|
7
|
-
import { ensure, EnsureError } from '@vxrn/helpers'
|
|
8
|
-
import { setDidRunPermissionCheck } from './helpers/didRunPermissionCheck'
|
|
9
|
-
import { mutatorContext } from './helpers/mutatorContext'
|
|
10
|
-
import { prettyFormatZeroQuery } from './helpers/prettyFormatZeroQuery'
|
|
11
|
-
import type { AuthData, Can, TableName, Transaction, Where } from './types'
|
|
12
|
-
import { getWhereTableName } from './where'
|
|
13
15
|
|
|
14
16
|
export function createPermissions<Schema extends ZeroSchema>({
|
|
15
17
|
environment,
|
package/src/createZeroClient.tsx
CHANGED
|
@@ -1,34 +1,55 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
HumanReadable,
|
|
3
|
-
Query,
|
|
4
|
-
ReadonlyJSONValue,
|
|
5
|
-
Row,
|
|
6
|
-
SyncedQuery,
|
|
7
|
-
Zero,
|
|
8
|
-
ZeroOptions,
|
|
9
|
-
Schema as ZeroSchema,
|
|
10
|
-
} from '@rocicorp/zero'
|
|
11
1
|
import { syncedQuery } from '@rocicorp/zero'
|
|
12
2
|
import { useZero, ZeroProvider, useQuery as zeroUseQuery } from '@rocicorp/zero/react'
|
|
13
3
|
import { createEmitter, mapObject } from '@vxrn/helpers'
|
|
14
4
|
import { createContext, use, useMemo, type ReactNode } from 'react'
|
|
5
|
+
|
|
15
6
|
import { createPermissions } from './createPermissions'
|
|
16
7
|
import { createMutators } from './helpers/createMutators'
|
|
17
8
|
import { prettyFormatZeroQuery } from './helpers/prettyFormatZeroQuery'
|
|
18
9
|
import { useZeroDebug } from './helpers/useZeroDebug'
|
|
10
|
+
import { registerQuery, getQueryName } from './queryRegistry'
|
|
19
11
|
import { setAuthData, setSchema } from './state'
|
|
12
|
+
|
|
20
13
|
import type { AuthData, GenericModels, GetZeroMutators, ZeroEvent } from './types'
|
|
14
|
+
import type {
|
|
15
|
+
HumanReadable,
|
|
16
|
+
Query,
|
|
17
|
+
ReadonlyJSONValue,
|
|
18
|
+
Row,
|
|
19
|
+
SyncedQuery,
|
|
20
|
+
Zero,
|
|
21
|
+
ZeroOptions,
|
|
22
|
+
Schema as ZeroSchema,
|
|
23
|
+
} from '@rocicorp/zero'
|
|
24
|
+
|
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
26
|
+
export type ClientQueries = Record<string, Record<string, (...args: any[]) => any>>
|
|
21
27
|
|
|
22
28
|
export function createZeroClient<
|
|
23
29
|
Schema extends ZeroSchema,
|
|
24
30
|
Models extends GenericModels,
|
|
25
|
-
>({
|
|
31
|
+
>({
|
|
32
|
+
schema,
|
|
33
|
+
models,
|
|
34
|
+
clientQueries,
|
|
35
|
+
}: {
|
|
36
|
+
schema: Schema
|
|
37
|
+
models: Models
|
|
38
|
+
clientQueries: ClientQueries
|
|
39
|
+
}) {
|
|
26
40
|
type ZeroMutators = GetZeroMutators<Models>
|
|
27
41
|
type ZeroInstance = Zero<Schema, ZeroMutators>
|
|
28
42
|
type TableName = keyof ZeroInstance['query']
|
|
29
43
|
|
|
30
44
|
setSchema(schema)
|
|
31
45
|
|
|
46
|
+
// build query registry from namespaced clientQueries
|
|
47
|
+
for (const [namespace, queries] of Object.entries(clientQueries)) {
|
|
48
|
+
for (const [name, fn] of Object.entries(queries)) {
|
|
49
|
+
registerQuery(fn, `${namespace}.${name}`)
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
32
53
|
const DisabledContext = createContext(false)
|
|
33
54
|
|
|
34
55
|
const modelWritePermissions = mapObject(models, (val) => val.permissions) as {
|
|
@@ -170,7 +191,7 @@ export function createZeroClient<
|
|
|
170
191
|
}
|
|
171
192
|
|
|
172
193
|
const fn = queryOrFn
|
|
173
|
-
const queryName = fn.name || 'anonymousQuery'
|
|
194
|
+
const queryName = getQueryName(fn) || fn.name || 'anonymousQuery'
|
|
174
195
|
|
|
175
196
|
// Determine if this is Pattern 2 (with params) or Pattern 3 (no params)
|
|
176
197
|
const hasParams =
|
|
@@ -200,7 +221,7 @@ export function createZeroClient<
|
|
|
200
221
|
const out = zeroUseQuery(actualQuery, options)
|
|
201
222
|
|
|
202
223
|
if (process.env.NODE_ENV === 'development') {
|
|
203
|
-
//
|
|
224
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
204
225
|
useZeroDebug(actualQuery, options, out)
|
|
205
226
|
}
|
|
206
227
|
|
|
@@ -218,10 +239,10 @@ export function createZeroClient<
|
|
|
218
239
|
...props
|
|
219
240
|
}: Omit<ZeroOptions<Schema, ZeroMutators>, 'schema' | 'mutators'> & {
|
|
220
241
|
children: ReactNode
|
|
221
|
-
authData?: AuthData
|
|
242
|
+
authData?: AuthData | null
|
|
222
243
|
disable?: boolean
|
|
223
244
|
}) => {
|
|
224
|
-
const authData = authDataIn as AuthData
|
|
245
|
+
const authData = (authDataIn ?? null) as AuthData
|
|
225
246
|
|
|
226
247
|
const mutators = useMemo(() => {
|
|
227
248
|
setAuthData(authData)
|
package/src/createZeroServer.ts
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
HumanReadable,
|
|
3
|
-
Query,
|
|
4
|
-
ReadonlyJSONValue,
|
|
5
|
-
SyncedQuery,
|
|
6
|
-
Schema as ZeroSchema,
|
|
7
|
-
} from '@rocicorp/zero'
|
|
8
|
-
import type { TransactionProviderInput } from '@rocicorp/zero/pg'
|
|
9
1
|
import { handleGetQueriesRequest, PushProcessor } from '@rocicorp/zero/pg'
|
|
10
2
|
import { zeroNodePg } from '@rocicorp/zero/server/adapters/pg'
|
|
11
3
|
import { assertString, randomId } from '@vxrn/helpers'
|
|
12
4
|
import { Pool } from 'pg'
|
|
5
|
+
|
|
13
6
|
import { createPermissions } from './createPermissions'
|
|
14
7
|
import { createMutators } from './helpers/createMutators'
|
|
15
8
|
import { isInZeroMutation, mutatorContext } from './helpers/mutatorContext'
|
|
16
9
|
import { setAuthData, setSchema } from './state'
|
|
10
|
+
|
|
17
11
|
import type {
|
|
18
12
|
AsyncAction,
|
|
19
13
|
AuthData,
|
|
@@ -21,21 +15,31 @@ import type {
|
|
|
21
15
|
GetZeroMutators,
|
|
22
16
|
Transaction,
|
|
23
17
|
} from './types'
|
|
18
|
+
import type {
|
|
19
|
+
HumanReadable,
|
|
20
|
+
Query,
|
|
21
|
+
ReadonlyJSONValue,
|
|
22
|
+
SyncedQuery,
|
|
23
|
+
Schema as ZeroSchema,
|
|
24
|
+
} from '@rocicorp/zero'
|
|
25
|
+
import type { TransactionProviderInput } from '@rocicorp/zero/pg'
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
export type ServerQueries = Record<
|
|
29
|
+
string,
|
|
30
|
+
Record<string, SyncedQuery<any, any, any, any, any>>
|
|
31
|
+
>
|
|
24
32
|
|
|
25
33
|
export function createZeroServer<
|
|
26
34
|
Schema extends ZeroSchema,
|
|
27
35
|
Models extends GenericModels,
|
|
28
36
|
ServerActions extends Record<string, unknown>,
|
|
29
|
-
Queries extends Record<string, SyncedQuery<any, any, any, any, any>> = Record<
|
|
30
|
-
string,
|
|
31
|
-
never
|
|
32
|
-
>,
|
|
33
37
|
>({
|
|
34
38
|
createServerActions,
|
|
35
39
|
database,
|
|
36
40
|
schema,
|
|
37
41
|
models,
|
|
38
|
-
|
|
42
|
+
serverQueries,
|
|
39
43
|
}: {
|
|
40
44
|
/**
|
|
41
45
|
* The DB connection string, same as ZERO_UPSTREAM_DB
|
|
@@ -44,7 +48,7 @@ export function createZeroServer<
|
|
|
44
48
|
schema: Schema
|
|
45
49
|
models: Models
|
|
46
50
|
createServerActions: () => ServerActions
|
|
47
|
-
|
|
51
|
+
serverQueries?: ServerQueries
|
|
48
52
|
}) {
|
|
49
53
|
setSchema(schema)
|
|
50
54
|
|
|
@@ -115,7 +119,9 @@ export function createZeroServer<
|
|
|
115
119
|
request: Request
|
|
116
120
|
}) => {
|
|
117
121
|
function getQuery(name: string, args: readonly ReadonlyJSONValue[]) {
|
|
118
|
-
|
|
122
|
+
// name format: "namespace.queryName" (e.g. "post.allPosts")
|
|
123
|
+
const [namespace, queryName] = name.split('.')
|
|
124
|
+
const q = serverQueries?.[namespace!]?.[queryName!]
|
|
119
125
|
if (!q) {
|
|
120
126
|
throw new Error(`No such query: ${name}`)
|
|
121
127
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import type { Query, Row } from '@rocicorp/zero'
|
|
2
1
|
import { sleep } from '@vxrn/helpers'
|
|
3
2
|
|
|
3
|
+
import type { Query, Row } from '@rocicorp/zero'
|
|
4
|
+
|
|
4
5
|
export async function batchQuery<Q extends Query<any, any, any>, Item extends Row<Q>>(
|
|
5
6
|
q: Q,
|
|
6
7
|
mapper: (items: Item[]) => Promise<void>,
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import { isClient, isServer, mapObject, time } from '@vxrn/helpers'
|
|
2
|
+
|
|
3
|
+
import { runWithContext } from './mutatorContext'
|
|
4
|
+
|
|
2
5
|
import type {
|
|
3
6
|
AuthData,
|
|
4
7
|
Can,
|
|
@@ -7,7 +10,6 @@ import type {
|
|
|
7
10
|
MutatorContext,
|
|
8
11
|
Transaction,
|
|
9
12
|
} from '../types'
|
|
10
|
-
import { runWithContext } from './mutatorContext'
|
|
11
13
|
|
|
12
14
|
export function createMutators<Models extends GenericModels>({
|
|
13
15
|
environment,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ensure } from '@vxrn/helpers'
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
import { mutatorContext } from './mutatorContext'
|
|
4
4
|
|
|
5
|
+
import type { AuthData } from '../types'
|
|
6
|
+
|
|
5
7
|
export const ensureLoggedIn = (): AuthData => {
|
|
6
8
|
const { authData } = mutatorContext()
|
|
7
9
|
ensure(authData, 'logged in')
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getAuthData } from '../state'
|
|
2
|
-
import type { AuthData } from '../types'
|
|
3
2
|
import { isInZeroMutation, mutatorContext } from './mutatorContext'
|
|
4
3
|
|
|
4
|
+
import type { AuthData } from '../types'
|
|
5
|
+
|
|
5
6
|
export function getQueryOrMutatorAuthData(): AuthData | null {
|
|
6
7
|
if (isInZeroMutation()) {
|
|
7
8
|
return mutatorContext().authData as AuthData
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { Query } from '@rocicorp/zero'
|
|
2
1
|
import { getCurrentComponentStack } from '@vxrn/helpers'
|
|
3
2
|
import { useEffect, useId } from 'react'
|
|
3
|
+
|
|
4
4
|
import { prettyFormatZeroQuery } from './prettyFormatZeroQuery'
|
|
5
5
|
|
|
6
|
+
import type { Query } from '@rocicorp/zero'
|
|
7
|
+
|
|
6
8
|
const activeQueries = new Map<string, number>()
|
|
7
9
|
|
|
8
10
|
// AST change tracking
|
package/src/index.ts
CHANGED
package/src/mutations.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { TableBuilderWithColumns } from '@rocicorp/zero'
|
|
2
1
|
import { getDidRunPermissionCheck } from './helpers/didRunPermissionCheck'
|
|
2
|
+
|
|
3
3
|
import type {
|
|
4
4
|
MutatorContext,
|
|
5
5
|
TableInsertRow,
|
|
@@ -7,6 +7,7 @@ import type {
|
|
|
7
7
|
TableUpdateRow,
|
|
8
8
|
Where,
|
|
9
9
|
} from './types'
|
|
10
|
+
import type { TableBuilderWithColumns } from '@rocicorp/zero'
|
|
10
11
|
|
|
11
12
|
// two ways to use it:
|
|
12
13
|
// - mutations({}) which doesn't add the "allowed" helper or add CRUD
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// registry for query functions to their stable names
|
|
2
|
+
// this allows minification while preserving query identity
|
|
3
|
+
|
|
4
|
+
const queryNameRegistry = new WeakMap<Function, string>()
|
|
5
|
+
|
|
6
|
+
export function registerQuery(fn: Function, name: string) {
|
|
7
|
+
queryNameRegistry.set(fn, name)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function getQueryName(fn: Function): string | undefined {
|
|
11
|
+
return queryNameRegistry.get(fn)
|
|
12
|
+
}
|
package/src/serverWhere.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { Condition } from '@rocicorp/zero'
|
|
2
|
-
import type { TableName, Where } from './types'
|
|
3
1
|
import { where } from './where'
|
|
4
2
|
|
|
3
|
+
import type { TableName, Where } from './types'
|
|
4
|
+
import type { Condition } from '@rocicorp/zero'
|
|
5
|
+
|
|
5
6
|
export function serverWhere<Table extends TableName, Builder extends Where<Table>>(
|
|
6
7
|
tableName: Table,
|
|
7
8
|
builder: Builder
|
package/src/state.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createBuilder, type Schema } from '@rocicorp/zero'
|
|
2
|
+
|
|
2
3
|
import type { AuthData, QueryBuilder } from './types'
|
|
3
4
|
|
|
4
5
|
let schema: Schema | null = null
|
|
@@ -23,8 +24,7 @@ export const setSchema = (_: Schema) => {
|
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
export const getAuthData = () => {
|
|
26
|
-
|
|
27
|
-
return authData
|
|
27
|
+
return authData || null
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export const setAuthData = (_: AuthData) => {
|
package/src/types.ts
CHANGED
|
@@ -47,13 +47,15 @@ export type TableName = keyof Schema['tables'] extends string
|
|
|
47
47
|
|
|
48
48
|
export type Transaction = ZeroTransaction<Schema>
|
|
49
49
|
|
|
50
|
-
export type AuthData =
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
export type AuthData =
|
|
51
|
+
FinalConfig['authData'] extends Record<string, unknown>
|
|
52
|
+
? FinalConfig['authData']
|
|
53
|
+
: Record<string, unknown>
|
|
53
54
|
|
|
54
|
-
export type ServerActions =
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
export type ServerActions =
|
|
56
|
+
FinalConfig['serverActions'] extends Record<string, unknown>
|
|
57
|
+
? FinalConfig['serverActions']
|
|
58
|
+
: Record<string, unknown>
|
|
57
59
|
|
|
58
60
|
export type QueryBuilder = SchemaQuery<Schema>
|
|
59
61
|
|
|
@@ -112,9 +114,8 @@ export type AsyncAction = () => Promise<void>
|
|
|
112
114
|
|
|
113
115
|
type GenericTable = TableBuilderWithColumns<any>
|
|
114
116
|
|
|
115
|
-
type GetTableSchema<TS extends GenericTable> =
|
|
116
|
-
? S
|
|
117
|
-
: never
|
|
117
|
+
type GetTableSchema<TS extends GenericTable> =
|
|
118
|
+
TS extends TableBuilderWithColumns<infer S> ? S : never
|
|
118
119
|
|
|
119
120
|
// all non-optional keys required (but optional can be undefined)
|
|
120
121
|
export type TableInsertRow<TS extends GenericTable> = NullToOptional<
|
package/src/where.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import type { Condition, ExpressionBuilder } from '@rocicorp/zero'
|
|
2
1
|
import { globalValue, isClient } from '@vxrn/helpers'
|
|
2
|
+
|
|
3
3
|
import { getQueryOrMutatorAuthData } from './helpers/getQueryOrMutatorAuthData'
|
|
4
|
+
|
|
4
5
|
import type { TableName, Where } from './types'
|
|
6
|
+
import type { Condition, ExpressionBuilder } from '@rocicorp/zero'
|
|
5
7
|
|
|
6
8
|
export function where<Table extends TableName, Builder extends Where<Table>>(
|
|
7
9
|
tableName: Table,
|