graphile / graphile/crystal

Automatic step coercion

Open
#1,971 0 comments 0 reactions 0 assignees View on GitHub
✨ feature
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.