<commit_before>'use strict';

import * as angular from 'angular';
import * as _ from 'lodash';

export interface IConverter<TDataType> {
	fromServer(raw: any): TDataType;
    toServer(data: TDataType): any,
}

export interface IRequestOptions {
    endpoint: string;
    useMock: boolean;
    logRequests: boolean;
}

export interface IGetListOptions<TDataType> extends IRequestOptions {
    params: any;
    getMockData(): TDataType[];
}

export interface IGetItemOptions<TDataType> extends IRequestOptions {
    getMockData(): TDataType;
}

export interface ICreateOptions<TDataType> extends IRequestOptions {
    domainObject: TDataType;
    addMockData(data: TDataType): void;
}

export interface IUpdateOptions<TDataType> extends IRequestOptions {
    domainObject: TDataType;
    updateMockData(data: TDataType): void;
}

export interface IDeleteOptions<TDataType> extends IRequestOptions {
    domainObject: TDataType;
    removeMockData(data: TDataType): void;
}

export interface IBaseDataServiceBehavior<TDataType> {
	getList(options: IGetListOptions<TDataType>): angular.IPromise<TDataType[]>;
    getItem(options: IGetItemOptions<TDataType>): angular.IPromise<TDataType>;
    create(options: ICreateOptions<TDataType>): angular.IPromise<TDataType>;
    update(options: IUpdateOptions<TDataType>): angular.IPromise<TDataType>;
    delete(options: IDeleteOptions<TDataType>): angular.IPromise<void>;
}

export class BaseDataServiceBehavior<TDataType> implements IBaseDataServiceBehavior<TDataType> {
    constructor(private $http: angular.IHttpService
            , private $q: angular.IQService
            , private transform: IConverter<TDataType> | {[index: string]: IConverter<any>}) { }

    getList(options: IGetListOptions<TDataType>): angular.IPromise<TDataType[]> {
        let promise: angular.IPromise<TDataType[]>;
        if (options.useMock) {
            promise = this.$q.when(options.getMockData());
        } else {
            promise = this.$http.get(options.endpoint, { params: options.params })
                .then((response: angular.IHttpPromiseCallbackArg<TDataType[]>): TDataType[] => {
                return response.data;
            });
        }
        return promise.then((data: TDataType[]): TDataType[] => {
			data = _.map(data, this.transformFromServer);
            if (options.logRequests) {
                this.log('getList', data, options.endpoint, options.useMock);
            }
            return data;
        })
    }

    getItem(options: IGetItemOptions<TDataType>): angular.IPromise<TDataType> {
        let promise: angular.IPromise<TDataType>;
        if (options.useMock) {
            promise = this.$q.when(options.getMockData());
        } else {
            promise = this.$http.get(options.endpoint)
                .then((response: angular.IHttpPromiseCallbackArg<TDataType>): TDataType => {
                return response.data;
            });
        }
        return promise.then((data: TDataType): TDataType => {
            data = this.transformFromServer(data);
            if (options.logRequests) {
                this.log('get', data, options.endpoint, options.useMock);
            }
            return data;
        });
    }

    create(options: ICreateOptions<TDataType>): angular.IPromise<TDataType> {
        let promise: angular.IPromise<TDataType>;
        options.domainObject = this.transformToServer(options.domainObject);
        if (options.useMock) {
            options.addMockData(options.domainObject);
            promise = this.$q.when(options.domainObject);
        } else {
            promise = this.$http.post(options.endpoint, JSON.stringify(options.domainObject))
                .then((result: angular.IHttpPromiseCallbackArg<TDataType>): TDataType => {
                return result.data;
            });
        }
        return promise.then((data: TDataType): TDataType => {
            data = this.transformFromServer(data);
            if (options.logRequests) {
                this.log('create', data, options.endpoint, options.useMock);
            }
            return data;
        });
    }

