api_maker 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +476 -0
- data/Rakefile +27 -0
- data/app/channels/api_maker/subscriptions_channel.rb +80 -0
- data/app/controllers/api_maker/base_controller.rb +32 -0
- data/app/controllers/api_maker/commands_controller.rb +26 -0
- data/app/controllers/api_maker/devise_controller.rb +60 -0
- data/app/controllers/api_maker/session_statuses_controller.rb +33 -0
- data/app/services/api_maker/application_service.rb +7 -0
- data/app/services/api_maker/collection_command_service.rb +24 -0
- data/app/services/api_maker/command_response.rb +67 -0
- data/app/services/api_maker/command_service.rb +31 -0
- data/app/services/api_maker/create_command.rb +62 -0
- data/app/services/api_maker/create_command_service.rb +18 -0
- data/app/services/api_maker/destroy_command.rb +39 -0
- data/app/services/api_maker/destroy_command_service.rb +22 -0
- data/app/services/api_maker/generate_react_native_api_service.rb +61 -0
- data/app/services/api_maker/index_command.rb +96 -0
- data/app/services/api_maker/index_command_service.rb +22 -0
- data/app/services/api_maker/js_method_namer_service.rb +11 -0
- data/app/services/api_maker/member_command_service.rb +25 -0
- data/app/services/api_maker/model_content_generator_service.rb +108 -0
- data/app/services/api_maker/models_finder_service.rb +22 -0
- data/app/services/api_maker/models_generator_service.rb +104 -0
- data/app/services/api_maker/update_command.rb +43 -0
- data/app/services/api_maker/update_command_service.rb +21 -0
- data/app/services/api_maker/valid_command.rb +35 -0
- data/app/services/api_maker/valid_command_service.rb +21 -0
- data/app/views/api_maker/_data.html.erb +15 -0
- data/config/rails_best_practices.yml +55 -0
- data/config/routes.rb +7 -0
- data/lib/api_maker.rb +36 -0
- data/lib/api_maker/ability.rb +39 -0
- data/lib/api_maker/ability_loader.rb +21 -0
- data/lib/api_maker/action_controller_base_extensions.rb +5 -0
- data/lib/api_maker/base_command.rb +81 -0
- data/lib/api_maker/base_resource.rb +78 -0
- data/lib/api_maker/collection_serializer.rb +69 -0
- data/lib/api_maker/command_spec_helper.rb +57 -0
- data/lib/api_maker/configuration.rb +34 -0
- data/lib/api_maker/engine.rb +5 -0
- data/lib/api_maker/individual_command.rb +37 -0
- data/lib/api_maker/javascript/api.js +92 -0
- data/lib/api_maker/javascript/base-model.js +543 -0
- data/lib/api_maker/javascript/bootstrap/attribute-row.jsx +16 -0
- data/lib/api_maker/javascript/bootstrap/attribute-rows.jsx +47 -0
- data/lib/api_maker/javascript/bootstrap/card.jsx +79 -0
- data/lib/api_maker/javascript/bootstrap/checkbox.jsx +127 -0
- data/lib/api_maker/javascript/bootstrap/checkboxes.jsx +105 -0
- data/lib/api_maker/javascript/bootstrap/live-table.jsx +168 -0
- data/lib/api_maker/javascript/bootstrap/money-input.jsx +136 -0
- data/lib/api_maker/javascript/bootstrap/radio-buttons.jsx +80 -0
- data/lib/api_maker/javascript/bootstrap/select.jsx +168 -0
- data/lib/api_maker/javascript/bootstrap/string-input.jsx +203 -0
- data/lib/api_maker/javascript/cable-connection-pool.js +169 -0
- data/lib/api_maker/javascript/cable-subscription-pool.js +111 -0
- data/lib/api_maker/javascript/cable-subscription.js +33 -0
- data/lib/api_maker/javascript/collection.js +186 -0
- data/lib/api_maker/javascript/commands-pool.js +123 -0
- data/lib/api_maker/javascript/custom-error.js +14 -0
- data/lib/api_maker/javascript/deserializer.js +35 -0
- data/lib/api_maker/javascript/devise.js.erb +113 -0
- data/lib/api_maker/javascript/error-logger.js +119 -0
- data/lib/api_maker/javascript/event-connection.jsx +24 -0
- data/lib/api_maker/javascript/event-created.jsx +26 -0
- data/lib/api_maker/javascript/event-destroyed.jsx +26 -0
- data/lib/api_maker/javascript/event-emitter-listener.jsx +32 -0
- data/lib/api_maker/javascript/event-listener.jsx +41 -0
- data/lib/api_maker/javascript/event-updated.jsx +26 -0
- data/lib/api_maker/javascript/form-data-to-object.js +70 -0
- data/lib/api_maker/javascript/included.js +39 -0
- data/lib/api_maker/javascript/key-value-store.js +47 -0
- data/lib/api_maker/javascript/logger.js +23 -0
- data/lib/api_maker/javascript/model-name.js +21 -0
- data/lib/api_maker/javascript/model-template.js.erb +110 -0
- data/lib/api_maker/javascript/models-response-reader.js +43 -0
- data/lib/api_maker/javascript/paginate.jsx +128 -0
- data/lib/api_maker/javascript/params.js +68 -0
- data/lib/api_maker/javascript/resource-route.jsx +75 -0
- data/lib/api_maker/javascript/resource-routes.jsx +36 -0
- data/lib/api_maker/javascript/result.js +25 -0
- data/lib/api_maker/javascript/session-status-updater.js +113 -0
- data/lib/api_maker/javascript/sort-link.jsx +88 -0
- data/lib/api_maker/javascript/updated-attribute.jsx +60 -0
- data/lib/api_maker/loader.rb +14 -0
- data/lib/api_maker/memory_storage.rb +65 -0
- data/lib/api_maker/model_extensions.rb +96 -0
- data/lib/api_maker/permitted_params_argument.rb +12 -0
- data/lib/api_maker/preloader.rb +91 -0
- data/lib/api_maker/preloader_belongs_to.rb +58 -0
- data/lib/api_maker/preloader_has_many.rb +69 -0
- data/lib/api_maker/preloader_has_one.rb +70 -0
- data/lib/api_maker/preloader_through.rb +101 -0
- data/lib/api_maker/railtie.rb +14 -0
- data/lib/api_maker/relationship_includer.rb +42 -0
- data/lib/api_maker/resource_routing.rb +8 -0
- data/lib/api_maker/result_parser.rb +50 -0
- data/lib/api_maker/serializer.rb +86 -0
- data/lib/api_maker/spec_helper.rb +100 -0
- data/lib/api_maker/version.rb +3 -0
- data/lib/tasks/api_maker_tasks.rake +5 -0
- metadata +581 -0
|
@@ -0,0 +1,123 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
}
|