Skip to content

pbkit-tanstack: generated output doesn't compile + query factories lack client/expand #47

Description

@Karnak19

Generating with tanstackPlugin against a real schema (~60 collections) produces a tanstack.gen.ts that fails tsc, plus a few design gaps that block real adoption once it compiles.

Compile blockers — root cause: type declarations split across files

types.gen.ts should be the single home for all generated types; sdk.gen.ts / tanstack.gen.ts should import types from it and contain only runtime code. Today they're scattered:

tanstack.gen.ts(4,15): error TS2305: Module './types.gen' has no exported member 'ListParams'.
tanstack.gen.ts(4,27): error TS2305: Module './types.gen' has no exported member 'RequestOptions'.
tanstack.gen.ts(54,24): error TS2304: Cannot find name 'MfasCreate'.
tanstack.gen.ts(60,52): error TS2304: Cannot find name 'MfasUpdate'.
… (×~120, every XxxCreate/XxxUpdate)
tanstack.gen.ts(3,47): error TS2307: Cannot find module '@tanstack/query-core'.
  • ListParams / RequestOptions are declared in sdk.gen.ts, but tanstack.gen.ts does import { ListParams, RequestOptions } from "./types.gen"TS2305. (The import path shows the intended home is types.gen — the declarations are just in the wrong file.)
  • The PbClient type is declared in client.gen.ts.
  • tanstack.gen.ts references XxxCreate / XxxUpdate (~120×, e.g. mutationFn: (data: MfasCreate) => …) but never imports themTS2304.
  • It imports { queryOptions, mutationOptions } from "@tanstack/query-core", but consumers usually have @tanstack/react-query (which re-exports both) → TS2307.

Fix: move ListParams, RequestOptions, and the PbClient type into types.gen.ts (the runtime client singleton stays in client.gen.ts); have sdk.gen.ts and tanstack.gen.ts import all types from types.gen.ts and runtime fns from sdk.gen.ts. This resolves TS2305 + TS2304 at the root. For TS2307, import from @tanstack/react-query or document @tanstack/query-core as a required peer install.

Repro: add tanstackPlugin to pbkit.config.tspbkit generatetsc --noEmit on the output.

Design gaps (block real adoption even after it compiles)

4. Query factories accept no client override. xOptions(id, options?: RequestOptions)queryFn: () => getX(id, options) always uses the default client.gen.ts singleton (new PocketBase("")). Apps with a cookie-authed browser client (or a per-request SSR client) can't inject it. Mutation factories already take opts?: { client } — queries should be symmetric.

5. Expand generic not preserved. options?: RequestOptions is non-generic, so the <const S> expand inference from the raw SDK fns is lost — useQuery(listingOptions(id, { expand: 'user' })).data.expand.user is untyped.

Both #4 and #5 are fixed by making the factory generic + client-aware:

export function listingOptions<const S extends string | undefined = undefined>(
  id: string,
  options?: Omit<RequestOptions, 'expand'> & { expand?: S },
  opts?: { client?: PbClient },
) {
  return queryOptions({
    queryKey: ['listings', id, options?.expand], // see #6
    queryFn: () => getListing(id, options, opts),
  });
}

6. Single-record query key ignores options → cache collisions. listingOptions(id) keys as ['listings', id], so getListing(id, { expand: 'user' }) and getListing(id) share a cache entry — one variant's payload is served for the other. Include options (expand/fields) in the key, the way the list factory already includes params.

Acceptance

  • Generated tanstack.gen.ts passes tsc --noEmit against a multi-collection schema.
  • useQuery(listingOptions(id, { expand: 'user' }, { client: pb })) uses pb and types .data.expand.user.
  • Distinct expand/fields produce distinct query keys.

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingenhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions