api_maker 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,43 @@
|
|
1
|
+
import Included from "./included"
|
2
|
+
|
3
|
+
const inflection = require("inflection")
|
4
|
+
|
5
|
+
export default class ModelsResponseReader {
|
6
|
+
static first(response) {
|
7
|
+
return ModelsResponseReader.collection(response)[0]
|
8
|
+
}
|
9
|
+
|
10
|
+
static collection(response) {
|
11
|
+
var reader = new ModelsResponseReader({response: response})
|
12
|
+
return reader.models()
|
13
|
+
}
|
14
|
+
|
15
|
+
constructor(args) {
|
16
|
+
this.response = args.response
|
17
|
+
}
|
18
|
+
|
19
|
+
models() {
|
20
|
+
var included = new Included(this.response)
|
21
|
+
var models = []
|
22
|
+
|
23
|
+
for(var modelType in this.response.data) {
|
24
|
+
var modelClassName = inflection.singularize(modelType)
|
25
|
+
var modelClass = require(`api-maker/models/${modelClassName}`).default
|
26
|
+
var collectionName = inflection.dasherize(modelClass.modelClassData().collectionName)
|
27
|
+
|
28
|
+
for(var modelId of this.response.data[modelType]) {
|
29
|
+
var modelData = this.response.included[collectionName][modelId]
|
30
|
+
|
31
|
+
if (!modelData)
|
32
|
+
throw new Error(`Couldn't find model data for ${collectionName}(${modelId})`)
|
33
|
+
|
34
|
+
var model = new modelClass({data: modelData, isNewRecord: false, response: this.response})
|
35
|
+
|
36
|
+
model._readIncludedRelationships(included)
|
37
|
+
models.push(model)
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
return models
|
42
|
+
}
|
43
|
+
}
|
@@ -0,0 +1,128 @@
|
|
1
|
+
import { Link } from "react-router-dom"
|
2
|
+
import qs from "qs"
|
3
|
+
import React from "react"
|
4
|
+
|
5
|
+
export default class extends React.Component {
|
6
|
+
isPageActiveClass(pageNumber) {
|
7
|
+
if (this.props.result.currentPage() == pageNumber)
|
8
|
+
return "active"
|
9
|
+
}
|
10
|
+
|
11
|
+
pages() {
|
12
|
+
var currentPage = this.props.result.currentPage()
|
13
|
+
var pages = []
|
14
|
+
var totalPages = this.props.result.totalPages()
|
15
|
+
var pagesFrom = currentPage - 5
|
16
|
+
var pagesTo = currentPage + 5
|
17
|
+
|
18
|
+
if (pagesFrom < 1)
|
19
|
+
pagesFrom = 1
|
20
|
+
|
21
|
+
if (pagesTo > totalPages)
|
22
|
+
pagesTo = totalPages
|
23
|
+
|
24
|
+
for(var i = pagesFrom; i <= pagesTo; i++) {
|
25
|
+
pages.push(i)
|
26
|
+
}
|
27
|
+
|
28
|
+
return pages
|
29
|
+
}
|
30
|
+
|
31
|
+
pagePath(pageNumber) {
|
32
|
+
var pageKey = this.props.result.data.collection.queryArgs.pageKey
|
33
|
+
if (!pageKey)
|
34
|
+
pageKey = "page"
|
35
|
+
|
36
|
+
var currentParams = qs.parse(window.location.search.substr(1))
|
37
|
+
currentParams[pageKey] = pageNumber
|
38
|
+
var newParams = qs.stringify(currentParams)
|
39
|
+
var newPath = `${location.pathname}?${newParams}`
|
40
|
+
|
41
|
+
return newPath
|
42
|
+
}
|
43
|
+
|
44
|
+
previousPagePath() {
|
45
|
+
var previousPage
|
46
|
+
|
47
|
+
if (this.props.result.currentPage() > 1) {
|
48
|
+
previousPage = this.props.result.currentPage() - 1
|
49
|
+
} else {
|
50
|
+
previousPage = this.props.result.currentPage()
|
51
|
+
}
|
52
|
+
|
53
|
+
return this.pagePath(previousPage)
|
54
|
+
}
|
55
|
+
|
56
|
+
nextPagePath() {
|
57
|
+
var nextPage
|
58
|
+
|
59
|
+
if (this.props.result.currentPage() < this.props.result.totalPages()) {
|
60
|
+
nextPage = this.props.result.currentPage() + 1
|
61
|
+
} else {
|
62
|
+
nextPage = this.props.result.currentPage()
|
63
|
+
}
|
64
|
+
|
65
|
+
return this.pagePath(nextPage)
|
66
|
+
}
|
67
|
+
|
68
|
+
showBackwardsDots() {
|
69
|
+
var currentPage = this.props.result.currentPage()
|
70
|
+
|
71
|
+
return (currentPage - 5 > 1)
|
72
|
+
}
|
73
|
+
|
74
|
+
showForwardsDots() {
|
75
|
+
var currentPage = this.props.result.currentPage()
|
76
|
+
var totalPages = this.props.result.totalPages()
|
77
|
+
|
78
|
+
return (currentPage + 5 < totalPages)
|
79
|
+
}
|
80
|
+
|
81
|
+
render() {
|
82
|
+
return (
|
83
|
+
<ul className="pagination">
|
84
|
+
<li className={`page-item ${this.props.result.currentPage() <= 1 ? "disabled" : ""}`} key="page-first">
|
85
|
+
<Link className="page-link" to={this.pagePath(1)}>
|
86
|
+
⇤
|
87
|
+
</Link>
|
88
|
+
</li>
|
89
|
+
<li className={`page-item ${this.props.result.currentPage() <= 1 ? "disabled" : ""}`} key="page-previous">
|
90
|
+
<Link className="page-link" to={this.previousPagePath()}>
|
91
|
+
←
|
92
|
+
</Link>
|
93
|
+
</li>
|
94
|
+
{this.showBackwardsDots() &&
|
95
|
+
<li className="page-item">
|
96
|
+
<a className="page-link disabled" href="#">
|
97
|
+
…
|
98
|
+
</a>
|
99
|
+
</li>
|
100
|
+
}
|
101
|
+
{this.pages().map(page =>
|
102
|
+
<li className={`page-item ${this.isPageActiveClass(page)}`} key={`page-${page}`}>
|
103
|
+
<Link className="page-link" to={this.pagePath(page)}>
|
104
|
+
{page}
|
105
|
+
</Link>
|
106
|
+
</li>
|
107
|
+
)}
|
108
|
+
{this.showForwardsDots() &&
|
109
|
+
<li className="page-item">
|
110
|
+
<a className="page-link disabled" href="#">
|
111
|
+
…
|
112
|
+
</a>
|
113
|
+
</li>
|
114
|
+
}
|
115
|
+
<li className={`page-item ${this.props.result.currentPage() >= this.props.result.totalPages() ? "disabled" : ""}`} key="page-next">
|
116
|
+
<Link className="page-link" to={this.nextPagePath()}>
|
117
|
+
→
|
118
|
+
</Link>
|
119
|
+
</li>
|
120
|
+
<li className={`page-item ${this.props.result.currentPage() >= this.props.result.totalPages() ? "disabled" : ""}`} key="page-last">
|
121
|
+
<Link className="page-link" to={this.pagePath(this.props.result.totalPages())}>
|
122
|
+
⇥
|
123
|
+
</Link>
|
124
|
+
</li>
|
125
|
+
</ul>
|
126
|
+
)
|
127
|
+
}
|
128
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import formSerialize from "form-serialize"
|
2
|
+
import KeyValueStore from "api-maker/key-value-store"
|
3
|
+
import merge from "merge"
|
4
|
+
import qs from "qs"
|
5
|
+
|
6
|
+
export default class Params {
|
7
|
+
static parse() {
|
8
|
+
return qs.parse(window.location.search.substr(1))
|
9
|
+
}
|
10
|
+
|
11
|
+
static change(given) {
|
12
|
+
return merge.recursive(true, Params.parse(), given)
|
13
|
+
}
|
14
|
+
|
15
|
+
static changeParams(given) {
|
16
|
+
var params = Params.change(given)
|
17
|
+
var newParams = qs.stringify(params)
|
18
|
+
var newPath = `${location.pathname}?${newParams}`
|
19
|
+
|
20
|
+
AppHistory.push(newPath)
|
21
|
+
}
|
22
|
+
|
23
|
+
static async getCachedParams(paramName, args = {}) {
|
24
|
+
var oldQuery = await KeyValueStore.get(paramName)
|
25
|
+
var params = Params.parse()
|
26
|
+
|
27
|
+
if (params && paramName in params) {
|
28
|
+
return params[paramName]
|
29
|
+
} else if (oldQuery) {
|
30
|
+
return oldQuery
|
31
|
+
} else {
|
32
|
+
return args.default || {}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
static async setCachedParams(paramName, qParams) {
|
37
|
+
return await KeyValueStore.set(paramName, qParams)
|
38
|
+
}
|
39
|
+
|
40
|
+
static serializeForm(form) {
|
41
|
+
var hash = formSerialize(form, {empty: true, hash: true})
|
42
|
+
return Params.setUndefined(hash)
|
43
|
+
}
|
44
|
+
|
45
|
+
// This is used to set all empty values to 'undefined' which makes qs removed those elements from the query string
|
46
|
+
static setUndefined(given) {
|
47
|
+
if (Array.isArray(given)) {
|
48
|
+
if (given.length == 0)
|
49
|
+
return undefined
|
50
|
+
|
51
|
+
return given.map(givenI => Params.setUndefined(givenI))
|
52
|
+
} else if (typeof given === "object") {
|
53
|
+
if (Object.keys(given).length == 0)
|
54
|
+
return undefined
|
55
|
+
|
56
|
+
var newGiven = {}
|
57
|
+
for(var key in given) {
|
58
|
+
newGiven[key] = Params.setUndefined(given[key])
|
59
|
+
}
|
60
|
+
|
61
|
+
return newGiven
|
62
|
+
} else if (given === "") {
|
63
|
+
return undefined
|
64
|
+
} else {
|
65
|
+
return given
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
const inflection = require("inflection")
|
2
|
+
|
3
|
+
export default class ResourceRoute {
|
4
|
+
constructor(args) {
|
5
|
+
this.args = args.args
|
6
|
+
this.parsedContext = args.parsedContext
|
7
|
+
this.route = args.route
|
8
|
+
}
|
9
|
+
|
10
|
+
routes() {
|
11
|
+
if (this.args.locales) {
|
12
|
+
return this.withLocale()
|
13
|
+
} else {
|
14
|
+
return this.withoutLocale()
|
15
|
+
}
|
16
|
+
}
|
17
|
+
|
18
|
+
findRouteParams(route) {
|
19
|
+
var result = []
|
20
|
+
var parts = route.path.split("/")
|
21
|
+
|
22
|
+
for(var part of parts) {
|
23
|
+
if (part.match(/^:([a-z_]+)$/))
|
24
|
+
result.push(part)
|
25
|
+
}
|
26
|
+
|
27
|
+
return result
|
28
|
+
}
|
29
|
+
|
30
|
+
requireComponent() {
|
31
|
+
var requireResult = this.parsedContext[`components/${this.route.component}.jsx`]
|
32
|
+
|
33
|
+
if (!requireResult)
|
34
|
+
var requireResult = this.parsedContext[`components/${this.route.component}/index.jsx`]
|
35
|
+
|
36
|
+
if (!requireResult)
|
37
|
+
throw new Error(`No such require: ${this.route.component}`)
|
38
|
+
|
39
|
+
return requireResult.default
|
40
|
+
}
|
41
|
+
|
42
|
+
withLocale() {
|
43
|
+
var component = this.requireComponent()
|
44
|
+
var Locales = require("shared/locales").default
|
45
|
+
var Path = require("shared/path").default
|
46
|
+
var routes = []
|
47
|
+
|
48
|
+
for(var locale of Locales.availableLocales()) {
|
49
|
+
var path = Path.localized(inflection.camelize(this.route.name, true), this.findRouteParams(this.route), {locale: locale})
|
50
|
+
|
51
|
+
routes.push({
|
52
|
+
path: path,
|
53
|
+
component: component
|
54
|
+
})
|
55
|
+
}
|
56
|
+
|
57
|
+
return routes
|
58
|
+
}
|
59
|
+
|
60
|
+
withoutLocale() {
|
61
|
+
var routePathName = inflection.camelize(this.route.name, true)
|
62
|
+
var routePathMethod = Routes[`${routePathName}Path`]
|
63
|
+
|
64
|
+
if (!routePathMethod)
|
65
|
+
throw new Error(`No such route could be found: ${routePathName}`)
|
66
|
+
|
67
|
+
var path = routePathMethod.apply(null, this.findRouteParams(this.route))
|
68
|
+
var component = this.requireComponent()
|
69
|
+
|
70
|
+
return [{
|
71
|
+
path: path,
|
72
|
+
component: component
|
73
|
+
}]
|
74
|
+
}
|
75
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import React from "react" // This fixes an issue with the Baristo project where it needed it to be loaded
|
2
|
+
import ResourceRoute from "./resource-route"
|
3
|
+
import { Route } from "react-router-dom"
|
4
|
+
|
5
|
+
export default class ApiMakerResourceRoutes {
|
6
|
+
static readRoutes(args = {}) {
|
7
|
+
if (!args.routes)
|
8
|
+
throw new Error("Please pass 'routes' to this method")
|
9
|
+
|
10
|
+
var parsedContext = ApiMakerResourceRoutes.parseContext(args)
|
11
|
+
var routesJson = args.routes
|
12
|
+
var routes = []
|
13
|
+
|
14
|
+
for(var route of routesJson.routes) {
|
15
|
+
var resourceRoute = new ResourceRoute({args, parsedContext, route})
|
16
|
+
|
17
|
+
for(var newRoute of resourceRoute.routes()) {
|
18
|
+
routes.push(
|
19
|
+
<Route exact key={`route-${newRoute.path}`} path={newRoute.path} component={newRoute.component} />
|
20
|
+
)
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
return routes
|
25
|
+
}
|
26
|
+
|
27
|
+
static parseContext(args) {
|
28
|
+
var result = {}
|
29
|
+
args.context.keys().forEach(key => {
|
30
|
+
var newKey = `${args.path}/${key.substring(2, key.length)}`
|
31
|
+
result[newKey] = args.context(key)
|
32
|
+
})
|
33
|
+
|
34
|
+
return result
|
35
|
+
}
|
36
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
export default class Result {
|
2
|
+
constructor(data) {
|
3
|
+
this.data = data
|
4
|
+
}
|
5
|
+
|
6
|
+
currentPage() {
|
7
|
+
return this.data.response.meta.currentPage
|
8
|
+
}
|
9
|
+
|
10
|
+
models() {
|
11
|
+
return this.data.models
|
12
|
+
}
|
13
|
+
|
14
|
+
modelClass() {
|
15
|
+
return this.data.collection.modelClass()
|
16
|
+
}
|
17
|
+
|
18
|
+
totalCount() {
|
19
|
+
return this.data.response.meta.totalCount
|
20
|
+
}
|
21
|
+
|
22
|
+
totalPages() {
|
23
|
+
return this.data.response.meta.totalPages
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,113 @@
|
|
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
|
+
}
|