diff --git a/generators/typescript/sdk/client-class-generator/src/request-parameter/FileUploadRequestParameter.ts b/generators/typescript/sdk/client-class-generator/src/request-parameter/FileUploadRequestParameter.ts index 814990ead906..f29808ebee6d 100644 --- a/generators/typescript/sdk/client-class-generator/src/request-parameter/FileUploadRequestParameter.ts +++ b/generators/typescript/sdk/client-class-generator/src/request-parameter/FileUploadRequestParameter.ts @@ -1,5 +1,5 @@ import { ExampleEndpointCall, HttpHeader, InlinedRequestBodyProperty, QueryParameter } from "@fern-fern/ir-sdk/api"; -import { GetReferenceOpts } from "@fern-typescript/commons"; +import { GetReferenceOpts, isValidIdentifier } from "@fern-typescript/commons"; import { GeneratedRequestWrapper, SdkContext } from "@fern-typescript/contexts"; import { ts } from "ts-morph"; @@ -111,9 +111,13 @@ export class FileUploadRequestParameter extends AbstractRequestParameter { } private getReferenceToProperty(propertyName: string): ts.Expression { - return ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier(this.getRequestParameterName()), - propertyName - ); + const requestIdentifier = ts.factory.createIdentifier(this.getRequestParameterName()); + if (!isValidIdentifier(propertyName)) { + return ts.factory.createElementAccessExpression( + requestIdentifier, + ts.factory.createStringLiteral(propertyName) + ); + } + return ts.factory.createPropertyAccessExpression(requestIdentifier, propertyName); } } diff --git a/generators/typescript/sdk/versions.yml b/generators/typescript/sdk/versions.yml index 74863357dbf4..fd10b2a3929b 100644 --- a/generators/typescript/sdk/versions.yml +++ b/generators/typescript/sdk/versions.yml @@ -1,4 +1,14 @@ # yaml-language-server: $schema=../../../fern-versions-yml.schema.json +- version: 3.38.4 + changelogEntry: + - summary: | + Fix file upload request parameters to use bracket notation for property names that are not valid JavaScript identifiers (e.g., header names with hyphens like `X-Custom-Header`). + Previously, the generator produced invalid JavaScript like `request.X - Custom - Header` which was interpreted as subtraction operations. + Now it correctly generates `request["X-Custom-Header"]`. + type: fix + createdAt: "2025-12-10" + irVersion: 62 + - version: 3.38.3 changelogEntry: - summary: | diff --git a/generators/typescript/utils/commons/src/codegen-utils/getPropertyKey.ts b/generators/typescript/utils/commons/src/codegen-utils/getPropertyKey.ts index 55358697fc74..34b5f50816d9 100644 --- a/generators/typescript/utils/commons/src/codegen-utils/getPropertyKey.ts +++ b/generators/typescript/utils/commons/src/codegen-utils/getPropertyKey.ts @@ -1,5 +1,13 @@ import esutils from "esutils"; +/** + * Checks if a string is a valid JavaScript/TypeScript identifier name. + * This can be used to determine whether to use dot notation (obj.prop) or bracket notation (obj["prop"]). + */ +export function isValidIdentifier(name: string): boolean { + return esutils.keyword.isIdentifierNameES6(name); +} + export function getPropertyKey(key: string): string { // [key: string]: any; => [key: string]: any; if (key.startsWith("[") && key.endsWith("]")) { diff --git a/generators/typescript/utils/commons/src/index.ts b/generators/typescript/utils/commons/src/index.ts index e0bd50858eb2..8a9cd783d0ad 100644 --- a/generators/typescript/utils/commons/src/index.ts +++ b/generators/typescript/utils/commons/src/index.ts @@ -9,7 +9,7 @@ export { getParameterNameForRootExamplePathParameter, getParameterNameForRootPathParameter } from "./codegen-utils/getParameterNameForPathParameter"; -export { getPropertyKey } from "./codegen-utils/getPropertyKey"; +export { getPropertyKey, isValidIdentifier } from "./codegen-utils/getPropertyKey"; export { getSchemaOptions } from "./codegen-utils/getSchemaOptions"; export { getSdkParameterPropertyName } from "./codegen-utils/getSdkParameterPropertyName"; export { getTextOfTsKeyword } from "./codegen-utils/getTextOfTsKeyword";