Skip to content

Commit

Permalink
feat: merge outputSchemaAsConst flag into outputSchema flag
Browse files Browse the repository at this point in the history
  • Loading branch information
cmd-johnson committed Sep 4, 2024
1 parent ba318c7 commit ffd4fd4
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 11 deletions.
6 changes: 4 additions & 2 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -454,9 +454,11 @@ Generated code will be placed in the Gradle build directory.

- With `--ts_proto_opt=annotateFilesWithVersion=false`, the generated files will not contain the versions of `protoc` and `ts-proto` used to generate the file. This option is normally set to `true`, such that files list the versions used.

- With `--ts_proto_opt=outputSchema=true`, meta typings will be generated that can later be used in other code generators. If outputSchema is instead specified to be `no-file-descriptor` then we do not include the file descriptor in the generated schema. This is useful if you are trying to minimize the size of the generated schema.
- With `--ts_proto_opt=outputSchema=true`, meta typings will be generated that can later be used in other code generators.

- With `--ts_proto_opt=outputSchemaAsConst=true`, the `protoMetadata` export of `outputSchema=true` is declared using `as const` and `satisfies` (supported by TypeScript since [4.9](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator)), providing more detailed type information.
- With `--ts_proto_opt=outputSchema=no-file-descriptor`, meta typings will be generated, but we do not include the file descriptor in the generated schema. This is useful if you are trying to minimize the size of the generated schema.

- With `--ts_proto_opt=outputSchema=const`, meta typings will be generated `as const`, allowing type-safe access to all its properties. (only works with TypeScript 4.9 and up, because it also uses the [`satisfies`](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator) operator). Can be combined with the `no-file-descriptor` option (`outputSchema=const,outputSchema=no-file-descriptor`) to not include the file descriptor in the generated schema.

- With `--ts_proto_opt=outputTypeAnnotations=true`, each message will be given a `$type` field containing its fully-qualified name. You can use `--ts_proto_opt=outputTypeAnnotations=static-only` to omit it from the `interface` declaration, or `--ts_proto_opt=outputTypeAnnotations=optional` to make it an optional property on the `interface` definition. The latter option may be useful if you want to use the `$type` field for runtime type checking on responses from a server.

Expand Down
2 changes: 1 addition & 1 deletion integration/meta-typings-as-const/parameters.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
outputJsonMethods=false,outputPartialMethods=false,outputClientImpl=true,outputSchema=true,outputSchemaAsConst=true
outputJsonMethods=false,outputPartialMethods=false,outputClientImpl=true,outputSchema=const
18 changes: 15 additions & 3 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,12 @@ export enum ServiceOption {
NONE = "none",
}

export enum OutputSchemaOption {
TRUE = "true",
NO_FILE_DESCRIPTOR = "no-file-descriptor",
CONST = "const",
}

export type Options = {
context: boolean;
snakeToCamel: Array<"json" | "keys">;
Expand Down Expand Up @@ -76,8 +82,7 @@ export type Options = {
unrecognizedEnumName: string;
unrecognizedEnumValue: number;
exportCommonSymbols: boolean;
outputSchema: boolean | "no-file-descriptor";
outputSchemaAsConst: boolean;
outputSchema: false | OutputSchemaOption[];
onlyTypes: boolean;
emitImportedFiles: boolean;
useAbortSignal: boolean;
Expand Down Expand Up @@ -148,7 +153,6 @@ export function defaultOptions(): Options {
unrecognizedEnumValue: -1,
exportCommonSymbols: true,
outputSchema: false,
outputSchemaAsConst: false,
onlyTypes: false,
emitImportedFiles: true,
useExactTypes: true,
Expand Down Expand Up @@ -238,6 +242,14 @@ export function optionsFromParameter(parameter: string | undefined): Options {
options.outputEncodeMethods = true;
}

// Handle outputSchema=true
if ((options.outputSchema as any) === true) {
options.outputSchema = []
}
if (typeof options.outputSchema === "string") {
options.outputSchema = [options.outputSchema]
}

if ((options.useDate as any) === true) {
// Treat useDate=true as DATE
options.useDate = DateOption.DATE;
Expand Down
13 changes: 9 additions & 4 deletions src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import SourceInfo from "./sourceInfo";
import { impFile, maybePrefixPackage } from "./utils";
import { basicTypeName, toReaderCall } from "./types";
import { BinaryReader } from "@bufbuild/protobuf/wire";
import { OutputSchemaOption } from "./options";

const fileDescriptorProto = imp("FileDescriptorProto@ts-proto-descriptors");

Expand All @@ -27,6 +28,10 @@ export function generateSchema(ctx: Context, fileDesc: FileDescriptorProto, sour
extensionCache[extension.extendee][extension.number] = extension;
});

const outputSchemaOptions = ctx.options.outputSchema ? ctx.options.outputSchema : [];
const outputFileDescriptor = !outputSchemaOptions.includes(OutputSchemaOption.NO_FILE_DESCRIPTOR);
const outputAsConst = outputSchemaOptions.includes(OutputSchemaOption.CONST);

chunks.push(code`
type ProtoMetaMessageOptions = {
options?: { [key: string]: any };
Expand All @@ -37,7 +42,7 @@ export function generateSchema(ctx: Context, fileDesc: FileDescriptorProto, sour
export interface ProtoMetadata {
${
ctx.options.outputSchema !== "no-file-descriptor" ? code`fileDescriptor: ${fileDescriptorProto};\n` : ""
outputFileDescriptor ? code`fileDescriptor: ${fileDescriptorProto};\n` : ""
}references: { [key: string]: any };
dependencies?: ProtoMetadata[];
options?: {
Expand Down Expand Up @@ -181,9 +186,9 @@ export function generateSchema(ctx: Context, fileDesc: FileDescriptorProto, sour
});

chunks.push(code`
export const ${def("protoMetadata")}${options.outputSchemaAsConst ? "" : ": ProtoMetadata"} = {
export const ${def("protoMetadata")}${outputAsConst ? "" : ": ProtoMetadata"} = {
${
ctx.options.outputSchema !== "no-file-descriptor" ? code`fileDescriptor: ${descriptor},\n` : ""
outputFileDescriptor ? code`fileDescriptor: ${descriptor},\n` : ""
}references: { ${joinCode(references, { on: "," })} },
dependencies: [${joinCode(dependencies, { on: "," })}],
${
Expand All @@ -196,7 +201,7 @@ export function generateSchema(ctx: Context, fileDesc: FileDescriptorProto, sour
}`
: ""
}
}${options.outputSchemaAsConst ? " as const satisfies ProtoMetadata" : ""}
}${outputAsConst ? " as const satisfies ProtoMetadata" : ""}
`);

return chunks;
Expand Down
1 change: 0 additions & 1 deletion tests/options-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ describe("options", () => {
"outputJsonMethods": true,
"outputPartialMethods": false,
"outputSchema": false,
"outputSchemaAsConst": false,
"outputServices": [],
"outputTypeAnnotations": false,
"outputTypeRegistry": false,
Expand Down

0 comments on commit ffd4fd4

Please sign in to comment.