Skip to content

Commit

Permalink
normalize-name-in-interface-and-type-alias (#2483)
Browse files Browse the repository at this point in the history
* normalize-name-in-interface-and-type-alias

* fix main

* fix alias

* fix ci

* fix ci

* unify rlc enum and union name

* Update packages/typespec-ts/test/modularUnit/enumUnion.spec.ts

Co-authored-by: Mary Gao <yanmeigao1210@gmail.com>

---------

Co-authored-by: Mary Gao <yanmeigao1210@gmail.com>
  • Loading branch information
qiaozha and MaryGao authored Apr 29, 2024
1 parent 09685d1 commit 0362739
Show file tree
Hide file tree
Showing 13 changed files with 158 additions and 52 deletions.
20 changes: 14 additions & 6 deletions packages/typespec-ts/src/modular/buildCodeModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ function processModelProperties(
// because it's impossible to have a anonymous model as the polymorphic base in typespec
// the only possibility is the anonymous model is an alias for an union type which has already been taken care of in the combined types.
if (newValue.name) {
newValue.name = normalizeName(newValue.name, NameType.Interface);
discriminatorInfo?.aliases.push(`${newValue.name}`);
newValue.alias = `${newValue.name}`;
newValue.name = `${newValue.name}Union`;
Expand Down Expand Up @@ -1108,9 +1109,10 @@ function emitEnum(context: SdkContext, type: Enum): Record<string, any> {

return {
type: "enum",
name: getLibraryName(context, type)
? getLibraryName(context, type)
: type.name,
name: normalizeName(
getLibraryName(context, type) ? getLibraryName(context, type) : type.name,
NameType.Interface
),
description: getDocStr(program, type),
valueType: { type: enumMemberType(type.members.values().next().value) },
values: enumValues,
Expand Down Expand Up @@ -1399,10 +1401,13 @@ function emitUnion(
}
return valueType;
});
const unionTypeName = unionName
? normalizeName(unionName, NameType.Interface)
: undefined;
return {
nullable: sdkType.nullable,
name: unionName,
description: `Type of ${unionName}`,
name: unionTypeName,
description: `Type of ${unionTypeName}`,
internal: true,
type: "combined",
types: variantTypes,
Expand All @@ -1417,11 +1422,14 @@ function emitUnion(
: variantTypes.map((x) => getTypeName(x).name).join(" | ")
};
} else if (sdkType.kind === "enum") {
const typeName = getLibraryName(context, type)
let typeName = getLibraryName(context, type)
? getLibraryName(context, type)
: sdkType.isGeneratedName
? type.name
: sdkType.name;
typeName = typeName
? normalizeName(typeName, NameType.Interface)
: undefined;
return {
name: typeName,
nullable: sdkType.nullable,
Expand Down
13 changes: 8 additions & 5 deletions packages/typespec-ts/src/utils/modelUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -401,10 +401,13 @@ function getSchemaForUnion(
.map((item) => `${getTypeName(item, [SchemaContext.Output]) ?? item}`)
.join(" | ");
if (!union.expression) {
schema.name = union.name;
const unionName = union.name
? normalizeName(union.name, NameType.Interface)
: undefined;
schema.name = unionName;
schema.type = "object";
schema.typeName = union.name;
schema.outputTypeName = union.name + "Output";
schema.typeName = unionName;
schema.outputTypeName = unionName + "Output";
schema.alias = unionAlias;
schema.outputAlias = outputUnionAlias;
} else if (union.expression && !union.name) {
Expand Down Expand Up @@ -938,8 +941,8 @@ function getSchemaForEnum(dpgContext: SdkContext, e: Enum) {
const schema: any = {
type: "object",
name: e.name,
typeName: e.name,
outputTypeName: e.name + "Output",
typeName: normalizeName(e.name, NameType.Interface),
outputTypeName: normalizeName(e.name, NameType.Interface) + "Output",
description: getDoc(dpgContext.program, e),
memberType: type
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ export interface RequestRegisterCC extends CommonRegistrationRequest {
}

export interface CommonRegistrationRequest {
payMethod: PAYMENT_METHODS;
payMethod: PaymentMethods;
}

export interface RequestRegisterVA {
prop: string;
}

/** Alias for PAYMENT_METHODS */
export type PAYMENT_METHODS = "01";
/** Alias for PaymentMethods */
export type PaymentMethods = "01";
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ export interface RequestRegisterCCOutput
}

export interface CommonRegistrationRequestOutput {
payMethod: PAYMENT_METHODSOutput;
payMethod: PaymentMethodsOutput;
}

export interface RequestRegisterVAOutput {
prop: string;
}

/** Alias for PAYMENT_METHODSOutput */
export type PAYMENT_METHODSOutput = "01";
/** Alias for PaymentMethodsOutput */
export type PaymentMethodsOutput = "01";
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export interface Dog {

export interface EnumsOnlyCases {
/** This should be receive/send the left variant */
lr: LR | UD;
lr: Lr | Ud;
/** This should be receive/send the up variant */
ud: UD | UD;
ud: Ud | Ud;
}

export interface StringAndArrayCases {
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface MixedTypesCases {

/** Alias for StringExtensibleNamedUnion */
export type StringExtensibleNamedUnion = string | "b" | "c";
/** Alias for LR */
export type LR = "left" | "right";
/** Alias for UD */
export type UD = "up" | "down";
/** Alias for Lr */
export type Lr = "left" | "right";
/** Alias for Ud */
export type Ud = "up" | "down";
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export interface DogOutput {

export interface EnumsOnlyCasesOutput {
/** This should be receive/send the left variant */
lr: LROutput | UDOutput;
lr: LrOutput | UdOutput;
/** This should be receive/send the up variant */
ud: UDOutput | UDOutput;
ud: UdOutput | UdOutput;
}

export interface StringAndArrayCasesOutput {
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface MixedTypesCasesOutput {

/** Alias for StringExtensibleNamedUnionOutput */
export type StringExtensibleNamedUnionOutput = string | "b" | "c";
/** Alias for LROutput */
export type LROutput = "left" | "right";
/** Alias for UDOutput */
export type UDOutput = "up" | "down";
/** Alias for LrOutput */
export type LrOutput = "left" | "right";
/** Alias for UdOutput */
export type UdOutput = "up" | "down";
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ export {
MixedLiteralsCases,
StringAndArrayCases,
EnumsOnlyCases,
LR,
UD,
Lr,
Ud,
Dog,
StringExtensibleNamedUnion,
StringsOnlyGetOptionalParams,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export {
MixedLiteralsCases,
StringAndArrayCases,
EnumsOnlyCases,
LR,
UD,
Lr,
Ud,
Dog,
StringExtensibleNamedUnion,
} from "./models.js";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,15 @@ export interface StringAndArrayCases {

export interface EnumsOnlyCases {
/** This should be receive/send the left variant */
lr: LR | UD;
lr: Lr | Ud;
/** This should be receive/send the up variant */
ud: UD | UD;
ud: Ud | Ud;
}

/** */
export type LR = "left" | "right";
export type Lr = "left" | "right";
/** */
export type UD = "up" | "down";
export type Ud = "up" | "down";

export interface Dog {
bark: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export interface Dog {

export interface EnumsOnlyCases {
/** This should be receive/send the left variant */
lr: LR | UD;
lr: Lr | Ud;
/** This should be receive/send the up variant */
ud: UD | UD;
ud: Ud | Ud;
}

export interface StringAndArrayCases {
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface MixedTypesCases {

/** Alias for StringExtensibleNamedUnion */
export type StringExtensibleNamedUnion = string | "b" | "c";
/** Alias for LR */
export type LR = "left" | "right";
/** Alias for UD */
export type UD = "up" | "down";
/** Alias for Lr */
export type Lr = "left" | "right";
/** Alias for Ud */
export type Ud = "up" | "down";
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export interface DogOutput {

export interface EnumsOnlyCasesOutput {
/** This should be receive/send the left variant */
lr: LROutput | UDOutput;
lr: LrOutput | UdOutput;
/** This should be receive/send the up variant */
ud: UDOutput | UDOutput;
ud: UdOutput | UdOutput;
}

export interface StringAndArrayCasesOutput {
Expand Down Expand Up @@ -47,7 +47,7 @@ export interface MixedTypesCasesOutput {

/** Alias for StringExtensibleNamedUnionOutput */
export type StringExtensibleNamedUnionOutput = string | "b" | "c";
/** Alias for LROutput */
export type LROutput = "left" | "right";
/** Alias for UDOutput */
export type UDOutput = "up" | "down";
/** Alias for LrOutput */
export type LrOutput = "left" | "right";
/** Alias for UdOutput */
export type UdOutput = "up" | "down";
37 changes: 34 additions & 3 deletions packages/typespec-ts/test/modularUnit/enumUnion.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -842,17 +842,48 @@ describe("model type", () => {
modelFile!.getFullText()!,
`
export interface Test {
color: LR | UD;
color: Lr | Ud;
}
/** */
export type LR = "left" | "right";
export type Lr = "left" | "right";
/** */
export type UD = "up" | "down";
export type Ud = "up" | "down";
`
);
});
it("non-standard enum/union name", async () => {
const modelFile = await emitModularModelsFromTypeSpec(`
union leftAndRight {
"left",
"right",
}
enum upAndDown {
up,
down,
}
model Test {
color: leftAndRight | upAndDown;
}
op read(@body body: Test): void;
`);
assert.ok(modelFile);
await assertEqualContent(
modelFile!.getFullText()!,
`
export interface Test {
color: LeftAndRight | UpAndDown;
}
/** Type of LeftAndRight */
/** */
export type LeftAndRight = "left" | "right";
/** */
export type UpAndDown = "up" | "down";
`
);
});
it("nullable numeric literal", async () => {
const modelFile = await emitModularModelsFromTypeSpec(`
model Test {
Expand Down
64 changes: 64 additions & 0 deletions packages/typespec-ts/test/unit/modelsGenerator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,49 @@ describe("Input/output model type", () => {
export type TranslationLanguageValuesOutput = "English" | "Chinese";`
);
});
it("should handle enum with non-standard name as property -> type alias with union", async () => {
const schemaOutput = await emitModelsFromTypeSpec(`
@doc("Extensible enum model description")
enum translationLanguageValues {
#suppress "@azure-tools/typespec-azure-core/documentation-required" "for test"
English,
#suppress "@azure-tools/typespec-azure-core/documentation-required" "for test"
Chinese,
}
model InputOutputModel {
@doc("Property description")
prop: translationLanguageValues;
}
@route("/models")
@get
op getModel(@body input: InputOutputModel): InputOutputModel;
`);
assert.ok(schemaOutput);
const { inputModelFile, outputModelFile } = schemaOutput!;
await assertEqualContent(
inputModelFile?.content!,
`
export interface InputOutputModel {
/** Property description */
prop: TranslationLanguageValues;
}
/** Extensible enum model description */
export type TranslationLanguageValues = "English" | "Chinese";
`
);
await assertEqualContent(
outputModelFile?.content!,
`
export interface InputOutputModelOutput {
/** Property description */
prop: TranslationLanguageValuesOutput;
}
/** Extensible enum model description */
export type TranslationLanguageValuesOutput = "English" | "Chinese";`
);
});
it("should handle enum as body -> type alias with union", async () => {
const schemaOutput = await emitParameterFromTypeSpec(`
#suppress "@azure-tools/typespec-azure-core/documentation-required" "for test"
Expand Down Expand Up @@ -2282,6 +2325,27 @@ describe("Input/output model type", () => {
});
});

it("union with non-standard name whose variants are pure primitive types", async () => {
const tspDefinition = `
union myNamedUnion {
one: string,
two: int32,
}
`;
const tspType = "myNamedUnion | null";
const inputModelName = "MyNamedUnion | null";
await verifyPropertyType(tspType, inputModelName, {
additionalTypeSpecDefinition: tspDefinition,
outputType: `MyNamedUnionOutput | null`,
additionalInputContent: `
/** Alias for MyNamedUnion */
export type MyNamedUnion = string | number;`,
additionalOutputContent: `
/** Alias for MyNamedUnionOutput */
export type MyNamedUnionOutput = string | number;`
});
});

it("union variants are pure constants", async () => {
const tspDefinition = `
union StringExtensibleNamedUnion {
Expand Down

0 comments on commit 0362739

Please sign in to comment.