From aed0b8aecd36ea2188a700076fcda721fc696146 Mon Sep 17 00:00:00 2001 From: Diullei Gomes Date: Wed, 6 Mar 2013 22:47:53 -0300 Subject: [PATCH] bug fix #369 - status property on angularjs response object --- angularjs/angular-tests.ts | 82 ++++++++++++++++++++++++++++++++++++++ angularjs/angular.d.ts | 73 ++++++++++++++++++--------------- 2 files changed, 122 insertions(+), 33 deletions(-) create mode 100644 angularjs/angular-tests.ts diff --git a/angularjs/angular-tests.ts b/angularjs/angular-tests.ts new file mode 100644 index 0000000000..e1426a1a4d --- /dev/null +++ b/angularjs/angular-tests.ts @@ -0,0 +1,82 @@ +/// + +// issue: https://github.com/borisyankov/DefinitelyTyped/issues/369 +https://github.com/witoldsz/angular-http-auth/blob/master/src/angular-http-auth.js +/** + * @license HTTP Auth Interceptor Module for AngularJS + * (c) 2012 Witold Szczerba + * License: MIT + */ +angular.module('http-auth-interceptor', []) + + .provider('authService', function () { + /** + * Holds all the requests which failed due to 401 response, + * so they can be re-requested in future, once login is completed. + */ + var buffer = []; + + /** + * Required by HTTP interceptor. + * Function is attached to provider to be invisible for regular users of this service. + */ + this.pushToBuffer = function (config: ng.IRequestConfig, deferred: ng.IDeferred) { + buffer.push({ + config: config, + deferred: deferred + }); + } + + this.$get = ['$rootScope', '$injector', function ($rootScope: ng.IScope, $injector: ng.auto.IInjectorService) { + var $http: ng.IHttpService; //initialized later because of circular dependency problem + function retry(config: ng.IRequestConfig, deferred: ng.IDeferred) { + $http = $http || $injector.get('$http'); + $http(config).then(function (response) { + deferred.resolve(response); + }); + } + function retryAll() { + for (var i = 0; i < buffer.length; ++i) { + retry(buffer[i].config, buffer[i].deferred); + } + buffer = []; + } + + return { + loginConfirmed: function () { + $rootScope.$broadcast('event:auth-loginConfirmed'); + retryAll(); + } + } + }] + }) + + /** + * $http interceptor. + * On 401 response - it stores the request and broadcasts 'event:angular-auth-loginRequired'. + */ + .config(['$httpProvider', 'authServiceProvider', function ($httpProvider: ng.IHttpProvider, authServiceProvider) { + + var interceptor = ['$rootScope', '$q', function ($rootScope: ng.IScope, $q: ng.IQService) { + function success(response: ng.PromiseCallbackArg) { + return response; + } + + function error(response: ng.PromiseCallbackArg) { + if (response.status === 401) { + var deferred = $q.defer(); + authServiceProvider.pushToBuffer(response.config, deferred); + $rootScope.$broadcast('event:auth-loginRequired'); + return deferred.promise; + } + // otherwise + return $q.reject(response); + } + + return function (promise: ng.IHttpPromise) { + return promise.then(success, error); + } + + }]; + $httpProvider.responseInterceptors.push(interceptor); + }]); \ No newline at end of file diff --git a/angularjs/angular.d.ts b/angularjs/angular.d.ts index 7fa05364d6..c5f5c3f87a 100644 --- a/angularjs/angular.d.ts +++ b/angularjs/angular.d.ts @@ -45,16 +45,16 @@ module ng { isString(value: any): bool; isUndefined(value: any): bool; lowercase(str: string): string; - /** construct your angular application + /** construct your angular application official docs: Interface for configuring angular modules. see: http://docs.angularjs.org/api/angular.Module */ module( - /** name of your module you want to create */ - name: string, - /** name of modules yours depends on */ - requires?: string[], - configFunction?: Function): IModule; + /** name of your module you want to create */ + name: string, + /** name of modules yours depends on */ + requires?: string[], + configFunction?: Function): IModule; noop(...args: any[]): void; toJson(obj: any, pretty?: bool): string; uppercase(str: string): string; @@ -72,11 +72,11 @@ module ng { // see http://docs.angularjs.org/api/angular.Module /////////////////////////////////////////////////////////////////////////// interface IModule { - /** configure existing services. + /** configure existing services. Use this method to register work which needs to be performed on module loading */ - config(configFn: Function): IModule; - /** configure existing services. + config(configFn: Function): IModule; + /** configure existing services. Use this method to register work which needs to be performed on module loading */ config(inlineAnnotadedFunction: any[]): IModule; @@ -84,17 +84,17 @@ module ng { controller(name: string, controllerConstructor: Function): IModule; controller(name: string, inlineAnnotadedConstructor: any[]): IModule; directive(name: string, directiveFactory: Function): IModule; - directive(name: string, inlineAnnotadedFunction: any[]): IModule; + directive(name: string, inlineAnnotadedFunction: any[]): IModule; factory(name: string, serviceFactoryFunction: Function): IModule; - factory(name: string, inlineAnnotadedFunction: any[]): IModule; + factory(name: string, inlineAnnotadedFunction: any[]): IModule; filter(name: string, filterFactoryFunction: Function): IModule; - filter(name: string, inlineAnnotadedFunction: any[]): IModule; + filter(name: string, inlineAnnotadedFunction: any[]): IModule; provider(name: string, serviceProviderConstructor: Function): IModule; provider(name: string, inlineAnnotadedConstructor: any[]): IModule; run(initializationFunction: Function): IModule; - run(inlineAnnotadedFunction: any[]): IModule; + run(inlineAnnotadedFunction: any[]): IModule; service(name: string, serviceConstructor: Function): IModule; - service(name: string, inlineAnnotadedConstructor: any[]): IModule; + service(name: string, inlineAnnotadedConstructor: any[]): IModule; value(name: string, value: any): IModule; // Properties @@ -139,14 +139,14 @@ module ng { // XXX Same as avove $modelValue: any; - + $parsers: IModelParser[]; $formatters: IModelFormatter[]; $error: any; $pristine: bool; $dirty: bool; $valid: bool; - $invalid: bool; + $invalid: bool; } interface IModelParser { @@ -165,12 +165,12 @@ module ng { // Documentation says exp is optional, but actual implementaton counts on it $apply(exp: string): any; $apply(exp: (scope: IScope) => any): any; - + $broadcast(name: string, ...args: any[]): IAngularEvent; $destroy(): void; $digest(): void; $emit(name: string, ...args: any[]): IAngularEvent; - + // Documentation says exp is optional, but actual implementaton counts on it $eval(expression: string): any; $eval(expression: (scope: IScope) => any): any; @@ -183,25 +183,25 @@ module ng { $new(isolate?: bool): IScope; $on(name: string, listener: (event: IAngularEvent, ...args: any[]) => any): Function; - + $watch(watchExpression: string, listener?: string, objectEquality?: bool): Function; $watch(watchExpression: string, listener?: (newValue: any, oldValue: any, scope: IScope) => any, objectEquality?: bool): Function; $watch(watchExpression: (scope: IScope) => any, listener?: string, objectEquality?: bool): Function; $watch(watchExpression: (scope: IScope) => any, listener?: (newValue: any, oldValue: any, scope: IScope) => any, objectEquality?: bool): Function; - + $id: number; } interface IAngularEvent { targetScope: IScope; currentScope: IScope; - name: string; + name: string; preventDefault: Function; defaultPrevented: bool; // Available only events that were $emit-ted stopPropagation?: Function; - } + } /////////////////////////////////////////////////////////////////////////// // WindowService @@ -385,8 +385,15 @@ module ng { when(value: any): IPromise; } + interface PromiseCallbackArg { + data?: any; + status?: number; + headers?: (headerName: string) => string; + config?: IRequestConfig; + } + interface IPromise { - then(successCallback: Function, errorCallback?: Function): IPromise; + then(successCallback: (response: PromiseCallbackArg) => any, errorCallback?: (response: PromiseCallbackArg) => any): IPromise; } interface IDeferred { @@ -420,7 +427,7 @@ module ng { // Methods bellow are not documented info(): any; - get(cacheId: string): ICacheObject; + get (cacheId: string): ICacheObject; } interface ICacheObject { @@ -432,7 +439,7 @@ module ng { //capacity: number; }; put(key: string, value?: any): void; - get(key: string): any; + get (key: string): any; remove(key: string): void; removeAll(): void; destroy(): void; @@ -484,8 +491,8 @@ module ng { interface IHttpService { // At least moethod and url must be provided... (config: IRequestConfig): IHttpPromise; - get(url: string, RequestConfig?: any): IHttpPromise; - delete(url: string, RequestConfig?: any): IHttpPromise; + get (url: string, RequestConfig?: any): IHttpPromise; + delete (url: string, RequestConfig?: any): IHttpPromise; head(url: string, RequestConfig?: any): IHttpPromise; jsonp(url: string, RequestConfig?: any): IHttpPromise; post(url: string, data: any, RequestConfig?: any): IHttpPromise; @@ -503,10 +510,10 @@ module ng { method: string; url: string; params?: any; - + // XXX it has it's own structure... perhaps we should define it in the future headers?: any; - + cache?: any; timeout?: number; withCredentials?: bool; @@ -522,7 +529,7 @@ module ng { error(callback: (data: any, status: number, headers: (headerName: string) => string, config: IRequestConfig) => any): IHttpPromise; } - interface IHttpProvider extends IServiceProvider { + interface IHttpProvider extends IServiceProvider { defaults: IRequestConfig; responseInterceptors: any[]; } @@ -589,7 +596,7 @@ module ng { // May not always be available. For instance, current will not be available // to a controller that was not initialized as a result of a route maching. current?: ICurrentRoute; - } + } // see http://docs.angularjs.org/api/ng.$routeProvider#when for options explanations interface IRoute { @@ -626,7 +633,7 @@ module ng { interface IInjectorService { annotate(fn: Function): string[]; annotate(inlineAnnotadedFunction: any[]): string[]; - get(name: string): any; + get (name: string): any; instantiate(typeConstructor: Function, locals?: any): any; invoke(func: Function, context?: any, locals?: any): any; } @@ -651,4 +658,4 @@ module ng { } -} +} \ No newline at end of file