1 | const semver = require('semver');
|
2 | const CONVERSION_OPERATORS = require('./constants/conversion-operators');
|
3 | const EXPRESSION_OPERATORS = require('./constants/expression-operators');
|
4 | const ACCUMULATORS = require('./constants/accumulators');
|
5 | const BSON_TYPES = require('./constants/bson-types');
|
6 | const QueryAutoCompleter = require('./query-autocompleter');
|
7 | const filter = require('./filter');
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | const STRING = 'string';
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | const PROJECT = '$project';
|
18 |
|
19 |
|
20 |
|
21 |
|
22 | const GROUP = '$group';
|
23 |
|
24 |
|
25 |
|
26 |
|
27 | const MATCH = '$match';
|
28 |
|
29 |
|
30 |
|
31 |
|
32 | const DOLLAR = '$';
|
33 |
|
34 |
|
35 |
|
36 |
|
37 | const BASE_COMPLETIONS = EXPRESSION_OPERATORS.concat(
|
38 | CONVERSION_OPERATORS.concat(BSON_TYPES)
|
39 | );
|
40 |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 | class StageAutoCompleter {
|
46 | |
47 |
|
48 |
|
49 |
|
50 |
|
51 | accumulators() {
|
52 | if (this.stageOperator) {
|
53 | if (this.stageOperator === PROJECT) {
|
54 | return ACCUMULATORS.filter(acc => {
|
55 | return (
|
56 | acc.projectVersion && semver.gte(this.version, acc.projectVersion)
|
57 | );
|
58 | });
|
59 | } else if (this.stageOperator === GROUP) {
|
60 | return ACCUMULATORS;
|
61 | }
|
62 | }
|
63 | return [];
|
64 | }
|
65 |
|
66 | |
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | constructor(version, textCompleter, fields, stageOperator) {
|
75 | this.version = version;
|
76 | this.textCompleter = textCompleter;
|
77 | this.fields = fields;
|
78 | this.variableFields = this.generateVariableFields(fields);
|
79 | this.stageOperator = stageOperator;
|
80 | this.queryAutoCompleter = new QueryAutoCompleter(
|
81 | version,
|
82 | textCompleter,
|
83 | fields
|
84 | );
|
85 | }
|
86 |
|
87 | |
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | update(fields, stageOperator) {
|
94 | this.fields = fields;
|
95 | this.variableFields = this.generateVariableFields(fields);
|
96 | this.queryAutoCompleter.fields = fields;
|
97 | this.stageOperator = stageOperator;
|
98 | }
|
99 |
|
100 | |
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 | generateVariableFields(fields) {
|
108 | return fields.map(field => {
|
109 | return {
|
110 | name: `$${field.name.replace(/"/g, '')}`,
|
111 | value: `$${field.value.replace(/"/g, '')}`,
|
112 | meta: field.meta,
|
113 | version: field.version,
|
114 | score: 1
|
115 | };
|
116 | });
|
117 | }
|
118 |
|
119 | |
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 | getCompletions(editor, session, position, prefix, done) {
|
131 |
|
132 | if (prefix === '') return done(null, []);
|
133 |
|
134 |
|
135 |
|
136 |
|
137 | const currentToken = session.getTokenAt(position.row, position.column);
|
138 | if (currentToken.type === STRING) {
|
139 | if (prefix === DOLLAR) {
|
140 | return done(null, this.variableFields);
|
141 | }
|
142 | return this.textCompleter.getCompletions(
|
143 | editor,
|
144 | session,
|
145 | position,
|
146 | prefix,
|
147 | done
|
148 | );
|
149 | }
|
150 |
|
151 | if (currentToken.type.includes('comment')) {
|
152 | return done(null, []);
|
153 | }
|
154 |
|
155 |
|
156 | if (this.stageOperator && this.stageOperator === MATCH) {
|
157 | this.queryAutoCompleter.getCompletions(
|
158 | editor,
|
159 | session,
|
160 | position,
|
161 | prefix,
|
162 | done
|
163 | );
|
164 | } else {
|
165 | const expressions = BASE_COMPLETIONS.concat(this.accumulators()).concat(
|
166 | this.fields
|
167 | );
|
168 | return done(null, filter(this.version, expressions, prefix));
|
169 | }
|
170 | }
|
171 | }
|
172 |
|
173 | module.exports = StageAutoCompleter;
|