@bitblit/ratchet-common 4.0.80-alpha
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/dist/cjs/2d/line-2d.js +2 -0
- package/dist/cjs/2d/plane-2d.js +2 -0
- package/dist/cjs/2d/point-2d.js +2 -0
- package/dist/cjs/2d/poly-line-2d.js +2 -0
- package/dist/cjs/2d/ratchet-2d.js +250 -0
- package/dist/cjs/build/build-information.js +2 -0
- package/dist/cjs/build/ratchet-common-info.js +18 -0
- package/dist/cjs/histogram/histogram-entry.js +2 -0
- package/dist/cjs/histogram/histogram.js +54 -0
- package/dist/cjs/index.js +74 -0
- package/dist/cjs/jwt/common-jwt-token.js +2 -0
- package/dist/cjs/jwt/expired-jwt-handling.js +9 -0
- package/dist/cjs/jwt/jwt-ratchet-like.js +2 -0
- package/dist/cjs/jwt/jwt-ratchet.js +164 -0
- package/dist/cjs/jwt/jwt-token-base.js +2 -0
- package/dist/cjs/lang/array-ratchet.js +87 -0
- package/dist/cjs/lang/base64-ratchet.js +49 -0
- package/dist/cjs/lang/boolean-ratchet.js +49 -0
- package/dist/cjs/lang/composite-last-success-provider.js +28 -0
- package/dist/cjs/lang/date-ratchet.js +33 -0
- package/dist/cjs/lang/duration-ratchet.js +46 -0
- package/dist/cjs/lang/enum-ratchet.js +34 -0
- package/dist/cjs/lang/error-ratchet.js +49 -0
- package/dist/cjs/lang/expiring-object.js +68 -0
- package/dist/cjs/lang/geolocation-ratchet.js +267 -0
- package/dist/cjs/lang/global-ratchet.js +48 -0
- package/dist/cjs/lang/key-value.js +6 -0
- package/dist/cjs/lang/last-success-provider.js +2 -0
- package/dist/cjs/lang/map-ratchet.js +168 -0
- package/dist/cjs/lang/no.js +8 -0
- package/dist/cjs/lang/number-ratchet.js +156 -0
- package/dist/cjs/lang/parsed-url.js +2 -0
- package/dist/cjs/lang/promise-ratchet.js +142 -0
- package/dist/cjs/lang/require-ratchet.js +60 -0
- package/dist/cjs/lang/stop-watch.js +117 -0
- package/dist/cjs/lang/string-ratchet.js +195 -0
- package/dist/cjs/lang/time-zone-ratchet.js +80 -0
- package/dist/cjs/lang/timeout-token.js +19 -0
- package/dist/cjs/lang/transform-ratchet.js +70 -0
- package/dist/cjs/logger/classic-single-line-log-message-formatter.js +18 -0
- package/dist/cjs/logger/log-message-builder.js +51 -0
- package/dist/cjs/logger/log-message-format-type.js +9 -0
- package/dist/cjs/logger/log-message-formatter.js +2 -0
- package/dist/cjs/logger/log-message-processor.js +2 -0
- package/dist/cjs/logger/log-message.js +2 -0
- package/dist/cjs/logger/log-snapshot.js +2 -0
- package/dist/cjs/logger/logger-instance.js +207 -0
- package/dist/cjs/logger/logger-level-name.js +12 -0
- package/dist/cjs/logger/logger-meta.js +2 -0
- package/dist/cjs/logger/logger-options.js +2 -0
- package/dist/cjs/logger/logger-output-function.js +9 -0
- package/dist/cjs/logger/logger-ring-buffer.js +76 -0
- package/dist/cjs/logger/logger-util.js +49 -0
- package/dist/cjs/logger/logger.js +139 -0
- package/dist/cjs/logger/none-log-message-formatter.js +9 -0
- package/dist/cjs/logger/structured-json-log-message-formatter.js +24 -0
- package/dist/cjs/network/browser-local-ip-provider.js +25 -0
- package/dist/cjs/network/fixed-local-ip-provider.js +12 -0
- package/dist/cjs/network/local-ip-provider.js +2 -0
- package/dist/cjs/network/network-ratchet.js +106 -0
- package/dist/cjs/stream/buffer-writable.js +20 -0
- package/dist/cjs/stream/stream-ratchet.js +72 -0
- package/dist/cjs/stream/string-writable.js +18 -0
- package/dist/cjs/third-party/google/google-recaptcha-ratchet.js +33 -0
- package/dist/cjs/third-party/twilio/twilio-ratchet.js +75 -0
- package/dist/cjs/transform/built-in-transforms.js +195 -0
- package/dist/cjs/transform/transform-rule.js +2 -0
- package/dist/cjs/tx/transaction-configuration.js +2 -0
- package/dist/cjs/tx/transaction-final-state.js +9 -0
- package/dist/cjs/tx/transaction-ratchet.js +80 -0
- package/dist/cjs/tx/transaction-result.js +2 -0
- package/dist/cjs/tx/transaction-step.js +2 -0
- package/dist/es/2d/line-2d.js +1 -0
- package/dist/es/2d/plane-2d.js +1 -0
- package/dist/es/2d/point-2d.js +1 -0
- package/dist/es/2d/poly-line-2d.js +1 -0
- package/dist/es/2d/ratchet-2d.js +245 -0
- package/dist/es/build/build-information.js +1 -0
- package/dist/es/build/ratchet-common-info.js +14 -0
- package/dist/es/histogram/histogram-entry.js +1 -0
- package/dist/es/histogram/histogram.js +50 -0
- package/dist/es/index.js +71 -0
- package/dist/es/jwt/common-jwt-token.js +1 -0
- package/dist/es/jwt/expired-jwt-handling.js +6 -0
- package/dist/es/jwt/jwt-ratchet-like.js +1 -0
- package/dist/es/jwt/jwt-ratchet.js +159 -0
- package/dist/es/jwt/jwt-token-base.js +1 -0
- package/dist/es/lang/array-ratchet.js +83 -0
- package/dist/es/lang/base64-ratchet.js +45 -0
- package/dist/es/lang/boolean-ratchet.js +45 -0
- package/dist/es/lang/composite-last-success-provider.js +24 -0
- package/dist/es/lang/date-ratchet.js +29 -0
- package/dist/es/lang/duration-ratchet.js +42 -0
- package/dist/es/lang/enum-ratchet.js +30 -0
- package/dist/es/lang/error-ratchet.js +44 -0
- package/dist/es/lang/expiring-object.js +63 -0
- package/dist/es/lang/geolocation-ratchet.js +263 -0
- package/dist/es/lang/global-ratchet.js +43 -0
- package/dist/es/lang/key-value.js +2 -0
- package/dist/es/lang/last-success-provider.js +1 -0
- package/dist/es/lang/map-ratchet.js +164 -0
- package/dist/es/lang/no.js +4 -0
- package/dist/es/lang/number-ratchet.js +152 -0
- package/dist/es/lang/parsed-url.js +1 -0
- package/dist/es/lang/promise-ratchet.js +138 -0
- package/dist/es/lang/require-ratchet.js +56 -0
- package/dist/es/lang/stop-watch.js +113 -0
- package/dist/es/lang/string-ratchet.js +191 -0
- package/dist/es/lang/time-zone-ratchet.js +76 -0
- package/dist/es/lang/timeout-token.js +15 -0
- package/dist/es/lang/transform-ratchet.js +66 -0
- package/dist/es/logger/classic-single-line-log-message-formatter.js +13 -0
- package/dist/es/logger/log-message-builder.js +47 -0
- package/dist/es/logger/log-message-format-type.js +6 -0
- package/dist/es/logger/log-message-formatter.js +1 -0
- package/dist/es/logger/log-message-processor.js +1 -0
- package/dist/es/logger/log-message.js +1 -0
- package/dist/es/logger/log-snapshot.js +1 -0
- package/dist/es/logger/logger-instance.js +201 -0
- package/dist/es/logger/logger-level-name.js +9 -0
- package/dist/es/logger/logger-meta.js +1 -0
- package/dist/es/logger/logger-options.js +1 -0
- package/dist/es/logger/logger-output-function.js +6 -0
- package/dist/es/logger/logger-ring-buffer.js +72 -0
- package/dist/es/logger/logger-util.js +44 -0
- package/dist/es/logger/logger.js +134 -0
- package/dist/es/logger/none-log-message-formatter.js +5 -0
- package/dist/es/logger/structured-json-log-message-formatter.js +19 -0
- package/dist/es/network/browser-local-ip-provider.js +21 -0
- package/dist/es/network/fixed-local-ip-provider.js +8 -0
- package/dist/es/network/local-ip-provider.js +1 -0
- package/dist/es/network/network-ratchet.js +102 -0
- package/dist/es/stream/buffer-writable.js +16 -0
- package/dist/es/stream/stream-ratchet.js +68 -0
- package/dist/es/stream/string-writable.js +14 -0
- package/dist/es/third-party/google/google-recaptcha-ratchet.js +28 -0
- package/dist/es/third-party/twilio/twilio-ratchet.js +70 -0
- package/dist/es/transform/built-in-transforms.js +191 -0
- package/dist/es/transform/transform-rule.js +1 -0
- package/dist/es/tx/transaction-configuration.js +1 -0
- package/dist/es/tx/transaction-final-state.js +6 -0
- package/dist/es/tx/transaction-ratchet.js +76 -0
- package/dist/es/tx/transaction-result.js +1 -0
- package/dist/es/tx/transaction-step.js +1 -0
- package/dist/tsconfig.cjs.tsbuildinfo +1 -0
- package/dist/tsconfig.es.tsbuildinfo +1 -0
- package/dist/tsconfig.types.tsbuildinfo +1 -0
- package/dist/types/2d/line-2d.d.ts +5 -0
- package/dist/types/2d/plane-2d.d.ts +6 -0
- package/dist/types/2d/point-2d.d.ts +4 -0
- package/dist/types/2d/poly-line-2d.d.ts +4 -0
- package/dist/types/2d/ratchet-2d.d.ts +37 -0
- package/dist/types/build/build-information.d.ts +8 -0
- package/dist/types/build/ratchet-common-info.d.ts +5 -0
- package/dist/types/histogram/histogram-entry.d.ts +4 -0
- package/dist/types/histogram/histogram.d.ts +15 -0
- package/dist/types/index.d.ts +74 -0
- package/dist/types/jwt/common-jwt-token.d.ts +17 -0
- package/dist/types/jwt/expired-jwt-handling.d.ts +5 -0
- package/dist/types/jwt/jwt-ratchet-like.d.ts +18 -0
- package/dist/types/jwt/jwt-ratchet.d.ts +39 -0
- package/dist/types/jwt/jwt-token-base.d.ts +13 -0
- package/dist/types/lang/array-ratchet.d.ts +30 -0
- package/dist/types/lang/base64-ratchet.d.ts +10 -0
- package/dist/types/lang/boolean-ratchet.d.ts +7 -0
- package/dist/types/lang/composite-last-success-provider.d.ts +8 -0
- package/dist/types/lang/date-ratchet.d.ts +11 -0
- package/dist/types/lang/duration-ratchet.d.ts +7 -0
- package/dist/types/lang/enum-ratchet.d.ts +12 -0
- package/dist/types/lang/error-ratchet.d.ts +6 -0
- package/dist/types/lang/expiring-object.d.ts +20 -0
- package/dist/types/lang/geolocation-ratchet.d.ts +40 -0
- package/dist/types/lang/global-ratchet.d.ts +6 -0
- package/dist/types/lang/key-value.d.ts +4 -0
- package/dist/types/lang/last-success-provider.d.ts +4 -0
- package/dist/types/lang/map-ratchet.d.ts +15 -0
- package/dist/types/lang/no.d.ts +3 -0
- package/dist/types/lang/number-ratchet.d.ts +20 -0
- package/dist/types/lang/parsed-url.d.ts +10 -0
- package/dist/types/lang/promise-ratchet.d.ts +32 -0
- package/dist/types/lang/require-ratchet.d.ts +11 -0
- package/dist/types/lang/stop-watch.d.ts +17 -0
- package/dist/types/lang/string-ratchet.d.ts +27 -0
- package/dist/types/lang/time-zone-ratchet.d.ts +50 -0
- package/dist/types/lang/timeout-token.d.ts +9 -0
- package/dist/types/lang/transform-ratchet.d.ts +7 -0
- package/dist/types/logger/classic-single-line-log-message-formatter.d.ts +6 -0
- package/dist/types/logger/log-message-builder.d.ts +14 -0
- package/dist/types/logger/log-message-format-type.d.ts +5 -0
- package/dist/types/logger/log-message-formatter.d.ts +5 -0
- package/dist/types/logger/log-message-processor.d.ts +5 -0
- package/dist/types/logger/log-message.d.ts +8 -0
- package/dist/types/logger/log-snapshot.d.ts +5 -0
- package/dist/types/logger/logger-instance.d.ts +46 -0
- package/dist/types/logger/logger-level-name.d.ts +8 -0
- package/dist/types/logger/logger-meta.d.ts +6 -0
- package/dist/types/logger/logger-options.d.ts +13 -0
- package/dist/types/logger/logger-output-function.d.ts +5 -0
- package/dist/types/logger/logger-ring-buffer.d.ts +18 -0
- package/dist/types/logger/logger-util.d.ts +8 -0
- package/dist/types/logger/logger.d.ts +52 -0
- package/dist/types/logger/none-log-message-formatter.d.ts +6 -0
- package/dist/types/logger/structured-json-log-message-formatter.d.ts +6 -0
- package/dist/types/network/browser-local-ip-provider.d.ts +7 -0
- package/dist/types/network/fixed-local-ip-provider.d.ts +6 -0
- package/dist/types/network/local-ip-provider.d.ts +4 -0
- package/dist/types/network/network-ratchet.d.ts +9 -0
- package/dist/types/stream/buffer-writable.d.ts +9 -0
- package/dist/types/stream/stream-ratchet.d.ts +12 -0
- package/dist/types/stream/string-writable.d.ts +8 -0
- package/dist/types/third-party/google/google-recaptcha-ratchet.d.ts +4 -0
- package/dist/types/third-party/twilio/twilio-ratchet.d.ts +15 -0
- package/dist/types/transform/built-in-transforms.d.ts +18 -0
- package/dist/types/transform/transform-rule.d.ts +3 -0
- package/dist/types/tx/transaction-configuration.d.ts +7 -0
- package/dist/types/tx/transaction-final-state.d.ts +5 -0
- package/dist/types/tx/transaction-ratchet.d.ts +6 -0
- package/dist/types/tx/transaction-result.d.ts +9 -0
- package/dist/types/tx/transaction-step.d.ts +5 -0
- package/package.json +65 -0
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NetworkRatchet = void 0;
|
|
4
|
+
const logger_1 = require("../logger/logger");
|
|
5
|
+
class NetworkRatchet {
|
|
6
|
+
static findLocalIp(useCache = true) {
|
|
7
|
+
logger_1.Logger.info('Attempting to find local IP (V 2)');
|
|
8
|
+
if (NetworkRatchet.LOCAL_IP && useCache) {
|
|
9
|
+
return Promise.resolve(NetworkRatchet.LOCAL_IP);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
if (typeof window !== 'undefined') {
|
|
13
|
+
return new Promise(function (resolve, reject) {
|
|
14
|
+
try {
|
|
15
|
+
const RTCPeerConnection = window['RTCPeerConnection'] || window['webkitRTCPeerConnection'] || window['mozRTCPeerConnection'];
|
|
16
|
+
if (RTCPeerConnection) {
|
|
17
|
+
const rtc = new RTCPeerConnection({ iceServers: [] });
|
|
18
|
+
const addrs = Object.create(null);
|
|
19
|
+
addrs['0.0.0.0'] = false;
|
|
20
|
+
if (1 || window['mozRTCPeerConnection']) {
|
|
21
|
+
rtc.createDataChannel('', { reliable: false });
|
|
22
|
+
}
|
|
23
|
+
rtc.onicecandidate = function (evt) {
|
|
24
|
+
if (evt.candidate) {
|
|
25
|
+
NetworkRatchet.grepSDP('a=' + evt.candidate.candidate, addrs, resolve);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
rtc.createOffer(function (offerDesc) {
|
|
29
|
+
NetworkRatchet.grepSDP(offerDesc.sdp, addrs, resolve);
|
|
30
|
+
rtc.setLocalDescription(offerDesc);
|
|
31
|
+
}, function (e) {
|
|
32
|
+
logger_1.Logger.warn('Offer failed : %s', e);
|
|
33
|
+
resolve(NetworkRatchet.updateLocalIP('FIND_UNSUPPORTED'));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
logger_1.Logger.warn('IP Address find not supported on this device');
|
|
38
|
+
resolve(NetworkRatchet.updateLocalIP('FIND_UNSUPPORTED'));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
logger_1.Logger.warn('Error finding local ip address : %s', err);
|
|
43
|
+
resolve(NetworkRatchet.updateLocalIP('ERROR'));
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
logger_1.Logger.warn('Window not found, cannot calculate local ip');
|
|
49
|
+
return Promise.resolve(NetworkRatchet.updateLocalIP('NO_WINDOW'));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
static parseUrl(href) {
|
|
54
|
+
const match = href.match(/^(https?\:)\/\/(([^:\/?#]*)(?:\:([0-9]+))?)([\/]{0,1}[^?#]*)(\?[^#]*|)(#.*|)$/);
|
|
55
|
+
const rval = match &&
|
|
56
|
+
{
|
|
57
|
+
href: href,
|
|
58
|
+
protocol: match[1],
|
|
59
|
+
host: match[2],
|
|
60
|
+
hostname: match[3],
|
|
61
|
+
port: match[4],
|
|
62
|
+
pathname: match[5],
|
|
63
|
+
search: match[6],
|
|
64
|
+
hash: match[7],
|
|
65
|
+
};
|
|
66
|
+
return rval;
|
|
67
|
+
}
|
|
68
|
+
static updateLocalIP(newIp) {
|
|
69
|
+
NetworkRatchet.LOCAL_IP = newIp;
|
|
70
|
+
return NetworkRatchet.LOCAL_IP;
|
|
71
|
+
}
|
|
72
|
+
static grepSDP(sdp, addrs, resolve) {
|
|
73
|
+
const hosts = [];
|
|
74
|
+
sdp.split('\r\n').forEach(function (line) {
|
|
75
|
+
if (~line.indexOf('a=candidate')) {
|
|
76
|
+
const parts = line.split(' '), addr = parts[4], type = parts[7];
|
|
77
|
+
if (type === 'host') {
|
|
78
|
+
NetworkRatchet.updateAddressList(addr, addrs, resolve);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (~line.indexOf('c=')) {
|
|
82
|
+
const parts = line.split(' '), addr = parts[2];
|
|
83
|
+
NetworkRatchet.updateAddressList(addr, addrs, resolve);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
static updateAddressList(newAddr, addrs, resolve) {
|
|
88
|
+
if (newAddr in addrs)
|
|
89
|
+
return;
|
|
90
|
+
else
|
|
91
|
+
addrs[newAddr] = true;
|
|
92
|
+
const displayAddrs = Object.keys(addrs).filter(function (k) {
|
|
93
|
+
return addrs[k];
|
|
94
|
+
});
|
|
95
|
+
if (displayAddrs && displayAddrs.length == 1) {
|
|
96
|
+
resolve(NetworkRatchet.updateLocalIP(displayAddrs[0]));
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
const multi = displayAddrs.sort().join(',');
|
|
100
|
+
logger_1.Logger.warn('Multiple addresses found, returning sorted join : %s', multi);
|
|
101
|
+
resolve(NetworkRatchet.updateLocalIP(multi));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.NetworkRatchet = NetworkRatchet;
|
|
106
|
+
NetworkRatchet.LOCAL_IP = null;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BufferWritable = void 0;
|
|
4
|
+
const stream_1 = require("stream");
|
|
5
|
+
class BufferWritable extends stream_1.Writable {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
this._val = [];
|
|
9
|
+
}
|
|
10
|
+
_write(chunk, encoding, callback) {
|
|
11
|
+
if (chunk) {
|
|
12
|
+
this._val.push(chunk);
|
|
13
|
+
}
|
|
14
|
+
callback();
|
|
15
|
+
}
|
|
16
|
+
get value() {
|
|
17
|
+
return Buffer.concat(this._val);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.BufferWritable = BufferWritable;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StreamRatchet = void 0;
|
|
4
|
+
const stream_1 = require("stream");
|
|
5
|
+
const error_ratchet_1 = require("../lang/error-ratchet");
|
|
6
|
+
const string_ratchet_1 = require("../lang/string-ratchet");
|
|
7
|
+
class StreamRatchet {
|
|
8
|
+
constructor() { }
|
|
9
|
+
static readableToBufferSync(stream) {
|
|
10
|
+
const bufs = [];
|
|
11
|
+
let next = stream.read();
|
|
12
|
+
while (next) {
|
|
13
|
+
bufs.push(next);
|
|
14
|
+
next = stream.read();
|
|
15
|
+
}
|
|
16
|
+
return Buffer.concat(bufs);
|
|
17
|
+
}
|
|
18
|
+
static async webReadableStreamToBuffer(stream) {
|
|
19
|
+
const out = [];
|
|
20
|
+
const writer = new WritableStream({
|
|
21
|
+
async write(chunk, controller) {
|
|
22
|
+
if (typeof chunk === 'string') {
|
|
23
|
+
string_ratchet_1.StringRatchet.stringToUint8Array(chunk);
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
out.push(chunk);
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
},
|
|
30
|
+
abort(reason) {
|
|
31
|
+
error_ratchet_1.ErrorRatchet.throwFormattedErr('StringWebWritableStream failure : %s', reason);
|
|
32
|
+
},
|
|
33
|
+
}, {
|
|
34
|
+
highWaterMark: 3,
|
|
35
|
+
size: () => 1,
|
|
36
|
+
});
|
|
37
|
+
await stream.pipeTo(writer);
|
|
38
|
+
return Buffer.concat(out);
|
|
39
|
+
}
|
|
40
|
+
static async webReadableStreamToString(stream) {
|
|
41
|
+
const buf = await StreamRatchet.webReadableStreamToBuffer(stream);
|
|
42
|
+
return buf.toString();
|
|
43
|
+
}
|
|
44
|
+
static stringToReadable(input) {
|
|
45
|
+
return new stream_1.Readable({
|
|
46
|
+
read() {
|
|
47
|
+
this.push(input);
|
|
48
|
+
this.push(null);
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
static stringToWebReadableStream(input) {
|
|
53
|
+
const rval = new ReadableStream({
|
|
54
|
+
start(controller) {
|
|
55
|
+
if (input) {
|
|
56
|
+
controller.enqueue(input);
|
|
57
|
+
}
|
|
58
|
+
controller.close();
|
|
59
|
+
return null;
|
|
60
|
+
},
|
|
61
|
+
}, {
|
|
62
|
+
highWaterMark: input ? input.length : null,
|
|
63
|
+
});
|
|
64
|
+
return rval;
|
|
65
|
+
}
|
|
66
|
+
static anyToStringReadable(input) {
|
|
67
|
+
return input === null || input === undefined
|
|
68
|
+
? StreamRatchet.stringToReadable(null)
|
|
69
|
+
: StreamRatchet.stringToReadable(string_ratchet_1.StringRatchet.safeString(input));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.StreamRatchet = StreamRatchet;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.StringWritable = void 0;
|
|
4
|
+
const stream_1 = require("stream");
|
|
5
|
+
class StringWritable extends stream_1.Writable {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
this._val = '';
|
|
9
|
+
}
|
|
10
|
+
_write(chunk, encoding, callback) {
|
|
11
|
+
this._val += chunk ? chunk.toString() : '';
|
|
12
|
+
callback();
|
|
13
|
+
}
|
|
14
|
+
get value() {
|
|
15
|
+
return this._val;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.StringWritable = StringWritable;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GoogleRecaptchaRatchet = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const logger_1 = require("../../logger/logger");
|
|
6
|
+
const string_ratchet_1 = require("../../lang/string-ratchet");
|
|
7
|
+
const cross_fetch_1 = tslib_1.__importDefault(require("cross-fetch"));
|
|
8
|
+
class GoogleRecaptchaRatchet {
|
|
9
|
+
static async verifyRecaptchaToken(keySecret, token, fetchFn = cross_fetch_1.default) {
|
|
10
|
+
logger_1.Logger.debug('Verifying recaptcha token : %s', token);
|
|
11
|
+
let rval = null;
|
|
12
|
+
if (!string_ratchet_1.StringRatchet.safeString(token)) {
|
|
13
|
+
logger_1.Logger.warn('Recaptcha validation error, no token passed : %s', token);
|
|
14
|
+
return rval;
|
|
15
|
+
}
|
|
16
|
+
logger_1.Logger.info('Validating Recaptcha via Google API : %s', token);
|
|
17
|
+
let url = GoogleRecaptchaRatchet.GOOGLE_VERIFY_URL;
|
|
18
|
+
url = url.split('{{KEY}}').join(keySecret);
|
|
19
|
+
url = url.split('{{TOKEN}}').join(token);
|
|
20
|
+
try {
|
|
21
|
+
const resp = await fetchFn(url);
|
|
22
|
+
const body = await resp.json();
|
|
23
|
+
rval = body && body.success;
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
logger_1.Logger.error('Failed to read from google : %s', err);
|
|
27
|
+
rval = false;
|
|
28
|
+
}
|
|
29
|
+
return rval;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
exports.GoogleRecaptchaRatchet = GoogleRecaptchaRatchet;
|
|
33
|
+
GoogleRecaptchaRatchet.GOOGLE_VERIFY_URL = 'https://www.google.com/recaptcha/api/siteverify?secret={{KEY}}&response={{TOKEN}}';
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TwilioRatchet = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const cross_fetch_1 = tslib_1.__importDefault(require("cross-fetch"));
|
|
6
|
+
const require_ratchet_1 = require("../../lang/require-ratchet");
|
|
7
|
+
const base64_ratchet_1 = require("../../lang/base64-ratchet");
|
|
8
|
+
const string_ratchet_1 = require("../../lang/string-ratchet");
|
|
9
|
+
const logger_1 = require("../../logger/logger");
|
|
10
|
+
class TwilioRatchet {
|
|
11
|
+
constructor(accountSid, authToken, outBoundNumber) {
|
|
12
|
+
this.accountSid = accountSid;
|
|
13
|
+
this.authToken = authToken;
|
|
14
|
+
this.outBoundNumber = outBoundNumber;
|
|
15
|
+
require_ratchet_1.RequireRatchet.notNullOrUndefined(accountSid, 'accountSid');
|
|
16
|
+
require_ratchet_1.RequireRatchet.notNullOrUndefined(authToken, 'authToken');
|
|
17
|
+
require_ratchet_1.RequireRatchet.notNullOrUndefined(outBoundNumber, 'outBoundNumber');
|
|
18
|
+
require_ratchet_1.RequireRatchet.true(TwilioRatchet.isValidE164Number(outBoundNumber), 'outBoundNumber invalid format');
|
|
19
|
+
}
|
|
20
|
+
static async sendMessageDirect(accountSid, authToken, outBoundNumber, recipientPhoneNumbers, message) {
|
|
21
|
+
const ratchet = new TwilioRatchet(accountSid, authToken, outBoundNumber);
|
|
22
|
+
const rval = await ratchet.sendMessage(recipientPhoneNumbers, message);
|
|
23
|
+
return rval;
|
|
24
|
+
}
|
|
25
|
+
static generateTwilioBasicAuth(sid, authToken) {
|
|
26
|
+
const authHeader = 'Basic ' + base64_ratchet_1.Base64Ratchet.generateBase64VersionOfString(sid + ':' + authToken);
|
|
27
|
+
return authHeader;
|
|
28
|
+
}
|
|
29
|
+
async sendMessage(recipientPhoneNumbers, message) {
|
|
30
|
+
const rval = [];
|
|
31
|
+
require_ratchet_1.RequireRatchet.notNullOrUndefined(recipientPhoneNumbers, 'recipientPhoneNumbers');
|
|
32
|
+
require_ratchet_1.RequireRatchet.notNullOrUndefined(string_ratchet_1.StringRatchet.trimToNull(message), 'message');
|
|
33
|
+
require_ratchet_1.RequireRatchet.true(recipientPhoneNumbers.length > 0, 'recipientPhoneNumbers non-empty');
|
|
34
|
+
recipientPhoneNumbers.forEach((p) => {
|
|
35
|
+
require_ratchet_1.RequireRatchet.true(TwilioRatchet.isValidE164Number(p), p + ' is not valid');
|
|
36
|
+
});
|
|
37
|
+
if (!!recipientPhoneNumbers && recipientPhoneNumbers.length > 0 && !!string_ratchet_1.StringRatchet.trimToNull(message)) {
|
|
38
|
+
logger_1.Logger.info('Sending %s to %j', message, recipientPhoneNumbers);
|
|
39
|
+
for (let i = 0; i < recipientPhoneNumbers.length; i++) {
|
|
40
|
+
const phoneNumber = recipientPhoneNumbers[i];
|
|
41
|
+
logger_1.Logger.info('To: %s', phoneNumber);
|
|
42
|
+
if (!TwilioRatchet.isValidE164Number(phoneNumber)) {
|
|
43
|
+
throw new Error('number must be E164 format!');
|
|
44
|
+
}
|
|
45
|
+
const body = 'Body=' +
|
|
46
|
+
encodeURIComponent(message) +
|
|
47
|
+
'&From=' +
|
|
48
|
+
encodeURIComponent(this.outBoundNumber) +
|
|
49
|
+
'&To=' +
|
|
50
|
+
encodeURIComponent(phoneNumber);
|
|
51
|
+
const post = {
|
|
52
|
+
method: 'post',
|
|
53
|
+
headers: {
|
|
54
|
+
authorization: TwilioRatchet.generateTwilioBasicAuth(this.accountSid, this.authToken),
|
|
55
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
56
|
+
},
|
|
57
|
+
body: body,
|
|
58
|
+
};
|
|
59
|
+
const res = await (0, cross_fetch_1.default)(TwilioRatchet.TWILLIO_BASE_API_URL + '/Accounts/' + this.accountSid + '/Messages.json', post);
|
|
60
|
+
const parsedResponse = await res.json();
|
|
61
|
+
logger_1.Logger.debug('TwilioRatchet: For %s got %j', phoneNumber, parsedResponse);
|
|
62
|
+
rval.push(parsedResponse);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
logger_1.Logger.warn('Not sending empty message / empty recipients');
|
|
67
|
+
}
|
|
68
|
+
return rval;
|
|
69
|
+
}
|
|
70
|
+
static isValidE164Number(num) {
|
|
71
|
+
return /^\+?[1-9]\d{1,14}$/.test(num);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
exports.TwilioRatchet = TwilioRatchet;
|
|
75
|
+
TwilioRatchet.TWILLIO_BASE_API_URL = 'https://api.twilio.com/2010-04-01';
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BuiltInTransforms = void 0;
|
|
4
|
+
const logger_1 = require("../logger/logger");
|
|
5
|
+
const number_ratchet_1 = require("../lang/number-ratchet");
|
|
6
|
+
const luxon_1 = require("luxon");
|
|
7
|
+
class BuiltInTransforms {
|
|
8
|
+
static keysOnly(rule) {
|
|
9
|
+
return {
|
|
10
|
+
transform(value, isKey, context) {
|
|
11
|
+
return isKey ? rule.transform(value, isKey, context) : value;
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
static valuesOnly(rule) {
|
|
16
|
+
return {
|
|
17
|
+
transform(value, isKey, context) {
|
|
18
|
+
return !isKey ? rule.transform(value, isKey, context) : value;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
static stringReplaceTransform(input, output) {
|
|
23
|
+
return {
|
|
24
|
+
transform(value, isKey, context) {
|
|
25
|
+
return value == input ? output : value;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
static stripStringTransform(input) {
|
|
30
|
+
return {
|
|
31
|
+
transform(value, isKey, context) {
|
|
32
|
+
return value == input ? null : value;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
static retainAll(input) {
|
|
37
|
+
return {
|
|
38
|
+
transform(value, isKey, context) {
|
|
39
|
+
return input.indexOf(value) == -1 ? null : value;
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
static removeAll(input) {
|
|
44
|
+
return {
|
|
45
|
+
transform(value, isKey, context) {
|
|
46
|
+
return input.indexOf(value) > -1 ? null : value;
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
static snakeToCamelCase() {
|
|
51
|
+
return {
|
|
52
|
+
transform(value, isKey, context) {
|
|
53
|
+
let rval = value;
|
|
54
|
+
if (typeof value == 'string') {
|
|
55
|
+
rval = value.replace(/_([a-z0-9])/gi, function (s, group1) {
|
|
56
|
+
return group1.toUpperCase();
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return rval;
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
static stringToNumber() {
|
|
64
|
+
return {
|
|
65
|
+
transform(value, isKey, context) {
|
|
66
|
+
let rval = value;
|
|
67
|
+
if (typeof value == 'string') {
|
|
68
|
+
const num = number_ratchet_1.NumberRatchet.safeNumber(value);
|
|
69
|
+
if (num !== null) {
|
|
70
|
+
rval = num;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return rval;
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
static camelToSnakeCase() {
|
|
78
|
+
return {
|
|
79
|
+
transform(value, isKey, context) {
|
|
80
|
+
let rval = value;
|
|
81
|
+
if (typeof value == 'string') {
|
|
82
|
+
rval = value
|
|
83
|
+
.replace(/\.?([A-Z]+)/g, function (x, y) {
|
|
84
|
+
return '_' + y.toLowerCase();
|
|
85
|
+
})
|
|
86
|
+
.replace(/^_/, '');
|
|
87
|
+
}
|
|
88
|
+
return rval;
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
static concatenateToNewField(newFieldName, oldFieldNamesInOrder, abortIfFieldMissing = true) {
|
|
93
|
+
return {
|
|
94
|
+
transform(value, isKey, context) {
|
|
95
|
+
if (typeof value == 'object') {
|
|
96
|
+
let rval = '';
|
|
97
|
+
oldFieldNamesInOrder.forEach((n) => {
|
|
98
|
+
if (rval != null) {
|
|
99
|
+
const temp = value[n];
|
|
100
|
+
if (temp == null && abortIfFieldMissing) {
|
|
101
|
+
rval = null;
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
rval = temp == null ? rval : rval + String(temp);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
if (rval != null) {
|
|
109
|
+
value[newFieldName] = rval;
|
|
110
|
+
oldFieldNamesInOrder.forEach((n) => delete value[n]);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return value;
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
static numberToBool(fieldNames) {
|
|
118
|
+
return {
|
|
119
|
+
transform(value, isKey, context) {
|
|
120
|
+
if (typeof value == 'object') {
|
|
121
|
+
fieldNames.forEach((n) => {
|
|
122
|
+
const oldVal = value[n];
|
|
123
|
+
if (typeof oldVal == 'number') {
|
|
124
|
+
const newVal = 0 != oldVal;
|
|
125
|
+
value[n] = newVal;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return value;
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
static boolToNumber(fieldNames) {
|
|
134
|
+
return {
|
|
135
|
+
transform(value, isKey, context) {
|
|
136
|
+
if (typeof value == 'object') {
|
|
137
|
+
fieldNames.forEach((n) => {
|
|
138
|
+
const oldVal = value[n];
|
|
139
|
+
if (typeof oldVal == 'boolean') {
|
|
140
|
+
const newVal = oldVal ? 1 : 0;
|
|
141
|
+
value[n] = newVal;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return value;
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
static makeDuplicateField(oldName, newName) {
|
|
150
|
+
return {
|
|
151
|
+
transform(value, isKey, context) {
|
|
152
|
+
if (typeof value == 'object') {
|
|
153
|
+
const oldVal = value[oldName];
|
|
154
|
+
if (oldVal != null) {
|
|
155
|
+
value[newName] = oldVal;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return value;
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
static addField(name, valueToAdd) {
|
|
163
|
+
return {
|
|
164
|
+
transform(value, isKey, context) {
|
|
165
|
+
if (typeof value == 'object') {
|
|
166
|
+
value[name] = valueToAdd;
|
|
167
|
+
}
|
|
168
|
+
return value;
|
|
169
|
+
},
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
static reformatDateFields(fieldNames, oldFormat, newFormat) {
|
|
173
|
+
return {
|
|
174
|
+
transform(value, isKey, context) {
|
|
175
|
+
if (typeof value == 'object') {
|
|
176
|
+
fieldNames.forEach((key) => {
|
|
177
|
+
const oldValue = value[key];
|
|
178
|
+
if (oldValue != null) {
|
|
179
|
+
try {
|
|
180
|
+
const parsed = luxon_1.DateTime.fromFormat(oldValue, oldFormat);
|
|
181
|
+
const newValue = parsed.toFormat(newFormat);
|
|
182
|
+
value[key] = newValue;
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
logger_1.Logger.warn('Failed to reparse date %s in format %s : %s', oldValue, oldFormat, err);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
return value;
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
exports.BuiltInTransforms = BuiltInTransforms;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TransactionFinalState = void 0;
|
|
4
|
+
var TransactionFinalState;
|
|
5
|
+
(function (TransactionFinalState) {
|
|
6
|
+
TransactionFinalState["Success"] = "Success";
|
|
7
|
+
TransactionFinalState["RolledBack"] = "RolledBack";
|
|
8
|
+
TransactionFinalState["RollbackFailed"] = "RollbackFailed";
|
|
9
|
+
})(TransactionFinalState = exports.TransactionFinalState || (exports.TransactionFinalState = {}));
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TransactionRatchet = void 0;
|
|
4
|
+
const logger_1 = require("../logger/logger");
|
|
5
|
+
const require_ratchet_1 = require("../lang/require-ratchet");
|
|
6
|
+
const logger_level_name_1 = require("../logger/logger-level-name");
|
|
7
|
+
const transaction_final_state_1 = require("./transaction-final-state");
|
|
8
|
+
class TransactionRatchet {
|
|
9
|
+
static async execute(steps, initialContext, inConfiguration) {
|
|
10
|
+
require_ratchet_1.RequireRatchet.notNullOrUndefined(steps, 'steps');
|
|
11
|
+
require_ratchet_1.RequireRatchet.notNullOrUndefined(initialContext, 'initialContext');
|
|
12
|
+
require_ratchet_1.RequireRatchet.true(steps.length > 0, 'steps may not be empty');
|
|
13
|
+
const config = Object.assign({}, inConfiguration || {});
|
|
14
|
+
config.stepLogLevel = config.stepLogLevel || logger_level_name_1.LoggerLevelName.info;
|
|
15
|
+
const rval = {
|
|
16
|
+
finalContext: initialContext,
|
|
17
|
+
finalState: null,
|
|
18
|
+
};
|
|
19
|
+
const stepNames = steps.map((s, idx) => s.name || 'Step ' + idx);
|
|
20
|
+
logger_1.Logger.info('Beginning transaction of %d steps', steps.length);
|
|
21
|
+
let idx = 0;
|
|
22
|
+
do {
|
|
23
|
+
logger_1.Logger.logByLevel(config.stepLogLevel, 'Processing step %d of %d (%s)', idx + 1, steps.length, stepNames[idx]);
|
|
24
|
+
try {
|
|
25
|
+
await steps[idx].execute(rval.finalContext, idx);
|
|
26
|
+
idx++;
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
logger_1.Logger.error('Failure detected on step %d : %s : %s : Rolling back', idx, stepNames[idx], err, err);
|
|
30
|
+
rval.error = err;
|
|
31
|
+
rval.errorStep = idx;
|
|
32
|
+
}
|
|
33
|
+
} while (!rval.error && idx < steps.length);
|
|
34
|
+
if (rval.error) {
|
|
35
|
+
do {
|
|
36
|
+
logger_1.Logger.logByLevel(config.stepLogLevel, 'Rolling back step %d of %d (%s)', idx + 1, steps.length, stepNames[idx]);
|
|
37
|
+
try {
|
|
38
|
+
if (steps[idx].rollback) {
|
|
39
|
+
await steps[idx].rollback(rval.finalContext, idx);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
logger_1.Logger.info('Skipping - no rollback defined');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
logger_1.Logger.error('Very bad - rollback code failed on step %d : %s : Aborting in invalid state: %s', idx, stepNames[idx], err, err);
|
|
47
|
+
rval.rollbackError = err;
|
|
48
|
+
rval.rollbackErrorStep = idx;
|
|
49
|
+
}
|
|
50
|
+
idx--;
|
|
51
|
+
} while (idx >= 0);
|
|
52
|
+
}
|
|
53
|
+
rval.finalState = rval.rollbackError
|
|
54
|
+
? transaction_final_state_1.TransactionFinalState.RollbackFailed
|
|
55
|
+
: rval.error
|
|
56
|
+
? transaction_final_state_1.TransactionFinalState.RolledBack
|
|
57
|
+
: transaction_final_state_1.TransactionFinalState.Success;
|
|
58
|
+
logger_1.Logger.info('Transaction completed with status : %s', rval.finalState);
|
|
59
|
+
if ((config === null || config === void 0 ? void 0 : config.executeAfterRollback) && rval.finalState !== transaction_final_state_1.TransactionFinalState.Success) {
|
|
60
|
+
try {
|
|
61
|
+
logger_1.Logger.info('Applying executeAfterRollback');
|
|
62
|
+
await config.executeAfterRollback(rval);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
logger_1.Logger.error('Very bad - failure in executeAfterRollback : %s', err, err);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if ((config === null || config === void 0 ? void 0 : config.executeAfterRollbackFailure) && rval.finalState !== transaction_final_state_1.TransactionFinalState.Success) {
|
|
69
|
+
try {
|
|
70
|
+
logger_1.Logger.info('Applying executeAfterRollbackFailure');
|
|
71
|
+
await config.executeAfterRollbackFailure(rval);
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
logger_1.Logger.error('Very bad - failure in executeAfterRollbackFailure : %s', err, err);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return rval;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.TransactionRatchet = TransactionRatchet;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|