1 | const QUERY_OPERATORS = require('./constants/query-operators');
|
2 | const BSON_TYPES = require('./constants/bson-types');
|
3 | const filter = require('./filter');
|
4 |
|
5 | /**
|
6 | * String token type.
|
7 | */
|
8 | const STRING = 'string';
|
9 |
|
10 | /**
|
11 | * The match completions.
|
12 | */
|
13 | const MATCH_COMPLETIONS = QUERY_OPERATORS.concat(BSON_TYPES);
|
14 |
|
15 | /**
|
16 | * Adds autocomplete suggestions for queries.
|
17 | */
|
18 | class QueryAutoCompleter {
|
19 | /**
|
20 | * Instantiate a new completer.
|
21 | *
|
22 | * @param {String} version - The version.
|
23 | * @param {TextCompleter} textCompleter - The fallback Ace text completer.
|
24 | * @param {Array} fields - The collection fields.
|
25 | */
|
26 | constructor(version, textCompleter, fields) {
|
27 | this.version = version;
|
28 | this.textCompleter = textCompleter;
|
29 | this.fields = fields;
|
30 | }
|
31 |
|
32 | /**
|
33 | * Update the autocompleter with new fields.
|
34 | *
|
35 | * @param {Array} fields - The new fields.
|
36 | */
|
37 | update(fields) {
|
38 | this.fields = fields;
|
39 | }
|
40 |
|
41 | /**
|
42 | * Get the completion list for the provided params.
|
43 | *
|
44 | * @param {Editor} editor - The ACE editor.
|
45 | * @param {EditSession} session - The current editor session.
|
46 | * @param {Position} position - The cursor position.
|
47 | * @param {String} prefix - The string prefix to complete.
|
48 | * @param {Function} done - The done callback.
|
49 | *
|
50 | * @returns {Function} The completion function.
|
51 | */
|
52 | getCompletions(editor, session, position, prefix, done) {
|
53 | // Empty prefixes do not return results.
|
54 | if (prefix === '') return done(null, []);
|
55 | // If the current token is a string with single or double quotes, then
|
56 | // we want to use the local text completer instead of suggesting operators.
|
57 | // This is so we can suggest user variable names inside the pipeline that they
|
58 | // have already typed.
|
59 | const currentToken = session.getTokenAt(position.row, position.column);
|
60 | if (currentToken.type === STRING) {
|
61 | return this.textCompleter.getCompletions(
|
62 | editor,
|
63 | session,
|
64 | position,
|
65 | prefix,
|
66 | done
|
67 | );
|
68 | }
|
69 | // If the current token is not a string, then we proceed as normal to suggest
|
70 | // operators to the user.
|
71 | const expressions = MATCH_COMPLETIONS.concat(this.fields);
|
72 | done(null, filter(this.version, expressions, prefix));
|
73 | }
|
74 | }
|
75 |
|
76 | module.exports = QueryAutoCompleter;
|