Skip to content

Commit c8b21a7

Browse files
committed
move common logics to core package
1 parent d3580b3 commit c8b21a7

File tree

14 files changed

+226
-152
lines changed

14 files changed

+226
-152
lines changed

packages/@proto-graphql/codegen-core/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
},
2222
"dependencies": {
2323
"@proto-graphql/proto-descriptors": "^0.2.0",
24-
"change-case": "^4.1.2"
24+
"change-case": "^4.1.2",
25+
"ts-poet": "^6.3.0"
2526
},
2627
"peerDependencies": {
2728
"google-protobuf": "^3.12.2"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
export * from "./types";
2+
export * from "./printer";
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import {
2+
EnumType,
3+
EnumTypeValue,
4+
InputObjectField,
5+
InputObjectType,
6+
ObjectField,
7+
ObjectOneofField,
8+
ObjectType,
9+
OneofUnionType,
10+
SquashedOneofUnionType,
11+
} from "../types";
12+
import { compact } from "./util";
13+
14+
export function protobufGraphQLExtensions(
15+
type:
16+
| ObjectType
17+
| InputObjectType
18+
| EnumType
19+
| OneofUnionType
20+
| SquashedOneofUnionType
21+
| ObjectField<any>
22+
| ObjectOneofField
23+
| InputObjectField<any>
24+
| EnumTypeValue
25+
): Record<string, Record<string, string>> {
26+
if (type instanceof ObjectType || type instanceof InputObjectType) {
27+
return {
28+
protobufMessage: {
29+
fullName: type.proto.fullName.toString(),
30+
name: type.proto.name,
31+
package: type.proto.file.package,
32+
},
33+
};
34+
}
35+
if (type instanceof EnumType) {
36+
return {
37+
protobufEnum: {
38+
name: type.proto.name,
39+
fullName: type.proto.fullName.toString(),
40+
package: type.proto.file.package,
41+
},
42+
};
43+
}
44+
if (type instanceof OneofUnionType || type instanceof SquashedOneofUnionType) {
45+
return {
46+
protobufOneof: compact({
47+
fullName: type.proto.fullName.toString(),
48+
name: type.proto.name,
49+
messageName: type.proto.kind === "Oneof" ? type.proto.parent.name : undefined,
50+
package: (type.proto.kind === "Message" ? type.proto : type.proto.parent).file.package,
51+
fields: type.fields.map((f) => ({
52+
name: f.proto.name,
53+
type: protoFieldTypeFullName(f),
54+
})),
55+
}),
56+
};
57+
}
58+
if (type instanceof ObjectField || type instanceof ObjectOneofField || type instanceof InputObjectField) {
59+
return {
60+
protobufField: compact({ name: type.proto.name, typeFullName: protoFieldTypeFullName(type) }),
61+
};
62+
}
63+
if (type instanceof EnumTypeValue) {
64+
return {
65+
protobufEnumValue: {
66+
name: type.proto.name,
67+
},
68+
};
69+
}
70+
71+
/* istanbul ignore next */
72+
const _exhaustiveCheck: never = type;
73+
return {};
74+
}
75+
76+
function protoFieldTypeFullName(
77+
field: ObjectField<any> | ObjectOneofField | InputObjectField<any>
78+
): string | undefined {
79+
if ((field instanceof ObjectField || field instanceof InputObjectField) && field.proto.type !== null) {
80+
if (field.proto.type.kind === "Scalar") {
81+
return field.proto.type.type;
82+
}
83+
return field.proto.type.fullName.toString();
84+
}
85+
return undefined;
86+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from "./util";
2+
export * from "./graphqlExtensions";
3+
export * from "./print";
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { ProtoFile } from "@proto-graphql/proto-descriptors";
2+
import { code, Code } from "ts-poet";
3+
4+
export function printCodes(codes: Code[], programName: string, file: ProtoFile): string {
5+
return (codes.length === 0 ? code`export {};` : code`${codes}`).toString({
6+
prefix: `
7+
// Code generated by ${programName}. DO NOT EDIT.
8+
// source: ${file.descriptor.getName()}
9+
10+
/* eslint-disable */
11+
`,
12+
dprintOptions: {
13+
lineWidth: 80,
14+
indentWidth: 2,
15+
useTabs: false,
16+
semiColons: "always",
17+
quoteStyle: "alwaysDouble",
18+
quoteProps: "asNeeded",
19+
newLineKind: "lf",
20+
useBraces: "whenNotSingleLine",
21+
bracePosition: "sameLineUnlessHanging",
22+
singleBodyPosition: "maintain",
23+
nextControlFlowPosition: "sameLine",
24+
trailingCommas: "onlyMultiLine",
25+
operatorPosition: "nextLine",
26+
preferHanging: false,
27+
"arrowFunction.useParentheses": "force",
28+
},
29+
});
30+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { ProtoEnum, ProtoMessage } from "@proto-graphql/proto-descriptors";
2+
import * as path from "path";
3+
import { code, Code, imp } from "ts-poet";
4+
import {
5+
EnumType,
6+
InputObjectType,
7+
InterfaceType,
8+
ObjectType,
9+
OneofUnionType,
10+
PrinterOptions,
11+
protoImportPath,
12+
SquashedOneofUnionType,
13+
} from "../types";
14+
15+
export function filename(
16+
type: ObjectType | InputObjectType | EnumType | OneofUnionType | SquashedOneofUnionType | InterfaceType,
17+
opts: Pick<PrinterOptions, "fileLayout">
18+
): string {
19+
switch (opts.fileLayout) {
20+
case "proto_file":
21+
return type.file.filename;
22+
case "graphql_type": {
23+
return path.join(path.dirname(type.file.filename), `${type.typeName}${type.file.extname}`);
24+
}
25+
/* istanbul ignore next */
26+
default: {
27+
const _exhaustiveCheck: never = opts.fileLayout;
28+
throw "unreachable";
29+
}
30+
}
31+
}
32+
33+
/** Remove nullish values recursively. */
34+
export function compact(v: any): any {
35+
if (typeof v !== "object") return v;
36+
if (Array.isArray(v)) return v.map(compact);
37+
if (v == null) return v;
38+
if ("toCodeString" in v) return v; // ignore nodes of ts-poet
39+
return compactObj(v);
40+
}
41+
42+
function compactObj<In extends Out, Out extends Record<string, unknown>>(obj: In): Out {
43+
return Object.keys(obj).reduce((newObj, key) => {
44+
const v = obj[key];
45+
return v == null ? newObj : { ...newObj, [key]: compact(v) };
46+
}, {} as Out);
47+
}
48+
49+
export function protoType(origProto: ProtoMessage | ProtoEnum, opts: PrinterOptions): Code {
50+
switch (opts.protobuf) {
51+
case "google-protobuf":
52+
case "protobufjs":
53+
throw new Error(`not implemented: ${opts.protobuf}`);
54+
case "ts-proto": {
55+
let proto = origProto;
56+
let name = proto.name;
57+
while (proto.parent.kind !== "File") {
58+
proto = proto.parent;
59+
name = `${proto.name}_${name}`;
60+
}
61+
return code`${imp(`${name}@${protoImportPath(proto, opts)}`)}`;
62+
}
63+
/* istanbul ignore next */
64+
default: {
65+
const _exhaustiveCheck: never = opts;
66+
throw "unreachable";
67+
}
68+
}
69+
}

packages/protoc-gen-pothos/src/dslgen/printers/enumType.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { EnumType } from "@proto-graphql/codegen-core";
1+
import { compact, EnumType, protobufGraphQLExtensions } from "@proto-graphql/codegen-core";
22
import { code, Code, joinCode, literalOf } from "ts-poet";
3-
import { compact, pothosBuilder, PothosPrinterOptions, pothosRef } from "./util";
3+
import { pothosBuilder, PothosPrinterOptions, pothosRef } from "./util";
44

55
/**
66
* @example
@@ -35,13 +35,7 @@ export function createEnumTypeCode(type: EnumType, opts: PothosPrinterOptions):
3535
)},`
3636
)
3737
)}} as const`,
38-
extensions: {
39-
protobufEnum: {
40-
name: type.proto.name,
41-
fullName: type.proto.fullName.toString(),
42-
package: type.proto.file.package,
43-
},
44-
},
38+
extensions: protobufGraphQLExtensions(type),
4539
};
4640
return code`
4741
export const ${pothosRef(type)} =

packages/protoc-gen-pothos/src/dslgen/printers/field.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
import {
2+
compact,
23
EnumType,
34
InputObjectField,
45
ObjectField,
56
ObjectOneofField,
67
ObjectType,
8+
protobufGraphQLExtensions,
79
ScalarType,
810
SquashedOneofUnionType,
911
} from "@proto-graphql/codegen-core";
1012
import { code, Code, literalOf } from "ts-poet";
1113
import { createEnumResolverCode } from "./fieldResolver/enumFieldResolver";
1214
import { createNonNullResolverCode } from "./fieldResolver/nonNullResolver";
1315
import { createOneofUnionResolverCode } from "./fieldResolver/oneofUnionResolver";
14-
import { compact, fieldTypeRef, PothosPrinterOptions, protoFieldTypeFullName } from "./util";
16+
import { fieldTypeRef, PothosPrinterOptions } from "./util";
1517

1618
/**
1719
* @example
@@ -70,9 +72,7 @@ export function createFieldRefCode(
7072
description: field.description,
7173
deprecationReason: field.deprecationReason,
7274
resolve: resolverCode ? code`${sourceExpr} => {${resolverCode}}` : null,
73-
extensions: {
74-
protobufField: { name: field.proto.name, typeFullName: protoFieldTypeFullName(field) },
75-
},
75+
extensions: protobufGraphQLExtensions(field),
7676
};
7777

7878
const shouldUseFieldFunc = isInput || resolverCode != null;

packages/protoc-gen-pothos/src/dslgen/printers/fieldResolver/enumFieldResolver.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
import { EnumType, ObjectField, PrinterOptions } from "@proto-graphql/codegen-core";
1+
import { EnumType, ObjectField, PrinterOptions, protoType } from "@proto-graphql/codegen-core";
22
import { Code, code } from "ts-poet";
3-
import { protoType } from "../util";
43

54
/**
65
* @example nullable

packages/protoc-gen-pothos/src/dslgen/printers/inputObjectType.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { InputObjectType } from "@proto-graphql/codegen-core";
1+
import { compact, InputObjectType, protobufGraphQLExtensions, protoType } from "@proto-graphql/codegen-core";
22
import { Code, code, imp, joinCode, literalOf } from "ts-poet";
33
import { createFieldRefCode, createNoopFieldRefCode } from "./field";
4-
import { compact, fieldTypeShape, pothosBuilder, PothosPrinterOptions, pothosRef, protoType, shapeType } from "./util";
4+
import { fieldTypeShape, pothosBuilder, PothosPrinterOptions, pothosRef, shapeType } from "./util";
55

66
/**
77
* @example
@@ -47,13 +47,7 @@ export function createInputObjectTypeCode(type: InputObjectType, opts: PothosPri
4747
? type.fields.map((f) => code`${f.name}: ${createFieldRefCode(f, opts)},`)
4848
: code`_: ${createNoopFieldRefCode({ input: true })}`
4949
}})`,
50-
extensions: {
51-
protobufMessage: {
52-
fullName: type.proto.fullName.toString(),
53-
name: type.proto.name,
54-
package: type.proto.file.package,
55-
},
56-
},
50+
extensions: protobufGraphQLExtensions(type),
5751
})
5852
)}
5953
);

0 commit comments

Comments
 (0)