Automatic step coercion
- Dominant language
- TypeScript
- Stars
- 12.9k
- Forks
- 625
- Avg merge
- 5h 23m
- Merged PRs (30d)
- 24
Description
### Feature description
When a step is used for a type which doesn't support that step class, the type could offer a function to attempt to coerce the step to a compatible type.
### Motivating example
https://discord.com/channels/489127045289476126/498852330754801666/1209806376595882014
Discord user `@box` received `Query planning error: $record.record is not a function` because they attempted to use the result of `object({sessionToken: withPgClientTransaction(...)).get('sessionToken')` for a built in type `SessionToken` which expects to represent a Postgres type, and thus should use the `PgSelectSingleStep` or `PgClassExpressionStep` step classes.
However, we _should_ be able to take an arbirary object and _assume_ it's the right type, and convert it to a `PgSelectSingleStep` by piping it through `json_populate_record` or similar. For example:
```ts
function pgSelectSingleFromObject(resource: PgResource, $obj: ExecutableStep): PgSelectSingle {
const $records = pgSelect({
identifiers: [],
resource,
from: (r) =>
sql`json_populate_record(null::${resource.codec.sqlType}, ${r.placeholder})`,
args: [{ step: $obj, pgCodec: TYPES.json }],
});
return $records.single();
}
// ...
const sessionTokenCodec = build.input.pgRegistry.pgCodecs.session_token;
const resource = build.pgTableResource(sessionTokenCodec, false);
SessionTokenType.extensions.grafast.coerceStep = ($step) => {
if ($step instanceof PgSelectSingleStep || $step instanceof PgClassExpressionStep) {
// No co-ercion needed; we already support these types
return $step;
} else {
// Attempt to convert
return pgSelectSingleFromObject(resource, $step);
}
}
```
Contributor guide
Assessment
This issue has not been assessed yet.