Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion packages/typespec-ts/src/modular/helpers/typeHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ const simpleTypeMap: Record<string, TypeMetadata> = {
unknown: { name: "any" }
};

function handleSimpleType(
type: Type,
format?: string
): TypeMetadata | undefined {
if (type.type === "integer") {
// Treat integer as number if format is specified as string
Comment thread
MaryGao marked this conversation as resolved.
Outdated
return format === "string" ? { name: "string" } : { name: "number" };
}
return simpleTypeMap[type.type];
}

function handleAnomymousModelName(type: Type) {
let retVal = `{`;
for (const prop of type.properties ?? []) {
Expand Down Expand Up @@ -73,7 +84,7 @@ function handleNullableTypeName(type: {
*/
export function getType(type: Type, format?: string): TypeMetadata {
// Handle simple type conversions
const simpleType = simpleTypeMap[type.type];
const simpleType = handleSimpleType(type, format);
if (simpleType) {
const typeMetadata: TypeMetadata = { ...simpleType };
if (isTypeNullable(type)) {
Expand Down
8 changes: 8 additions & 0 deletions packages/typespec-ts/test/commands/cadl-ranch-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,10 @@ export const rlcTsps = [
{
outputPath: "client/structure/client-operation-group",
inputPath: "client/structure/client-operation-group"
},
{
outputPath: "encode/numeric",
inputPath: "encode/numeric"
}
];

Expand Down Expand Up @@ -562,6 +566,10 @@ export const modularTsps = [
{
outputPath: "client/structure/client-operation-group",
inputPath: "client/structure/client-operation-group"
},
{
outputPath: "encode/numeric",
inputPath: "encode/numeric"
}
];

Expand Down
47 changes: 47 additions & 0 deletions packages/typespec-ts/test/integration/encodeNumeric.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { assert } from "chai";
import EncodeNumericClientFactory, {
NumericClient
} from "./generated/encode/numeric/src/index.js";
describe("EncodeNumericClient Rest Client", () => {
let client: NumericClient;

beforeEach(() => {
client = EncodeNumericClientFactory({
allowInsecureConnection: true
});
});

describe("property", () => {
it(`should post safeint property`, async () => {
const result = await client
.path(`/encode/numeric/property/safeint`)
.post({
body: {
value: "10000000000"
}
});
assert.strictEqual(result.status, "200");
assert.strictEqual(result.body.value, "10000000000");
});

it(`should post uint32 property`, async () => {
const result = await client.path(`/encode/numeric/property/uint32`).post({
body: {
value: "1"
}
});
assert.strictEqual(result.status, "200");
assert.strictEqual(result.body.value, "1");
});

it(`should post uint8 property`, async () => {
const result = await client.path(`/encode/numeric/property/uint8`).post({
body: {
value: "255"
}
});
assert.strictEqual(result.status, "200");
assert.strictEqual(result.body.value, "255");
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
!/src
/src/**
!/src/index.d.ts
!/.gitignore
!/tspconfig.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Client } from '@azure-rest/core-client';
import { ClientOptions } from '@azure-rest/core-client';
import { HttpResponse } from '@azure-rest/core-client';
import { RequestParameters } from '@azure-rest/core-client';
import { StreamableMethod } from '@azure-rest/core-client';

declare function createClient(options?: NumericClientOptions): NumericClient;
export default createClient;

export declare type NumericClient = Client & {
path: Routes;
};

export declare interface NumericClientOptions extends ClientOptions {
}

export declare interface PropertySafeintAsString200Response extends HttpResponse {
status: "200";
body: SafeintAsStringPropertyOutput;
}

export declare interface PropertySafeintAsStringBodyParam {
body: SafeintAsStringProperty;
}

export declare type PropertySafeintAsStringParameters = PropertySafeintAsStringBodyParam & RequestParameters;

export declare interface PropertyUint32AsStringOptional200Response extends HttpResponse {
status: "200";
body: Uint32AsStringPropertyOutput;
}

export declare interface PropertyUint32AsStringOptionalBodyParam {
body: Uint32AsStringProperty;
}

export declare type PropertyUint32AsStringOptionalParameters = PropertyUint32AsStringOptionalBodyParam & RequestParameters;

export declare interface PropertyUint8AsString200Response extends HttpResponse {
status: "200";
body: Uint8AsStringPropertyOutput;
}

export declare interface PropertyUint8AsStringBodyParam {
body: Uint8AsStringProperty;
}

export declare type PropertyUint8AsStringParameters = PropertyUint8AsStringBodyParam & RequestParameters;

export declare interface Routes {
(path: "/encode/numeric/property/safeint"): SafeintAsString;
(path: "/encode/numeric/property/uint32"): Uint32AsStringOptional;
(path: "/encode/numeric/property/uint8"): Uint8AsString;
}

export declare interface SafeintAsString {
post(options: PropertySafeintAsStringParameters): StreamableMethod<PropertySafeintAsString200Response>;
}

export declare interface SafeintAsStringProperty {
value: string;
}

export declare interface SafeintAsStringPropertyOutput {
value: string;
}

export declare interface Uint32AsStringOptional {
post(options: PropertyUint32AsStringOptionalParameters): StreamableMethod<PropertyUint32AsStringOptional200Response>;
}

export declare interface Uint32AsStringProperty {
value?: string;
}

export declare interface Uint32AsStringPropertyOutput {
value?: string;
}

export declare interface Uint8AsString {
post(options: PropertyUint8AsStringParameters): StreamableMethod<PropertyUint8AsString200Response>;
}

export declare interface Uint8AsStringProperty {
value: string;
}

export declare interface Uint8AsStringPropertyOutput {
value: string;
}

export { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
emit:
- "@azure-tools/typespec-ts"
options:
"@azure-tools/typespec-ts":
"emitter-output-dir": "{project-root}"
generateMetadata: true
addCredentials: false
azureSdkForJs: false
isTypeSpecTest: true
enableOperationGroup: true
packageDetails:
name: "@msinternal/encode-numeric"
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { assert } from "chai";
import { NumericClient } from "./generated/encode/numeric/src/index.js";
describe("EncodeNumericClient Rest Client", () => {
let client: NumericClient;

beforeEach(() => {
client = new NumericClient({
endpoint: "http://localhost:3002",
allowInsecureConnection: true,
retryOptions: {
maxRetries: 0
}
});
});

describe("query", () => {
it(`should get safeint numeric`, async () => {
const result = await client.property.safeintAsString({
value: "10000000000"
});
console.log(result);
assert.strictEqual(result.value, "10000000000");
});

it(`should get uint32 numeric`, async () => {
const result = await client.property.uint32AsStringOptional({
value: "1"
});
assert.strictEqual(result.value, "1");
});

it(`should get uint8 numeric`, async () => {
const result = await client.property.uint8AsString({ value: "255" });
assert.strictEqual(result.value, "255");
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
!/src
/src/**
!/src/index.d.ts
!/.gitignore
!/tspconfig.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { ClientOptions } from '@azure-rest/core-client';
import { OperationOptions } from '@azure-rest/core-client';
import { Pipeline } from '@azure/core-rest-pipeline';

export declare class NumericClient {
private _client;
readonly pipeline: Pipeline;
constructor(options?: NumericClientOptionalParams);
readonly property: PropertyOperations;
}

export declare interface NumericClientOptionalParams extends ClientOptions {
}

export declare interface PropertyOperations {
safeintAsString: (value: SafeintAsStringProperty, options?: PropertySafeintAsStringOptionalParams) => Promise<SafeintAsStringProperty>;
uint32AsStringOptional: (value: Uint32AsStringProperty, options?: PropertyUint32AsStringOptionalOptionalParams) => Promise<Uint32AsStringProperty>;
uint8AsString: (value: Uint8AsStringProperty, options?: PropertyUint8AsStringOptionalParams) => Promise<Uint8AsStringProperty>;
}

export declare interface PropertySafeintAsStringOptionalParams extends OperationOptions {
}

export declare interface PropertyUint32AsStringOptionalOptionalParams extends OperationOptions {
}

export declare interface PropertyUint8AsStringOptionalParams extends OperationOptions {
}

export declare interface SafeintAsStringProperty {
value: number;
}

export declare interface Uint32AsStringProperty {
value?: number;
}

export declare interface Uint8AsStringProperty {
value: number;
}

export { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
emit:
- "@azure-tools/typespec-ts"
options:
"@azure-tools/typespec-ts":
"emitter-output-dir": "{project-root}"
generateMetadata: true
generateTest: false
addCredentials: false
azureSdkForJs: false
isTypeSpecTest: true
enableOperationGroup: true
isModularLibrary: true
hierarchyClient: false
packageDetails:
name: "@msinternal/encode-numeric"
42 changes: 39 additions & 3 deletions packages/typespec-ts/test/modularUnit/modelsGenerator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ describe("model property type", () => {
});
});


it("should handle boolean literal type", async () => {
const tspContent = `
@doc("The configuration for a streaming chat completion request.")
Expand All @@ -121,8 +120,7 @@ describe("model property type", () => {
...StreamingChatCompletionOptions
): void;
`;
const operationFiles =
await emitModularOperationsFromTypeSpec(tspContent);
const operationFiles = await emitModularOperationsFromTypeSpec(tspContent);
assert.ok(operationFiles);
assert.equal(operationFiles?.length, 1);
await assertEqualContent(
Expand Down Expand Up @@ -2158,3 +2156,41 @@ describe("spread record", () => {
);
});
});

describe("@encode", () => {
it("should take numeric as string for @encode as string", async () => {
const tspContent = `
model Foo {
@encode("string")
prop1: int32;
@encode("string")
prop2: decimal;
}
op post(@body body: Foo): { @body body: Foo };`;

const modelFile = await emitModularModelsFromTypeSpec(
tspContent,
false,
false,
false,
true,
false
);
assert.ok(modelFile);
await assertEqualContent(
modelFile?.getFullText()!,
`
export interface Foo {
prop1: string;
prop2: string;
}

export function fooSerializer(item: Foo): Record<string, unknown> {
return {
prop1: item["prop1"],
prop2: item["prop2"],
};
}`
);
});
});
Loading