red_base 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (278) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +339 -0
  3. data/README.rdoc +40 -0
  4. data/Rakefile +42 -0
  5. data/app/assets/fonts/DroidNaskh-Bold.ttf +0 -0
  6. data/app/assets/fonts/DroidNaskh-Regular.ttf +0 -0
  7. data/app/assets/fonts/OpenSans-Bold.ttf +0 -0
  8. data/app/assets/fonts/OpenSans-BoldItalic.ttf +0 -0
  9. data/app/assets/fonts/OpenSans-ExtraBold.ttf +0 -0
  10. data/app/assets/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
  11. data/app/assets/fonts/OpenSans-Italic.ttf +0 -0
  12. data/app/assets/fonts/OpenSans-Light.ttf +0 -0
  13. data/app/assets/fonts/OpenSans-LightItalic.ttf +0 -0
  14. data/app/assets/fonts/OpenSans-Regular.ttf +0 -0
  15. data/app/assets/fonts/OpenSans-Semibold.ttf +0 -0
  16. data/app/assets/fonts/OpenSans-SemiboldItalic.ttf +0 -0
  17. data/app/assets/javascripts/red_base/application.js +20 -0
  18. data/app/assets/javascripts/red_base/dashboard/angular.js +9 -0
  19. data/app/assets/javascripts/red_base/dashboard/app.js +65 -0
  20. data/app/assets/javascripts/red_base/dashboard/application.js.erb +24 -0
  21. data/app/assets/javascripts/red_base/dashboard/functions.js.erb +91 -0
  22. data/app/assets/javascripts/red_base/dashboard/init.js +38 -0
  23. data/app/assets/javascripts/red_base/dashboard/init.js~ +0 -0
  24. data/app/assets/javascripts/red_base/dashboard/lib/angular-animate.js +1226 -0
  25. data/app/assets/javascripts/red_base/dashboard/lib/angular-gettext.js +202 -0
  26. data/app/assets/javascripts/red_base/dashboard/lib/angular-resource.js +578 -0
  27. data/app/assets/javascripts/red_base/dashboard/lib/angular-route.js +880 -0
  28. data/app/assets/javascripts/red_base/dashboard/lib/angular.js +20031 -0
  29. data/app/assets/javascripts/red_base/dashboard/lib/lodash.underscore.js +4893 -0
  30. data/app/assets/javascripts/red_base/dashboard/lib/restangular.js +1066 -0
  31. data/app/assets/javascripts/red_base/dashboard/locale/translations.js +5 -0
  32. data/app/assets/javascripts/red_base/dashboard/modules/anim.js +32 -0
  33. data/app/assets/javascripts/red_base/dashboard/modules/api.js +32 -0
  34. data/app/assets/javascripts/red_base/dashboard/modules/auth/auth.js +34 -0
  35. data/app/assets/javascripts/red_base/dashboard/modules/auth/group.js +174 -0
  36. data/app/assets/javascripts/red_base/dashboard/modules/auth/user.js +122 -0
  37. data/app/assets/javascripts/red_base/dashboard/modules/list-view.js +293 -0
  38. data/app/assets/javascripts/red_base/dashboard/modules/logs.js +41 -0
  39. data/app/assets/javascripts/red_base/dashboard/modules/modules.js +50 -0
  40. data/app/assets/javascripts/red_base/dashboard/modules/nav.js.erb +92 -0
  41. data/app/assets/javascripts/red_base/dashboard/templates/application.handlebars.erb +42 -0
  42. data/app/assets/javascripts/red_base/dashboard/templates/auth/groups/details.handlebars.erb +15 -0
  43. data/app/assets/javascripts/red_base/dashboard/templates/auth/groups/index.handlebars.erb +7 -0
  44. data/app/assets/javascripts/red_base/dashboard/templates/auth/groups/new.handlebars.erb +39 -0
  45. data/app/assets/javascripts/red_base/dashboard/templates/auth/index.handlebars.erb +31 -0
  46. data/app/assets/javascripts/red_base/dashboard/templates/auth/users/details.handlebars.erb +15 -0
  47. data/app/assets/javascripts/red_base/dashboard/templates/auth/users/index.handlebars.erb +11 -0
  48. data/app/assets/javascripts/red_base/dashboard/templates/auth/users/new.handlebars.erb +33 -0
  49. data/app/assets/javascripts/red_base/dashboard/templates/components/list-view.handlebars.erb +59 -0
  50. data/app/assets/javascripts/red_base/dashboard/templates/components/model-form.handlebars.erb +3 -0
  51. data/app/assets/javascripts/red_base/dashboard/templates/modules.handlebars.erb +15 -0
  52. data/app/assets/javascripts/red_base/dashboard/templates/navigation.handlebars.erb +43 -0
  53. data/app/assets/javascripts/red_base/dashboard/templates/widgets.handlebars +23 -0
  54. data/app/assets/javascripts/red_base/dashboard/variables.js.erb +17 -0
  55. data/app/assets/javascripts/red_base/groups.js +2 -0
  56. data/app/assets/javascripts/red_base/home.js +2 -0
  57. data/app/assets/javascripts/red_base/i18n.js +13 -0
  58. data/app/assets/javascripts/red_base/locale/en.json +27 -0
  59. data/app/assets/javascripts/red_base/locale/fa.json +27 -0
  60. data/app/assets/javascripts/red_base/users.js +2 -0
  61. data/app/assets/stylesheets/red_base/base.css.scss +402 -0
  62. data/app/assets/stylesheets/red_base/dashboard/dashboard.css.scss +169 -0
  63. data/app/assets/stylesheets/red_base/dashboard/ltr/application.css +21 -0
  64. data/app/assets/stylesheets/red_base/dashboard/ltr/base.css.scss.erb +28 -0
  65. data/app/assets/stylesheets/red_base/dashboard/ltr/base.css.scss~ +15 -0
  66. data/app/assets/stylesheets/red_base/dashboard/ltr/buttons.css.scss.erb +48 -0
  67. data/app/assets/stylesheets/red_base/dashboard/ltr/direction.css.scss +38 -0
  68. data/app/assets/stylesheets/red_base/dashboard/ltr/foundation_and_overrides.css.scss +1014 -0
  69. data/app/assets/stylesheets/red_base/dashboard/rtl/application.css +21 -0
  70. data/app/assets/stylesheets/red_base/dashboard/rtl/base.css.scss.erb +31 -0
  71. data/app/assets/stylesheets/red_base/dashboard/rtl/base.css.scss~ +1 -0
  72. data/app/assets/stylesheets/red_base/dashboard/rtl/base.css_flymake.scss +25 -0
  73. data/app/assets/stylesheets/red_base/dashboard/rtl/buttons.css.scss.erb +45 -0
  74. data/app/assets/stylesheets/red_base/dashboard/rtl/direction.css.scss +37 -0
  75. data/app/assets/stylesheets/red_base/dashboard/rtl/foundation_and_overrides.css.scss +1014 -0
  76. data/app/assets/stylesheets/red_base/dashboard/sidebar.css.scss +93 -0
  77. data/app/assets/stylesheets/red_base/devise.css.scss +34 -0
  78. data/app/assets/stylesheets/red_base/groups.css +4 -0
  79. data/app/assets/stylesheets/red_base/home.css.scss +14 -0
  80. data/app/assets/stylesheets/red_base/ltr/application.css +20 -0
  81. data/app/assets/stylesheets/red_base/ltr/buttons.css.scss.erb +48 -0
  82. data/app/assets/stylesheets/red_base/ltr/foundation_and_overrides.scss.erb +1012 -0
  83. data/app/assets/stylesheets/red_base/mixins.css.scss +15 -0
  84. data/app/assets/stylesheets/red_base/mixins.css.scss~ +7 -0
  85. data/app/assets/stylesheets/red_base/rtl/application.css +20 -0
  86. data/app/assets/stylesheets/red_base/rtl/buttons.css.scss.erb +48 -0
  87. data/app/assets/stylesheets/red_base/rtl/foundation_and_overrides.scss.erb +1012 -0
  88. data/app/assets/stylesheets/red_base/users.css +4 -0
  89. data/app/assets/stylesheets/red_base/variables.css.scss +100 -0
  90. data/app/controllers/red_base/api/v1/groups_controller.rb +65 -0
  91. data/app/controllers/red_base/api/v1/logs_controller.rb +12 -0
  92. data/app/controllers/red_base/api/v1/permissions_controller.rb +17 -0
  93. data/app/controllers/red_base/api/v1/users_controller.rb +54 -0
  94. data/app/controllers/red_base/api_controller.rb +51 -0
  95. data/app/controllers/red_base/application_controller.rb +34 -0
  96. data/app/controllers/red_base/dashboard_controller.rb +40 -0
  97. data/app/controllers/red_base/home_controller.rb +19 -0
  98. data/app/controllers/red_base/omniauth/callbacks_controller.rb +43 -0
  99. data/app/controllers/red_base/users/omniauth_callbacks_controller.rb~ +2 -0
  100. data/app/helpers/red_base/application_helper.rb +4 -0
  101. data/app/helpers/red_base/dashboard_helper.rb +5 -0
  102. data/app/helpers/red_base/groups_helper.rb +4 -0
  103. data/app/helpers/red_base/home_helper.rb +4 -0
  104. data/app/helpers/red_base/users_helper.rb +4 -0
  105. data/app/models/ability.rb +39 -0
  106. data/app/models/red_base/group.rb +27 -0
  107. data/app/models/red_base/permission.rb +15 -0
  108. data/app/models/red_base/user.rb +77 -0
  109. data/app/views/angularjs_templates/auth/groups/details.html +21 -0
  110. data/app/views/angularjs_templates/auth/groups/index.html +5 -0
  111. data/app/views/angularjs_templates/auth/groups/new.html +40 -0
  112. data/app/views/angularjs_templates/auth/index.html +30 -0
  113. data/app/views/angularjs_templates/auth/users/details.html +28 -0
  114. data/app/views/angularjs_templates/auth/users/index.html +6 -0
  115. data/app/views/angularjs_templates/auth/users/new.html +45 -0
  116. data/app/views/angularjs_templates/index.html +8 -0
  117. data/app/views/angularjs_templates/list-view/index.html +66 -0
  118. data/app/views/angularjs_templates/locale/fa.po +25 -0
  119. data/app/views/angularjs_templates/locale/templates.pot +24 -0
  120. data/app/views/angularjs_templates/logs/index.html +6 -0
  121. data/app/views/angularjs_templates/modules.html +17 -0
  122. data/app/views/angularjs_templates/nav.html.erb +38 -0
  123. data/app/views/angularjs_templates/nav.html.erb~ +43 -0
  124. data/app/views/devise/confirmations/new.html.erb +34 -0
  125. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  126. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  127. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  128. data/app/views/devise/passwords/edit.html.erb +44 -0
  129. data/app/views/devise/passwords/new.html.erb +32 -0
  130. data/app/views/devise/registrations/edit.html.erb +29 -0
  131. data/app/views/devise/registrations/new.html.erb +91 -0
  132. data/app/views/devise/sessions/new.html.erb +98 -0
  133. data/app/views/devise/shared/_links.erb +25 -0
  134. data/app/views/devise/unlocks/new.html.erb +30 -0
  135. data/app/views/layouts/red_base/application.html.erb +90 -0
  136. data/app/views/layouts/red_base/dashboard.html.erb +21 -0
  137. data/app/views/red_base/api/v1/groups/create.json.jbuilder +4 -0
  138. data/app/views/red_base/api/v1/groups/destroy.html.erb +2 -0
  139. data/app/views/red_base/api/v1/groups/destroy.json.jbuilder +1 -0
  140. data/app/views/red_base/api/v1/groups/edit.html.erb +2 -0
  141. data/app/views/red_base/api/v1/groups/index.html.erb +2 -0
  142. data/app/views/red_base/api/v1/groups/index.json.jbuilder +6 -0
  143. data/app/views/red_base/api/v1/groups/new.html.erb +2 -0
  144. data/app/views/red_base/api/v1/groups/show.html.erb +2 -0
  145. data/app/views/red_base/api/v1/groups/show.json.jbuilder +5 -0
  146. data/app/views/red_base/api/v1/groups/update.json.jbuilder +4 -0
  147. data/app/views/red_base/api/v1/logs/index.json.jbuilder +1 -0
  148. data/app/views/red_base/api/v1/permissions/index.json.jbuilder +1 -0
  149. data/app/views/red_base/api/v1/users/create.html.erb +2 -0
  150. data/app/views/red_base/api/v1/users/create.json.jbuilder +1 -0
  151. data/app/views/red_base/api/v1/users/destroy.json.jbuilder +1 -0
  152. data/app/views/red_base/api/v1/users/distroy.html.erb +2 -0
  153. data/app/views/red_base/api/v1/users/edit.html.erb +2 -0
  154. data/app/views/red_base/api/v1/users/index.html.erb +2 -0
  155. data/app/views/red_base/api/v1/users/index.json.jbuilder +4 -0
  156. data/app/views/red_base/api/v1/users/show.html.erb +2 -0
  157. data/app/views/red_base/api/v1/users/show.json.jbuilder +2 -0
  158. data/app/views/red_base/api/v1/users/update.json.jbuilder +1 -0
  159. data/app/views/red_base/dashboard/index.html.erb +37 -0
  160. data/app/views/red_base/home/index.html.erb +119 -0
  161. data/config/initializers/devise.rb +28 -0
  162. data/config/locales/devise.en.yml +59 -0
  163. data/config/locales/devise.fa.yml +56 -0
  164. data/config/locales/fa/LC_MESSAGES/red_base.mo +0 -0
  165. data/config/locales/fa/messages.mo +0 -0
  166. data/config/locales/fa/red_base.po +181 -0
  167. data/config/locales/red_base.pot +181 -0
  168. data/config/routes.rb +33 -0
  169. data/db/migrate/20131013091000_devise_create_red_base_users.rb +64 -0
  170. data/db/migrate/20131020124701_create_red_base_groups.rb +9 -0
  171. data/db/migrate/20131021170923_create_red_base_permissions.rb +10 -0
  172. data/db/migrate/20131123120422_add_permissions_groups_table.rb +8 -0
  173. data/db/seeds.rb +15 -0
  174. data/lib/devise_patch.rb~ +5 -0
  175. data/lib/generators/red_base/USAGE +8 -0
  176. data/lib/generators/red_base/angularjs_resource_generator.rb +74 -0
  177. data/lib/generators/red_base/install_all_generator.rb +38 -0
  178. data/lib/generators/red_base/install_generator.rb +42 -0
  179. data/lib/generators/red_base/install_specs_generator.rb +48 -0
  180. data/lib/generators/red_base/js_scaffold_generator.rb +232 -0
  181. data/lib/generators/red_base/templates/README +41 -0
  182. data/lib/generators/red_base/templates/README~ +4 -0
  183. data/lib/generators/red_base/templates/SPECS +13 -0
  184. data/lib/generators/red_base/templates/angularjs/details.html.erb +20 -0
  185. data/lib/generators/red_base/templates/angularjs/details.html.erb~ +0 -0
  186. data/lib/generators/red_base/templates/angularjs/index.html.erb +59 -0
  187. data/lib/generators/red_base/templates/angularjs/module.js.erb +259 -0
  188. data/lib/generators/red_base/templates/angularjs/new.html.erb +43 -0
  189. data/lib/generators/red_base/templates/api/controller.rb.erb +54 -0
  190. data/lib/generators/red_base/templates/api/controller.rb.erb~ +37 -0
  191. data/lib/generators/red_base/templates/devise.rb +251 -0
  192. data/lib/generators/red_base/templates/devise.rb~ +238 -0
  193. data/lib/generators/red_base/templates/fast_gettext.rb +4 -0
  194. data/lib/generators/red_base/templates/features/api.feature +92 -0
  195. data/lib/generators/red_base/templates/features/api.step.rb +7 -0
  196. data/lib/generators/red_base/templates/features/step_definitions/email_steps.rb +206 -0
  197. data/lib/generators/red_base/templates/features/support/email_spec.rb +1 -0
  198. data/lib/generators/red_base/templates/features/support/env.rb +79 -0
  199. data/lib/generators/red_base/templates/formtastic.rb +76 -0
  200. data/lib/generators/red_base/templates/js_scaffold.README +25 -0
  201. data/lib/generators/red_base/templates/red_base.rb +14 -0
  202. data/lib/generators/red_base/templates/red_base.rb~ +251 -0
  203. data/lib/generators/red_base/templates/seeds.rb +1 -0
  204. data/lib/generators/red_base/templates/spec/factories/groups.rb +5 -0
  205. data/lib/generators/red_base/templates/spec/factories/users.rb +10 -0
  206. data/lib/generators/red_base/templates/spec/spec_helper.rb +69 -0
  207. data/lib/generators/red_base/templates/spec/support/devise.rb +3 -0
  208. data/lib/generators/red_base/templates/views/create.json.jbuilder.erb +2 -0
  209. data/lib/generators/red_base/templates/views/destroy.json.jbuilder.erb +1 -0
  210. data/lib/generators/red_base/templates/views/index.json.jbuilder.erb +10 -0
  211. data/lib/generators/red_base/templates/views/index.json.jbuilder.erb~ +0 -0
  212. data/lib/generators/red_base/templates/views/show.json.jbuilder.erb +6 -0
  213. data/lib/generators/red_base/templates/views/update.json.jbuilder.erb +6 -0
  214. data/lib/generators/red_base/views_generator.rb +41 -0
  215. data/lib/red_base/active_record.rb +78 -0
  216. data/lib/red_base/active_record.rb~ +0 -0
  217. data/lib/red_base/api/groups_api.rb +41 -0
  218. data/lib/red_base/api/permissions_api.rb +24 -0
  219. data/lib/red_base/api/root.rb +15 -0
  220. data/lib/red_base/api/users_api.rb +20 -0
  221. data/lib/red_base/api.rb +61 -0
  222. data/lib/red_base/cucumber/auth.rb +45 -0
  223. data/lib/red_base/cucumber/exceptions.rb +40 -0
  224. data/lib/red_base/cucumber/interaction.rb +43 -0
  225. data/lib/red_base/cucumber/query.rb +28 -0
  226. data/lib/red_base/cucumber/urls.rb +76 -0
  227. data/lib/red_base/cucumber.rb +25 -0
  228. data/lib/red_base/dashboard/controller.rb +42 -0
  229. data/lib/red_base/dashboard/module.rb +45 -0
  230. data/lib/red_base/dashboard/module.rb~ +25 -0
  231. data/lib/red_base/dashboard.rb +60 -0
  232. data/lib/red_base/dashboard.rb~ +18 -0
  233. data/lib/red_base/engine.rb +132 -0
  234. data/lib/red_base/exceptions.rb +26 -0
  235. data/lib/red_base/i18n.rb +35 -0
  236. data/lib/red_base/initialize.rb +7 -0
  237. data/lib/red_base/omniauth/callbacks.rb +58 -0
  238. data/lib/red_base/omniauth/callbakcs.rb~ +7 -0
  239. data/lib/red_base/omniauth.rb +24 -0
  240. data/lib/red_base/omniauth.rb~ +1 -0
  241. data/lib/red_base/plugins.rb +44 -0
  242. data/lib/red_base/version.rb +22 -0
  243. data/lib/red_base.rb +30 -0
  244. data/lib/tasks/grunt/Gruntfile.js +25 -0
  245. data/lib/tasks/red_base_tasks.rake +23 -0
  246. data/spec/dummy/README.rdoc +28 -0
  247. data/spec/dummy/Rakefile +6 -0
  248. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  249. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  250. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  251. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  252. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  253. data/spec/dummy/bin/bundle +3 -0
  254. data/spec/dummy/bin/rails +4 -0
  255. data/spec/dummy/bin/rake +4 -0
  256. data/spec/dummy/config/application.rb +23 -0
  257. data/spec/dummy/config/boot.rb +5 -0
  258. data/spec/dummy/config/database.yml +25 -0
  259. data/spec/dummy/config/environment.rb +5 -0
  260. data/spec/dummy/config/environments/development.rb +29 -0
  261. data/spec/dummy/config/environments/production.rb +80 -0
  262. data/spec/dummy/config/environments/test.rb +36 -0
  263. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  264. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  265. data/spec/dummy/config/initializers/inflections.rb +16 -0
  266. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  267. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  268. data/spec/dummy/config/initializers/session_store.rb +3 -0
  269. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  270. data/spec/dummy/config/locales/en.yml +23 -0
  271. data/spec/dummy/config/routes.rb +4 -0
  272. data/spec/dummy/config.ru +4 -0
  273. data/spec/dummy/public/404.html +58 -0
  274. data/spec/dummy/public/422.html +58 -0
  275. data/spec/dummy/public/500.html +57 -0
  276. data/spec/dummy/public/favicon.ico +0 -0
  277. data/spec/spec_helper.rb +52 -0
  278. metadata +661 -0
