@odata2ts/odata2ts
Version:
Flexible generator to produce various TypeScript artefacts (from simple model interfaces to complete odata clients) from OData metadata files
237 lines • 11.8 kB
JavaScript
import { __awaiter } from "tslib";
import { loadConverters } from "@odata2ts/converter-runtime";
import { ODataTypesV4, ODataVersions } from "@odata2ts/odata-core";
import { withNamespace } from "./DataModel.js";
import { Digester } from "./DataModelDigestion.js";
import { ODataVersion } from "./DataTypeModel.js";
export const digest = (schemas, options, namingHelper) => __awaiter(void 0, void 0, void 0, function* () {
const converters = yield loadConverters(ODataVersions.V4, options.converters);
const digester = new DigesterV4(schemas, options, namingHelper, converters);
return digester.digest();
});
class DigesterV4 extends Digester {
constructor(schemas, options, namingHelper, converters) {
super(ODataVersion.V4, schemas, options, namingHelper, converters);
}
getNavigationProps(entityType) {
return entityType.NavigationProperty || [];
}
digestOperations(schema) {
const nsWithAlias = [schema.$.Namespace, schema.$.Alias];
// functions & actions
this.addOperations(nsWithAlias, schema.Function, "Function" /* OperationTypes.Function */);
this.addOperations(nsWithAlias, schema.Action, "Action" /* OperationTypes.Action */);
}
digestEntityContainer(schema) {
var _a, _b, _c, _d;
if (schema.EntityContainer && schema.EntityContainer.length) {
const container = schema.EntityContainer[0];
const ecName = container.$.Name;
(_a = container.ActionImport) === null || _a === void 0 ? void 0 : _a.forEach((actionImport) => {
const odataName = actionImport.$.Name;
const fqName = withNamespace(ecName, odataName);
const opConfig = this.serviceConfigHelper.findOperationImportConfig(ecName, odataName);
const opName = this.nameValidator.addOperationImportType(fqName, (opConfig === null || opConfig === void 0 ? void 0 : opConfig.mappedName) || odataName);
this.dataModel.addAction(fqName, {
fqName,
name: this.namingHelper.getActionName(opName),
odataName: actionImport.$.Name,
operation: actionImport.$.Action,
});
});
(_b = container.FunctionImport) === null || _b === void 0 ? void 0 : _b.forEach((funcImport) => {
const odataName = funcImport.$.Name;
const fqName = withNamespace(ecName, odataName);
const opConfig = this.serviceConfigHelper.findOperationImportConfig(ecName, odataName);
const opName = this.nameValidator.addOperationImportType(fqName, (opConfig === null || opConfig === void 0 ? void 0 : opConfig.mappedName) || odataName);
this.dataModel.addFunction(fqName, {
fqName,
odataName,
name: this.namingHelper.getFunctionName(opName),
operation: funcImport.$.Function,
entitySet: funcImport.$.EntitySet,
});
});
(_c = container.Singleton) === null || _c === void 0 ? void 0 : _c.forEach((singleton) => {
const odataName = singleton.$.Name;
const fqName = withNamespace(ecName, odataName);
const singletonConfig = this.serviceConfigHelper.findOperationImportConfig(ecName, odataName);
const name = this.nameValidator.addSingleton(withNamespace(fqName, odataName), (singletonConfig === null || singletonConfig === void 0 ? void 0 : singletonConfig.mappedName) || odataName);
const navPropBindings = singleton.NavigationPropertyBinding || [];
const entityType = this.dataModel.getEntityType(singleton.$.Type);
if (!entityType) {
throw new Error(`Entity type "${singleton.$.Type}" not found!`);
}
this.dataModel.addSingleton(fqName, {
fqName,
odataName,
name,
entityType,
navPropBinding: navPropBindings.map((binding) => ({
path: this.namingHelper.stripServicePrefix(binding.$.Path),
target: binding.$.Target,
})),
});
});
(_d = container.EntitySet) === null || _d === void 0 ? void 0 : _d.forEach((entitySet) => {
const odataName = entitySet.$.Name;
const fqName = withNamespace(ecName, odataName);
const config = this.serviceConfigHelper.findOperationImportConfig(ecName, odataName);
const name = this.nameValidator.addEntitySet(fqName, (config === null || config === void 0 ? void 0 : config.mappedName) || odataName);
const navPropBindings = entitySet.NavigationPropertyBinding || [];
const entityType = this.dataModel.getEntityType(entitySet.$.EntityType);
if (!entityType) {
throw new Error(`Entity type "${entitySet.$.EntityType}" not found!`);
}
this.dataModel.addEntitySet(fqName, {
fqName,
odataName,
name,
entityType,
navPropBinding: navPropBindings.map((binding) => ({
path: this.namingHelper.stripServicePrefix(binding.$.Path),
target: binding.$.Target,
})),
});
});
}
}
mapODataType(type) {
switch (type) {
case ODataTypesV4.Boolean:
return {
outputType: "boolean",
qPath: "QBooleanPath",
qCollection: "QBooleanCollection",
qParam: "QBooleanParam",
};
case ODataTypesV4.Int64:
case ODataTypesV4.Decimal:
if (this.options.v4BigNumberAsString) {
return {
outputType: "string",
qPath: "QBigNumberPath",
qCollection: "QBigNumberCollection",
qParam: "QBigNumberParam",
};
}
// yes, intentional fall through!
case ODataTypesV4.Byte:
case ODataTypesV4.SByte:
case ODataTypesV4.Int16:
case ODataTypesV4.Int32:
case ODataTypesV4.Single:
case ODataTypesV4.Double:
return {
outputType: "number",
qPath: "QNumberPath",
qCollection: "QNumberCollection",
qParam: "QNumberParam",
};
case ODataTypesV4.String:
return {
outputType: "string",
qPath: "QStringPath",
qCollection: "QStringCollection",
qParam: "QStringParam",
};
case ODataTypesV4.Date:
return {
outputType: "string",
qPath: "QDatePath",
qCollection: "QDateCollection",
qParam: "QDateParam",
};
case ODataTypesV4.TimeOfDay:
return {
outputType: "string",
qPath: "QTimeOfDayPath",
qCollection: "QTimeOfDayCollection",
qParam: "QTimeOfDayParam",
};
case ODataTypesV4.DateTimeOffset:
return {
outputType: "string",
qPath: "QDateTimeOffsetPath",
qCollection: "QDateTimeOffsetCollection",
qParam: "QDateTimeOffsetParam",
};
// case ODataTypesV4.Duration:
// return {
// outputType: "string",
// qPath: "QDurationPath",
// qCollection: "QDurationCollection",
// qParam: "QDurationParam",
// };
case ODataTypesV4.Binary:
return {
outputType: "string",
qPath: "QBinaryPath",
qCollection: "QBinaryCollection",
qParam: "QBinaryParam",
};
case ODataTypesV4.Guid:
return {
outputType: "string",
qPath: "QGuidPath",
qCollection: "QGuidCollection",
qParam: "QGuidParam",
};
default:
return {
outputType: "string",
qPath: "QStringPath",
qCollection: "QStringCollection",
qParam: undefined,
};
}
}
addOperations(ns, operations, type) {
const [namespace] = ns;
if (!operations || !operations.length) {
return;
}
operations.forEach((op) => {
var _a, _b, _c, _d;
const odataName = op.$.Name;
const isBound = op.$.IsBound === "true";
const fqName = withNamespace(namespace, odataName);
const opConfig = this.serviceConfigHelper.findOperationTypeConfig(ns, odataName);
const params = (_b = (_a = op.Parameter) === null || _a === void 0 ? void 0 : _a.map((p) => this.mapProp(p))) !== null && _b !== void 0 ? _b : [];
const returnType = (_c = op.ReturnType) === null || _c === void 0 ? void 0 : _c.map((rt) => {
return this.mapProp(Object.assign(Object.assign({}, rt), { $: Object.assign({ Name: "NO_NAME_BECAUSE_RETURN_TYPE" }, rt.$) }));
})[0];
if (isBound && !params.length) {
throw new Error(`IllegalState: Operation '${odataName}' is bound, but has no parameters!`);
}
const bindingProp = isBound ? params.shift() : undefined;
const bindingEntityName = bindingProp ? (_d = this.dataModel.getModel(bindingProp.fqType)) === null || _d === void 0 ? void 0 : _d.name : undefined;
const opName = bindingEntityName
? this.nameValidator.addBoundOperationType(bindingEntityName, fqName, (opConfig === null || opConfig === void 0 ? void 0 : opConfig.mappedName) || odataName, type)
: this.nameValidator.addUnboundOperationType(fqName, (opConfig === null || opConfig === void 0 ? void 0 : opConfig.mappedName) || odataName, type);
const name = type === "Function" /* OperationTypes.Function */
? this.namingHelper.getFunctionName(opName)
: this.namingHelper.getActionName(opName);
const qName = type === "Function" /* OperationTypes.Function */
? this.namingHelper.getQFunctionName(opName, bindingEntityName)
: this.namingHelper.getQActionName(opName, bindingEntityName);
const opType = {
fqName,
odataName: isBound ? fqName : odataName,
name,
qName,
paramsModelName: this.namingHelper.getOperationParamsModelName(opName, bindingEntityName),
type,
parameters: params,
returnType,
};
if (bindingProp) {
this.dataModel.addBoundOperationType(namespace, bindingProp, opType);
}
else {
this.dataModel.addUnboundOperationType(namespace, opType);
}
});
}
}
//# sourceMappingURL=DataModelDigestionV4.js.map