UNPKG

pailingual-odata

Version:

TypeScript client for OData v4 services

154 lines (130 loc) 5.17 kB
import { Query} from "./query"; import { EdmEntityType, EdmTypes, ApiMetadata } from "./metadata"; import { SingleSource } from "./singleSource"; import { serializeValue } from "./serialization" import { Executable, ExecutableAndCount } from "./executable"; import * as helpers from "./utils"; export class CollectionSource extends ExecutableAndCount { constructor( protected __metadata: EdmEntityType, protected __apiMetadata: ApiMetadata, query: Query ) { super(query); this._generateOperationsProperties(); } private _generateOperationsProperties() { if (this.__apiMetadata) { helpers.generateOperations(this, () => this.query, this.__apiMetadata, this.__metadata, true); } } $byKey(key: any) { let expression = (typeof key === "object" && !(key instanceof Date)) ? this.getExpressionByValues(key as Record<string, any>) : this.getExpressionByKeyValue(key) var query = this.query.byKey(expression); return new SingleSource(this.__metadata, this.__apiMetadata, query) } private getExpressionByKeyValue(value: any): string { let md = this.__metadata; let keys = this.__metadata.keys; while (md.baseType && !keys) { md = md.baseType; keys = md.keys; } if (!keys) throw new Error(`Metadata: Keys not defined for entity type '${md.name}'`); if (keys.length > 1) throw new Error('For entity with composite key use named parameters'); let keyType = md.properties[keys[0]].type as EdmTypes; let res = serializeValue(value, keyType, true); if (!res) throw new Error("Key must be not null value"); return res; } private getExpressionByValues(values: Record<string, any>): string { var res = new Array<string>(); for (let prop in values) { let propMetadata = this.__metadata.properties[prop]; if (!propMetadata) throw new Error(`Property '${prop}' for entity '${this.__metadata.name}' not found.`); let value = serializeValue(values[prop], propMetadata.type as EdmTypes, true); let exp = `${prop}=${value}`; res.push(exp); } return res.join(","); } $cast(fullTypeName: string): CollectionSource { const typeMetadata = this.__apiMetadata.getEdmTypeMetadata(fullTypeName) as EdmEntityType; if (!typeMetadata) throw new Error(`EntityType '${fullTypeName}' not found.`); const q = this.query.cast(fullTypeName); return new CollectionSource(typeMetadata, this.__apiMetadata, q); } $count() { const query = this.query.count(); return new Executable(query); } $delete(key: any) { return this.$byKey(key).$delete(); } $expand(prop: string, exp?: Function) { const q = this.query.expand(prop, exp); return new CollectionSource(this.__metadata, this.__apiMetadata, q); } $filter(expr: string) { const q = this.query.filter(expr); return new CollectionSource(this.__metadata, this.__apiMetadata, q); } $orderBy(...fields: (string | Function)[]) { return this.orderByImpl(fields); } $orderByDesc(...fields: (string | Function)[]) { return this.orderByImpl(fields, true); } private orderByImpl(fields: (string | Function)[], desc = false) { var expressions: string[] = fields.map(f => { let exp = (typeof f == "string") ? f : helpers.buildPathExpression(f, this.__metadata, this.__apiMetadata); if (desc) exp += " desc"; return exp; }); const q = this.query.orderBy(expressions); return new CollectionSource(this.__metadata, this.__apiMetadata, q); } $insert(obj: any) { const q = this.query.insert(obj); return new Executable(q); } $patch(key: any, obj: any) { return this.$byKey(key).$patch(obj); } $top(num: number) { const q = this.query.top(num); return new CollectionSource(this.__metadata, this.__apiMetadata, q); } $skip(num: number) { const q = this.query.skip(num); return new CollectionSource(this.__metadata, this.__apiMetadata, q); } $search(expr: string) { const q = this.query.search(expr); return new CollectionSource(this.__metadata, this.__apiMetadata, q); } $select(...fields: string[]) { const q = this.query.select(fields); return new CollectionSource(this.__metadata, this.__apiMetadata, q); } $unsafeExpand(exp: string) { return this.$expand(exp); } $update(key: any, obj: any) { return this.$byKey(key).$update(obj); } $urlWithCount() { return this.query.count({ inline: true }).url(); } }