    update(options: IUpdateOptions<TDataType>): angular.IPromise<TDataType> {
        let promise: angular.IPromise<TDataType>;
        options.domainObject = this.transformToServer(options.domainObject);
        if (options.useMock) {
            options.updateMockData(options.domainObject)
            promise = this.$q.when(options.domainObject);
        } else {
            promise = this.$http.put(options.endpoint, options.domainObject)
                .then((result: angular.IHttpPromiseCallbackArg<TDataType>): TDataType => {
                return result.data;
            });
        }
        return promise.then((data: TDataType): TDataType => {
            data = this.transformFromServer(data);
            if (options.logRequests) {
                this.log('update', options.domainObject, options.endpoint, options.useMock);
            }
            return data;
        });
    }

    delete(options: IDeleteOptions<TDataType>): angular.IPromise<void> {
        let promise: angular.IPromise<void>;
        if (options.useMock) {
            options.removeMockData(options.domainObject);
            promise = this.$q.when();
        } else {
            promise = this.$http.delete<void>(options.endpoint).then((): void => { return null; });
        }
        return promise.then((): void => {
            if (options.logRequests) {
                this.log('delete', options.domainObject, options.endpoint, options.useMock);
            }
        });
    }

    private log(requestName: string, data: any, endpoint: string, useMock: boolean): void {
        let mockString = useMock ? 'Mocked ' : '';
        let endpointString = endpoint == null ? 'unspecified' : endpoint;
        console.log(mockString + requestName + ' for endpoint ' + endpointString + ':');
        console.log(data);
    }

    private transformFromServer(rawData: any): TDataType {
		if (this.isConverter(this.transform)) {
			return this.transform.fromServer(rawData);
		} else if (this.map != null) {
			return <any>_.mapValues(rawData, (prop: any, key: string): any => {
				if (_.has(this.map, key)) {
					return this.map[key].fromServer(prop);
				}
				return prop;
			});
		}

		return rawData;
    }

