api_maker 0.0.1 → 0.0.2

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.
Files changed (135) hide show
  1. checksums.yaml +4 -4
  2. data/app/api_maker/api_helpers/api_maker_helpers.rb +5 -0
  3. data/app/api_maker/services/can_can/load_abilities.rb +30 -0
  4. data/app/api_maker/services/devise/sign_in.rb +64 -0
  5. data/app/api_maker/services/devise/sign_out.rb +9 -0
  6. data/app/api_maker/services/models/find_or_create_by.rb +18 -0
  7. data/app/channels/api_maker/subscriptions_channel.rb +33 -2
  8. data/app/controllers/api_maker/base_controller.rb +7 -3
  9. data/app/controllers/api_maker/commands_controller.rb +26 -4
  10. data/app/controllers/api_maker/session_statuses_controller.rb +1 -1
  11. data/app/services/api_maker/abilities_loader.rb +104 -0
  12. data/app/services/api_maker/application_service.rb +2 -1
  13. data/app/services/api_maker/base_command.rb +248 -0
  14. data/app/services/api_maker/collection_command_service.rb +29 -15
  15. data/app/services/api_maker/collection_loader.rb +124 -0
  16. data/app/services/api_maker/command_failed_error.rb +3 -0
  17. data/app/services/api_maker/command_response.rb +17 -6
  18. data/app/services/api_maker/command_service.rb +3 -3
  19. data/app/services/api_maker/create_command.rb +11 -26
  20. data/app/services/api_maker/create_command_service.rb +3 -3
  21. data/app/services/api_maker/database_type.rb +9 -0
  22. data/app/services/api_maker/deep_merge_params.rb +26 -0
  23. data/app/services/api_maker/deserializer.rb +35 -0
  24. data/app/services/api_maker/destroy_command.rb +15 -21
  25. data/app/services/api_maker/destroy_command_service.rb +3 -3
  26. data/app/services/api_maker/generate_react_native_api_service.rb +3 -19
  27. data/app/services/api_maker/include_helpers.rb +17 -0
  28. data/app/services/api_maker/index_command.rb +8 -88
  29. data/app/services/api_maker/index_command_service.rb +5 -5
  30. data/app/services/api_maker/js_method_namer_service.rb +1 -1
  31. data/app/services/api_maker/locals_from_controller.rb +14 -0
  32. data/app/services/api_maker/member_command_service.rb +15 -13
  33. data/app/services/api_maker/model_classes_java_script_generator_service.rb +37 -0
  34. data/app/services/api_maker/model_content_generator_service.rb +17 -21
  35. data/app/services/api_maker/models/save.rb +29 -0
  36. data/app/services/api_maker/models_finder_service.rb +6 -2
  37. data/app/services/api_maker/models_generator_service.rb +6 -43
  38. data/app/services/api_maker/move_components_to_routes.rb +50 -0
  39. data/app/services/api_maker/primary_id_for_model.rb +6 -0
  40. data/app/services/api_maker/reset_indexed_db_service.rb +36 -0
  41. data/app/services/api_maker/routes_file_reloader.rb +20 -0
  42. data/app/services/api_maker/select_columns_on_collection.rb +78 -0
  43. data/app/services/api_maker/select_parser.rb +32 -0
  44. data/app/services/api_maker/service_command.rb +27 -0
  45. data/app/services/api_maker/service_command_service.rb +14 -0
  46. data/app/services/api_maker/simple_model_errors.rb +52 -0
  47. data/app/services/api_maker/update_command.rb +8 -24
  48. data/app/services/api_maker/update_command_service.rb +3 -3
  49. data/app/services/api_maker/valid_command.rb +4 -13
  50. data/app/services/api_maker/valid_command_service.rb +3 -3
  51. data/app/services/api_maker/validation_errors_generator_service.rb +146 -0
  52. data/app/views/api_maker/_data.html.erb +17 -11
  53. data/config/routes.rb +0 -2
  54. data/lib/api_maker/ability.rb +22 -7
  55. data/lib/api_maker/ability_loader.rb +9 -6
  56. data/lib/api_maker/base_collection_instance.rb +15 -0
  57. data/lib/api_maker/base_resource.rb +135 -9
  58. data/lib/api_maker/base_service.rb +14 -0
  59. data/lib/api_maker/collection_serializer.rb +95 -34
  60. data/lib/api_maker/command_spec_helper.rb +41 -11
  61. data/lib/api_maker/configuration.rb +31 -4
  62. data/lib/api_maker/expect_to_able_to_helper.rb +31 -0
  63. data/lib/api_maker/individual_command.rb +24 -9
  64. data/lib/api_maker/javascript/model-template.js.erb +39 -25
  65. data/lib/api_maker/javascript/models.js.erb +6 -0
  66. data/lib/api_maker/loader.rb +1 -1
  67. data/lib/api_maker/memory_storage.rb +1 -1
  68. data/lib/api_maker/model_extensions.rb +34 -18
  69. data/lib/api_maker/permitted_params_argument.rb +5 -1
  70. data/lib/api_maker/preloader.rb +71 -32
  71. data/lib/api_maker/preloader_base.rb +108 -0
  72. data/lib/api_maker/preloader_belongs_to.rb +34 -33
  73. data/lib/api_maker/preloader_has_many.rb +45 -39
  74. data/lib/api_maker/preloader_has_one.rb +30 -47
  75. data/lib/api_maker/railtie.rb +3 -11
  76. data/lib/api_maker/relationship_preloader.rb +42 -0
  77. data/lib/api_maker/resource_routing.rb +18 -4
  78. data/lib/api_maker/result_parser.rb +34 -20
  79. data/lib/api_maker/serializer.rb +53 -22
  80. data/lib/api_maker/spec_helper/browser_logs.rb +14 -0
  81. data/lib/api_maker/spec_helper/execute_collection_command.rb +46 -0
  82. data/lib/api_maker/spec_helper/execute_member_command.rb +52 -0
  83. data/lib/api_maker/spec_helper/expect_no_browser_errors.rb +18 -0
  84. data/lib/api_maker/spec_helper/wait_for_expect.rb +20 -0
  85. data/lib/api_maker/spec_helper/wait_for_flash_message.rb +21 -0
  86. data/lib/api_maker/spec_helper.rb +112 -48
  87. data/lib/api_maker/version.rb +1 -1
  88. data/lib/api_maker.rb +7 -3
  89. metadata +108 -89
  90. data/README.md +0 -476
  91. data/app/controllers/api_maker/devise_controller.rb +0 -60
  92. data/lib/api_maker/base_command.rb +0 -81
  93. data/lib/api_maker/javascript/api.js +0 -92
  94. data/lib/api_maker/javascript/base-model.js +0 -543
  95. data/lib/api_maker/javascript/bootstrap/attribute-row.jsx +0 -16
  96. data/lib/api_maker/javascript/bootstrap/attribute-rows.jsx +0 -47
  97. data/lib/api_maker/javascript/bootstrap/card.jsx +0 -79
  98. data/lib/api_maker/javascript/bootstrap/checkbox.jsx +0 -127
  99. data/lib/api_maker/javascript/bootstrap/checkboxes.jsx +0 -105
  100. data/lib/api_maker/javascript/bootstrap/live-table.jsx +0 -168
  101. data/lib/api_maker/javascript/bootstrap/money-input.jsx +0 -136
  102. data/lib/api_maker/javascript/bootstrap/radio-buttons.jsx +0 -80
  103. data/lib/api_maker/javascript/bootstrap/select.jsx +0 -168
  104. data/lib/api_maker/javascript/bootstrap/string-input.jsx +0 -203
  105. data/lib/api_maker/javascript/cable-connection-pool.js +0 -169
  106. data/lib/api_maker/javascript/cable-subscription-pool.js +0 -111
  107. data/lib/api_maker/javascript/cable-subscription.js +0 -33
  108. data/lib/api_maker/javascript/collection.js +0 -186
  109. data/lib/api_maker/javascript/commands-pool.js +0 -123
  110. data/lib/api_maker/javascript/custom-error.js +0 -14
  111. data/lib/api_maker/javascript/deserializer.js +0 -35
  112. data/lib/api_maker/javascript/devise.js.erb +0 -113
  113. data/lib/api_maker/javascript/error-logger.js +0 -119
  114. data/lib/api_maker/javascript/event-connection.jsx +0 -24
  115. data/lib/api_maker/javascript/event-created.jsx +0 -26
  116. data/lib/api_maker/javascript/event-destroyed.jsx +0 -26
  117. data/lib/api_maker/javascript/event-emitter-listener.jsx +0 -32
  118. data/lib/api_maker/javascript/event-listener.jsx +0 -41
  119. data/lib/api_maker/javascript/event-updated.jsx +0 -26
  120. data/lib/api_maker/javascript/form-data-to-object.js +0 -70
  121. data/lib/api_maker/javascript/included.js +0 -39
  122. data/lib/api_maker/javascript/key-value-store.js +0 -47
  123. data/lib/api_maker/javascript/logger.js +0 -23
  124. data/lib/api_maker/javascript/model-name.js +0 -21
  125. data/lib/api_maker/javascript/models-response-reader.js +0 -43
  126. data/lib/api_maker/javascript/paginate.jsx +0 -128
  127. data/lib/api_maker/javascript/params.js +0 -68
  128. data/lib/api_maker/javascript/resource-route.jsx +0 -75
  129. data/lib/api_maker/javascript/resource-routes.jsx +0 -36
  130. data/lib/api_maker/javascript/result.js +0 -25
  131. data/lib/api_maker/javascript/session-status-updater.js +0 -113
  132. data/lib/api_maker/javascript/sort-link.jsx +0 -88
  133. data/lib/api_maker/javascript/updated-attribute.jsx +0 -60
  134. data/lib/api_maker/preloader_through.rb +0 -101
  135. data/lib/api_maker/relationship_includer.rb +0 -42
