angularjs-rails-resource 0.2.5 → 1.0.0.pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -2
- data/EXAMPLES.md +116 -116
- data/README.md +89 -38
- data/angularjs-rails-resource.js +157 -114
- data/angularjs-rails-resource.min.js +2 -2
- data/angularjs-rails-resource.zip +0 -0
- data/bower.json +1 -1
- data/lib/angularjs-rails-resource/version.rb +1 -1
- data/package.json +5 -5
- data/test/unit/angularjs/rails/resourceProviderSpec.js +12 -12
- data/test/unit/angularjs/rails/resourceSerializerSpec.js +1 -1
- data/test/unit/angularjs/rails/resourceSpec.js +99 -8
- data/test/unit/angularjs/rails/rootWrappingSpec.js +1 -1
- data/test/unit/angularjs/rails/serializationSpec.js +0 -16
- data/vendor/assets/javascripts/angularjs/rails/resource/resource.js +149 -97
- data/vendor/assets/javascripts/angularjs/rails/resource/serialization.js +6 -15
- data/vendor/assets/javascripts/angularjs/rails/resource/utils/url_builder.js +1 -1
- metadata +4 -4
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* A resource factory inspired by $resource from AngularJS
|
3
|
-
* @version
|
3
|
+
* @version v1.0.0-pre1 - 2013-10-06
|
4
4
|
* @link https://github.com/FineLinePrototyping/angularjs-rails-resource.git
|
5
5
|
* @author
|
6
6
|
*/
|
7
|
-
!function(){angular.module("rails",["ng"])}(),function(){angular.module("rails").factory("RailsInflector",function(){function a(a){return angular.isString(a)?a.replace(/_[\w\d]/g,function(a,b,c){return 0===b?a:c.charAt(b+1).toUpperCase()}):a}function b(a){return angular.isString(a)?a.replace(/[A-Z]/g,function(a,b){return 0===b?a:"_"+a.toLowerCase()}):a}function c(a){return a+"s"}return{camelize:a,underscore:b,pluralize:c}})}(),function(a){angular.module("rails").factory("RailsResourceInjector",["$injector",function(b){function c(c){return c?angular.isString(c)?b.get(c):c:a}function d(d){return d?b.instantiate(c(d)):a}return{createService:d,getDependency:c}}])}(),function(){angular.module("rails").factory("railsUrlBuilder",["$interpolate",function(a){return function(b){var c;return angular.isFunction(b)?b:(-1===b.indexOf(a.startSymbol())&&(b=b+"/"+a.startSymbol()+"id"+a.endSymbol()),c=a(b),function(a){return b=c(a),"/"===b.charAt(b.length-1)&&(b=b.substr(0,b.length-1)),b})}}])}(),function(a){angular.module("rails").provider("railsSerializer",function(){var b={underscore:a,camelize:a,pluralize:a,exclusionMatchers:[]};this.underscore=function(a){return b.underscore=a,this},this.camelize=function(a){return b.camelize=a,this},this.pluralize=function(a){return b.pluralize=a,this},this.exclusionMatchers=function(a){return b.exclusionMatchers=a,this},this.$get=["$injector","RailsInflector","RailsResourceInjector",function(c,d,e){function f(c,d){function f(){angular.isFunction(c)&&(d=c,c={}),this.exclusions={},this.inclusions={},this.serializeMappings={},this.deserializeMappings={},this.customSerializedAttributes={},this.preservedAttributes={},this.customSerializers={},this.nestedResources={},this.options=angular.extend({excludeByDefault:!1},b,c||{}),d&&d.call(this,this)}return f.prototype.exclude=function(){var a=this.exclusions;return angular.forEach(arguments,function(b){a[b]=!1}),this},f.prototype.only=function(){var a=this.inclusions;return this.options.excludeByDefault=!0,angular.forEach(arguments,function(b){a[b]=!0}),this},f.prototype.nestedAttribute=function(){var a=this;return angular.forEach(arguments,function(b){a.rename(b,b+"_attributes")}),this},f.prototype.resource=function(a,b,c){return this.nestedResources[a]=b,c&&this.serializeWith(a,c),this},f.prototype.rename=function(b,c,d){return this.serializeMappings[b]=c,(d||d===a)&&(this.deserializeMappings[c]=b),this},f.prototype.add=function(a,b){return this.customSerializedAttributes[a]=b,this},f.prototype.preserve=function(a){return this.preservedAttributes[a]=!0,this},f.prototype.serializeWith=function(a,b){return this.customSerializers[a]=b,this},f.prototype.isExcludedFromSerialization=function(b){if(this.options.excludeByDefault&&!this.inclusions.hasOwnProperty(b)||this.exclusions.hasOwnProperty(b))return!0;if(this.options.exclusionMatchers){var c=!1;return angular.forEach(this.options.exclusionMatchers,function(d){angular.isString(d)?c=c||0===b.indexOf(d):angular.isFunction(d)?c=c||d.call(a,b):d instanceof RegExp&&(c=c||d.test(b))}),c}return!1},f.prototype.getSerializedAttributeName=function(b){var c=this.serializeMappings[b]||b,d=this.isExcludedFromSerialization(c),e=this.isExcludedFromSerialization(b);if(this.options.excludeByDefault){if(d&&e)return a}else if(d||e)return a;return this.underscore(c)},f.prototype.isExcludedFromDeserialization=function(){return!1},f.prototype.getDeserializedAttributeName=function(b){var c=this.camelize(b);return c=this.deserializeMappings[b]||this.deserializeMappings[c]||c,this.isExcludedFromDeserialization(b)||this.isExcludedFromDeserialization(c)?a:c},f.prototype.getNestedResource=function(a){return e.getDependency(this.nestedResources[a])},f.prototype.getAttributeSerializer=function(b){var c=this.getNestedResource(b),d=this.customSerializers[b];return d?e.createService(d):c?c.serializer:a},f.prototype.serializeValue=function(a){var b=a,c=this;if(angular.isArray(a))b=[],angular.forEach(a,function(a){b.push(c.serializeValue(a))});else if(angular.isObject(a)){if(angular.isDate(a))return a;b={},angular.forEach(a,function(a,d){angular.isFunction(a)||c.serializeAttribute(b,d,a)})}return b},f.prototype.serializeAttribute=function(b,c,d){var e=this.getAttributeSerializer(c),f=this.getSerializedAttributeName(c);f!==a&&(b[f]=e?e.serialize(d):this.serializeValue(d))},f.prototype.serialize=function(a){var b=this.serializeValue(a),c=this;return angular.isObject(b)&&angular.forEach(this.customSerializedAttributes,function(d,e){angular.isFunction(d)&&(d=d.call(a,a)),c.serializeAttribute(b,e,d)}),b},f.prototype.deserializeValue=function(a,b){var c=a,d=this;if(angular.isArray(a))c=[],angular.forEach(a,function(a){c.push(d.deserializeValue(a,b))});else if(angular.isObject(a)){if(angular.isDate(a))return a;c={},b&&(c=new b),angular.forEach(a,function(a,b){d.deserializeAttribute(c,b,a)})}return c},f.prototype.deserializeAttribute=function(b,c,d){var e,f,g=this.getDeserializedAttributeName(c);g!==a&&(e=this.getAttributeSerializer(g),f=this.getNestedResource(g),b[g]=this.preservedAttributes[g]?d:e?e.deserialize(d,f):this.deserializeValue(d,f))},f.prototype.deserialize=function(a,b){return this.deserializeValue(a,b)},f.prototype.pluralize=function(a){return this.options.pluralize?this.options.pluralize(a):a},f.prototype.underscore=function(a){return this.options.underscore?this.options.underscore(a):a},f.prototype.camelize=function(a){return this.options.camelize?this.options.camelize(a):a},f}return b.underscore=b.underscore||d.underscore,b.camelize=b.camelize||d.camelize,b.pluralize=b.pluralize||d.pluralize,f.defaultOptions=b,f}]})}(),function(a){angular.module("rails").factory("railsRootWrappingTransformer",function(){return function(a,b){var c={};return c[angular.isArray(a)?b.rootPluralName:b.rootName]=a,c}}),angular.module("rails").factory("railsRootWrappingInterceptor",function(){return function(a){var b=a.resource;return b?a.then(function(a){return a.data&&a.data.hasOwnProperty(b.rootName)?a.data=a.data[b.rootName]:a.data&&a.data.hasOwnProperty(b.rootPluralName)&&(a.data=a.data[b.rootPluralName]),a}):a}}),angular.module("rails").provider("railsResourceFactory",function(){var b={enableRootWrapping:!0,updateMethod:"put",httpConfig:{},defaultParams:a};this.enableRootWrapping=function(a){return b.enableRootWrapping=a,this},this.updateMethod=function(a){return b.updateMethod=a,this},this.httpConfig=function(a){return b.httpConfig=a,this},this.defaultParams=function(a){return b.defaultParams=a,this},this.$get=["$http","$q","railsUrlBuilder","railsSerializer","railsRootWrappingTransformer","railsRootWrappingInterceptor","RailsResourceInjector",function(c,d,e,f,g,h,i){function j(d){function j(a,b){return b&&("/"!==b[0]&&(a+="/"),a+=b),a}function k(a){var b=this;if(a){var c=function(a){return{resource:k,context:b,response:a,then:function(a){return this.response=a(this.response,this.resource,this.context),c(this.response)}}},d=k.callInterceptors(c({data:a}),this).response.data;angular.extend(this,d)}}var l=d.requestTransformers,m=d.responseInterceptors,n=d.afterResponseInterceptors;return k.setUrl=function(a){k.url=e(a)},k.setUrl(d.url),k.enableRootWrapping=d.wrapData===a?b.enableRootWrapping:d.wrapData,k.httpConfig=d.httpConfig||b.httpConfig,k.httpConfig.headers=angular.extend({Accept:"application/json","Content-Type":"application/json"},k.httpConfig.headers||{}),k.defaultParams=d.defaultParams||b.defaultParams,k.updateMethod=(d.updateMethod||b.updateMethod).toLowerCase(),k.requestTransformers=[],k.responseInterceptors=[],k.afterResponseInterceptors=[],k.serializer=i.createService(d.serializer||f()),k.rootName=k.serializer.underscore(d.name),k.rootPluralName=k.serializer.underscore(d.pluralName||k.serializer.pluralize(d.name)),k.beforeResponse=function(a){a=i.getDependency(a),k.responseInterceptors.push(function(b){return b.then(function(c){return a(c.data,b.resource,b.context),c})})},k.afterResponse=function(a){a=i.getDependency(a),k.afterResponseInterceptors.push(function(b){return b.then(function(c){return a(c,b.resource),c})})},k.beforeRequest=function(a){a=i.getDependency(a),k.requestTransformers.push(function(b,c){return a(b,c)||b})},angular.forEach(m,function(a){k.responseInterceptors.push(i.getDependency(a))}),angular.forEach(n,function(a){k.afterResponseInterceptors.push(i.getDependency(a))}),angular.forEach(l,function(a){k.requestTransformers.push(i.getDependency(a))}),k.transformData=function(a){return a=k.serializer.serialize(a),angular.forEach(k.requestTransformers,function(b){a=b(a,k)}),k.enableRootWrapping&&(a=g(a,k)),a},k.callInterceptors=function(a,b){return a=a.then(function(a){return a.originalData=a.data,a}),k.enableRootWrapping&&(a.resource=k,a=h(a)),a.then(function(a){return a.data=k.serializer.deserialize(a.data,k),a}),angular.forEach(k.responseInterceptors,function(c){a.resource=k,a.context=b,a=c(a)}),a},k.callAfterInterceptors=function(a){return angular.forEach(k.afterResponseInterceptors,function(b){a.resource=k,a=b(a)}),a},k.processResponse=function(a){return a=k.callInterceptors(a).then(function(a){return a.data}),k.callAfterInterceptors(a)},k.getParameters=function(a){var b;return k.defaultParams&&(b=k.defaultParams),angular.isObject(a)&&(b=angular.extend(b||{},a)),b},k.getHttpConfig=function(a){var b=k.getParameters(a);return b?angular.extend({params:b},k.httpConfig):angular.copy(k.httpConfig)},k.$url=k.resourceUrl=function(a,b){return angular.isObject(a)||(a={id:a}),j(k.url(a||{}),b)},k.$get=function(a,b){return k.processResponse(c.get(a,k.getHttpConfig(b)))},k.query=function(a,b){return k.$get(k.resourceUrl(b),a)},k.get=function(a,b){return k.$get(k.resourceUrl(a),b)},k.prototype.$url=function(a){return j(k.resourceUrl(this),a)},k.prototype.processResponse=function(a){return a=k.callInterceptors(a,this),a=a.then(angular.bind(this,function(a){return a.hasOwnProperty("data")&&angular.isObject(a.data)&&angular.extend(this,a.data),this})),k.callAfterInterceptors(a)},angular.forEach(["post","put","patch"],function(a){k["$"+a]=function(b,d){var e;return d=k.transformData(angular.copy(d)),e=angular.extend({method:a,url:b,data:d},k.getHttpConfig()),k.processResponse(c(e))},k.prototype["$"+a]=function(b){var d,e;return d=k.transformData(angular.copy(this,{})),e=angular.extend({method:a,url:b,data:d},k.getHttpConfig()),this.processResponse(c(e))}}),k.prototype.create=function(){return this.$post(this.$url(),this)},k.prototype.update=function(){return this["$"+k.updateMethod](this.$url(),this)},k.prototype.isNew=function(){return null==this.id},k.prototype.save=function(){return this.isNew()?this.create():this.update()},k.$delete=function(a){return k.processResponse(c["delete"](a,k.getHttpConfig()))},k.prototype.$delete=function(a){return this.processResponse(c["delete"](a,k.getHttpConfig()))},k.prototype.remove=k.prototype["delete"]=function(){return this.$delete(this.$url())},k}return j}]})}();
|
7
|
+
!function(){angular.module("rails",["ng"])}(),function(){angular.module("rails").factory("RailsInflector",function(){function a(a){return angular.isString(a)?a.replace(/_[\w\d]/g,function(a,b,c){return 0===b?a:c.charAt(b+1).toUpperCase()}):a}function b(a){return angular.isString(a)?a.replace(/[A-Z]/g,function(a,b){return 0===b?a:"_"+a.toLowerCase()}):a}function c(a){return a+"s"}return{camelize:a,underscore:b,pluralize:c}})}(),function(a){angular.module("rails").factory("RailsResourceInjector",["$injector",function(b){function c(c){return c?angular.isString(c)?b.get(c):c:a}function d(d){return d?b.instantiate(c(d)):a}return{createService:d,getDependency:c}}])}(),function(){angular.module("rails").factory("railsUrlBuilder",["$interpolate",function(a){return function(b){var c;return angular.isFunction(b)||angular.isUndefined(b)?b:(-1===b.indexOf(a.startSymbol())&&(b=b+"/"+a.startSymbol()+"id"+a.endSymbol()),c=a(b),function(a){return b=c(a),"/"===b.charAt(b.length-1)&&(b=b.substr(0,b.length-1)),b})}}])}(),function(a){angular.module("rails").provider("railsSerializer",function(){var b={underscore:a,camelize:a,pluralize:a,exclusionMatchers:[]};this.underscore=function(a){return b.underscore=a,this},this.camelize=function(a){return b.camelize=a,this},this.pluralize=function(a){return b.pluralize=a,this},this.exclusionMatchers=function(a){return b.exclusionMatchers=a,this},this.$get=["$injector","RailsInflector","RailsResourceInjector",function(c,d,e){function f(c,d){function f(){angular.isFunction(c)&&(d=c,c={}),this.exclusions={},this.inclusions={},this.serializeMappings={},this.deserializeMappings={},this.customSerializedAttributes={},this.preservedAttributes={},this.customSerializers={},this.nestedResources={},this.options=angular.extend({excludeByDefault:!1},b,c||{}),d&&d.call(this,this)}return f.prototype.exclude=function(){var a=this.exclusions;return angular.forEach(arguments,function(b){a[b]=!1}),this},f.prototype.only=function(){var a=this.inclusions;return this.options.excludeByDefault=!0,angular.forEach(arguments,function(b){a[b]=!0}),this},f.prototype.nestedAttribute=function(){var a=this;return angular.forEach(arguments,function(b){a.rename(b,b+"_attributes")}),this},f.prototype.resource=function(a,b,c){return this.nestedResources[a]=b,c&&this.serializeWith(a,c),this},f.prototype.rename=function(b,c,d){return this.serializeMappings[b]=c,(d||d===a)&&(this.deserializeMappings[c]=b),this},f.prototype.add=function(a,b){return this.customSerializedAttributes[a]=b,this},f.prototype.preserve=function(a){return this.preservedAttributes[a]=!0,this},f.prototype.serializeWith=function(a,b){return this.customSerializers[a]=b,this},f.prototype.isExcludedFromSerialization=function(b){if(this.options.excludeByDefault&&!this.inclusions.hasOwnProperty(b)||this.exclusions.hasOwnProperty(b))return!0;if(this.options.exclusionMatchers){var c=!1;return angular.forEach(this.options.exclusionMatchers,function(d){angular.isString(d)?c=c||0===b.indexOf(d):angular.isFunction(d)?c=c||d.call(a,b):d instanceof RegExp&&(c=c||d.test(b))}),c}return!1},f.prototype.getSerializedAttributeName=function(b){var c=this.serializeMappings[b]||b;return this.isExcludedFromSerialization(b)||this.isExcludedFromSerialization(c)?a:this.underscore(c)},f.prototype.isExcludedFromDeserialization=function(){return!1},f.prototype.getDeserializedAttributeName=function(b){var c=this.camelize(b);return c=this.deserializeMappings[b]||this.deserializeMappings[c]||c,this.isExcludedFromDeserialization(b)||this.isExcludedFromDeserialization(c)?a:c},f.prototype.getNestedResource=function(a){return e.getDependency(this.nestedResources[a])},f.prototype.getAttributeSerializer=function(b){var c=this.getNestedResource(b),d=this.customSerializers[b];return d?e.createService(d):c?c.config.serializer:a},f.prototype.serializeValue=function(a){var b=a,c=this;if(angular.isArray(a))b=[],angular.forEach(a,function(a){b.push(c.serializeValue(a))});else if(angular.isObject(a)){if(angular.isDate(a))return a;b={},angular.forEach(a,function(a,d){angular.isFunction(a)||c.serializeAttribute(b,d,a)})}return b},f.prototype.serializeAttribute=function(b,c,d){var e=this.getAttributeSerializer(c),f=this.getSerializedAttributeName(c);f!==a&&(b[f]=e?e.serialize(d):this.serializeValue(d))},f.prototype.serialize=function(a){var b=this.serializeValue(a),c=this;return angular.isObject(b)&&angular.forEach(this.customSerializedAttributes,function(d,e){angular.isFunction(d)&&(d=d.call(a,a)),c.serializeAttribute(b,e,d)}),b},f.prototype.deserializeValue=function(a,b){var c=a,d=this;if(angular.isArray(a))c=[],angular.forEach(a,function(a){c.push(d.deserializeValue(a,b))});else if(angular.isObject(a)){if(angular.isDate(a))return a;c={},b&&(c=new b.config.resourceConstructor),angular.forEach(a,function(a,b){d.deserializeAttribute(c,b,a)})}return c},f.prototype.deserializeAttribute=function(b,c,d){var e,f,g=this.getDeserializedAttributeName(c);g!==a&&(e=this.getAttributeSerializer(g),f=this.getNestedResource(g),b[g]=this.preservedAttributes[g]?d:e?e.deserialize(d,f):this.deserializeValue(d,f))},f.prototype.deserialize=function(a,b){return this.deserializeValue(a,b)},f.prototype.pluralize=function(a){return this.options.pluralize?this.options.pluralize(a):a},f.prototype.underscore=function(a){return this.options.underscore?this.options.underscore(a):a},f.prototype.camelize=function(a){return this.options.camelize?this.options.camelize(a):a},f}return b.underscore=b.underscore||d.underscore,b.camelize=b.camelize||d.camelize,b.pluralize=b.pluralize||d.pluralize,f.defaultOptions=b,f}]})}(),function(a){angular.module("rails").factory("railsRootWrappingTransformer",function(){return function(a,b){var c={};return c[angular.isArray(a)?b.config.pluralName:b.config.name]=a,c}}),angular.module("rails").factory("railsRootWrappingInterceptor",function(){return function(a){var b=a.resource;return b?a.then(function(a){return a.data&&a.data.hasOwnProperty(b.config.name)?a.data=a.data[b.config.name]:a.data&&a.data.hasOwnProperty(b.config.pluralName)&&(a.data=a.data[b.config.pluralName]),a}):a}}),angular.module("rails").provider("RailsResource",function(){var b={rootWrapping:!0,updateMethod:"put",httpConfig:{},defaultParams:a};this.rootWrapping=function(a){return b.rootWrapping=a,this},this.updateMethod=function(a){return b.updateMethod=a,this},this.httpConfig=function(a){return b.httpConfig=a,this},this.defaultParams=function(a){return b.defaultParams=a,this},this.$get=["$http","$q","railsUrlBuilder","railsSerializer","railsRootWrappingTransformer","railsRootWrappingInterceptor","RailsResourceInjector",function(c,d,e,f,g,h,i){function j(a,b){return b&&("/"!==b[0]&&(a+="/"),a+=b),a}function k(a,b){for(var c,d=0,e=a.length;e>d;d++)c=a[d],angular.isString(c)&&(c=a[d]=i.getDependency(c)),b(c)}function l(a){var b=this;if(a){var c=function(a){return{resource:l,context:b,response:a,then:function(a){return this.response=a(this.response,this.resource,this.context),c(this.response)}}},d=this.constructor.callInterceptors(c({data:a}),this).response.data;angular.extend(this,d)}}return l.extend=function(a){function b(){this.constructor=a}var c={}.hasOwnProperty,d=this;for(var e in d)c.call(d,e)&&(a[e]=d[e]);return b.prototype=d.prototype,a.prototype=new b,a.__super__=d.prototype,a},l.configure=function(c){c=c||{},this.config&&(c=angular.extend({},this.config,c)),this.config={},this.config.url=c.url,this.config.rootWrapping=c.rootWrapping===a?b.rootWrapping:c.rootWrapping,this.config.httpConfig=c.httpConfig||b.httpConfig,this.config.httpConfig.headers=angular.extend({Accept:"application/json","Content-Type":"application/json"},this.config.httpConfig.headers||{}),this.config.defaultParams=c.defaultParams||b.defaultParams,this.config.updateMethod=(c.updateMethod||b.updateMethod).toLowerCase(),this.config.requestTransformers=c.requestTransformers?c.requestTransformers.slice(0):[],this.config.responseInterceptors=c.responseInterceptors?c.responseInterceptors.slice(0):[],this.config.afterResponseInterceptors=c.afterResponseInterceptors?c.afterResponseInterceptors.slice(0):[],this.config.serializer=angular.isObject(c.serializer)?c.serializer:i.createService(c.serializer||f()),this.config.name=this.config.serializer.underscore(c.name),this.config.pluralName=this.config.serializer.underscore(c.pluralName||this.config.serializer.pluralize(this.config.name)),this.config.urlBuilder=e(this.config.url),this.config.resourceConstructor=this},l.configure({}),l.setUrl=function(a){this.configure({url:a})},l.buildUrl=function(a){return this.config.urlBuilder(a)},l.beforeResponse=function(a){a=i.getDependency(a),this.config.responseInterceptors.push(function(b){return b.then(function(c){return a(c.data,b.resource.config.resourceConstructor,b.context),c})})},l.afterResponse=function(a){a=i.getDependency(a),this.config.afterResponseInterceptors.push(function(b){return b.then(function(c){return a(c,b.resource.config.resourceConstructor),c})})},l.beforeRequest=function(a){a=i.getDependency(a),this.config.requestTransformers.push(function(b,c){return a(b,c.config.resourceConstructor)||b})},l.transformData=function(a){var b=this.config;return a=b.serializer.serialize(a),k(this.config.requestTransformers,function(c){a=c(a,b.resourceConstructor)}),b.rootWrapping&&(a=g(a,b.resourceConstructor)),a},l.callInterceptors=function(a,b){var c=this.config;return a=a.then(function(a){return a.originalData=a.data,a}),c.rootWrapping&&(a.resource=c.resourceConstructor,a=h(a)),a.then(function(a){return a.data=c.serializer.deserialize(a.data,c.resourceConstructor),a}),k(c.responseInterceptors,function(d){a.resource=c.resourceConstructor,a.context=b,a=d(a)}),a},l.callAfterInterceptors=function(a){var b=this.config;return k(b.afterResponseInterceptors,function(c){a.resource=b.resourceConstructor,a=c(a)}),a},l.processResponse=function(a){return a=this.callInterceptors(a).then(function(a){return a.data}),this.callAfterInterceptors(a)},l.getParameters=function(a){var b;return this.config.defaultParams&&(b=this.config.defaultParams),angular.isObject(a)&&(b=angular.extend(b||{},a)),b},l.getHttpConfig=function(a){var b=this.getParameters(a);return b?angular.extend({params:b},this.config.httpConfig):angular.copy(this.config.httpConfig)},l.$url=l.resourceUrl=function(a,b){return angular.isObject(a)||(a={id:a}),j(this.buildUrl(a||{}),b)},l.$get=function(a,b){return this.processResponse(c.get(a,this.getHttpConfig(b)))},l.query=function(a,b){return this.$get(this.resourceUrl(b),a)},l.get=function(a,b){return this.$get(this.resourceUrl(a),b)},l.prototype.$url=function(a){return j(this.constructor.resourceUrl(this),a)},l.prototype.processResponse=function(a){return a=this.constructor.callInterceptors(a,this),a=a.then(angular.bind(this,function(a){return a.hasOwnProperty("data")&&angular.isObject(a.data)&&angular.extend(this,a.data),this})),this.constructor.callAfterInterceptors(a)},angular.forEach(["post","put","patch"],function(a){l["$"+a]=function(b,d){var e;return d=this.transformData(angular.copy(d,{})),e=angular.extend({method:a,url:b,data:d},this.getHttpConfig()),this.processResponse(c(e))},l.prototype["$"+a]=function(b){var d,e;return d=this.constructor.transformData(angular.copy(this,{})),e=angular.extend({method:a,url:b,data:d},this.constructor.getHttpConfig()),this.processResponse(c(e))}}),l.prototype.create=function(){return this.$post(this.$url(),this)},l.prototype.update=function(){return this["$"+this.constructor.config.updateMethod](this.$url(),this)},l.prototype.isNew=function(){return null==this.id},l.prototype.save=function(){return this.isNew()?this.create():this.update()},l.$delete=function(a){return this.processResponse(c["delete"](a,this.getHttpConfig()))},l.prototype.$delete=function(a){return this.processResponse(c["delete"](a,this.constructor.getHttpConfig()))},l.prototype.remove=l.prototype["delete"]=function(){return this.$delete(this.$url())},l}]}),angular.module("rails").factory("railsResourceFactory",["RailsResource",function(a){return function(b){function c(){c.__super__.constructor.apply(this,arguments)}return a.extend(c),c.configure(b),c}}])}();
|
Binary file
|
data/bower.json
CHANGED
data/package.json
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
{
|
2
2
|
"name": "angularjs-rails-resource",
|
3
|
-
"description": "A resource factory inspired by $resource from AngularJS",
|
4
|
-
"version": "0.
|
5
|
-
"main": "dist/angularjs-rails-resource.min.js",
|
6
|
-
"homepage": "https://github.com/FineLinePrototyping/angularjs-rails-resource.git",
|
7
|
-
"author": "",
|
3
|
+
"description" : "A resource factory inspired by $resource from AngularJS",
|
4
|
+
"version": "1.0.0-pre1",
|
5
|
+
"main" : "dist/angularjs-rails-resource.min.js",
|
6
|
+
"homepage" : "https://github.com/FineLinePrototyping/angularjs-rails-resource.git",
|
7
|
+
"author" : "",
|
8
8
|
"repository": {
|
9
9
|
"type": "git",
|
10
10
|
"url": "https://github.com/FineLinePrototyping/angularjs-rails-resource.git"
|
@@ -2,42 +2,42 @@ describe('resource provider factory config', function () {
|
|
2
2
|
'use strict';
|
3
3
|
|
4
4
|
it('should allow disabling root wrapping globally', function () {
|
5
|
-
module('rails', function (
|
6
|
-
expect(
|
5
|
+
module('rails', function (RailsResourceProvider) {
|
6
|
+
expect(RailsResourceProvider.rootWrapping(false)).toBe(RailsResourceProvider);
|
7
7
|
});
|
8
8
|
|
9
9
|
inject(function (railsResourceFactory) {
|
10
|
-
expect(railsResourceFactory({name: 'test', url: '/test'}).
|
10
|
+
expect(railsResourceFactory({name: 'test', url: '/test'}).config.rootWrapping).toBe(false);
|
11
11
|
});
|
12
12
|
});
|
13
13
|
|
14
14
|
it('should allow setting updateMethod globally', function () {
|
15
|
-
module('rails', function (
|
16
|
-
expect(
|
15
|
+
module('rails', function (RailsResourceProvider) {
|
16
|
+
expect(RailsResourceProvider.updateMethod('patch')).toBe(RailsResourceProvider);
|
17
17
|
});
|
18
18
|
|
19
19
|
inject(function (railsResourceFactory) {
|
20
|
-
expect(railsResourceFactory({name: 'test', url: '/test'}).updateMethod).toBe('patch');
|
20
|
+
expect(railsResourceFactory({name: 'test', url: '/test'}).config.updateMethod).toBe('patch');
|
21
21
|
});
|
22
22
|
});
|
23
23
|
|
24
24
|
it('should allow setting http headers options globally', function () {
|
25
|
-
module('rails', function (
|
26
|
-
expect(
|
25
|
+
module('rails', function (RailsResourceProvider) {
|
26
|
+
expect(RailsResourceProvider.httpConfig({headers: {'test': "header"}})).toBe(RailsResourceProvider);
|
27
27
|
});
|
28
28
|
|
29
29
|
inject(function (railsResourceFactory) {
|
30
|
-
expect(railsResourceFactory({name: 'test', url: '/test'}).httpConfig.headers).toEqualData({'Accept': 'application/json', 'Content-Type': 'application/json', 'test': 'header'});
|
30
|
+
expect(railsResourceFactory({name: 'test', url: '/test'}).config.httpConfig.headers).toEqualData({'Accept': 'application/json', 'Content-Type': 'application/json', 'test': 'header'});
|
31
31
|
});
|
32
32
|
});
|
33
33
|
|
34
34
|
it('should allow setting default query parameters options globally', function () {
|
35
|
-
module('rails', function (
|
36
|
-
expect(
|
35
|
+
module('rails', function (RailsResourceProvider) {
|
36
|
+
expect(RailsResourceProvider.defaultParams({'test': "1"})).toBe(RailsResourceProvider);
|
37
37
|
});
|
38
38
|
|
39
39
|
inject(function (railsResourceFactory) {
|
40
|
-
expect(railsResourceFactory({name: 'test', url: '/test'}).defaultParams).toEqualData({'test': '1'});
|
40
|
+
expect(railsResourceFactory({name: 'test', url: '/test'}).config.defaultParams).toEqualData({'test': '1'});
|
41
41
|
});
|
42
42
|
});
|
43
43
|
});
|
@@ -381,6 +381,17 @@ describe('railsResourceFactory', function () {
|
|
381
381
|
expect(test).toEqualData({id: 123, abcDef: "T"});
|
382
382
|
});
|
383
383
|
|
384
|
+
it('should allow changing urls after first operation', function () {
|
385
|
+
$httpBackend.expectGET('/test/123').respond(200, {test: {id: 123, abc: 'xyz'}});
|
386
|
+
Test.get(123);
|
387
|
+
$httpBackend.flush();
|
388
|
+
|
389
|
+
$httpBackend.expectGET('/test2/123').respond(200, {test: {id: 123, abc: 'xyz'}});
|
390
|
+
Test.setUrl('/test2');
|
391
|
+
Test.get(123);
|
392
|
+
$httpBackend.flush();
|
393
|
+
});
|
394
|
+
|
384
395
|
it('should support constructing with date properties', function () {
|
385
396
|
var testDate = new Date(),
|
386
397
|
test = new Test({id: 123, testDate: testDate});
|
@@ -415,14 +426,6 @@ describe('railsResourceFactory', function () {
|
|
415
426
|
expect(test).toEqualData({id: 123, abc: 'xyz', xyz: 'abc', extra: 'test'});
|
416
427
|
}));
|
417
428
|
});
|
418
|
-
|
419
|
-
it('should be able to $post an array of resources', function () {
|
420
|
-
var data = [{id: 123, abc: 'xyz'}, {id: 124, abc: 'xyz'}];
|
421
|
-
$httpBackend['expectPOST']('/xyz', {tests: data} ).respond(200, {tests: data});
|
422
|
-
Test.$post('/xyz', data);
|
423
|
-
$httpBackend.flush();
|
424
|
-
});
|
425
|
-
|
426
429
|
});
|
427
430
|
|
428
431
|
describe('plural', function() {
|
@@ -484,4 +487,92 @@ describe('railsResourceFactory', function () {
|
|
484
487
|
expect(result.length).toBe(0);
|
485
488
|
}));
|
486
489
|
});
|
490
|
+
|
491
|
+
describe('subclassing', function() {
|
492
|
+
var $httpBackend, $rootScope, Book, CarManual,
|
493
|
+
// generated CoffeeScript Code
|
494
|
+
__hasProp = {}.hasOwnProperty,
|
495
|
+
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
|
496
|
+
|
497
|
+
|
498
|
+
beforeEach(inject(function (_$httpBackend_, _$rootScope_, RailsResource) {
|
499
|
+
$httpBackend = _$httpBackend_;
|
500
|
+
$rootScope = _$rootScope_;
|
501
|
+
|
502
|
+
// generated CoffeeScript Code
|
503
|
+
Book = (function(_super) {
|
504
|
+
__extends(Book, _super);
|
505
|
+
|
506
|
+
// @configure url: '/books', name: 'book'
|
507
|
+
Book.configure({ url: '/books', name: 'book' });
|
508
|
+
|
509
|
+
function Book() {
|
510
|
+
Book.__super__.constructor.apply(this, arguments);
|
511
|
+
this.subclass = true;
|
512
|
+
}
|
513
|
+
|
514
|
+
return Book;
|
515
|
+
|
516
|
+
})(RailsResource);
|
517
|
+
|
518
|
+
CarManual = (function(_super) {
|
519
|
+
__extends(CarManual, _super);
|
520
|
+
|
521
|
+
CarManual.configure({ url: '/car_manuals', name: 'car_manual' });
|
522
|
+
|
523
|
+
function CarManual() {
|
524
|
+
CarManual.__super__.constructor.apply(this, arguments);
|
525
|
+
this.subclass = true;
|
526
|
+
}
|
527
|
+
|
528
|
+
return CarManual;
|
529
|
+
|
530
|
+
})(Book);
|
531
|
+
}));
|
532
|
+
|
533
|
+
afterEach(function() {
|
534
|
+
$httpBackend.verifyNoOutstandingExpectation();
|
535
|
+
$httpBackend.verifyNoOutstandingRequest();
|
536
|
+
});
|
537
|
+
|
538
|
+
it('get should return resource instance of subclass', function() {
|
539
|
+
var promise, result;
|
540
|
+
|
541
|
+
$httpBackend.expectGET('/car_manuals/123').respond(200, {car_manual: {id: 123, abc: 'xyz'}});
|
542
|
+
|
543
|
+
expect(promise = CarManual.get(123)).toBeDefined();
|
544
|
+
|
545
|
+
promise.then(function (response) {
|
546
|
+
result = response;
|
547
|
+
});
|
548
|
+
|
549
|
+
$httpBackend.flush();
|
550
|
+
|
551
|
+
expect(result).toBeInstanceOf(CarManual);
|
552
|
+
expect(result).toEqualData({id: 123, abc: 'xyz', subclass: true});
|
553
|
+
});
|
554
|
+
|
555
|
+
it('should have configuration per-class', function() {
|
556
|
+
var promise, result;
|
557
|
+
|
558
|
+
$httpBackend.expectGET('/books/123').respond(200, {book: {id: 123, abc: 'xyz'}});
|
559
|
+
|
560
|
+
expect(promise = Book.get(123)).toBeDefined();
|
561
|
+
|
562
|
+
promise.then(function (response) {
|
563
|
+
result = response;
|
564
|
+
});
|
565
|
+
|
566
|
+
$httpBackend.flush();
|
567
|
+
|
568
|
+
expect(result).toBeInstanceOf(Book);
|
569
|
+
expect(result).toEqualData({id: 123, abc: 'xyz', subclass: true});
|
570
|
+
});
|
571
|
+
|
572
|
+
it('should allow constructing subclasses with data', function () {
|
573
|
+
var carManual = new CarManual({id: 1, name: 'Honda CR-V'});
|
574
|
+
expect(carManual.id).toBe(1);
|
575
|
+
expect(carManual.name).toBe('Honda CR-V');
|
576
|
+
});
|
577
|
+
});
|
487
578
|
});
|
@@ -390,22 +390,6 @@ describe('railsSerializer', function () {
|
|
390
390
|
result = serializer.deserialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
|
391
391
|
expect(result).toEqualData({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
|
392
392
|
});
|
393
|
-
|
394
|
-
it('should only serialize id and books', function() {
|
395
|
-
var result,
|
396
|
-
serializer = createSerializer(function(config) {
|
397
|
-
this.only('id', 'books');
|
398
|
-
this.nestedAttribute('books');
|
399
|
-
this.serializeWith('books', factory(function() { }));
|
400
|
-
});
|
401
|
-
var book = { id: 1, title: 'A Game of Thrones', publicationDate: '1996-08-06' };
|
402
|
-
result = serializer.serialize({
|
403
|
-
id: 1, first: 'George', last: 'Martin', books: [book]
|
404
|
-
});
|
405
|
-
expect(result).toEqualData({ id: 1, books_attributes: [{ id: 1, title: 'A Game of Thrones', publication_date: '1996-08-06' }] });
|
406
|
-
result = serializer.deserialize(result);
|
407
|
-
expect(result).toEqual({ id: 1, books: [book]});
|
408
|
-
});
|
409
393
|
});
|
410
394
|
});
|
411
395
|
});
|
@@ -2,7 +2,7 @@
|
|
2
2
|
angular.module('rails').factory('railsRootWrappingTransformer', function () {
|
3
3
|
return function (data, resource) {
|
4
4
|
var result = {};
|
5
|
-
result[angular.isArray(data) ? resource.
|
5
|
+
result[angular.isArray(data) ? resource.config.pluralName : resource.config.name] = data;
|
6
6
|
return result;
|
7
7
|
};
|
8
8
|
});
|
@@ -16,10 +16,10 @@
|
|
16
16
|
}
|
17
17
|
|
18
18
|
return promise.then(function (response) {
|
19
|
-
if (response.data && response.data.hasOwnProperty(resource.
|
20
|
-
response.data = response.data[resource.
|
21
|
-
} else if (response.data && response.data.hasOwnProperty(resource.
|
22
|
-
response.data = response.data[resource.
|
19
|
+
if (response.data && response.data.hasOwnProperty(resource.config.name)) {
|
20
|
+
response.data = response.data[resource.config.name];
|
21
|
+
} else if (response.data && response.data.hasOwnProperty(resource.config.pluralName)) {
|
22
|
+
response.data = response.data[resource.config.pluralName];
|
23
23
|
}
|
24
24
|
|
25
25
|
return response;
|
@@ -27,16 +27,16 @@
|
|
27
27
|
};
|
28
28
|
});
|
29
29
|
|
30
|
-
angular.module('rails').provider('
|
30
|
+
angular.module('rails').provider('RailsResource', function () {
|
31
31
|
var defaultOptions = {
|
32
|
-
|
32
|
+
rootWrapping: true,
|
33
33
|
updateMethod: 'put',
|
34
34
|
httpConfig: {},
|
35
35
|
defaultParams: undefined
|
36
36
|
};
|
37
37
|
|
38
|
-
this.
|
39
|
-
defaultOptions.
|
38
|
+
this.rootWrapping = function (value) {
|
39
|
+
defaultOptions.rootWrapping = value;
|
40
40
|
return this;
|
41
41
|
};
|
42
42
|
|
@@ -58,11 +58,6 @@
|
|
58
58
|
this.$get = ['$http', '$q', 'railsUrlBuilder', 'railsSerializer', 'railsRootWrappingTransformer', 'railsRootWrappingInterceptor', 'RailsResourceInjector',
|
59
59
|
function ($http, $q, railsUrlBuilder, railsSerializer, railsRootWrappingTransformer, railsRootWrappingInterceptor, RailsResourceInjector) {
|
60
60
|
|
61
|
-
function railsResourceFactory(config) {
|
62
|
-
var transformers = config.requestTransformers,
|
63
|
-
interceptors = config.responseInterceptors,
|
64
|
-
afterInterceptors = config.afterResponseInterceptors;
|
65
|
-
|
66
61
|
function appendPath(url, path) {
|
67
62
|
if (path) {
|
68
63
|
if (path[0] !== '/') {
|
@@ -75,43 +70,100 @@
|
|
75
70
|
return url;
|
76
71
|
}
|
77
72
|
|
73
|
+
function forEachDependency(list, callback) {
|
74
|
+
var dependency;
|
75
|
+
|
76
|
+
for (var i = 0, len = list.length; i < len; i++) {
|
77
|
+
dependency = list[i];
|
78
|
+
|
79
|
+
if (angular.isString(dependency)) {
|
80
|
+
dependency = list[i] = RailsResourceInjector.getDependency(dependency);
|
81
|
+
}
|
82
|
+
|
83
|
+
callback(dependency);
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
78
87
|
function RailsResource(value) {
|
79
88
|
var instance = this;
|
80
89
|
if (value) {
|
81
|
-
var immediatePromise = function(data) {
|
90
|
+
var immediatePromise = function (data) {
|
82
91
|
return {
|
83
92
|
resource: RailsResource,
|
84
93
|
context: instance,
|
85
94
|
response: data,
|
86
|
-
then: function(callback) {
|
95
|
+
then: function (callback) {
|
87
96
|
this.response = callback(this.response, this.resource, this.context);
|
88
97
|
return immediatePromise(this.response);
|
89
98
|
}
|
90
99
|
}
|
91
100
|
};
|
92
101
|
|
93
|
-
var data =
|
102
|
+
var data = this.constructor.callInterceptors(immediatePromise({data: value}), this).response.data;
|
94
103
|
angular.extend(this, data);
|
95
104
|
}
|
96
105
|
}
|
97
106
|
|
98
|
-
RailsResource.
|
99
|
-
|
107
|
+
RailsResource.extend = function (child) {
|
108
|
+
// Extend logic copied from CoffeeScript generated code
|
109
|
+
var __hasProp = {}.hasOwnProperty, parent = this;
|
110
|
+
for (var key in parent) {
|
111
|
+
if (__hasProp.call(parent, key)) child[key] = parent[key];
|
112
|
+
}
|
113
|
+
|
114
|
+
function ctor() {
|
115
|
+
this.constructor = child;
|
116
|
+
}
|
117
|
+
|
118
|
+
ctor.prototype = parent.prototype;
|
119
|
+
child.prototype = new ctor();
|
120
|
+
child.__super__ = parent.prototype;
|
121
|
+
return child;
|
100
122
|
};
|
101
|
-
RailsResource.setUrl(config.url);
|
102
123
|
|
103
|
-
|
104
|
-
RailsResource.
|
105
|
-
|
106
|
-
|
107
|
-
|
124
|
+
// allow calling configure multiple times to set configuration options and override values from inherited resources
|
125
|
+
RailsResource.configure = function (cfg) {
|
126
|
+
cfg = cfg || {};
|
127
|
+
|
128
|
+
if (this.config) {
|
129
|
+
cfg = angular.extend({}, this.config, cfg);
|
130
|
+
}
|
131
|
+
|
132
|
+
this.config = {};
|
133
|
+
this.config.url = cfg.url;
|
134
|
+
this.config.rootWrapping = cfg.rootWrapping === undefined ? defaultOptions.rootWrapping : cfg.rootWrapping; // using undefined check because config.rootWrapping || true would be true when config.rootWrapping === false
|
135
|
+
this.config.httpConfig = cfg.httpConfig || defaultOptions.httpConfig;
|
136
|
+
this.config.httpConfig.headers = angular.extend({'Accept': 'application/json', 'Content-Type': 'application/json'}, this.config.httpConfig.headers || {});
|
137
|
+
this.config.defaultParams = cfg.defaultParams || defaultOptions.defaultParams;
|
138
|
+
this.config.updateMethod = (cfg.updateMethod || defaultOptions.updateMethod).toLowerCase();
|
139
|
+
|
140
|
+
this.config.requestTransformers = cfg.requestTransformers ? cfg.requestTransformers.slice(0) : [];
|
141
|
+
this.config.responseInterceptors = cfg.responseInterceptors ? cfg.responseInterceptors.slice(0) : [];
|
142
|
+
this.config.afterResponseInterceptors = cfg.afterResponseInterceptors ? cfg.afterResponseInterceptors.slice(0) : [];
|
143
|
+
|
144
|
+
// strings and functions are not considered objects by angular.isObject()
|
145
|
+
if (angular.isObject(cfg.serializer)) {
|
146
|
+
this.config.serializer = cfg.serializer;
|
147
|
+
} else {
|
148
|
+
this.config.serializer = RailsResourceInjector.createService(cfg.serializer || railsSerializer());
|
149
|
+
}
|
150
|
+
|
151
|
+
this.config.name = this.config.serializer.underscore(cfg.name);
|
152
|
+
this.config.pluralName = this.config.serializer.underscore(cfg.pluralName || this.config.serializer.pluralize(this.config.name));
|
108
153
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
RailsResource.
|
114
|
-
|
154
|
+
this.config.urlBuilder = railsUrlBuilder(this.config.url);
|
155
|
+
this.config.resourceConstructor = this;
|
156
|
+
};
|
157
|
+
|
158
|
+
RailsResource.configure({});
|
159
|
+
|
160
|
+
RailsResource.setUrl = function (url) {
|
161
|
+
this.configure({url: url});
|
162
|
+
};
|
163
|
+
|
164
|
+
RailsResource.buildUrl = function (context) {
|
165
|
+
return this.config.urlBuilder(context);
|
166
|
+
};
|
115
167
|
|
116
168
|
/**
|
117
169
|
* Add a callback to run on response and construction.
|
@@ -119,11 +171,11 @@
|
|
119
171
|
* constructor is the resource class calling the function,
|
120
172
|
* context is the resource instance of the calling method (create, update, delete) or undefined if the method was a class method (get, query)
|
121
173
|
*/
|
122
|
-
RailsResource.beforeResponse = function(fn) {
|
174
|
+
RailsResource.beforeResponse = function (fn) {
|
123
175
|
fn = RailsResourceInjector.getDependency(fn);
|
124
|
-
|
125
|
-
return promise.then(function(response) {
|
126
|
-
fn(response.data, promise.resource, promise.context);
|
176
|
+
this.config.responseInterceptors.push(function (promise) {
|
177
|
+
return promise.then(function (response) {
|
178
|
+
fn(response.data, promise.resource.config.resourceConstructor, promise.context);
|
127
179
|
return response;
|
128
180
|
});
|
129
181
|
});
|
@@ -133,11 +185,11 @@
|
|
133
185
|
* Add a callback to run after response has been processed. These callbacks are not called on object construction.
|
134
186
|
* @param fn(response data, constructor) - response data is either the resource instance returned or an array of resource instances and constructor is the resource class calling the function
|
135
187
|
*/
|
136
|
-
RailsResource.afterResponse = function(fn) {
|
188
|
+
RailsResource.afterResponse = function (fn) {
|
137
189
|
fn = RailsResourceInjector.getDependency(fn);
|
138
|
-
|
139
|
-
return promise.then(function(response) {
|
140
|
-
fn(response, promise.resource);
|
190
|
+
this.config.afterResponseInterceptors.push(function (promise) {
|
191
|
+
return promise.then(function (response) {
|
192
|
+
fn(response, promise.resource.config.resourceConstructor);
|
141
193
|
return response;
|
142
194
|
});
|
143
195
|
});
|
@@ -147,38 +199,24 @@
|
|
147
199
|
* Adds a function to run after serializing the data to send to the server, but before root-wrapping it.
|
148
200
|
* @param fn (data, constructor) - data object is the serialized resource instance, and constructor the resource class calling the function
|
149
201
|
*/
|
150
|
-
RailsResource.beforeRequest = function(fn) {
|
202
|
+
RailsResource.beforeRequest = function (fn) {
|
151
203
|
fn = RailsResourceInjector.getDependency(fn);
|
152
|
-
|
153
|
-
return fn(data, resource) || data;
|
204
|
+
this.config.requestTransformers.push(function (data, resource) {
|
205
|
+
return fn(data, resource.config.resourceConstructor) || data;
|
154
206
|
});
|
155
207
|
};
|
156
208
|
|
157
|
-
// copied from $HttpProvider to support interceptors being dependency names or anonymous factory functions
|
158
|
-
angular.forEach(interceptors, function (interceptor) {
|
159
|
-
RailsResource.responseInterceptors.push(RailsResourceInjector.getDependency(interceptor));
|
160
|
-
});
|
161
|
-
|
162
|
-
angular.forEach(afterInterceptors, function (interceptor) {
|
163
|
-
RailsResource.afterResponseInterceptors.push(RailsResourceInjector.getDependency(interceptor));
|
164
|
-
});
|
165
|
-
|
166
|
-
angular.forEach(transformers, function (transformer) {
|
167
|
-
RailsResource.requestTransformers.push(RailsResourceInjector.getDependency(transformer));
|
168
|
-
});
|
169
|
-
|
170
209
|
// transform data for request:
|
171
210
|
RailsResource.transformData = function (data) {
|
172
|
-
|
211
|
+
var config = this.config;
|
212
|
+
data = config.serializer.serialize(data);
|
173
213
|
|
174
|
-
|
175
|
-
|
176
|
-
data = transformer(data, RailsResource);
|
214
|
+
forEachDependency(this.config.requestTransformers, function (transformer) {
|
215
|
+
data = transformer(data, config.resourceConstructor);
|
177
216
|
});
|
178
217
|
|
179
|
-
|
180
|
-
|
181
|
-
data = railsRootWrappingTransformer(data, RailsResource);
|
218
|
+
if (config.rootWrapping) {
|
219
|
+
data = railsRootWrappingTransformer(data, config.resourceConstructor);
|
182
220
|
}
|
183
221
|
|
184
222
|
return data;
|
@@ -186,25 +224,27 @@
|
|
186
224
|
|
187
225
|
// transform data on response:
|
188
226
|
RailsResource.callInterceptors = function (promise, context) {
|
227
|
+
var config = this.config;
|
228
|
+
|
189
229
|
promise = promise.then(function (response) {
|
190
230
|
// store off the data in case something (like our root unwrapping) assigns data as a new object
|
191
231
|
response.originalData = response.data;
|
192
232
|
return response;
|
193
233
|
});
|
194
234
|
|
195
|
-
if (
|
196
|
-
promise.resource =
|
235
|
+
if (config.rootWrapping) {
|
236
|
+
promise.resource = config.resourceConstructor;
|
197
237
|
promise = railsRootWrappingInterceptor(promise);
|
198
238
|
}
|
199
239
|
|
200
240
|
promise.then(function (response) {
|
201
|
-
response.data =
|
241
|
+
response.data = config.serializer.deserialize(response.data, config.resourceConstructor);
|
202
242
|
return response;
|
203
243
|
});
|
204
244
|
|
205
245
|
// data is now deserialized. call response interceptors including beforeResponse
|
206
|
-
|
207
|
-
promise.resource =
|
246
|
+
forEachDependency(config.responseInterceptors, function (interceptor) {
|
247
|
+
promise.resource = config.resourceConstructor;
|
208
248
|
promise.context = context;
|
209
249
|
promise = interceptor(promise);
|
210
250
|
});
|
@@ -214,9 +254,10 @@
|
|
214
254
|
|
215
255
|
// transform data after response has been converted to a resource instance:
|
216
256
|
RailsResource.callAfterInterceptors = function (promise) {
|
257
|
+
var config = this.config;
|
217
258
|
// data is now deserialized. call response interceptors including afterResponse
|
218
|
-
|
219
|
-
promise.resource =
|
259
|
+
forEachDependency(config.afterResponseInterceptors, function (interceptor) {
|
260
|
+
promise.resource = config.resourceConstructor;
|
220
261
|
promise = interceptor(promise);
|
221
262
|
});
|
222
263
|
|
@@ -224,18 +265,18 @@
|
|
224
265
|
};
|
225
266
|
|
226
267
|
RailsResource.processResponse = function (promise) {
|
227
|
-
promise =
|
268
|
+
promise = this.callInterceptors(promise).then(function (response) {
|
228
269
|
return response.data;
|
229
270
|
});
|
230
271
|
|
231
|
-
return
|
272
|
+
return this.callAfterInterceptors(promise);
|
232
273
|
};
|
233
274
|
|
234
275
|
RailsResource.getParameters = function (queryParams) {
|
235
276
|
var params;
|
236
277
|
|
237
|
-
if (
|
238
|
-
params =
|
278
|
+
if (this.config.defaultParams) {
|
279
|
+
params = this.config.defaultParams;
|
239
280
|
}
|
240
281
|
|
241
282
|
if (angular.isObject(queryParams)) {
|
@@ -246,13 +287,13 @@
|
|
246
287
|
};
|
247
288
|
|
248
289
|
RailsResource.getHttpConfig = function (queryParams) {
|
249
|
-
var params =
|
290
|
+
var params = this.getParameters(queryParams);
|
250
291
|
|
251
292
|
if (params) {
|
252
|
-
return angular.extend({params: params},
|
293
|
+
return angular.extend({params: params}, this.config.httpConfig);
|
253
294
|
}
|
254
295
|
|
255
|
-
return angular.copy(
|
296
|
+
return angular.copy(this.config.httpConfig);
|
256
297
|
};
|
257
298
|
|
258
299
|
/**
|
@@ -275,19 +316,19 @@
|
|
275
316
|
context = {id: context};
|
276
317
|
}
|
277
318
|
|
278
|
-
return appendPath(
|
319
|
+
return appendPath(this.buildUrl(context || {}), path);
|
279
320
|
};
|
280
321
|
|
281
322
|
RailsResource.$get = function (url, queryParams) {
|
282
|
-
return
|
323
|
+
return this.processResponse($http.get(url, this.getHttpConfig(queryParams)));
|
283
324
|
};
|
284
325
|
|
285
326
|
RailsResource.query = function (queryParams, context) {
|
286
|
-
return
|
327
|
+
return this.$get(this.resourceUrl(context), queryParams);
|
287
328
|
};
|
288
329
|
|
289
330
|
RailsResource.get = function (context, queryParams) {
|
290
|
-
return
|
331
|
+
return this.$get(this.resourceUrl(context), queryParams);
|
291
332
|
};
|
292
333
|
|
293
334
|
/**
|
@@ -296,12 +337,12 @@
|
|
296
337
|
* @param path {string} (optional) An additional path to append to the URL
|
297
338
|
* @returns {string} The URL for the resource
|
298
339
|
*/
|
299
|
-
RailsResource.prototype.$url = function(path) {
|
300
|
-
return appendPath(
|
340
|
+
RailsResource.prototype.$url = function (path) {
|
341
|
+
return appendPath(this.constructor.resourceUrl(this), path);
|
301
342
|
};
|
302
343
|
|
303
344
|
RailsResource.prototype.processResponse = function (promise) {
|
304
|
-
promise =
|
345
|
+
promise = this.constructor.callInterceptors(promise, this);
|
305
346
|
|
306
347
|
promise = promise.then(angular.bind(this, function (response) {
|
307
348
|
// we may not have response data
|
@@ -312,23 +353,23 @@
|
|
312
353
|
return this;
|
313
354
|
}));
|
314
355
|
|
315
|
-
return
|
356
|
+
return this.constructor.callAfterInterceptors(promise);
|
316
357
|
};
|
317
358
|
|
318
359
|
angular.forEach(['post', 'put', 'patch'], function (method) {
|
319
360
|
RailsResource['$' + method] = function (url, data) {
|
320
361
|
var config;
|
321
362
|
// clone so we can manipulate w/o modifying the actual instance
|
322
|
-
data =
|
323
|
-
config = angular.extend({method: method, url: url, data: data},
|
324
|
-
return
|
363
|
+
data = this.transformData(angular.copy(data, {}));
|
364
|
+
config = angular.extend({method: method, url: url, data: data}, this.getHttpConfig());
|
365
|
+
return this.processResponse($http(config));
|
325
366
|
};
|
326
367
|
|
327
368
|
RailsResource.prototype['$' + method] = function (url) {
|
328
369
|
var data, config;
|
329
370
|
// clone so we can manipulate w/o modifying the actual instance
|
330
|
-
data =
|
331
|
-
config = angular.extend({method: method, url: url, data: data},
|
371
|
+
data = this.constructor.transformData(angular.copy(this, {}));
|
372
|
+
config = angular.extend({method: method, url: url, data: data}, this.constructor.getHttpConfig());
|
332
373
|
return this.processResponse($http(config));
|
333
374
|
|
334
375
|
};
|
@@ -339,12 +380,12 @@
|
|
339
380
|
};
|
340
381
|
|
341
382
|
RailsResource.prototype.update = function () {
|
342
|
-
return this['$' +
|
383
|
+
return this['$' + this.constructor.config.updateMethod](this.$url(), this);
|
343
384
|
};
|
344
385
|
|
345
386
|
RailsResource.prototype.isNew = function () {
|
346
387
|
return this.id == null;
|
347
|
-
}
|
388
|
+
};
|
348
389
|
|
349
390
|
RailsResource.prototype.save = function () {
|
350
391
|
if (this.isNew()) {
|
@@ -352,14 +393,14 @@
|
|
352
393
|
} else {
|
353
394
|
return this.update();
|
354
395
|
}
|
355
|
-
}
|
396
|
+
};
|
356
397
|
|
357
398
|
RailsResource['$delete'] = function (url) {
|
358
|
-
return
|
399
|
+
return this.processResponse($http['delete'](url, this.getHttpConfig()));
|
359
400
|
};
|
360
401
|
|
361
402
|
RailsResource.prototype['$delete'] = function (url) {
|
362
|
-
return this.processResponse($http['delete'](url,
|
403
|
+
return this.processResponse($http['delete'](url, this.constructor.getHttpConfig()));
|
363
404
|
};
|
364
405
|
|
365
406
|
//using ['delete'] instead of .delete for IE7/8 compatibility
|
@@ -368,9 +409,20 @@
|
|
368
409
|
};
|
369
410
|
|
370
411
|
return RailsResource;
|
412
|
+
}];
|
413
|
+
});
|
414
|
+
|
415
|
+
angular.module('rails').factory('railsResourceFactory', ['RailsResource', function (RailsResource) {
|
416
|
+
return function (config) {
|
417
|
+
function Resource() {
|
418
|
+
Resource.__super__.constructor.apply(this, arguments);
|
371
419
|
}
|
372
420
|
|
373
|
-
|
374
|
-
|
375
|
-
|
421
|
+
RailsResource.extend(Resource);
|
422
|
+
Resource.configure(config);
|
423
|
+
|
424
|
+
return Resource;
|
425
|
+
}
|
426
|
+
}]);
|
427
|
+
|
376
428
|
}());
|