express-ext 0.2.5 → 0.2.6
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/lib/resources.js +17 -20
- package/lib/search.js +100 -50
- package/package.json +6 -2
- package/src/resources.ts +10 -2
- package/src/search.ts +100 -44
package/lib/resources.js
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports,
|
|
3
|
-
var fs = require(
|
|
4
|
-
var http = require(
|
|
5
|
-
var https = require(
|
|
1
|
+
'use strict';
|
|
2
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
|
+
var fs = require('fs');
|
|
4
|
+
var http = require('http');
|
|
5
|
+
var https = require('https');
|
|
6
6
|
var resources = (function () {
|
|
7
|
-
function resources() {
|
|
8
|
-
|
|
7
|
+
function resources() {}
|
|
8
|
+
resources.page = 'page';
|
|
9
|
+
resources.sort = 'sort';
|
|
10
|
+
resources.partial = 'partial';
|
|
9
11
|
resources.encoding = 'utf-8';
|
|
10
12
|
return resources;
|
|
11
|
-
}()
|
|
13
|
+
})();
|
|
12
14
|
exports.resources = resources;
|
|
13
15
|
var TypeChecker = (function () {
|
|
14
16
|
function TypeChecker(attributes, allowUndefined) {
|
|
@@ -20,19 +22,17 @@ var TypeChecker = (function () {
|
|
|
20
22
|
var obj = req.body;
|
|
21
23
|
if (!obj || obj === '') {
|
|
22
24
|
res.status(400).end('The request body cannot be empty');
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
+
} else {
|
|
25
26
|
var errors = resources.check(obj, this.attributes, this.allowUndefined);
|
|
26
27
|
if (errors.length > 0) {
|
|
27
28
|
res.status(400).json(errors).end();
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
29
|
+
} else {
|
|
30
30
|
next();
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
};
|
|
34
34
|
return TypeChecker;
|
|
35
|
-
}()
|
|
35
|
+
})();
|
|
36
36
|
exports.TypeChecker = TypeChecker;
|
|
37
37
|
function check(attributes, allowUndefined) {
|
|
38
38
|
var x = new TypeChecker(attributes, allowUndefined);
|
|
@@ -64,23 +64,20 @@ function start(a, s) {
|
|
|
64
64
|
https.createServer(s.options, a).listen(s.port, function () {
|
|
65
65
|
console.log('Use https and start server at port ' + s.port);
|
|
66
66
|
});
|
|
67
|
-
}
|
|
68
|
-
else if (s.key && s.cert && s.key.length > 0 && s.cert.length > 0) {
|
|
67
|
+
} else if (s.key && s.cert && s.key.length > 0 && s.cert.length > 0) {
|
|
69
68
|
var options = {
|
|
70
69
|
key: fs.readFileSync(s.key),
|
|
71
|
-
cert: fs.readFileSync(s.cert)
|
|
70
|
+
cert: fs.readFileSync(s.cert),
|
|
72
71
|
};
|
|
73
72
|
https.createServer(options, a).listen(s.port, function () {
|
|
74
73
|
console.log('Use https and start server at port ' + s.port);
|
|
75
74
|
});
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
75
|
+
} else {
|
|
78
76
|
http.createServer(a).listen(s.port, function () {
|
|
79
77
|
console.log('Start server at port ' + s.port);
|
|
80
78
|
});
|
|
81
79
|
}
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
80
|
+
} else {
|
|
84
81
|
http.createServer(a).listen(s.port, function () {
|
|
85
82
|
console.log('Start server at port ' + s.port);
|
|
86
83
|
});
|
package/lib/search.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
3
3
|
var http_1 = require('./http');
|
|
4
|
+
var resources_1 = require('./resources');
|
|
5
|
+
var et = '';
|
|
4
6
|
function getOffset(limit, page) {
|
|
5
7
|
var offset = limit * (page - 1);
|
|
6
8
|
return offset < 0 ? 0 : offset;
|
|
@@ -32,68 +34,116 @@ function buildPages(pageSize, total) {
|
|
|
32
34
|
return arr;
|
|
33
35
|
}
|
|
34
36
|
exports.buildPages = buildPages;
|
|
35
|
-
function
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
function hasSearch(req) {
|
|
38
|
+
return req.url.indexOf('?') >= 0;
|
|
39
|
+
}
|
|
40
|
+
exports.hasSearch = hasSearch;
|
|
41
|
+
function getSearch(url) {
|
|
42
|
+
var i = url.indexOf('?');
|
|
43
|
+
return i < 0 ? et : url.substring(i + 1);
|
|
44
|
+
}
|
|
45
|
+
exports.getSearch = getSearch;
|
|
46
|
+
function getField(search, fieldName) {
|
|
47
|
+
var i = search.indexOf(fieldName + '=');
|
|
38
48
|
if (i < 0) {
|
|
39
49
|
return '';
|
|
40
50
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return query;
|
|
49
|
-
}
|
|
50
|
-
var partialTrue = partialIsTrue && partialIsTrue.length > 0 ? partialIsTrue : PartialTrue;
|
|
51
|
-
var p1 = '&' + partialTrue;
|
|
52
|
-
var q1 = query.indexOf(p1);
|
|
53
|
-
if (q1 >= 0) {
|
|
54
|
-
query = query.substring(0, q1) + query.substring(q1 + partialTrue.length + 2);
|
|
55
|
-
} else {
|
|
56
|
-
var p2 = partialTrue + '&';
|
|
57
|
-
var q2 = query.indexOf(p2);
|
|
58
|
-
if (q2 >= 0) {
|
|
59
|
-
query = query.substring(0, q1) + query.substring(q1 + partialTrue.length + 2);
|
|
51
|
+
if (i > 0) {
|
|
52
|
+
if (search.substring(i - 1, 1) != '&') {
|
|
53
|
+
i = search.indexOf('&' + fieldName + '=');
|
|
54
|
+
if (i < 0) {
|
|
55
|
+
return search;
|
|
56
|
+
}
|
|
57
|
+
i = i + 1;
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
|
-
var
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
60
|
+
var j = search.indexOf('&', i + fieldName.length);
|
|
61
|
+
return j >= 0 ? search.substring(i, j) : search.substring(i);
|
|
62
|
+
}
|
|
63
|
+
exports.getField = getField;
|
|
64
|
+
function removeField(search, fieldName) {
|
|
65
|
+
var i = search.indexOf(fieldName + '=');
|
|
66
|
+
if (i < 0) {
|
|
67
|
+
return search;
|
|
68
|
+
}
|
|
69
|
+
if (i > 0) {
|
|
70
|
+
if (search.substring(i - 1, 1) != '&') {
|
|
71
|
+
i = search.indexOf('&' + fieldName + '=');
|
|
72
|
+
if (i < 0) {
|
|
73
|
+
return search;
|
|
74
|
+
}
|
|
75
|
+
i = i + 1;
|
|
73
76
|
}
|
|
74
|
-
return query.replace(pageQuery, '');
|
|
75
77
|
}
|
|
78
|
+
var j = search.indexOf('&', i + fieldName.length);
|
|
79
|
+
return j >= 0 ? search.substring(0, i) + search.substring(j + 1) : search.substring(0, i - 1);
|
|
76
80
|
}
|
|
77
|
-
exports.
|
|
78
|
-
function
|
|
79
|
-
|
|
81
|
+
exports.removeField = removeField;
|
|
82
|
+
function removePage(search) {
|
|
83
|
+
search = removeField(search, resources_1.resources.page);
|
|
84
|
+
search = removeField(search, resources_1.resources.partial);
|
|
85
|
+
return search;
|
|
80
86
|
}
|
|
81
|
-
exports.
|
|
82
|
-
function
|
|
83
|
-
var
|
|
84
|
-
return
|
|
87
|
+
exports.removePage = removePage;
|
|
88
|
+
function buildPageSearch(search) {
|
|
89
|
+
var sr = removePage(search);
|
|
90
|
+
return sr.length == 0 ? sr : '&' + sr;
|
|
91
|
+
}
|
|
92
|
+
exports.buildPageSearch = buildPageSearch;
|
|
93
|
+
function buildPageSearchFromUrl(url) {
|
|
94
|
+
var search = getSearch(url);
|
|
95
|
+
return buildPageSearch(search);
|
|
96
|
+
}
|
|
97
|
+
exports.buildPageSearchFromUrl = buildPageSearchFromUrl;
|
|
98
|
+
function removeSort(search) {
|
|
99
|
+
search = removeField(search, resources_1.resources.sort);
|
|
100
|
+
search = removeField(search, resources_1.resources.partial);
|
|
101
|
+
return search;
|
|
102
|
+
}
|
|
103
|
+
exports.removeSort = removeSort;
|
|
104
|
+
function getSortString(field, sort) {
|
|
105
|
+
if (field === sort.field) {
|
|
106
|
+
return sort.type === '-' ? field : '-' + field;
|
|
107
|
+
}
|
|
108
|
+
return field;
|
|
85
109
|
}
|
|
86
|
-
exports.
|
|
87
|
-
function
|
|
88
|
-
|
|
89
|
-
|
|
110
|
+
exports.getSortString = getSortString;
|
|
111
|
+
function buildSort(s) {
|
|
112
|
+
if (!s || s.indexOf(',') >= 0) {
|
|
113
|
+
return {};
|
|
114
|
+
}
|
|
115
|
+
if (s.startsWith('-')) {
|
|
116
|
+
return { field: s.substring(1), type: '-' };
|
|
117
|
+
} else {
|
|
118
|
+
return { field: s.startsWith('+') ? s.substring(1) : s, type: '+' };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.buildSort = buildSort;
|
|
122
|
+
function buildSortFromRequest(req) {
|
|
123
|
+
var s = http_1.query(req, resources_1.resources.sort);
|
|
124
|
+
return buildSort(s);
|
|
125
|
+
}
|
|
126
|
+
exports.buildSortFromRequest = buildSortFromRequest;
|
|
127
|
+
function renderSort(field, sort) {
|
|
128
|
+
if (field === sort.field) {
|
|
129
|
+
return sort.type === '-' ? "<i class='sort-down'></i>" : "<i class='sort-up'></i>";
|
|
130
|
+
}
|
|
131
|
+
return et;
|
|
90
132
|
}
|
|
91
|
-
exports.
|
|
92
|
-
function
|
|
93
|
-
|
|
94
|
-
|
|
133
|
+
exports.renderSort = renderSort;
|
|
134
|
+
function buildSortSearch(search, fields, sort) {
|
|
135
|
+
search = removeSort(search);
|
|
136
|
+
var sorts = {};
|
|
137
|
+
var prefix = search.length > 0 ? '?' + search + '&' : '?';
|
|
138
|
+
for (var i = 0; i < fields.length; i++) {
|
|
139
|
+
sorts[fields[i]] = {
|
|
140
|
+
url: prefix + resources_1.resources.sort + '=' + getSortString(fields[i], sort),
|
|
141
|
+
tag: renderSort(fields[i], sort),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
return sorts;
|
|
95
145
|
}
|
|
96
|
-
exports.
|
|
146
|
+
exports.buildSortSearch = buildSortSearch;
|
|
97
147
|
function jsonResult(res, result, quick, fields, config) {
|
|
98
148
|
if (quick && fields && fields.length > 0) {
|
|
99
149
|
res.status(200).json(toCsv(fields, result)).end();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "express-ext",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "express-ext",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -25,7 +25,11 @@
|
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
27
|
"express",
|
|
28
|
+
"express-plus",
|
|
29
|
+
"express plus",
|
|
28
30
|
"express-ext",
|
|
29
|
-
"express
|
|
31
|
+
"express ext",
|
|
32
|
+
"express-extension",
|
|
33
|
+
"express extension"
|
|
30
34
|
]
|
|
31
35
|
}
|
package/src/resources.ts
CHANGED
|
@@ -6,6 +6,9 @@ import { Attributes, ErrorMessage } from './metadata';
|
|
|
6
6
|
|
|
7
7
|
// tslint:disable-next-line:class-name
|
|
8
8
|
export class resources {
|
|
9
|
+
static page = 'page';
|
|
10
|
+
static sort = 'sort';
|
|
11
|
+
static partial = 'partial';
|
|
9
12
|
static createValidator?: <T>(attributes: Attributes, allowUndefined?: boolean, max?: number) => Validator<T>;
|
|
10
13
|
static check: (obj: any, attributes: Attributes, allowUndefined?: boolean, patch?: boolean) => ErrorMessage[];
|
|
11
14
|
static encoding?: BufferEncoding = 'utf-8';
|
|
@@ -64,7 +67,12 @@ export interface TemplateNode {
|
|
|
64
67
|
suffix?: string | null;
|
|
65
68
|
prefix?: string | null;
|
|
66
69
|
}
|
|
67
|
-
export function loadTemplates(
|
|
70
|
+
export function loadTemplates(
|
|
71
|
+
ok: boolean | undefined,
|
|
72
|
+
buildTemplates: (streams: string[], correct?: (stream: string) => string) => Map<string, Template>,
|
|
73
|
+
correct?: (stream: string) => string,
|
|
74
|
+
files?: string[],
|
|
75
|
+
): Map<string, Template> | undefined {
|
|
68
76
|
if (!ok) {
|
|
69
77
|
return undefined;
|
|
70
78
|
}
|
|
@@ -97,7 +105,7 @@ export function start(a: Application, s: Server): void {
|
|
|
97
105
|
} else if (s.key && s.cert && s.key.length > 0 && s.cert.length > 0) {
|
|
98
106
|
const options = {
|
|
99
107
|
key: fs.readFileSync(s.key),
|
|
100
|
-
cert: fs.readFileSync(s.cert)
|
|
108
|
+
cert: fs.readFileSync(s.cert),
|
|
101
109
|
};
|
|
102
110
|
https.createServer(options, a).listen(s.port, () => {
|
|
103
111
|
console.log('Use https and start server at port ' + s.port);
|
package/src/search.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { Request, Response } from 'express';
|
|
2
|
-
import { minimizeArray } from './http';
|
|
2
|
+
import { minimizeArray, query } from './http';
|
|
3
3
|
import { Attribute, Attributes } from './metadata';
|
|
4
|
+
import { resources } from './resources';
|
|
5
|
+
|
|
6
|
+
const et = '';
|
|
4
7
|
|
|
5
8
|
export interface Filter {
|
|
6
9
|
fields?: string[];
|
|
@@ -58,61 +61,114 @@ export function buildPages(pageSize?: number, total?: number): number[] {
|
|
|
58
61
|
}
|
|
59
62
|
return arr;
|
|
60
63
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
|
|
65
|
+
export function hasSearch(req: Request): boolean {
|
|
66
|
+
return req.url.indexOf('?') >= 0;
|
|
67
|
+
}
|
|
68
|
+
export function getSearch(url: string): string {
|
|
69
|
+
const i = url.indexOf('?');
|
|
70
|
+
return i < 0 ? et : url.substring(i + 1);
|
|
71
|
+
}
|
|
72
|
+
export function getField(search: string, fieldName: string): string {
|
|
73
|
+
let i = search.indexOf(fieldName + '=');
|
|
64
74
|
if (i < 0) {
|
|
65
75
|
return '';
|
|
66
76
|
}
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
if (i > 0) {
|
|
78
|
+
if (search.substring(i - 1, 1) != '&') {
|
|
79
|
+
i = search.indexOf('&' + fieldName + '=');
|
|
80
|
+
if (i < 0) {
|
|
81
|
+
return search;
|
|
82
|
+
}
|
|
83
|
+
i = i + 1;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const j = search.indexOf('&', i + fieldName.length);
|
|
87
|
+
return j >= 0 ? search.substring(i, j) : search.substring(i);
|
|
69
88
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (
|
|
73
|
-
return
|
|
89
|
+
export function removeField(search: string, fieldName: string): string {
|
|
90
|
+
let i = search.indexOf(fieldName + '=');
|
|
91
|
+
if (i < 0) {
|
|
92
|
+
return search;
|
|
74
93
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
const q2 = query.indexOf(p2);
|
|
83
|
-
if (q2 >= 0) {
|
|
84
|
-
query = query.substring(0, q1) + query.substring(q1 + partialTrue.length + 2);
|
|
94
|
+
if (i > 0) {
|
|
95
|
+
if (search.substring(i - 1, 1) != '&') {
|
|
96
|
+
i = search.indexOf('&' + fieldName + '=');
|
|
97
|
+
if (i < 0) {
|
|
98
|
+
return search;
|
|
99
|
+
}
|
|
100
|
+
i = i + 1;
|
|
85
101
|
}
|
|
86
102
|
}
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
103
|
+
const j = search.indexOf('&', i + fieldName.length);
|
|
104
|
+
return j >= 0 ? search.substring(0, i) + search.substring(j + 1) : search.substring(0, i - 1);
|
|
105
|
+
}
|
|
106
|
+
export function removePage(search: string): string {
|
|
107
|
+
search = removeField(search, resources.page);
|
|
108
|
+
search = removeField(search, resources.partial);
|
|
109
|
+
return search;
|
|
110
|
+
}
|
|
111
|
+
export function buildPageSearch(search: string): string {
|
|
112
|
+
const sr = removePage(search);
|
|
113
|
+
return sr.length == 0 ? sr : '&' + sr;
|
|
114
|
+
}
|
|
115
|
+
export function buildPageSearchFromUrl(url: string): string {
|
|
116
|
+
const search = getSearch(url);
|
|
117
|
+
return buildPageSearch(search);
|
|
118
|
+
}
|
|
119
|
+
export function removeSort(search: string): string {
|
|
120
|
+
search = removeField(search, resources.sort);
|
|
121
|
+
search = removeField(search, resources.partial);
|
|
122
|
+
return search;
|
|
123
|
+
}
|
|
124
|
+
export interface Sort {
|
|
125
|
+
field?: string;
|
|
126
|
+
type?: string;
|
|
127
|
+
}
|
|
128
|
+
export interface SortType {
|
|
129
|
+
url: string;
|
|
130
|
+
tag: string;
|
|
131
|
+
}
|
|
132
|
+
export interface SortMap {
|
|
133
|
+
[key: string]: SortType;
|
|
134
|
+
}
|
|
135
|
+
export function getSortString(field: string, sort: Sort): string {
|
|
136
|
+
if (field === sort.field) {
|
|
137
|
+
return sort.type === '-' ? field : '-' + field;
|
|
100
138
|
}
|
|
139
|
+
return field;
|
|
101
140
|
}
|
|
102
|
-
export function
|
|
103
|
-
|
|
141
|
+
export function buildSort(s?: string): Sort {
|
|
142
|
+
if (!s || s.indexOf(',') >= 0) {
|
|
143
|
+
return {} as Sort;
|
|
144
|
+
}
|
|
145
|
+
if (s.startsWith('-')) {
|
|
146
|
+
return { field: s.substring(1), type: '-' };
|
|
147
|
+
} else {
|
|
148
|
+
return { field: s.startsWith('+') ? s.substring(1) : s, type: '+' };
|
|
149
|
+
}
|
|
104
150
|
}
|
|
105
|
-
export function
|
|
106
|
-
const
|
|
107
|
-
return
|
|
151
|
+
export function buildSortFromRequest(req: Request): Sort {
|
|
152
|
+
const s = query(req, resources.sort);
|
|
153
|
+
return buildSort(s);
|
|
108
154
|
}
|
|
109
|
-
export function
|
|
110
|
-
|
|
111
|
-
|
|
155
|
+
export function renderSort(field: string, sort: Sort): string {
|
|
156
|
+
if (field === sort.field) {
|
|
157
|
+
return sort.type === '-' ? "<i class='sort-down'></i>" : "<i class='sort-up'></i>";
|
|
158
|
+
}
|
|
159
|
+
return et;
|
|
112
160
|
}
|
|
113
|
-
export function
|
|
114
|
-
|
|
115
|
-
|
|
161
|
+
export function buildSortSearch(search: string, fields: string[], sort: Sort): SortMap {
|
|
162
|
+
search = removeSort(search);
|
|
163
|
+
let sorts: SortMap = {};
|
|
164
|
+
const prefix = search.length > 0 ? '?' + search + '&' : '?';
|
|
165
|
+
for (let i = 0; i < fields.length; i++) {
|
|
166
|
+
sorts[fields[i]] = {
|
|
167
|
+
url: prefix + resources.sort + '=' + getSortString(fields[i], sort),
|
|
168
|
+
tag: renderSort(fields[i], sort),
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return sorts;
|
|
116
172
|
}
|
|
117
173
|
|
|
118
174
|
export function jsonResult<T>(res: Response, result: SearchResult<T>, quick?: boolean, fields?: string[], config?: SearchConfig): void {
|