protoc-gen-pothos 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -0
- package/lib/dslgen/printers/enumType.js +29 -64
- package/lib/dslgen/printers/field.js +46 -95
- package/lib/dslgen/printers/fieldResolver/enumFieldResolver.js +39 -46
- package/lib/dslgen/printers/fieldResolver/nonNullResolver.js +7 -8
- package/lib/dslgen/printers/fieldResolver/oneofUnionResolver.js +21 -41
- package/lib/dslgen/printers/index.js +9 -44
- package/lib/dslgen/printers/inputObjectType.js +39 -82
- package/lib/dslgen/printers/objectType.js +36 -89
- package/lib/dslgen/printers/oneofUnionType.js +13 -62
- package/lib/dslgen/printers/util.js +59 -86
- package/lib/printer.js +10 -40
- package/lib/process.js +1 -1
- package/module/dslgen/printers/enumType.js +28 -60
- package/module/dslgen/printers/field.js +48 -94
- package/module/dslgen/printers/fieldResolver/enumFieldResolver.js +37 -41
- package/module/dslgen/printers/fieldResolver/nonNullResolver.js +5 -3
- package/module/dslgen/printers/fieldResolver/oneofUnionResolver.js +19 -36
- package/module/dslgen/printers/index.js +11 -41
- package/module/dslgen/printers/inputObjectType.js +40 -80
- package/module/dslgen/printers/objectType.js +37 -87
- package/module/dslgen/printers/oneofUnionType.js +13 -59
- package/module/dslgen/printers/util.js +36 -78
- package/module/printer.js +12 -39
- package/module/process.js +1 -1
- package/package.json +6 -5
|
@@ -1,68 +1,36 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { compact, protobufGraphQLExtensions } from "@proto-graphql/codegen-core";
|
|
2
|
+
import { code, joinCode, literalOf } from "ts-poet";
|
|
3
|
+
import { pothosBuilder, pothosRef } from "./util";
|
|
3
4
|
/**
|
|
4
5
|
* @example
|
|
5
6
|
* ```ts
|
|
6
|
-
* export cosnt Hello = builder.enumType("Hello", {
|
|
7
|
+
* export cosnt Hello$Ref = builder.enumType("Hello", {
|
|
8
|
+
* values: [
|
|
9
|
+
* // ...
|
|
10
|
+
* ],
|
|
7
11
|
* // ...
|
|
8
12
|
* })
|
|
9
13
|
* ```
|
|
10
14
|
*/
|
|
11
|
-
export function
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* @example
|
|
35
|
-
* ```ts
|
|
36
|
-
* {{
|
|
37
|
-
* protobufEnum: {
|
|
38
|
-
* name: "...",
|
|
39
|
-
* fullName: "...",
|
|
40
|
-
* package: "...",
|
|
41
|
-
* },
|
|
42
|
-
* } as ProtobufEnumExtensions)
|
|
43
|
-
* ```
|
|
44
|
-
*/
|
|
45
|
-
function createExtensionsObjectLiteralExpr(type) {
|
|
46
|
-
return ts.factory.createObjectLiteralExpression([
|
|
47
|
-
ts.factory.createPropertyAssignment("protobufEnum", ts.factory.createObjectLiteralExpression([
|
|
48
|
-
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(type.proto.name)),
|
|
49
|
-
ts.factory.createPropertyAssignment("fullName", ts.factory.createStringLiteral(type.proto.fullName.toString())),
|
|
50
|
-
ts.factory.createPropertyAssignment("package", ts.factory.createStringLiteral(type.proto.file.package)),
|
|
51
|
-
], true)),
|
|
52
|
-
], true);
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* @example
|
|
56
|
-
* ```ts
|
|
57
|
-
* ({
|
|
58
|
-
* protobufEnumValue: {
|
|
59
|
-
* name: "...",
|
|
60
|
-
* },
|
|
61
|
-
* } as ProtobufEnumValueExtensions)
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
function createExtensionsObjectLiteralExprForEnumValue(ev) {
|
|
65
|
-
return ts.factory.createObjectLiteralExpression([
|
|
66
|
-
ts.factory.createPropertyAssignment("protobufEnumValue", ts.factory.createObjectLiteralExpression([ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(ev.proto.name))], true)),
|
|
67
|
-
], true);
|
|
15
|
+
export function createEnumTypeCode(type, opts) {
|
|
16
|
+
const typeOpts = {
|
|
17
|
+
description: type.description,
|
|
18
|
+
values: code `{${joinCode(type.values
|
|
19
|
+
.filter((v) => !v.isIgnored() && !v.isUnespecified())
|
|
20
|
+
.map((ev) => code `${ev.name}: ${literalOf(compact({
|
|
21
|
+
description: ev.description,
|
|
22
|
+
deprecationReason: ev.deprecationReason,
|
|
23
|
+
value: ev.number,
|
|
24
|
+
extensions: {
|
|
25
|
+
protobufEnumValue: {
|
|
26
|
+
name: ev.proto.name,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}))},`))}} as const`,
|
|
30
|
+
extensions: protobufGraphQLExtensions(type),
|
|
31
|
+
};
|
|
32
|
+
return code `
|
|
33
|
+
export const ${pothosRef(type)} =
|
|
34
|
+
${pothosBuilder(type, opts)}.enumType(${literalOf(type.typeName)}, ${literalOf(compact(typeOpts))});
|
|
35
|
+
`;
|
|
68
36
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { EnumType, InputObjectField, ObjectField, ObjectOneofField, ObjectType, ScalarType, SquashedOneofUnionType, } from "@proto-graphql/codegen-core";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
1
|
+
import { compact, createGetFieldValueCode, EnumType, InputObjectField, ObjectField, ObjectOneofField, ObjectType, protobufGraphQLExtensions, ScalarType, SquashedOneofUnionType, } from "@proto-graphql/codegen-core";
|
|
2
|
+
import { code, literalOf } from "ts-poet";
|
|
3
|
+
import { createEnumResolverCode } from "./fieldResolver/enumFieldResolver";
|
|
4
|
+
import { createNonNullResolverCode } from "./fieldResolver/nonNullResolver";
|
|
5
|
+
import { createOneofUnionResolverCode } from "./fieldResolver/oneofUnionResolver";
|
|
6
|
+
import { fieldTypeRef } from "./util";
|
|
7
7
|
/**
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
@@ -24,53 +24,45 @@ import { createDeprecationPropertyAssignment, createDescriptionPropertyAssignmen
|
|
|
24
24
|
* })
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
|
-
export function
|
|
28
|
-
let typeExpr = field.type instanceof ScalarType
|
|
29
|
-
? ts.factory.createStringLiteral(field.type.typeName)
|
|
30
|
-
: ts.factory.createIdentifier(field.type.pothosRefObjectName);
|
|
27
|
+
export function createFieldRefCode(field, opts) {
|
|
31
28
|
const isInput = field instanceof InputObjectField;
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
let
|
|
35
|
-
// let defaultValueExpr: ts.Expression | undefined;
|
|
36
|
-
if (field.isList()) {
|
|
37
|
-
typeExpr = ts.factory.createArrayLiteralExpression([typeExpr], false);
|
|
38
|
-
// if (isInput) {
|
|
39
|
-
// defaultValueExpr = ts.factory.createArrayLiteralExpression([], false);
|
|
40
|
-
// }
|
|
41
|
-
nullableExpr = ts.factory.createObjectLiteralExpression([
|
|
42
|
-
ts.factory.createPropertyAssignment("list", nullableExpr),
|
|
43
|
-
ts.factory.createPropertyAssignment("items", nonNullableToken),
|
|
44
|
-
], false);
|
|
45
|
-
}
|
|
46
|
-
let createResolveStmts;
|
|
29
|
+
const baseType = field.type instanceof ScalarType ? literalOf(field.type.typeName) : fieldTypeRef(field, opts);
|
|
30
|
+
const sourceExpr = code `source`;
|
|
31
|
+
let resolverCode;
|
|
47
32
|
if (!isInput) {
|
|
48
|
-
const nullableInProto = field.type instanceof ObjectType ||
|
|
49
|
-
(field.type instanceof ScalarType && !field.type.isPrimitive() && !field.type.isWrapperType());
|
|
50
|
-
if (nullableInProto && !field.isNullable()) {
|
|
51
|
-
createResolveStmts = (sourceExpr) => createNonNullResolverStmts(ts.factory.createPropertyAccessExpression(sourceExpr, field.protoJsName));
|
|
52
|
-
}
|
|
53
|
-
if (field.type instanceof EnumType && field instanceof ObjectField) {
|
|
54
|
-
createResolveStmts = (sourceExpr) => createEnumResolverStmts(ts.factory.createPropertyAccessExpression(sourceExpr, field.protoJsName), field);
|
|
55
|
-
}
|
|
56
33
|
if (field instanceof ObjectOneofField) {
|
|
57
|
-
|
|
34
|
+
resolverCode = createOneofUnionResolverCode(sourceExpr, field);
|
|
58
35
|
}
|
|
59
|
-
|
|
60
|
-
|
|
36
|
+
else {
|
|
37
|
+
const valueExpr = createGetFieldValueCode(sourceExpr, field.proto, opts);
|
|
38
|
+
const nullableInProto = field.type instanceof ObjectType ||
|
|
39
|
+
(field.type instanceof ScalarType && !field.type.isPrimitive() && !field.type.isWrapperType());
|
|
40
|
+
if (nullableInProto && !field.isNullable()) {
|
|
41
|
+
resolverCode = createNonNullResolverCode(valueExpr);
|
|
42
|
+
}
|
|
43
|
+
if (field.type instanceof EnumType && field instanceof ObjectField) {
|
|
44
|
+
resolverCode = createEnumResolverCode(valueExpr, field, opts);
|
|
45
|
+
}
|
|
46
|
+
if (field.type instanceof SquashedOneofUnionType && field instanceof ObjectField) {
|
|
47
|
+
resolverCode = createOneofUnionResolverCode(valueExpr, field);
|
|
48
|
+
}
|
|
61
49
|
}
|
|
62
50
|
}
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
51
|
+
const nullableValue = isInput !== field.isNullable(); /* Logical XOR */
|
|
52
|
+
const fieldOpts = {
|
|
53
|
+
type: field.isList() ? code `[${baseType}]` : baseType,
|
|
54
|
+
[isInput ? "required" : "nullable"]: field.isList()
|
|
55
|
+
? { list: nullableValue, items: isInput /* always non-null */ }
|
|
56
|
+
: nullableValue,
|
|
57
|
+
description: field.description,
|
|
58
|
+
deprecationReason: field.deprecationReason,
|
|
59
|
+
resolve: resolverCode ? code `${sourceExpr} => {${resolverCode}}` : null,
|
|
60
|
+
extensions: protobufGraphQLExtensions(field),
|
|
61
|
+
};
|
|
62
|
+
const shouldUseFieldFunc = isInput || resolverCode != null;
|
|
63
|
+
return shouldUseFieldFunc
|
|
64
|
+
? code `t.field(${literalOf(compact(fieldOpts))})`
|
|
65
|
+
: code `t.expose(${literalOf(field.proto.jsonName)}, ${literalOf(compact(fieldOpts))})`;
|
|
74
66
|
}
|
|
75
67
|
/**
|
|
76
68
|
* @example
|
|
@@ -85,51 +77,13 @@ export function createFieldDefinitionExpr(field) {
|
|
|
85
77
|
* })
|
|
86
78
|
* ```
|
|
87
79
|
*/
|
|
88
|
-
export function
|
|
89
|
-
return
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
? null
|
|
98
|
-
: ts.factory.createMethodDeclaration(undefined, undefined, undefined, "resolve", undefined, undefined, [], undefined, ts.factory.createBlock([
|
|
99
|
-
ts.factory.createReturnStatement(ts.factory.createToken(ts.SyntaxKind.TrueKeyword)),
|
|
100
|
-
])),
|
|
101
|
-
].filter(onlyNonNull()), true),
|
|
102
|
-
]);
|
|
103
|
-
}
|
|
104
|
-
function createResolverExpr(createStmts) {
|
|
105
|
-
return ts.factory.createArrowFunction(undefined, undefined, [ts.factory.createParameterDeclaration(undefined, undefined, undefined, ts.factory.createIdentifier("source"))], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createBlock(createStmts(ts.factory.createIdentifier("source")), true));
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* @example
|
|
109
|
-
* ```ts
|
|
110
|
-
* ({
|
|
111
|
-
* protobufField: {
|
|
112
|
-
* name: "...",
|
|
113
|
-
* },
|
|
114
|
-
* } as ProtobufFieldExtensions)
|
|
115
|
-
* ```
|
|
116
|
-
*/
|
|
117
|
-
function createExtensionsObjectLiteralExpr(field) {
|
|
118
|
-
let typeName;
|
|
119
|
-
if ((field instanceof ObjectField || field instanceof InputObjectField) && field.proto.type !== null) {
|
|
120
|
-
if (field.proto.type.kind === "Scalar") {
|
|
121
|
-
typeName = field.proto.type.type;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
typeName = field.proto.type.fullName.toString();
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return ts.factory.createObjectLiteralExpression([
|
|
128
|
-
ts.factory.createPropertyAssignment("protobufField", ts.factory.createObjectLiteralExpression([
|
|
129
|
-
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(field.proto.name)),
|
|
130
|
-
typeName
|
|
131
|
-
? ts.factory.createPropertyAssignment("typeFullName", ts.factory.createStringLiteral(typeName))
|
|
132
|
-
: undefined,
|
|
133
|
-
].filter(onlyNonNull()), true)),
|
|
134
|
-
], true);
|
|
80
|
+
export function createNoopFieldRefCode(opts) {
|
|
81
|
+
return code `
|
|
82
|
+
t.field({
|
|
83
|
+
type: "Boolean",
|
|
84
|
+
${opts.input ? "required: false" : "nullable: true"},
|
|
85
|
+
description: "noop field",
|
|
86
|
+
${opts.input ? "" : "resolve: () => true,"}
|
|
87
|
+
})
|
|
88
|
+
`;
|
|
135
89
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { protoType } from "@proto-graphql/codegen-core";
|
|
2
|
+
import { code } from "ts-poet";
|
|
3
3
|
/**
|
|
4
4
|
* @example nullable
|
|
5
5
|
* ```ts
|
|
@@ -16,46 +16,42 @@ import { createFullNameExpr, onlyNonNull } from "../util";
|
|
|
16
16
|
* return root.myEnum
|
|
17
17
|
* ```
|
|
18
18
|
*/
|
|
19
|
-
export function
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
19
|
+
export function createEnumResolverCode(valueExpr, field, opts) {
|
|
20
|
+
const createBlockStmtCodes = (valueExpr) => {
|
|
21
|
+
const chunks = [];
|
|
22
|
+
if (field.type.unspecifiedValue != null) {
|
|
23
|
+
const escapeCode = field.isNullable() && !field.isList()
|
|
24
|
+
? code `return null;`
|
|
25
|
+
: code `throw new Error("${field.name} is required field. But got unspecified.");`;
|
|
26
|
+
chunks.push(code `
|
|
27
|
+
if (${valueExpr} === ${protoType(field.type.proto, opts)}.${field.type.unspecifiedValue.proto.name}) {
|
|
28
|
+
${escapeCode}
|
|
29
|
+
}
|
|
30
|
+
`);
|
|
31
|
+
}
|
|
32
|
+
for (const ev of field.type.valuesWithIgnored) {
|
|
33
|
+
if (!ev.isIgnored())
|
|
34
|
+
continue;
|
|
35
|
+
chunks.push(code `
|
|
36
|
+
if (${valueExpr} === ${protoType(field.type.proto, opts)}.${ev.proto.name}) {
|
|
37
|
+
throw new Error("${ev.name} is ignored in GraphQL schema");
|
|
38
|
+
}
|
|
39
|
+
`);
|
|
40
|
+
}
|
|
41
|
+
return chunks;
|
|
42
|
+
};
|
|
27
43
|
if (field.isList()) {
|
|
28
|
-
const
|
|
29
|
-
if (
|
|
30
|
-
return
|
|
44
|
+
const stmts = createBlockStmtCodes(code `item`);
|
|
45
|
+
if (stmts.length === 0) {
|
|
46
|
+
return code `return ${valueExpr}`;
|
|
31
47
|
}
|
|
32
|
-
return
|
|
33
|
-
|
|
34
|
-
|
|
48
|
+
return code `return ${valueExpr}.map(item => {
|
|
49
|
+
${stmts}
|
|
50
|
+
return item;
|
|
51
|
+
})`;
|
|
35
52
|
}
|
|
36
|
-
return
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
}
|
|
41
|
-
function createGuardStmts(valueExpr, thenStmt, unspecifiedValue, ignoredValues) {
|
|
42
|
-
return [
|
|
43
|
-
unspecifiedValue
|
|
44
|
-
? ts.factory.createIfStatement(ts.factory.createBinaryExpression(valueExpr, ts.SyntaxKind.EqualsEqualsEqualsToken, createFullNameExpr(unspecifiedValue.fullName)), thenStmt)
|
|
45
|
-
: null,
|
|
46
|
-
...ignoredValues.map((ev) => ev.isIgnored()
|
|
47
|
-
? ts.factory.createIfStatement(ts.factory.createBinaryExpression(valueExpr, ts.SyntaxKind.EqualsEqualsEqualsToken, createFullNameExpr(ev.fullName)), ts.factory.createBlock([
|
|
48
|
-
ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), undefined, [
|
|
49
|
-
ts.factory.createStringLiteral(`${ev.name} is ignored in GraphQL schema`),
|
|
50
|
-
])),
|
|
51
|
-
], true // multiline
|
|
52
|
-
))
|
|
53
|
-
: null),
|
|
54
|
-
].filter(onlyNonNull());
|
|
55
|
-
}
|
|
56
|
-
function createMapExpr(listExpr, blockFn) {
|
|
57
|
-
return ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(listExpr, "map"), undefined, [
|
|
58
|
-
ts.factory.createArrowFunction(undefined, undefined, [ts.factory.createParameterDeclaration(undefined, undefined, undefined, "item", undefined, undefined, undefined)], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createBlock(blockFn(ts.factory.createIdentifier("item")), true // multiline
|
|
59
|
-
)),
|
|
60
|
-
]);
|
|
53
|
+
return code `
|
|
54
|
+
${createBlockStmtCodes(valueExpr)}
|
|
55
|
+
return ${valueExpr};
|
|
56
|
+
`;
|
|
61
57
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
export function
|
|
3
|
-
return
|
|
1
|
+
import { code } from "ts-poet";
|
|
2
|
+
export function createNonNullResolverCode(valueExpr) {
|
|
3
|
+
return code `
|
|
4
|
+
return ${valueExpr}!;
|
|
5
|
+
`;
|
|
4
6
|
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { ObjectField, ObjectOneofField } from "@proto-graphql/codegen-core";
|
|
2
|
-
import
|
|
3
|
-
import { onlyNonNull } from "../util";
|
|
2
|
+
import { code, joinCode } from "ts-poet";
|
|
4
3
|
/**
|
|
5
4
|
* @example nullable
|
|
6
5
|
* ```ts
|
|
@@ -11,44 +10,28 @@ import { onlyNonNull } from "../util";
|
|
|
11
10
|
* return value
|
|
12
11
|
* ```
|
|
13
12
|
*/
|
|
14
|
-
export function
|
|
15
|
-
const
|
|
13
|
+
export function createOneofUnionResolverCode(sourceExpr, field) {
|
|
14
|
+
const createBlockStmtCode = (sourceExpr, { nullable }) => {
|
|
16
15
|
const createFieldExpr = (memberField) => {
|
|
17
16
|
if (field instanceof ObjectOneofField) {
|
|
18
|
-
return
|
|
17
|
+
return code `${sourceExpr}.${memberField.proto.jsonName}`;
|
|
19
18
|
}
|
|
20
|
-
return
|
|
19
|
+
return code `${sourceExpr}?.${memberField.proto.jsonName}`;
|
|
21
20
|
};
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return createFieldExpr(field);
|
|
30
|
-
}
|
|
31
|
-
return ts.factory.createBinaryExpression(createFieldExpr(field), ts.factory.createToken(ts.SyntaxKind.QuestionQuestionToken), expr);
|
|
32
|
-
}, null)),
|
|
33
|
-
], ts.NodeFlags.Const)),
|
|
34
|
-
nullable
|
|
35
|
-
? undefined
|
|
36
|
-
: ts.factory.createIfStatement(ts.factory.createBinaryExpression(valueExpr, ts.SyntaxKind.EqualsEqualsToken, ts.factory.createToken(ts.SyntaxKind.NullKeyword)), ts.factory.createBlock([
|
|
37
|
-
ts.factory.createThrowStatement(ts.factory.createNewExpression(ts.factory.createIdentifier("Error"), undefined, [
|
|
38
|
-
ts.factory.createStringLiteral(`${field.name} should not be null`),
|
|
39
|
-
])),
|
|
40
|
-
], true)),
|
|
41
|
-
ts.factory.createReturnStatement(valueExpr),
|
|
42
|
-
].filter(onlyNonNull());
|
|
21
|
+
return code `
|
|
22
|
+
const value = ${joinCode(field.type.fields.map(createFieldExpr), { on: "??" })};
|
|
23
|
+
if (value == null) {
|
|
24
|
+
${nullable ? "return null" : `throw new Error("${field.name} should not be null")`};
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
`;
|
|
43
28
|
};
|
|
44
|
-
if (
|
|
45
|
-
return
|
|
29
|
+
if (field instanceof ObjectField && field.isList()) {
|
|
30
|
+
return code `
|
|
31
|
+
return ${sourceExpr}.map(item => {
|
|
32
|
+
${createBlockStmtCode(code `item`, { nullable: false })}
|
|
33
|
+
})
|
|
34
|
+
`;
|
|
46
35
|
}
|
|
47
|
-
return
|
|
48
|
-
ts.factory.createReturnStatement(ts.factory.createCallExpression(ts.factory.createPropertyAccessExpression(sourceExpr, "map"), undefined, [
|
|
49
|
-
ts.factory.createArrowFunction(undefined, undefined, [
|
|
50
|
-
ts.factory.createParameterDeclaration(undefined, undefined, undefined, "item", undefined, undefined, undefined),
|
|
51
|
-
], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createBlock(createResolverStmts(ts.factory.createIdentifier("item"), field, { nullable: false }), true)),
|
|
52
|
-
])),
|
|
53
|
-
];
|
|
36
|
+
return createBlockStmtCode(sourceExpr, { nullable: field.isNullable() });
|
|
54
37
|
}
|
|
@@ -1,53 +1,23 @@
|
|
|
1
1
|
import { EnumType, InputObjectType, ObjectType, OneofUnionType, SquashedOneofUnionType, } from "@proto-graphql/codegen-core";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
export function createImportDecls(types) {
|
|
9
|
-
return types
|
|
10
|
-
.flatMap((t) => t.importModules)
|
|
11
|
-
.filter(onlyUnique((m) => JSON.stringify([m.alias, m.module])))
|
|
12
|
-
.sort(({ module: a }, { module: b }) => {
|
|
13
|
-
const pat = /^\.+\//;
|
|
14
|
-
const [aIsRel, bIsRel] = [a.match(pat), b.match(pat)];
|
|
15
|
-
if (aIsRel && !bIsRel)
|
|
16
|
-
return 1;
|
|
17
|
-
if (!aIsRel && bIsRel)
|
|
18
|
-
return -1;
|
|
19
|
-
if (a < b)
|
|
20
|
-
return -1;
|
|
21
|
-
if (a > b)
|
|
22
|
-
return 1;
|
|
23
|
-
return 0;
|
|
24
|
-
})
|
|
25
|
-
.map((m) => createImportDecl(m));
|
|
26
|
-
}
|
|
27
|
-
export function createReExportStmts(types) {
|
|
28
|
-
return types
|
|
29
|
-
.flatMap((t) => t.exportTypes)
|
|
30
|
-
.sort()
|
|
31
|
-
.filter(onlyUnique(({ type }) => fullNameString(type)))
|
|
32
|
-
.map(({ name, type }) => ts.factory.createTypeAliasDeclaration(undefined, [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)], name, undefined, ts.factory.createTypeReferenceNode(createQualifiedName(type))));
|
|
33
|
-
}
|
|
34
|
-
export function createTypeDslStmts(types) {
|
|
35
|
-
return types
|
|
36
|
-
.flatMap((type) => {
|
|
2
|
+
import { createEnumTypeCode } from "./enumType";
|
|
3
|
+
import { createInputObjectTypeCode } from "./inputObjectType";
|
|
4
|
+
import { createObjectTypeCode } from "./objectType";
|
|
5
|
+
import { createOneofUnionTypeCode } from "./oneofUnionType";
|
|
6
|
+
export function createTypeDslCodes(types, opts) {
|
|
7
|
+
return types.flatMap((type) => {
|
|
37
8
|
if (type instanceof ObjectType) {
|
|
38
|
-
return
|
|
9
|
+
return createObjectTypeCode(type, opts);
|
|
39
10
|
}
|
|
40
11
|
if (type instanceof InputObjectType) {
|
|
41
|
-
return
|
|
12
|
+
return createInputObjectTypeCode(type, opts);
|
|
42
13
|
}
|
|
43
14
|
if (type instanceof EnumType) {
|
|
44
|
-
return [
|
|
15
|
+
return [createEnumTypeCode(type, opts)];
|
|
45
16
|
}
|
|
46
17
|
if (type instanceof OneofUnionType || type instanceof SquashedOneofUnionType) {
|
|
47
|
-
return [
|
|
18
|
+
return [createOneofUnionTypeCode(type, opts)];
|
|
48
19
|
}
|
|
49
20
|
const _exhaustiveCheck = type;
|
|
50
21
|
throw "unreachable";
|
|
51
|
-
})
|
|
52
|
-
.filter(onlyNonNull());
|
|
22
|
+
});
|
|
53
23
|
}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { InputObjectType } from "@proto-graphql/codegen-core";
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { compact, InputObjectType, protobufGraphQLExtensions, protoType } from "@proto-graphql/codegen-core";
|
|
2
|
+
import { code, imp, joinCode, literalOf } from "ts-poet";
|
|
3
|
+
import { createFieldRefCode, createNoopFieldRefCode } from "./field";
|
|
4
|
+
import { fieldTypeShape, pothosBuilder, pothosRef, shapeType } from "./util";
|
|
5
5
|
/**
|
|
6
6
|
* @example
|
|
7
7
|
* ```ts
|
|
8
|
-
* export
|
|
9
|
-
*
|
|
8
|
+
* export type HelloInput$Shape = {
|
|
9
|
+
* // ...
|
|
10
|
+
* }
|
|
11
|
+
* export const HelloInput$Ref: pothos.InputObjectRef<Hello$SHape> = builder.inputRef("HelloInput").implement({
|
|
10
12
|
* description: "...",
|
|
11
13
|
* fields: (t) => ({
|
|
12
14
|
* // ...
|
|
@@ -14,80 +16,38 @@ import { createBuilderPropExpr, createDescriptionPropertyAssignment, createDslEx
|
|
|
14
16
|
* })
|
|
15
17
|
* ```
|
|
16
18
|
*/
|
|
17
|
-
export function
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
])),
|
|
28
|
-
];
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* @example
|
|
32
|
-
* ```ts
|
|
33
|
-
* definition(t) {
|
|
34
|
-
* // ...
|
|
35
|
-
* }
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
function createInputObjectTypeFieldsMethodExpr(type) {
|
|
39
|
-
return ts.factory.createArrowFunction(undefined, undefined, [ts.factory.createParameterDeclaration(undefined, undefined, undefined, "t", undefined, undefined, undefined)], undefined, ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken), ts.factory.createParenthesizedExpression(ts.factory.createObjectLiteralExpression(type.fields.length > 0
|
|
40
|
-
? type.fields.map((f) => ts.factory.createPropertyAssignment(f.name, createFieldDefinitionExpr(f)))
|
|
41
|
-
: [ts.factory.createPropertyAssignment("_", createNoopFieldDefinitionExpr({ input: true }))], true)));
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* @example
|
|
45
|
-
* ```ts
|
|
46
|
-
* {
|
|
47
|
-
* message?: _$hello$hello_pb$Hello["message"] | null,
|
|
48
|
-
* // ...
|
|
49
|
-
* }
|
|
50
|
-
* ```
|
|
51
|
-
*/
|
|
52
|
-
function createInputObjectTypeShapeDecl(type) {
|
|
53
|
-
return ts.factory.createTypeAliasDeclaration(undefined, [ts.factory.createToken(ts.SyntaxKind.ExportKeyword)], createInputObjectTypeShapeIdent(type), undefined, ts.factory.createTypeLiteralNode(type.fields.map((field) => {
|
|
54
|
-
let typeNode = ts.factory.createIndexedAccessTypeNode(ts.factory.createTypeReferenceNode(createQualifiedName(type.protoTypeFullName)), ts.factory.createLiteralTypeNode(ts.factory.createStringLiteral(field.protoJsName)));
|
|
55
|
-
if (field.type instanceof InputObjectType) {
|
|
56
|
-
typeNode = ts.factory.createTypeReferenceNode(createInputObjectTypeShapeIdent(field.type));
|
|
57
|
-
if (field.isList()) {
|
|
58
|
-
typeNode = ts.factory.createTypeReferenceNode("Array", [typeNode]);
|
|
59
|
-
}
|
|
19
|
+
export function createInputObjectTypeCode(type, opts) {
|
|
20
|
+
const shapeTypeCode = code `
|
|
21
|
+
export type ${shapeType(type)} = {
|
|
22
|
+
${joinCode(type.fields.map((f) => {
|
|
23
|
+
let typeNode;
|
|
24
|
+
if (f.type instanceof InputObjectType) {
|
|
25
|
+
// @ts-expect-error f should be inferred as InputObjectField<InputObjectType>
|
|
26
|
+
typeNode = code `${fieldTypeShape(f, opts)}`;
|
|
27
|
+
if (f.isList())
|
|
28
|
+
typeNode = code `Array<${typeNode}>`;
|
|
60
29
|
}
|
|
61
|
-
|
|
62
|
-
typeNode =
|
|
63
|
-
typeNode,
|
|
64
|
-
ts.factory.createLiteralTypeNode(ts.factory.createToken(ts.SyntaxKind.NullKeyword)),
|
|
65
|
-
]);
|
|
30
|
+
else {
|
|
31
|
+
typeNode = code `${protoType(type.proto, opts)}[${literalOf(f.proto.jsonName)}]`;
|
|
66
32
|
}
|
|
67
|
-
return
|
|
68
|
-
}))
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
ts.factory.createPropertyAssignment("protobufMessage", ts.factory.createObjectLiteralExpression([
|
|
88
|
-
ts.factory.createPropertyAssignment("fullName", ts.factory.createStringLiteral(type.proto.fullName.toString())),
|
|
89
|
-
ts.factory.createPropertyAssignment("name", ts.factory.createStringLiteral(type.proto.name)),
|
|
90
|
-
ts.factory.createPropertyAssignment("package", ts.factory.createStringLiteral(type.proto.file.package)),
|
|
91
|
-
], true)),
|
|
92
|
-
], true);
|
|
33
|
+
return f.isNullable() ? code `${f.name}?: ${typeNode} | null,` : code `${f.name}: ${typeNode},`;
|
|
34
|
+
}))}
|
|
35
|
+
};
|
|
36
|
+
`;
|
|
37
|
+
const refCode = code `
|
|
38
|
+
export const ${pothosRef(type)}: ${imp("InputObjectRef@@pothos/core")}<${shapeType(type)}> =
|
|
39
|
+
${pothosBuilder(type, opts)}.inputRef<${shapeType(type)}>(${literalOf(type.typeName)}).implement(
|
|
40
|
+
${literalOf(compact({
|
|
41
|
+
description: type.description,
|
|
42
|
+
fields: code `t => ({${type.fields.length > 0
|
|
43
|
+
? type.fields.map((f) => code `${f.name}: ${createFieldRefCode(f, opts)},`)
|
|
44
|
+
: code `_: ${createNoopFieldRefCode({ input: true })}`}})`,
|
|
45
|
+
extensions: protobufGraphQLExtensions(type),
|
|
46
|
+
}))}
|
|
47
|
+
);
|
|
48
|
+
`;
|
|
49
|
+
return code `
|
|
50
|
+
${shapeTypeCode}
|
|
51
|
+
${refCode}
|
|
52
|
+
`;
|
|
93
53
|
}
|