in packages/typespec-powershell/src/utils/modelUtils.ts [192:331]
export function getSchemaForType(
dpgContext: SdkContext,
typeInput: Type,
options?: GetSchemaOptions
): any {
const program = dpgContext.program;
const { usage } = options ?? {};
const type = getEffectiveModelFromType(program, typeInput);
if (schemaCache.has(type)) {
return schemaCache.get(type);
}
const builtinType = getSchemaForLiteral(type);
if (builtinType !== undefined) {
// add in description elements for types derived from primitive types (SecureString, etc.)
const doc = getDoc(program, type);
if (doc) {
builtinType.description = doc;
}
schemaCache.set(type, builtinType);
return builtinType;
}
if (type.kind === "ModelProperty") {
const typeSchema: Schema = getSchemaForType(dpgContext, type.type, options);
if (isStringType(program, type.type) || isNumericType(program, type.type)) {
// applyIntrinsicDecorators for string and numeric types
// unlike m4, min/max length and pattern, secrets, etc. are not part of the schema
let propertySchema = { ...typeSchema };
propertySchema = applyIntrinsicDecorators(dpgContext, type, propertySchema);
propertySchema.language.default.name = type.name;
propertySchema.language.default.description = getDoc(program, type) || "";
schemaCache.set(type, <Schema>propertySchema);
return propertySchema;
} else {
return typeSchema;
}
}
if (type.kind === "Model") {
if (modelSet.has(type)) {
return undefined;
} else {
modelSet.add(type);
}
const schema = getSchemaForModel(dpgContext, type, options) as any;
if (isAnonymousObjectSchema(schema)) {
if (Object.keys(schema.properties ?? {}).length === 0) {
// Handle empty anonymous model as Record
// schema.typeName =
// // schema.type === "object" ? SchemaType.Dictionary : SchemaType.Any;
// schema.type === "object" ? "Record<string, unknown>" : "unknown";
// if (usage && usage.includes(SchemaContext.Output)) {
// schema.outputTypeName =
// schema.type === "object" ? "Record<string, any>" : "any";
// }
// by xiaogang, we only need on any schema for empty anonymous model
if (schemaCache.has(ANY_SCHEMA)) {
return schemaCache.get(ANY_SCHEMA);
}
schema.type = SchemaType.Any;
schemaCache.set(ANY_SCHEMA, schema);
return schema;
} else {
// Handle non-empty anonymous model as inline model
if (usage && usage.includes(SchemaContext.Output)) {
schema.outputTypeName = getModelInlineSigniture(schema, {
usage: [SchemaContext.Output]
});
}
schema.typeName = getModelInlineSigniture(schema, {
usage: [SchemaContext.Input]
});
schema.type = "object";
}
} else if (
!isArrayModelType(program, type) &&
!isRecordModelType(program, type)
) {
if (usage && usage.includes(SchemaContext.Output)) {
schema.outputTypeName = `${schema.name}Output`;
}
schema.typeName = `${schema.language.default.name}`;
}
schema.usage = usage;
schemaCache.set(type, schema);
return schema;
} else if (type.kind === "Union") {
const schema = getSchemaForUnion(dpgContext, type, options);
if (schema) {
schemaCache.set(type, schema);
}
return schema;
} else if (type.kind === "UnionVariant") {
const schema = getSchemaForUnionVariant(dpgContext, type, options);
schemaCache.set(type, schema);
return schema;
} else if (type.kind === "Enum") {
const schema = getSchemaForEnum(dpgContext, type);
schemaCache.set(type, schema);
return schema;
} else if (type.kind === "Scalar") {
const schema = getSchemaForScalar(dpgContext, type, options);
schemaCache.set(type, schema);
return schema;
} else if (type.kind === "EnumMember") {
//ToDo: by xiaogang, need to confirm
return getSchemaForEnumMember(program, type);
}
if (isUnknownType(type)) {
// Unknown type, return any schema
if (schemaCache.has(ANY_SCHEMA)) {
return schemaCache.get(ANY_SCHEMA);
}
const returnType = new AnySchema("any");
schemaCache.set(ANY_SCHEMA, returnType);
return returnType;
}
if (isNeverType(type)) {
return { type: "never" };
}
if (isNullType(type)) {
return { type: "null" };
}
// reportDiagnostic(program, {
// code: "invalid-schema",
// format: { type: type.kind },
// target: type
// });
function addValidation(schema: Schema, type: ModelProperty) {
if (isStringType(program, type.type)) {
(<any>schema).minLength = getMinLength(program, type);
(<any>schema).maxLength = getMaxLength(program, type);
(<any>schema).pattern = getPattern(program, type);
} else if (isNumericType(program, type.type)) {
(<any>schema).minimum = getMinValue(program, type);
(<any>schema).maximum = getMaxValue(program, type);
}
}
return undefined;
}