@azure-tools/typespec-java
Version:
TypeSpec library for emitting Java client from the TypeSpec REST protocol binding
247 lines • 11.2 kB
JavaScript
import { ArraySchema, ObjectSchema, Property, } from "@autorest/codemodel";
import { KnownMediaType } from "@azure-tools/codegen";
import { getNamespace, pascalCase } from "./utils.js";
/*
* These schema need to reflect
* 1. wire schema via "serializedName"
* 2. client schema in Java via "name"
*/
export function createResponseErrorSchema(schemas, stringSchema) {
const responseErrorSchema = new ObjectSchema("Error", "The error object.", {
language: {
default: {
namespace: "Azure.Core.Foundations",
},
java: {
namespace: "com.azure.core.models",
},
},
});
responseErrorSchema.language.default.crossLanguageDefinitionId = "Azure.Core.Foundations.Error";
schemas.add(responseErrorSchema);
responseErrorSchema.addProperty(new Property("code", "One of a server-defined set of error codes.", stringSchema, {
serializedName: "code",
required: true,
nullable: false,
readOnly: true,
}));
responseErrorSchema.addProperty(new Property("message", "A human-readable representation of the error.", stringSchema, {
serializedName: "message",
required: true,
nullable: false,
readOnly: true,
}));
responseErrorSchema.addProperty(new Property("target", "The target of this error.", stringSchema, {
serializedName: "target",
required: false,
nullable: true,
readOnly: true,
}));
const errorDetailsSchema = new ArraySchema("errorDetails", "the array of errors.", responseErrorSchema);
responseErrorSchema.addProperty(new Property("errorDetails", "An array of details about specific errors that led to this reported error.", errorDetailsSchema, {
serializedName: "details",
required: false,
nullable: true,
readOnly: true,
}));
const innerErrorSchema = createResponseInnerErrorSchema(schemas, stringSchema);
responseErrorSchema.addProperty(new Property("innerError", "An object containing more specific information than the current object about the error.", innerErrorSchema, {
serializedName: "innererror",
required: false,
nullable: true,
readOnly: true,
}));
return responseErrorSchema;
}
export function createResponseInnerErrorSchema(schemas, stringSchema) {
const responseInnerErrorSchema = new ObjectSchema("InnerError", "An object containing more specific information about the error.", {
language: {
default: {
namespace: "Azure.Core.Foundations",
},
java: {
namespace: "com.azure.core.models",
},
},
});
responseInnerErrorSchema.language.default.crossLanguageDefinitionId =
"Azure.Core.Foundations.InnerError";
schemas.add(responseInnerErrorSchema);
responseInnerErrorSchema.addProperty(new Property("code", "One of a server-defined set of error codes.", stringSchema, {
serializedName: "code",
required: false,
nullable: true,
readOnly: true,
}));
responseInnerErrorSchema.addProperty(new Property("innerError", "Inner error.", responseInnerErrorSchema, {
serializedName: "innererror",
required: false,
nullable: true,
readOnly: true,
}));
return responseInnerErrorSchema;
}
export function createPollOperationDetailsSchema(schemas, stringSchema) {
const pollOperationDetailsSchema = new ObjectSchema("PollOperationDetails", "Status details for long running operations.", {
language: {
default: {
namespace: "Azure.Core.Foundations",
},
java: {
namespace: "com.azure.core.util.polling",
},
},
});
schemas.add(pollOperationDetailsSchema);
pollOperationDetailsSchema.addProperty(new Property("operationId", "The unique ID of the operation.", stringSchema, {
serializedName: "id",
required: true,
nullable: false,
readOnly: true,
}));
pollOperationDetailsSchema.addProperty(new Property("status", "The status of the operation.", stringSchema, {
serializedName: "status",
required: true,
nullable: false,
readOnly: true,
}));
const responseErrorSchema = createResponseErrorSchema(schemas, stringSchema);
pollOperationDetailsSchema.addProperty(new Property("error", 'Error object that describes the error when status is "Failed".', responseErrorSchema, {
serializedName: "error",
required: false,
nullable: true,
readOnly: true,
}));
return pollOperationDetailsSchema;
}
const fileDetailsMap = new Map();
function getFileSchemaName(baseName, sdkModelType) {
// If the TypeSpec Model exists and is not TypeSpec.Http.File, directly use its name
if (sdkModelType && sdkModelType.crossLanguageDefinitionId !== "TypeSpec.Http.File") {
return baseName;
}
// make sure suffix "FileDetails"
if (baseName.toLocaleLowerCase().endsWith("filedetails")) {
return pascalCase(baseName);
}
else if (baseName.toLocaleLowerCase().endsWith("file")) {
return pascalCase(baseName) + "Details";
}
else {
return pascalCase(baseName) + "FileDetails";
}
}
function createFileDetailsSchema(schemaName, propertyName, namespace, javaNamespace, schemas) {
const fileDetailsSchema = new ObjectSchema(schemaName, 'The file details for the "' + propertyName + '" field.', {
language: {
default: {
namespace: namespace,
},
java: {
namespace: javaNamespace,
},
},
serializationFormats: [KnownMediaType.Multipart],
});
schemas.add(fileDetailsSchema);
fileDetailsMap.set(schemaName, fileDetailsSchema);
return fileDetailsSchema;
}
function addContentProperty(fileDetailsSchema, binarySchema) {
fileDetailsSchema.addProperty(new Property("content", "The content of the file.", binarySchema, {
required: true,
nullable: false,
readOnly: false,
}));
}
function addFilenameProperty(fileDetailsSchema, stringSchema, filenameProperty, processSchemaFunc) {
fileDetailsSchema.addProperty(new Property("filename", "The filename of the file.", (filenameProperty === null || filenameProperty === void 0 ? void 0 : filenameProperty.type.kind) === "constant" && processSchemaFunc
? processSchemaFunc(filenameProperty.type)
: stringSchema, {
required: filenameProperty ? !filenameProperty.optional : false,
nullable: false,
readOnly: false,
}));
}
function addContentTypeProperty(fileDetailsSchema, stringSchema, contentTypeProperty, processSchemaFunc) {
fileDetailsSchema.addProperty(new Property("contentType", "The content-type of the file.", (contentTypeProperty === null || contentTypeProperty === void 0 ? void 0 : contentTypeProperty.type.kind) === "constant" && processSchemaFunc
? processSchemaFunc(contentTypeProperty.type)
: stringSchema, {
required: contentTypeProperty ? !contentTypeProperty.optional : false,
nullable: false,
readOnly: false,
clientDefaultValue: (contentTypeProperty === null || contentTypeProperty === void 0 ? void 0 : contentTypeProperty.type.kind) === "constant" ? undefined : "application/octet-stream",
}));
}
export function getFileDetailsSchema(property, namespace, javaNamespace, schemas, binarySchema, stringSchema, processSchemaFunc) {
var _a;
let fileSdkType;
if (property.type.kind === "model") {
fileSdkType = property.type;
}
else if (property.type.kind === "array" && property.type.valueType.kind === "model") {
fileSdkType = property.type.valueType;
}
if (fileSdkType) {
// property.type is File, use name and properties from property.type for the File schema
/*
Current logic:
- Class name suffix "FileDetails"
- No class hierarchy for File
- File has 3 properties: "content", "filename", "contentType" (Note that it is "contents" in TypeSpec)
- No adjustment on "content" property, it is always BinaryData and required
- Allow constant type for "filename" and "contentType" (to be discussed for other types e.g. enum)
- Allow required for "filename" and "contentType"
*/
const filePropertyName = property.name;
const fileSchemaName = fileSdkType.name;
const schemaName = getFileSchemaName(fileSchemaName, fileSdkType);
let fileDetailsSchema = fileDetailsMap.get(schemaName);
if (!fileDetailsSchema) {
const typeNamespace = (_a = getNamespace(property.type.__raw)) !== null && _a !== void 0 ? _a : namespace;
fileDetailsSchema = createFileDetailsSchema(schemaName, filePropertyName, typeNamespace, javaNamespace, schemas);
// description if available
if (fileSdkType.summary) {
fileDetailsSchema.summary = fileSdkType.summary;
}
if (fileSdkType.doc) {
fileDetailsSchema.language.default.description = fileSdkType.doc;
}
// crossLanguageDefinitionId
fileDetailsSchema.language.default.crossLanguageDefinitionId =
fileSdkType.crossLanguageDefinitionId;
let contentTypeProperty;
let filenameProperty;
// find "filename" and "contentType" property in current model and its base models
while (fileSdkType !== undefined) {
for (const property of fileSdkType.properties) {
if (!filenameProperty && property.name === "filename") {
filenameProperty = property;
}
if (!contentTypeProperty && property.name === "contentType") {
contentTypeProperty = property;
}
}
fileSdkType = fileSdkType.baseModel;
}
addContentProperty(fileDetailsSchema, binarySchema);
addFilenameProperty(fileDetailsSchema, stringSchema, filenameProperty, processSchemaFunc);
addContentTypeProperty(fileDetailsSchema, stringSchema, contentTypeProperty, processSchemaFunc);
}
return fileDetailsSchema;
}
else {
// property.type is bytes, create a File schema
const filePropertyName = property.name;
const schemaName = getFileSchemaName(filePropertyName);
let fileDetailsSchema = fileDetailsMap.get(schemaName);
if (!fileDetailsSchema) {
fileDetailsSchema = createFileDetailsSchema(schemaName, filePropertyName, namespace, javaNamespace, schemas);
addContentProperty(fileDetailsSchema, binarySchema);
addFilenameProperty(fileDetailsSchema, stringSchema);
addContentTypeProperty(fileDetailsSchema, stringSchema);
}
return fileDetailsSchema;
}
}
//# sourceMappingURL=external-schemas.js.map