over-zero 0.0.32 → 0.0.34
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 +224 -205
- package/dist/cjs/cli.js +57 -40
- package/dist/cjs/cli.js.map +1 -1
- package/dist/cjs/cli.native.js +270 -248
- 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 +5 -3
- package/dist/cjs/createZeroServer.js +8 -3
- package/dist/cjs/createZeroServer.js.map +1 -1
- package/dist/cjs/createZeroServer.native.js +39 -3
- 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 +58 -41
- package/dist/esm/cli.js.map +1 -1
- package/dist/esm/cli.mjs +223 -204
- package/dist/esm/cli.mjs.map +1 -1
- package/dist/esm/cli.native.js +269 -247
- 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 +8 -3
- package/dist/esm/createZeroServer.js.map +1 -1
- package/dist/esm/createZeroServer.mjs +5 -3
- package/dist/esm/createZeroServer.mjs.map +1 -1
- package/dist/esm/createZeroServer.native.js +39 -3
- 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 +119 -122
- package/src/createPermissions.ts +8 -6
- package/src/createZeroClient.tsx +37 -15
- package/src/createZeroServer.ts +30 -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 groupedQueriesOutput = generateGroupedQueriesFile(allQueries)
|
|
278
|
+
const syncedQueriesOutput = generateSyncedQueriesFile(allQueries)
|
|
279
|
+
|
|
280
|
+
const groupedChanged = writeFileIfChanged(
|
|
281
|
+
resolve(generatedDir, 'groupedQueries.ts'),
|
|
282
|
+
groupedQueriesOutput
|
|
283
|
+
)
|
|
284
|
+
const syncedChanged = writeFileIfChanged(
|
|
285
|
+
resolve(generatedDir, 'syncedQueries.ts'),
|
|
286
|
+
syncedQueriesOutput
|
|
330
287
|
)
|
|
331
288
|
|
|
332
|
-
if (
|
|
333
|
-
console.info(` 📝 Updated
|
|
289
|
+
if (groupedChanged) {
|
|
290
|
+
console.info(` 📝 Updated groupedQueries.ts`)
|
|
291
|
+
}
|
|
292
|
+
if (syncedChanged) {
|
|
293
|
+
console.info(` 📝 Updated syncedQueries.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 generateGroupedQueriesFile(
|
|
449
409
|
queries: Array<{
|
|
450
410
|
name: string
|
|
451
411
|
params: string
|
|
@@ -453,82 +413,119 @@ 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 re-exports
|
|
420
|
+
const exports = sortedFiles
|
|
421
|
+
.map((file) => `export * as ${file} from '../queries/${file}'`)
|
|
422
|
+
.join('\n')
|
|
423
|
+
|
|
424
|
+
return `/**
|
|
425
|
+
* auto-generated by: over-zero generate
|
|
426
|
+
*
|
|
427
|
+
* grouped query re-exports for minification-safe query identity.
|
|
428
|
+
* this file re-exports all query modules - while this breaks tree-shaking,
|
|
429
|
+
* queries are typically small and few in number even in larger apps.
|
|
430
|
+
*/
|
|
431
|
+
${exports}
|
|
432
|
+
`
|
|
433
|
+
}
|
|
458
434
|
|
|
459
|
-
|
|
435
|
+
function generateSyncedQueriesFile(
|
|
436
|
+
queries: Array<{
|
|
437
|
+
name: string
|
|
438
|
+
params: string
|
|
439
|
+
valibotCode: string
|
|
440
|
+
sourceFile: string
|
|
441
|
+
}>
|
|
442
|
+
) {
|
|
443
|
+
// group queries by source file
|
|
460
444
|
const queryByFile = new Map<string, typeof queries>()
|
|
461
|
-
for (const q of
|
|
445
|
+
for (const q of queries) {
|
|
462
446
|
if (!queryByFile.has(q.sourceFile)) {
|
|
463
447
|
queryByFile.set(q.sourceFile, [])
|
|
464
448
|
}
|
|
465
449
|
queryByFile.get(q.sourceFile)!.push(q)
|
|
466
450
|
}
|
|
467
451
|
|
|
468
|
-
//
|
|
469
|
-
const
|
|
470
|
-
.sort()
|
|
471
|
-
.map((file) => `import * as ${file}Queries from '../queries/${file}'`)
|
|
472
|
-
.join('\n')
|
|
452
|
+
// sort file names for consistent output
|
|
453
|
+
const sortedFiles = Array.from(queryByFile.keys()).sort()
|
|
473
454
|
|
|
474
|
-
const imports =
|
|
455
|
+
const imports = `// auto-generated by: over-zero generate
|
|
456
|
+
// server-side syncedQuery wrappers with validators
|
|
475
457
|
import { syncedQuery } from '@rocicorp/zero'
|
|
476
|
-
|
|
458
|
+
import * as v from 'valibot'
|
|
459
|
+
import * as Queries from './groupedQueries'
|
|
477
460
|
`
|
|
478
461
|
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
462
|
+
// generate grouped exports by namespace
|
|
463
|
+
const namespaceExports = sortedFiles
|
|
464
|
+
.map((file) => {
|
|
465
|
+
const fileQueries = queryByFile
|
|
466
|
+
.get(file)!
|
|
467
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
468
|
+
|
|
469
|
+
const queryDefs = fileQueries
|
|
470
|
+
.map((q) => {
|
|
471
|
+
// extract validator schema
|
|
472
|
+
const lines = q.valibotCode.split('\n').filter((l) => l.trim())
|
|
473
|
+
const schemaLineIndex = lines.findIndex((l) =>
|
|
474
|
+
l.startsWith('export const QueryParams')
|
|
475
|
+
)
|
|
486
476
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
477
|
+
let validatorDef = 'v.void()'
|
|
478
|
+
if (schemaLineIndex !== -1) {
|
|
479
|
+
const schemaLines: string[] = []
|
|
480
|
+
let openBraces = 0
|
|
481
|
+
let started = false
|
|
482
|
+
|
|
483
|
+
for (let i = schemaLineIndex; i < lines.length; i++) {
|
|
484
|
+
const line = lines[i]!
|
|
485
|
+
const cleaned = started
|
|
486
|
+
? line
|
|
487
|
+
: line.replace('export const QueryParams = ', '')
|
|
488
|
+
schemaLines.push(cleaned)
|
|
489
|
+
started = true
|
|
490
|
+
|
|
491
|
+
openBraces += (cleaned.match(/\{/g) || []).length
|
|
492
|
+
openBraces -= (cleaned.match(/\}/g) || []).length
|
|
493
|
+
openBraces += (cleaned.match(/\(/g) || []).length
|
|
494
|
+
openBraces -= (cleaned.match(/\)/g) || []).length
|
|
495
|
+
|
|
496
|
+
if (openBraces === 0 && schemaLines.length > 0) {
|
|
497
|
+
break
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
validatorDef = schemaLines.join('\n')
|
|
506
501
|
}
|
|
507
|
-
}
|
|
508
|
-
validatorDef = schemaLines.join('\n')
|
|
509
|
-
}
|
|
510
502
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
503
|
+
// wrap validator in v.parser(v.tuple([...]))
|
|
504
|
+
const wrappedValidator =
|
|
505
|
+
validatorDef === 'v.void()'
|
|
506
|
+
? 'v.parser(v.tuple([]))'
|
|
507
|
+
: `v.parser(v.tuple([${validatorDef}]))`
|
|
508
|
+
|
|
509
|
+
// namespaced query name: file.queryName
|
|
510
|
+
const namespacedName = `${q.sourceFile}.${q.name}`
|
|
511
|
+
|
|
512
|
+
// for void queries, no arg parameter
|
|
513
|
+
const queryFn =
|
|
514
|
+
validatorDef === 'v.void()'
|
|
515
|
+
? `() => Queries.${file}.${q.name}()`
|
|
516
|
+
: `(arg) => Queries.${file}.${q.name}(arg)`
|
|
517
|
+
|
|
518
|
+
return ` ${q.name}: syncedQuery('${namespacedName}', ${wrappedValidator}, ${queryFn}),`
|
|
519
|
+
})
|
|
520
|
+
.join('\n')
|
|
521
|
+
|
|
522
|
+
return `export const ${file} = {\n${queryDefs}\n}`
|
|
528
523
|
})
|
|
529
524
|
.join('\n\n')
|
|
530
525
|
|
|
531
|
-
return imports
|
|
526
|
+
return `${imports}
|
|
527
|
+
${namespaceExports}
|
|
528
|
+
`
|
|
532
529
|
}
|
|
533
530
|
|
|
534
531
|
function generateReadmeFile() {
|
|
@@ -541,7 +538,8 @@ this folder is auto-generated by over-zero. do not edit files here directly.
|
|
|
541
538
|
- \`models.ts\` - exports all models from ../models
|
|
542
539
|
- \`types.ts\` - typescript types derived from table schemas
|
|
543
540
|
- \`tables.ts\` - exports table schemas for type inference
|
|
544
|
-
- \`
|
|
541
|
+
- \`groupedQueries.ts\` - namespaced query re-exports for client setup
|
|
542
|
+
- \`syncedQueries.ts\` - namespaced syncedQuery wrappers for server setup
|
|
545
543
|
|
|
546
544
|
## usage guidelines
|
|
547
545
|
|
|
@@ -549,16 +547,15 @@ this folder is auto-generated by over-zero. do not edit files here directly.
|
|
|
549
547
|
|
|
550
548
|
### queries
|
|
551
549
|
|
|
552
|
-
|
|
550
|
+
write your queries as plain functions in \`../queries/\` and import them directly:
|
|
553
551
|
|
|
554
552
|
\`\`\`ts
|
|
555
|
-
// ❌ bad - don't import from generated
|
|
556
|
-
import { channelMessages } from '~/data/generated/queries'
|
|
557
|
-
|
|
558
553
|
// ✅ good - import from queries
|
|
559
554
|
import { channelMessages } from '~/data/queries/message'
|
|
560
555
|
\`\`\`
|
|
561
556
|
|
|
557
|
+
the generated query files are only used internally by zero client/server setup.
|
|
558
|
+
|
|
562
559
|
### types
|
|
563
560
|
|
|
564
561
|
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,56 @@
|
|
|
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
|
+
// grouped queries: { namespace: { queryName: queryFn } }
|
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
27
|
+
export type GroupedQueries = Record<string, Record<string, (...args: any[]) => any>>
|
|
21
28
|
|
|
22
29
|
export function createZeroClient<
|
|
23
30
|
Schema extends ZeroSchema,
|
|
24
31
|
Models extends GenericModels,
|
|
25
|
-
>({
|
|
32
|
+
>({
|
|
33
|
+
schema,
|
|
34
|
+
models,
|
|
35
|
+
groupedQueries,
|
|
36
|
+
}: {
|
|
37
|
+
schema: Schema
|
|
38
|
+
models: Models
|
|
39
|
+
groupedQueries: GroupedQueries
|
|
40
|
+
}) {
|
|
26
41
|
type ZeroMutators = GetZeroMutators<Models>
|
|
27
42
|
type ZeroInstance = Zero<Schema, ZeroMutators>
|
|
28
43
|
type TableName = keyof ZeroInstance['query']
|
|
29
44
|
|
|
30
45
|
setSchema(schema)
|
|
31
46
|
|
|
47
|
+
// build query registry from grouped queries
|
|
48
|
+
for (const [namespace, queries] of Object.entries(groupedQueries)) {
|
|
49
|
+
for (const [name, fn] of Object.entries(queries)) {
|
|
50
|
+
registerQuery(fn, `${namespace}.${name}`)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
32
54
|
const DisabledContext = createContext(false)
|
|
33
55
|
|
|
34
56
|
const modelWritePermissions = mapObject(models, (val) => val.permissions) as {
|
|
@@ -170,7 +192,7 @@ export function createZeroClient<
|
|
|
170
192
|
}
|
|
171
193
|
|
|
172
194
|
const fn = queryOrFn
|
|
173
|
-
const queryName = fn.name || 'anonymousQuery'
|
|
195
|
+
const queryName = getQueryName(fn) || fn.name || 'anonymousQuery'
|
|
174
196
|
|
|
175
197
|
// Determine if this is Pattern 2 (with params) or Pattern 3 (no params)
|
|
176
198
|
const hasParams =
|
|
@@ -200,7 +222,7 @@ export function createZeroClient<
|
|
|
200
222
|
const out = zeroUseQuery(actualQuery, options)
|
|
201
223
|
|
|
202
224
|
if (process.env.NODE_ENV === 'development') {
|
|
203
|
-
//
|
|
225
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
204
226
|
useZeroDebug(actualQuery, options, out)
|
|
205
227
|
}
|
|
206
228
|
|
|
@@ -218,10 +240,10 @@ export function createZeroClient<
|
|
|
218
240
|
...props
|
|
219
241
|
}: Omit<ZeroOptions<Schema, ZeroMutators>, 'schema' | 'mutators'> & {
|
|
220
242
|
children: ReactNode
|
|
221
|
-
authData?: AuthData
|
|
243
|
+
authData?: AuthData | null
|
|
222
244
|
disable?: boolean
|
|
223
245
|
}) => {
|
|
224
|
-
const authData = authDataIn as AuthData
|
|
246
|
+
const authData = (authDataIn ?? null) as AuthData
|
|
225
247
|
|
|
226
248
|
const mutators = useMemo(() => {
|
|
227
249
|
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,32 @@ 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
|
+
// grouped synced queries: { namespace: { queryName: SyncedQuery } }
|
|
28
|
+
export type SyncedQueries = 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,
|
|
30
|
-
string,
|
|
31
|
-
never
|
|
32
|
-
>,
|
|
37
|
+
Queries extends SyncedQueries = Record<string, never>,
|
|
33
38
|
>({
|
|
34
39
|
createServerActions,
|
|
35
40
|
database,
|
|
36
41
|
schema,
|
|
37
42
|
models,
|
|
38
|
-
|
|
43
|
+
syncedQueries,
|
|
39
44
|
}: {
|
|
40
45
|
/**
|
|
41
46
|
* The DB connection string, same as ZERO_UPSTREAM_DB
|
|
@@ -44,7 +49,7 @@ export function createZeroServer<
|
|
|
44
49
|
schema: Schema
|
|
45
50
|
models: Models
|
|
46
51
|
createServerActions: () => ServerActions
|
|
47
|
-
|
|
52
|
+
syncedQueries?: Queries
|
|
48
53
|
}) {
|
|
49
54
|
setSchema(schema)
|
|
50
55
|
|
|
@@ -107,6 +112,16 @@ export function createZeroServer<
|
|
|
107
112
|
}
|
|
108
113
|
}
|
|
109
114
|
|
|
115
|
+
// build flat lookup map from grouped syncedQueries: "namespace.queryName" => SyncedQuery
|
|
116
|
+
const queryLookup = new Map<string, SyncedQuery<any, any, any, any, any>>()
|
|
117
|
+
if (syncedQueries) {
|
|
118
|
+
for (const [namespace, queries] of Object.entries(syncedQueries)) {
|
|
119
|
+
for (const [queryName, syncedQuery] of Object.entries(queries)) {
|
|
120
|
+
queryLookup.set(`${namespace}.${queryName}`, syncedQuery)
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
110
125
|
const handleQueryRequest = async ({
|
|
111
126
|
authData,
|
|
112
127
|
request,
|
|
@@ -115,7 +130,7 @@ export function createZeroServer<
|
|
|
115
130
|
request: Request
|
|
116
131
|
}) => {
|
|
117
132
|
function getQuery(name: string, args: readonly ReadonlyJSONValue[]) {
|
|
118
|
-
const q =
|
|
133
|
+
const q = queryLookup.get(name)
|
|
119
134
|
if (!q) {
|
|
120
135
|
throw new Error(`No such query: ${name}`)
|
|
121
136
|
}
|
|
@@ -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
|