Skip to content

Commit b7fc0ff

Browse files
Allow custom input schema types
1 parent e94cadf commit b7fc0ff

File tree

3 files changed

+38
-11
lines changed

3 files changed

+38
-11
lines changed

docs/collections/powersync-collection.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ const documentsCollection = createCollection(
101101

102102
#### Option 2: Using Advanced Schema Validation
103103

104-
Additional validations can be performed by supplying a compatible validation schema (such as a Zod schema). The typing of the validator is constrained to match the typing of the SQLite table.
104+
Additional validations can be performed by supplying a compatible validation schema (such as a Zod schema). The output typing of the validator is constrained to match the typing of the SQLite table. The input typing can be arbitrary.
105105

106106
```ts
107107
import { createCollection } from "@tanstack/react-db"
@@ -111,10 +111,7 @@ import { z } from "zod"
111111
// The output of this schema must match the SQLite schema
112112
const schema = z.object({
113113
id: z.string(),
114-
name: z
115-
.string()
116-
.min(3, { message: "Should be at least 3 characters" })
117-
.nullable(),
114+
name: z.string().min(3, { message: "Should be at least 3 characters" }),
118115
})
119116

120117
const documentsCollection = createCollection(

packages/powersync-db-collection/src/powersync.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@ import { PowerSyncTransactor } from "./PowerSyncTransactor"
66
import { convertTableToSchema } from "./schema"
77
import type { Table, TriggerDiffRecord } from "@powersync/common"
88
import type { StandardSchemaV1 } from "@standard-schema/spec"
9-
import type { CollectionConfig, SyncConfig } from "@tanstack/db"
9+
import type {
10+
CollectionConfig,
11+
InferSchemaOutput,
12+
SyncConfig,
13+
} from "@tanstack/db"
1014
import type {
1115
EnhancedPowerSyncCollectionConfig,
1216
PowerSyncCollectionConfig,
@@ -91,13 +95,10 @@ export function powerSyncCollectionOptions<TTable extends Table = Table>(
9195
*/
9296
export function powerSyncCollectionOptions<
9397
TTable extends Table,
94-
TSchema extends StandardSchemaV1<
95-
ExtractedTable<TTable>,
96-
ExtractedTable<TTable>
97-
>,
98+
TSchema extends StandardSchemaV1<any, ExtractedTable<TTable>>,
9899
>(
99100
config: PowerSyncCollectionConfig<TTable, TSchema>
100-
): CollectionConfig<ExtractedTable<TTable>, string, TSchema> & {
101+
): CollectionConfig<InferSchemaOutput<TSchema>, string, TSchema> & {
101102
utils: PowerSyncCollectionUtils
102103
schema: TSchema
103104
}

packages/powersync-db-collection/tests/powersync.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,35 @@ describe(`PowerSync Integration`, () => {
156156
}
157157
}
158158
})
159+
160+
it(`should allow custom input types`, async () => {
161+
const db = await createDatabase()
162+
163+
// The input can be arbitrarily typed, as long as it converts to SQLite
164+
const schema = z.object({
165+
id: z.string(),
166+
name: z.number().transform((val) => `Number: ${val}`),
167+
})
168+
169+
const collection = createCollection(
170+
powerSyncCollectionOptions({
171+
database: db,
172+
table: APP_SCHEMA.props.documents,
173+
schema,
174+
})
175+
)
176+
onTestFinished(() => collection.cleanup())
177+
178+
const id = randomUUID()
179+
collection.insert({
180+
id,
181+
name: 42,
182+
})
183+
184+
const item = collection.get(id)
185+
186+
expect(item?.name).eq(`Number: 42`)
187+
})
159188
})
160189

161190
describe(`sync`, () => {

0 commit comments

Comments
 (0)