UNPKG

@odata2ts/odata2ts

Version:

Flexible generator to produce various TypeScript artefacts (from simple model interfaces to complete odata clients) from OData metadata files

223 lines 10.3 kB
import { __awaiter } from "tslib"; import { loadConverters } from "@odata2ts/converter-runtime"; import { ODataTypesV2, ODataVersions } from "@odata2ts/odata-core"; import { withNamespace } from "./DataModel.js"; import { Digester } from "./DataModelDigestion.js"; import { ODataVersion } from "./DataTypeModel.js"; /** * Digests an EDMX schema to produce a DataModel. * * @param schemas * @param options * @param namingHelper */ export const digest = (schemas, options, namingHelper) => __awaiter(void 0, void 0, void 0, function* () { const converters = yield loadConverters(ODataVersions.V2, options.converters); const digester = new DigesterV3(schemas, options, namingHelper, converters); return digester.digest(); }); class DigesterV3 extends Digester { constructor(schemas, options, namingHelper, converters) { super(ODataVersion.V2, schemas, options, namingHelper, converters); } findAssociationEnd(np) { var _a; for (let schema of this.schemas) { if (schema.Association) { const relationship = this.namingHelper.stripServicePrefix(np.$.Relationship); const association = (_a = schema.Association) === null || _a === void 0 ? void 0 : _a.find((a) => a.$.Name === relationship); const result = association === null || association === void 0 ? void 0 : association.End.find((e) => e.$.Role === np.$.ToRole); if (result) { return result; } } } throw new Error(`Association end couldn't be determined for NavigationProperty [${np.$.Name}]`); } getNavigationProps(entityType) { // return (entityType as EntityTypeV3).NavigationProperty || []; const et = entityType; if (et.NavigationProperty) { return et.NavigationProperty.map((np) => { const end = this.findAssociationEnd(np); const isRequired = end.$.Multiplicity !== "*" && !end.$.Multiplicity.startsWith("0.."); const isCollection = end.$.Multiplicity !== "1" && !end.$.Multiplicity.endsWith("..1"); return { $: { Name: np.$.Name, Type: isCollection ? `Collection(${end.$.Type})` : end.$.Type, Nullable: isRequired ? "false" : "true", }, }; }); } return []; } // in V2 all we have & need is the FunctionImport: Function & Action elements are only known in V4. digestOperations(schema) { } digestEntityContainer(schema) { var _a, _b; if (schema.EntityContainer && schema.EntityContainer.length) { const container = schema.EntityContainer[0]; const ecName = container.$.Name; (_a = container.FunctionImport) === null || _a === void 0 ? void 0 : _a.forEach((funcImport) => { var _a, _b, _c, _d; 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); const name = this.namingHelper.getFunctionName(opName); const usePost = ((_a = funcImport.$["m:HttpMethod"]) === null || _a === void 0 ? void 0 : _a.toUpperCase()) === "POST"; const parameters = (_c = (_b = funcImport.Parameter) === null || _b === void 0 ? void 0 : _b.map((p) => this.mapProp(p))) !== null && _c !== void 0 ? _c : []; // TODO: the spec allows for multiple ReturnType elements // https://docs.microsoft.com/en-us/openspecs/windows_protocols/mc-csdl/f510f36a-36bf-47f4-ac41-4a0ff921fbfa // totally unclear how the response object would look like const returnTypeDef = funcImport.$.ReturnType || (((_d = funcImport.ReturnType) === null || _d === void 0 ? void 0 : _d.length) ? funcImport.ReturnType[0].$.Type : undefined); const returnType = returnTypeDef ? this.mapProp({ $: { Name: "NO_NAME_BECAUSE_RETURN_TYPE", Type: returnTypeDef } }) : undefined; // V2 only knows the FunctionImport element // we generate the data structure for the function here this.dataModel.addUnboundOperationType(ecName, { fqName, odataName, name, paramsModelName: this.namingHelper.getOperationParamsModelName(opName), qName: this.namingHelper.getQFunctionName(opName), type: "Function" /* OperationTypes.Function */, parameters, returnType, usePost, }); this.dataModel.addFunction(fqName, { fqName, odataName, name, entitySet: funcImport.$.EntitySet, operation: fqName, }); }); (_b = container.EntitySet) === null || _b === void 0 ? void 0 : _b.forEach((entitySet) => { const odataName = entitySet.$.Name; const fqName = withNamespace(ecName, odataName); const config = this.serviceConfigHelper.findEntitySetConfig(ecName, odataName); const name = this.nameValidator.addEntitySet(fqName, (config === null || config === void 0 ? void 0 : config.mappedName) || odataName); 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, }); }); } } mapODataType(type) { switch (type) { case ODataTypesV2.Boolean: return { outputType: "boolean", qPath: "QBooleanPath", qCollection: "QBooleanCollection", qParam: "QBooleanParam", }; case ODataTypesV2.Int16: case ODataTypesV2.Int32: return { outputType: "number", qPath: "QNumberV2Path", qCollection: "QNumberV2Collection", qParam: "QNumberParam", }; case ODataTypesV2.Byte: case ODataTypesV2.SByte: return { outputType: "string", qPath: "QStringNumberV2Path", qCollection: "QStringNumberV2Collection", qParam: "QStringNumberV2Param", }; case ODataTypesV2.Int64: return { outputType: "string", qPath: "QStringNumberV2Path", qCollection: "QStringNumberV2Collection", qParam: "QInt64V2Param", }; case ODataTypesV2.Single: return { outputType: "string", qPath: "QStringNumberV2Path", qCollection: "QStringNumberV2Collection", qParam: "QSingleV2Param", }; case ODataTypesV2.Double: return { outputType: "string", qPath: "QStringNumberV2Path", qCollection: "QStringNumberV2Collection", qParam: "QDoubleV2Param", }; case ODataTypesV2.Decimal: return { outputType: "string", qPath: "QStringNumberV2Path", qCollection: "QStringNumberV2Collection", qParam: "QDecimalV2Param", }; case ODataTypesV2.String: return { outputType: "string", qPath: "QStringV2Path", qCollection: "QStringV2Collection", qParam: "QStringParam", }; case ODataTypesV2.DateTime: return { outputType: "string", qPath: "QDateTimeV2Path", qCollection: "QDateTimeV2Collection", qParam: "QDateTimeV2Param", }; case ODataTypesV2.Time: return { outputType: "string", qPath: "QTimeV2Path", qCollection: "QTimeV2Collection", qParam: "QTimeV2Param", }; case ODataTypesV2.DateTimeOffset: return { outputType: "string", qPath: "QDateTimeOffsetV2Path", qCollection: "QDateTimeOffsetV2Collection", qParam: "QDateTimeOffsetV2Param", }; case ODataTypesV2.Binary: return { outputType: "string", qPath: "QBinaryPath", qCollection: "QBinaryCollection", qParam: "QBinaryV2Param", }; case ODataTypesV2.Guid: return { outputType: "string", qPath: "QGuidV2Path", qCollection: "QGuidV2Collection", qParam: "QGuidV2Param", }; default: return { outputType: "string", qPath: "QStringV2Path", qCollection: "QStringV2Collection", qParam: undefined, }; } } } //# sourceMappingURL=DataModelDigestionV2.js.map