    private transformToServer(data: TDataType): any {
		if (this.isConverter(this.transform)) {
			return this.transform.toServer(data);
		} else if (this.map != null) {
			return <any>_.mapValues(data, (prop: any, key: string): any => {
				if (_.has(this.map, key)) {
					return this.map[key].toServer(prop);
				}
				return prop;
			});
		}
<commit_msg>Map no longer exists. Use transform instead<commit_after>'use strict';

import * as angular from 'angular';
import * as _ from 'lodash';

export interface IConverter<TDataType> {
	fromServer(raw: any): TDataType;
    toServer(data: TDataType): any,
}

export interface IRequestOptions {
    endpoint: string;
    useMock: boolean;
    logRequests: boolean;
}

export interface IGetListOptions<TDataType> extends IRequestOptions {
    params: any;
    getMockData(): TDataType[];
}

export interface IGetItemOptions<TDataType> extends IRequestOptions {
    getMockData(): TDataType;
}

export interface ICreateOptions<TDataType> extends IRequestOptions {
    domainObject: TDataType;
    addMockData(data: TDataType): void;
}

export interface IUpdateOptions<TDataType> extends IRequestOptions {
    domainObject: TDataType;
    updateMockData(data: TDataType): void;
}

export interface IDeleteOptions<TDataType> extends IRequestOptions {
    domainObject: TDataType;
    removeMockData(data: TDataType): void;
}

export interface IBaseDataServiceBehavior<TDataType> {
	getList(options: IGetListOptions<TDataType>): angular.IPromise<TDataType[]>;
    getItem(options: IGetItemOptions<TDataType>): angular.IPromise<TDataType>;
    create(options: ICreateOptions<TDataType>): angular.IPromise<TDataType>;
    update(options: IUpdateOptions<TDataType>): angular.IPromise<TDataType>;
    delete(options: IDeleteOptions<TDataType>): angular.IPromise<void>;
}

export class BaseDataServiceBehavior<TDataType> implements IBaseDataServiceBehavior<TDataType> {
    constructor(private $http: angular.IHttpService
            , private $q: angular.IQService
            , private transform: IConverter<TDataType> | {[index: string]: IConverter<any>}) { }

    getList(options: IGetListOptions<TDataType>): angular.IPromise<TDataType[]> {
        let promise: angular.IPromise<TDataType[]>;
        if (options.useMock) {
            promise = this.$q.when(options.getMockData());
        } else {
            promise = this.$http.get(options.endpoint, { params: options.params })
                .then((response: angular.IHttpPromiseCallbackArg<TDataType[]>): TDataType[] => {
                return response.data;
            });
        }
        return promise.then((data: TDataType[]): TDataType[] => {
			data = _.map(data, this.transformFromServer);
            if (options.logRequests) {
                this.log('getList', data, options.endpoint, options.useMock);
            }
            return data;
        })
    }

    getItem(options: IGetItemOptions<TDataType>): angular.IPromise<TDataType> {
        let promise: angular.IPromise<TDataType>;
        if (options.useMock) {
            promise = this.$q.when(options.getMockData());
        } else {
            promise = this.$http.get(options.endpoint)
                .then((response: angular.IHttpPromiseCallbackArg<TDataType>): TDataType => {
                return response.data;
            });
        }
        return promise.then((data: TDataType): TDataType => {
            data = this.transformFromServer(data);
            if (options.logRequests) {
                this.log('get', data, options.endpoint, options.useMock);
            }
            return data;
        });
    }

    create(options: ICreateOptions<TDataType>): angular.IPromise<TDataType> {
        let promise: angular.IPromise<TDataType>;
        options.domainObject = this.transformToServer(options.domainObject);
        if (options.useMock) {
            options.addMockData(options.domainObject);
            promise = this.$q.when(options.domainObject);
        } else {
            promise = this.$http.post(options.endpoint, JSON.stringify(options.domainObject))
                .then((result: angular.IHttpPromiseCallbackArg<TDataType>): TDataType => {
                return result.data;
            });
        }
        return promise.then((data: TDataType): TDataType => {
            data = this.transformFromServer(data);
            if (options.logRequests) {
                this.log('create', data, options.endpoint, options.useMock);
            }
            return data;
        });
    }

    update(options: IUpdateOptions<TDataType>): angular.IPromise<TDataType> {
        let promise: angular.IPromise<TDataType>;
        options.domainObject = this.transformToServer(options.domainObject);
        if (options.useMock) {
            options.updateMockData(options.domainObject)
            promise = this.$q.when(options.domainObject);
        } else {
            promise = this.$http.put(options.endpoint, options.domainObject)
                .then((result: angular.IHttpPromiseCallbackArg<TDataType>): TDataType => {
                return result.data;
            });
        }
        return promise.then((data: TDataType): TDataType => {
            data = this.transformFromServer(data);
            if (options.logRequests) {
                this.log('update', options.domainObject, options.endpoint, options.useMock);
            }
            return data;
        });
    }

    delete(options: IDeleteOptions<TDataType>): angular.IPromise<void> {
        let promise: angular.IPromise<void>;
        if (options.useMock) {
            options.removeMockData(options.domainObject);
            promise = this.$q.when();
        } else {
            promise = this.$http.delete<void>(options.endpoint).then((): void => { return null; });
        }
        return promise.then((): void => {
            if (options.logRequests) {
                this.log('delete', options.domainObject, options.endpoint, options.useMock);
            }
        });
    }

    private log(requestName: string, data: any, endpoint: string, useMock: boolean): void {
        let mockString = useMock ? 'Mocked ' : '';
        let endpointString = endpoint == null ? 'unspecified' : endpoint;
        console.log(mockString + requestName + ' for endpoint ' + endpointString + ':');
        console.log(data);
    }

    private transformFromServer(rawData: any): TDataType {
		if (this.isConverter(this.transform)) {
			return this.transform.fromServer(rawData);
		} else if (this.transform != null) {
			return <any>_.mapValues(rawData, (prop: any, key: string): any => {
				if (_.has(this.transform, key)) {
					return this.transform[key].fromServer(prop);
				}
				return prop;
			});
		}

		return rawData;
    }

    private transformToServer(data: TDataType): any {
		if (this.isConverter(this.transform)) {
			return this.transform.toServer(data);
		} else if (this.transform != null) {
			return <any>_.mapValues(data, (prop: any, key: string): any => {
				if (_.has(this.transform, key)) {
					return this.transform[key].toServer(prop);
				}
				return prop;
			});
		}

{'fraction_non_alphanumeric': 0.12408704724996274, 'fraction_numerical': 0.0, 'mean_word_length': 2.7337228714524207, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 113, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4820435', 'n_tokens_mistral': 3810, 'n_tokens_neox': 3841, 'n_words': 716}