@sera4/essentia 1.1.66-rc.1 → 3.0.8
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/README.md +352 -8
- package/dist/ts/index.d.ts +1 -1
- package/dist/ts/index.js +1 -1
- package/dist/ts/index.js.map +1 -1
- package/dist/ts/logger/s4-logger.js +0 -2
- package/dist/ts/logger/s4-logger.js.map +1 -1
- package/dist/ts/queue/index.d.ts +2 -38
- package/dist/ts/queue/index.js +67 -136
- package/dist/ts/queue/index.js.map +1 -1
- package/package.json +51 -12
- package/package.tar.gz +0 -0
- package/cache/index.js +0 -188
- package/constants/index.js +0 -9
- package/coverage/base.css +0 -224
- package/coverage/block-navigation.js +0 -87
- package/coverage/configurations/index.html +0 -116
- package/coverage/configurations/server-config.ts.html +0 -94
- package/coverage/dns/DnsCache.ts.html +0 -598
- package/coverage/dns/index.html +0 -131
- package/coverage/dns/index.ts.html +0 -94
- package/coverage/favicon.png +0 -0
- package/coverage/health/index.html +0 -116
- package/coverage/health/index.ts.html +0 -778
- package/coverage/index.html +0 -161
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/configurations/index.html +0 -116
- package/coverage/lcov-report/configurations/server-config.ts.html +0 -94
- package/coverage/lcov-report/dns/DnsCache.ts.html +0 -598
- package/coverage/lcov-report/dns/index.html +0 -131
- package/coverage/lcov-report/dns/index.ts.html +0 -94
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/health/index.html +0 -116
- package/coverage/lcov-report/health/index.ts.html +0 -778
- package/coverage/lcov-report/index.html +0 -161
- package/coverage/lcov-report/logger/index.html +0 -131
- package/coverage/lcov-report/logger/index.ts.html +0 -94
- package/coverage/lcov-report/logger/s4-logger.ts.html +0 -514
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -196
- package/coverage/lcov.info +0 -747
- package/coverage/logger/index.html +0 -131
- package/coverage/logger/index.ts.html +0 -94
- package/coverage/logger/s4-logger.ts.html +0 -514
- package/coverage/prettify.css +0 -1
- package/coverage/prettify.js +0 -2
- package/coverage/sort-arrow-sprite.png +0 -0
- package/coverage/sorter.js +0 -196
- package/coverage/tmp/coverage-24302-1746472691313-0.json +0 -1
- package/coverage/tmp/coverage-24302-1746472691366-1.json +0 -1
- package/dist/cache/index.d.ts +0 -22
- package/dist/cache/index.js +0 -166
- package/dist/cache/index.js.map +0 -1
- package/dist/constants/index.d.ts +0 -6
- package/dist/constants/index.js +0 -9
- package/dist/constants/index.js.map +0 -1
- package/dist/coverage/block-navigation.d.ts +0 -1
- package/dist/coverage/block-navigation.js +0 -70
- package/dist/coverage/block-navigation.js.map +0 -1
- package/dist/coverage/lcov-report/block-navigation.d.ts +0 -1
- package/dist/coverage/lcov-report/block-navigation.js +0 -70
- package/dist/coverage/lcov-report/block-navigation.js.map +0 -1
- package/dist/coverage/lcov-report/prettify.d.ts +0 -0
- package/dist/coverage/lcov-report/prettify.js +0 -477
- package/dist/coverage/lcov-report/prettify.js.map +0 -1
- package/dist/coverage/lcov-report/sorter.d.ts +0 -1
- package/dist/coverage/lcov-report/sorter.js +0 -163
- package/dist/coverage/lcov-report/sorter.js.map +0 -1
- package/dist/coverage/prettify.d.ts +0 -0
- package/dist/coverage/prettify.js +0 -477
- package/dist/coverage/prettify.js.map +0 -1
- package/dist/coverage/sorter.d.ts +0 -1
- package/dist/coverage/sorter.js +0 -163
- package/dist/coverage/sorter.js.map +0 -1
- package/dist/formatter/index.d.ts +0 -37
- package/dist/formatter/index.js +0 -75
- package/dist/formatter/index.js.map +0 -1
- package/dist/hal/index.d.ts +0 -5
- package/dist/hal/index.js +0 -69
- package/dist/hal/index.js.map +0 -1
- package/dist/health/health-logger.d.ts +0 -9
- package/dist/health/health-logger.js +0 -34
- package/dist/health/health-logger.js.map +0 -1
- package/dist/health/index.d.ts +0 -19
- package/dist/health/index.js +0 -175
- package/dist/health/index.js.map +0 -1
- package/dist/helpers/index.d.ts +0 -1
- package/dist/helpers/index.js +0 -2
- package/dist/helpers/index.js.map +0 -1
- package/dist/helpers/test-server-wrapper.d.ts +0 -120
- package/dist/helpers/test-server-wrapper.js +0 -165
- package/dist/helpers/test-server-wrapper.js.map +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -17
- package/dist/index.js.map +0 -1
- package/dist/last-commit.d.ts +0 -1
- package/dist/last-commit.js +0 -12
- package/dist/last-commit.js.map +0 -1
- package/dist/last_commit/index.d.ts +0 -7
- package/dist/last_commit/index.js +0 -83
- package/dist/last_commit/index.js.map +0 -1
- package/dist/paginator/s4-pagination.d.ts +0 -9
- package/dist/paginator/s4-pagination.js +0 -49
- package/dist/paginator/s4-pagination.js.map +0 -1
- package/dist/paginator/sql-pagination.d.ts +0 -27
- package/dist/paginator/sql-pagination.js +0 -166
- package/dist/paginator/sql-pagination.js.map +0 -1
- package/dist/paper-trail/helpers.d.ts +0 -11
- package/dist/paper-trail/helpers.js +0 -74
- package/dist/paper-trail/helpers.js.map +0 -1
- package/dist/paper-trail/index.d.ts +0 -13
- package/dist/paper-trail/index.js +0 -662
- package/dist/paper-trail/index.js.map +0 -1
- package/dist/prompts/index.d.ts +0 -14
- package/dist/prompts/index.js +0 -63
- package/dist/prompts/index.js.map +0 -1
- package/dist/queue/index.d.ts +0 -166
- package/dist/queue/index.js +0 -371
- package/dist/queue/index.js.map +0 -1
- package/dist/queue/publisher.d.ts +0 -31
- package/dist/queue/publisher.js +0 -84
- package/dist/queue/publisher.js.map +0 -1
- package/dist/queue/queue-logger.d.ts +0 -9
- package/dist/queue/queue-logger.js +0 -35
- package/dist/queue/queue-logger.js.map +0 -1
- package/dist/queue/subscriber.d.ts +0 -39
- package/dist/queue/subscriber.js +0 -97
- package/dist/queue/subscriber.js.map +0 -1
- package/dist/safe_proxy/index.d.ts +0 -13
- package/dist/safe_proxy/index.js +0 -54
- package/dist/safe_proxy/index.js.map +0 -1
- package/dist/serializer/index.d.ts +0 -5
- package/dist/serializer/index.js +0 -83
- package/dist/serializer/index.js.map +0 -1
- package/dist/test/debug-array.d.ts +0 -0
- package/dist/test/debug-array.js +0 -1
- package/dist/test/debug-array.js.map +0 -1
- package/dist/test/debug-setJSONB.d.ts +0 -0
- package/dist/test/debug-setJSONB.js +0 -1
- package/dist/test/debug-setJSONB.js.map +0 -1
- package/dist/test/prompt.test.d.ts +0 -1
- package/dist/test/prompt.test.js +0 -74
- package/dist/test/prompt.test.js.map +0 -1
- package/dist/test/s4-formatter.spec.d.ts +0 -1
- package/dist/test/s4-formatter.spec.js +0 -67
- package/dist/test/s4-formatter.spec.js.map +0 -1
- package/dist/test/s4-pagination.spec.d.ts +0 -1
- package/dist/test/s4-pagination.spec.js +0 -170
- package/dist/test/s4-pagination.spec.js.map +0 -1
- package/dist/test/safe-proxy.spec.d.ts +0 -1
- package/dist/test/safe-proxy.spec.js +0 -252
- package/dist/test/safe-proxy.spec.js.map +0 -1
- package/dist/test/serializer.spec.d.ts +0 -1
- package/dist/test/serializer.spec.js +0 -27
- package/dist/test/serializer.spec.js.map +0 -1
- package/dist/test/utils.spec.d.ts +0 -1
- package/dist/test/utils.spec.js +0 -446
- package/dist/test/utils.spec.js.map +0 -1
- package/dist/ts/task-scheduler/index.d.ts +0 -130
- package/dist/ts/task-scheduler/index.js +0 -259
- package/dist/ts/task-scheduler/index.js.map +0 -1
- package/formatter/index.js +0 -81
- package/hal/README.md +0 -54
- package/hal/index.js +0 -75
- package/health/health-logger.js +0 -40
- package/health/index.js +0 -188
- package/helpers/index.js +0 -1
- package/helpers/test-server-wrapper.js +0 -196
- package/last-commit.js +0 -12
- package/last_commit/index.js +0 -82
- package/logger/s4-logger.js +0 -128
- package/paginator/README.md +0 -183
- package/paginator/s4-pagination.js +0 -51
- package/paginator/sql-pagination.js +0 -178
- package/paper-trail/README.md +0 -68
- package/paper-trail/helpers.js +0 -99
- package/paper-trail/index.js +0 -843
- package/prompts/index.js +0 -78
- package/queue/index.js +0 -402
- package/queue/publisher.js +0 -96
- package/queue/queue-logger.js +0 -40
- package/queue/subscriber.js +0 -107
- package/safe_proxy/index.js +0 -61
- package/scripts/publish.sh +0 -46
- package/serializer/index.js +0 -90
- package/test/health.spec.js +0 -213
- package/test/prompt.test.js +0 -91
- package/test/s4-formatter.spec.js +0 -80
- package/test/s4-pagination.spec.js +0 -196
- package/test/serializer.spec.js +0 -34
- package/test/utils.spec.js +0 -145
- package/utils/index.js +0 -74
package/paginator/README.md
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
# PAGINATOR
|
|
2
|
-
|
|
3
|
-
This is a module to add pagination to Sequelize ORM based projects.
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
In your model definition, set pagination on your model
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
import { paginator } from "@sera4/essentia";
|
|
11
|
-
...
|
|
12
|
-
|
|
13
|
-
module.exports = (sequelize, DataTypes) => {
|
|
14
|
-
const Post = sequelize.define('Post', {...}, {...});
|
|
15
|
-
// Add pagination
|
|
16
|
-
paginator.paginate(Post);
|
|
17
|
-
return Post;
|
|
18
|
-
};
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
Later in your controller you can call the paginate method on your model
|
|
22
|
-
to return paginated results:
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
app.get('/posts', (req, res) => {
|
|
26
|
-
Post.using(req.query).paginate()
|
|
27
|
-
.then(p => res.status(200).json(p));
|
|
28
|
-
})
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
For example, calling `/posts?page_size=2&page_index=1 will return
|
|
32
|
-
something similar to the following:
|
|
33
|
-
|
|
34
|
-
```
|
|
35
|
-
{
|
|
36
|
-
"_pagination": {
|
|
37
|
-
"current_page": 1,
|
|
38
|
-
"first_page": false,
|
|
39
|
-
"last_page": false,
|
|
40
|
-
"page_size": 2,
|
|
41
|
-
"total_pages": 2500,
|
|
42
|
-
"total_size": 5000,
|
|
43
|
-
"out_of_bounds": false,
|
|
44
|
-
"previous_page": 0,
|
|
45
|
-
"next_page": 2
|
|
46
|
-
},
|
|
47
|
-
"_collection": [
|
|
48
|
-
{
|
|
49
|
-
"id": 42803,
|
|
50
|
-
"title": "FYrlujXyrcviLIkQNQsyIXEaRdARCJqNPIDsDiFuLxENtFXPRS",
|
|
51
|
-
"name": "uLHnWSekmNNKueYiglAkAwWckFetoSnudXalelnAkpnayIgiUi",
|
|
52
|
-
"content": "THISkjbnGVprKVFsMnlNEhgDYSGRZcomhNkcrbnuvnqogCdUen",
|
|
53
|
-
"created_at": "2018-11-03T16:04:10.526Z",
|
|
54
|
-
"updated_at": "2018-11-03T16:04:10.526Z"
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
"id": 42804,
|
|
58
|
-
"title": "VHgYIBGIuyObzHjrpAwFwbtZSVMnCZdTIAIzzlQHChEPbwGwmU",
|
|
59
|
-
"name": "upvMbeIKAcuwHBruLyPcwEUYlAbQqqljUcMajOyvGaqCTahwfs",
|
|
60
|
-
"content": "EeopiRHsUdNNqzshkafYqkVzACOyWQpdPXCBSzuPBIDHWGqWuk",
|
|
61
|
-
"created_at": "2018-11-03T16:04:10.534Z",
|
|
62
|
-
"updated_at": "2018-11-03T16:04:10.534Z"
|
|
63
|
-
}
|
|
64
|
-
]
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
The `using` method takes 2 parameters:
|
|
69
|
-
|
|
70
|
-
* options - this is where the pagination parameters are read from. By default the method will be looking for `page_size` and `page_index`
|
|
71
|
-
* res - this is the express js response object and the method will also add pagination in the headers (if configured as such)
|
|
72
|
-
|
|
73
|
-
You can configure the pagination globally via `paginator.configure(options)`. The following options are available:
|
|
74
|
-
|
|
75
|
-
* Configuring the url keys for pagination:
|
|
76
|
-
* `paginateIn.size=page_size` - This is the key that will be used to parse number of items to read when the `using` method is called. Renaming this to `per_page` for examle, the url must contain the following query parameters `/posts?per_page=20` to load 20 posts
|
|
77
|
-
* `paginateIn.index=page_index` - This is the key that will be used to parse the offset to read when the `using` method is called. Renaming this to `page` requires an url with `/posts?page_size=20&page=2` to read rows 21 through 40 from the database.
|
|
78
|
-
* Configure the way the pagination data is displayed
|
|
79
|
-
* `paginateOut.current_page=current_page` Label used to show the current page value in the pagination data
|
|
80
|
-
* `paginateOut.first_page=first_page` Label used to show the first page value in the pagination data
|
|
81
|
-
* `paginateOut.last_page=last_page` Label used to show the last page value in the pagination data
|
|
82
|
-
* `paginateOut.next_page=next_page` Label used to show the next page value in the pagination data
|
|
83
|
-
* `paginateOut.out_of_bounds=out_of_bounds` Label used to show the out of bounds value in the pagination data
|
|
84
|
-
* `paginateOut.page_size=page_size` Label used to show the page size value in the pagination data
|
|
85
|
-
* `paginateOut.previous_page=previous_page` Label used to show the previous size value in the pagination data
|
|
86
|
-
* `paginateOut.total_pages=total_pages` Label used to show the total pages value in the pagination data
|
|
87
|
-
* `paginateOut.total_size=total_size` Label used to show the total size value in the pagination data
|
|
88
|
-
* `paginateOut.links=""` Label used to show the links in the pagination data. If this value is empty or null, no links are added in the pagination data. If set to `true`, then a `_links` key is added to the pagination data with links to previous and next pages if available. You can provide a non empty string instead of `true` to use your own lable for this key.
|
|
89
|
-
* Other configurations:
|
|
90
|
-
* `zeroBasedOffset=true` When false, the indexing is done from 1, otherwise it's done from 0 like in arrays
|
|
91
|
-
* `paginationHeader=tws-pagination` The name of the pagination header used when adding pagination in the headers
|
|
92
|
-
* `headersOnly=false` If this is set to true, then the pagination will return an array of objects and all the pagination data can be found in the headers. Otherwise the result will have a key for pagination (`_pagination`) and a key for the results (`_collection`)
|
|
93
|
-
* `paginationTag=_pagination` Used to overwrite the key name used for pagination
|
|
94
|
-
* `collectionTag=_collection` Used to overwrite the key name used for results
|
|
95
|
-
|
|
96
|
-
The configuration is done globally, so you can add something like this as early as possible to your code:
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
paginator.configure({
|
|
100
|
-
paginateIn : {
|
|
101
|
-
size: "items_per_page",
|
|
102
|
-
index: "page_number",
|
|
103
|
-
},
|
|
104
|
-
paginateOut : {
|
|
105
|
-
links: "myLinks",
|
|
106
|
-
current_page: "the_current_page"
|
|
107
|
-
},
|
|
108
|
-
zeroBasedOffset : false,
|
|
109
|
-
paginationTag : "paginationData",
|
|
110
|
-
collectionTag : "paginatedCollection"
|
|
111
|
-
});
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
This will require an url like `/posts?items_per_page=2&page_number=1` and will produce the following results:
|
|
115
|
-
|
|
116
|
-
```
|
|
117
|
-
{
|
|
118
|
-
"paginationData": {
|
|
119
|
-
"the_current_page": 1,
|
|
120
|
-
"first_page": true,
|
|
121
|
-
"last_page": false,
|
|
122
|
-
"page_size": 2,
|
|
123
|
-
"total_pages": 2500,
|
|
124
|
-
"total_size": 5000,
|
|
125
|
-
"out_of_bounds": false,
|
|
126
|
-
"next_page": 2,
|
|
127
|
-
"myLinks": {
|
|
128
|
-
"first_page": "?page_number=1&items_per_page=2",
|
|
129
|
-
"last_page": "?page_number=2500&items_per_page=2",
|
|
130
|
-
"next_page": "?page_number=2&items_per_page=2"
|
|
131
|
-
}
|
|
132
|
-
},
|
|
133
|
-
"paginatedCollection": [
|
|
134
|
-
{
|
|
135
|
-
"id": 42801,
|
|
136
|
-
"title": "LJitZgbNPLpOlnkYdynKlSYnCjuLBYiVHYMfAPlSALeoVTuNKw",
|
|
137
|
-
"name": "cvnititqxdPnHdomgxJJVGynNInkScmDlkzAALunYFHNRjffqE",
|
|
138
|
-
"content": "LcURropLnJiudElgAVhsBSMRBRNUzHLDiTebZxxpplXdpeGEFa",
|
|
139
|
-
"created_at": "2018-11-03T16:04:10.511Z",
|
|
140
|
-
"updated_at": "2018-11-03T16:04:10.511Z"
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
"id": 42802,
|
|
144
|
-
"title": "mTyXHFoJjgXmwASYvfFgZJcstUTbHjvrcuVoaUMdXZmXuMrfBz",
|
|
145
|
-
"name": "yxrOfMUdiJqNMNdWAfKXbsMsskKbpeRzxfEoicEcSdNDhGaPBE",
|
|
146
|
-
"content": "TEAEugRIeOfceEyREmAGcxldDbtzqlaWGDRMIjAhmfAuwJraot",
|
|
147
|
-
"created_at": "2018-11-03T16:04:10.518Z",
|
|
148
|
-
"updated_at": "2018-11-03T16:04:10.518Z"
|
|
149
|
-
}
|
|
150
|
-
]
|
|
151
|
-
}
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
You may notice that the links in the pagination only have query parameters. If you want to include the resource, provide the resource name when adding pagination to your model.
|
|
155
|
-
|
|
156
|
-
For example:
|
|
157
|
-
```
|
|
158
|
-
import { paginator } from "@sera4/essentia"
|
|
159
|
-
...
|
|
160
|
-
|
|
161
|
-
module.exports = (sequelize, DataTypes) => {
|
|
162
|
-
const Post = sequelize.define('Post', {...}, {...});
|
|
163
|
-
// Add pagination
|
|
164
|
-
paginator.paginate(Post, "/posts");
|
|
165
|
-
return Post;
|
|
166
|
-
};
|
|
167
|
-
```
|
|
168
|
-
This will return pagination links in the pagination data prependend with the provided resource:
|
|
169
|
-
```
|
|
170
|
-
"myLinks": {
|
|
171
|
-
"first_page": "?page_number=1&items_per_page=2",
|
|
172
|
-
"last_page": "?page_number=2500&items_per_page=2",
|
|
173
|
-
"next_page": "?page_number=2&items_per_page=2"
|
|
174
|
-
}
|
|
175
|
-
```
|
|
176
|
-
becomes
|
|
177
|
-
```
|
|
178
|
-
"myLinks": {
|
|
179
|
-
"first_page": "/posts?page_number=1&items_per_page=2",
|
|
180
|
-
"last_page": "/posts?page_number=2500&items_per_page=2",
|
|
181
|
-
"next_page": "/posts?page_number=2&items_per_page=2"
|
|
182
|
-
}
|
|
183
|
-
```
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
const default_page = 1;
|
|
2
|
-
const default_size = 5;
|
|
3
|
-
|
|
4
|
-
function parseRequest(req, item, default_value) {
|
|
5
|
-
if (!req || !req.query) {
|
|
6
|
-
return default_value;
|
|
7
|
-
}
|
|
8
|
-
var r = parseInt(req.query[item]);
|
|
9
|
-
if (isNaN(r) || r < default_value) {
|
|
10
|
-
r = default_value;
|
|
11
|
-
}
|
|
12
|
-
return r;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
class S4Pagination {
|
|
16
|
-
createPaginator(req, res, next) {
|
|
17
|
-
var paginator = {
|
|
18
|
-
page : parseRequest(req, "page", default_page),
|
|
19
|
-
page_size : parseRequest(req, "page_size", default_size),
|
|
20
|
-
reply : function(data) {
|
|
21
|
-
if (!data) {
|
|
22
|
-
res.status(500).end();
|
|
23
|
-
return;
|
|
24
|
-
}
|
|
25
|
-
var pagination = {
|
|
26
|
-
total : data.total,
|
|
27
|
-
total_pages : data.pages,
|
|
28
|
-
current_page : data.page,
|
|
29
|
-
first_page : data.page === 1,
|
|
30
|
-
last_page : data.offset === data.pages,
|
|
31
|
-
page_size : data.limit,
|
|
32
|
-
out_of_bounds : data.docs.length === 0
|
|
33
|
-
}
|
|
34
|
-
if (!pagination.out_of_bounds) {
|
|
35
|
-
if (pagination.current_page > 1) {
|
|
36
|
-
pagination.previous_page = pagination.current_page - 1;
|
|
37
|
-
}
|
|
38
|
-
if (pagination.current_page < pagination.total_pages) {
|
|
39
|
-
pagination.next_page = pagination.current_page + 1;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
res.set("s4-pagination", JSON.stringify(pagination));
|
|
43
|
-
res.json(data.docs)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return paginator;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const paginator = new S4Pagination();
|
|
51
|
-
export default paginator;
|
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
"use strict"
|
|
2
|
-
|
|
3
|
-
class SequelizePaginator {
|
|
4
|
-
|
|
5
|
-
constructor() {
|
|
6
|
-
this.paginateIn = {
|
|
7
|
-
size: "page_size",
|
|
8
|
-
index: "page_index"
|
|
9
|
-
};
|
|
10
|
-
this.paginateOut = {
|
|
11
|
-
current_page: "current_page",
|
|
12
|
-
first_page: "first_page",
|
|
13
|
-
last_page: "last_page",
|
|
14
|
-
next_page: "next_page",
|
|
15
|
-
out_of_bounds: "out_of_bounds",
|
|
16
|
-
page_size: "page_size",
|
|
17
|
-
previous_page: "previous_page",
|
|
18
|
-
total_pages: "total_pages",
|
|
19
|
-
total_size: "total_size",
|
|
20
|
-
links: "",
|
|
21
|
-
};
|
|
22
|
-
this.zeroBasedOffset = true;
|
|
23
|
-
this.paginationHeader = "tws-pagination";
|
|
24
|
-
this.headersOnly = false;
|
|
25
|
-
this.paginationTag = "_pagination";
|
|
26
|
-
this.collectionTag = "_collection";
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
paginate(Model, resource="") {
|
|
30
|
-
const model = Model.instance || Model;
|
|
31
|
-
const DEFAULT_PAGINATION = {limit : 15, offset: 0}
|
|
32
|
-
var pagination = {limit : 15, offset: 0}
|
|
33
|
-
var response = null;
|
|
34
|
-
var resource = resource;
|
|
35
|
-
|
|
36
|
-
const using = (options, resp) => {
|
|
37
|
-
response = resp;
|
|
38
|
-
var limit = DEFAULT_PAGINATION.limit;
|
|
39
|
-
var offset = DEFAULT_PAGINATION.offset;
|
|
40
|
-
|
|
41
|
-
if (options && options[this.paginateIn.size]) {
|
|
42
|
-
limit = parseInt(options[this.paginateIn.size]);
|
|
43
|
-
}
|
|
44
|
-
if (options && options[this.paginateIn.index]) {
|
|
45
|
-
offset = parseInt(options[this.paginateIn.index]);
|
|
46
|
-
}
|
|
47
|
-
if (!Number.isInteger(limit) || limit < 1) {
|
|
48
|
-
limit = 1;
|
|
49
|
-
}
|
|
50
|
-
if (!Number.isInteger(offset) || offset < 0) {
|
|
51
|
-
offset = 0;
|
|
52
|
-
}
|
|
53
|
-
if (!this.zeroBasedOffset) {
|
|
54
|
-
offset = offset <= 1 ? 0 : offset - 1;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
pagination.limit = limit;
|
|
58
|
-
pagination.offset = offset;
|
|
59
|
-
return model;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const paginate = (options) => {
|
|
63
|
-
if (!options) {
|
|
64
|
-
options = {};
|
|
65
|
-
}
|
|
66
|
-
options.limit = pagination.limit;
|
|
67
|
-
options.offset = pagination.limit * pagination.offset;
|
|
68
|
-
|
|
69
|
-
return new Promise((resolve, reject) => {
|
|
70
|
-
model.findAndCountAll(options)
|
|
71
|
-
.then(r => {
|
|
72
|
-
var paginationData = getPaginationData(r);
|
|
73
|
-
if (response) {
|
|
74
|
-
response.set(this.paginationHeader, JSON.stringify(paginationData));
|
|
75
|
-
}
|
|
76
|
-
var data = {};
|
|
77
|
-
if (this.headersOnly) {
|
|
78
|
-
data = r.rows
|
|
79
|
-
} else {
|
|
80
|
-
data[this.paginationTag] = addLinks(paginationData);
|
|
81
|
-
data[this.collectionTag] = r.rows;
|
|
82
|
-
}
|
|
83
|
-
resolve(data);
|
|
84
|
-
}).catch(e => reject(e));
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const addLinks = (data) => {
|
|
89
|
-
var linksKey = null;
|
|
90
|
-
if (this.paginateOut.links === true) {
|
|
91
|
-
linksKey = "links"
|
|
92
|
-
} else if (this.paginateOut.links) {
|
|
93
|
-
linksKey = this.paginateOut.links;
|
|
94
|
-
}
|
|
95
|
-
if (data && linksKey && !data[this.paginateOut["out_of_bounds"]]) {
|
|
96
|
-
var links = {}
|
|
97
|
-
var firstPageIndex = this.zeroBasedOffset ? 0 : 1;
|
|
98
|
-
var lastPageIndex = this.zeroBasedOffset ? data[this.paginateOut["total_pages"]] - 1 : data[this.paginateOut["total_pages"]];
|
|
99
|
-
links[this.paginateOut["first_page"]] = `${resource}?${this.paginateIn["index"]}=${firstPageIndex}&${this.paginateIn["size"]}=${data[this.paginateOut["page_size"]]}`;
|
|
100
|
-
links[this.paginateOut["last_page"]] = `${resource}?${this.paginateIn["index"]}=${lastPageIndex}&${this.paginateIn["size"]}=${data[this.paginateOut["page_size"]]}`;
|
|
101
|
-
if (!data[this.paginateOut["first_page"]]) {
|
|
102
|
-
links[this.paginateOut["previous_page"]] =
|
|
103
|
-
`${resource}?${this.paginateIn["index"]}=${data[this.paginateOut["previous_page"]]}&${this.paginateIn["size"]}=${data[this.paginateOut["page_size"]]}`;
|
|
104
|
-
}
|
|
105
|
-
if (!data[this.paginateOut["last_page"]]) {
|
|
106
|
-
links[this.paginateOut["next_page"]] =
|
|
107
|
-
`${resource}?${this.paginateIn["index"]}=${data[this.paginateOut["next_page"]]}&${this.paginateIn["size"]}=${data[this.paginateOut["page_size"]]}`;
|
|
108
|
-
}
|
|
109
|
-
data[linksKey] = links;
|
|
110
|
-
}
|
|
111
|
-
return data;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
const getPaginationData = (result) => {
|
|
115
|
-
var currentPage = this.zeroBasedOffset ? pagination.offset : pagination.offset + 1;
|
|
116
|
-
var outOfBounds = result.rows.length === 0;
|
|
117
|
-
|
|
118
|
-
// For queries with aggregation (Group By, Count), sequelize findAndCountAll returns an array of objects instead of just an integer
|
|
119
|
-
// To avoid implementing a custom findAndCountAll, we just use the array's Length
|
|
120
|
-
if (Array.isArray(result.count)) {
|
|
121
|
-
result.count = result.count.length;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
var totalPages = Math.ceil(result.count / pagination.limit);
|
|
125
|
-
var data = {};
|
|
126
|
-
data[this.paginateOut["current_page"]] = currentPage;
|
|
127
|
-
data[this.paginateOut["first_page"]] = outOfBounds ? false : pagination.offset === 0;
|
|
128
|
-
data[this.paginateOut["last_page"]] = outOfBounds ? false : (pagination.offset * pagination.limit) + pagination.limit >= result.count;
|
|
129
|
-
data[this.paginateOut["page_size"]] = pagination.limit;
|
|
130
|
-
data[this.paginateOut["total_pages"]] = totalPages;
|
|
131
|
-
data[this.paginateOut["total_size"]] = result.count;
|
|
132
|
-
data[this.paginateOut["out_of_bounds"]] = outOfBounds;
|
|
133
|
-
if (!outOfBounds) {
|
|
134
|
-
if ((this.zeroBasedOffset && currentPage > 0) || (!this.zeroBasedOffset && currentPage > 1)) {
|
|
135
|
-
data[this.paginateOut["previous_page"]] = currentPage - 1;
|
|
136
|
-
}
|
|
137
|
-
if ((this.zeroBasedOffset && currentPage + 1 < totalPages) || (!this.zeroBasedOffset && currentPage < totalPages)) {
|
|
138
|
-
data[this.paginateOut["next_page"]] = currentPage + 1;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return data;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
model.using = using;
|
|
145
|
-
model.paginate = paginate;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
configure(options) {
|
|
149
|
-
// Parse the object options
|
|
150
|
-
if (options.paginateIn) {
|
|
151
|
-
var x = options.paginateIn;
|
|
152
|
-
for (var key in this.paginateIn) {
|
|
153
|
-
if (this.paginateIn.hasOwnProperty(key) && x.hasOwnProperty(key)) {
|
|
154
|
-
this.paginateIn[key] = x[key];
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
if (options.paginateOut) {
|
|
159
|
-
var x = options.paginateOut;
|
|
160
|
-
for (var key in this.paginateOut) {
|
|
161
|
-
if (this.paginateOut.hasOwnProperty(key) && x.hasOwnProperty(key)) {
|
|
162
|
-
this.paginateOut[key] = x[key];
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
// Parse the simple options
|
|
167
|
-
for(var key in this) {
|
|
168
|
-
if (!["paginateIn", "paginateOut"].includes(key)) {
|
|
169
|
-
if (this.hasOwnProperty(key) && options.hasOwnProperty(key)) {
|
|
170
|
-
this[key] = options[key];
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const sqlPaginator = new SequelizePaginator();
|
|
178
|
-
export default sqlPaginator;
|
package/paper-trail/README.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# Sequelize Paper Trail
|
|
2
|
-
|
|
3
|
-
A paper trail/sequelize hook plugin. This plugin has been modified to use the node14 CLS API called AsyncLocalStorage as well as fix some of the postgres related bugs. We have kept our own implemnetation and various changes were needed to support the express framework and pushing this to the public would hinder the general usability of this library for all.
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
In your database setup, setup your models and then attach the paperTrail to them. Many default options need to be changed to support underscore notation and the use of Account instead of User as the default table, thus suggestions options for TWS projects are shown below.
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
import { paperTrail } from "@sera4/essentia"
|
|
11
|
-
import Sequelize from 'sequelize';
|
|
12
|
-
|
|
13
|
-
...
|
|
14
|
-
|
|
15
|
-
const sequelize = new Sequelize(...);
|
|
16
|
-
|
|
17
|
-
PaperTrail.init(sequelize, Sequelize, { UUID: true,
|
|
18
|
-
underscored: true, enableMigration: true, underscoredAttributes: true,
|
|
19
|
-
debug: false, userModel: 'Account', enableCompression: true });
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
const db = {};
|
|
23
|
-
// for any model you want enabled
|
|
24
|
-
db["Tenant"] = TenantModel(sequelize, Sequelize);
|
|
25
|
-
|
|
26
|
-
db.PaperTrail = PaperTrail.init(sequelize, Sequelize, { UUID: true, underscored: true,
|
|
27
|
-
enableMigration: true, underscoredAttributes: true, continuationKey: "accountId",
|
|
28
|
-
debug: false, userModel: 'Account', userModelAttribute: 'account_id',
|
|
29
|
-
enableCompression: true });
|
|
30
|
-
|
|
31
|
-
// sending in DB will allow you to access this using db['Revision'] later.
|
|
32
|
-
db.PaperTrail.defineModels(db);
|
|
33
|
-
|
|
34
|
-
.. and for any model that needs a papertrail, call hasPaperTrail() on it ..
|
|
35
|
-
db["Tenant"].hasPaperTrail();
|
|
36
|
-
db["TenantLicense"].hasPaperTrail();
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
and similarly, to use the automatic ALS (asyncLocalStorage) for automatic setting of the account/userID - add this into your middleware
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
import db from "../database/models/index.js";
|
|
43
|
-
|
|
44
|
-
let alsEnabled = db.PaperTrail.alsEnabled();
|
|
45
|
-
|
|
46
|
-
const localStorageMiddleware = async (req, res, next) => {
|
|
47
|
-
await asyncLocalStorage.run(new Map(), () => {
|
|
48
|
-
if (!alsEnabled) {
|
|
49
|
-
alsEnabled = true;
|
|
50
|
-
db.PaperTrail.setupALS(asyncLocalStorage);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
next();
|
|
54
|
-
});
|
|
55
|
-
};
|
|
56
|
-
```
|
|
57
|
-
as this will ensure that the ALS context is initialized AFTER the first `run()` invocation.
|
|
58
|
-
|
|
59
|
-
`Please note`: For automatic accountId fetching, it is imperitive that you add
|
|
60
|
-
|
|
61
|
-
```
|
|
62
|
-
asyncLocalStorage.getStore().set("accountId", accountId);
|
|
63
|
-
```
|
|
64
|
-
somewhere into your express middleware so the database hooks can pickup the accountId when changes are made.
|
|
65
|
-
|
|
66
|
-
## History
|
|
67
|
-
|
|
68
|
-
This is a private fork/implementation of https://github.com/nielsgl/sequelize-paper-trail which has been released under MIT license. This was privitized due to the number of commented out items/untested in their project as well as the change from CLS (continuation-local-storage) which is experimental to the supported AsyncLocalStorage which was stabilized in Node 14 as the CLS API 101.
|
package/paper-trail/helpers.js
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
import pkg from 'deep-diff';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
|
|
4
|
-
const { diff } = pkg;
|
|
5
|
-
const capitalizeFirstLetter = string =>
|
|
6
|
-
string.charAt(0).toUpperCase() + string.slice(1);
|
|
7
|
-
|
|
8
|
-
const toUnderscored = obj => {
|
|
9
|
-
_.forEach(obj, (k, v) => {
|
|
10
|
-
obj[k] = v
|
|
11
|
-
.replace(/(?:^|\.?)([A-Z])/g, (x, y) => `_${y.toLowerCase()}`)
|
|
12
|
-
.replace(/^_/, '');
|
|
13
|
-
});
|
|
14
|
-
return obj;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
const calcDelta = (current, next, exclude, strict, DEBUG = false) => {
|
|
18
|
-
if (DEBUG) {
|
|
19
|
-
console.log('current', current);
|
|
20
|
-
console.log('next', next);
|
|
21
|
-
console.log('exclude', exclude);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const di = diff(current, next);
|
|
25
|
-
|
|
26
|
-
if (DEBUG) {
|
|
27
|
-
console.log('di', di);
|
|
28
|
-
|
|
29
|
-
let diffs2 = [];
|
|
30
|
-
if (di) {
|
|
31
|
-
diffs2 = di.map(i =>
|
|
32
|
-
JSON.parse(JSON.stringify(i).replace('"__data",', '')),
|
|
33
|
-
);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
console.log('diffs2', diffs2);
|
|
37
|
-
|
|
38
|
-
console.log(
|
|
39
|
-
'filter1',
|
|
40
|
-
diffs2.filter(i => i.path.join(',').indexOf('_') === -1),
|
|
41
|
-
);
|
|
42
|
-
|
|
43
|
-
console.log(
|
|
44
|
-
'filter2',
|
|
45
|
-
diffs2.filter(i => exclude.every(x => i.path.indexOf(x) === -1)),
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
let diffs = [];
|
|
50
|
-
if (di) {
|
|
51
|
-
diffs = di
|
|
52
|
-
.map(i => JSON.parse(JSON.stringify(i).replace('"__data",', '')))
|
|
53
|
-
.filter(i => {
|
|
54
|
-
if (!strict && i.kind === 'E') {
|
|
55
|
-
// eslint-disable-next-line eqeqeq
|
|
56
|
-
if (i.lhs != i.rhs) return i;
|
|
57
|
-
} else return i;
|
|
58
|
-
return false;
|
|
59
|
-
})
|
|
60
|
-
.filter(i => exclude.every(x => i.path.indexOf(x) === -1));
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (diffs.length > 0) {
|
|
64
|
-
return diffs;
|
|
65
|
-
}
|
|
66
|
-
return null;
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const diffToString = val => {
|
|
70
|
-
if (typeof val === 'undefined' || val === null)
|
|
71
|
-
return '';
|
|
72
|
-
|
|
73
|
-
if (val === true)
|
|
74
|
-
return '1';
|
|
75
|
-
|
|
76
|
-
if (val === false)
|
|
77
|
-
return '0';
|
|
78
|
-
|
|
79
|
-
if (typeof val === 'string')
|
|
80
|
-
return val;
|
|
81
|
-
|
|
82
|
-
if (!Number.isNaN(Number(val)))
|
|
83
|
-
return `${String(val)}`;
|
|
84
|
-
|
|
85
|
-
if ((typeof val === 'undefined' ? 'undefined' : typeof val) === 'object')
|
|
86
|
-
return `${JSON.stringify(val)}`;
|
|
87
|
-
|
|
88
|
-
if (Array.isArray(val))
|
|
89
|
-
return `${JSON.stringify(val)}`;
|
|
90
|
-
|
|
91
|
-
return '';
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
export default {
|
|
95
|
-
capitalizeFirstLetter,
|
|
96
|
-
toUnderscored,
|
|
97
|
-
calcDelta,
|
|
98
|
-
diffToString
|
|
99
|
-
};
|