expressa 1.1.2 → 1.2.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.
- package/.circleci/config.yml +1 -1
- package/README.md +4 -3
- package/controllers/collections.js +53 -32
- package/controllers/install.js +34 -27
- package/db/cached.js +3 -0
- package/db/file.js +3 -0
- package/db/memory.js +3 -0
- package/db/mongo.js +7 -8
- package/db/postgres.js +13 -0
- package/index.js +6 -5
- package/listeners_validation.js +4 -0
- package/modules/admin/.babelrc +13 -12
- package/modules/admin/build/webpack.prod.conf.js +5 -3
- package/modules/admin/config/index.js +2 -2
- package/modules/admin/dist/index.html +1 -1
- package/modules/admin/dist/index.html.gz +0 -0
- package/modules/admin/dist/static/css/app.9dd57eea.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-1dff.39c7634b.css +1 -0
- package/modules/admin/dist/static/css/chunk-1dff.39c7634b.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-3bc2.89632b9d.css.gz +0 -0
- package/modules/admin/dist/static/css/{chunk-5cee.ce0e4bdb.css → chunk-5cee.9685afb8.css} +0 -0
- package/modules/admin/dist/static/css/chunk-5cee.9685afb8.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-621e.f3d0eab6.css +1 -0
- package/modules/admin/dist/static/css/chunk-621e.f3d0eab6.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-7291.13514e45.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-a99c.c4b0e273.css +1 -0
- package/modules/admin/dist/static/css/chunk-a99c.c4b0e273.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-b423.5f239333.css.gz +0 -0
- package/modules/admin/dist/static/css/{chunk-bd5f.aefa49d7.css → chunk-bd5f.6ab011ba.css} +0 -0
- package/modules/admin/dist/static/css/chunk-bd5f.6ab011ba.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-e375.1d849865.css +1 -0
- package/modules/admin/dist/static/css/chunk-e375.1d849865.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-elementUI.3d004d9f.css.gz +0 -0
- package/modules/admin/dist/static/css/{chunk-759b.3a895a1e.css → chunk-f075.3a895a1e.css} +0 -0
- package/modules/admin/dist/static/css/chunk-f075.3a895a1e.css.gz +0 -0
- package/modules/admin/dist/static/css/chunk-libs.327ad89e.css +14 -0
- package/modules/admin/dist/static/css/chunk-libs.327ad89e.css.gz +0 -0
- package/modules/admin/dist/static/js/app.947e8310.js +1 -0
- package/modules/admin/dist/static/js/app.947e8310.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-09d8.561880e0.js +2 -0
- package/modules/admin/dist/static/js/{chunk-23bd.5fa24c85.js.LICENSE.txt → chunk-09d8.561880e0.js.LICENSE.txt} +1 -1
- package/modules/admin/dist/static/js/chunk-09d8.561880e0.js.LICENSE.txt.gz +0 -0
- package/modules/admin/dist/static/js/chunk-09d8.561880e0.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-1dff.b5ee003b.js +1 -0
- package/modules/admin/dist/static/js/chunk-1dff.b5ee003b.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-3bc2.b0270c10.js +1 -0
- package/modules/admin/dist/static/js/chunk-3bc2.b0270c10.js.gz +0 -0
- package/modules/admin/dist/static/js/{chunk-5cee.a3b03f7a.js → chunk-5cee.a6f0e769.js} +0 -0
- package/modules/admin/dist/static/js/chunk-5cee.a6f0e769.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-621e.c63db96c.js +1 -0
- package/modules/admin/dist/static/js/chunk-621e.c63db96c.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-7291.f914fca7.js +1 -0
- package/modules/admin/dist/static/js/chunk-7291.f914fca7.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-a99c.3f48f127.js +1 -0
- package/modules/admin/dist/static/js/chunk-a99c.3f48f127.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-b423.387c504c.js.gz +0 -0
- package/modules/admin/dist/static/js/{chunk-bd5f.e9509f10.js → chunk-bd5f.af5f2197.js} +0 -0
- package/modules/admin/dist/static/js/chunk-bd5f.af5f2197.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-e375.7ba1b61f.js +1 -0
- package/modules/admin/dist/static/js/chunk-e375.7ba1b61f.js.gz +0 -0
- package/modules/admin/dist/static/js/{chunk-e7c3.e5df8ceb.js → chunk-e7c3.a8659352.js} +1 -1
- package/modules/admin/dist/static/js/chunk-e7c3.a8659352.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-elementUI.b0c99c08.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-f075.6b230660.js +1 -0
- package/modules/admin/dist/static/js/chunk-f075.6b230660.js.gz +0 -0
- package/modules/admin/dist/static/js/chunk-libs.5637556a.js +2 -0
- package/modules/admin/dist/static/js/{chunk-libs.b6f27cfe.js.LICENSE.txt → chunk-libs.5637556a.js.LICENSE.txt} +1 -1
- package/modules/admin/dist/static/js/chunk-libs.5637556a.js.LICENSE.txt.gz +0 -0
- package/modules/admin/dist/static/js/chunk-libs.5637556a.js.gz +0 -0
- package/modules/admin/package.json +4 -3
- package/modules/admin/src/main.js +2 -2
- package/modules/admin/src/router/index.js +185 -185
- package/modules/admin/src/utils/request.js +47 -48
- package/modules/admin/src/views/ListDocuments2.vue +407 -309
- package/package.json +5 -5
- package/test/collections.js +2 -3
- package/test/collections.querying.js +18 -4
- package/test/test.js +4 -0
- package/util.js +19 -0
- package/modules/admin/dist/static/css/chunk-36ca.e7e72230.css +0 -1
- package/modules/admin/dist/static/css/chunk-62f2.538cfd24.css +0 -1
- package/modules/admin/dist/static/css/chunk-7869.220d4af5.css +0 -1
- package/modules/admin/dist/static/css/chunk-e80a.5ee55031.css +0 -1
- package/modules/admin/dist/static/css/chunk-libs.68e8d170.css +0 -14
- package/modules/admin/dist/static/js/app.12d7fe96.js +0 -1
- package/modules/admin/dist/static/js/chunk-23bd.5fa24c85.js +0 -2
- package/modules/admin/dist/static/js/chunk-36ca.eda87655.js +0 -1
- package/modules/admin/dist/static/js/chunk-3bc2.028748b7.js +0 -1
- package/modules/admin/dist/static/js/chunk-62f2.ee07e11b.js +0 -1
- package/modules/admin/dist/static/js/chunk-7291.590524e9.js +0 -1
- package/modules/admin/dist/static/js/chunk-759b.89a889b6.js +0 -1
- package/modules/admin/dist/static/js/chunk-7869.b7ab2c47.js +0 -1
- package/modules/admin/dist/static/js/chunk-e80a.cc0d79f4.js +0 -1
- package/modules/admin/dist/static/js/chunk-libs.b6f27cfe.js +0 -2
package/.circleci/config.yml
CHANGED
package/README.md
CHANGED
|
@@ -52,9 +52,10 @@ Once you add a collections in the admin interface, every collection will have th
|
|
|
52
52
|
| POST | /users/login | expects JSON in the message body. e.g. `{"email": "email@example.com", password: "<the password>"} |
|
|
53
53
|
| GET | /:collection | get an array of all documents in a collection |
|
|
54
54
|
| GET | /:collection/:id | get a specific document |
|
|
55
|
-
| GET | /:collection/?query={..} | get an array of documents matching the [mongo query](https://www.npmjs.com/package/mongo-query)
|
|
56
|
-
| GET | /:collection/?query={..}&limit=10&
|
|
57
|
-
| GET | /:collection/?query={..}&
|
|
55
|
+
| GET | /:collection/?query={..} | get an array of documents matching the [mongo query](https://www.npmjs.com/package/mongo-query) |
|
|
56
|
+
| GET | /:collection/?query={..}&limit=10&offset=10&orderby={"meta.created":1} | same as previous, but with targeted output control and sorting |
|
|
57
|
+
| GET | /:collection/?query={..}&page=1&pageitems=10 | similar to previous, but with pagination support |
|
|
58
|
+
| GET | /:collection/?query={..}&page=1&pageitems=10&pagemetadisable=1 | same as previous but *slightly* faster and with less pagination detail |
|
|
58
59
|
| GET | /:collection/?query={..}&fields={..} | the fields param can be used to do a mongo projection to request only specific fields |
|
|
59
60
|
| GET | /:collection/?fieldname=value | get an array of documents matching with the specified values. See [node-mongo-querystring](https://github.com/Turistforeningen/node-mongo-querystring) for details. |
|
|
60
61
|
| GET | /:collection/schema | get the collection schema |
|
|
@@ -18,54 +18,75 @@ exports.getSchema = async function (req) {
|
|
|
18
18
|
|
|
19
19
|
exports.get = async function (req) {
|
|
20
20
|
assertValidCollection(req)
|
|
21
|
-
let total = 0
|
|
22
21
|
if (typeof req.db[req.params.collection] === 'undefined') {
|
|
23
22
|
throw new util.ApiError(404, 'unknown collection')
|
|
24
23
|
}
|
|
24
|
+
|
|
25
25
|
const fields = req.query.fields ? JSON.parse(req.query.fields) : null
|
|
26
|
-
|
|
26
|
+
|
|
27
|
+
let data, query
|
|
27
28
|
if (req.query.query) {
|
|
28
29
|
query = JSON.parse(req.query.query)
|
|
29
|
-
} else {
|
|
30
|
-
const { skip, offset, limit, page, orderby, fields, ...params } = req.query // eslint-disable-line no-unused-vars
|
|
31
|
-
query = queryStringParser.parse(params)
|
|
32
30
|
}
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
else {
|
|
32
|
+
const { skip, offset, limit, page, pageitems, pagemetadisable, orderby, fields, ...params } = req.query // eslint-disable-line no-unused-vars
|
|
33
|
+
query = queryStringParser.parse(params)
|
|
35
34
|
}
|
|
36
|
-
if (req.query.
|
|
37
|
-
req.query.
|
|
35
|
+
if (req.query.orderby) {
|
|
36
|
+
req.query.orderby = JSON.parse(req.query.orderby)
|
|
37
|
+
req.query.orderby = util.normalizeOrderBy(req.query.orderby)
|
|
38
38
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
|
|
40
|
+
if (req.uid) {
|
|
41
|
+
// scenario where logged in user can only retrieve own docs
|
|
42
|
+
if (!req.hasPermission(`${req.params.collection}: view`) && req.hasPermission(`${req.params.collection}: view own`)) {
|
|
43
|
+
query['meta.owner'] = req.uid
|
|
44
|
+
fields['meta.owner'] = 1
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
|
-
let orderby
|
|
47
|
-
if (req.query.orderby) {
|
|
48
|
-
orderby = JSON.parse(req.query.orderby)
|
|
49
|
-
orderby = util.normalizeOrderBy(orderby)
|
|
50
|
-
}
|
|
51
47
|
|
|
52
|
-
|
|
53
|
-
req.query.
|
|
54
|
-
total = data.length
|
|
55
|
-
const limit = req.query.pageitems || (total > 10 ? 10 : total)
|
|
56
|
-
// calculate pagination in case `page`-queryarg was passed
|
|
57
|
-
const allowed = await Promise.all(data.map((doc) =>
|
|
58
|
-
util.notify('get', req, req.params.collection, doc).catch(() => false)
|
|
59
|
-
))
|
|
60
|
-
let result = data.filter((doc, i) => allowed[i] === true)
|
|
61
|
-
if (req.query.page) {
|
|
48
|
+
if (req.query.page != null) {
|
|
49
|
+
req.query.page = parseInt(req.query.page)
|
|
62
50
|
if (req.query.page <= 0) {
|
|
63
51
|
throw new util.ApiError(400, 'invalid page number')
|
|
64
52
|
}
|
|
65
|
-
|
|
53
|
+
req.query.pageitems = parseInt(req.query.pageitems) || parseInt(req.query.limit) || 10
|
|
54
|
+
req.query.offset = util.getDatabaseOffset(req.query.page, req.query.pageitems)
|
|
55
|
+
req.query.orderby = req.query.orderby || util.normalizeOrderBy({ 'meta.created': 1 }) // paging requires orderby to ensure consistent results with offset and limit
|
|
56
|
+
delete req.query.limit
|
|
57
|
+
delete req.query.skip
|
|
58
|
+
let pageData, totalItems
|
|
59
|
+
if (req.query.pagemetadisable) {
|
|
60
|
+
// a way to skip the extra count database call, but lose additional page detail
|
|
61
|
+
pageData = await req.db[req.params.collection].find(query, req.query.offset, req.query.pageitems, req.query.orderby, fields)
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// this is default - full detail
|
|
65
|
+
[pageData, totalItems] = await Promise.all([
|
|
66
|
+
req.db[req.params.collection].find(query, req.query.offset, req.query.pageitems, req.query.orderby, fields),
|
|
67
|
+
req.db[req.params.collection].count(query)
|
|
68
|
+
])
|
|
69
|
+
}
|
|
70
|
+
await Promise.all(pageData.map((doc) => util.notify('get', req, req.params.collection, doc)))
|
|
71
|
+
data = util.createPagePagination(pageData, req.query.page, req.query.pageitems, totalItems)
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
if (req.query.limit) {
|
|
75
|
+
req.query.limit = parseInt(req.query.limit)
|
|
76
|
+
}
|
|
77
|
+
if (req.query.skip) {
|
|
78
|
+
req.query.offset = parseInt(req.query.skip)
|
|
79
|
+
delete req.query.skip
|
|
80
|
+
}
|
|
81
|
+
else if (req.query.offset) {
|
|
82
|
+
req.query.offset = parseInt(req.query.offset)
|
|
83
|
+
}
|
|
84
|
+
data = await req.db[req.params.collection].find(query, req.query.offset, req.query.limit, req.query.orderby, fields)
|
|
85
|
+
await Promise.all(data.map((doc) => util.notify('get', req, req.params.collection, doc)))
|
|
66
86
|
}
|
|
67
|
-
|
|
68
|
-
|
|
87
|
+
|
|
88
|
+
await util.notify('getpresend', req, req.params.collection, data)
|
|
89
|
+
return data
|
|
69
90
|
}
|
|
70
91
|
|
|
71
92
|
exports.insert = async function (req) {
|
package/controllers/install.js
CHANGED
|
@@ -27,39 +27,46 @@ exports.install = async (req, api) => {
|
|
|
27
27
|
|
|
28
28
|
const modules = selectedModules.map((name) => req.modules[name])
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
settings._id = process.env.NODE_ENV
|
|
32
|
-
settings.jwt_secret = util.createSecureRandomId()
|
|
33
|
-
// Remove fields that are not real settings
|
|
34
|
-
delete settings.email
|
|
35
|
-
delete settings.user_storage
|
|
36
|
-
delete settings.password
|
|
37
|
-
Object.assign(req.settings, settings)
|
|
38
|
-
await req.db.settings.create(settings)
|
|
30
|
+
let settings = await api.db.settings.get(process.env.NODE_ENV).catch(() => {})
|
|
39
31
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
32
|
+
if (!settings) {
|
|
33
|
+
settings = JSON.parse(JSON.stringify(req.body.settings))
|
|
34
|
+
settings._id = process.env.NODE_ENV
|
|
35
|
+
settings.jwt_secret = util.createSecureRandomId()
|
|
36
|
+
// Remove fields that are not real settings
|
|
37
|
+
delete settings.email
|
|
38
|
+
delete settings.user_storage
|
|
39
|
+
delete settings.password
|
|
40
|
+
Object.assign(req.settings, settings)
|
|
41
|
+
await req.db.settings.create(settings)
|
|
42
|
+
|
|
43
|
+
for (const m of modules) {
|
|
44
|
+
const colls = await util.resolve(m.collections, api)
|
|
45
|
+
if (colls) {
|
|
46
|
+
for (const coll of colls) {
|
|
47
|
+
if (!coll.storage) {
|
|
48
|
+
coll.storage = 'file'
|
|
49
|
+
}
|
|
50
|
+
if (coll._id == 'users') {
|
|
51
|
+
if (req.body.settings.user_storage) {
|
|
52
|
+
coll.storage = req.body.settings.user_storage
|
|
53
|
+
}
|
|
54
|
+
coll.enableLogin = true
|
|
50
55
|
}
|
|
51
|
-
coll
|
|
56
|
+
await req.db.collection.create(coll)
|
|
57
|
+
await api.notify('changed', req, 'collection', coll)
|
|
58
|
+
// await collectionsApi.insert(Object.assign({}, req, { body: coll }))
|
|
52
59
|
}
|
|
53
|
-
await req.db.collection.create(coll)
|
|
54
|
-
await api.notify('changed', req, 'collection', coll)
|
|
55
|
-
// await collectionsApi.insert(Object.assign({}, req, { body: coll }))
|
|
56
60
|
}
|
|
61
|
+
await util.resolve(m.install, api)
|
|
62
|
+
}
|
|
63
|
+
await exports.updateAdminPermissions(api)
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
if (settings.installed) {
|
|
67
|
+
throw new Error(`${process.env.NODE_ENV}.json exists and indicates expressa is already installed. Try setting 'installed' to false if you are attempting to reinstall.`)
|
|
57
68
|
}
|
|
58
|
-
|
|
59
|
-
await util.resolve(m.install, api)
|
|
60
69
|
}
|
|
61
|
-
|
|
62
|
-
await exports.updateAdminPermissions(api)
|
|
63
70
|
|
|
64
71
|
settings.installed = true
|
|
65
72
|
settings.enforce_permissions = true
|
package/db/cached.js
CHANGED
|
@@ -14,6 +14,9 @@ module.exports = function (storage) {
|
|
|
14
14
|
find: function (query, offset, limit, orderby, fields) {
|
|
15
15
|
return cache.find(query, offset, limit, orderby, fields)
|
|
16
16
|
},
|
|
17
|
+
count: async function(...params) {
|
|
18
|
+
return await cache.count(...params)
|
|
19
|
+
},
|
|
17
20
|
get: function (id, fields) {
|
|
18
21
|
return cache.get(id, fields)
|
|
19
22
|
},
|
package/db/file.js
CHANGED
package/db/memory.js
CHANGED
|
@@ -30,6 +30,9 @@ module.exports = function (settings, collection) {
|
|
|
30
30
|
}
|
|
31
31
|
return matches
|
|
32
32
|
},
|
|
33
|
+
count: async function(...params) {
|
|
34
|
+
return (await this.find(...params)).length
|
|
35
|
+
},
|
|
33
36
|
get: async function (id, fields) {
|
|
34
37
|
if (!store[id]) {
|
|
35
38
|
throw new util.ApiError(404, 'document not found')
|
package/db/mongo.js
CHANGED
|
@@ -19,13 +19,7 @@ module.exports = function (settings, collection) {
|
|
|
19
19
|
},
|
|
20
20
|
find: async function (query, skip, limit, orderby, fields) {
|
|
21
21
|
const db = await this.getClient()
|
|
22
|
-
const cursor = db.collection(collection).find(query, { fields
|
|
23
|
-
if (typeof skip !== 'undefined') {
|
|
24
|
-
cursor.skip(skip)
|
|
25
|
-
}
|
|
26
|
-
if (typeof limit !== 'undefined') {
|
|
27
|
-
cursor.limit(limit)
|
|
28
|
-
}
|
|
22
|
+
const cursor = db.collection(collection).find(query, { skip, limit, projection: fields, sort: orderby })
|
|
29
23
|
const docs = await cursor.toArray()
|
|
30
24
|
docs.forEach((doc) => {
|
|
31
25
|
if (doc._id) {
|
|
@@ -34,9 +28,14 @@ module.exports = function (settings, collection) {
|
|
|
34
28
|
})
|
|
35
29
|
return docs
|
|
36
30
|
},
|
|
31
|
+
count: async function(query, skip, limit) {
|
|
32
|
+
const db = await this.getClient()
|
|
33
|
+
const count = await db.collection(collection).count(query, { skip, limit })
|
|
34
|
+
return count
|
|
35
|
+
},
|
|
37
36
|
get: async function (id, fields) {
|
|
38
37
|
const db = await this.getClient()
|
|
39
|
-
const doc = await db.collection(collection).findOne({ _id: id }, { fields })
|
|
38
|
+
const doc = await db.collection(collection).findOne({ _id: id }, { projection: fields })
|
|
40
39
|
if (doc) {
|
|
41
40
|
doc._id = doc._id.toString()
|
|
42
41
|
}
|
package/db/postgres.js
CHANGED
|
@@ -35,6 +35,19 @@ module.exports = function (settings, collectionId, collection) {
|
|
|
35
35
|
const result = await pool.query(query)
|
|
36
36
|
return result.rows.map((row) => row.data)
|
|
37
37
|
},
|
|
38
|
+
count: async function(rawQuery, offset, limit) {
|
|
39
|
+
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
40
|
+
const pgQuery = mongoToPostgres('data', rawQuery || {}, arrayFields)
|
|
41
|
+
let query = 'SELECT COUNT(*) FROM ' + collectionId + (pgQuery ? ' WHERE ' + pgQuery : '')
|
|
42
|
+
if (typeof offset !== 'undefined') {
|
|
43
|
+
query += ' OFFSET ' + offset
|
|
44
|
+
}
|
|
45
|
+
if (typeof limit !== 'undefined') {
|
|
46
|
+
query += ' LIMIT ' + limit
|
|
47
|
+
}
|
|
48
|
+
const result = await pool.query(query)
|
|
49
|
+
return parseInt(result.rows[0].count)
|
|
50
|
+
},
|
|
38
51
|
get: async function (id, fields) {
|
|
39
52
|
const arrayFields = util.getArrayPaths('', collection.schema)
|
|
40
53
|
const select = fields ? mongoToPostgres.convertSelect('data', fields, arrayFields) : '*'
|
package/index.js
CHANGED
|
@@ -33,8 +33,6 @@ async function bootstrapCollections (router) {
|
|
|
33
33
|
}))
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
let initialized = false
|
|
37
|
-
|
|
38
36
|
async function initCollections (db, router) {
|
|
39
37
|
debug('init collections')
|
|
40
38
|
try {
|
|
@@ -103,6 +101,7 @@ function ph (requestHandler) {
|
|
|
103
101
|
|
|
104
102
|
module.exports.api = function (settings) {
|
|
105
103
|
const router = express.Router()
|
|
104
|
+
router.initialized = false
|
|
106
105
|
router.custom = express.Router()
|
|
107
106
|
router.dbTypes = dbTypes
|
|
108
107
|
router.settings = settings || {}
|
|
@@ -117,7 +116,9 @@ module.exports.api = function (settings) {
|
|
|
117
116
|
generateDocumentId: util.generateDocumentId,
|
|
118
117
|
doLogin: auth.doLogin,
|
|
119
118
|
createPagination: util.createPagination,
|
|
120
|
-
|
|
119
|
+
createPagePagination: util.createPagePagination,
|
|
120
|
+
normalizeOrderBy: util.normalizeOrderBy,
|
|
121
|
+
getDatabaseOffset: util.getDatabaseOffset,
|
|
121
122
|
}
|
|
122
123
|
router.eventListeners = {}
|
|
123
124
|
|
|
@@ -137,7 +138,7 @@ module.exports.api = function (settings) {
|
|
|
137
138
|
}
|
|
138
139
|
router.eventListeners[event].push(listener)
|
|
139
140
|
router.eventListeners[event].sort((a, b) => a.priority - b.priority)
|
|
140
|
-
if (event === 'ready' && initialized) {
|
|
141
|
+
if (event === 'ready' && router.initialized) {
|
|
141
142
|
listener(router)
|
|
142
143
|
}
|
|
143
144
|
}
|
|
@@ -205,7 +206,7 @@ module.exports.api = function (settings) {
|
|
|
205
206
|
console.error(e)
|
|
206
207
|
}
|
|
207
208
|
|
|
208
|
-
initialized = true
|
|
209
|
+
router.initialized = true
|
|
209
210
|
await util.notify('ready', router)
|
|
210
211
|
})()
|
|
211
212
|
|
package/listeners_validation.js
CHANGED
|
@@ -16,6 +16,10 @@ ajv.addKeyword({
|
|
|
16
16
|
type: 'string',
|
|
17
17
|
schemaType: 'object',
|
|
18
18
|
})
|
|
19
|
+
ajv.addKeyword({
|
|
20
|
+
keyword: 'propertyOrder',
|
|
21
|
+
schemaType: 'number',
|
|
22
|
+
})
|
|
19
23
|
const formatKey = ajv.getKeyword('format')
|
|
20
24
|
formatKey.type = formatKey.type.concat(['array', 'boolean', 'object'])
|
|
21
25
|
|
package/modules/admin/.babelrc
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
{
|
|
2
|
-
"sourceType": "module",
|
|
3
|
-
"presets": [
|
|
4
|
-
["env", {
|
|
5
|
-
"targets": {
|
|
6
|
-
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
1
|
+
{
|
|
2
|
+
"sourceType": "module",
|
|
3
|
+
"presets": [
|
|
4
|
+
["env", {
|
|
5
|
+
"targets": {
|
|
6
|
+
"browsers": ["> 1%", "last 2 versions", "not ie <= 8"]
|
|
7
|
+
},
|
|
8
|
+
"exclude": ["transform-regenerator"]
|
|
9
|
+
}],
|
|
10
|
+
"stage-2"
|
|
11
|
+
],
|
|
12
|
+
"plugins":["transform-vue-jsx", "transform-runtime"]
|
|
13
|
+
}
|
|
@@ -131,13 +131,15 @@ if (config.build.productionGzip) {
|
|
|
131
131
|
|
|
132
132
|
webpackConfig.plugins.push(
|
|
133
133
|
new CompressionWebpackPlugin({
|
|
134
|
-
|
|
134
|
+
filename: '[path][base].gz',
|
|
135
135
|
algorithm: 'gzip',
|
|
136
136
|
test: new RegExp(
|
|
137
137
|
'\\.(' + config.build.productionGzipExtensions.join('|') + ')$'
|
|
138
138
|
),
|
|
139
|
-
|
|
140
|
-
|
|
139
|
+
compressionOptions: {
|
|
140
|
+
level: 9,
|
|
141
|
+
},
|
|
142
|
+
minRatio: Infinity,
|
|
141
143
|
})
|
|
142
144
|
)
|
|
143
145
|
}
|
|
@@ -71,8 +71,8 @@ module.exports = {
|
|
|
71
71
|
// Surge or Netlify already gzip all static assets for you.
|
|
72
72
|
// Before setting to `true`, make sure to:
|
|
73
73
|
// npm install --save-dev compression-webpack-plugin
|
|
74
|
-
productionGzip:
|
|
75
|
-
productionGzipExtensions: ['js',
|
|
74
|
+
productionGzip: true,
|
|
75
|
+
productionGzipExtensions: ['json','js','js.map','css','html','svg','xml','txt'],
|
|
76
76
|
|
|
77
77
|
// Run the build command with an extra argument to
|
|
78
78
|
// View the bundle analyzer report after build finishes:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><script crossorigin src=https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.min.js></script><script crossorigin src=https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.min.js></script><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel=stylesheet><script src=settings.js></script><title>Expressa Admin</title><link rel=
|
|
1
|
+
<!DOCTYPE html><html><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><script crossorigin src=https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.min.js></script><script crossorigin src=https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.min.js></script><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel=stylesheet><script src=settings.js></script><title>Expressa Admin</title><link rel=icon href=/admin/favicon.ico><link href=/admin/static/css/chunk-elementUI.3d004d9f.css rel=stylesheet><link href=/admin/static/css/chunk-libs.327ad89e.css rel=stylesheet><link href=/admin/static/css/app.9dd57eea.css rel=stylesheet></head><body><div id=app></div><script>!function(e){function n(n){for(var r,c,a=n[0],f=n[1],i=n[2],h=0,s=[];h<a.length;h++)c=a[h],Object.prototype.hasOwnProperty.call(u,c)&&u[c]&&s.push(u[c][0]),u[c]=0;for(r in f)Object.prototype.hasOwnProperty.call(f,r)&&(e[r]=f[r]);for(l&&l(n);s.length;)s.shift()();return o.push.apply(o,i||[]),t()}function t(){for(var e,n=0;n<o.length;n++){for(var t=o[n],r=!0,c=1;c<t.length;c++){var f=t[c];0!==u[f]&&(r=!1)}r&&(o.splice(n--,1),e=a(a.s=t[0]))}return e}var r={},c={runtime:0},u={runtime:0},o=[];function a(n){if(r[n])return r[n].exports;var t=r[n]={i:n,l:!1,exports:{}};return e[n].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var n=[];c[e]?n.push(c[e]):0!==c[e]&&{"chunk-621e":1,"chunk-e375":1,"chunk-3bc2":1,"chunk-5cee":1,"chunk-7291":1,"chunk-a99c":1,"chunk-1dff":1,"chunk-b423":1,"chunk-bd5f":1,"chunk-f075":1}[e]&&n.push(c[e]=new Promise((function(n,t){for(var r="static/css/"+({}[e]||e)+"."+{"chunk-09d8":"31d6cfe0","chunk-621e":"f3d0eab6","chunk-e375":"1d849865","chunk-3bc2":"89632b9d","chunk-5cee":"9685afb8","chunk-7291":"13514e45","chunk-a99c":"c4b0e273","chunk-1dff":"39c7634b","chunk-b423":"5f239333","chunk-bd5f":"6ab011ba","chunk-e7c3":"31d6cfe0","chunk-f075":"3a895a1e"}[e]+".css",c=a.p+r,u=document.getElementsByTagName("link"),o=0;o<u.length;o++){var f=(h=u[o]).getAttribute("data-href")||h.getAttribute("href");if("stylesheet"===h.rel&&(f===r||f===c))return n()}var i=document.getElementsByTagName("style");for(o=0;o<i.length;o++){var h;if((f=(h=i[o]).getAttribute("data-href"))===r||f===c)return n()}var l=document.createElement("link");l.rel="stylesheet",l.type="text/css",l.onload=n,l.onerror=function(n){var r=n&&n.target&&n.target.src||c,u=new Error("Loading CSS chunk "+e+" failed.\n("+r+")");u.request=r,t(u)},l.href=c,document.getElementsByTagName("head")[0].appendChild(l)})).then((function(){c[e]=0})));var t=u[e];if(0!==t)if(t)n.push(t[2]);else{var r=new Promise((function(n,r){t=u[e]=[n,r]}));n.push(t[2]=r);var o,f=document.createElement("script");f.charset="utf-8",f.timeout=120,a.nc&&f.setAttribute("nonce",a.nc),f.src=function(e){return a.p+"static/js/"+({}[e]||e)+"."+{"chunk-09d8":"561880e0","chunk-621e":"c63db96c","chunk-e375":"7ba1b61f","chunk-3bc2":"b0270c10","chunk-5cee":"a6f0e769","chunk-7291":"f914fca7","chunk-a99c":"3f48f127","chunk-1dff":"b5ee003b","chunk-b423":"387c504c","chunk-bd5f":"af5f2197","chunk-e7c3":"a8659352","chunk-f075":"6b230660"}[e]+".js"}(e);var i=new Error;o=function(n){f.onerror=f.onload=null,clearTimeout(h);var t=u[e];if(0!==t){if(t){var r=n&&("load"===n.type?"missing":n.type),c=n&&n.target&&n.target.src;i.message="Loading chunk "+e+" failed.\n("+r+": "+c+")",i.name="ChunkLoadError",i.type=r,i.request=c,t[1](i)}u[e]=void 0}};var h=setTimeout((function(){o({type:"timeout",target:f})}),12e4);f.onerror=f.onload=o,document.head.appendChild(f)}return Promise.all(n)},a.m=e,a.c=r,a.d=function(e,n,t){a.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,n){if(1&n&&(e=a(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var r in e)a.d(t,r,function(n){return e[n]}.bind(null,r));return t},a.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(n,"a",n),n},a.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},a.p="/admin/",a.oe=function(e){throw console.error(e),e};var f=window.webpackJsonp=window.webpackJsonp||[],i=f.push.bind(f);f.push=n,f=f.slice();for(var h=0;h<f.length;h++)n(f[h]);var l=i;t()}([]);</script><script src=/admin/static/js/chunk-elementUI.b0c99c08.js></script><script src=/admin/static/js/chunk-libs.5637556a.js></script><script src=/admin/static/js/app.947e8310.js></script></body></html>
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.dashboard-container[data-v-5d163182]{margin:30px}.dashboard-text[data-v-5d163182]{font-size:30px;line-height:46px}a#settings-link[data-v-5d163182]{color:#35a;padding-left:25px}
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.expandable-textarea{display:block;min-height:250px;min-width:250px;resize:both!important}.jsoneditor-vue img{border:1px solid #ddd;border-radius:4px;padding:5px;width:150px}.jsoneditor-vue img:hover{-webkit-box-shadow:0 0 2px 1px rgba(0,140,186,.5);box-shadow:0 0 2px 1px rgba(0,140,186,.5)}.jsoneditor-vue button.btn{font-size:14px!important;padding:3px}.jsoneditor-vue .form-control-label,label{font-weight:700}.jsoneditor-vue input[type=checkbox]{margin-right:5px;margin-top:3px}.error-message[data-v-3c5b79e9]{color:red}
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.el-table[data-v-3b6dfa90] th{background-color:#343a40!important;border-color:#454d55;color:#fff}
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.expandable-textarea{display:block;min-height:250px;min-width:250px;resize:both!important}.jsoneditor-vue img{border:1px solid #ddd;border-radius:4px;padding:5px;width:150px}.jsoneditor-vue img:hover{-webkit-box-shadow:0 0 2px 1px rgba(0,140,186,.5);box-shadow:0 0 2px 1px rgba(0,140,186,.5)}.jsoneditor-vue button.btn{font-size:14px!important;padding:3px}.jsoneditor-vue .form-control-label,label{font-weight:700}.jsoneditor-vue input[type=checkbox]{margin-right:5px;margin-top:3px}.comment-link{margin-top:-15px}.error-message{color:red}
|
|
Binary file
|
|
Binary file
|
|
File without changes
|
|
Binary file
|