@akc42/server-utils 1.4.1 → 2.0.0
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 +18 -16
- package/debug.js +68 -0
- package/logger.js +54 -64
- package/package.json +7 -5
- package/responder.js +91 -92
- package/utils.js +35 -5
- package/version.js +62 -64
package/README.md
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
# server-utils
|
|
2
2
|
A Set of Utilities that I generally use on SPA projects for the server side of the project
|
|
3
3
|
|
|
4
|
-
It consists of 4 separate packages.
|
|
4
|
+
It consists of 4 separate packages 6 entry points.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
variables to locate the database DATABASE_DB_DIR and DATABASE_DB are the directory and filename respectively of the sqlite3
|
|
8
|
-
database. It also used DATABASE_DB_BUSY for the busy timeout. DATABASE_DB_DIR can either be an absolute value, or relative
|
|
9
|
-
from the project root (see npm module `app-root-path`). If the database file does not exist, it attempt to create it from the script
|
|
10
|
-
read from file named by DATABASE_INIT_FILE. The path can be relative to project root or an absolute value.
|
|
6
|
+
The packages are:-
|
|
11
7
|
|
|
12
8
|
`logger` provides a logging service for the app. It is controlled by three environment variables LOG_NONE prevents it from logging anything.
|
|
13
9
|
This is designed to be used during testing of the server side of the app so that nothing is logged. LOG_NO_DATE omits the date and time from
|
|
@@ -23,22 +19,28 @@ with `new Responder(response);` and the resultant object has three methods;
|
|
|
23
19
|
promise which resolves when any blockage is cleared.
|
|
24
20
|
- `end` signifies the end of stream. Any attempt to call the other two methods after this has been called will throw an error.
|
|
25
21
|
|
|
26
|
-
`
|
|
22
|
+
`Version` provides an async function with a single parameter, the path to you
|
|
23
|
+
project root) that ultimately resolves to an object which has two
|
|
27
24
|
fields. `version` which is the version string and `year` which is the copyright
|
|
28
|
-
year.
|
|
29
|
-
instructions for that module if it doesn't give the right result for you. The
|
|
30
|
-
project root is where either the `.git` directory exists (in which case
|
|
25
|
+
year. The project root is where either the `.git` directory exists (in which case
|
|
31
26
|
`version` will ask git for the version and calculate the copyright year from the
|
|
32
27
|
last git log entry) or where a `release.info` file is sitting (in which case
|
|
33
28
|
`version` will expect that to contain a version string and have a modification
|
|
34
29
|
time from which the copyright year can be derived). If neither of those
|
|
35
30
|
possibilities exist it will try to get the version info from the `package.json` file.
|
|
36
31
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
32
|
+
`Debug` module provides three entry points, `Debug`, `dumpDebugCache` and
|
|
33
|
+
`setDebugConfig`. The `Debug` entry point is the main one, the user calls this a
|
|
34
|
+
string representing the topic for the debug stream and we return a function that
|
|
35
|
+
will allow him to call with string arguments which will be concatenated (with a
|
|
36
|
+
space separator) to form a debug string. If `setDebugConfig` has already been
|
|
37
|
+
called to specify that the topic is to be logged (by providing a colon
|
|
38
|
+
separated list of topics to be logged), then this is output. Regardless, all
|
|
39
|
+
debug calls are stored in a 50 line cache, and will be output (newest first) on a call
|
|
40
|
+
to `dumpDebugCache`
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
Thise are installed with as many of few of the items that you want like so:-
|
|
42
44
|
```
|
|
43
|
-
|
|
45
|
+
import {logger,Responder,Debug} from '@akc42/server-utils';
|
|
44
46
|
```
|
package/debug.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
@licence
|
|
3
|
+
Copyright (c) 2021 Alan Chandler, all rights reserved
|
|
4
|
+
|
|
5
|
+
This file is part of Server Utils.
|
|
6
|
+
|
|
7
|
+
Server Utils is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
Server Utils is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with Server Utils. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
import chalk from 'chalk';
|
|
22
|
+
let config = '';
|
|
23
|
+
let cache = [];
|
|
24
|
+
|
|
25
|
+
export function Debug (topic) {
|
|
26
|
+
const t = topic;
|
|
27
|
+
let timestamp = new Date().getTime();
|
|
28
|
+
return function (...args) {
|
|
29
|
+
let enabled = false;
|
|
30
|
+
if (config) {
|
|
31
|
+
const topics = config.split(':');
|
|
32
|
+
if (topics.includes(t)) enabled = true;
|
|
33
|
+
}
|
|
34
|
+
const now = new Date().getTime();
|
|
35
|
+
const gap = now - timestamp;
|
|
36
|
+
timestamp = now;
|
|
37
|
+
const message = args.reduce((cum, arg) => {
|
|
38
|
+
return `${cum} ${arg}`.trim();
|
|
39
|
+
}, '');
|
|
40
|
+
const output = `${chalk.greenBright(topic)} ${chalk.cyan(message)} ${chalk.whiteBright(`(${gap}ms)`)}`
|
|
41
|
+
if (enabled) {
|
|
42
|
+
console.log(output);
|
|
43
|
+
}
|
|
44
|
+
cache.push(output);
|
|
45
|
+
cache.splice(0,cache.length - 50); //prevent it getting too big
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export function dumpDebugCache() {
|
|
49
|
+
const output = chalk.white.bgBlue('Above are all the debug calls (most recent first) which lead up to, and then followed on from, the error above');
|
|
50
|
+
cache.reverse();
|
|
51
|
+
for(const line of cache) {
|
|
52
|
+
console.log(line);
|
|
53
|
+
}
|
|
54
|
+
cache.reverse();
|
|
55
|
+
console.log(output);
|
|
56
|
+
};
|
|
57
|
+
export function setDebugConfig(con) {
|
|
58
|
+
if (con !== config) {
|
|
59
|
+
config = con;
|
|
60
|
+
const output = `${chalk.greenBright('debug server config')} ${chalk.redBright(`new server config "${config}"`)}`
|
|
61
|
+
console.log(output);
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
package/logger.js
CHANGED
|
@@ -1,86 +1,76 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@licence
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2021 Alan Chandler, all rights reserved
|
|
4
4
|
|
|
5
|
-
This file is part of
|
|
5
|
+
This file is part of Server Utils.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Server Utils is free software: you can redistribute it and/or modify
|
|
8
8
|
it under the terms of the GNU General Public License as published by
|
|
9
9
|
the Free Software Foundation, either version 3 of the License, or
|
|
10
10
|
(at your option) any later version.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Server Utils is distributed in the hope that it will be useful,
|
|
13
13
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
14
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
15
|
GNU General Public License for more details.
|
|
16
16
|
|
|
17
17
|
You should have received a copy of the GNU General Public License
|
|
18
|
-
along with
|
|
18
|
+
along with Server Utils. If not, see <http://www.gnu.org/licenses/>.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import chalk from 'chalk';
|
|
22
|
+
import { isIP } from 'net';
|
|
21
23
|
|
|
24
|
+
const COLOURS = {
|
|
25
|
+
app: chalk.rgb(255, 136, 0).bold, //orange,
|
|
26
|
+
db: chalk.greenBright,
|
|
27
|
+
api: chalk.magentaBright,
|
|
28
|
+
client: chalk.redBright,
|
|
29
|
+
log: chalk.yellowBright,
|
|
30
|
+
mail: chalk.cyanBright,
|
|
31
|
+
//error like have backGround colouring
|
|
32
|
+
auth: chalk.black.bgCyan,
|
|
33
|
+
err: chalk.white.bgBlue,
|
|
34
|
+
error: chalk.white.bgRed
|
|
22
35
|
|
|
36
|
+
};
|
|
37
|
+
let cyrb53;
|
|
38
|
+
if (process.env.LOG_NO_ENCODE) {
|
|
39
|
+
cyrb53 = (str, seed = 0) => {return str;};
|
|
40
|
+
} else {
|
|
41
|
+
cyrb53 = (str, seed = 0) => {
|
|
42
|
+
let h1 = 0xdeadbeef ^ seed, h2 = 0x41c6ce57 ^ seed;
|
|
43
|
+
for (let i = 0, ch; i < str.length; i++) {
|
|
44
|
+
ch = str.charCodeAt(i);
|
|
45
|
+
h1 = Math.imul(h1 ^ ch, 2654435761);
|
|
46
|
+
h2 = Math.imul(h2 ^ ch, 1597334677);
|
|
47
|
+
}
|
|
48
|
+
h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909);
|
|
49
|
+
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
50
|
+
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
|
51
|
+
};
|
|
52
|
+
}
|
|
23
53
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909);
|
|
43
|
-
return 4294967296 * (2097151 & h2) + (h1 >>> 0);
|
|
44
|
-
};
|
|
54
|
+
export default async function logger(ip,level, ...messages) {
|
|
55
|
+
if (process.env.LOG_NONE === undefined) {
|
|
56
|
+
let logLine = '';
|
|
57
|
+
if (process.env.LOG_NO_DATE === undefined) logLine += new Date().toISOString() + ': ';
|
|
58
|
+
let message;
|
|
59
|
+
let logcolor;
|
|
60
|
+
if (isIP(ip) === 0 ) {
|
|
61
|
+
logcolor = ip;
|
|
62
|
+
message = level + messages.join(' ');
|
|
63
|
+
} else {
|
|
64
|
+
const client = process.env.LOG_IP_HIDDEN !== undefined ? cyrb53(ip): ip;
|
|
65
|
+
logLine += COLOURS.client(client + ': ');
|
|
66
|
+
logcolor = level
|
|
67
|
+
message = messages.join(' ');
|
|
68
|
+
}
|
|
69
|
+
logLine += COLOURS[logcolor](message);
|
|
70
|
+
//eslint-disable-next-line no-console
|
|
71
|
+
console.log(logLine.trim());
|
|
45
72
|
}
|
|
46
|
-
|
|
47
|
-
const {default: chalk} = await import('chalk');
|
|
48
|
-
accept({
|
|
49
|
-
app: chalk.rgb(255, 136, 0).bold, //orange,
|
|
50
|
-
db: chalk.greenBright,
|
|
51
|
-
api: chalk.magentaBright,
|
|
52
|
-
client: chalk.redBright,
|
|
53
|
-
log: chalk.yellowBright,
|
|
54
|
-
mail: chalk.cyanBright,
|
|
55
|
-
//error like have backGround colouring
|
|
56
|
-
auth: chalk.black.bgCyan,
|
|
57
|
-
err: chalk.white.bgBlue,
|
|
58
|
-
error: chalk.white.bgRed
|
|
59
|
-
});
|
|
60
|
-
});
|
|
73
|
+
}
|
|
61
74
|
|
|
62
75
|
|
|
63
|
-
async function logger(ip,level, ...messages) {
|
|
64
|
-
if (process.env.LOG_NONE === undefined) {
|
|
65
|
-
COLOURS = await COLOURPromise;
|
|
66
|
-
let logLine = '';
|
|
67
|
-
if (process.env.LOG_NO_DATE === undefined) logLine += new Date().toISOString() + ': ';
|
|
68
|
-
let message;
|
|
69
|
-
let logcolor;
|
|
70
|
-
if (isIP(ip) === 0 ) {
|
|
71
|
-
logcolor = ip;
|
|
72
|
-
message = level + messages.join(' ');
|
|
73
|
-
} else {
|
|
74
|
-
const client = process.env.LOG_IP_HIDDEN !== undefined ? cyrb53(ip): ip;
|
|
75
|
-
logLine += COLOURS.client(client + ': ');
|
|
76
|
-
logcolor = level
|
|
77
|
-
message = messages.join(' ');
|
|
78
|
-
}
|
|
79
|
-
logLine += COLOURS[logcolor](message);
|
|
80
|
-
//eslint-disable-next-line no-console
|
|
81
|
-
console.log(logLine.trim());
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
76
|
|
|
85
|
-
module.exports = logger;
|
|
86
|
-
})();
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akc42/server-utils",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "A Set of Utilities to use on the Server Side of a Project",
|
|
5
|
-
"main": "utils.js",
|
|
6
|
+
"main": "./utils.js",
|
|
6
7
|
"scripts": {
|
|
7
8
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
9
|
},
|
|
@@ -21,8 +22,9 @@
|
|
|
21
22
|
},
|
|
22
23
|
"homepage": "https://github.com/akc42/server-utils#readme",
|
|
23
24
|
"dependencies": {
|
|
24
|
-
"app-root-path": "^3.
|
|
25
|
-
"chalk": "^5.
|
|
26
|
-
"debug": "^4.3.
|
|
25
|
+
"app-root-path": "^3.1.0",
|
|
26
|
+
"chalk": "^5.1.2",
|
|
27
|
+
"debug": "^4.3.4"
|
|
27
28
|
}
|
|
29
|
+
|
|
28
30
|
}
|
package/responder.js
CHANGED
|
@@ -1,122 +1,121 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@licence
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2021 Alan Chandler, all rights reserved
|
|
4
4
|
|
|
5
|
-
This file is part of
|
|
5
|
+
This file is part of Server Utils.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Server Utils is free software: you can redistribute it and/or modify
|
|
8
8
|
it under the terms of the GNU General Public License as published by
|
|
9
9
|
the Free Software Foundation, either version 3 of the License, or
|
|
10
10
|
(at your option) any later version.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Server Utils is distributed in the hope that it will be useful,
|
|
13
13
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
14
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
15
|
GNU General Public License for more details.
|
|
16
16
|
|
|
17
17
|
You should have received a copy of the GNU General Public License
|
|
18
|
-
along with
|
|
18
|
+
along with Server Utils. If not, see <http://www.gnu.org/licenses/>.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import Debug from 'debug';
|
|
21
22
|
|
|
22
|
-
(function() {
|
|
23
|
-
'use strict';
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
|
|
25
|
+
const debug = Debug('responder');
|
|
26
26
|
|
|
27
|
-
class Responder {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
this.response.write(',"' + name + '": ');
|
|
48
|
-
} else {
|
|
49
|
-
this.response.write('{"' + name + '": ');
|
|
27
|
+
export default class Responder {
|
|
28
|
+
constructor(response) {
|
|
29
|
+
debug('Starting responder');
|
|
30
|
+
this.response = response;
|
|
31
|
+
this.doneFirstRow = false;
|
|
32
|
+
this.doneFirstSection = false;
|
|
33
|
+
this.ended = false;
|
|
34
|
+
this.isArray = false;
|
|
35
|
+
this.awaitingDrain = false;
|
|
36
|
+
}
|
|
37
|
+
addSection(name, value) {
|
|
38
|
+
if (!this.ended) {
|
|
39
|
+
if (this.isArray) {
|
|
40
|
+
throw new Error('Cannot add section to an array');
|
|
41
|
+
}
|
|
42
|
+
if (this.doneFirstSection) {
|
|
43
|
+
//need to close previous one
|
|
44
|
+
if (this.inSection) {
|
|
45
|
+
this.response.write(']');
|
|
50
46
|
}
|
|
47
|
+
this.response.write(',"' + name + '": ');
|
|
48
|
+
} else {
|
|
49
|
+
this.response.write('{"' + name + '": ');
|
|
50
|
+
}
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
this.doneFirstSection = true;
|
|
62
|
-
this.doneFirstRow = false;
|
|
52
|
+
if (value !== undefined) {
|
|
53
|
+
this.response.write(JSON.stringify(value));
|
|
54
|
+
this.inSection = false;
|
|
55
|
+
debug('Value section %s',name);
|
|
56
|
+
} else {
|
|
57
|
+
this.response.write('[');
|
|
58
|
+
this.inSection = true;
|
|
59
|
+
debug('In section %s',name);
|
|
63
60
|
}
|
|
61
|
+
this.doneFirstSection = true;
|
|
62
|
+
this.doneFirstRow = false;
|
|
64
63
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
64
|
+
}
|
|
65
|
+
write(row) {
|
|
66
|
+
if (!this.ended) {
|
|
67
|
+
if (!this.doneFirstSection) {
|
|
68
|
+
this.isArray = true;
|
|
69
|
+
this.response.write('[');
|
|
70
|
+
this.doneFirstSection = true;
|
|
71
|
+
this.inSection = true;
|
|
72
|
+
}
|
|
73
|
+
if (!this.inSection) {
|
|
74
|
+
throw new Error('Cannot add rows after a value section without a new section header');
|
|
75
|
+
}
|
|
76
|
+
if (this.doneFirstRow) {
|
|
77
|
+
this.response.write(',');
|
|
78
|
+
}
|
|
79
|
+
this.doneFirstRow = true;
|
|
80
|
+
const JSONrow = JSON.stringify(row);
|
|
81
|
+
const reply = this.response.write(JSONrow);
|
|
82
|
+
if (reply) {
|
|
83
|
+
return Promise.resolve();
|
|
84
|
+
}
|
|
85
|
+
debug('False reply from write so need return the promise of a drain');
|
|
86
|
+
if (!this.awaitingDrain) {
|
|
87
|
+
this.awaitingDrain = true;
|
|
88
|
+
const self = this;
|
|
89
|
+
debug('create a drain promise as we do not have one');
|
|
90
|
+
this.drainPromise = new Promise(resolve => {
|
|
91
|
+
self.response.once('drain', () => {
|
|
92
|
+
self.awaitingDrain = false;
|
|
93
|
+
debug('drained so resolve promise of drain');
|
|
94
|
+
resolve();
|
|
96
95
|
});
|
|
97
|
-
}
|
|
98
|
-
return this.drainPromise;
|
|
96
|
+
});
|
|
99
97
|
}
|
|
100
|
-
return
|
|
98
|
+
return this.drainPromise;
|
|
101
99
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
100
|
+
return Promise.reject(); //mark as blocked
|
|
101
|
+
}
|
|
102
|
+
end() {
|
|
103
|
+
debug('End Responder');
|
|
104
|
+
if (!this.ended) {
|
|
105
|
+
if (this.inSection) {
|
|
106
|
+
this.response.write(']');
|
|
107
|
+
}
|
|
108
|
+
if (!this.isArray) {
|
|
109
|
+
if (this.doneFirstSection) {
|
|
110
|
+
this.response.end('}');
|
|
114
111
|
} else {
|
|
115
|
-
this.response.end();
|
|
112
|
+
this.response.end('[]');
|
|
116
113
|
}
|
|
114
|
+
} else {
|
|
115
|
+
this.response.end();
|
|
117
116
|
}
|
|
118
|
-
this.ended = true;
|
|
119
117
|
}
|
|
118
|
+
this.ended = true;
|
|
120
119
|
}
|
|
121
|
-
|
|
122
|
-
|
|
120
|
+
}
|
|
121
|
+
|
package/utils.js
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
@licence
|
|
3
|
+
Copyright (c) 2021 Alan Chandler, all rights reserved
|
|
4
|
+
|
|
5
|
+
This file is part of Server Utils.
|
|
6
|
+
|
|
7
|
+
Server Utils is free software: you can redistribute it and/or modify
|
|
8
|
+
it under the terms of the GNU General Public License as published by
|
|
9
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
10
|
+
(at your option) any later version.
|
|
11
|
+
|
|
12
|
+
Server Utils is distributed in the hope that it will be useful,
|
|
13
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
|
+
GNU General Public License for more details.
|
|
16
|
+
|
|
17
|
+
You should have received a copy of the GNU General Public License
|
|
18
|
+
along with Server Utils. If not, see <http://www.gnu.org/licenses/>.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
import logger from './logger.js';
|
|
23
|
+
import Version from './version.js';
|
|
24
|
+
import Responder from './responder.js';
|
|
25
|
+
import { Debug, dumpDebugCache, setDebugConfig} from './debug.js';
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
logger,
|
|
30
|
+
Version,
|
|
31
|
+
Responder,
|
|
32
|
+
Debug,
|
|
33
|
+
dumpDebugCache,
|
|
34
|
+
setDebugConfig
|
|
35
|
+
}
|
package/version.js
CHANGED
|
@@ -1,97 +1,95 @@
|
|
|
1
1
|
/**
|
|
2
2
|
@licence
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2021 Alan Chandler, all rights reserved
|
|
4
4
|
|
|
5
|
-
This file is part of
|
|
5
|
+
This file is part of Server Utils.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Server Utils is free software: you can redistribute it and/or modify
|
|
8
8
|
it under the terms of the GNU General Public License as published by
|
|
9
9
|
the Free Software Foundation, either version 3 of the License, or
|
|
10
10
|
(at your option) any later version.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Server Utils is distributed in the hope that it will be useful,
|
|
13
13
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
14
14
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
15
15
|
GNU General Public License for more details.
|
|
16
16
|
|
|
17
17
|
You should have received a copy of the GNU General Public License
|
|
18
|
-
along with
|
|
18
|
+
along with Server Utils. If not, see <http://www.gnu.org/licenses/>.
|
|
19
19
|
*/
|
|
20
|
-
(() => {
|
|
21
|
-
const debug = require('debug')('version');
|
|
22
|
-
const fs = require('fs').promises;
|
|
23
|
-
const path = require('path');
|
|
24
|
-
const child = require('child_process');
|
|
25
|
-
const root = require('app-root-path').toString();
|
|
26
20
|
|
|
21
|
+
import {Debug} from './debug.js';
|
|
22
|
+
import {access, readFile, stat} from 'node:fs/promises';
|
|
23
|
+
import { resolve } from 'node:path';
|
|
24
|
+
import { exec } from 'node:child_process';
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
26
|
+
const debug = Debug('version');
|
|
27
|
+
|
|
28
|
+
function shCmd(cmd, root) {
|
|
29
|
+
debug('About to execute Command ', cmd);
|
|
30
|
+
return new Promise((accept, reject) => {
|
|
31
|
+
exec(cmd, { cwd: root }, (err, stdout, stderr) => {
|
|
32
|
+
if (stderr) {
|
|
33
|
+
debug('Command ', cmd, 'about to fail with ', err);
|
|
34
|
+
reject(err);
|
|
35
|
+
} else {
|
|
36
|
+
const out = stdout.trim();
|
|
37
|
+
debug('Command ', cmd, 'Success with ', out);
|
|
38
|
+
accept(out);
|
|
39
|
+
}
|
|
41
40
|
});
|
|
42
|
-
}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
export default async function(root) {
|
|
43
44
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
let vtime;
|
|
45
|
+
let version;
|
|
46
|
+
let vtime;
|
|
47
47
|
|
|
48
|
+
try {
|
|
49
|
+
debug('Look for git')
|
|
50
|
+
await access(resolve(root, '.git'));
|
|
51
|
+
debug('Git found, so use it to get data')
|
|
52
|
+
//we get here if there is a git directory, so we can look up version and latest commit from them
|
|
53
|
+
version = await shCmd('git describe --abbrev=0 --tags');
|
|
54
|
+
//git is installed and we found a tag
|
|
55
|
+
try {
|
|
56
|
+
vtime = await shCmd('git log -1 --format=%cd');
|
|
57
|
+
} catch (e) {
|
|
58
|
+
vtime = new Date(); //fake it;
|
|
59
|
+
}
|
|
60
|
+
} catch (e) {
|
|
61
|
+
//no git, or no tag, so we must look for a version file
|
|
48
62
|
try {
|
|
49
|
-
debug('
|
|
50
|
-
await
|
|
51
|
-
debug('Git found, so use it to get data')
|
|
52
|
-
//we get here if there is a git directory, so we can look up version and latest commit from them
|
|
53
|
-
version = await shCmd('git describe --abbrev=0 --tags');
|
|
54
|
-
//git is installed and we found a tag
|
|
63
|
+
debug('Git approach failed, so look for release info');
|
|
64
|
+
version = await readFile(resolve(root, 'release.info'), 'utf8');
|
|
55
65
|
try {
|
|
56
|
-
|
|
66
|
+
const { mtime } = await stat(resolve(root, 'release.info'));
|
|
67
|
+
vtime = mtime;
|
|
57
68
|
} catch (e) {
|
|
58
|
-
vtime = new Date();
|
|
69
|
+
vtime = new Date();
|
|
59
70
|
}
|
|
60
|
-
} catch
|
|
61
|
-
//no
|
|
71
|
+
} catch(e) {
|
|
72
|
+
//no release info file, so use package.json
|
|
62
73
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
74
|
+
const pjsonfile = resolve(root, 'package.json');
|
|
75
|
+
const pjson = await import(pjsonfile);
|
|
76
|
+
version = 'v'+ pjson.version;
|
|
65
77
|
try {
|
|
66
|
-
const { mtime } = await
|
|
78
|
+
const { mtime } = await stat(pjsonfile);
|
|
67
79
|
vtime = mtime;
|
|
68
80
|
} catch (e) {
|
|
69
81
|
vtime = new Date();
|
|
70
82
|
}
|
|
71
83
|
} catch(e) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
const pjsonfile = path.resolve(root, 'package.json');
|
|
75
|
-
const pjson = require(pjsonfile);
|
|
76
|
-
version = 'v'+ pjson.version;
|
|
77
|
-
try {
|
|
78
|
-
const { mtime } = await fs.stat(pjsonfile);
|
|
79
|
-
vtime = mtime;
|
|
80
|
-
} catch (e) {
|
|
81
|
-
vtime = new Date();
|
|
82
|
-
}
|
|
83
|
-
} catch(e) {
|
|
84
|
-
version = 'v1.0.0';
|
|
85
|
-
vtime = new Date();
|
|
86
|
-
}
|
|
84
|
+
version = 'v1.0.0';
|
|
85
|
+
vtime = new Date();
|
|
87
86
|
}
|
|
88
|
-
} finally {
|
|
89
|
-
const finalversion = version.replace(/\s+/g, ' ').trim(); //trim out new lines and multiple spaces just one.
|
|
90
|
-
const copyrightTime = new Date(vtime);
|
|
91
|
-
debug('Resolving with Git copyright Year is ', copyrightTime.getUTCFullYear());
|
|
92
|
-
resolve({ version: finalversion, year: copyrightTime.getUTCFullYear() });
|
|
93
87
|
}
|
|
94
|
-
}
|
|
95
|
-
|
|
88
|
+
} finally {
|
|
89
|
+
const finalversion = version.replace(/\s+/g, ' ').trim(); //trim out new lines and multiple spaces just one.
|
|
90
|
+
const copyrightTime = new Date(vtime);
|
|
91
|
+
debug('Resolving with Git copyright Year is ', copyrightTime.getUTCFullYear());
|
|
92
|
+
return({ version: finalversion, year: copyrightTime.getUTCFullYear() });
|
|
93
|
+
}
|
|
94
|
+
};
|
|
96
95
|
|
|
97
|
-
})();
|