@sera4/essentia 1.1.66-rc.1 → 3.0.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/README.md +352 -8
- package/dist/ts/index.d.ts +1 -2
- package/dist/ts/index.js +1 -3
- 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/queue/subscriber.js
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
import logger from "./queue-logger.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* A subscriber for AMQP service
|
|
5
|
-
*/
|
|
6
|
-
export class Subscriber {
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Builds a subscriber
|
|
10
|
-
* @param {String} exchange name of the AMQP exchange.
|
|
11
|
-
* @param {String} queue name of the AMQP service.
|
|
12
|
-
* @param {String} type direct|fanout or other supported connection types.
|
|
13
|
-
* @param {String} key routing key. This will be used to bind the queue to the exchange.
|
|
14
|
-
* @param {String} name a usefull name to be printed in the logs.
|
|
15
|
-
* @param {Object} options connection options
|
|
16
|
-
*/
|
|
17
|
-
constructor(exchange, queue, key, name) {
|
|
18
|
-
this.exchange = exchange;
|
|
19
|
-
this.queue = queue;
|
|
20
|
-
this.key = key;
|
|
21
|
-
this.name = name;
|
|
22
|
-
this.channel = null;
|
|
23
|
-
this.callbacks = [];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Initializes the subscriber on the given connection.
|
|
28
|
-
* During this call, the exchange and the queues are asserted
|
|
29
|
-
* and bound via the key provided in the constructor.
|
|
30
|
-
* @param {Object} conn aqmp connection object
|
|
31
|
-
*/
|
|
32
|
-
async init (conn) {
|
|
33
|
-
logger.debug(`Initializing SUB channel for ${this.name}`);
|
|
34
|
-
|
|
35
|
-
if(this.channel) {
|
|
36
|
-
logger.warn(`SUB channel for ${this.name} already initialized`);
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
this.channel = await conn.createChannel();
|
|
41
|
-
if (!this.channel) {
|
|
42
|
-
throw(new Error(`Cannot create SUB channel for ${this.name}`));
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
this.channel.on("error", (err) => {
|
|
46
|
-
logger.debug(`Connection error for ${this.name}`, err);
|
|
47
|
-
this.channel = null;
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
this.channel.on("close", () => {
|
|
51
|
-
logger.debug(`Connection closed for ${this.name}`);
|
|
52
|
-
this.channel = null;
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
logger.debug(`Initialized SUB channel for ${this.name}`);
|
|
56
|
-
const { name: exchangeName, options: exchangeOptions, type } = this.exchange;
|
|
57
|
-
const { name: queueName, options: queueOptions } = this.queue;
|
|
58
|
-
|
|
59
|
-
await this.channel.assertExchange(exchangeName, type, exchangeOptions);
|
|
60
|
-
await this.channel.assertQueue(queueName, queueOptions);
|
|
61
|
-
|
|
62
|
-
logger.debug(`Binding queue ${queueName} on ${exchangeName} exchange for ${this.key} key`);
|
|
63
|
-
await this.channel.bindQueue(queueName, exchangeName, this.key);
|
|
64
|
-
|
|
65
|
-
this.channel.consume(queueName, (msg) => {
|
|
66
|
-
const { fields, content } = msg;
|
|
67
|
-
let payload = null;
|
|
68
|
-
let error = null;
|
|
69
|
-
try {
|
|
70
|
-
payload = JSON.parse(content.toString());
|
|
71
|
-
} catch (e) {
|
|
72
|
-
logger.error("Failed to parse incomming message:", e);
|
|
73
|
-
error = e;
|
|
74
|
-
payload = { error, original_content: content.toString() };
|
|
75
|
-
}
|
|
76
|
-
payload.metadata = fields;
|
|
77
|
-
logger.debug(`Got message from exchange '${fields.exchange}' with key '${fields.routingKey}'`);
|
|
78
|
-
logger.debug("Content", payload);
|
|
79
|
-
this.callbacks.forEach(cb => {
|
|
80
|
-
cb(payload, error);
|
|
81
|
-
});
|
|
82
|
-
this.channel.ack(msg);
|
|
83
|
-
}, { noAck: false });
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Closes the channel
|
|
88
|
-
* @returns promise
|
|
89
|
-
*/
|
|
90
|
-
async closeChannel() {
|
|
91
|
-
if (this.channel) {
|
|
92
|
-
logger.debug("Closing subscriber channel", this.name);
|
|
93
|
-
return this.channel.close();
|
|
94
|
-
} else {
|
|
95
|
-
logger.error("Can't close a null subscriber channel");
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Register a new callback to recive message through this
|
|
101
|
-
* subscriber object
|
|
102
|
-
* @param {function} cb A callback to be called when a message arrives
|
|
103
|
-
*/
|
|
104
|
-
registerCallback(cb) {
|
|
105
|
-
this.callbacks.push(cb);
|
|
106
|
-
}
|
|
107
|
-
}
|
package/safe_proxy/index.js
DELETED
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
import axios from "axios";
|
|
4
|
-
import lodash from 'lodash';
|
|
5
|
-
const { omitBy, isNil } = lodash;
|
|
6
|
-
|
|
7
|
-
/* A class which safely wraps an axios connection in order to pass the current user through to
|
|
8
|
-
* the next service. Useful when one of our microservices requires auth as either an admin (sera4tal)
|
|
9
|
-
* or as the end user (example: DELETE /auth/sessions/:id
|
|
10
|
-
*
|
|
11
|
-
* Similar to proxy however this isn't a proxy, it's a full out new call that we can manage
|
|
12
|
-
* each method requires a res.locals from a pre-authd session
|
|
13
|
-
*/
|
|
14
|
-
class SafeProxy {
|
|
15
|
-
constructor() {
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
// a safe post request
|
|
19
|
-
// locals = res.locals - your authentication details
|
|
20
|
-
post(locals, url, options = { headers: {}, data: {}}) {
|
|
21
|
-
let { account, tenant, membership } = locals;
|
|
22
|
-
return this._proxyRequest({ account, tenant, membership }, url, "post", options);
|
|
23
|
-
}
|
|
24
|
-
delete(locals, url, options = { headers: {}, data: {}}) {
|
|
25
|
-
let { account, tenant, membership } = locals;
|
|
26
|
-
return this._proxyRequest({ account, tenant, membership }, url, "delete", options);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/* private methods */
|
|
30
|
-
// supports get, delete, post
|
|
31
|
-
// options includes { headers, data } for post / delete payloads
|
|
32
|
-
async _proxyRequest(locals, url, method = "get", options) {
|
|
33
|
-
let request;
|
|
34
|
-
let membership = locals.membership ? JSON.stringify(locals.membership) : null;
|
|
35
|
-
let headers = omitBy({ ...options.headers,
|
|
36
|
-
"tws-account-id": locals.account?.id,
|
|
37
|
-
"tws-tenant-id": locals.tenant?.id,
|
|
38
|
-
"tws-membership-id": locals.membership?.id,
|
|
39
|
-
"tws-membership": membership
|
|
40
|
-
}, isNil);
|
|
41
|
-
|
|
42
|
-
switch(method) {
|
|
43
|
-
case "post":
|
|
44
|
-
request = axios.post(url, { ...options.data }, { headers })
|
|
45
|
-
break;
|
|
46
|
-
case "delete":
|
|
47
|
-
request = axios.delete(url, { ...options.data, headers } )
|
|
48
|
-
break;
|
|
49
|
-
case "get":
|
|
50
|
-
request = axios.get(url, { headers, data } )
|
|
51
|
-
break;
|
|
52
|
-
default:
|
|
53
|
-
throw new Error("uknown type called in proxyRequest");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return request;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export const safeProxy = new SafeProxy();
|
package/scripts/publish.sh
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
set -euo pipefail
|
|
3
|
-
|
|
4
|
-
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
5
|
-
cd "$ROOT"
|
|
6
|
-
|
|
7
|
-
# ── Version resolution ────────────────────────────────────────────────────────
|
|
8
|
-
VERSION="${BUILD_VERSION:-}"
|
|
9
|
-
|
|
10
|
-
if [ -z "$VERSION" ]; then
|
|
11
|
-
VERSION=$(node -p "require('./package.json').version")
|
|
12
|
-
fi
|
|
13
|
-
|
|
14
|
-
if [ -z "$VERSION" ] || [ "$VERSION" = "0.0.0" ]; then
|
|
15
|
-
echo "error: no version specified — set BUILD_VERSION or package.json version" >&2
|
|
16
|
-
exit 1
|
|
17
|
-
fi
|
|
18
|
-
|
|
19
|
-
PACKAGE=$(node -p "require('./package.json').name")
|
|
20
|
-
echo "publishing $PACKAGE@$VERSION"
|
|
21
|
-
|
|
22
|
-
# ── Stamp version, restore on exit ───────────────────────────────────────────
|
|
23
|
-
ORIGINAL_VERSION=$(node -p "require('./package.json').version")
|
|
24
|
-
restore_version() {
|
|
25
|
-
npm pkg set version="$ORIGINAL_VERSION" --silent
|
|
26
|
-
}
|
|
27
|
-
trap restore_version EXIT
|
|
28
|
-
|
|
29
|
-
npm pkg set version="$VERSION" --silent
|
|
30
|
-
|
|
31
|
-
# ── Build ─────────────────────────────────────────────────────────────────────
|
|
32
|
-
echo "building..."
|
|
33
|
-
npm run build
|
|
34
|
-
|
|
35
|
-
# ── Dist-tag: prerelease versions get 'next', stable versions get 'latest' ───
|
|
36
|
-
if [[ "$VERSION" =~ -[a-zA-Z] ]]; then
|
|
37
|
-
DIST_TAG="next"
|
|
38
|
-
else
|
|
39
|
-
DIST_TAG="latest"
|
|
40
|
-
fi
|
|
41
|
-
|
|
42
|
-
# ── Publish ───────────────────────────────────────────────────────────────────
|
|
43
|
-
echo "publishing with tag: $DIST_TAG"
|
|
44
|
-
npm publish --access public --tag "$DIST_TAG"
|
|
45
|
-
|
|
46
|
-
echo "done: $PACKAGE@$VERSION"
|
package/serializer/index.js
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import _ from "lodash";
|
|
2
|
-
|
|
3
|
-
const customSerializers = {};
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
/**
|
|
7
|
-
* Seralizes a Sequelize Model.
|
|
8
|
-
* @param {Object} Model the squelize model to add this plugin to
|
|
9
|
-
* @param {Object} options various options for serialization. These can be:
|
|
10
|
-
* • hide - an array of fields to be omitted
|
|
11
|
-
* • remove - an array of fields ot be REMOVED so they cannot be unhidden
|
|
12
|
-
* • decorators - an array of special decorators to run during serialization
|
|
13
|
-
* • handler - a handler for transforming data using only the values
|
|
14
|
-
* • advhandler - an advanced handler for transforming data using the value, object or options
|
|
15
|
-
* • includeAllFields - show fields that are normally hidden
|
|
16
|
-
* • includeFields[..] - show specific fields that are normally hidden
|
|
17
|
-
*/
|
|
18
|
-
serialize : (Model, options) => {
|
|
19
|
-
Model.prototype.toJSON = function(eachOptions={}) {
|
|
20
|
-
const hide = options && options.hide ? options.hide : [];
|
|
21
|
-
const remove = options && options.remove ? options.remove : [];
|
|
22
|
-
// ignore hide principles; but still do NOT show null
|
|
23
|
-
const includeAllFields = eachOptions["includeAllFields"];
|
|
24
|
-
|
|
25
|
-
// optionally force a normally hidden fields to be seen (by name)
|
|
26
|
-
const includeFields = eachOptions["includeFields"] || []
|
|
27
|
-
const handlerOptions = eachOptions["handlerOptions"] || {}
|
|
28
|
-
|
|
29
|
-
const values = this.get();
|
|
30
|
-
|
|
31
|
-
if (options?.decorators) {
|
|
32
|
-
options.decorators.forEach(dec => {
|
|
33
|
-
const k = dec.name;
|
|
34
|
-
const v = values[k];
|
|
35
|
-
// the advanced handler takes more parameters
|
|
36
|
-
if (dec.advHandler) {
|
|
37
|
-
values[k] = dec.advHandler(v, this, handlerOptions);
|
|
38
|
-
} else {
|
|
39
|
-
values[k] = dec.handler(v);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// for security reasons, some fields may need to be removed, such as
|
|
45
|
-
// password salts and mfa tokens
|
|
46
|
-
remove.forEach((field) => {
|
|
47
|
-
delete values[field];
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// hidden fields CAN be resurrected if NOT null, and forced to be
|
|
51
|
-
// included
|
|
52
|
-
let serialized = _.omitBy(values, (v, k) => {
|
|
53
|
-
if (v === null) return true;
|
|
54
|
-
|
|
55
|
-
let omitted = (includeAllFields ? false : hide.includes(k));
|
|
56
|
-
if (omitted && includeFields[k]) omitted = true ;
|
|
57
|
-
return omitted;
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const s = eachOptions["serializer"];
|
|
61
|
-
if (s && customSerializers[s]) {
|
|
62
|
-
serialized = customSerializers[s](serialized);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (Array.isArray(eachOptions.includes)) {
|
|
66
|
-
// Attach any included options that are
|
|
67
|
-
// not null or undefined
|
|
68
|
-
eachOptions.includes.forEach(include => {
|
|
69
|
-
if (include) {
|
|
70
|
-
const key = Object.keys(include);
|
|
71
|
-
const value = include[key];
|
|
72
|
-
if (value) {
|
|
73
|
-
serialized[key] = value;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
return serialized;
|
|
79
|
-
}
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Registers a custom serializer.
|
|
84
|
-
* @param {String} name the name of the custom serializer
|
|
85
|
-
* @param {Function} serializer a custom serializer function associated with the name
|
|
86
|
-
*/
|
|
87
|
-
register : (name, serializer) => {
|
|
88
|
-
customSerializers[name] = serializer;
|
|
89
|
-
}
|
|
90
|
-
}
|
package/test/health.spec.js
DELETED
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import { expect, should as chaiShould } from "chai";
|
|
2
|
-
import sinon from "sinon";
|
|
3
|
-
import express from "express";
|
|
4
|
-
import { healthCheck as hc } from "../index.js";
|
|
5
|
-
|
|
6
|
-
const should = chaiShould();
|
|
7
|
-
|
|
8
|
-
const mockResponse = () => {
|
|
9
|
-
const res = {};
|
|
10
|
-
res.status = sinon.stub().returns(res);
|
|
11
|
-
res.setHeader = sinon.stub();
|
|
12
|
-
res.json = sinon.stub().returns(res);
|
|
13
|
-
res.send = sinon.spy();
|
|
14
|
-
return res;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/* algorithm for shuffling an array */
|
|
18
|
-
const shuffle = (a) => {
|
|
19
|
-
for (let i = a.length - 1; i > 0; i--) {
|
|
20
|
-
const j = Math.floor(Math.random() * (i + 1));
|
|
21
|
-
[a[i], a[j]] = [a[j], a[i]];
|
|
22
|
-
}
|
|
23
|
-
return a;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
describe("HealthCheck Testing", () => {
|
|
27
|
-
let healthCheck = new hc();
|
|
28
|
-
|
|
29
|
-
describe("Health Check Sanity", () => {
|
|
30
|
-
it ("Should have NO predefined health checks", () => {
|
|
31
|
-
return expect(healthCheck.healthChecks).to.be.an('array').that.is.empty;
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it ("Should have have a sane default path route", () => {
|
|
35
|
-
return expect(healthCheck.defaultPath()).to.match(/health_check/);
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
it ("Should have have sane response defaults", () => {
|
|
39
|
-
expect(healthCheck.defaultResponse).to.have.property("status", 200);
|
|
40
|
-
expect(healthCheck.defaultResponse).to.have.property("errors").to.be.an('object').to.be.empty;
|
|
41
|
-
})
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
describe("Health Check Router", () => {
|
|
45
|
-
it ("Should throw without a proper router object", () => {
|
|
46
|
-
expect(healthCheck.routes.bind(healthCheck)).to.throw('missing_express_router');
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it ("Should return a proper router object with an improved route", () => {
|
|
50
|
-
let router = express.Router();
|
|
51
|
-
let improved_router = healthCheck.routes(router);
|
|
52
|
-
expect(improved_router).to.equal(router);
|
|
53
|
-
})
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
describe("Check Health Checks", () => {
|
|
57
|
-
let req, res;
|
|
58
|
-
|
|
59
|
-
beforeEach("Setup hc object", () => {
|
|
60
|
-
res = mockResponse();
|
|
61
|
-
req = { baseUrl: "server.example.com/api/health_check.json" };
|
|
62
|
-
healthCheck = new hc();
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
it ("Returns ok with no additional health check routes defined", (done) => {
|
|
66
|
-
req = { baseUrl: "server.example.com/api/health_check.json" };
|
|
67
|
-
|
|
68
|
-
const expectedResult = { check: 1, healthy: "true", message: "success" }
|
|
69
|
-
|
|
70
|
-
healthCheck.checkHealth(req, res)
|
|
71
|
-
.then((r) => {
|
|
72
|
-
sinon.assert.alwaysCalledWith(res.status, 200);
|
|
73
|
-
sinon.assert.calledOnce(res.status);
|
|
74
|
-
sinon.assert.alwaysCalledWith(res.json, expectedResult)
|
|
75
|
-
done()
|
|
76
|
-
});
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
it("Returns success with a simple successful (v1) health check defined", (done) => {
|
|
80
|
-
const sampleCheck = async () => {
|
|
81
|
-
return { name: "db", "result": "success", critical: false };
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
healthCheck.addCheck(sampleCheck);
|
|
85
|
-
expect(healthCheck.healthChecks).to.be.an('array').with.lengthOf(1);
|
|
86
|
-
|
|
87
|
-
const expectedResult = { check: 1, healthy: "true", message: "success" }
|
|
88
|
-
healthCheck.checkHealth(req, res)
|
|
89
|
-
.then((r) => {
|
|
90
|
-
sinon.assert.alwaysCalledWith(res.status, 200);
|
|
91
|
-
sinon.assert.alwaysCalledWith(res.json, expectedResult);
|
|
92
|
-
done()
|
|
93
|
-
});
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it("Returns fail with a failed health check", (done) => {
|
|
97
|
-
const sampleCheck = async () => {
|
|
98
|
-
return { name: "db", "result": "fail" };
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
healthCheck.addCheck(sampleCheck);
|
|
102
|
-
expect(healthCheck.healthChecks).to.be.an('array').with.lengthOf(1);
|
|
103
|
-
|
|
104
|
-
const expectedResult = { check: 1, healthy: "false", message: "fail" }
|
|
105
|
-
healthCheck.checkHealth(req, res)
|
|
106
|
-
.then(e => { done() })
|
|
107
|
-
.catch(err => {
|
|
108
|
-
sinon.assert.alwaysCalledWith(res.status, 500);
|
|
109
|
-
sinon.assert.alwaysCalledWith(res.json, expectedResult);
|
|
110
|
-
done()
|
|
111
|
-
})
|
|
112
|
-
})
|
|
113
|
-
|
|
114
|
-
it("Returns unhealthy with an OK and failed health check", (done) => {
|
|
115
|
-
const sampleFail = async () => {
|
|
116
|
-
return { name: "db", "result": "fail" };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const sampleSuccess= async () => {
|
|
120
|
-
return { name: "redis", "result": "success" };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
shuffle([sampleFail, sampleSuccess]).forEach(el => {
|
|
124
|
-
healthCheck.addCheck(el);
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
expect(healthCheck.healthChecks).to.be.an('array').with.lengthOf(2);
|
|
128
|
-
|
|
129
|
-
healthCheck.checkHealth(req, res)
|
|
130
|
-
.then(e => { done() })
|
|
131
|
-
.catch(err => {
|
|
132
|
-
sinon.assert.alwaysCalledWith(res.status, 500);
|
|
133
|
-
sinon.assert.alwaysCalledWith(res.json, 'fail');
|
|
134
|
-
done()
|
|
135
|
-
})
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
it("Returns healthy/200 when non-critical element fails (v2)", async () => {
|
|
139
|
-
const sampleCheck= async () => { throw new Error({status: 500}) }
|
|
140
|
-
|
|
141
|
-
healthCheck.setupCheck({ name: "sample", critical: false, healthFunction: sampleCheck });
|
|
142
|
-
expect(healthCheck.healthChecks).to.be.an('array').with.lengthOf(1);
|
|
143
|
-
|
|
144
|
-
await healthCheck.checkHealth(req, res)
|
|
145
|
-
|
|
146
|
-
sinon.assert.alwaysCalledWith(res.status, 200);
|
|
147
|
-
|
|
148
|
-
const expectedResult = {
|
|
149
|
-
check: 1,
|
|
150
|
-
healthy: "true",
|
|
151
|
-
message: "fail",
|
|
152
|
-
services: [{ critical: false, name: "sample", result: "fail", status: undefined }]
|
|
153
|
-
}
|
|
154
|
-
sinon.assert.alwaysCalledWith(res.json, expectedResult);
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
it("Returns unhealthy/500 when a critical component returns failure (v2)", async () => {
|
|
158
|
-
const sampleCheck= async () => { throw new Error({status: 500}) }
|
|
159
|
-
|
|
160
|
-
healthCheck.setupCheck({ name: "sample", critical: true, healthFunction: sampleCheck });
|
|
161
|
-
expect(healthCheck.healthChecks).to.be.an('array').with.lengthOf(1);
|
|
162
|
-
|
|
163
|
-
await healthCheck.checkHealth(req, res)
|
|
164
|
-
|
|
165
|
-
const expectedResult = {
|
|
166
|
-
check: 1, healthy: false,
|
|
167
|
-
message: "fail",
|
|
168
|
-
services: [{ critical: true, name: "sample", result: "fail", status: undefined }]
|
|
169
|
-
}
|
|
170
|
-
sinon.assert.alwaysCalledWith(res.status, 500);
|
|
171
|
-
sinon.assert.alwaysCalledWith(res.json, expectedResult);
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
it("Returns unhealthy/500 when a critical component returns failure (v2)", async () => {
|
|
175
|
-
const sampleCheck= async () => { throw new Error({status: 500}) }
|
|
176
|
-
const sampleCheck2= async () => { return true }
|
|
177
|
-
|
|
178
|
-
healthCheck.setupCheck({ name: "sample", critical: true, healthFunction: sampleCheck });
|
|
179
|
-
healthCheck.setupCheck({ name: "sample2", critical: true, healthFunction: sampleCheck2 });
|
|
180
|
-
expect(healthCheck.healthChecks).to.be.an('array').with.lengthOf(2);
|
|
181
|
-
|
|
182
|
-
await healthCheck.checkHealth(req, res)
|
|
183
|
-
|
|
184
|
-
const expectedResult = {
|
|
185
|
-
check: 1, healthy: false,
|
|
186
|
-
message: "fail",
|
|
187
|
-
services: [
|
|
188
|
-
{ critical: true, name: "sample", result: "fail", status: undefined },
|
|
189
|
-
{ critical: true, name: "sample2", result: "success" }]
|
|
190
|
-
}
|
|
191
|
-
sinon.assert.alwaysCalledWith(res.status, 500);
|
|
192
|
-
sinon.assert.alwaysCalledWith(res.json, expectedResult);
|
|
193
|
-
})
|
|
194
|
-
|
|
195
|
-
it("Returns a different ID each time it runscheck", (done) => {
|
|
196
|
-
let req2, res2;
|
|
197
|
-
res2 = mockResponse();
|
|
198
|
-
|
|
199
|
-
req = { baseUrl: "server.example.com/api/health_check.json" };
|
|
200
|
-
req2 = req
|
|
201
|
-
|
|
202
|
-
healthCheck.checkHealth(req, res)
|
|
203
|
-
.then(() => {
|
|
204
|
-
expect(healthCheck.lastCallId).to.equal(1)
|
|
205
|
-
healthCheck.checkHealth(req2, res2)
|
|
206
|
-
.then(() => {
|
|
207
|
-
expect(healthCheck.lastCallId).to.equal(2)
|
|
208
|
-
done()
|
|
209
|
-
})
|
|
210
|
-
})
|
|
211
|
-
})
|
|
212
|
-
})
|
|
213
|
-
});
|
package/test/prompt.test.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import { expect } from "chai";
|
|
2
|
-
import sinon from "sinon";
|
|
3
|
-
import prompt from "prompt";
|
|
4
|
-
import { ArgumentParser } from 'argparse';
|
|
5
|
-
import logger from "../logger/s4-logger.js";
|
|
6
|
-
|
|
7
|
-
import { setupCLIParser, cliSleep, promptCLIAsync, commonCLIInit, waitCLIPrompt, continueCLIPrompt } from "../prompts/index.js";
|
|
8
|
-
|
|
9
|
-
describe("Prompt Functions", () => {
|
|
10
|
-
describe("Setup Parser", () => {
|
|
11
|
-
let loggerStub;
|
|
12
|
-
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
loggerStub = sinon.stub(logger, "info");
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
afterEach(() => {
|
|
18
|
-
loggerStub.restore();
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it("should create an ArgumentParser with the given description", () => {
|
|
22
|
-
const description = "Test Description";
|
|
23
|
-
const parser = setupCLIParser(description);
|
|
24
|
-
|
|
25
|
-
expect(parser).to.be.instanceOf(ArgumentParser);
|
|
26
|
-
expect(loggerStub.calledWith(description)).to.be.true;
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe("cliSleep", () => {
|
|
31
|
-
it("should return a promise that resolves after the specified time", async () => {
|
|
32
|
-
const clock = sinon.useFakeTimers();
|
|
33
|
-
const ms = 1000;
|
|
34
|
-
|
|
35
|
-
const promise = cliSleep(ms);
|
|
36
|
-
clock.tick(ms);
|
|
37
|
-
|
|
38
|
-
await promise;
|
|
39
|
-
clock.restore();
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
describe("Prompt Async", () => {
|
|
44
|
-
let promptStub;
|
|
45
|
-
|
|
46
|
-
beforeEach(() => {
|
|
47
|
-
promptStub = sinon.stub(prompt, "get");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
afterEach(() => {
|
|
51
|
-
promptStub.restore();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it("should resolve with response when prompt succeeds", async () => {
|
|
55
|
-
const options = { name: "test" };
|
|
56
|
-
const mockResponse = { name: "response" };
|
|
57
|
-
|
|
58
|
-
promptStub.yields(null, mockResponse);
|
|
59
|
-
|
|
60
|
-
const result = await promptCLIAsync(options);
|
|
61
|
-
expect(result).to.equal(mockResponse);
|
|
62
|
-
expect(promptStub.calledWith(options)).to.be.true;
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
it("should reject with error when prompt fails", async () => {
|
|
66
|
-
const options = { name: "test" };
|
|
67
|
-
const mockError = new Error("Prompt error");
|
|
68
|
-
|
|
69
|
-
promptStub.yields(mockError, null);
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
await promptCLIAsync(options);
|
|
73
|
-
expect.fail("Should have thrown an error");
|
|
74
|
-
} catch (error) {
|
|
75
|
-
expect(error).to.equal(mockError);
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
describe("Prompt Objects", () => {
|
|
81
|
-
it("should define waitPrompt with correct structure", () => {
|
|
82
|
-
expect(waitCLIPrompt).to.have.property("Push <enter> when done");
|
|
83
|
-
expect(waitCLIPrompt["Push <enter> when done"]).to.have.property("type", "boolean");
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it("should define continuePrompt with correct structure", () => {
|
|
87
|
-
expect(continueCLIPrompt).to.have.property("Push <enter> to continue");
|
|
88
|
-
expect(continueCLIPrompt["Push <enter> to continue"]).to.have.property("type", "boolean");
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
});
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import should from "should";
|
|
2
|
-
import { expect as expect } from "chai";
|
|
3
|
-
|
|
4
|
-
import S4Formatter from "../formatter/index.js";
|
|
5
|
-
|
|
6
|
-
describe("Formatter", function () {
|
|
7
|
-
let response;
|
|
8
|
-
|
|
9
|
-
describe("Sending legacy format []", function () {
|
|
10
|
-
before("Setup", function () {
|
|
11
|
-
const error = { status: 200, error: ["error1"] }
|
|
12
|
-
response = S4Formatter.formatError(error);
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
describe("Default values", function () {
|
|
16
|
-
it("should have a generic error", function () {
|
|
17
|
-
response.should.have.property("errors");
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
it("should have error code set correctly", function () {
|
|
21
|
-
response.should.have.property("status", 200);
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
describe("Support null error payloads", function () {
|
|
27
|
-
before("Setup", function () {
|
|
28
|
-
response = S4Formatter.formatError(null);
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
describe("Default values", function () {
|
|
32
|
-
it("Should have a default error level and blank errors", function () {
|
|
33
|
-
expect(response).to.have.property("status",422);
|
|
34
|
-
expect(response).to.have.property("errors").to.be.empty;
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
describe("Should not fold in funky keys/values", function () {
|
|
41
|
-
before("Setup", function () {
|
|
42
|
-
response = S4Formatter.formatError({randomKey: 123});
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
describe("Default values", function () {
|
|
46
|
-
it("Should not funky key name folded in", function () {
|
|
47
|
-
response.should.not.have.property("randomKey", {});
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
describe("Support validator formats", function () {
|
|
53
|
-
before("Setup", function () {
|
|
54
|
-
let error = {
|
|
55
|
-
"status": 422,
|
|
56
|
-
"errors": {
|
|
57
|
-
"password": {
|
|
58
|
-
"location": "body",
|
|
59
|
-
"param": "password",
|
|
60
|
-
"value": "badPassw0rd",
|
|
61
|
-
"msg": "weak"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
response = S4Formatter.formatError(error);
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
describe("Default values", function () {
|
|
70
|
-
it("Should have a default error level and blank errors", function () {
|
|
71
|
-
response.should.have.property("status", 422);
|
|
72
|
-
expect(response).to.be.an("object");
|
|
73
|
-
expect(response).to.have.property('errors');
|
|
74
|
-
expect(Object.keys(response['errors'])).to.have.lengthOf('1')
|
|
75
|
-
response.should.have.property("errors");
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
})
|