UNPKG

angular-odata

Version:

Client side OData typescript library for Angular

439 lines 64 kB
import { HttpEventType } from '@angular/common/http'; import { NEVER } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; import { ODataInMemoryCache } from './cache'; import { DEFAULT_VERSION } from './constants'; import { ODataCollection, ODataModel, } from './models'; import { ODataApiOptions } from './options'; import { ODataQueryOptions, ODataPathSegments, ODataRequest, ODataResponse, ODataBatchResource, ODataMetadataResource, ODataActionResource, ODataFunctionResource, ODataEntityResource, ODataEntitySetResource, ODataSingletonResource, ODataNavigationPropertyResource, } from './resources'; import { EDM_PARSERS, ODataSchema, } from './schema'; import { NONE_PARSER, PathSegment, } from './types'; /** * Api abstraction for consuming OData services. */ export class ODataApi { requester; serviceRootUrl; metadataUrl; name; version; default; creation; // Options options; // Cache cache; // Error Handler errorHandler; // Base Parsers parsers; // Schemas schemas; constructor(config) { this.serviceRootUrl = config.serviceRootUrl; if (this.serviceRootUrl.includes('?')) throw new Error("The 'serviceRootUrl' should not contain query string. Please use 'params' to add extra parameters"); if (!this.serviceRootUrl.endsWith('/')) this.serviceRootUrl += '/'; this.metadataUrl = config.metadataUrl ?? `${this.serviceRootUrl}$metadata`; this.name = config.name; this.version = config.version ?? DEFAULT_VERSION; this.default = config.default ?? false; this.creation = config.creation ?? new Date(); this.options = new ODataApiOptions({ ...config.options, version: this.version, }); this.cache = config.cache ?? new ODataInMemoryCache(); this.errorHandler = config.errorHandler; this.parsers = new Map(Object.entries(config.parsers ?? EDM_PARSERS)); this.schemas = (config.schemas ?? []).map((schema) => new ODataSchema(schema, this)); } configure(settings = {}) { this.requester = settings.requester; this.schemas.forEach((schema) => { schema.configure({ options: this.options.parserOptions, }); }); } populate(metadata) { const config = metadata.toConfig(); this.version = config.version ?? DEFAULT_VERSION; const schemas = (config.schemas ?? []).map((schema) => new ODataSchema(schema, this)); this.schemas = [...this.schemas, ...schemas]; schemas.forEach((schema) => { schema.configure({ options: this.options.parserOptions, }); }); } fromJson(json) { const segments = ODataPathSegments.fromJson(json.segments); const query = ODataQueryOptions.fromJson(json.options); switch (segments.last()?.name) { case PathSegment.entitySet: if (segments.last()?.hasKey()) { return new ODataEntityResource(this, { segments, query }); } else { return new ODataEntitySetResource(this, { segments, query }); } case PathSegment.navigationProperty: return new ODataNavigationPropertyResource(this, { segments, query }); case PathSegment.singleton: return new ODataSingletonResource(this, { segments, query }); case PathSegment.action: return new ODataActionResource(this, { segments, query }); case PathSegment.function: return new ODataFunctionResource(this, { segments, query }); } throw new Error('No Resource for json'); } /** * Build a metadata resource. * @returns ODataMetadataResource */ metadata() { return ODataMetadataResource.factory(this); } /** * Build a batch resource. * @returns ODataBatchResource */ batch() { return ODataBatchResource.factory(this); } /** * Build a singleton resource. * @param path Name of the singleton * @returns */ singleton(name) { const singleton = this.findSingleton(name); return ODataSingletonResource.factory(this, { path: singleton?.name ?? name, type: singleton?.singletonType, }); } /** * Build an entity set resource. * @param path Name of the entity set * @returns */ entitySet(name) { const entitySet = this.findEntitySet(name); return ODataEntitySetResource.factory(this, { path: entitySet?.name ?? name, type: entitySet?.entityType, }); } /** * Unbound Action * @param {string} path? * @returns ODataActionResource */ action(path) { const callable = this.findCallable(path); return ODataActionResource.factory(this, { path, outgoingType: callable?.type(), incomingType: callable?.returnType(), }); } /** * Unbound Function * @param {string} path? * @returns ODataFunctionResource */ function(path) { const callable = this.findCallable(path); return ODataFunctionResource.factory(this, { path, outgoingType: callable?.type(), incomingType: callable?.returnType(), }); } callable(type) { return this.findCallable(type); } enumType(type) { return this.findEnumType(type); } structuredType(type) { return this.findStructuredType(type); } //request(req: ODataRequest<any>): Observable<any> { request(method, resource, options) { let req = ODataRequest.factory(this, method, resource, { body: options.body, etag: options.etag, context: options.context, headers: options.headers, params: options.params, responseType: options.responseType, observe: (options.observe === 'events' ? 'events' : 'response'), withCount: options.withCount, bodyQueryOptions: options.bodyQueryOptions, reportProgress: options.reportProgress, fetchPolicy: options.fetchPolicy, parserOptions: options.parserOptions, withCredentials: options.withCredentials, }); let res$ = this.requester !== undefined ? this.requester(req) : NEVER; res$ = res$.pipe(map((res) => res.type === HttpEventType.Response ? ODataResponse.fromHttpResponse(req, res) : res)); if (this.errorHandler !== undefined) res$ = res$.pipe(catchError(this.errorHandler)); if (options.observe === 'events') { return res$; } res$ = this.cache.handleRequest(req, res$); switch (options.observe || 'body') { case 'body': switch (options.responseType) { case 'entities': return res$.pipe(map((res) => res.entities())); case 'entity': return res$.pipe(map((res) => res.entity())); case 'property': return res$.pipe(map((res) => res.property())); case 'value': return res$.pipe(map((res) => res.value())); default: // Other responseTypes (arraybuffer, blob, json, text) return body return res$.pipe(map((res) => res.body)); } case 'response': // The response stream was requested directly, so return it. return res$; default: // Guard against new future observe types being added. throw new Error(`Unreachable: unhandled observe type ${options.observe}}`); } } //# region Find by Type // Memoize memo = { enumTypes: new Map(), structuredTypes: new Map(), callables: new Map(), entitySets: new Map(), singletons: new Map(), parsers: new Map(), options: new Map(), }; createSchema(config) { const schema = new ODataSchema(config, this); schema.configure({ options: this.options.parserOptions, }); this.schemas.push(schema); return schema; } findSchema(type) { const schemas = this.schemas.filter((s) => s.isNamespaceOf(type)); if (schemas.length === 0) return undefined; if (schemas.length === 1) return schemas[0]; return schemas .sort((s1, s2) => s1.namespace.length - s2.namespace.length) .pop(); } //#region EnumTypes findEnumType(value) { if (this.memo.enumTypes.has(value)) { return this.memo.enumTypes.get(value); } const enumTypes = this.schemas.reduce((acc, schema) => [...acc, ...schema.enums], []); let enumType = enumTypes.find((e) => e.type() === value); enumType = enumType ?? enumTypes.find((e) => e.name === value); this.memo.enumTypes.set(value, enumType); return enumType; } //#endregion //#region StructuredTypes findStructuredType(value) { if (this.memo.structuredTypes.has(value)) { return this.memo.structuredTypes.get(value); } const structuredTypes = this.schemas.reduce((acc, schema) => [...acc, ...schema.entities], []); let structuredType = structuredTypes.find((e) => e.type() === value); structuredType = structuredType ?? structuredTypes.find((e) => e.name === value); this.memo.structuredTypes.set(value, structuredType); return structuredType; } //#endregion //#region Callables findCallable(value, bindingType) { const key = bindingType !== undefined ? `${bindingType}/${value}` : value; if (this.memo.callables.has(key)) { return this.memo.callables.get(key); } const bindingStructuredType = bindingType !== undefined ? this.findStructuredType(bindingType) : undefined; const callables = this.schemas.reduce((acc, schema) => [...acc, ...schema.callables], []); let callable = callables.find((c) => { const isCallableType = c.type() == value; const callableBindingType = c.binding()?.type; const callableBindingStructuredType = callableBindingType !== undefined ? this.findStructuredType(callableBindingType) : undefined; return (isCallableType && (!bindingStructuredType || (callableBindingStructuredType && bindingStructuredType.isSubtypeOf(callableBindingStructuredType)))); }); callable = callable ?? callables.find((c) => { const isCallableType = c.name == value; const callableBindingType = c.binding()?.type; const callableBindingStructuredType = callableBindingType !== undefined ? this.findStructuredType(callableBindingType) : undefined; return (isCallableType && (!bindingStructuredType || (callableBindingStructuredType && bindingStructuredType.isSubtypeOf(callableBindingStructuredType)))); }); this.memo.callables.set(key, callable); return callable; } //#endregion //#region EntitySets findEntitySet(value) { if (this.memo.entitySets.has(value)) { return this.memo.entitySets.get(value); } const entitySets = this.schemas.reduce((acc, schema) => [...acc, ...schema.entitySets], []); let entitySet = entitySets.find((e) => e.type() === value); entitySet = entitySet ?? entitySets.find((e) => e.name === value); this.memo.entitySets.set(value, entitySet); return entitySet; } //#endregion //#region Singletons findSingleton(value) { if (this.memo.singletons.has(value)) { return this.memo.singletons.get(value); } const singletons = this.schemas.reduce((acc, schema) => [...acc, ...schema.singletons], []); let singleton = singletons.find((e) => e.type() === value); singleton = singleton ?? singletons.find((e) => e.name === value); this.memo.singletons.set(value, singleton); return singleton; } //#endregion findModel(type) { return this.findStructuredType(type)?.model; } createModel(structured) { if (structured.model !== undefined) return structured.model; // Build Ad-hoc model const Model = class extends ODataModel { }; // Build Meta Model.meta = this.optionsForType(structured.type(), { structuredType: structured, }); if (Model.meta !== undefined) { // Configure Model.meta.configure({ options: this.options.parserOptions, }); } // Store New Model for next time structured.model = Model; return Model; } modelForType(type) { let Model = this.findModel(type); if (Model === undefined) { const structured = this.findStructuredType(type); if (structured === undefined) throw Error(`No structured type for ${type}`); Model = this.createModel(structured); } return Model; } findCollection(type) { return this.findStructuredType(type)?.collection; } createCollection(structured, model) { if (structured.collection !== undefined) return structured.collection; if (model === undefined) model = this.createModel(structured); const Collection = class extends ODataCollection { static model = model; }; structured.collection = Collection; return Collection; } collectionForType(type) { let Collection = this.findCollection(type); if (Collection === undefined) { const structured = this.findStructuredType(type); if (structured === undefined) throw Error(`No structured type for ${type}`); const Model = this.modelForType(type); Collection = this.createCollection(structured, Model); } return Collection; } findEntitySetForEntityType(entityType) { if (this.memo.entitySets.has(entityType)) { return this.memo.entitySets.get(entityType); } const entitySet = this.schemas .reduce((acc, schema) => [...acc, ...schema.entitySets], []) .find((e) => e.entityType === entityType); this.memo.entitySets.set(entityType, entitySet); return entitySet; } parserForType(type, bindingType) { const key = bindingType !== undefined ? `${bindingType}/${type}` : type; if (this.memo.parsers.has(key)) { return this.memo.parsers.get(key); } // None Parser by default let parser = NONE_PARSER; if (this.parsers.has(type)) { // Edm, Base Parsers parser = this.parsers.get(type); } else if (!type.startsWith('Edm.')) { // Callable, EnumType, StructuredType (ComplexType and EntityType) Parsers let value = this.findCallable(type, bindingType) ?? this.findEnumType(type) ?? this.findStructuredType(type); parser = value?.parser; } // Set Parser for next time this.memo.parsers.set(key, parser); return parser; } optionsForType(type, { structuredType, config, } = {}) { // Strucutred Options if (this.memo.options.has(type)) { return this.memo.options.get(type); } let meta = undefined; if (!type.startsWith('Edm.')) { structuredType = this.findStructuredType(type) ?? structuredType; if (structuredType !== undefined) { meta = ODataModel.buildMetaOptions({ config, structuredType }); } } // Set Options for next time this.memo.options.set(type, meta); return meta; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBpLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci1vZGF0YS9zcmMvbGliL2FwaS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWEsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDaEUsT0FBTyxFQUFFLEtBQUssRUFBYyxNQUFNLE1BQU0sQ0FBQztBQUN6QyxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2pELE9BQU8sRUFBYyxrQkFBa0IsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6RCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzlDLE9BQU8sRUFFTCxlQUFlLEVBQ2YsVUFBVSxHQUVYLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFNUMsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixpQkFBaUIsRUFDakIsWUFBWSxFQUNaLGFBQWEsRUFDYixrQkFBa0IsRUFDbEIscUJBQXFCLEVBQ3JCLG1CQUFtQixFQUNuQixxQkFBcUIsRUFDckIsbUJBQW1CLEVBQ25CLHNCQUFzQixFQUN0QixzQkFBc0IsRUFDdEIsK0JBQStCLEdBQ2hDLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFDTCxXQUFXLEVBSVgsV0FBVyxHQUdaLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFJTCxXQUFXLEVBR1gsV0FBVyxHQUdaLE1BQU0sU0FBUyxDQUFDO0FBR2pCOztHQUVHO0FBQ0gsTUFBTSxPQUFPLFFBQVE7SUFDbkIsU0FBUyxDQUFtRDtJQUM1RCxjQUFjLENBQVM7SUFDdkIsV0FBVyxDQUFTO0lBQ3BCLElBQUksQ0FBVTtJQUNkLE9BQU8sQ0FBZTtJQUN0QixPQUFPLENBQVU7SUFDakIsUUFBUSxDQUFPO0lBQ2YsVUFBVTtJQUNWLE9BQU8sQ0FBa0I7SUFD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QztJQUNoQixDQUFDO0lBRU0sY0FBYyxDQUNuQixJQUFZLEVBQ1osRUFDRSxjQUFjLEVBQ2QsTUFBTSxNQUNnRSxFQUFFO1FBRTFFLHFCQUFxQjtRQUNyQixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ2hDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBcUMsQ0FBQztRQUN6RSxDQUFDO1FBRUQsSUFBSSxJQUFJLEdBQXFDLFNBQVMsQ0FBQztRQUN2RCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQzdCLGNBQWMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUksSUFBSSxDQUFDLElBQUksY0FBYyxDQUFDO1lBQ3BFLElBQUksY0FBYyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUNqQyxJQUFJLEdBQUcsVUFBVSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUM7WUFDakUsQ0FBQztRQUNILENBQUM7UUFDRCw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNsQyxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBFdmVudCwgSHR0cEV2ZW50VHlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IE5FVkVSLCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBPRGF0YUNhY2hlLCBPRGF0YUluTWVtb3J5Q2FjaGUgfSBmcm9tICcuL2NhY2hlJztcbmltcG9ydCB7IERFRkFVTFRfVkVSU0lPTiB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7XG4gIE1vZGVsT3B0aW9ucyxcbiAgT0RhdGFDb2xsZWN0aW9uLFxuICBPRGF0YU1vZGVsLFxuICBPRGF0YU1vZGVsT3B0aW9ucyxcbn0gZnJvbSAnLi9tb2RlbHMnO1xuaW1wb3J0IHsgT0RhdGFBcGlPcHRpb25zIH0gZnJvbSAnLi9vcHRpb25zJztcbmltcG9ydCB7IE9EYXRhT3B0aW9ucywgT0RhdGFSZXNvdXJjZSwgT0RhdGFTZWdtZW50IH0gZnJvbSAnLi9yZXNvdXJjZXMnO1xuaW1wb3J0IHtcbiAgT0RhdGFRdWVyeU9wdGlvbnMsXG4gIE9EYXRhUGF0aFNlZ21lbnRzLFxuICBPRGF0YVJlcXVlc3QsXG4gIE9EYXRhUmVzcG9uc2UsXG4gIE9EYXRhQmF0Y2hSZXNvdXJjZSxcbiAgT0RhdGFNZXRhZGF0YVJlc291cmNlLFxuICBPRGF0YUFjdGlvblJlc291cmNlLFxuICBPRGF0YUZ1bmN0aW9uUmVzb3VyY2UsXG4gIE9EYXRhRW50aXR5UmVzb3VyY2UsXG4gIE9EYXRhRW50aXR5U2V0UmVzb3VyY2UsXG4gIE9EYXRhU2luZ2xldG9uUmVzb3VyY2UsXG4gIE9EYXRhTmF2aWdhdGlvblByb3BlcnR5UmVzb3VyY2UsXG59IGZyb20gJy4vcmVzb3VyY2VzJztcbmltcG9ydCB7XG4gIEVETV9QQVJTRVJTLFxuICBPRGF0YUNhbGxhYmxlLFxuICBPRGF0YUVudGl0eVNldCxcbiAgT0RhdGFFbnVtVHlwZSxcbiAgT0RhdGFTY2hlbWEsXG4gIE9EYXRhU2luZ2xldG9uLFxuICBPRGF0YVN0cnVjdHVyZWRUeXBlLFxufSBmcm9tICcuL3NjaGVtYSc7XG5pbXBvcnQge1xuICBBcGlDb25maWcsXG4gIEFwaU9wdGlvbnMsXG4gIEVkbVR5cGUsXG4gIE5PTkVfUEFSU0VSLFxuICBPRGF0YVZlcnNpb24sXG4gIFBhcnNlcixcbiAgUGF0aFNlZ21lbnQsXG4gIFF1ZXJ5T3B0aW9uLFxuICBTY2hlbWFDb25maWcsXG59IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IHsgT0RhdGFNZXRhZGF0YSB9IGZyb20gJy4vbWV0YWRhdGEvbWV0YWRhdGEnO1xuXG4vKipcbiAqIEFwaSBhYnN0cmFjdGlvbiBmb3IgY29uc3VtaW5nIE9EYXRhIHNlcnZpY2VzLlxuICovXG5leHBvcnQgY2xhc3MgT0RhdGFBcGkge1xuICByZXF1ZXN0ZXI/OiAocmVxdWVzdDogT0RhdGFSZXF1ZXN0PGFueT4pID0+IE9ic2VydmFibGU8YW55PjtcbiAgc2VydmljZVJvb3RVcmw6IHN0cmluZztcbiAgbWV0YWRhdGFVcmw6IHN0cmluZztcbiAgbmFtZT86IHN0cmluZztcbiAgdmVyc2lvbjogT0RhdGFWZXJzaW9uO1xuICBkZWZhdWx0OiBib29sZWFuO1xuICBjcmVhdGlvbjogRGF0ZTtcbiAgLy8gT3B0aW9uc1xuICBvcHRpb25zOiBPRGF0YUFwaU9wdGlvbnM7XG4gIC8vIENhY2hlXG4gIGNhY2hlITogT0RhdGFDYWNoZTtcbiAgLy8gRXJyb3IgSGFuZGxlclxuICBlcnJvckhhbmRsZXI/OiAoZXJyb3I6IGFueSwgY2F1Z2h0OiBPYnNlcnZhYmxlPGFueT4pID0+IE9ic2VydmFibGU8bmV2ZXI+O1xuICAvLyBCYXNlIFBhcnNlcnNcbiAgcGFyc2VyczogTWFwPHN0cmluZywgUGFyc2VyPGFueT4+O1xuICAvLyBTY2hlbWFzXG4gIHNjaGVtYXM6IE9EYXRhU2NoZW1hW107XG5cbiAgY29uc3RydWN0b3IoY29uZmlnOiBBcGlDb25maWcpIHtcbiAgICB0aGlzLnNlcnZpY2VSb290VXJsID0gY29uZmlnLnNlcnZpY2VSb290VXJsO1xuICAgIGlmICh0aGlzLnNlcnZpY2VSb290VXJsLmluY2x1ZGVzKCc/JykpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiVGhlICdzZXJ2aWNlUm9vdFVybCcgc2hvdWxkIG5vdCBjb250YWluIHF1ZXJ5IHN0cmluZy4gUGxlYXNlIHVzZSAncGFyYW1zJyB0byBhZGQgZXh0cmEgcGFyYW1ldGVyc1wiLFxuICAgICAgKTtcbiAgICBpZiAoIXRoaXMuc2VydmljZVJvb3RVcmwuZW5kc1dpdGgoJy8nKSkgdGhpcy5zZXJ2aWNlUm9vdFVybCArPSAnLyc7XG4gICAgdGhpcy5tZXRhZGF0YVVybCA9IGNvbmZpZy5tZXRhZGF0YVVybCA/PyBgJHt0aGlzLnNlcnZpY2VSb290VXJsfSRtZXRhZGF0YWA7XG4gICAgdGhpcy5uYW1lID0gY29uZmlnLm5hbWU7XG4gICAgdGhpcy52ZXJzaW9uID0gY29uZmlnLnZlcnNpb24gPz8gREVGQVVMVF9WRVJTSU9OO1xuICAgIHRoaXMuZGVmYXVsdCA9IGNvbmZpZy5kZWZhdWx0ID8/IGZhbHNlO1xuICAgIHRoaXMuY3JlYXRpb24gPSBjb25maWcuY3JlYXRpb24gPz8gbmV3IERhdGUoKTtcbiAgICB0aGlzLm9wdGlvbnMgPSBuZXcgT0RhdGFBcGlPcHRpb25zKHtcbiAgICAgIC4uLmNvbmZpZy5vcHRpb25zLFxuICAgICAgdmVyc2lvbjogdGhpcy52ZXJzaW9uLFxuICAgIH0pO1xuXG4gICAgdGhpcy5jYWNoZSA9IChjb25maWcuY2FjaGUgYXMgT0RhdGFDYWNoZSkgPz8gbmV3IE9EYXRhSW5NZW1vcnlDYWNoZSgpO1xuICAgIHRoaXMuZXJyb3JIYW5kbGVyID0gY29uZmlnLmVycm9ySGFuZGxlcjtcbiAgICB0aGlzLnBhcnNlcnMgPSBuZXcgTWFwKE9iamVjdC5lbnRyaWVzKGNvbmZpZy5wYXJzZXJzID8/IEVETV9QQVJTRVJTKSk7XG5cbiAgICB0aGlzLnNjaGVtYXMgPSAoY29uZmlnLnNjaGVtYXMgPz8gW10pLm1hcChcbiAgICAgIChzY2hlbWEpID0+IG5ldyBPRGF0YVNjaGVtYShzY2hlbWEsIHRoaXMpLFxuICAgICk7XG4gIH1cblxuICBjb25maWd1cmUoXG4gICAgc2V0dGluZ3M6IHtcbiAgICAgIHJlcXVlc3Rlcj86IChyZXF1ZXN0OiBPRGF0YVJlcXVlc3Q8YW55PikgPT4gT2JzZXJ2YWJsZTxhbnk+O1xuICAgIH0gPSB7fSxcbiAgKSB7XG4gICAgdGhpcy5yZXF1ZXN0ZXIgPSBzZXR0aW5ncy5yZXF1ZXN0ZXI7XG4gICAgdGhpcy5zY2hlbWFzLmZvckVhY2goKHNjaGVtYSkgPT4ge1xuICAgICAgc2NoZW1hLmNvbmZpZ3VyZSh7XG4gICAgICAgIG9wdGlvbnM6IHRoaXMub3B0aW9ucy5wYXJzZXJPcHRpb25zLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwb3B1bGF0ZShtZXRhZGF0YTogT0RhdGFNZXRhZGF0YSkge1xuICAgIGNvbnN0IGNvbmZpZyA9IG1ldGFkYXRhLnRvQ29uZmlnKCk7XG4gICAgdGhpcy52ZXJzaW9uID0gY29uZmlnLnZlcnNpb24gPz8gREVGQVVMVF9WRVJTSU9OO1xuICAgIGNvbnN0IHNjaGVtYXMgPSAoY29uZmlnLnNjaGVtYXMgPz8gW10pLm1hcChcbiAgICAgIChzY2hlbWEpID0+IG5ldyBPRGF0YVNjaGVtYShzY2hlbWEsIHRoaXMpLFxuICAgICk7XG4gICAgdGhpcy5zY2hlbWFzID0gWy4uLnRoaXMuc2NoZW1hcywgLi4uc2NoZW1hc107XG4gICAgc2NoZW1hcy5mb3JFYWNoKChzY2hlbWEpID0+IHtcbiAgICAgIHNjaGVtYS5jb25maWd1cmUoe1xuICAgICAgICBvcHRpb25zOiB0aGlzLm9wdGlvbnMucGFyc2VyT3B0aW9ucyxcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgZnJvbUpzb248UCwgUj4oanNvbjoge1xuICAgIHNlZ21lbnRzOiBPRGF0YVNlZ21lbnRbXTtcbiAgICBvcHRpb25zOiB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfTtcbiAgfSk6IE9EYXRhQWN0aW9uUmVzb3VyY2U8UCwgUj4gfCBPRGF0YUZ1bmN0aW9uUmVzb3VyY2U8UCwgUj47XG4gIGZyb21Kc29uPEU+KGpzb246IHtcbiAgICBzZWdtZW50czogT0RhdGFTZWdtZW50W107XG4gICAgb3B0aW9uczogeyBbbmFtZTogc3RyaW5nXTogYW55IH07XG4gIH0pOlxuICAgIHwgT0RhdGFFbnRpdHlSZXNvdXJjZTxFPlxuICAgIHwgT0RhdGFFbnRpdHlTZXRSZXNvdXJjZTxFPlxuICAgIHwgT0RhdGFOYXZpZ2F0aW9uUHJvcGVydHlSZXNvdXJjZTxFPlxuICAgIHwgT0RhdGFTaW5nbGV0b25SZXNvdXJjZTxFPjtcbiAgZnJvbUpzb24oanNvbjoge1xuICAgIHNlZ21lbnRzOiBPRGF0YVNlZ21lbnRbXTtcbiAgICBvcHRpb25zOiB7IFtuYW1lOiBzdHJpbmddOiBhbnkgfTtcbiAgfSkge1xuICAgIGNvbnN0IHNlZ21lbnRzID0gT0RhdGFQYXRoU2VnbWVudHMuZnJvbUpzb24oanNvbi5zZWdtZW50cyk7XG4gICAgY29uc3QgcXVlcnkgPSBPRGF0YVF1ZXJ5T3B0aW9ucy5mcm9tSnNvbjxhbnk+KGpzb24ub3B0aW9ucyk7XG4gICAgc3dpdGNoIChzZWdtZW50cy5sYXN0KCk/Lm5hbWUgYXMgUGF0aFNlZ21lbnQpIHtcbiAgICAgIGNhc2UgUGF0aFNlZ21lbnQuZW50aXR5U2V0OlxuICAgICAgICBpZiAoc2VnbWVudHMubGFzdCgpPy5oYXNLZXkoKSkge1xuICAgICAgICAgIHJldHVybiBuZXcgT0RhdGFFbnRpdHlSZXNvdXJjZSh0aGlzLCB7IHNlZ21lbnRzLCBxdWVyeSB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbmV3IE9EYXRhRW50aXR5U2V0UmVzb3VyY2UodGhpcywgeyBzZWdtZW50cywgcXVlcnkgfSk7XG4gICAgICAgIH1cbiAgICAgIGNhc2UgUGF0aFNlZ21lbnQubmF2aWdhdGlvblByb3BlcnR5OlxuICAgICAgICByZXR1cm4gbmV3IE9EYXRhTmF2aWdhdGlvblByb3BlcnR5UmVzb3VyY2UodGhpcywgeyBzZWdtZW50cywgcXVlcnkgfSk7XG4gICAgICBjYXNlIFBhdGhTZWdtZW50LnNpbmdsZXRvbjpcbiAgICAgICAgcmV0dXJuIG5ldyBPRGF0YVNpbmdsZXRvblJlc291cmNlKHRoaXMsIHsgc2VnbWVudHMsIHF1ZXJ5IH0pO1xuICAgICAgY2FzZSBQYXRoU2VnbWVudC5hY3Rpb246XG4gICAgICAgIHJldHVybiBuZXcgT0RhdGFBY3Rpb25SZXNvdXJjZSh0aGlzLCB7IHNlZ21lbnRzLCBxdWVyeSB9KTtcbiAgICAgIGNhc2UgUGF0aFNlZ21lbnQuZnVuY3Rpb246XG4gICAgICAgIHJldHVybiBuZXcgT0RhdGFGdW5jdGlvblJlc291cmNlKHRoaXMsIHsgc2VnbWVudHMsIHF1ZXJ5IH0pO1xuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIFJlc291cmNlIGZvciBqc29uJyk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBtZXRhZGF0YSByZXNvdXJjZS5cbiAgICogQHJldHVybnMgT0RhdGFNZXRhZGF0YVJlc291cmNlXG4gICAqL1xuICBtZXRhZGF0YSgpOiBPRGF0YU1ldGFkYXRhUmVzb3VyY2Uge1xuICAgIHJldHVybiBPRGF0YU1ldGFkYXRhUmVzb3VyY2UuZmFjdG9yeSh0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhIGJhdGNoIHJlc291cmNlLlxuICAgKiBAcmV0dXJucyBPRGF0YUJhdGNoUmVzb3VyY2VcbiAgICovXG4gIGJhdGNoKCk6IE9EYXRhQmF0Y2hSZXNvdXJjZSB7XG4gICAgcmV0dXJuIE9EYXRhQmF0Y2hSZXNvdXJjZS5mYWN0b3J5KHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIGEgc2luZ2xldG9uIHJlc291cmNlLlxuICAgKiBAcGFyYW0gcGF0aCBOYW1lIG9mIHRoZSBzaW5nbGV0b25cbiAgICogQHJldHVybnNcbiAgICovXG4gIHNpbmdsZXRvbjxUPihuYW1lOiBzdHJpbmcpIHtcbiAgICBjb25zdCBzaW5nbGV0b24gPSB0aGlzLmZpbmRTaW5nbGV0b24obmFtZSk7XG4gICAgcmV0dXJuIE9EYXRhU2luZ2xldG9uUmVzb3VyY2UuZmFjdG9yeTxUPih0aGlzLCB7XG4gICAgICBwYXRoOiBzaW5nbGV0b24/Lm5hbWUgPz8gbmFtZSxcbiAgICAgIHR5cGU6IHNpbmdsZXRvbj8uc2luZ2xldG9uVHlwZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhbiBlbnRpdHkgc2V0IHJlc291cmNlLlxuICAgKiBAcGFyYW0gcGF0aCBOYW1lIG9mIHRoZSBlbnRpdHkgc2V0XG4gICAqIEByZXR1cm5zXG4gICAqL1xuICBlbnRpdHlTZXQ8VD4obmFtZTogc3RyaW5nKTogT0RhdGFFbnRpdHlTZXRSZXNvdXJjZTxUPiB7XG4gICAgY29uc3QgZW50aXR5U2V0ID0gdGhpcy5maW5kRW50aXR5U2V0KG5hbWUpO1xuICAgIHJldHVybiBPRGF0YUVudGl0eVNldFJlc291cmNlLmZhY3Rvcnk8VD4odGhpcywge1xuICAgICAgcGF0aDogZW50aXR5U2V0Py5uYW1lID8/IG5hbWUsXG4gICAgICB0eXBlOiBlbnRpdHlTZXQ/LmVudGl0eVR5cGUsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVW5ib3VuZCBBY3Rpb25cbiAgICogQHBhcmFtICB7c3RyaW5nfSBwYXRoP1xuICAgKiBAcmV0dXJucyBPRGF0YUFjdGlvblJlc291cmNlXG4gICAqL1xuICBhY3Rpb248UCwgUj4ocGF0aDogc3RyaW5nKTogT0RhdGFBY3Rpb25SZXNvdXJjZTxQLCBSPiB7XG4gICAgY29uc3QgY2FsbGFibGUgPSB0aGlzLmZpbmRDYWxsYWJsZTxSPihwYXRoKTtcbiAgICByZXR1cm4gT0RhdGFBY3Rpb25SZXNvdXJjZS5mYWN0b3J5PFAsIFI+KHRoaXMsIHtcbiAgICAgIHBhdGgsXG4gICAgICBvdXRnb2luZ1R5cGU6IGNhbGxhYmxlPy50eXBlKCksXG4gICAgICBpbmNvbWluZ1R5cGU6IGNhbGxhYmxlPy5yZXR1cm5UeXBlKCksXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVW5ib3VuZCBGdW5jdGlvblxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHBhdGg/XG4gICAqIEByZXR1cm5zIE9EYXRhRnVuY3Rpb25SZXNvdXJjZVxuICAgKi9cbiAgZnVuY3Rpb248UCwgUj4ocGF0aDogc3RyaW5nKTogT0RhdGFGdW5jdGlvblJlc291cmNlPFAsIFI+IHtcbiAgICBjb25zdCBjYWxsYWJsZSA9IHRoaXMuZmluZENhbGxhYmxlPFI+KHBhdGgpO1xuICAgIHJldHVybiBPRGF0YUZ1bmN0aW9uUmVzb3VyY2UuZmFjdG9yeTxQLCBSPih0aGlzLCB7XG4gICAgICBwYXRoLFxuICAgICAgb3V0Z29pbmdUeXBlOiBjYWxsYWJsZT8udHlwZSgpLFxuICAgICAgaW5jb21pbmdUeXBlOiBjYWxsYWJsZT8ucmV0dXJuVHlwZSgpLFxuICAgIH0pO1xuICB9XG5cbiAgY2FsbGFibGU8VD4odHlwZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluZENhbGxhYmxlPFQ+KHR5cGUpO1xuICB9XG5cbiAgZW51bVR5cGU8VD4odHlwZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluZEVudW1UeXBlPFQ+KHR5cGUpO1xuICB9XG5cbiAgc3RydWN0dXJlZFR5cGU8VD4odHlwZTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZmluZFN0cnVjdHVyZWRUeXBlPFQ+KHR5cGUpO1xuICB9XG5cbiAgLy9yZXF1ZXN0KHJlcTogT0RhdGFSZXF1ZXN0PGFueT4pOiBPYnNlcnZhYmxlPGFueT4ge1xuICByZXF1ZXN0PFQ+KFxuICAgIG1ldGhvZDogc3RyaW5nLFxuICAgIHJlc291cmNlOiBPRGF0YVJlc291cmNlPGFueT4sXG4gICAgb3B0aW9uczogT0RhdGFPcHRpb25zICYge1xuICAgICAgYm9keT86IGFueTtcbiAgICAgIGV0YWc/OiBzdHJpbmc7XG4gICAgICByZXNwb25zZVR5cGU/OlxuICAgICAgICB8ICdhcnJheWJ1ZmZlcidcbiAgICAgICAgfCAnYmxvYidcbiAgICAgICAgfCAnanNvbidcbiAgICAgICAgfCAndGV4dCdcbiAgICAgICAgfCAndmFsdWUnXG4gICAgICAgIHwgJ3Byb3BlcnR5J1xuICAgICAgICB8ICdlbnRpdHknXG4gICAgICAgIHwgJ2VudGl0aWVzJztcbiAgICAgIG9ic2VydmU/OiAnYm9keScgfCAnZXZlbnRzJyB8ICdyZXNwb25zZSc7XG4gICAgICB3aXRoQ291bnQ/OiBib29sZWFuO1xuICAgICAgYm9keVF1ZXJ5T3B0aW9ucz86IFF1ZXJ5T3B0aW9uW107XG4gICAgfSxcbiAgKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICBsZXQgcmVxID0gT0RhdGFSZXF1ZXN0LmZhY3RvcnkodGhpcywgbWV0aG9kLCByZXNvdXJjZSwge1xuICAgICAgYm9keTogb3B0aW9ucy5ib2R5LFxuICAgICAgZXRhZzogb3B0aW9ucy5ldGFnLFxuICAgICAgY29udGV4dDogb3B0aW9ucy5jb250ZXh0LFxuICAgICAgaGVhZGVyczogb3B0aW9ucy5oZWFkZXJzLFxuICAgICAgcGFyYW1zOiBvcHRpb25zLnBhcmFtcyxcbiAgICAgIHJlc3BvbnNlVHlwZTogb3B0aW9ucy5yZXNwb25zZVR5cGUsXG4gICAgICBvYnNlcnZlOiAob3B0aW9ucy5vYnNlcnZlID09PSAnZXZlbnRzJyA/ICdldmVudHMnIDogJ3Jlc3BvbnNlJykgYXNcbiAgICAgICAgfCAnZXZlbnRzJ1xuICAgICAgICB8ICdyZXNwb25zZScsXG4gICAgICB3aXRoQ291bnQ6IG9wdGlvbnMud2l0aENvdW50LFxuICAgICAgYm9keVF1ZXJ5T3B0aW9uczogb3B0aW9ucy5ib2R5UXVlcnlPcHRpb25zLFxuICAgICAgcmVwb3J0UHJvZ3Jlc3M6IG9wdGlvbnMucmVwb3J0UHJvZ3Jlc3MsXG4gICAgICBmZXRjaFBvbGljeTogb3B0aW9ucy5mZXRjaFBvbGljeSxcbiAgICAgIHBhcnNlck9wdGlvbnM6IG9wdGlvbnMucGFyc2VyT3B0aW9ucyxcbiAgICAgIHdpdGhDcmVkZW50aWFsczogb3B0aW9ucy53aXRoQ3JlZGVudGlhbHMsXG4gICAgfSk7XG5cbiAgICBsZXQgcmVzJCA9IHRoaXMucmVxdWVzdGVyICE9PSB1bmRlZmluZWQgPyB0aGlzLnJlcXVlc3RlcihyZXEpIDogTkVWRVI7XG5cbiAgICByZXMkID0gcmVzJC5waXBlKFxuICAgICAgbWFwKChyZXM6IEh0dHBFdmVudDxhbnk+KSA9PlxuICAgICAgICByZXMudHlwZSA9PT0gSHR0cEV2ZW50VHlwZS5SZXNwb25zZVxuICAgICAgICAgID8gT0RhdGFSZXNwb25zZS5mcm9tSHR0cFJlc3BvbnNlPGFueT4ocmVxLCByZXMpXG4gICAgICAgICAgOiByZXMsXG4gICAgICApLFxuICAgICk7XG5cbiAgICBpZiAodGhpcy5lcnJvckhhbmRsZXIgIT09IHVuZGVmaW5lZClcbiAgICAgIHJlcyQgPSByZXMkLnBpcGUoY2F0Y2hFcnJvcih0aGlzLmVycm9ySGFuZGxlcikpO1xuXG4gICAgaWYgKG9wdGlvbnMub2JzZXJ2ZSA9PT0gJ2V2ZW50cycpIHtcbiAgICAgIHJldHVybiByZXMkO1xuICAgIH1cblxuICAgIHJlcyQgPSB0aGlzLmNhY2hlLmhhbmRsZVJlcXVlc3QocmVxLCByZXMkKTtcblxuICAgIHN3aXRjaCAob3B0aW9ucy5vYnNlcnZlIHx8ICdib2R5Jykge1xuICAgICAgY2FzZSAnYm9keSc6XG4gICAgICAgIHN3aXRjaCAob3B0aW9ucy5yZXNwb25zZVR5cGUpIHtcbiAgICAgICAgICBjYXNlICdlbnRpdGllcyc6XG4gICAgICAgICAgICByZXR1cm4gcmVzJC5waXBlKG1hcCgocmVzOiBPRGF0YVJlc3BvbnNlPFQ+KSA9PiByZXMuZW50aXRpZXMoKSkpO1xuICAgICAgICAgIGNhc2UgJ2VudGl0eSc6XG4gICAgICAgICAgICByZXR1cm4gcmVzJC5waXBlKG1hcCgocmVzOiBPRGF0YVJlc3BvbnNlPFQ+KSA9PiByZXMuZW5