From 476e99bcbc651cec1946d0dbad09dc9aea3224ff Mon Sep 17 00:00:00 2001 From: Gavin Mogan Date: Tue, 15 Oct 2024 11:03:42 -0700 Subject: [PATCH] fix: Unbreak a use case for #1110 / fix for #1121 (#1123) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Function" is builtin, but anything prefixed or suffixed for whatever reason shouldn't be handled the same way. So check if the final result is in builtin list, not the original unmodified name I have concerns about maybeSnakeToCamel being called earlier now, but i can't find any tests for options.snakeToCamel.includes("keys") so i'm not sure if i broke anything ``` /** Converts `key` to TS/JS camel-case idiom, unless overridden not to. */ đź’ˇexport function maybeSnakeToCamel(key: string, options: Pick): string { if (options.snakeToCamel.includes("keys") && key.includes("_")) { return snakeToCamel(key); } else { return key; } } ``` But all tests pass --- integration/test-1110/test-1110-test.ts | 7 +- integration/test-1110/test-1110.proto | 7 ++ integration/test-1110/test-1110.ts | 127 ++++++++++++++++++++++++ src/visit.ts | 9 +- 4 files changed, 144 insertions(+), 6 deletions(-) diff --git a/integration/test-1110/test-1110-test.ts b/integration/test-1110/test-1110-test.ts index b1991f3f2..39b934d42 100644 --- a/integration/test-1110/test-1110-test.ts +++ b/integration/test-1110/test-1110-test.ts @@ -1,8 +1,13 @@ -import { UserRule } from "./test-1110"; +import { UserRule, Nested_Function } from "./test-1110"; describe("test-1110", () => { it("Able to create a partial user rule with reserved word messages", () => { const simple: UserRule = UserRule.fromPartial({ UUID: "foo" }); expect(simple).toBeTruthy(); }); + + it("built in handling should only be done to top level", () => { + const nestedFunction: Nested_Function = Nested_Function.fromPartial({}); + expect(nestedFunction).toBeTruthy(); + }); }); diff --git a/integration/test-1110/test-1110.proto b/integration/test-1110/test-1110.proto index ee5b6ae82..53d4c4fcb 100644 --- a/integration/test-1110/test-1110.proto +++ b/integration/test-1110/test-1110.proto @@ -25,5 +25,12 @@ message Function { string name = 2; } +message Nested { + message Function { + string namespace = 1; + string name = 2; + } +} + service APIService { } diff --git a/integration/test-1110/test-1110.ts b/integration/test-1110/test-1110.ts index 51c2baa1e..9d5e3f807 100644 --- a/integration/test-1110/test-1110.ts +++ b/integration/test-1110/test-1110.ts @@ -31,6 +31,14 @@ export interface FunctionMessage { name: string; } +export interface Nested { +} + +export interface Nested_Function { + namespace: string; + name: string; +} + function createBaseUserRule(): UserRule { return { UUID: "" }; } @@ -393,6 +401,125 @@ export const FunctionMessage: MessageFns = { }, }; +function createBaseNested(): Nested { + return {}; +} + +export const Nested: MessageFns = { + encode(_: Nested, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Nested { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNested(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(_: any): Nested { + return {}; + }, + + toJSON(_: Nested): unknown { + const obj: any = {}; + return obj; + }, + + create(base?: DeepPartial): Nested { + return Nested.fromPartial(base ?? {}); + }, + fromPartial(_: DeepPartial): Nested { + const message = createBaseNested(); + return message; + }, +}; + +function createBaseNested_Function(): Nested_Function { + return { namespace: "", name: "" }; +} + +export const Nested_Function: MessageFns = { + encode(message: Nested_Function, writer: BinaryWriter = new BinaryWriter()): BinaryWriter { + if (message.namespace !== "") { + writer.uint32(10).string(message.namespace); + } + if (message.name !== "") { + writer.uint32(18).string(message.name); + } + return writer; + }, + + decode(input: BinaryReader | Uint8Array, length?: number): Nested_Function { + const reader = input instanceof BinaryReader ? input : new BinaryReader(input); + let end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseNested_Function(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: { + if (tag !== 10) { + break; + } + + message.namespace = reader.string(); + continue; + } + case 2: { + if (tag !== 18) { + break; + } + + message.name = reader.string(); + continue; + } + } + if ((tag & 7) === 4 || tag === 0) { + break; + } + reader.skip(tag & 7); + } + return message; + }, + + fromJSON(object: any): Nested_Function { + return { + namespace: isSet(object.namespace) ? globalThis.String(object.namespace) : "", + name: isSet(object.name) ? globalThis.String(object.name) : "", + }; + }, + + toJSON(message: Nested_Function): unknown { + const obj: any = {}; + if (message.namespace !== "") { + obj.namespace = message.namespace; + } + if (message.name !== "") { + obj.name = message.name; + } + return obj; + }, + + create(base?: DeepPartial): Nested_Function { + return Nested_Function.fromPartial(base ?? {}); + }, + fromPartial(object: DeepPartial): Nested_Function { + const message = createBaseNested_Function(); + message.namespace = object.namespace ?? ""; + message.name = object.name ?? ""; + return message; + }, +}; + export interface APIService { } diff --git a/src/visit.ts b/src/visit.ts index a4f3f9730..36a0174ba 100644 --- a/src/visit.ts +++ b/src/visit.ts @@ -39,7 +39,7 @@ export function visit( const protoFullName = protoPrefix + enumDesc.name; // I.e. FooBar_ZazInner const tsFullName = tsPrefix + maybeSnakeToCamel(enumDesc.name, options); - const tsFullNameWithAffixes = `${options.typePrefix}${tsFullName}${options.typeSuffix}`; + const tsFullNameWithAffixes = messageName(`${options.typePrefix}${tsFullName}${options.typeSuffix}`); const nestedSourceInfo = sourceInfo.open(childEnumType, index); enumFn(tsFullNameWithAffixes, enumDesc, nestedSourceInfo, protoFullName); }); @@ -51,8 +51,8 @@ export function visit( // I.e. Foo_Bar.Zaz_Inner const protoFullName = protoPrefix + message.name; // I.e. FooBar_ZazInner - const tsFullName = tsPrefix + maybeSnakeToCamel(messageName(message), options); - const tsFullNameWithAffixes = `${options.typePrefix}${tsFullName}${options.typeSuffix}`; + const tsFullName = tsPrefix + maybeSnakeToCamel(message.name, options); + const tsFullNameWithAffixes = messageName(`${options.typePrefix}${tsFullName}${options.typeSuffix}`); const nestedSourceInfo = sourceInfo.open(childType, index); messageFn(tsFullNameWithAffixes, message, nestedSourceInfo, protoFullName); const delim = options.useSnakeTypeName ? "_" : ""; @@ -63,8 +63,7 @@ export function visit( const builtInNames = ["Date", "Function"]; /** Potentially suffixes `Message` to names to avoid conflicts, i.e. with `Date`. */ -function messageName(message: DescriptorProto): string { - const { name } = message; +function messageName(name: string): string { return builtInNames.includes(name) ? `${name}Message` : name; }