@@ -0,0 +1,1066 @@
1
+ (function() {
2
+
3
+ var module = angular.module('restangular', []);
4
+
5
+ module.provider('Restangular', function() {
6
+ // Configuration
7
+ var Configurer = {};
8
+ Configurer.init = function(object, config) {
9
+ /**
10
+ * Those are HTTP safe methods for which there is no need to pass any data with the request.
11
+ */
12
+
13
+ object.configuration = config;
14
+
15
+ var safeMethods= ["get", "head", "options", "trace", "getlist"];
16
+ config.isSafe = function(operation) {
17
+ return _.contains(safeMethods, operation.toLowerCase());
18
+ };
19
+
20
+ var absolutePattern = /^https?:\/\//i;
21
+ config.isAbsoluteUrl = function(string) {
22
+ return string && absolutePattern.test(string);
23
+ };
24
+ /**
25
+ * This is the BaseURL to be used with Restangular
26
+ */
27
+ config.baseUrl = _.isUndefined(config.baseUrl) ? "" : config.baseUrl;
28
+ object.setBaseUrl = function(newBaseUrl) {
29
+ config.baseUrl = /\/$/.test(newBaseUrl)
30
+ ? newBaseUrl.substring(0, newBaseUrl.length-1)
31
+ : newBaseUrl;
32
+ return this;
33
+ };
34
+
35
+ /**
36
+ * Sets the extra fields to keep from the parents
37
+ */
38
+ config.extraFields = config.extraFields || [];
39
+ object.setExtraFields = function(newExtraFields) {
40
+ config.extraFields = newExtraFields;
41
+ return this;
42
+ };
43
+
44
+ /**
45
+ * Some default $http parameter to be used in EVERY call
46
+ **/
47
+ config.defaultHttpFields = config.defaultHttpFields || {};
48
+ object.setDefaultHttpFields = function(values) {
49
+ config.defaultHttpFields = values;
50
+ return this;
51
+ };
52
+
53
+ config.withHttpValues = function(httpLocalConfig, obj) {
54
+ return _.defaults(obj, httpLocalConfig, config.defaultHttpFields);
55
+ };
56
+
57
+ config.encodeIds = _.isUndefined(config.encodeIds) ? true : config.encodeIds;
58
+ object.setEncodeIds = function(encode) {
59
+ config.encodeIds = encode;
60
+ }
61
+
62
+ config.defaultRequestParams = config.defaultRequestParams || {
63
+ get: {},
64
+ post: {},
65
+ put: {},
66
+ remove: {},
67
+ common: {}
68
+ };
69
+
70
+ object.setDefaultRequestParams = function(param1, param2) {
71
+ var methods = [],
72
+ params = param2 || param1;
73
+ if (!_.isUndefined(param2)) {
74
+ if (_.isArray(param1)) {
75
+ methods = param1;
76
+ } else {
77
+ methods.push(param1);
78
+ }
79
+ } else {
80
+ methods.push('common');
81
+ }
82
+
83
+ _.each(methods, function (method) {
84
+ config.defaultRequestParams[method] = params;
85
+ });
86
+ return this;
87
+ }
88
+
89
+ object.requestParams = config.defaultRequestParams;
90
+
91
+
92
+ config.defaultHeaders = config.defaultHeaders || {};
93
+ object.setDefaultHeaders = function(headers) {
94
+ config.defaultHeaders = headers;
95
+ object.defaultHeaders = config.defaultHeaders;
96
+ return this;
97
+ };
98
+
99
+ object.defaultHeaders = config.defaultHeaders;
100
+
101
+ /**
102
+ * Method overriders will set which methods are sent via POST with an X-HTTP-Method-Override
103
+ **/
104
+ config.methodOverriders = config.methodOverriders || [];
105
+ object.setMethodOverriders = function(values) {
106
+ var overriders = _.extend([], values);
107
+ if (config.isOverridenMethod('delete', overriders)) {
108
+ overriders.push("remove");
109
+ }
110
+ config.methodOverriders = overriders;
111
+ return this;
112
+ };
113
+
114
+ config.isOverridenMethod = function(method, values) {
115
+ var search = values || config.methodOverriders;
116
+ return !_.isUndefined(_.find(search, function(one) {
117
+ return one.toLowerCase() === method.toLowerCase();
118
+ }));
119
+ };
120
+
121
+ /**
122
+ * Sets the URL creator type. For now, only Path is created. In the future we'll have queryParams
123
+ **/
124
+ config.urlCreator = config.urlCreator || "path";
125
+ object.setUrlCreator = function(name) {
126
+ if (!_.has(config.urlCreatorFactory, name)) {
127
+ throw new Error("URL Path selected isn't valid");
128
+ }
129
+
130
+ config.urlCreator = name;
131
+ return this;
132
+ };
133
+
134
+ /**
135
+ * You can set the restangular fields here. The 3 required fields for Restangular are:
136
+ *
137
+ * id: Id of the element
138
+ * route: name of the route of this element
139
+ * parentResource: the reference to the parent resource
140
+ *
141
+ * All of this fields except for id, are handled (and created) by Restangular. By default,
142
+ * the field values will be id, route and parentResource respectively
143
+ */
144
+ config.restangularFields = config.restangularFields || {
145
+ id: "id",
146
+ route: "route",
147
+ parentResource: "parentResource",
148
+ restangularCollection: "restangularCollection",
149
+ cannonicalId: "__cannonicalId",
150
+ etag: "restangularEtag",
151
+ selfLink: "href",
152
+ get: "get",
153
+ getList: "getList",
154
+ put: "put",
155
+ post: "post",
156
+ remove: "remove",
157
+ head: "head",
158
+ trace: "trace",
159
+ options: "options",
160
+ patch: "patch",
161
+ getRestangularUrl: "getRestangularUrl",
162
+ putElement: "putElement",
163
+ addRestangularMethod: "addRestangularMethod",
164
+ getParentList: "getParentList",
165
+ clone: "clone",
166
+ ids: "ids",
167
+ httpConfig: '_$httpConfig'
168
+ };
169
+ object.setRestangularFields = function(resFields) {
170
+ config.restangularFields =
171
+ _.extend(config.restangularFields, resFields);
172
+ return this;
173
+ };
174
+
175
+ config.setFieldToElem = function(field, elem, value) {
176
+ var properties = field.split('.');
177
+ var idValue = elem;
178
+ _.each(_.initial(properties), function(prop) {
179
+ idValue[prop] = {};
180
+ idValue = idValue[prop];
181
+ });
182
+ idValue[_.last(properties)] = value;
183
+ return this;
184
+ };
185
+
186
+ config.getFieldFromElem = function(field, elem) {
187
+ var properties = field.split('.');
188
+ var idValue = angular.copy(elem);
189
+ _.each(properties, function(prop) {
190
+ if (idValue) {
191
+ idValue = idValue[prop];
192
+ }
193
+ });
194
+ return idValue;
195
+ };
196
+
197
+ config.setIdToElem = function(elem, id) {
198
+ config.setFieldToElem(config.restangularFields.id, elem, id);
199
+ return this;
200
+ };
201
+
202
+ config.getIdFromElem = function(elem) {
203
+ return config.getFieldFromElem(config.restangularFields.id, elem);
204
+ };
205
+
206
+ config.isValidId = function(elemId) {
207
+ return "" !== elemId && !_.isUndefined(elemId) && !_.isNull(elemId)
208
+ }
209
+
210
+ config.setUrlToElem = function(elem, url) {
211
+ config.setFieldToElem(config.restangularFields.selfLink, elem, url);
212
+ return this;
213
+ }
214
+
215
+ config.getUrlFromElem = function(elem) {
216
+ return config.getFieldFromElem(config.restangularFields.selfLink, elem);
217
+ }
218
+
219
+ config.useCannonicalId = _.isUndefined(config.useCannonicalId) ? false : config.useCannonicalId;
220
+ object.setUseCannonicalId = function(value) {
221
+ config.useCannonicalId = value;
222
+ return this;
223
+ }
224
+
225
+ config.getCannonicalIdFromElem = function(elem) {
226
+ var cannonicalId = elem[config.restangularFields.cannonicalId];
227
+ var actualId = config.isValidId(cannonicalId) ?
228
+ cannonicalId : config.getIdFromElem(elem);
229
+ return actualId;
230
+ };
231
+
232
+ /**
233
+ * Sets the Response parser. This is used in case your response isn't directly the data.
234
+ * For example if you have a response like {meta: {'meta'}, data: {name: 'Gonto'}}
235
+ * you can extract this data which is the one that needs wrapping
236
+ *
237
+ * The ResponseExtractor is a function that receives the response and the method executed.
238
+ */
239
+
240
+ config.responseExtractor = config.responseExtractor || function(data, operation,
241
+ what, url, response, deferred) {
242
+ return data;
243
+ };
244
+
245
+ object.setResponseExtractor = function(extractor) {
246
+ config.responseExtractor = extractor;
247
+ return this;
248
+ };
249
+
250
+ object.setResponseInterceptor = object.setResponseExtractor;
251
+
252
+ /**
253
+ * Response interceptor is called just before resolving promises.
254
+ */
255
+
256
+
257
+ /**
258
+ * Request interceptor is called before sending an object to the server.
259
+ */
260
+ config.fullRequestInterceptor = config.fullRequestInterceptor || function(element, operation,
261
+ path, url, headers, params, httpConfig) {
262
+ return {
263
+ element: element,
264
+ headers: headers,
265
+ params: params,
266
+ httpConfig: httpConfig
267
+ };
268
+ };
269
+
270
+ object.setRequestInterceptor = function(interceptor) {
271
+ config.fullRequestInterceptor = function(elem, operation, path, url, headers, params, httpConfig) {
272
+ return {
273
+ headers: headers,
274
+ params: params,
275
+ element: interceptor(elem, operation, path, url),
276
+ httpConfig: httpConfig
277
+ }
278
+ };
279
+ return this;
280
+ };
281
+
282
+ object.setFullRequestInterceptor = function(interceptor) {
283
+ config.fullRequestInterceptor = interceptor;
284
+ return this;
285
+ };
286
+
287
+ config.errorInterceptor = config.errorInterceptor || function() {};
288
+
289
+ object.setErrorInterceptor = function(interceptor) {
290
+ config.errorInterceptor = interceptor;
291
+ return this;
292
+ };
293
+
294
+ config.onBeforeElemRestangularized = config.onBeforeElemRestangularized || function(elem) {
295
+ return elem;
296
+ }
297
+ object.setOnBeforeElemRestangularized = function(post) {
298
+ config.onBeforeElemRestangularized = post;
299
+ return this;
300
+ };
301
+
302
+ /**
303
+ * This method is called after an element has been "Restangularized".
304
+ *
305
+ * It receives the element, a boolean indicating if it's an element or a collection
306
+ * and the name of the model
307
+ *
308
+ */
309
+ config.onElemRestangularized = config.onElemRestangularized || function(elem) {
310
+ return elem;
311
+ };
312
+ object.setOnElemRestangularized = function(post) {
313
+ config.onElemRestangularized = post;
314
+ return this;
315
+ };
316
+
317
+ /**
318
+ * Depracated. Don't use this!!
319
+ */
320
+ object.setListTypeIsArray = function(val) {
321
+
322
+ };
323
+
324
+ config.shouldSaveParent = config.shouldSaveParent || function() {
325
+ return true;
326
+ };
327
+ object.setParentless = function(values) {
328
+ if (_.isArray(values)) {
329
+ config.shouldSaveParent = function(route) {
330
+ return !_.contains(values, route);
331
+ }
332
+ } else if (_.isBoolean(values)) {
333
+ config.shouldSaveParent = function() {
334
+ return !values;
335
+ }
336
+ }
337
+ return this;
338
+ };
339
+
340
+ /**
341
+ * This lets you set a suffix to every request.
342
+ *
343
+ * For example, if your api requires that for JSon requests you do /users/123.json, you can set that
344
+ * in here.
345
+ *
346
+ *
347
+ * By default, the suffix is null
348
+ */
349
+ config.suffix = _.isUndefined(config.suffix) ? null : config.suffix;
350
+ object.setRequestSuffix = function(newSuffix) {
351
+ config.suffix = newSuffix;
352
+ return this;
353
+ };
354
+
355
+ /**
356
+ * Add element transformers for certain routes.
357
+ */
358
+ config.transformers = config.transformers || {};
359
+ object.addElementTransformer = function(type, secondArg, thirdArg) {
360
+ var isCollection = null;
361
+ var transformer = null;
362
+ if (arguments.length === 2) {
363
+ transformer = secondArg;
364
+ } else {
365
+ transformer = thirdArg;
366
+ isCollection = secondArg;
367
+ }
368
+
369
+ var typeTransformers = config.transformers[type];
370
+ if (!typeTransformers) {
371
+ typeTransformers = config.transformers[type] = [];
372
+ }
373
+
374
+ typeTransformers.push(function(coll, elem) {
375
+ if (_.isNull(isCollection) || (coll == isCollection)) {
376
+ return transformer(elem);
377
+ }
378
+ return elem;
379
+ });
380
+ };
381
+
382
+ object.extendCollection = function(route, fn) {
383
+ return object.addElementTransformer(route, true, fn);
384
+ };
385
+
386
+ object.extendModel = function(route, fn) {
387
+ return object.addElementTransformer(route, false, fn);
388
+ };
389
+
390
+ config.transformElem = function(elem, isCollection, route, Restangular) {
391
+ var typeTransformers = config.transformers[route];
392
+ var changedElem = elem;
393
+ if (typeTransformers) {
394
+ _.each(typeTransformers, function(transformer) {
395
+ changedElem = transformer(isCollection, changedElem);
396
+ });
397
+ }
398
+ return config.onElemRestangularized(changedElem,
399
+ isCollection, route, Restangular);
400
+ };
401
+
402
+ config.fullResponse = _.isUndefined(config.fullResponse) ? false : config.fullResponse;
403
+ object.setFullResponse = function(full) {
404
+ config.fullResponse = full;
405
+ return this;
406
+ };
407
+
408
+
409
+
410
+ //Internal values and functions
411
+ config.urlCreatorFactory = {};
412
+
413
+ /**
414
+ * Base URL Creator. Base prototype for everything related to it
415
+ **/
416
+
417
+ var BaseCreator = function() {
418
+ };
419
+
420
+ BaseCreator.prototype.setConfig = function(config) {
421
+ this.config = config;
422
+ return this;
423
+ };
424
+
425
+ BaseCreator.prototype.parentsArray = function(current) {
426
+ var parents = [];
427
+ while(current) {
428
+ parents.push(current);
429
+ current = current[this.config.restangularFields.parentResource];
430
+ }
431
+ return parents.reverse();
432
+ };
433
+
434
+ function RestangularResource(config, $http, url, configurer) {
435
+ var resource = {};
436
+ _.each(_.keys(configurer), function(key) {
437
+ var value = configurer[key];
438
+
439
+ // Add default parameters
440
+ value.params = _.extend({}, value.params,
441
+ config.defaultRequestParams[value.method.toLowerCase()]);
442
+ // We don't want the ? if no params are there
443
+ if (_.isEmpty(value.params)) {
444
+ delete value.params;
445
+ }
446
+
447
+ if (config.isSafe(value.method)) {
448
+
449
+ resource[key] = function() {
450
+ return $http(_.extend(value, {
451
+ url: url
452
+ }));
453
+ }
454
+
455
+ } else {
456
+
457
+ resource[key] = function(data) {
458
+ return $http(_.extend(value, {
459
+ url: url,
460
+ data: data
461
+ }));
462
+ }
463
+
464
+ }
465
+ });
466
+
467
+ return resource;
468
+ }
469
+
470
+ BaseCreator.prototype.resource = function(current, $http, localHttpConfig, callHeaders, callParams, what, etag, operation) {
471
+
472
+ var params = _.defaults(callParams || {}, this.config.defaultRequestParams.common);
473
+ var headers = _.defaults(callHeaders || {}, this.config.defaultHeaders);
474
+
475
+ if (etag) {
476
+ if (!config.isSafe(operation)) {
477
+ headers['If-Match'] = etag;
478
+ } else {
479
+ headers['If-None-Match'] = etag;
480
+ }
481
+ }
482
+
483
+ var url = this.base(current);
484
+
485
+ if (what) {
486
+ var add = '';
487
+ if (!/\/$/.test(url)) {
488
+ add += '/';
489
+ }
490
+ add += what;
491
+ url += add;
492
+ }
493
+
494
+ if (this.config.suffix
495
+ && url.indexOf(this.config.suffix, url.length - this.config.suffix.length) === -1) {
496
+
497
+ url += this.config.suffix;
498
+ }
499
+
500
+ current[this.config.restangularFields.httpConfig] = undefined;
501
+
502
+
503
+ return RestangularResource(this.config, $http, url, {
504
+ getList: this.config.withHttpValues(localHttpConfig,
505
+ {method: 'GET',
506
+ params: params,
507
+ headers: headers}),
508
+
509
+ get: this.config.withHttpValues(localHttpConfig,
510
+ {method: 'GET',
511
+ params: params,
512
+ headers: headers}),
513
+
514
+ put: this.config.withHttpValues(localHttpConfig,
515
+ {method: 'PUT',
516
+ params: params,
517
+ headers: headers}),
518
+
519
+ post: this.config.withHttpValues(localHttpConfig,
520
+ {method: 'POST',
521
+ params: params,
522
+ headers: headers}),
523
+
524
+ remove: this.config.withHttpValues(localHttpConfig,
525
+ {method: 'DELETE',
526
+ params: params,
527
+ headers: headers}),
528
+
529
+ head: this.config.withHttpValues(localHttpConfig,
530
+ {method: 'HEAD',
531
+ params: params,
532
+ headers: headers}),
533
+
534
+ trace: this.config.withHttpValues(localHttpConfig,
535
+ {method: 'TRACE',
536
+ params: params,
537
+ headers: headers}),
538
+
539
+ options: this.config.withHttpValues(localHttpConfig,
540
+ {method: 'OPTIONS',
541
+ params: params,
542
+ headers: headers}),
543
+
544
+ patch: this.config.withHttpValues(localHttpConfig,
545
+ {method: 'PATCH',
546
+ params: params,
547
+ headers: headers})
548
+ });
549
+ };
550
+
551
+ /**
552
+ * This is the Path URL creator. It uses Path to show Hierarchy in the Rest API.
553
+ * This means that if you have an Account that then has a set of Buildings, a URL to a building
554
+ * would be /accounts/123/buildings/456
555
+ **/
556
+ var Path = function() {
557
+ };
558
+
559
+ Path.prototype = new BaseCreator();
560
+
561
+ Path.prototype.base = function(current) {
562
+ var __this = this;
563
+ return _.reduce(this.parentsArray(current), function(acum, elem) {
564
+ var elemUrl;
565
+ var elemSelfLink = __this.config.getUrlFromElem(elem);
566
+ if (elemSelfLink) {
567
+ if (__this.config.isAbsoluteUrl(elemSelfLink)) {
568
+ return elemSelfLink;
569
+ } else {
570
+ elemUrl = elemSelfLink;
571
+ }
572
+ } else {
573
+ elemUrl = elem[__this.config.restangularFields.route];
574
+
575
+ if (elem[__this.config.restangularFields.restangularCollection]) {
576
+ var ids = elem[__this.config.restangularFields.ids];
577
+ if (ids) {
578
+ elemUrl += "/" + ids.join(",");
579
+ }
580
+ } else {
581
+ var elemId;
582
+ if (__this.config.useCannonicalId) {
583
+ elemId = __this.config.getCannonicalIdFromElem(elem);
584
+ } else {
585
+ elemId = __this.config.getIdFromElem(elem);
586
+ }
587
+
588
+ if (config.isValidId(elemId)) {
589
+ elemUrl += "/" + (__this.config.encodeIds ? encodeURIComponent(elemId) : elemId);
590
+ }
591
+ }
592
+ }
593
+
594
+ return acum + "/" + elemUrl;
595
+
596
+ }, this.config.baseUrl);
597
+ };
598
+
599
+
600
+
601
+ Path.prototype.fetchUrl = function(current, what) {
602
+ var baseUrl = this.base(current);
603
+ if (what) {
604
+ baseUrl += "/" + what;
605
+ }
606
+ return baseUrl;
607
+ };
608
+
609
+
610
+
611
+ config.urlCreatorFactory.path = Path;
612
+
613
+ }
614
+
615
+ var globalConfiguration = {};
616
+
617
+ Configurer.init(this, globalConfiguration);
618
+
619
+
620
+
621
+
622
+ this.$get = ['$http', '$q', function($http, $q) {
623
+
624
+ function createServiceForConfiguration(config) {
625
+ var service = {};
626
+
627
+ var urlHandler = new config.urlCreatorFactory[config.urlCreator]();
628
+ urlHandler.setConfig(config);
629
+
630
+ function restangularizeBase(parent, elem, route) {
631
+ elem[config.restangularFields.route] = route;
632
+ elem[config.restangularFields.getRestangularUrl] = _.bind(urlHandler.fetchUrl, urlHandler, elem);
633
+ elem[config.restangularFields.addRestangularMethod] = _.bind(addRestangularMethodFunction, elem);
634
+ elem[config.restangularFields.clone] = _.bind(copyRestangularizedElement, elem, elem);
635
+ elem.withHttpConfig = _.bind(withHttpConfig, elem);
636
+
637
+ // RequestLess connection
638
+ elem.one = _.bind(one, elem, elem);
639
+ elem.all = _.bind(all, elem, elem);
640
+ elem.several = _.bind(several, elem, elem);
641
+ elem.oneUrl = _.bind(oneUrl, elem, elem);
642
+ elem.allUrl = _.bind(allUrl, elem, elem);
643
+
644
+ if (parent && config.shouldSaveParent(route)) {
645
+ var parentId = config.getIdFromElem(parent);
646
+ var parentUrl = config.getUrlFromElem(parent);
647
+
648
+ var restangularFieldsForParent = _.union(
649
+ _.values( _.pick(config.restangularFields, ['route', 'parentResource']) ),
650
+ config.extraFields
651
+ );
652
+ var parentResource = _.pick(parent, restangularFieldsForParent);
653
+
654
+ if (config.isValidId(parentId)) {
655
+ config.setIdToElem(parentResource, parentId);
656
+ }
657
+ if (config.isValidId(parentUrl)) {
658
+ config.setUrlToElem(parentResource, parentUrl);
659
+ }
660
+
661
+ elem[config.restangularFields.parentResource] = parentResource;
662
+ } else {
663
+ elem[config.restangularFields.parentResource] = null;
664
+ }
665
+ return elem;
666
+ }
667
+
668
+
669
+
670
+ function one(parent, route, id) {
671
+ var elem = {};
672
+ config.setIdToElem(elem, id);
673
+ return restangularizeElem(parent, elem , route);
674
+ }
675
+
676
+
677
+ function all(parent, route) {
678
+ return restangularizeCollection(parent, [] , route, true);
679
+ }
680
+
681
+ function several(parent, route, ids) {
682
+ var collection = [];
683
+ collection[config.restangularFields.ids] =
684
+ Array.prototype.splice.call(arguments, 2);
685
+ return restangularizeCollection(parent, collection , route, true);
686
+ }
687
+
688
+ function oneUrl(parent, route, url) {
689
+ var elem = {};
690
+ config.setUrlToElem(elem, url);
691
+ return restangularizeElem(parent, elem , route);
692
+ }
693
+
694
+
695
+ function allUrl(parent, route, url) {
696
+ var elem = {};
697
+ config.setUrlToElem(elem, url);
698
+ return restangularizeCollection(parent, elem , route, true);
699
+ }
700
+ // Promises
701
+ function restangularizePromise(promise, isCollection) {
702
+ promise.call = _.bind(promiseCall, promise);
703
+ promise.get = _.bind(promiseGet, promise);
704
+ promise[config.restangularFields.restangularCollection] = isCollection;
705
+ if (isCollection) {
706
+ promise.push = _.bind(promiseCall, promise, "push");
707
+ }
708
+ return promise;
709
+ }
710
+
711
+ function promiseCall(method) {
712
+ var deferred = $q.defer();
713
+ var callArgs = arguments;
714
+ this.then(function(val) {
715
+ var params = Array.prototype.slice.call(callArgs, 1);
716
+ var func = val[method];
717
+ func.apply(val, params);
718
+ deferred.resolve(val);
719
+ });
720
+ return restangularizePromise(deferred.promise, this[config.restangularFields.restangularCollection]);
721
+ }
722
+
723
+ function promiseGet(what) {
724
+ var deferred = $q.defer();
725
+ this.then(function(val) {
726
+ deferred.resolve(val[what]);
727
+ });
728
+ return restangularizePromise(deferred.promise, this[config.restangularFields.restangularCollection]);
729
+ }
730
+
731
+ function resolvePromise(deferred, response, data) {
732
+
733
+ // Trigger the full response interceptor.
734
+ if (config.fullResponse) {
735
+ return deferred.resolve(_.extend(response, {
736
+ data: data
737
+ }));
738
+ } else {
739
+ deferred.resolve(data);
740
+ }
741
+ }
742
+
743
+
744
+ // Elements
745
+
746
+ function stripRestangular(elem) {
747
+ return _.omit(elem, _.values(_.omit(config.restangularFields, 'id')));
748
+ }
749
+
750
+ function addCustomOperation(elem) {
751
+ elem.customOperation = _.bind(customFunction, elem);
752
+ _.each(["put", "post", "get", "delete"], function(oper) {
753
+ _.each(["do", "custom"], function(alias) {
754
+ var callOperation = oper === 'delete' ? 'remove' : oper;
755
+ var name = alias + oper.toUpperCase();
756
+ var callFunction;
757
+
758
+ if (callOperation !== 'put' && callOperation !== 'post') {
759
+ callFunction = customFunction;
760
+ } else {
761
+ callFunction = function(operation, elem, path, params, headers) {
762
+ return _.bind(customFunction, this)(operation, path, params, headers, elem);
763
+ }
764
+ }
765
+ elem[name] = _.bind(callFunction, elem, callOperation);
766
+ });
767
+ });
768
+ elem.customGETLIST = _.bind(fetchFunction, elem);
769
+ elem.doGETLIST = elem.customGETLIST;
770
+ }
771
+
772
+ function copyRestangularizedElement(fromElement) {
773
+ var copiedElement = angular.copy(fromElement);
774
+ return restangularizeElem(copiedElement[config.restangularFields.parentResource],
775
+ copiedElement, copiedElement[config.restangularFields.route]);
776
+ }
777
+
778
+ function restangularizeElem(parent, element, route, collection) {
779
+ var elem = config.onBeforeElemRestangularized(element, false, route);
780
+
781
+ var localElem = restangularizeBase(parent, elem, route);
782
+
783
+ if (config.useCannonicalId) {
784
+ localElem[config.restangularFields.cannonicalId] = config.getIdFromElem(localElem)
785
+ }
786
+
787
+ if (collection) {
788
+ localElem[config.restangularFields.getParentList] = function() {
789
+ return collection;
790
+ }
791
+ }
792
+
793
+
794
+ localElem[config.restangularFields.restangularCollection] = false;
795
+ localElem[config.restangularFields.get] = _.bind(getFunction, localElem);
796
+ localElem[config.restangularFields.getList] = _.bind(fetchFunction, localElem);
797
+ localElem[config.restangularFields.put] = _.bind(putFunction, localElem);
798
+ localElem[config.restangularFields.post] = _.bind(postFunction, localElem);
799
+ localElem[config.restangularFields.remove] = _.bind(deleteFunction, localElem);
800
+ localElem[config.restangularFields.head] = _.bind(headFunction, localElem);
801
+ localElem[config.restangularFields.trace] = _.bind(traceFunction, localElem);
802
+ localElem[config.restangularFields.options] = _.bind(optionsFunction, localElem);
803
+ localElem[config.restangularFields.patch] = _.bind(patchFunction, localElem);
804
+
805
+ addCustomOperation(localElem);
806
+ return config.transformElem(localElem, false, route, service);
807
+ }
808
+
809
+ function restangularizeCollection(parent, element, route) {
810
+ var elem = config.onBeforeElemRestangularized(element, true, route);
811
+
812
+ var localElem = restangularizeBase(parent, elem, route);
813
+ localElem[config.restangularFields.restangularCollection] = true;
814
+ localElem[config.restangularFields.post] = _.bind(postFunction, localElem, null);
815
+ localElem[config.restangularFields.head] = _.bind(headFunction, localElem);
816
+ localElem[config.restangularFields.trace] = _.bind(traceFunction, localElem);
817
+ localElem[config.restangularFields.putElement] = _.bind(putElementFunction, localElem);
818
+ localElem[config.restangularFields.options] = _.bind(optionsFunction, localElem);
819
+ localElem[config.restangularFields.patch] = _.bind(patchFunction, localElem);
820
+ localElem[config.restangularFields.get] = _.bind(getById, localElem);
821
+ localElem[config.restangularFields.getList] = _.bind(fetchFunction, localElem, null);
822
+
823
+ addCustomOperation(localElem);
824
+ return config.transformElem(localElem, true, route, service);
825
+ }
826
+
827
+ function getById(id, reqParams, headers){
828
+ return this.customGET(id.toString(), reqParams, headers);
829
+ }
830
+
831
+ function putElementFunction(idx, params, headers) {
832
+ var __this = this;
833
+ var elemToPut = this[idx];
834
+ var deferred = $q.defer();
835
+ elemToPut.put(params, headers).then(function(serverElem) {
836
+ var newArray = copyRestangularizedElement(__this);
837
+ newArray[idx] = serverElem;
838
+ deferred.resolve(newArray);
839
+ }, function(response) {
840
+ deferred.reject(response);
841
+ });
842
+
843
+ return restangularizePromise(deferred.promise, true)
844
+ }
845
+
846
+ function parseResponse(resData, operation, route, fetchUrl, response, deferred) {
847
+ var data = config.responseExtractor(resData, operation, route, fetchUrl, response, deferred);
848
+ var etag = response.headers("ETag");
849
+ if (data && etag) {
850
+ data[config.restangularFields.etag] = etag;
851
+ }
852
+ return data;
853
+ }
854
+
855
+
856
+ function fetchFunction(what, reqParams, headers) {
857
+ var __this = this;
858
+ var deferred = $q.defer();
859
+ var operation = 'getList';
860
+ var url = urlHandler.fetchUrl(this, what);
861
+ var whatFetched = what || __this[config.restangularFields.route];
862
+
863
+
864
+ var request = config.fullRequestInterceptor(null, operation,
865
+ whatFetched, url, headers || {}, reqParams || {}, this[config.restangularFields.httpConfig] || {});
866
+
867
+ urlHandler.resource(this, $http, request.httpConfig, request.headers, request.params, what,
868
+ this[config.restangularFields.etag], operation).getList().then(function(response) {
869
+ var resData = response.data;
870
+ var data = parseResponse(resData, operation, whatFetched, url, response, deferred);
871
+ var processedData = _.map(data, function(elem) {
872
+ if (!__this[config.restangularFields.restangularCollection]) {
873
+ return restangularizeElem(__this, elem, what, data);
874
+ } else {
875
+ return restangularizeElem(__this[config.restangularFields.parentResource],
876
+ elem, __this[config.restangularFields.route], data);
877
+ }
878
+
879
+ });
880
+
881
+ processedData = _.extend(data, processedData);
882
+ if (!__this[config.restangularFields.restangularCollection]) {
883
+ resolvePromise(deferred, response, restangularizeCollection(__this, processedData, what));
884
+ } else {
885
+ resolvePromise(deferred, response, restangularizeCollection(__this[config.restangularFields.parentResource], processedData, __this[config.restangularFields.route]));
886
+ }
887
+ }, function error(response) {
888
+ if ( config.errorInterceptor(response) !== false ) {
889
+ deferred.reject(response);
890
+ }
891
+ });
892
+
893
+ return restangularizePromise(deferred.promise, true);
894
+ }
895
+
896
+ function withHttpConfig(httpConfig) {
897
+ this[config.restangularFields.httpConfig] = httpConfig;
898
+ return this;
899
+ }
900
+
901
+ function elemFunction(operation, what, params, obj, headers) {
902
+ var __this = this;
903
+ var deferred = $q.defer();
904
+ var resParams = params || {};
905
+ var route = what || this[config.restangularFields.route];
906
+ var fetchUrl = urlHandler.fetchUrl(this, what);
907
+
908
+ var callObj = obj || this;
909
+ var etag = callObj[config.restangularFields.etag];
910
+ if (_.isObject(callObj)) {
911
+ callObj = stripRestangular(callObj);
912
+ }
913
+ var request = config.fullRequestInterceptor(callObj, operation, route, fetchUrl,
914
+ headers || {}, resParams || {}, this[config.restangularFields.httpConfig] || {});
915
+
916
+ var okCallback = function(response) {
917
+ var resData = response.data;
918
+ var elem = parseResponse(resData, operation, route, fetchUrl, response, deferred);
919
+ if (elem) {
920
+
921
+ if (operation === "post" && !__this[config.restangularFields.restangularCollection]) {
922
+ resolvePromise(deferred, response, restangularizeElem(__this, elem, what));
923
+ } else {
924
+ resolvePromise(deferred, response, restangularizeElem(__this[config.restangularFields.parentResource], elem, __this[config.restangularFields.route]));
925
+ }
926
+
927
+ } else {
928
+ resolvePromise(deferred, response, undefined);
929
+ }
930
+ };
931
+
932
+ var errorCallback = function(response) {
933
+ if ( config.errorInterceptor(response) !== false ) {
934
+ deferred.reject(response);
935
+ }
936
+ };
937
+ // Overring HTTP Method
938
+ var callOperation = operation;
939
+ var callHeaders = _.extend({}, request.headers);
940
+ var isOverrideOperation = config.isOverridenMethod(operation);
941
+ if (isOverrideOperation) {
942
+ callOperation = 'post';
943
+ callHeaders = _.extend(callHeaders, {'X-HTTP-Method-Override': operation === 'remove' ? 'DELETE' : operation});
944
+ }
945
+
946
+ if (config.isSafe(operation)) {
947
+ if (isOverrideOperation) {
948
+ urlHandler.resource(this, $http, request.httpConfig, callHeaders, request.params,
949
+ what, etag, callOperation)[callOperation]({}).then(okCallback, errorCallback);
950
+ } else {
951
+ urlHandler.resource(this, $http, request.httpConfig, callHeaders, request.params,
952
+ what, etag, callOperation)[callOperation]().then(okCallback, errorCallback);
953
+ }
954
+ } else {
955
+ urlHandler.resource(this, $http, request.httpConfig, callHeaders, request.params,
956
+ what, etag, callOperation)[callOperation](request.element).then(okCallback, errorCallback);
957
+ }
958
+
959
+ return restangularizePromise(deferred.promise);
960
+ }
961
+
962
+ function getFunction(params, headers) {
963
+ return _.bind(elemFunction, this)("get", undefined, params, undefined, headers);
964
+ }
965
+
966
+ function deleteFunction(params, headers) {
967
+ return _.bind(elemFunction, this)("remove", undefined, params, undefined, headers);
968
+ }
969
+
970
+ function putFunction(params, headers) {
971
+ return _.bind(elemFunction, this)("put", undefined, params, undefined, headers);
972
+ }
973
+
974
+ function postFunction(what, elem, params, headers) {
975
+ return _.bind(elemFunction, this)("post", what, params, elem, headers);
976
+ }
977
+
978
+ function headFunction(params, headers) {
979
+ return _.bind(elemFunction, this)("head", undefined, params, undefined, headers);
980
+ }
981
+
982
+ function traceFunction(params, headers) {
983
+ return _.bind(elemFunction, this)("trace", undefined, params, undefined, headers);
984
+ }
985
+
986
+ function optionsFunction(params, headers) {
987
+ return _.bind(elemFunction, this)("options", undefined, params, undefined, headers);
988
+ }
989
+
990
+ function patchFunction(elem, params, headers) {
991
+ return _.bind(elemFunction, this)("patch", undefined, params, elem, headers);
992
+ }
993
+
994
+ function customFunction(operation, path, params, headers, elem) {
995
+ return _.bind(elemFunction, this)(operation, path, params, elem, headers);
996
+ }
997
+
998
+ function addRestangularMethodFunction(name, operation, path, defaultParams, defaultHeaders, defaultElem) {
999
+ var bindedFunction;
1000
+ if (operation === 'getList') {
1001
+ bindedFunction = _.bind(fetchFunction, this, path);
1002
+ } else {
1003
+ bindedFunction = _.bind(customFunction, this, operation, path);
1004
+ }
1005
+
1006
+ var createdFunction = function(params, headers, elem) {
1007
+ var callParams = _.defaults({
1008
+ params: params,
1009
+ headers: headers,
1010
+ elem: elem
1011
+ }, {
1012
+ params: defaultParams,
1013
+ headers: defaultHeaders,
1014
+ elem: defaultElem
1015
+ });
1016
+ return bindedFunction(callParams.params, callParams.headers, callParams.elem);
1017
+ };
1018
+
1019
+ if (config.isSafe(operation)) {
1020
+ this[name] = createdFunction;
1021
+ } else {
1022
+ this[name] = function(elem, params, headers) {
1023
+ return createdFunction(params, headers, elem);
1024
+ }
1025
+ }
1026
+
1027
+ }
1028
+
1029
+ function withConfigurationFunction(configurer) {
1030
+ var newConfig = angular.copy(globalConfiguration);
1031
+ Configurer.init(newConfig, newConfig);
1032
+ configurer(newConfig);
1033
+ return createServiceForConfiguration(newConfig);
1034
+ }
1035
+
1036
+
1037
+ Configurer.init(service, config);
1038
+
1039
+ service.copy = _.bind(copyRestangularizedElement, service);
1040
+
1041
+ service.withConfig = _.bind(withConfigurationFunction, service);
1042
+
1043
+ service.one = _.bind(one, service, null);
1044
+
1045
+ service.all = _.bind(all, service, null);
1046
+
1047
+ service.several = _.bind(several, service, null);
1048
+
1049
+ service.oneUrl = _.bind(oneUrl, service, null);
1050
+
1051
+ service.allUrl = _.bind(allUrl, service, null);
1052
+
1053
+ service.restangularizeElement = _.bind(restangularizeElem, service);
1054
+
1055
+ service.restangularizeCollection = _.bind(restangularizeCollection, service);
1056
+
1057
+ return service;
1058
+ }
1059
+
1060
+ return createServiceForConfiguration(globalConfiguration);
1061
+
1062
+ }];
1063
+ }
1064
+ );
1065
+
1066
+ })();