atriusmaps-node-sdk 3.3.632 → 3.3.634
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.md +1 -2
- package/README.md +15 -16
- package/dist/cjs/deploy/prepareSDKConfig.js +73 -57
- package/dist/cjs/nodesdk/nodeEntry.js +51 -44
- package/dist/cjs/package.json.js +4 -1
- package/dist/cjs/plugins/clientAPI/src/clientAPI.js +6 -4
- package/dist/cjs/plugins/dynamicPois/src/dynamicPois.js +32 -26
- package/dist/cjs/plugins/dynamicPois/src/processors.js +41 -35
- package/dist/cjs/plugins/poiDataManager/src/poiDataManager.js +102 -95
- package/dist/cjs/plugins/sdkServer/src/sdkHeadless.js +52 -26
- package/dist/cjs/plugins/sdkServer/src/sdkServer.js +86 -66
- package/dist/cjs/plugins/searchService/src/flexsearchExports/lang.js +16 -16
- package/dist/cjs/plugins/searchService/src/flexsearchExports/simple.js +31 -8
- package/dist/cjs/plugins/searchService/src/poiSearch.js +14 -17
- package/dist/cjs/plugins/searchService/src/searchService.js +41 -39
- package/dist/cjs/plugins/searchService/src/searchTypeahead.js +14 -19
- package/dist/cjs/plugins/searchService/src/utils.js +4 -5
- package/dist/cjs/plugins/venueDataLoader/src/venueDataLoader.js +145 -127
- package/dist/cjs/plugins/venueDataLoader/src/venueLoadingUtils.js +37 -39
- package/dist/cjs/plugins/wayfinder/src/findRoute.js +11 -18
- package/dist/cjs/plugins/wayfinder/src/minPriorityQueue.js +18 -19
- package/dist/cjs/plugins/wayfinder/src/navGraph.js +111 -91
- package/dist/cjs/plugins/wayfinder/src/navGraphDebug.js +19 -16
- package/dist/cjs/plugins/wayfinder/src/segmentBadges.js +1 -1
- package/dist/cjs/plugins/wayfinder/src/segmentBuilder.js +79 -76
- package/dist/cjs/plugins/wayfinder/src/segmentCategories.js +1 -1
- package/dist/cjs/plugins/wayfinder/src/stepBuilder.js +147 -107
- package/dist/cjs/plugins/wayfinder/src/wayfinder.js +178 -148
- package/dist/cjs/src/app.js +64 -44
- package/dist/cjs/src/configs/postproc-mol-url-parms.js +22 -21
- package/dist/cjs/src/configs/postproc-stateTracking.js +5 -8
- package/dist/cjs/src/controller.js +11 -6
- package/dist/cjs/src/debugTools.js +61 -34
- package/dist/cjs/src/env.js +7 -4
- package/dist/cjs/src/extModules/bustle.js +35 -45
- package/dist/cjs/src/extModules/flexapi/src/help.js +16 -8
- package/dist/cjs/src/extModules/flexapi/src/index.js +39 -18
- package/dist/cjs/src/extModules/flexapi/src/validate.js +129 -87
- package/dist/cjs/src/extModules/geohasher.js +7 -7
- package/dist/cjs/src/extModules/log.js +20 -22
- package/dist/cjs/src/historyManager.js +2 -2
- package/dist/cjs/src/utils/bounds.js +6 -6
- package/dist/cjs/src/utils/buildStructureLookup.js +3 -3
- package/dist/cjs/src/utils/configUtils.js +14 -18
- package/dist/cjs/src/utils/dom.js +12 -18
- package/dist/cjs/src/utils/funcs.js +12 -15
- package/dist/cjs/src/utils/geodesy.js +7 -9
- package/dist/cjs/src/utils/geom.js +52 -40
- package/dist/cjs/src/utils/i18n.js +47 -36
- package/dist/cjs/src/utils/location.js +12 -13
- package/dist/cjs/src/utils/observable.js +27 -28
- package/dist/cjs/src/utils/rand.js +9 -10
- package/dist/package.json.js +1 -1
- package/package.json +1 -1
|
@@ -8,11 +8,11 @@ var Zousan = require('zousan');
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
const bustleResponseComparitor = (r1, r2) => {
|
|
11
|
-
if (r1.responseOrder == null)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return r1.responseOrder - r2.responseOrder
|
|
11
|
+
if (r1.responseOrder == null)
|
|
12
|
+
// null or undefined
|
|
13
|
+
return r2.responseOrder == null ? 0 : 1; // any order is higher pri than none
|
|
14
|
+
if (r2.responseOrder == null) return -1;
|
|
15
|
+
return r1.responseOrder - r2.responseOrder;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
// Remove element from array at index specified and return the removed element.
|
|
@@ -24,62 +24,57 @@ const arRm = (ar, value) => {
|
|
|
24
24
|
let i = 0;
|
|
25
25
|
do {
|
|
26
26
|
i = ar.indexOf(value, i);
|
|
27
|
-
if (i >= 0)
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return ar
|
|
27
|
+
if (i >= 0) arRmAt(ar, i);
|
|
28
|
+
} while (i >= 0);
|
|
29
|
+
return ar;
|
|
31
30
|
};
|
|
32
31
|
|
|
33
32
|
// This creates a bus instance. When used as a Singleton, you will only call this once
|
|
34
33
|
// for the life of your app. To isolate events (perhaps for performance or security
|
|
35
34
|
// reasons) you can create multple bus instances.
|
|
36
|
-
function create
|
|
35
|
+
function create(opts = {}) {
|
|
37
36
|
// If a log option is defined, use it - and if it supports sublogs, instantiate that. If all else fails, use console
|
|
38
37
|
const log = opts.log ? (opts.log.sublog ? opts.log.sublog('bustle', { color: 'pink' }) : opts.log) : console;
|
|
39
38
|
|
|
40
|
-
const ons = {
|
|
41
|
-
const mons = {
|
|
39
|
+
const ons = {}; // holds your listeners
|
|
40
|
+
const mons = {}; // holds your monitors
|
|
42
41
|
|
|
43
42
|
// subscribes to an event. Your listener will always be called
|
|
44
43
|
// with a single argument. I am considering adding another way
|
|
45
44
|
// to subscribe to events by observing an event and then
|
|
46
45
|
// subscribing to that observer.
|
|
47
|
-
function on
|
|
48
|
-
if (!ons[ev])
|
|
49
|
-
ons[ev] = [];
|
|
46
|
+
function on(ev, fn) {
|
|
47
|
+
if (!ons[ev]) ons[ev] = [];
|
|
50
48
|
|
|
51
49
|
ons[ev].push(fn);
|
|
52
50
|
|
|
53
|
-
return () => off(ev, fn)
|
|
51
|
+
return () => off(ev, fn);
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
// Similar to "on" but is always called after all normal "on" listeners,
|
|
57
55
|
// and any values returned by a monitor call are ignored (not added to the
|
|
58
56
|
// response). Also, any calls to monitor listeners contains both the message
|
|
59
57
|
// object AND a promise containing the response from the normal listeners.
|
|
60
|
-
function monitor
|
|
61
|
-
if (!mons[ev])
|
|
62
|
-
mons[ev] = [];
|
|
58
|
+
function monitor(ev, fn) {
|
|
59
|
+
if (!mons[ev]) mons[ev] = [];
|
|
63
60
|
|
|
64
61
|
mons[ev].push(fn);
|
|
65
62
|
|
|
66
|
-
return () => moff(ev, fn)
|
|
63
|
+
return () => moff(ev, fn);
|
|
67
64
|
}
|
|
68
65
|
|
|
69
|
-
function off
|
|
66
|
+
function off(ev, fn) {
|
|
70
67
|
// run ASAP but not immediate, in case it removes in its own function
|
|
71
68
|
Zousan.soon(() => {
|
|
72
|
-
if (!ons[ev])
|
|
73
|
-
return
|
|
69
|
+
if (!ons[ev]) return;
|
|
74
70
|
arRm(ons[ev], fn);
|
|
75
71
|
});
|
|
76
72
|
}
|
|
77
73
|
|
|
78
|
-
function moff
|
|
74
|
+
function moff(ev, fn) {
|
|
79
75
|
// run ASAP but not immediate, in case it removes in its own function
|
|
80
76
|
Zousan.soon(() => {
|
|
81
|
-
if (!mons[ev])
|
|
82
|
-
return
|
|
77
|
+
if (!mons[ev]) return;
|
|
83
78
|
arRm(mons[ev], fn);
|
|
84
79
|
});
|
|
85
80
|
}
|
|
@@ -94,12 +89,10 @@ function create (opts = { }) {
|
|
|
94
89
|
try {
|
|
95
90
|
res.push(listener(ob));
|
|
96
91
|
} catch (err) {
|
|
97
|
-
if (opts.reportAllErrors)
|
|
98
|
-
log.error(err);
|
|
92
|
+
if (opts.reportAllErrors) log.error(err);
|
|
99
93
|
if (opts.rejectOnError)
|
|
100
94
|
res.push(Zousan.reject(err)); // will cause the Zousan.all to reject the send
|
|
101
|
-
else
|
|
102
|
-
res.push(err);
|
|
95
|
+
else res.push(err);
|
|
103
96
|
}
|
|
104
97
|
}
|
|
105
98
|
}
|
|
@@ -111,8 +104,7 @@ function create (opts = { }) {
|
|
|
111
104
|
try {
|
|
112
105
|
listener(ob, results);
|
|
113
106
|
} catch (err) {
|
|
114
|
-
if (opts.reportAllErrors)
|
|
115
|
-
log.error(err);
|
|
107
|
+
if (opts.reportAllErrors) log.error(err);
|
|
116
108
|
}
|
|
117
109
|
}
|
|
118
110
|
}
|
|
@@ -125,30 +117,28 @@ function create (opts = { }) {
|
|
|
125
117
|
// and returns that result. If there are 0 or more than 1 listener, the returned
|
|
126
118
|
// promise is rejected
|
|
127
119
|
const get = (ev, ob) =>
|
|
128
|
-
send(ev, ob).then(res =>
|
|
129
|
-
|
|
130
|
-
|
|
120
|
+
send(ev, ob).then(res =>
|
|
121
|
+
res.length !== 1
|
|
122
|
+
? Zousan.reject(`${ev} event did not return a single result, but ${res.length} results.`)
|
|
123
|
+
: res[0],
|
|
124
|
+
);
|
|
131
125
|
|
|
132
126
|
// Allows for any number of listeners to exist - but extracts the first one
|
|
133
127
|
// and returns it. If there are NO listeners, undefined is returned. The promise
|
|
134
128
|
// is never rejected.
|
|
135
129
|
const getFirst = (ev, ob) =>
|
|
136
|
-
send(ev, ob).then(res => res.length >= 1
|
|
137
|
-
? res.sort(bustleResponseComparitor)[0]
|
|
138
|
-
: undefined);
|
|
130
|
+
send(ev, ob).then(res => (res.length >= 1 ? res.sort(bustleResponseComparitor)[0] : undefined));
|
|
139
131
|
|
|
140
|
-
function send
|
|
132
|
+
function send(ev, ob) {
|
|
141
133
|
if (opts.showEvents) {
|
|
142
134
|
if (typeof opts.showEvents === 'function') {
|
|
143
|
-
if (opts.showEvents(ev, ob))
|
|
144
|
-
|
|
145
|
-
} else
|
|
146
|
-
log.info('send with', ev, ' and ', ob);
|
|
135
|
+
if (opts.showEvents(ev, ob)) log.info('send with', ev, ' and ', ob);
|
|
136
|
+
} else log.info('send with', ev, ' and ', ob);
|
|
147
137
|
}
|
|
148
|
-
return new Zousan(resolve => Zousan.soon(serve(ev, ob, resolve)))
|
|
138
|
+
return new Zousan(resolve => Zousan.soon(serve(ev, ob, resolve)));
|
|
149
139
|
}
|
|
150
140
|
|
|
151
|
-
return { get, getFirst, moff, monitor, off, on, send }
|
|
141
|
+
return { get, getFirst, moff, monitor, off, on, send };
|
|
152
142
|
}
|
|
153
143
|
|
|
154
144
|
exports.create = create;
|
|
@@ -1,24 +1,32 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
function pad
|
|
4
|
-
while (str.length < total) {
|
|
5
|
-
|
|
3
|
+
function pad(total, str) {
|
|
4
|
+
while (str.length < total) {
|
|
5
|
+
str += ' ';
|
|
6
|
+
}
|
|
7
|
+
return str;
|
|
6
8
|
}
|
|
7
9
|
|
|
8
|
-
const getHelpHeader = () =>
|
|
10
|
+
const getHelpHeader = () =>
|
|
11
|
+
pad(18, 'Command') + 'Arguments\n' + pad(18, '----------------') + '----------------\n';
|
|
9
12
|
|
|
10
13
|
/**
|
|
11
14
|
* Returns help on the passed command signature
|
|
12
15
|
*/
|
|
13
|
-
const getHelp = sig =>
|
|
14
|
-
(
|
|
16
|
+
const getHelp = sig =>
|
|
17
|
+
pad(18, sig.command) +
|
|
18
|
+
(sig.args
|
|
19
|
+
? sig.args
|
|
20
|
+
.map(argob => `${argob.name} {${argob.type}} ${argob.optional ? ' (optional)' : ' (required)'}`)
|
|
21
|
+
.join(', ')
|
|
22
|
+
: '');
|
|
15
23
|
|
|
16
|
-
const sigsort = (s1, s2) => s1.command > s2.command ? 1 : -1;
|
|
24
|
+
const sigsort = (s1, s2) => (s1.command > s2.command ? 1 : -1);
|
|
17
25
|
/**
|
|
18
26
|
* Returns help on the passed command signatures
|
|
19
27
|
*/
|
|
20
28
|
const getHelpList = sigList => {
|
|
21
|
-
return sigList.sort(sigsort).reduce((ret, sig) => `${ret}${getHelp(sig)}\n`, getHelpHeader())
|
|
29
|
+
return sigList.sort(sigsort).reduce((ret, sig) => `${ret}${getHelp(sig)}\n`, getHelpHeader());
|
|
22
30
|
};
|
|
23
31
|
|
|
24
32
|
exports.getHelp = getHelp;
|
|
@@ -7,54 +7,75 @@ var validate = require('./validate.js');
|
|
|
7
7
|
const COMMAND_VALIDATION_REGEX = /^[-_.0-9a-zA-Z]+$/;
|
|
8
8
|
const JS = JSON.stringify;
|
|
9
9
|
|
|
10
|
-
function create
|
|
10
|
+
function create() {
|
|
11
11
|
const commandDefsList = [];
|
|
12
12
|
const commands = () => commandDefsList.map(cob => cob.sig);
|
|
13
|
-
const customTypes = {
|
|
13
|
+
const customTypes = {};
|
|
14
14
|
const library = { customTypes, commandDefsList };
|
|
15
15
|
const getCommandJSON = () => ({ commands: commands(), customTypes });
|
|
16
16
|
|
|
17
|
-
function registerCommand
|
|
17
|
+
function registerCommand(sig, fn) {
|
|
18
18
|
const command = sig.command;
|
|
19
|
-
if (command === undefined) {
|
|
19
|
+
if (command === undefined) {
|
|
20
|
+
throw Error(`Invalid command specification in registerCommand: ${JS(sig)}. No 'command' property specified.`);
|
|
21
|
+
}
|
|
20
22
|
|
|
21
23
|
if (!COMMAND_VALIDATION_REGEX.test(command)) {
|
|
22
|
-
const er = Error(
|
|
23
|
-
|
|
24
|
+
const er = Error(
|
|
25
|
+
`Invalid command specification in registerCommand: ${JS(sig)}. Command name '${command}' not valid.`,
|
|
26
|
+
);
|
|
27
|
+
throw er;
|
|
24
28
|
}
|
|
25
29
|
|
|
26
30
|
commandDefsList.push({ sig, fn });
|
|
27
31
|
|
|
28
|
-
return execute
|
|
32
|
+
return execute;
|
|
29
33
|
}
|
|
30
34
|
|
|
31
|
-
function registerCustomType
|
|
35
|
+
function registerCustomType(name, spec) {
|
|
32
36
|
customTypes[name] = spec;
|
|
33
37
|
}
|
|
34
38
|
|
|
35
|
-
function execute
|
|
39
|
+
function execute(cob) {
|
|
36
40
|
return new Zousan((resolve, reject) => {
|
|
37
|
-
if (!cob) {
|
|
41
|
+
if (!cob) {
|
|
42
|
+
return reject(new Error(`No command specified in command object ${JS(cob)}`));
|
|
43
|
+
}
|
|
38
44
|
|
|
39
|
-
const commandMatches = library.commandDefsList
|
|
40
|
-
.filter(com => com.sig.command === cob.command);
|
|
45
|
+
const commandMatches = library.commandDefsList.filter(com => com.sig.command === cob.command);
|
|
41
46
|
|
|
42
|
-
if (commandMatches.length === 0) {
|
|
47
|
+
if (commandMatches.length === 0) {
|
|
48
|
+
return reject(
|
|
49
|
+
new Error(`No API command '${cob.command}' found.\n${help.getHelpList(library.commandDefsList.map(o => o.sig))}`),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
43
52
|
|
|
44
53
|
const sigMatch = validate.getSigMatch(library, cob);
|
|
45
54
|
|
|
46
55
|
if (!sigMatch) {
|
|
47
|
-
if (commandMatches.length === 1) {
|
|
56
|
+
if (commandMatches.length === 1) {
|
|
57
|
+
return reject(
|
|
58
|
+
new Error(`Required fields not present in ${JS(cob)}\n${help.getHelpHeader()}${help.getHelp(commandMatches[0].sig)}`),
|
|
59
|
+
);
|
|
60
|
+
} else {
|
|
61
|
+
return reject(
|
|
62
|
+
new Error(
|
|
63
|
+
`Command arguments did not match any required signatures: ${JS(cob)}\n${help.getHelpList(library.commandDefsList.map(o => o.sig))}`,
|
|
64
|
+
),
|
|
65
|
+
);
|
|
66
|
+
}
|
|
48
67
|
}
|
|
49
68
|
|
|
50
69
|
// console.log(`command ${JS(cob)} is ${JS(sigMatch.sig)}`)
|
|
51
70
|
|
|
52
71
|
try {
|
|
53
72
|
validate.validate(library, sigMatch.sig, cob); // this will throw an error if invalid
|
|
54
|
-
} catch (e) {
|
|
73
|
+
} catch (e) {
|
|
74
|
+
return reject(e);
|
|
75
|
+
}
|
|
55
76
|
|
|
56
77
|
resolve(sigMatch.fn(cob));
|
|
57
|
-
})
|
|
78
|
+
});
|
|
58
79
|
}
|
|
59
80
|
|
|
60
81
|
registerCommand({ command: 'help', args: [] }, () => help.getHelpList(commands()));
|
|
@@ -63,8 +84,8 @@ function create () {
|
|
|
63
84
|
return {
|
|
64
85
|
registerCommand,
|
|
65
86
|
registerCustomType,
|
|
66
|
-
execute
|
|
67
|
-
}
|
|
87
|
+
execute,
|
|
88
|
+
};
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
module.exports = create;
|
|
@@ -1,34 +1,44 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
// small helper for showing args
|
|
4
|
-
const SQ = '
|
|
5
|
-
const sqStr = function (str) {
|
|
4
|
+
const SQ = "'"; // single quote
|
|
5
|
+
const sqStr = function (str) {
|
|
6
|
+
return SQ + str + SQ;
|
|
7
|
+
};
|
|
6
8
|
|
|
7
|
-
function validate
|
|
8
|
-
if (sig.args)
|
|
9
|
-
checkTypeList(library.customTypes, sig.args, cob);
|
|
9
|
+
function validate(library, sig, cob) {
|
|
10
|
+
if (sig.args) checkTypeList(library.customTypes, sig.args, cob);
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
function getSigMatch
|
|
13
|
-
const matches = library.commandDefsList
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
function getSigMatch(library, cob) {
|
|
14
|
+
const matches = library.commandDefsList.filter(cd => cd.sig.command === cob.command && matchesArgs(cd.sig, cob));
|
|
15
|
+
if (matches.length > 1) {
|
|
16
|
+
throw Error('Command matches multiple signatures!');
|
|
17
|
+
}
|
|
18
|
+
if (matches.length > 0) {
|
|
19
|
+
return matches[0];
|
|
20
|
+
}
|
|
21
|
+
return null; // no matching signature found
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
// returns true if each of the required arguments in the command
|
|
21
25
|
// spec (c) is defined within the command object (o) - else false
|
|
22
|
-
function matchesArgs
|
|
23
|
-
if (!c.args) {
|
|
26
|
+
function matchesArgs(c, o) {
|
|
27
|
+
if (!c.args) {
|
|
28
|
+
return true;
|
|
29
|
+
} // no args
|
|
24
30
|
return c.args.reduce(function (cs, argOb) {
|
|
25
|
-
return o[argOb.name] !== undefined || argOb.optional ? cs : false
|
|
26
|
-
}, true)
|
|
31
|
+
return o[argOb.name] !== undefined || argOb.optional ? cs : false;
|
|
32
|
+
}, true);
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
function checkMinMax
|
|
30
|
-
if (typeSpec.min !== undefined && value < typeSpec.min) {
|
|
31
|
-
|
|
35
|
+
function checkMinMax(name, typeSpec, value) {
|
|
36
|
+
if (typeSpec.min !== undefined && value < typeSpec.min) {
|
|
37
|
+
throw Error('argument ' + sqStr(name) + ' must be at least ' + typeSpec.min + ' but is ' + value);
|
|
38
|
+
}
|
|
39
|
+
if (typeSpec.max !== undefined && value > typeSpec.max) {
|
|
40
|
+
throw Error('argument ' + sqStr(name) + ' must be at most ' + typeSpec.max + ' but is ' + value);
|
|
41
|
+
}
|
|
32
42
|
}
|
|
33
43
|
|
|
34
44
|
/**
|
|
@@ -39,82 +49,111 @@ function checkMinMax (name, typeSpec, value) {
|
|
|
39
49
|
* @param {*} value The JSON value to be checked against this spec
|
|
40
50
|
* @return {true|string} returns true if arg is valid, else a string description of the problem
|
|
41
51
|
*/
|
|
42
|
-
function checkType
|
|
43
|
-
if (!typeSpec)
|
|
44
|
-
|
|
52
|
+
function checkType(customTypes, typeSpec, value) {
|
|
53
|
+
if (!typeSpec)
|
|
54
|
+
// if there is no typespec to validate against, any value is ok
|
|
55
|
+
return true;
|
|
45
56
|
|
|
46
57
|
const name = typeSpec.name || '';
|
|
47
58
|
|
|
48
59
|
// if type is a reference/custom, grab that type def but allow "optional" override - TODO: consider other overrides (perhaps all but "type"?)
|
|
49
60
|
if (customTypes && customTypes[typeSpec.type])
|
|
50
|
-
typeSpec = Object.assign({}, customTypes[typeSpec.type], typeSpec, {
|
|
61
|
+
typeSpec = Object.assign({}, customTypes[typeSpec.type], typeSpec, {
|
|
62
|
+
type: customTypes[typeSpec.type].type,
|
|
63
|
+
});
|
|
51
64
|
|
|
52
65
|
if (typeSpec.type === 'integer') {
|
|
53
|
-
if (typeof value === 'string')
|
|
54
|
-
value = parseInt(value, 10);
|
|
66
|
+
if (typeof value === 'string') value = parseInt(value, 10);
|
|
55
67
|
if (!Number.isInteger(value))
|
|
56
|
-
throw Error('expected integer argument for argument ' + sqStr(name) + ' but received ' + value)
|
|
68
|
+
throw Error('expected integer argument for argument ' + sqStr(name) + ' but received ' + value);
|
|
57
69
|
checkMinMax(name, typeSpec, value);
|
|
58
|
-
} else
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
70
|
+
} else if (typeSpec.type === 'float') {
|
|
71
|
+
if (typeof value === 'string') value = parseFloat(value);
|
|
72
|
+
if (!Number.isFinite(value))
|
|
73
|
+
throw Error('expected float argument for argument ' + sqStr(name) + " but received '" + value + "'");
|
|
74
|
+
checkMinMax(name, typeSpec, value);
|
|
75
|
+
} else if (typeSpec.type === 'string') {
|
|
76
|
+
if (typeof value !== 'string') throw Error(`argument ${sqStr(name)} must be a string but is not (value: ${value})`);
|
|
77
|
+
if (typeSpec.minLength && value.length < typeSpec.minLength)
|
|
78
|
+
throw Error(
|
|
79
|
+
`argument ${sqStr(name)} must be a at least ${typeSpec.minLength} characters but is '${value}' (${value.length} chars)`,
|
|
80
|
+
);
|
|
81
|
+
if (typeSpec.maxLength && value.length > typeSpec.maxLength)
|
|
82
|
+
throw Error(
|
|
83
|
+
`argument ${sqStr(name)} must be a at most ${typeSpec.maxLength} characters but is '${value}' (${value.length} chars)`,
|
|
84
|
+
);
|
|
85
|
+
} else if (typeSpec.type === 'boolean') {
|
|
86
|
+
if (
|
|
87
|
+
value !== true &&
|
|
88
|
+
value !== false &&
|
|
89
|
+
value !== 'false' &&
|
|
90
|
+
value !== 'true' &&
|
|
91
|
+
value !== 'yes' &&
|
|
92
|
+
value !== 'no'
|
|
93
|
+
) {
|
|
94
|
+
throw Error(
|
|
95
|
+
'argument ' + sqStr(name) + ' must be a boolean but is type ' + typeof value + ' with value of ' + value,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
} else if (typeSpec.type === 'list') {
|
|
99
|
+
if (!Array.isArray(value)) throw Error('argument ' + sqStr(name) + ' must be a list but is not. Value = ' + value);
|
|
100
|
+
if (typeSpec.minLength !== undefined && typeSpec.minLength > value.length)
|
|
101
|
+
throw Error(
|
|
102
|
+
'argument ' +
|
|
103
|
+
sqStr(name) +
|
|
104
|
+
' must contain at least ' +
|
|
105
|
+
typeSpec.minLength +
|
|
106
|
+
' items but only contains ' +
|
|
107
|
+
value.length +
|
|
108
|
+
' items',
|
|
109
|
+
);
|
|
110
|
+
if (typeSpec.maxLength !== undefined && typeSpec.maxLength < value.length)
|
|
111
|
+
throw Error(
|
|
112
|
+
'argument ' +
|
|
113
|
+
sqStr(name) +
|
|
114
|
+
' must contain at most ' +
|
|
115
|
+
typeSpec.maxLength +
|
|
116
|
+
' items but contains ' +
|
|
117
|
+
value.length +
|
|
118
|
+
' items',
|
|
119
|
+
);
|
|
120
|
+
if (typeSpec.itemType) {
|
|
121
|
+
const allItemsValid = value.reduce(function (isValid, curItem) {
|
|
122
|
+
try {
|
|
123
|
+
checkType(customTypes, typeSpec.itemType, curItem);
|
|
124
|
+
} catch (e) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
return isValid;
|
|
128
|
+
}, true);
|
|
129
|
+
if (!allItemsValid) {
|
|
130
|
+
throw Error(
|
|
131
|
+
`argument ${sqStr(name)} contains an invalid item(s). All items in the list must be of type: ${JSON.stringify(typeSpec.itemType)} - list: ${JSON.stringify(value)}`,
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} else if (typeSpec.type === 'object') {
|
|
136
|
+
if (typeof value !== 'object' || Array.isArray(value))
|
|
137
|
+
throw Error('argument ' + sqStr(name) + ' must be an object but is not. Value = ' + value);
|
|
138
|
+
try {
|
|
139
|
+
if (typeSpec.props) checkTypeList(customTypes, typeSpec.props, value);
|
|
140
|
+
} catch (e) {
|
|
141
|
+
throw Error('Within ' + name + ', ' + e.message);
|
|
142
|
+
}
|
|
143
|
+
} else if (typeSpec.type === 'multi') {
|
|
144
|
+
const oneTypeValid = typeSpec.types.reduce((isValid, curType) => {
|
|
145
|
+
try {
|
|
146
|
+
checkType(customTypes, curType, value);
|
|
147
|
+
} catch (e) {
|
|
148
|
+
return isValid;
|
|
149
|
+
}
|
|
150
|
+
return true;
|
|
151
|
+
}, false);
|
|
152
|
+
if (!oneTypeValid)
|
|
153
|
+
throw Error(`Argument ${sqStr(name)} can be of several types, but is not valid for any: ${value}`);
|
|
154
|
+
} else throw Error('type ' + typeSpec.type + ' is an unknown type');
|
|
116
155
|
|
|
117
|
-
return true
|
|
156
|
+
return true;
|
|
118
157
|
}
|
|
119
158
|
|
|
120
159
|
/**
|
|
@@ -123,10 +162,13 @@ function checkType (customTypes, typeSpec, value) {
|
|
|
123
162
|
* @param typeList A list of types to check
|
|
124
163
|
* @param args The properties object to check against
|
|
125
164
|
*/
|
|
126
|
-
function checkTypeList
|
|
165
|
+
function checkTypeList(customTypes, typeList, args) {
|
|
127
166
|
typeList.forEach(nextType => {
|
|
128
|
-
if (args[nextType.name] !== undefined) {
|
|
129
|
-
|
|
167
|
+
if (args[nextType.name] !== undefined) {
|
|
168
|
+
checkType(customTypes, nextType, args[nextType.name]);
|
|
169
|
+
} else if (!nextType.optional) {
|
|
170
|
+
throw Error('you must include a value for ' + nextType.name);
|
|
171
|
+
}
|
|
130
172
|
});
|
|
131
173
|
}
|
|
132
174
|
|
|
@@ -17,14 +17,14 @@ const NEIGHBORS = {
|
|
|
17
17
|
right: { even: 'bc01fg45238967deuvhjyznpkmstqrwx' },
|
|
18
18
|
left: { even: '238967debc01fg45kmstqrwxuvhjyznp' },
|
|
19
19
|
top: { even: 'p0r21436x8zb9dcf5h7kjnmqesgutwvy' },
|
|
20
|
-
bottom: { even: '14365h7k9dcfesgujnmqp0r2twvyx8zb' }
|
|
20
|
+
bottom: { even: '14365h7k9dcfesgujnmqp0r2twvyx8zb' },
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
const BORDERS = {
|
|
24
24
|
right: { even: 'bcfguvyz' },
|
|
25
25
|
left: { even: '0145hjnp' },
|
|
26
26
|
top: { even: 'prxz' },
|
|
27
|
-
bottom: { even: '028b' }
|
|
27
|
+
bottom: { even: '028b' },
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
NEIGHBORS.bottom.odd = NEIGHBORS.left.even;
|
|
@@ -37,18 +37,18 @@ BORDERS.top.odd = BORDERS.right.even;
|
|
|
37
37
|
BORDERS.left.odd = BORDERS.bottom.even;
|
|
38
38
|
BORDERS.right.odd = BORDERS.top.even;
|
|
39
39
|
|
|
40
|
-
function calculateAdjacent
|
|
40
|
+
function calculateAdjacent(srcHash, dir) {
|
|
41
41
|
srcHash = srcHash.toLowerCase();
|
|
42
42
|
const lastChr = srcHash.charAt(srcHash.length - 1);
|
|
43
|
-
const type =
|
|
43
|
+
const type = srcHash.length % 2 ? 'odd' : 'even';
|
|
44
44
|
let base = srcHash.substring(0, srcHash.length - 1);
|
|
45
45
|
if (BORDERS[dir][type].indexOf(lastChr) !== -1) {
|
|
46
46
|
base = calculateAdjacent(base, dir);
|
|
47
47
|
}
|
|
48
|
-
return base + BASE32[NEIGHBORS[dir][type].indexOf(lastChr)]
|
|
48
|
+
return base + BASE32[NEIGHBORS[dir][type].indexOf(lastChr)];
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
function encode
|
|
51
|
+
function encode(latitude, longitude, precision) {
|
|
52
52
|
let isEven = 1;
|
|
53
53
|
const lat = [-90, 90.0];
|
|
54
54
|
const lng = [-180, 180.0];
|
|
@@ -86,7 +86,7 @@ function encode (latitude, longitude, precision) {
|
|
|
86
86
|
ch = 0;
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
return geohash
|
|
89
|
+
return geohash;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
exports.calculateAdjacent = calculateAdjacent;
|