on-zero 0.1.45 → 0.1.47
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/constants.cjs +2 -1
- package/dist/cjs/constants.js +2 -1
- package/dist/cjs/constants.js.map +1 -1
- package/dist/cjs/constants.native.js +1 -1
- package/dist/cjs/generate.cjs +26 -11
- package/dist/cjs/generate.js +32 -10
- package/dist/cjs/generate.js.map +1 -1
- package/dist/cjs/generate.native.js +36 -19
- package/dist/cjs/generate.native.js.map +1 -1
- package/dist/cjs/generate.test.cjs +24 -1
- package/dist/cjs/generate.test.js +27 -1
- package/dist/cjs/generate.test.js.map +1 -1
- package/dist/cjs/generate.test.native.js +24 -1
- package/dist/cjs/generate.test.native.js.map +1 -1
- package/dist/cjs/mutations.cjs +3 -2
- package/dist/cjs/mutations.js +2 -2
- package/dist/cjs/mutations.js.map +1 -1
- package/dist/cjs/mutations.native.js +3 -2
- package/dist/cjs/mutations.native.js.map +1 -1
- package/dist/esm/constants.js +2 -1
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/constants.mjs +2 -1
- package/dist/esm/constants.mjs.map +1 -1
- package/dist/esm/constants.native.js +1 -1
- package/dist/esm/generate.js +32 -10
- package/dist/esm/generate.js.map +1 -1
- package/dist/esm/generate.mjs +26 -11
- package/dist/esm/generate.mjs.map +1 -1
- package/dist/esm/generate.native.js +36 -19
- package/dist/esm/generate.native.js.map +1 -1
- package/dist/esm/generate.test.js +27 -1
- package/dist/esm/generate.test.js.map +1 -1
- package/dist/esm/generate.test.mjs +24 -1
- package/dist/esm/generate.test.mjs.map +1 -1
- package/dist/esm/generate.test.native.js +24 -1
- package/dist/esm/generate.test.native.js.map +1 -1
- package/dist/esm/mutations.js +2 -1
- package/dist/esm/mutations.js.map +1 -1
- package/dist/esm/mutations.mjs +2 -1
- package/dist/esm/mutations.mjs.map +1 -1
- package/dist/esm/mutations.native.js +2 -1
- package/dist/esm/mutations.native.js.map +1 -1
- package/package.json +2 -2
- package/src/constants.native.ts +1 -1
- package/src/constants.ts +8 -1
- package/src/generate.test.ts +37 -1
- package/src/generate.ts +39 -10
- package/src/mutations.ts +2 -1
- package/types/constants.d.ts.map +1 -1
- package/types/constants.native.d.ts +1 -1
- package/types/constants.native.d.ts.map +1 -1
- package/types/generate.d.ts.map +1 -1
- package/types/mutations.d.ts.map +1 -1
- package/types/state.d.ts +1 -1
package/src/generate.test.ts
CHANGED
|
@@ -270,7 +270,7 @@ export const mutate = mutations(schema, perm)
|
|
|
270
270
|
expect(content).toContain('delete:')
|
|
271
271
|
})
|
|
272
272
|
|
|
273
|
-
test('
|
|
273
|
+
test('treats models without export const mutate as empty mutations', async () => {
|
|
274
274
|
writeFileSync(
|
|
275
275
|
join(testDir, 'models/readonly.ts'),
|
|
276
276
|
`
|
|
@@ -285,6 +285,9 @@ export const schema = table('readonly').columns({
|
|
|
285
285
|
|
|
286
286
|
const result = await generate({ dir: testDir, silent: true })
|
|
287
287
|
expect(result.mutationCount).toBe(0)
|
|
288
|
+
|
|
289
|
+
const content = readFileSync(join(testDir, 'generated/syncedMutations.ts'), 'utf-8')
|
|
290
|
+
expect(content).toContain('readonly: {')
|
|
288
291
|
})
|
|
289
292
|
|
|
290
293
|
test('extracts custom mutations from bare mutations({})', async () => {
|
|
@@ -505,6 +508,39 @@ export const mutate = mutations(schema, perm, {
|
|
|
505
508
|
expect(content).not.toMatch(/rename:[\s\S]*count/)
|
|
506
509
|
})
|
|
507
510
|
|
|
511
|
+
test('skips symbol-keyed properties when resolving imported mutation param types', async () => {
|
|
512
|
+
writeFileSync(
|
|
513
|
+
join(testDir, 'models/types.ts'),
|
|
514
|
+
`
|
|
515
|
+
export type WeirdParams = {
|
|
516
|
+
id: string
|
|
517
|
+
[Symbol.iterator]?: () => Iterator<string>
|
|
518
|
+
}
|
|
519
|
+
`
|
|
520
|
+
)
|
|
521
|
+
|
|
522
|
+
writeFileSync(
|
|
523
|
+
join(testDir, 'models/item.ts'),
|
|
524
|
+
`
|
|
525
|
+
import { mutations } from 'on-zero'
|
|
526
|
+
import type { WeirdParams } from './types'
|
|
527
|
+
|
|
528
|
+
export const mutate = mutations({
|
|
529
|
+
run: async ({ tx }, params: WeirdParams) => {
|
|
530
|
+
await tx.mutate.item.delete({ id: params.id })
|
|
531
|
+
},
|
|
532
|
+
})
|
|
533
|
+
`
|
|
534
|
+
)
|
|
535
|
+
|
|
536
|
+
await generate({ dir: testDir, silent: true })
|
|
537
|
+
|
|
538
|
+
const content = readFileSync(join(testDir, 'generated/syncedMutations.ts'), 'utf-8')
|
|
539
|
+
expect(content).toContain('run')
|
|
540
|
+
expect(content).toContain('id: v.string()')
|
|
541
|
+
expect(content).not.toContain('__@iterator')
|
|
542
|
+
})
|
|
543
|
+
|
|
508
544
|
test('resolves imported types in query params', async () => {
|
|
509
545
|
writeFileSync(
|
|
510
546
|
join(testDir, 'models/post.ts'),
|
package/src/generate.ts
CHANGED
|
@@ -430,7 +430,7 @@ function extractMutationsFromModel(
|
|
|
430
430
|
ts: typeof import('typescript'),
|
|
431
431
|
sourceFile: ReturnType<typeof ts.createSourceFile>,
|
|
432
432
|
content: string,
|
|
433
|
-
|
|
433
|
+
fileName: string,
|
|
434
434
|
silent: boolean,
|
|
435
435
|
typeToValibot: (typeString: string) => string | null,
|
|
436
436
|
resolvedTypes?: Map<string, import('typescript').Type>,
|
|
@@ -450,7 +450,15 @@ function extractMutationsFromModel(
|
|
|
450
450
|
}
|
|
451
451
|
})
|
|
452
452
|
|
|
453
|
-
if (!mutateNode)
|
|
453
|
+
if (!mutateNode) {
|
|
454
|
+
return {
|
|
455
|
+
modelName: basename(fileName, '.ts'),
|
|
456
|
+
hasCRUD: false,
|
|
457
|
+
columns: {},
|
|
458
|
+
primaryKeys: [],
|
|
459
|
+
custom: [],
|
|
460
|
+
}
|
|
461
|
+
}
|
|
454
462
|
|
|
455
463
|
const call = mutateNode as import('typescript').CallExpression
|
|
456
464
|
const args = call.arguments
|
|
@@ -621,6 +629,16 @@ function columnTypeToValibot(col: SchemaColumn): string {
|
|
|
621
629
|
return col.optional ? `v.optional(v.nullable(${base}))` : base
|
|
622
630
|
}
|
|
623
631
|
|
|
632
|
+
function shouldSkipObjectKey(name: string): boolean {
|
|
633
|
+
// TypeScript exposes symbol keys as synthetic names like "__@iterator@851".
|
|
634
|
+
// These cannot come from JSON mutation payloads and break codegen if emitted.
|
|
635
|
+
return name.startsWith('__@')
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function formatObjectKey(name: string): string {
|
|
639
|
+
return /^[$A-Z_a-z][$\w]*$/.test(name) ? name : JSON.stringify(name)
|
|
640
|
+
}
|
|
641
|
+
|
|
624
642
|
function schemaColumnsToValibot(
|
|
625
643
|
columns: Record<string, SchemaColumn>,
|
|
626
644
|
primaryKeys: string[],
|
|
@@ -632,22 +650,29 @@ function schemaColumnsToValibot(
|
|
|
632
650
|
// only PKs
|
|
633
651
|
for (const pk of primaryKeys) {
|
|
634
652
|
const col = columns[pk]
|
|
635
|
-
if (col)
|
|
653
|
+
if (col)
|
|
654
|
+
entries.push(
|
|
655
|
+
`${formatObjectKey(pk)}: ${columnTypeToValibot({ ...col, optional: false })}`
|
|
656
|
+
)
|
|
636
657
|
}
|
|
637
658
|
} else if (mode === 'update') {
|
|
638
659
|
// PKs required, rest optional
|
|
639
660
|
for (const [name, col] of Object.entries(columns)) {
|
|
640
661
|
const isPK = primaryKeys.includes(name)
|
|
641
662
|
if (isPK) {
|
|
642
|
-
entries.push(
|
|
663
|
+
entries.push(
|
|
664
|
+
`${formatObjectKey(name)}: ${columnTypeToValibot({ ...col, optional: false })}`
|
|
665
|
+
)
|
|
643
666
|
} else {
|
|
644
|
-
entries.push(
|
|
667
|
+
entries.push(
|
|
668
|
+
`${formatObjectKey(name)}: ${columnTypeToValibot({ ...col, optional: true })}`
|
|
669
|
+
)
|
|
645
670
|
}
|
|
646
671
|
}
|
|
647
672
|
} else {
|
|
648
673
|
// insert: all columns as-is
|
|
649
674
|
for (const [name, col] of Object.entries(columns)) {
|
|
650
|
-
entries.push(`${name}: ${columnTypeToValibot(col)}`)
|
|
675
|
+
entries.push(`${formatObjectKey(name)}: ${columnTypeToValibot(col)}`)
|
|
651
676
|
}
|
|
652
677
|
}
|
|
653
678
|
|
|
@@ -750,7 +775,7 @@ function parseTypeString(type: string): string | null {
|
|
|
750
775
|
if (!parsed) return null // can't resolve inner type
|
|
751
776
|
let val = parsed
|
|
752
777
|
if (opt) val = `v.optional(${val})`
|
|
753
|
-
entries.push(`${name}: ${val}`)
|
|
778
|
+
entries.push(`${formatObjectKey(name)}: ${val}`)
|
|
754
779
|
}
|
|
755
780
|
if (entries.length === 0) return 'v.object({})'
|
|
756
781
|
return `v.object({\n ${entries.join(',\n ')},\n })`
|
|
@@ -853,14 +878,17 @@ function tsTypeToValibot(
|
|
|
853
878
|
if (props.length === 0) return 'v.object({})'
|
|
854
879
|
const entries: string[] = []
|
|
855
880
|
for (const prop of props) {
|
|
881
|
+
const name = prop.getName()
|
|
882
|
+
if (shouldSkipObjectKey(name)) continue
|
|
856
883
|
const propType = resolveSymbolType(prop)
|
|
857
884
|
const isOptional = !!(prop.getFlags() & ts.SymbolFlags.Optional)
|
|
858
885
|
let val = recurse(propType)
|
|
859
886
|
if (isOptional && !val.startsWith('v.optional(')) {
|
|
860
887
|
val = `v.optional(${val})`
|
|
861
888
|
}
|
|
862
|
-
entries.push(`${
|
|
889
|
+
entries.push(`${formatObjectKey(name)}: ${val}`)
|
|
863
890
|
}
|
|
891
|
+
if (entries.length === 0) return 'v.object({})'
|
|
864
892
|
return `v.object({\n ${entries.join(',\n ')},\n })`
|
|
865
893
|
}
|
|
866
894
|
|
|
@@ -895,13 +923,15 @@ function tsTypeToValibot(
|
|
|
895
923
|
// regular object
|
|
896
924
|
const entries: string[] = []
|
|
897
925
|
for (const prop of props) {
|
|
926
|
+
const name = prop.getName()
|
|
927
|
+
if (shouldSkipObjectKey(name)) continue
|
|
898
928
|
const propType = resolveSymbolType(prop)
|
|
899
929
|
const isOptional = !!(prop.getFlags() & ts.SymbolFlags.Optional)
|
|
900
930
|
let val = recurse(propType)
|
|
901
931
|
if (isOptional && !val.startsWith('v.optional(')) {
|
|
902
932
|
val = `v.optional(${val})`
|
|
903
933
|
}
|
|
904
|
-
entries.push(`${
|
|
934
|
+
entries.push(`${formatObjectKey(name)}: ${val}`)
|
|
905
935
|
}
|
|
906
936
|
if (entries.length === 0) return 'v.object({})'
|
|
907
937
|
return `v.object({\n ${entries.join(',\n ')},\n })`
|
|
@@ -1124,7 +1154,6 @@ export async function generate(options: GenerateOptions): Promise<GenerateResult
|
|
|
1124
1154
|
|
|
1125
1155
|
try {
|
|
1126
1156
|
const content = readFileSync(filePath, 'utf-8')
|
|
1127
|
-
if (!content.includes('export const mutate')) continue
|
|
1128
1157
|
|
|
1129
1158
|
mutationFiles.push({ path: filePath, content, baseName: fileBaseName })
|
|
1130
1159
|
|
package/src/mutations.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isServer } from './constants'
|
|
1
2
|
import { getDidRunPermissionCheck } from './helpers/didRunPermissionCheck'
|
|
2
3
|
import { setMutationsPermissions } from './modelRegistry'
|
|
3
4
|
|
|
@@ -143,7 +144,7 @@ export function mutations<
|
|
|
143
144
|
}
|
|
144
145
|
|
|
145
146
|
// only validate on the server
|
|
146
|
-
if (
|
|
147
|
+
if (isServer) {
|
|
147
148
|
await ctx.can(permissions, obj)
|
|
148
149
|
}
|
|
149
150
|
}
|
package/types/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,QAAQ,SAE6C,CAAA;AAElE,eAAO,MAAM,SAAS,SAAY,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.native.d.ts","sourceRoot":"","sources":["../src/constants.native.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,QAAQ,CAAA;AAC7B,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"constants.native.d.ts","sourceRoot":"","sources":["../src/constants.native.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ,QAAQ,CAAA;AAC7B,eAAO,MAAM,SAAS,OAAO,CAAA"}
|
package/types/generate.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAw7BA,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,sBAAsB;IACtB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAmUhF;AAED,wBAAsB,KAAK,CAAC,OAAO,EAAE,YAAY,yCAkChD"}
|
package/types/mutations.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../src/mutations.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mutations.d.ts","sourceRoot":"","sources":["../src/mutations.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,cAAc,EACd,cAAc,EAEd,cAAc,EACd,KAAK,EACN,MAAM,SAAS,CAAA;AAChB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AA2D7D,KAAK,eAAe,CAAC,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AACnF,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;AAevD,KAAK,YAAY,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAA;AAEhD,KAAK,aAAa,CAAC,KAAK,SAAS,YAAY,IAAI;IAC/C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAC9C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAC9C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;IAC9C,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAA;CAC/C,CAAA;AAED,KAAK,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE1D,KAAK,iBAAiB,CAAC,KAAK,SAAS,YAAY,EAAE,SAAS,SAAS,gBAAgB,IAAI;KACtF,GAAG,IAAI,SAAS,GAAG,MAAM,SAAS,GAAG,GAAG,SAAS,MAAM,SAAS,GAC7D,SAAS,CAAC,GAAG,CAAC,GACd,GAAG,SAAS,MAAM,aAAa,CAAC,GAAG,CAAC,GAClC,aAAa,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GACzB,KAAK;CACZ,CAAA;AAED,wBAAgB,SAAS,CAAC,SAAS,SAAS,gBAAgB,EAC1D,SAAS,EAAE,SAAS,GACnB,SAAS,CAAA;AACZ,wBAAgB,SAAS,CAAC,KAAK,SAAS,YAAY,EAAE,WAAW,SAAS,KAAK,EAC7E,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,GACvB,iBAAiB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;AAC/B,wBAAgB,SAAS,CACvB,KAAK,SAAS,YAAY,EAC1B,WAAW,SAAS,KAAK,EACzB,SAAS,SAAS,gBAAgB,EAElC,KAAK,EAAE,KAAK,EACZ,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,SAAS,GACnB,iBAAiB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA"}
|
package/types/state.d.ts
CHANGED
|
@@ -5,6 +5,6 @@ export declare const getSchema: () => Schema;
|
|
|
5
5
|
export declare const setSchema: (_: Schema) => void;
|
|
6
6
|
export declare const getAuthData: () => {} | null;
|
|
7
7
|
export declare const setAuthData: (_: AuthData) => void;
|
|
8
|
-
export declare const getEnvironment: () => "
|
|
8
|
+
export declare const getEnvironment: () => "client" | "server" | null;
|
|
9
9
|
export declare const setEnvironment: (env: "client" | "server") => void;
|
|
10
10
|
//# sourceMappingURL=state.d.ts.map
|