api_maker 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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,186 +0,0 @@
1
- import CommandsPool from "./commands-pool"
2
- import merge from "merge"
3
- import ModelsResponseReader from "./models-response-reader"
4
- import Result from "./result"
5
-
6
- const inflection = require("inflection")
7
-
8
- export default class Collection {
9
- constructor(args, queryArgs = {}) {
10
- this.queryArgs = queryArgs
11
- this.args = args
12
- }
13
-
14
- accessibleBy(abilityName) {
15
- return this._clone({accessibleBy: abilityName})
16
- }
17
-
18
- distinct() {
19
- return this._clone({distinct: true})
20
- }
21
-
22
- async each(callback) {
23
- var array = await this.toArray()
24
-
25
- for(var model in array) {
26
- callback.call(model)
27
- }
28
- }
29
-
30
- async first() {
31
- var models = await this.toArray()
32
- return models[0]
33
- }
34
-
35
- async count() {
36
- var response = await this._clone({count: true})._response()
37
- return response.count
38
- }
39
-
40
- isLoaded() {
41
- if (this.args.reflectionName in this.args.model.relationshipsCache)
42
- return true
43
-
44
- return false
45
- }
46
-
47
- limit(amount) {
48
- return this._clone({limit: amount})
49
- }
50
-
51
- loaded() {
52
- if (!(this.args.reflectionName in this.args.model.relationshipsCache)) {
53
- throw new Error(`${this.args.reflectionName} hasnt been loaded yet`)
54
- }
55
-
56
- return this.args.model.relationshipsCache[this.args.reflectionName]
57
- }
58
-
59
- preload(preloadValue) {
60
- return this._clone({preload: preloadValue})
61
- }
62
-
63
- page(pageNumber) {
64
- if (!pageNumber)
65
- pageNumber = 1
66
-
67
- var changes = {page: pageNumber}
68
-
69
- if (!this.queryArgs.ransack || !this.queryArgs.ransack.s)
70
- changes.ransack = {s: `${this.args.modelClass.modelClassData().primaryKey} asc`}
71
-
72
- return this._clone(changes)
73
- }
74
-
75
- pageKey(pageKeyValue) {
76
- return this._clone({pageKey: pageKeyValue})
77
- }
78
-
79
- ransack(params) {
80
- return this._clone({ransack: params})
81
- }
82
-
83
- async result() {
84
- var response = await this._response()
85
- var models = this._responseToModels(response)
86
- var result = new Result({collection: this, models, response})
87
- return result
88
- }
89
-
90
- searchKey(searchKey) {
91
- return this._clone({searchKey: searchKey})
92
- }
93
-
94
- select(originalSelect) {
95
- var newSelect = {}
96
-
97
- for(var originalModelName in originalSelect) {
98
- var newModalName = inflection.dasherize(inflection.underscore(originalModelName))
99
- var newValues = []
100
- var originalValues = originalSelect[originalModelName]
101
-
102
- for(var originalAttributeName of originalValues) {
103
- var newAttributeName = inflection.underscore(originalAttributeName)
104
- newValues.push(newAttributeName)
105
- }
106
-
107
- newSelect[newModalName] = newValues
108
- }
109
-
110
- return this._clone({select: newSelect})
111
- }
112
-
113
- sort(sortBy) {
114
- return this._clone({ransack: {s: sortBy}})
115
- }
116
-
117
- async toArray() {
118
- var response = await this._response()
119
- return this._responseToModels(response)
120
- }
121
-
122
- modelClass() {
123
- return require(`api-maker/models/${inflection.dasherize(inflection.singularize(this.args.modelClass.modelClassData().collectionName))}`).default
124
- }
125
-
126
- _clone(args) {
127
- return new Collection(this.args, this._merge(this.queryArgs, args))
128
- }
129
-
130
- _merge(object1, object2) {
131
- return merge.recursive(true, object1, object2)
132
- }
133
-
134
- _response() {
135
- var modelClassData = this.args.modelClass.modelClassData()
136
-
137
- return CommandsPool.addCommand(
138
- {
139
- args: this._params(),
140
- command: `${modelClassData.collectionName}-index`,
141
- collectionName: modelClassData.collectionName,
142
- type: "index"
143
- },
144
- {}
145
- )
146
- }
147
-
148
- _responseToModels(response) {
149
- var modelsResponseReader = new ModelsResponseReader({response: response})
150
- return modelsResponseReader.models()
151
- }
152
-
153
- _params() {
154
- var params = {}
155
-
156
- if (this.queryArgs.params)
157
- params = this._merge(params, this.queryArgs.params)
158
-
159
- if (this.queryArgs.accessibleBy) {
160
- params.accessible_by = inflection.underscore(this.queryArgs.accessibleBy)
161
- }
162
-
163
- if (this.queryArgs.count)
164
- params.count = this.queryArgs.count
165
-
166
- if (this.queryArgs.distinct)
167
- params.distinct = this.queryArgs.distinct
168
-
169
- if (this.queryArgs.ransack)
170
- params.q = this.queryArgs.ransack
171
-
172
- if (this.queryArgs.limit)
173
- params.limit = this.queryArgs.limit
174
-
175
- if (this.queryArgs.preload)
176
- params.include = this.queryArgs.preload
177
-
178
- if (this.queryArgs.page)
179
- params.page = this.queryArgs.page
180
-
181
- if (this.queryArgs.select)
182
- params.select = this.queryArgs.select
183
-
184
- return params
185
- }
186
- }
@@ -1,123 +0,0 @@
1
- import Api from "./api"
2
- import CustomError from "./custom-error"
3
- import Deserializer from "./deserializer"
4
- import FormDataToObject from "./form-data-to-object"
5
- import objectToFormData from "object-to-formdata"
6
-
7
- export default class ApiMakerCommandsPool {
8
- static addCommand(data, args = {}) {
9
- if (args.instant) {
10
- var pool = new ApiMakerCommandsPool()
11
- } else {
12
- var pool = ApiMakerCommandsPool.current()
13
- }
14
-
15
- var promiseResult = pool.addCommand(data)
16
-
17
- if (args.instant) {
18
- pool.flush()
19
- } else {
20
- pool.setFlushTimeout()
21
- }
22
-
23
- return promiseResult
24
- }
25
-
26
- static current() {
27
- if (!window.currentApiMakerCommandsPool)
28
- window.currentApiMakerCommandsPool = new ApiMakerCommandsPool()
29
-
30
- return window.currentApiMakerCommandsPool
31
- }
32
-
33
- static flush() {
34
- ApiMakerCommandsPool.current().flush()
35
- }
36
-
37
- constructor() {
38
- this.pool = {}
39
- this.poolData = {}
40
- this.currentId = 1
41
- this.globalRequestData = null
42
- }
43
-
44
- addCommand(data) {
45
- return new Promise((resolve, reject) => {
46
- var id = this.currentId
47
- this.currentId += 1
48
-
49
- var commandType = data.type
50
- var commandName = data.command
51
- var collectionName = data.collectionName
52
-
53
- this.pool[id] = {resolve: resolve, reject: reject}
54
-
55
- if (!this.poolData[commandType])
56
- this.poolData[commandType] = {}
57
-
58
- if (!this.poolData[commandType][collectionName])
59
- this.poolData[commandType][collectionName] = {}
60
-
61
- if (!this.poolData[commandType][collectionName][commandName])
62
- this.poolData[commandType][collectionName][commandName] = {}
63
-
64
- if (data.args instanceof FormData) {
65
- var args = FormDataToObject.toObject(data.args)
66
- } else {
67
- var args = data.args
68
- }
69
-
70
- this.poolData[commandType][collectionName][commandName][id] = {
71
- args: args,
72
- primary_key: data.primaryKey,
73
- id: id
74
- }
75
- })
76
- }
77
-
78
- async flush() {
79
- if (Object.keys(this.pool) == 0)
80
- return
81
-
82
- this.clearTimeout()
83
-
84
- var currentPool = this.pool
85
- var currentPoolData = this.poolData
86
-
87
- this.pool = {}
88
- this.poolData = {}
89
-
90
- var objectForFormData = {pool: currentPoolData}
91
-
92
- if (this.globalRequestData)
93
- objectForFormData.global = this.globalRequestData
94
-
95
- var formData = objectToFormData(objectForFormData)
96
- var url = `/api_maker/commands`
97
- var response = await Api.requestLocal({path: url, method: "POST", rawData: formData})
98
-
99
- for(var commandId in response.responses) {
100
- var commandResponse = response.responses[commandId]
101
- var commandResponseData = Deserializer.parse(commandResponse.data)
102
- var commandData = currentPool[parseInt(commandId)]
103
-
104
- if (commandResponse.type == "success") {
105
- commandData.resolve(commandResponseData)
106
- } else if (commandResponse.type == "error") {
107
- commandData.reject(new CustomError("Command error", {response: commandResponseData}))
108
- } else {
109
- commandData.reject(new CustomError("Command failed", {response: commandResponseData}))
110
- }
111
- }
112
- }
113
-
114
- clearTimeout() {
115
- if (this.flushTimeout)
116
- clearTimeout(this.flushTimeout)
117
- }
118
-
119
- setFlushTimeout() {
120
- this.clearTimeout()
121
- this.flushTimeout = setTimeout(() => this.flush(), 0)
122
- }
123
- }
@@ -1,14 +0,0 @@
1
- export default class ApiMakerCustomError extends Error {
2
- constructor(message, args = {}) {
3
- if (args.response && args.response.errors)
4
- message = `${message}: ${args.response.errors.join(". ")}`
5
-
6
- super(message)
7
-
8
- // Maintains proper stack trace for where our error was thrown (only available on V8)
9
- if (Error.captureStackTrace)
10
- Error.captureStackTrace(this, ApiMakerCustomError)
11
-
12
- this.args = args
13
- }
14
- }
@@ -1,35 +0,0 @@
1
- import Money from "js-money"
2
-
3
- const inflection = require("inflection")
4
-
5
- export default class ApiMakerDeserializer {
6
- static parse(object) {
7
- if (Array.isArray(object)) {
8
- return object.map(value => ApiMakerDeserializer.parse(value))
9
- } else if (object && typeof object == "object") {
10
- if (object.api_maker_type == "money") {
11
- var cents = object.amount
12
- var currency = object.currency
13
-
14
- return Money.fromInteger(cents, currency)
15
- } else if (object.api_maker_type == "model") {
16
- var modelClassName = inflection.singularize(object.model_name)
17
- var modelClass = require(`api-maker/models/${modelClassName}`).default
18
- var model = new modelClass({data: object.serialized, isNewRecord: false})
19
-
20
- return model
21
- } else {
22
- var newObject = {}
23
-
24
- for(var key in object) {
25
- var value = object[key]
26
- newObject[key] = ApiMakerDeserializer.parse(value)
27
- }
28
-
29
- return newObject
30
- }
31
- } else {
32
- return object
33
- }
34
- }
35
- }
@@ -1,113 +0,0 @@
1
- import Api from "./api"
2
- import CustomError from "./custom-error"
3
- import EventEmitter from "events"
4
- const inflection = require("inflection")
5
-
6
- export default class Devise {
7
- static callSignOutEvent(args) {
8
- Devise.events().emit("onDeviseSignOut", {args: args})
9
- }
10
-
11
- static current() {
12
- if (!window.currentApiMakerDevise)
13
- window.currentApiMakerDevise = new Devise()
14
-
15
- return window.currentApiMakerDevise
16
- }
17
-
18
- static events() {
19
- if (!window.apiMakerDeviseEvents)
20
- window.apiMakerDeviseEvents = new EventEmitter()
21
-
22
- return window.apiMakerDeviseEvents
23
- }
24
-
25
- <% Devise.mappings.each do |scope| %>
26
- <%
27
- klass = scope[1].class_name.safe_constantize
28
- resource = ApiMaker::Serializer.resource_for(klass)
29
- %>
30
- <% if resource %>
31
- static <%= ApiMaker::JsMethodNamerService.execute!(name: "is_#{scope[0]}_signed_in") %>() {
32
- if (Devise.current().getCurrentScope("<%= scope[1].class_name %>"))
33
- return true
34
-
35
- return false
36
- }
37
-
38
- static current<%= scope[1].class_name %>() {
39
- return Devise.current().getCurrentScope("<%= scope[1].class_name %>")
40
- }
41
- <% end %>
42
- <% end %>
43
-
44
- static async signIn(username, password, args = {}) {
45
- if (!args.scope)
46
- args.scope = "user"
47
-
48
- var postData = {"username": username, "password": password, "args": args}
49
- var response = await Api.post("/api_maker/devise/do_sign_in", postData)
50
-
51
- if (response.success) {
52
- var modelClass = require(`api-maker/models/${inflection.dasherize(args.scope)}`).default
53
- var modelInstance = new modelClass(response.model_data)
54
-
55
- Devise.updateSession(modelInstance)
56
- Devise.events().emit("onDeviseSignIn", Object.assign({username: username}, args))
57
-
58
- return {model: modelInstance, response: response}
59
- } else {
60
- throw new CustomError("Sign in failed", {response: response})
61
- }
62
- }
63
-
64
- static updateSession(model) {
65
- var scope = model.modelClassData().name
66
- Devise.current().currents[scope] = model
67
- }
68
-
69
- static setSignedOut(args) {
70
- Devise.current().currents[inflection.camelize(args.scope)] = null
71
- }
72
-
73
- static async signOut(args = {}) {
74
- if (!args.scope)
75
- args.scope = "user"
76
-
77
- var postData = {"args": args}
78
- var response = await Api.post("/api_maker/devise/do_sign_out", postData)
79
-
80
- if (response.success) {
81
- Devise.setSignedOut(args)
82
- Devise.callSignOutEvent(args)
83
- return response
84
- } else {
85
- throw new CustomError("Sign out failed", {response: response})
86
- }
87
- }
88
-
89
- constructor() {
90
- this.currents = {}
91
- }
92
-
93
- getCurrentScope(scope) {
94
- if (!(scope in this.currents))
95
- this.currents[scope] = this.loadCurrentScope(scope)
96
-
97
- return this.currents[scope]
98
- }
99
-
100
- loadCurrentScope(scope) {
101
- var apiMakerDataElement = document.querySelector(".api-maker-data")
102
- var keyName = `current${inflection.camelize(scope)}`
103
- var scopeData = apiMakerDataElement.dataset[keyName]
104
-
105
- if (!scopeData)
106
- return null
107
-
108
- var modelClass = require(`api-maker/models/${inflection.dasherize(inflection.underscore(scope))}`).default
109
- var modelInstance = new modelClass({data: JSON.parse(scopeData)})
110
-
111
- return modelInstance
112
- }
113
- }
@@ -1,119 +0,0 @@
1
- import retrace from "retrace"
2
-
3
- export default class ErrorLogger {
4
- constructor() {
5
- this.errors = []
6
- }
7
-
8
- loadSourceMaps() {
9
- return new Promise(resolve => {
10
- var scripts = document.querySelectorAll("script")
11
- var promises = []
12
-
13
- for(var script of scripts) {
14
- var src = script.getAttribute("src")
15
- var type = script.getAttribute("type")
16
-
17
- if (src && src.includes("/packs/") && (type == "text/javascript" || !type)) {
18
- var promise = this.loadSourceMapForScript(script)
19
- promises.push(promise)
20
- }
21
- }
22
-
23
- Promise.all(promises).then(() => { resolve() })
24
- })
25
- }
26
-
27
- loadSourceMapForScript(script) {
28
- var src = script.getAttribute("src")
29
- var url = this.loadUrl(src)
30
- var originalUrl = `${url.origin}${url.pathname}`
31
- var mapUrl = `${url.origin}${url.pathname}.map`
32
-
33
- return new Promise(resolve => {
34
- var xhr = new XMLHttpRequest()
35
- xhr.open("GET", mapUrl, true)
36
- xhr.onload = () => {
37
- retrace.register(originalUrl, xhr.responseText)
38
- resolve()
39
- }
40
- xhr.send()
41
- })
42
- }
43
-
44
- loadUrl(url) {
45
- var parser = document.createElement("a")
46
- parser.href = url
47
-
48
- return parser
49
- }
50
-
51
- enable() {
52
- this.connectOnError()
53
- this.connectUnhandledRejection()
54
- }
55
-
56
- getErrors() {
57
- return this.errors
58
- }
59
-
60
- connectOnError() {
61
- window.addEventListener("error", (event) => {
62
- if (!this.isHandlingError) {
63
- try {
64
- this.isHandlingError = true
65
- this.errors.push({
66
- errorClass: event.error ? event.error.name : "No error class",
67
- file: event.filename,
68
- message: event.message || "Unknown error",
69
- url: window.location.href,
70
- line: event.lineno,
71
- error: event.error
72
- })
73
- } finally {
74
- this.isHandlingError = false
75
- }
76
- }
77
- })
78
- }
79
-
80
- connectUnhandledRejection() {
81
- window.addEventListener("unhandledrejection", (event, test) => {
82
- if (!this.isHandlingError) {
83
- this.isHandlingError = true
84
-
85
- try {
86
- if (event.reason.stack) {
87
- retrace.map(event.reason.stack).then(mappedStackTrace => {
88
- this.errors.push({
89
- errorClass: "UnhandledRejection",
90
- file: null,
91
- message: event.reason.message || "Unhandled promise rejection",
92
- url: window.location.href,
93
- line: null,
94
- backtrace: mappedStackTrace.split("\n")
95
- })
96
- })
97
- } else {
98
- this.errors.push({
99
- errorClass: "UnhandledRejection",
100
- file: null,
101
- message: event.reason.message || "Unhandled promise rejection",
102
- url: window.location.href,
103
- line: null,
104
- backtrace: null
105
- })
106
- }
107
- } finally {
108
- this.isHandlingError = false
109
- }
110
- }
111
- })
112
- }
113
-
114
- testPromiseError() {
115
- return new Promise(resolve => {
116
- throw new Error("testPromiseError")
117
- })
118
- }
119
- }
@@ -1,24 +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 ApiMakerEventConnection extends React.Component {
6
- static propTypes = PropTypesExact({
7
- model: PropTypes.object.isRequired,
8
- event: PropTypes.string.isRequired,
9
- onCall: PropTypes.func.isRequired
10
- })
11
-
12
- componentDidMount() {
13
- this.subscription = this.props.model.connect(this.props.event, this.props.onCall)
14
- }
15
-
16
- componentWillUnmount() {
17
- if (this.subscription)
18
- this.subscription.unsubscribe()
19
- }
20
-
21
- render() {
22
- return ""
23
- }
24
- }
@@ -1,26 +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 ApiMakerEventCreated extends React.Component {
6
- static propTypes = PropTypesExact({
7
- modelClass: PropTypes.func.isRequired,
8
- onCreated: PropTypes.func.isRequired
9
- })
10
-
11
- componentDidMount() {
12
- this.connect()
13
- }
14
-
15
- componentWillUnmount() {
16
- this.connectCreated.unsubscribe()
17
- }
18
-
19
- connect() {
20
- this.connectCreated = this.props.modelClass.connectCreated(this.props.onCreated)
21
- }
22
-
23
- render() {
24
- return ""
25
- }
26
- }
@@ -1,26 +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 ApiMakerEventDestroyed extends React.Component {
6
- static propTypes = PropTypesExact({
7
- model: PropTypes.object.isRequired,
8
- onDestroyed: PropTypes.func.isRequired
9
- })
10
-
11
- componentDidMount() {
12
- this.connect()
13
- }
14
-
15
- componentWillUnmount() {
16
- this.connectDestroyed.unsubscribe()
17
- }
18
-
19
- connect() {
20
- this.connectDestroyed = this.props.model.connectDestroyed(this.props.onDestroyed)
21
- }
22
-
23
- render() {
24
- return ""
25
- }
26
- }
@@ -1,32 +0,0 @@
1
- import EventEmitter from "events"
2
- import PropTypes from "prop-types"
3
- import React from "react"
4
-
5
- export default class ApiMakerEventEmitterListener extends React.Component {
6
- static propTypes = {
7
- events: PropTypes.instanceOf(EventEmitter).isRequired,
8
- event: PropTypes.string.isRequired,
9
- onCalled: PropTypes.func.isRequired
10
- }
11
-
12
- constructor(props) {
13
- super(props)
14
- this.onCalled = this.onCalled.bind(this)
15
- }
16
-
17
- componentDidMount() {
18
- this.props.events.addListener(this.props.event, this.onCalled)
19
- }
20
-
21
- componentWillUnmount() {
22
- this.props.events.removeListener(this.props.event, this.onCalled)
23
- }
24
-
25
- onCalled(...args) {
26
- this.props.onCalled.apply(null, ...args)
27
- }
28
-
29
- render() {
30
- return ""
31
- }
32
- }