ts-server-lib 0.0.17
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/LICENSE +1 -0
- package/README.md +8 -0
- package/db/TSMongo.d.ts +103 -0
- package/db/TSMongo.js +483 -0
- package/db/TSRQW.d.ts +271 -0
- package/db/TSRQW.js +699 -0
- package/db/TSRedis.d.ts +174 -0
- package/db/TSRedis.js +602 -0
- package/package.json +85 -0
- package/ussd/TSUssdMenu.d.ts +139 -0
- package/ussd/TSUssdMenu.js +364 -0
- package/ussd/TSUssdScreen.d.ts +58 -0
- package/ussd/TSUssdScreen.js +218 -0
- package/ussd/index.d.ts +3 -0
- package/ussd/index.js +19 -0
- package/ussd/providers/AfricasTalking.d.ts +3 -0
- package/ussd/providers/AfricasTalking.js +17 -0
- package/ussd/providers/AirtelDRC.d.ts +9 -0
- package/ussd/providers/AirtelDRC.js +31 -0
- package/ussd/providers/OrangeDRC.d.ts +5 -0
- package/ussd/providers/OrangeDRC.js +213 -0
- package/ussd/providers/VodacomDRC.d.ts +9 -0
- package/ussd/providers/VodacomDRC.js +48 -0
- package/ussd/providers/_.d.ts +55 -0
- package/ussd/providers/_.js +83 -0
- package/ussd/providers/index.d.ts +13 -0
- package/ussd/providers/index.js +56 -0
- package/utils/TSFile.d.ts +36 -0
- package/utils/TSFile.js +244 -0
- package/utils/TSHash.d.ts +20 -0
- package/utils/TSHash.js +75 -0
- package/utils/TSRequest.d.ts +39 -0
- package/utils/TSRequest.js +256 -0
- package/utils/TSStub.d.ts +159 -0
- package/utils/TSStub.js +296 -0
- package/utils/abort.d.ts +18 -0
- package/utils/abort.js +97 -0
- package/utils/mime.json +11358 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* USSD Menu with state
|
|
3
|
+
*
|
|
4
|
+
* - General rules
|
|
5
|
+
* - Routing
|
|
6
|
+
* - ussd text in form 1*2*7
|
|
7
|
+
* - * bring back to start menu
|
|
8
|
+
*
|
|
9
|
+
* - Development Section
|
|
10
|
+
* - To publish local ussd receiver to remote through ssh
|
|
11
|
+
* # ssh -R 9093:localhost:9090 root@185.41.154.247 -N
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
import { EventEmitter } from 'events';
|
|
15
|
+
export declare class TSUssdState {
|
|
16
|
+
menu: TSUssdMenu;
|
|
17
|
+
name: string | null;
|
|
18
|
+
run: ((state: TSUssdState) => void) | null;
|
|
19
|
+
defaultNext: string | null;
|
|
20
|
+
val: string | null;
|
|
21
|
+
next: Record<string, unknown> | null;
|
|
22
|
+
constructor(menu: TSUssdMenu);
|
|
23
|
+
}
|
|
24
|
+
export declare class TSUssdMenu extends EventEmitter {
|
|
25
|
+
map: Record<string, unknown>;
|
|
26
|
+
static START_STATE: string;
|
|
27
|
+
static config: any;
|
|
28
|
+
session: any;
|
|
29
|
+
args: any;
|
|
30
|
+
states: any;
|
|
31
|
+
result: string;
|
|
32
|
+
onResult: any;
|
|
33
|
+
current: any;
|
|
34
|
+
val: string;
|
|
35
|
+
static forOwn(items: unknown[] | Record<string, unknown>, cb: (v: unknown, key?: number | string) => void): void;
|
|
36
|
+
static mapArgs(args?: Record<string, unknown>, map?: Record<string, unknown>): Record<string, unknown>;
|
|
37
|
+
static cleanRoute(route: string): string;
|
|
38
|
+
constructor(args: Record<string, unknown> | undefined, map: Record<string, unknown>);
|
|
39
|
+
/**
|
|
40
|
+
* A callback after result is set
|
|
41
|
+
*/
|
|
42
|
+
callOnResult(): void;
|
|
43
|
+
/**
|
|
44
|
+
* This method send message to the client and take the session opened
|
|
45
|
+
*
|
|
46
|
+
* @param text string Message to sent
|
|
47
|
+
*/
|
|
48
|
+
con(text: string): string;
|
|
49
|
+
/**
|
|
50
|
+
* This method send message to the client and close the session
|
|
51
|
+
*
|
|
52
|
+
* @param text string Message to sent
|
|
53
|
+
*/
|
|
54
|
+
end(text: string): string;
|
|
55
|
+
/**
|
|
56
|
+
* This method format the message and if debug calcualte the length
|
|
57
|
+
*
|
|
58
|
+
* @param text string Message to sent
|
|
59
|
+
*/
|
|
60
|
+
print(text: string): string;
|
|
61
|
+
testLinkRule(rule: string | RegExp | unknown, val: string): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Find state based on route — async/await, no external dependencies.
|
|
64
|
+
*
|
|
65
|
+
* next values may be: a string, a callback-based function (cb) => void,
|
|
66
|
+
* a function returning a string synchronously, or a function returning a Promise.
|
|
67
|
+
*/
|
|
68
|
+
resolveRoute(route: string): Promise<TSUssdState | undefined>;
|
|
69
|
+
runState(state: TSUssdState): boolean | undefined;
|
|
70
|
+
go(stateName: string): void;
|
|
71
|
+
goStart(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Configure custom session handler cross-compatible between callbacks and promises
|
|
74
|
+
*
|
|
75
|
+
* @example Memory configuration example with callback
|
|
76
|
+
*
|
|
77
|
+
* let sessions = {};
|
|
78
|
+
* let menu = new UssdMenu();
|
|
79
|
+
* menu.sessionConfig({
|
|
80
|
+
* start: (sessionId, callback) {
|
|
81
|
+
* // initialize current session if it doesn't exist this is called by menu.run()
|
|
82
|
+
* if(!(sessionId in sessions)) sessions[sessionId] = {};
|
|
83
|
+
* callback();
|
|
84
|
+
* },
|
|
85
|
+
* end: (sessionId, callback) {
|
|
86
|
+
* // clear current session this is called by menu.end()
|
|
87
|
+
* delete sessions[sessionId];
|
|
88
|
+
* callback();
|
|
89
|
+
* },
|
|
90
|
+
* set: (sessionId, key, value, callback) {
|
|
91
|
+
* // store key-value pair in current session
|
|
92
|
+
* sessions[sessionId][key] = value;
|
|
93
|
+
* callback();
|
|
94
|
+
* },
|
|
95
|
+
* get: (sessionId, key, callback) {
|
|
96
|
+
* // retrieve value by key in current session
|
|
97
|
+
* callback(null, sessions[sessionId][key]);
|
|
98
|
+
* },
|
|
99
|
+
* del: (sessionId, key, callback) {
|
|
100
|
+
* delete sessions[sessionId][key];
|
|
101
|
+
* callback();
|
|
102
|
+
* }
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* @param {Object} c object with implementation for get, set, start and end methods
|
|
106
|
+
* @param {String} a attribute of args
|
|
107
|
+
*/
|
|
108
|
+
sessionConfig(c: Record<string, (...args: unknown[]) => unknown>, a?: string): void;
|
|
109
|
+
/**
|
|
110
|
+
* Create a state on the ussd chain
|
|
111
|
+
*
|
|
112
|
+
* @param string name name of the state
|
|
113
|
+
* @param object options
|
|
114
|
+
* @param object options.next object mapping of route val to state names
|
|
115
|
+
* @param string options.defaultNext name of state to run when the given route from this state can't be resolved
|
|
116
|
+
* @param function options.run the method to run when this state is resolved
|
|
117
|
+
* @return TSUssdMenu the same instance of Ussd
|
|
118
|
+
*/
|
|
119
|
+
state(name: string, options: {
|
|
120
|
+
next?: Record<string, unknown>;
|
|
121
|
+
defaultNext?: string;
|
|
122
|
+
run?: (state: TSUssdState) => void;
|
|
123
|
+
}): this;
|
|
124
|
+
/**
|
|
125
|
+
* Create the start state of the ussd chain
|
|
126
|
+
*/
|
|
127
|
+
startState(options: {
|
|
128
|
+
next?: Record<string, unknown>;
|
|
129
|
+
defaultNext?: string;
|
|
130
|
+
run?: (state: TSUssdState) => void;
|
|
131
|
+
}): this;
|
|
132
|
+
/**
|
|
133
|
+
* Run the ussd menu
|
|
134
|
+
*
|
|
135
|
+
* @param function onResult a callback to handle on result
|
|
136
|
+
* @param TSUssdArgs options request args from the gateway api
|
|
137
|
+
*/
|
|
138
|
+
run(onResult: (result: string) => void, map: Record<string, unknown>): void;
|
|
139
|
+
}
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TSUssdMenu = exports.TSUssdState = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* USSD Menu with state
|
|
6
|
+
*
|
|
7
|
+
* - General rules
|
|
8
|
+
* - Routing
|
|
9
|
+
* - ussd text in form 1*2*7
|
|
10
|
+
* - * bring back to start menu
|
|
11
|
+
*
|
|
12
|
+
* - Development Section
|
|
13
|
+
* - To publish local ussd receiver to remote through ssh
|
|
14
|
+
* # ssh -R 9093:localhost:9090 root@185.41.154.247 -N
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
const events_1 = require("events");
|
|
18
|
+
class TSUssdState {
|
|
19
|
+
menu;
|
|
20
|
+
name;
|
|
21
|
+
run;
|
|
22
|
+
defaultNext;
|
|
23
|
+
val;
|
|
24
|
+
next = null;
|
|
25
|
+
constructor(menu) {
|
|
26
|
+
this.menu = menu;
|
|
27
|
+
this.name = null;
|
|
28
|
+
this.run = null;
|
|
29
|
+
this.defaultNext = null;
|
|
30
|
+
this.val = null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
exports.TSUssdState = TSUssdState;
|
|
34
|
+
class TSUssdMenu extends events_1.EventEmitter {
|
|
35
|
+
map;
|
|
36
|
+
static START_STATE = '__start__';
|
|
37
|
+
static config = {
|
|
38
|
+
debug: true,
|
|
39
|
+
general: { separator: ')' },
|
|
40
|
+
navigation: { back: '00', main: '01' },
|
|
41
|
+
pager: {
|
|
42
|
+
default: 3, maxLength: 90, mapping: {},
|
|
43
|
+
strategies: [{ term: ' - ', enabled: true, type: 'truncate' }]
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
session;
|
|
47
|
+
args;
|
|
48
|
+
states;
|
|
49
|
+
result;
|
|
50
|
+
onResult;
|
|
51
|
+
current;
|
|
52
|
+
val;
|
|
53
|
+
static forOwn(items, cb) {
|
|
54
|
+
const obj = items;
|
|
55
|
+
for (const i in obj) {
|
|
56
|
+
if (Object.hasOwn(obj, i)) {
|
|
57
|
+
cb(obj[i], i);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
static mapArgs(args = {}, map = {}) {
|
|
62
|
+
const results = { provider: map.provider };
|
|
63
|
+
for (const p in args) {
|
|
64
|
+
if (Object.hasOwn(args, p) && Object.hasOwn(map, p)) {
|
|
65
|
+
results[String(map[p])] = args[p];
|
|
66
|
+
}
|
|
67
|
+
else if (Object.hasOwn(args, p)) {
|
|
68
|
+
results[p] = args[p];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return results;
|
|
72
|
+
}
|
|
73
|
+
static cleanRoute(route) {
|
|
74
|
+
if (route && route.includes('*000')) {
|
|
75
|
+
const reset = route.substring(route.lastIndexOf('*000') + 4);
|
|
76
|
+
route = '*' + (reset === '0' ? '' : reset);
|
|
77
|
+
}
|
|
78
|
+
return route;
|
|
79
|
+
}
|
|
80
|
+
constructor(args = {}, map) {
|
|
81
|
+
super();
|
|
82
|
+
this.map = map;
|
|
83
|
+
this.session = null;
|
|
84
|
+
this.args = TSUssdMenu.mapArgs(args, map);
|
|
85
|
+
this.states = {};
|
|
86
|
+
this.result = '';
|
|
87
|
+
this.onResult = null;
|
|
88
|
+
this.val = '';
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* A callback after result is set
|
|
92
|
+
*/
|
|
93
|
+
callOnResult() {
|
|
94
|
+
if (this.onResult) {
|
|
95
|
+
this.onResult(this.result);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* This method send message to the client and take the session opened
|
|
100
|
+
*
|
|
101
|
+
* @param text string Message to sent
|
|
102
|
+
*/
|
|
103
|
+
con(text) {
|
|
104
|
+
this.result = 'CON ' + this.print(text);
|
|
105
|
+
this.callOnResult();
|
|
106
|
+
return this.result;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* This method send message to the client and close the session
|
|
110
|
+
*
|
|
111
|
+
* @param text string Message to sent
|
|
112
|
+
*/
|
|
113
|
+
end(text) {
|
|
114
|
+
this.result = 'END ' + this.print(text);
|
|
115
|
+
this.callOnResult();
|
|
116
|
+
if (this.session) {
|
|
117
|
+
this.session.end();
|
|
118
|
+
}
|
|
119
|
+
return this.result;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* This method format the message and if debug calcualte the length
|
|
123
|
+
*
|
|
124
|
+
* @param text string Message to sent
|
|
125
|
+
*/
|
|
126
|
+
print(text) {
|
|
127
|
+
return TSUssdMenu.config.debug ? '[' + (this.current ? this.current.name : 'N/A') + ':' + text.length + '] ' + text : text;
|
|
128
|
+
}
|
|
129
|
+
testLinkRule(rule, val) {
|
|
130
|
+
// if rule starts with *, treat as regex
|
|
131
|
+
if (typeof rule === 'string' && rule.startsWith('*')) {
|
|
132
|
+
return new RegExp(rule.substring(1)).test(val);
|
|
133
|
+
}
|
|
134
|
+
return rule === val;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Find state based on route — async/await, no external dependencies.
|
|
138
|
+
*
|
|
139
|
+
* next values may be: a string, a callback-based function (cb) => void,
|
|
140
|
+
* a function returning a string synchronously, or a function returning a Promise.
|
|
141
|
+
*/
|
|
142
|
+
async resolveRoute(route) {
|
|
143
|
+
route = TSUssdMenu.cleanRoute(route);
|
|
144
|
+
const parts = !route ? [] : route.split('*');
|
|
145
|
+
let state = this.states[TSUssdMenu.START_STATE];
|
|
146
|
+
if (!state.next || Object.keys(state.next).length === 0) {
|
|
147
|
+
return this.states[state.defaultNext];
|
|
148
|
+
}
|
|
149
|
+
if ('' in state.next) {
|
|
150
|
+
parts.unshift('');
|
|
151
|
+
}
|
|
152
|
+
while (parts.length > 0) {
|
|
153
|
+
const part = parts.shift();
|
|
154
|
+
let nextFound = false;
|
|
155
|
+
this.val = part ?? '';
|
|
156
|
+
for (const [link, next] of Object.entries(state.next)) {
|
|
157
|
+
if (!this.testLinkRule(link, part ?? ''))
|
|
158
|
+
continue;
|
|
159
|
+
let nextPath;
|
|
160
|
+
if (typeof next === 'string') {
|
|
161
|
+
nextPath = next;
|
|
162
|
+
}
|
|
163
|
+
else if (typeof next === 'function') {
|
|
164
|
+
// supports: callback-based fn(cb), sync-returning fn, and promise-returning fn
|
|
165
|
+
nextPath = await new Promise((resolve, reject) => {
|
|
166
|
+
const result = next(resolve);
|
|
167
|
+
if (typeof result === 'string')
|
|
168
|
+
resolve(result);
|
|
169
|
+
else if (result && typeof result.then === 'function')
|
|
170
|
+
result.then(resolve).catch(reject);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
if (!nextPath)
|
|
174
|
+
continue;
|
|
175
|
+
state = this.states[nextPath];
|
|
176
|
+
this.current = state;
|
|
177
|
+
if (!state)
|
|
178
|
+
throw new Error(`[TSUssdMenu]: declared state does not exist: ${nextPath}`);
|
|
179
|
+
state.val = part ?? '';
|
|
180
|
+
nextFound = true;
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
if (!nextFound && state.defaultNext) {
|
|
184
|
+
state = this.states[state.defaultNext];
|
|
185
|
+
this.current = state;
|
|
186
|
+
state.val = part;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return state;
|
|
190
|
+
}
|
|
191
|
+
runState(state) {
|
|
192
|
+
if (!state.run) {
|
|
193
|
+
return this.emit('error', new Error(`run function not defined for state: ${state.name}`));
|
|
194
|
+
}
|
|
195
|
+
state.run(state);
|
|
196
|
+
}
|
|
197
|
+
go(stateName) {
|
|
198
|
+
const state = this.states[stateName];
|
|
199
|
+
state.val = this.val;
|
|
200
|
+
this.current = state;
|
|
201
|
+
this.runState(state);
|
|
202
|
+
}
|
|
203
|
+
goStart() {
|
|
204
|
+
this.go(TSUssdMenu.START_STATE);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Configure custom session handler cross-compatible between callbacks and promises
|
|
208
|
+
*
|
|
209
|
+
* @example Memory configuration example with callback
|
|
210
|
+
*
|
|
211
|
+
* let sessions = {};
|
|
212
|
+
* let menu = new UssdMenu();
|
|
213
|
+
* menu.sessionConfig({
|
|
214
|
+
* start: (sessionId, callback) {
|
|
215
|
+
* // initialize current session if it doesn't exist this is called by menu.run()
|
|
216
|
+
* if(!(sessionId in sessions)) sessions[sessionId] = {};
|
|
217
|
+
* callback();
|
|
218
|
+
* },
|
|
219
|
+
* end: (sessionId, callback) {
|
|
220
|
+
* // clear current session this is called by menu.end()
|
|
221
|
+
* delete sessions[sessionId];
|
|
222
|
+
* callback();
|
|
223
|
+
* },
|
|
224
|
+
* set: (sessionId, key, value, callback) {
|
|
225
|
+
* // store key-value pair in current session
|
|
226
|
+
* sessions[sessionId][key] = value;
|
|
227
|
+
* callback();
|
|
228
|
+
* },
|
|
229
|
+
* get: (sessionId, key, callback) {
|
|
230
|
+
* // retrieve value by key in current session
|
|
231
|
+
* callback(null, sessions[sessionId][key]);
|
|
232
|
+
* },
|
|
233
|
+
* del: (sessionId, key, callback) {
|
|
234
|
+
* delete sessions[sessionId][key];
|
|
235
|
+
* callback();
|
|
236
|
+
* }
|
|
237
|
+
* });
|
|
238
|
+
*
|
|
239
|
+
* @param {Object} c object with implementation for get, set, start and end methods
|
|
240
|
+
* @param {String} a attribute of args
|
|
241
|
+
*/
|
|
242
|
+
sessionConfig(c, a = 'sessionId') {
|
|
243
|
+
// creates a callback that calls the promise resolve and reject functions as well as the provided callback
|
|
244
|
+
const makeCb = (resolve, reject, cb) => (err, res) => {
|
|
245
|
+
if (err) {
|
|
246
|
+
if (cb) {
|
|
247
|
+
cb(err);
|
|
248
|
+
}
|
|
249
|
+
reject(err);
|
|
250
|
+
this.emit('error', err);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
if (cb) {
|
|
254
|
+
cb(null, res);
|
|
255
|
+
}
|
|
256
|
+
resolve(res);
|
|
257
|
+
}
|
|
258
|
+
};
|
|
259
|
+
// if p is a promise, handle its resolve and reject chains and invoke the provided callback
|
|
260
|
+
const resolveIfPromise = (p, resolve, reject, cb) => {
|
|
261
|
+
if (p && typeof p.then === 'function') {
|
|
262
|
+
p.then((res) => {
|
|
263
|
+
if (cb) {
|
|
264
|
+
cb(null, res);
|
|
265
|
+
}
|
|
266
|
+
resolve(res);
|
|
267
|
+
}).catch((err) => {
|
|
268
|
+
if (cb) {
|
|
269
|
+
cb(err);
|
|
270
|
+
}
|
|
271
|
+
reject(err);
|
|
272
|
+
this.emit('error', err);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
// implement session methods based on user-defined handlers
|
|
277
|
+
this.session = {
|
|
278
|
+
start: async (cb) => new Promise((resolve, reject) => {
|
|
279
|
+
const res = c.start(this.args[a], makeCb(resolve, reject, cb));
|
|
280
|
+
resolveIfPromise(res, resolve, reject, cb);
|
|
281
|
+
}),
|
|
282
|
+
get: async (key, cb) => new Promise((resolve, reject) => {
|
|
283
|
+
const res = c.get(this.args[a], key, makeCb(resolve, reject, cb));
|
|
284
|
+
resolveIfPromise(res, resolve, reject, cb);
|
|
285
|
+
}),
|
|
286
|
+
del: async (key, cb) => new Promise((resolve, reject) => {
|
|
287
|
+
const res = c.del(this.args[a], key, makeCb(resolve, reject, cb));
|
|
288
|
+
resolveIfPromise(res, resolve, reject, cb);
|
|
289
|
+
}),
|
|
290
|
+
set: async (key, val, cb) => new Promise((resolve, reject) => {
|
|
291
|
+
const res = c.set(this.args[a], key, val, makeCb(resolve, reject, cb));
|
|
292
|
+
resolveIfPromise(res, resolve, reject, cb);
|
|
293
|
+
}),
|
|
294
|
+
end: async (cb) => new Promise((resolve, reject) => {
|
|
295
|
+
const res = c.end(this.args[a], makeCb(resolve, reject, cb));
|
|
296
|
+
resolveIfPromise(res, resolve, reject, cb);
|
|
297
|
+
})
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Create a state on the ussd chain
|
|
302
|
+
*
|
|
303
|
+
* @param string name name of the state
|
|
304
|
+
* @param object options
|
|
305
|
+
* @param object options.next object mapping of route val to state names
|
|
306
|
+
* @param string options.defaultNext name of state to run when the given route from this state can't be resolved
|
|
307
|
+
* @param function options.run the method to run when this state is resolved
|
|
308
|
+
* @return TSUssdMenu the same instance of Ussd
|
|
309
|
+
*/
|
|
310
|
+
state(name, options) {
|
|
311
|
+
const state = new TSUssdState(this);
|
|
312
|
+
this.states[name] = state;
|
|
313
|
+
state.name = name;
|
|
314
|
+
state.next = options.next ?? null;
|
|
315
|
+
state.run = options.run ?? null;
|
|
316
|
+
// default defaultNext to same state
|
|
317
|
+
state.defaultNext = options.defaultNext || name;
|
|
318
|
+
return this;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Create the start state of the ussd chain
|
|
322
|
+
*/
|
|
323
|
+
startState(options) {
|
|
324
|
+
return this.state(TSUssdMenu.START_STATE, options);
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Run the ussd menu
|
|
328
|
+
*
|
|
329
|
+
* @param function onResult a callback to handle on result
|
|
330
|
+
* @param TSUssdArgs options request args from the gateway api
|
|
331
|
+
*/
|
|
332
|
+
run(onResult, map) {
|
|
333
|
+
if (map.provider !== this.args.provider) {
|
|
334
|
+
this.args = TSUssdMenu.mapArgs(this.args, map);
|
|
335
|
+
}
|
|
336
|
+
const mapAny = map;
|
|
337
|
+
const mapUnderscore = mapAny._;
|
|
338
|
+
if (mapUnderscore?.[String(this.args.phoneNumber)] && /\d/.test(String(mapUnderscore[String(this.args.phoneNumber)]))) {
|
|
339
|
+
this.args.phoneNumber = mapUnderscore[String(this.args.phoneNumber)];
|
|
340
|
+
}
|
|
341
|
+
else if (mapUnderscore) {
|
|
342
|
+
this.args._ = mapUnderscore;
|
|
343
|
+
}
|
|
344
|
+
this.onResult = onResult;
|
|
345
|
+
const run = async () => {
|
|
346
|
+
try {
|
|
347
|
+
const state = await this.resolveRoute(this.args.message);
|
|
348
|
+
this.current = state;
|
|
349
|
+
if (state)
|
|
350
|
+
this.runState(state);
|
|
351
|
+
}
|
|
352
|
+
catch (err) {
|
|
353
|
+
this.emit('error', err);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
if (this.session) {
|
|
357
|
+
void this.session.start().then(run);
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
void run();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
exports.TSUssdMenu = TSUssdMenu;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { TSUssdMenu } from './TSUssdMenu';
|
|
2
|
+
type PagerStrategy = {
|
|
3
|
+
term?: string;
|
|
4
|
+
type?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare class TSUssdScreen {
|
|
7
|
+
menu: TSUssdMenu;
|
|
8
|
+
storage?: {
|
|
9
|
+
hget: (k: string, f: string) => Promise<unknown>;
|
|
10
|
+
hset: (k: string, f: string, d: unknown) => Promise<unknown>;
|
|
11
|
+
} | undefined;
|
|
12
|
+
strategies: {
|
|
13
|
+
truncate: (data: {
|
|
14
|
+
name?: string;
|
|
15
|
+
}[], c: PagerStrategy & {
|
|
16
|
+
term: string;
|
|
17
|
+
}, factor: number) => {
|
|
18
|
+
name?: string;
|
|
19
|
+
}[];
|
|
20
|
+
};
|
|
21
|
+
static nav(command: number | string): unknown;
|
|
22
|
+
static pagerChoice(max?: number, min?: number): string;
|
|
23
|
+
constructor(menu: TSUssdMenu, storage?: {
|
|
24
|
+
hget: (k: string, f: string) => Promise<unknown>;
|
|
25
|
+
hset: (k: string, f: string, d: unknown) => Promise<unknown>;
|
|
26
|
+
} | undefined);
|
|
27
|
+
render(items: unknown[]): void;
|
|
28
|
+
bind(m: number | string, s: unknown): void;
|
|
29
|
+
screen(title: number | string, items: Record<string, unknown>): any;
|
|
30
|
+
list(items: unknown[], title?: string, key?: string, meta?: Record<string, boolean>): string;
|
|
31
|
+
getAndSet(key: string, field: string): Promise<Record<string, unknown> | null>;
|
|
32
|
+
pager(items: {
|
|
33
|
+
name?: string;
|
|
34
|
+
length?: number;
|
|
35
|
+
}[] | undefined, key: string, pagerSize: number): Promise<{
|
|
36
|
+
meta: {
|
|
37
|
+
command: number;
|
|
38
|
+
total: number;
|
|
39
|
+
length: number;
|
|
40
|
+
offset: number;
|
|
41
|
+
limit: number;
|
|
42
|
+
};
|
|
43
|
+
data: unknown[];
|
|
44
|
+
}>;
|
|
45
|
+
_pager(items: unknown[] | undefined, key: string, pagerSize: number): Promise<{
|
|
46
|
+
meta: {
|
|
47
|
+
command: number;
|
|
48
|
+
total: number;
|
|
49
|
+
length: number;
|
|
50
|
+
offset: number;
|
|
51
|
+
limit: number;
|
|
52
|
+
};
|
|
53
|
+
data: unknown[];
|
|
54
|
+
}>;
|
|
55
|
+
pagerPickAndSet(dataSet: unknown[] | undefined, field: string, size?: number): Promise<any>;
|
|
56
|
+
checkPick(entity: unknown, state?: string): boolean;
|
|
57
|
+
}
|
|
58
|
+
export {};
|