diff --git a/src/typespec-aaz/src/convertor.ts b/src/typespec-aaz/src/convertor.ts index f49cda13..b7200322 100644 --- a/src/typespec-aaz/src/convertor.ts +++ b/src/typespec-aaz/src/convertor.ts @@ -55,6 +55,7 @@ import { isVoidType, resolveEncodedName, IntrinsicType, + serializeValueAsJson, } from "@typespec/compiler"; import { TwoLevelMap } from "@typespec/compiler/utils"; import { @@ -699,7 +700,7 @@ function convert2CMDSchema( if (param.defaultValue) { schema.default = { - value: getDefaultValue(context, param.defaultValue), + value: getDefaultValue(context, param.defaultValue, param), }; } } @@ -708,6 +709,10 @@ function convert2CMDSchema( ...schema, ...applySchemaFormat(context, param, schema as CMDSchemaBase), }; + schema = { + ...schema, + ...applyEncoding(context, param, schema), + }; schema = { ...schema, ...applyExtensionsDecorators(context, param, schema), @@ -759,6 +764,7 @@ function convert2CMDSchemaBase(context: AAZSchemaEmitterContext, type: Type): CM } if (schema) { schema = applySchemaFormat(context, type, schema); + schema = applyEncoding(context, type, schema); schema = applyExtensionsDecorators(context, type, schema); } @@ -1898,6 +1904,20 @@ function emitArrayFormat( // TODO: add emitResourceIdFormat +function applyEncoding(context: AAZSchemaEmitterContext, type: Type, schema: CMDSchemaBase): CMDSchemaBase { + if (type.kind !== "Scalar" && type.kind !== "ModelProperty") { + return schema; + } + const encodeData = getEncode(context.program, type); + if (encodeData !== undefined) { + schema = { + ...schema, + ...convertScalar2CMDSchemaBase(context, encodeData.type), + }; + } + return schema; +} + // apply extension decorators function applyExtensionsDecorators(context: AAZSchemaEmitterContext, type: Type, schema: CMDSchemaBase): CMDSchemaBase { const extensions = getExtensions(context.program, type); @@ -2124,25 +2144,6 @@ function getClsDefinitionModel(schema: CMDClsSchemaBase): CMDObjectSchemaBase | return schema.type.pendingSchema.schema!; } -function getDefaultValue(content: AAZSchemaEmitterContext, defaultType: Value): unknown { - switch (defaultType.valueKind) { - case "StringValue": - return defaultType.value; - case "NumericValue": - return defaultType.value.asNumber() ?? undefined; - case "BooleanValue": - return defaultType.value; - case "ArrayValue": - return defaultType.values.map((x) => getDefaultValue(content, x)); - case "NullValue": - return null; - case "EnumValue": - return defaultType.value.value ?? defaultType.value.name; - default: - reportDiagnostic(content.program, { - code: "invalid-default", - format: { type: defaultType.valueKind }, - target: defaultType, - }); - } +function getDefaultValue(context: AAZSchemaEmitterContext, defaultType: Value, modelProperty: ModelProperty): any { + return serializeValueAsJson(context.program, defaultType, modelProperty); } diff --git a/src/typespec-aaz/test/encoding.test.ts b/src/typespec-aaz/test/encoding.test.ts new file mode 100644 index 00000000..da40899e --- /dev/null +++ b/src/typespec-aaz/test/encoding.test.ts @@ -0,0 +1,44 @@ +import { TestHost, BasicTestRunner } from "@typespec/compiler/testing"; +import { describe, expect, it, beforeEach } from "vitest"; +import { createTypespecAazTestHost, createTypespecAazTestRunner, compileTypespecAAZOperations } from "./test-aaz.js"; +import { ModelVar, generateCompileArmResourceTemplate, findObjectsWithKey } from "./util.js"; + +describe("encoding parsing", () => { + let host: TestHost; + let runner: BasicTestRunner; + + beforeEach(async () => { + host = await createTypespecAazTestHost(); + runner = await createTypespecAazTestRunner(host); + }); + + it("validate encoding duration with default", async () => { + const modelTmp: ModelVar = { + modelKey: "targetValue", + modelContent: "TargetEncodingModel", + isComposite: true, + appendModel: ` + model TargetEncodingModel { + @encode(DurationKnownEncoding.seconds, int32) + errorRateTimeWindowInSeconds?: duration = duration.fromISO("PT60S"); + } + `, + }; + + const code: string = generateCompileArmResourceTemplate(modelTmp); + const result = await compileTypespecAAZOperations( + code, + { + "operation": "get-resources-operations", + "api-version": "A", + "resources": ["/subscriptions/{}/resourcegroups/{}/providers/microsoft.mock/mockresources/{}"], + }, + runner, + ); + const resultObj = JSON.parse(result!); + expect(Array.isArray(resultObj)).toBe(true); + expect(resultObj.length).toBe(1); + const targetObj = findObjectsWithKey(resultObj[0].pathItem.get.read.http.responses, "targetValue"); + await expect(JSON.stringify(targetObj, null, 2)).toMatchFileSnapshot("./snapshots/encoding-duration-prop.json"); + }); +}); diff --git a/src/typespec-aaz/test/snapshots/encoding-duration-prop.json b/src/typespec-aaz/test/snapshots/encoding-duration-prop.json new file mode 100644 index 00000000..fe26afa2 --- /dev/null +++ b/src/typespec-aaz/test/snapshots/encoding-duration-prop.json @@ -0,0 +1,14 @@ +{ + "type": "object", + "props": [ + { + "type": "integer32", + "name": "errorRateTimeWindowInSeconds", + "default": { + "value": 60 + } + } + ], + "name": "targetValue", + "required": true +} \ No newline at end of file