Skip to content

Commit 80f2c89

Browse files
authored
Allow customizing the type of scalars in queries generator (#1313)
Add the ability for users of the queries generator to override the TypeScript types of custom scalar variables via `OverrideCodecType`. The default scalar types are non-overrideable.
1 parent 6623d7a commit 80f2c89

File tree

6 files changed

+49
-3
lines changed

6 files changed

+49
-3
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
2+
export interface OverrideCodecType {}
3+
4+
export type ResolvedCodecType<TDbTypeName, TDefaultTsType> =
5+
TDbTypeName extends keyof OverrideCodecType
6+
? OverrideCodecType[TDbTypeName]
7+
: TDefaultTsType;

packages/gel/src/index.shared.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,14 @@ export * from "./errors";
5353

5454
export type { Codecs } from "./codecs/codecs";
5555

56+
export type { OverrideCodecType, ResolvedCodecType } from "./codecTypeRegistry";
57+
5658
/* Private APIs */
5759
import type * as codecs from "./codecs/ifaces";
60+
import { ScalarCodec } from "./codecs/ifaces";
5861
import * as reg from "./codecs/registry";
5962
import * as buf from "./primitives/buffer";
6063
export const _CodecsRegistry = reg.CodecsRegistry;
6164
export const _ReadBuffer = buf.ReadBuffer;
6265
export type _ICodec = codecs.ICodec;
66+
export const _ScalarCodec = ScalarCodec;

packages/gel/src/reflection/analyzeQuery.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,14 @@ type QueryType = {
2323
imports: Set<string>;
2424
};
2525

26+
export type AnalyzeQueryOptions = {
27+
useResolvedCodecType?: boolean;
28+
};
29+
2630
export async function analyzeQuery(
2731
client: Client,
2832
query: string,
33+
{ useResolvedCodecType = false }: AnalyzeQueryOptions = {},
2934
): Promise<QueryType> {
3035
const {
3136
cardinality,
@@ -34,11 +39,18 @@ export async function analyzeQuery(
3439
out: outCodec,
3540
} = await client.describe(query);
3641

42+
const generators: CodecGeneratorMap = useResolvedCodecType
43+
? new Map([...defaultCodecGenerators, resolvedCodecTypeScalarTypeGenerator])
44+
: defaultCodecGenerators;
45+
3746
const args = generateTSTypeFromCodec(inCodec, Cardinality.One, {
3847
optionalNulls: true,
3948
readonly: true,
49+
generators,
50+
});
51+
const result = generateTSTypeFromCodec(outCodec, cardinality, {
52+
generators,
4053
});
41-
const result = generateTSTypeFromCodec(outCodec, cardinality);
4254

4355
const imports = args.imports.merge(result.imports);
4456
return {
@@ -160,6 +172,21 @@ const getSortPriority = (field: FieldDef) => {
160172
return 8;
161173
};
162174

175+
const resolvedCodecTypeScalarTypeGenerator = genDef(
176+
ScalarCodec,
177+
(codec, ctx) => {
178+
if (codec.tsModule) {
179+
ctx.imports.add(codec.tsModule, codec.tsType);
180+
}
181+
const isCustomScalar = !codec.typeName.startsWith("std::");
182+
if (isCustomScalar) {
183+
ctx.imports.add("gel", "ResolvedCodecType");
184+
return `ResolvedCodecType<"${codec.typeName}", ${codec.tsType}>`;
185+
}
186+
return codec.tsType;
187+
},
188+
);
189+
163190
export const defaultCodecGenerators: CodecGeneratorMap = new Map([
164191
genDef(NullCodec, () => "null"),
165192
genDef(EnumCodec, (codec) => {

packages/generate/src/cli.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,9 @@ const run = async () => {
206206
case "--use-http-client":
207207
options.useHttpClient = true;
208208
break;
209+
case "--use-resolved-codec-type":
210+
options.useResolvedCodecType = true;
211+
break;
209212
case "--target": {
210213
if (
211214
generator === Generator.Interfaces ||

packages/generate/src/commandutil.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export interface CommandOptions {
1616
forceOverwrite?: boolean;
1717
updateIgnoreFile?: boolean;
1818
useHttpClient?: boolean;
19+
useResolvedCodecType?: boolean;
1920
future?: Partial<Record<keyof typeof defaultFutureFlags, boolean>>;
2021
patterns?: string[];
2122
}

packages/generate/src/queries.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ currently supported.`);
6666

6767
try {
6868
const query = await readFileUtf8(p);
69-
const types = await $.analyzeQuery(client, query);
69+
const types = await $.analyzeQuery(client, query, {
70+
useResolvedCodecType: params.options.useResolvedCodecType,
71+
});
7072
console.log(` ${prettyPath}`);
7173
const files = generateFiles({
7274
target: params.options.target!,
@@ -120,7 +122,9 @@ currently supported.`);
120122
try {
121123
const query = await readFileUtf8(p);
122124
if (!query) return;
123-
const types = await $.analyzeQuery(client, query);
125+
const types = await $.analyzeQuery(client, query, {
126+
useResolvedCodecType: params.options.useResolvedCodecType,
127+
});
124128
const files = generateFiles({
125129
target: params.options.target!,
126130
path: p,

0 commit comments

Comments
 (0)