@@ -1,113 +0,0 @@
1
- import Devise from "./devise"
2
-
3
- var inflection = require("inflection")
4
- var wakeEvent = require("wake-event")
5
-
6
- export default class ApiMakerSessionStatusUpdater {
7
- static current() {
8
- if (!window.apiMakerSessionStatusUpdater)
9
- window.apiMakerSessionStatusUpdater = new ApiMakerSessionStatusUpdater()
10
-
11
- return window.apiMakerSessionStatusUpdater
12
- }
13
-
14
- constructor(args = {}) {
15
- this.debugging = args.debug || false
16
- this.events = {}
17
- this.timeout = args.timeout || 600000
18
-
19
- this.connectOnlineEvent()
20
- this.connectWakeEvent()
21
- }
22
-
23
- connectOnlineEvent() {
24
- window.addEventListener("online", () => { this.updateSessionStatus() }, false)
25
- }
26
-
27
- connectWakeEvent() {
28
- wakeEvent(() => { this.updateSessionStatus() })
29
- }
30
-
31
- debug(message) {
32
- if (this.debugging)
33
- console.log(`ApiMakerSessionStatusUpdater: ${message}`)
34
- }
35
-
36
- sessionStatus() {
37
- return new Promise(resolve => {
38
- var xhr = new XMLHttpRequest()
39
- xhr.open("POST", "/api_maker/session_statuses", true)
40
- xhr.onload = () => {
41
- var response = JSON.parse(xhr.responseText)
42
- resolve(response)
43
- }
44
- xhr.send()
45
- })
46
- }
47
-
48
- onSignedOut(callback) {
49
- this.addEvent("onSignedOut", callback)
50
- }
51
-
52
- startTimeout() {
53
- this.debug("startTimeout")
54
-
55
- if (this.updateTimeout)
56
- clearTimeout(this.updateTimeout)
57
-
58
- this.updateTimeout = setTimeout(
59
- () => {
60
- this.startTimeout()
61
- this.updateSessionStatus()
62
- },
63
- this.timeout
64
- )
65
- }
66
-
67
- stopTimeout() {
68
- if (this.updateTimeout)
69
- clearTimeout(this.updateTimeout)
70
- }
71
-
72
- updateSessionStatus() {
73
- this.debug("updateSessionStatus")
74
-
75
- this.sessionStatus().then(result => {
76
- this.debug(`Result: ${JSON.stringify(result, null, 2)}`)
77
- this.updateMetaElementsFromResult(result)
78
- this.updateUserSessionsFromResult(result)
79
- })
80
- }
81
-
82
- updateMetaElementsFromResult(result) {
83
- this.debug("updateMetaElementsFromResult")
84
- var csrfTokenElement = document.querySelector("meta[name='csrf-token']")
85
-
86
- if (csrfTokenElement) {
87
- this.debug(`Changing token from "${csrfTokenElement.getAttribute("content")}" to "${result.csrf_token}"`)
88
- csrfTokenElement.setAttribute("content", result.csrf_token)
89
- } else {
90
- this.debug("csrf token element couldn't be found")
91
- }
92
- }
93
-
94
- updateUserSessionsFromResult(result) {
95
- for(var scopeName in result.scopes) {
96
- this.updateUserSessionScopeFromResult(scopeName, result.scopes[scopeName])
97
- }
98
- }
99
-
100
- updateUserSessionScopeFromResult(scopeName, scope) {
101
- var deviseMethodName = `current${inflection.camelize(scopeName)}`
102
- var deviseIsSignedInMethodName = `is${inflection.camelize(scopeName)}SignedIn`
103
- var currentlySignedIn = Devise[deviseIsSignedInMethodName]()
104
- var signedInOnBackend = scope.signed_in
105
-
106
- if (currentlySignedIn && !signedInOnBackend) {
107
- this.debug(`${inflection.camelize(scopeName)} signed in on frontend but not in backend!`)
108
-
109
- Devise.setSignedOut({scope: scopeName})
110
- Devise.callSignOutEvent({scope: scopeName})
111
- }
112
- }
113
- }
@@ -1,88 +0,0 @@
1
- import { Link } from "react-router-dom"
2
- import qs from "qs"
3
- import React from "react"
4
-
5
- const inflection = require("inflection")
6
-
7
- export default class extends React.Component {
8
- constructor(props) {
9
- super(props)
10
-
11
- var searchKey = this.props.query.queryArgs.searchKey
12
- if (!searchKey)
13
- searchKey = "q"
14
-
15
- this.state = {searchKey: searchKey}
16
- }
17
-
18
- attribute() {
19
- return inflection.underscore(this.props.attribute)
20
- }
21
-
22
- href() {
23
- var currentParams = qs.parse(window.location.search.substr(1))
24
-
25
- if (!currentParams[this.state.searchKey])
26
- currentParams[this.state.searchKey] = {}
27
-
28
- currentParams[this.state.searchKey]["s"] = `${this.attribute()} ${this.sortMode()}`
29
-
30
- var newParams = qs.stringify(currentParams)
31
- var newPath = `${location.pathname}?${newParams}`
32
-
33
- return newPath
34
- }
35
-
36
- isSortedByAttribute() {
37
- if (this.props.query.queryArgs.ransack && this.props.query.queryArgs.ransack.s == this.attribute())
38
- return true
39
-
40
- if (this.props.query.queryArgs.ransack && this.props.query.queryArgs.ransack.s == `${this.attribute()} asc`)
41
- return true
42
-
43
- return false
44
- }
45
-
46
- render() {
47
- var LinkComponent = this.linkComponent()
48
- var { attribute, className, linkComponent, query, title, ...other } = this.props
49
-
50
- return (
51
- <LinkComponent {...other} className={this.className()} data-attribute={attribute} data-sort-mode={this.sortMode()} to={this.href()}>
52
- {this.title()}
53
- </LinkComponent>
54
- )
55
- }
56
-
57
- className() {
58
- var classNames = ["component-api-maker-bootstrap-sort-link"]
59
-
60
- if (this.props.className)
61
- classNames.push(this.props.className)
62
-
63
- return classNames.join(" ")
64
- }
65
-
66
- linkComponent() {
67
- if (this.props.linkComponent) {
68
- return this.props.linkComponent
69
- } else {
70
- return Link
71
- }
72
- }
73
-
74
- sortMode() {
75
- if (this.isSortedByAttribute()) {
76
- return "desc"
77
- } else {
78
- return "asc"
79
- }
80
- }
81
-
82
- title() {
83
- if (this.props.title)
84
- return this.props.title
85
-
86
- return this.props.query.modelClass().humanAttributeName(this.props.attribute)
87
- }
88
- }
@@ -1,60 +0,0 @@
1
- import PropTypes from "prop-types"
2
- import PropTypesExact from "prop-types-exact"
3
- import React from "react"
4
-
5
- export default class ApiMakerUpdatedAttribute extends React.Component {
6
- static propTypes = PropTypesExact({
7
- attribute: PropTypes.string,
8
- model: PropTypes.object.isRequired,
9
- onValue: PropTypes.func
10
- })
11
-
12
- constructor(props) {
13
- super(props)
14
- this.state = {
15
- model: this.props.model
16
- }
17
- }
18
-
19
- componentDidMount() {
20
- this.setAttribute()
21
- this.connect()
22
- }
23
-
24
- componentWillUnmount() {
25
- this.connectUpdated.unsubscribe()
26
- }
27
-
28
- connect() {
29
- this.connectUpdated = this.props.model.connectUpdated(args =>
30
- this.setState(
31
- {model: args.model},
32
- () => this.setAttribute()
33
- )
34
- )
35
- }
36
-
37
- setAttribute() {
38
- var newValue
39
-
40
- if (this.props.onValue) {
41
- newValue = this.props.onValue.apply(null, [{model: this.state.model}])
42
- } else {
43
- if (!this.state.model[this.props.attribute])
44
- throw new Error(`No such method: ${this.state.model.modelClassData().name}#${this.props.attribute}()`)
45
-
46
- newValue = this.state.model[this.props.attribute].apply(this.state.model)
47
- }
48
-
49
- this.setState({
50
- value: newValue
51
- })
52
- }
53
-
54
- render() {
55
- if (this.state.value === undefined)
56
- return ""
57
-
58
- return this.state.value
59
- }
60
- }
@@ -1,101 +0,0 @@
1
- class ApiMaker::PreloaderThrough
2
- def initialize(collection:, reflection:)
3
- @collection = collection
4
- @reflection = reflection
5
- end
6
-
7
- def models_query_through_reflection
8
- last_reflection = @reflection.through_reflection.inverse_of
9
-
10
- if last_reflection
11
- table_name = last_reflection.table_name
12
- primary_key = last_reflection.klass.primary_key
13
- else
14
- table_name = @reflection.through_reflection.active_record.model_name.plural
15
- primary_key = @reflection.through_reflection.active_record.primary_key
16
- end
17
-
18
- joins_hash = joins_array_to_hash(joins_for_reflection(@reflection))
19
-
20
- @reflection.klass.joins(joins_hash)
21
- .where(table_name => {primary_key => @collection.map(&:id)})
22
- end
23
-
24
- def joins_for_reflection(current_reflection)
25
- joins = []
26
-
27
- loop do
28
- # Resolve if the through relationship is through multiple other through relationships
29
- current_reflection = resolve_through(current_reflection)
30
-
31
- macro = current_reflection.through_reflection.macro
32
- inverse_name = current_reflection.through_reflection.__send__(:inverse_name)
33
-
34
- if inverse_name
35
- joins << inverse_name
36
- elsif macro == :has_many
37
- joins << current_reflection.through_reflection.name
38
- elsif macro == :belongs_to || macro == :has_one
39
- joins << current_reflection.through_reflection.active_record.model_name.plural.to_sym
40
- else
41
- raise "Unknown class: #{current_reflection.through_reflection.class.name}"
42
- end
43
-
44
- current_reflection = next_reflection_for(current_reflection)
45
-
46
- unless current_reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
47
- joins.append(append_name_for_current_reflection(current_reflection))
48
- break
49
- end
50
- end
51
-
52
- joins
53
- end
54
-
55
- def append_name_for_current_reflection(current_reflection)
56
- singular_name = current_reflection.__send__(:inverse_name)&.to_s || current_reflection.active_record.model_name.param_key
57
- return singular_name.to_sym if @reflection.klass.reflections.key?(singular_name)
58
-
59
- plural_name = singular_name.pluralize
60
- return plural_name.to_sym if @reflection.klass.reflections.key?(plural_name)
61
-
62
- raise "Couldn't find a reflection name #{singular_name} or #{plural_name} on #{@reflection.klass.name}"
63
- end
64
-
65
- def joins_array_to_hash(array)
66
- array = array.clone
67
-
68
- result = {}
69
- work_result = result
70
-
71
- while array.any?
72
- element = array.pop
73
-
74
- if array.length == 1
75
- work_result[element] = array.pop
76
- else
77
- work_result[element] = {}
78
- end
79
-
80
- work_result = work_result[element]
81
- end
82
-
83
- result
84
- end
85
-
86
- def next_reflection_for(current_reflection)
87
- reflection_name = (current_reflection.source_reflection_name || @reflection.name).to_s
88
-
89
- new_reflection = current_reflection.through_reflection.klass.reflections[reflection_name.pluralize]
90
- new_reflection ||= current_reflection.through_reflection.klass.reflections[reflection_name.singularize]
91
-
92
- raise "No such reflection: #{current_reflection.through_reflection.klass.name}##{reflection_name}" unless new_reflection
93
-
94
- new_reflection
95
- end
96
-
97
- def resolve_through(current_reflection)
98
- current_reflection = current_reflection.through_reflection while current_reflection.through_reflection.is_a?(ActiveRecord::Reflection::ThroughReflection)
99
- current_reflection
100
- end
101
- end
@@ -1,42 +0,0 @@
1
- class ApiMaker::RelationshipIncluder
2
- def self.parse(include_param)
3
- if include_param.nil?
4
- nil
5
- elsif include_param.is_a?(String)
6
- ApiMaker::RelationshipIncluder.parse_string(include_param)
7
- elsif include_param.is_a?(Array)
8
- ApiMaker::RelationshipIncluder.parse_array(include_param)
9
- else
10
- raise "Unexpected parameter given (#{include_param.class.name}): #{include_param}"
11
- end
12
- end
13
-
14
- def self.parse_string(include_param)
15
- splitted = include_param.split(".")
16
- initial = splitted.shift
17
- rest = splitted.join(".")
18
- {initial => rest}
19
- end
20
-
21
- def self.parse_array(include_param)
22
- result = {}
23
- include_param.each do |include_param_i|
24
- parsed = ApiMaker::RelationshipIncluder.parse(include_param_i)
25
- parsed.each do |key, value|
26
- if result.key?(key)
27
- if result[key].is_a?(String)
28
- result[key] = [result[key], value]
29
- elsif result[key].is_a?(Array)
30
- result[key] << value
31
- else
32
- raise "Unknown object: #{result[key].class.name}"
33
- end
34
- else
35
- result[key] = value
36
- end
37
- end
38
- end
39
-
40
- result
41
- end
42
- end