@budibase/server 2.3.18-alpha.2 → 2.3.18-alpha.21
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/__mocks__/node-fetch.ts +3 -0
- package/builder/assets/blankScreenPreview.72634dd1.png +0 -0
- package/builder/assets/{index.bbe4c16b.js → index.baf0ac34.js} +430 -417
- package/builder/assets/index.dc0472d8.css +6 -0
- package/builder/assets/listScreenPreview.599c0aae.png +0 -0
- package/builder/index.html +2 -2
- package/dist/api/controllers/automation.js +11 -2
- package/dist/api/controllers/cloud.js +2 -2
- package/dist/api/controllers/row/ExternalRequest.js +49 -24
- package/dist/api/controllers/row/external.js +1 -1
- package/dist/api/controllers/row/internalSearch.js +6 -450
- package/dist/api/controllers/row/utils.js +1 -3
- package/dist/api/routes/automation.js +1 -1
- package/dist/api/routes/public/applications.js +7 -7
- package/dist/api/routes/public/queries.js +2 -2
- package/dist/api/routes/public/rows.js +5 -5
- package/dist/api/routes/public/tables.js +5 -5
- package/dist/api/routes/public/users.js +5 -5
- package/dist/app.js +2 -0
- package/dist/db/index.js +25 -2
- package/dist/db/utils.js +2 -5
- package/dist/db/views/staticViews.js +2 -1
- package/dist/integrations/base/sql.js +4 -8
- package/dist/integrations/googlesheets.js +17 -20
- package/dist/middleware/authorized.js +5 -3
- package/dist/middleware/builder.js +6 -3
- package/dist/migrations/functions/backfill/global/configs.js +10 -4
- package/dist/migrations/tests/helpers.js +1 -1
- package/dist/migrations/tests/structures.js +1 -1
- package/dist/package.json +9 -8
- package/dist/startup.js +3 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/jest.config.ts +1 -0
- package/package.json +10 -9
- package/scripts/test.sh +12 -0
- package/specs/{generate.js → generate.ts} +7 -9
- package/specs/openapi.json +24 -24
- package/specs/openapi.yaml +24 -24
- package/specs/{parameters.js → parameters.ts} +6 -6
- package/specs/resources/{application.js → application.ts} +4 -4
- package/specs/resources/{index.js → index.ts} +8 -8
- package/specs/resources/{misc.js → misc.ts} +3 -3
- package/specs/resources/{query.js → query.ts} +4 -4
- package/specs/resources/{row.js → row.ts} +3 -4
- package/specs/resources/{table.js → table.ts} +5 -5
- package/specs/resources/{user.js → user.ts} +3 -3
- package/specs/resources/utils/Resource.ts +39 -0
- package/specs/resources/utils/{index.js → index.ts} +1 -1
- package/specs/{security.js → security.ts} +1 -1
- package/src/api/controllers/automation.ts +13 -2
- package/src/api/controllers/cloud.ts +2 -2
- package/src/api/controllers/row/ExternalRequest.ts +95 -28
- package/src/api/controllers/row/external.ts +1 -1
- package/src/api/controllers/row/internalSearch.ts +11 -524
- package/src/api/controllers/row/utils.ts +1 -2
- package/src/api/routes/automation.ts +1 -1
- package/src/api/routes/public/applications.ts +7 -7
- package/src/api/routes/public/queries.ts +2 -2
- package/src/api/routes/public/rows.ts +5 -5
- package/src/api/routes/public/tables.ts +5 -5
- package/src/api/routes/public/tests/{compare.spec.js → compare.spec.ts} +44 -25
- package/src/api/routes/public/users.ts +5 -5
- package/src/api/routes/tests/{cloud.seq.spec.ts → cloud.spec.ts} +13 -20
- package/src/api/routes/tests/utilities/TestFunctions.ts +1 -2
- package/src/app.ts +2 -0
- package/src/db/index.ts +2 -2
- package/src/db/utils.ts +0 -4
- package/src/db/views/staticViews.ts +3 -3
- package/src/definitions/openapi.ts +449 -63
- package/src/integration-test/postgres.spec.ts +351 -81
- package/src/integrations/base/sql.ts +4 -8
- package/src/integrations/googlesheets.ts +21 -22
- package/src/integrations/tests/googlesheets.spec.ts +122 -0
- package/src/middleware/authorized.ts +6 -4
- package/src/middleware/builder.ts +8 -3
- package/src/migrations/functions/backfill/global/configs.ts +15 -9
- package/src/migrations/functions/tests/userEmailViewCasing.spec.js +3 -4
- package/src/migrations/tests/helpers.ts +2 -2
- package/src/migrations/tests/structures.ts +1 -0
- package/src/startup.ts +4 -1
- package/src/tests/jestEnv.ts +1 -0
- package/src/tests/utilities/TestConfiguration.ts +42 -30
- package/src/tests/utilities/structures.ts +0 -2
- package/builder/assets/index.7e76c039.css +0 -6
- package/dist/integrations/base/utils.js +0 -16
- package/specs/resources/utils/Resource.js +0 -26
- package/src/integrations/base/utils.ts +0 -12
|
@@ -8,465 +8,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.fullSearch = exports.paginatedSearch =
|
|
16
|
-
const utils_1 = require("../../../db/utils");
|
|
17
|
-
const utils_2 = require("./utils");
|
|
18
|
-
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
12
|
+
exports.fullSearch = exports.paginatedSearch = void 0;
|
|
19
13
|
const backend_core_1 = require("@budibase/backend-core");
|
|
20
|
-
|
|
21
|
-
* Class to build lucene query URLs.
|
|
22
|
-
* Optionally takes a base lucene query object.
|
|
23
|
-
*/
|
|
24
|
-
class QueryBuilder {
|
|
25
|
-
constructor(base) {
|
|
26
|
-
this.query = Object.assign({ allOr: false, string: {}, fuzzy: {}, range: {}, equal: {}, notEqual: {}, empty: {}, notEmpty: {}, oneOf: {}, contains: {}, notContains: {}, containsAny: {} }, base);
|
|
27
|
-
this.limit = 50;
|
|
28
|
-
this.sortOrder = "ascending";
|
|
29
|
-
this.sortType = "string";
|
|
30
|
-
this.includeDocs = true;
|
|
31
|
-
}
|
|
32
|
-
setVersion(version) {
|
|
33
|
-
if (version != null) {
|
|
34
|
-
this.version = version;
|
|
35
|
-
}
|
|
36
|
-
return this;
|
|
37
|
-
}
|
|
38
|
-
setTable(tableId) {
|
|
39
|
-
this.query.equal.tableId = tableId;
|
|
40
|
-
return this;
|
|
41
|
-
}
|
|
42
|
-
setLimit(limit) {
|
|
43
|
-
if (limit != null) {
|
|
44
|
-
this.limit = limit;
|
|
45
|
-
}
|
|
46
|
-
return this;
|
|
47
|
-
}
|
|
48
|
-
setSort(sort) {
|
|
49
|
-
if (sort != null) {
|
|
50
|
-
this.sort = sort;
|
|
51
|
-
}
|
|
52
|
-
return this;
|
|
53
|
-
}
|
|
54
|
-
setSortOrder(sortOrder) {
|
|
55
|
-
if (sortOrder != null) {
|
|
56
|
-
this.sortOrder = sortOrder;
|
|
57
|
-
}
|
|
58
|
-
return this;
|
|
59
|
-
}
|
|
60
|
-
setSortType(sortType) {
|
|
61
|
-
if (sortType != null) {
|
|
62
|
-
this.sortType = sortType;
|
|
63
|
-
}
|
|
64
|
-
return this;
|
|
65
|
-
}
|
|
66
|
-
setBookmark(bookmark) {
|
|
67
|
-
if (bookmark != null) {
|
|
68
|
-
this.bookmark = bookmark;
|
|
69
|
-
}
|
|
70
|
-
return this;
|
|
71
|
-
}
|
|
72
|
-
excludeDocs() {
|
|
73
|
-
this.includeDocs = false;
|
|
74
|
-
return this;
|
|
75
|
-
}
|
|
76
|
-
addString(key, partial) {
|
|
77
|
-
this.query.string[key] = partial;
|
|
78
|
-
return this;
|
|
79
|
-
}
|
|
80
|
-
addFuzzy(key, fuzzy) {
|
|
81
|
-
this.query.fuzzy[key] = fuzzy;
|
|
82
|
-
return this;
|
|
83
|
-
}
|
|
84
|
-
addRange(key, low, high) {
|
|
85
|
-
this.query.range[key] = {
|
|
86
|
-
low,
|
|
87
|
-
high,
|
|
88
|
-
};
|
|
89
|
-
return this;
|
|
90
|
-
}
|
|
91
|
-
addEqual(key, value) {
|
|
92
|
-
this.query.equal[key] = value;
|
|
93
|
-
return this;
|
|
94
|
-
}
|
|
95
|
-
addNotEqual(key, value) {
|
|
96
|
-
this.query.notEqual[key] = value;
|
|
97
|
-
return this;
|
|
98
|
-
}
|
|
99
|
-
addEmpty(key, value) {
|
|
100
|
-
this.query.empty[key] = value;
|
|
101
|
-
return this;
|
|
102
|
-
}
|
|
103
|
-
addNotEmpty(key, value) {
|
|
104
|
-
this.query.notEmpty[key] = value;
|
|
105
|
-
return this;
|
|
106
|
-
}
|
|
107
|
-
addOneOf(key, value) {
|
|
108
|
-
this.query.oneOf[key] = value;
|
|
109
|
-
return this;
|
|
110
|
-
}
|
|
111
|
-
addContains(key, value) {
|
|
112
|
-
this.query.contains[key] = value;
|
|
113
|
-
return this;
|
|
114
|
-
}
|
|
115
|
-
addNotContains(key, value) {
|
|
116
|
-
this.query.notContains[key] = value;
|
|
117
|
-
return this;
|
|
118
|
-
}
|
|
119
|
-
addContainsAny(key, value) {
|
|
120
|
-
this.query.containsAny[key] = value;
|
|
121
|
-
return this;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Preprocesses a value before going into a lucene search.
|
|
125
|
-
* Transforms strings to lowercase and wraps strings and bools in quotes.
|
|
126
|
-
* @param value The value to process
|
|
127
|
-
* @param options The preprocess options
|
|
128
|
-
* @returns {string|*}
|
|
129
|
-
*/
|
|
130
|
-
preprocess(value, { escape, lowercase, wrap, type } = {}) {
|
|
131
|
-
const hasVersion = !!this.version;
|
|
132
|
-
// Determine if type needs wrapped
|
|
133
|
-
const originalType = typeof value;
|
|
134
|
-
// Convert to lowercase
|
|
135
|
-
if (value && lowercase) {
|
|
136
|
-
value = value.toLowerCase ? value.toLowerCase() : value;
|
|
137
|
-
}
|
|
138
|
-
// Escape characters
|
|
139
|
-
if (escape && originalType === "string") {
|
|
140
|
-
value = `${value}`.replace(/[ #+\-&|!(){}\]^"~*?:\\]/g, "\\$&");
|
|
141
|
-
}
|
|
142
|
-
// Wrap in quotes
|
|
143
|
-
if (originalType === "string" && !isNaN(value) && !type) {
|
|
144
|
-
value = `"${value}"`;
|
|
145
|
-
}
|
|
146
|
-
else if (hasVersion && wrap) {
|
|
147
|
-
value = originalType === "number" ? value : `"${value}"`;
|
|
148
|
-
}
|
|
149
|
-
return value;
|
|
150
|
-
}
|
|
151
|
-
buildSearchQuery() {
|
|
152
|
-
const builder = this;
|
|
153
|
-
let allOr = this.query && this.query.allOr;
|
|
154
|
-
let query = allOr ? "" : "*:*";
|
|
155
|
-
const allPreProcessingOpts = { escape: true, lowercase: true, wrap: true };
|
|
156
|
-
let tableId;
|
|
157
|
-
if (this.query.equal.tableId) {
|
|
158
|
-
tableId = this.query.equal.tableId;
|
|
159
|
-
delete this.query.equal.tableId;
|
|
160
|
-
}
|
|
161
|
-
const equal = (key, value) => {
|
|
162
|
-
// 0 evaluates to false, which means we would return all rows if we don't check it
|
|
163
|
-
if (!value && value !== 0) {
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
return `${key}:${builder.preprocess(value, allPreProcessingOpts)}`;
|
|
167
|
-
};
|
|
168
|
-
const contains = (key, value, mode = "AND") => {
|
|
169
|
-
if (Array.isArray(value) && value.length === 0) {
|
|
170
|
-
return null;
|
|
171
|
-
}
|
|
172
|
-
if (!Array.isArray(value)) {
|
|
173
|
-
return `${key}:${value}`;
|
|
174
|
-
}
|
|
175
|
-
let statement = `${builder.preprocess(value[0], { escape: true })}`;
|
|
176
|
-
for (let i = 1; i < value.length; i++) {
|
|
177
|
-
statement += ` ${mode} ${builder.preprocess(value[i], {
|
|
178
|
-
escape: true,
|
|
179
|
-
})}`;
|
|
180
|
-
}
|
|
181
|
-
return `${key}:(${statement})`;
|
|
182
|
-
};
|
|
183
|
-
const notContains = (key, value) => {
|
|
184
|
-
// @ts-ignore
|
|
185
|
-
const allPrefix = allOr === "" ? "*:* AND" : "";
|
|
186
|
-
return allPrefix + "NOT " + contains(key, value);
|
|
187
|
-
};
|
|
188
|
-
const containsAny = (key, value) => {
|
|
189
|
-
return contains(key, value, "OR");
|
|
190
|
-
};
|
|
191
|
-
const oneOf = (key, value) => {
|
|
192
|
-
if (!Array.isArray(value)) {
|
|
193
|
-
if (typeof value === "string") {
|
|
194
|
-
value = value.split(",");
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
return "";
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
let orStatement = `${builder.preprocess(value[0], allPreProcessingOpts)}`;
|
|
201
|
-
for (let i = 1; i < value.length; i++) {
|
|
202
|
-
orStatement += ` OR ${builder.preprocess(value[i], allPreProcessingOpts)}`;
|
|
203
|
-
}
|
|
204
|
-
return `${key}:(${orStatement})`;
|
|
205
|
-
};
|
|
206
|
-
function build(structure, queryFn) {
|
|
207
|
-
for (let [key, value] of Object.entries(structure)) {
|
|
208
|
-
// check for new format - remove numbering if needed
|
|
209
|
-
key = (0, utils_2.removeKeyNumbering)(key);
|
|
210
|
-
key = builder.preprocess(key.replace(/ /g, "_"), {
|
|
211
|
-
escape: true,
|
|
212
|
-
});
|
|
213
|
-
const expression = queryFn(key, value);
|
|
214
|
-
if (expression == null) {
|
|
215
|
-
continue;
|
|
216
|
-
}
|
|
217
|
-
if (query.length > 0) {
|
|
218
|
-
query += ` ${allOr ? "OR" : "AND"} `;
|
|
219
|
-
}
|
|
220
|
-
query += expression;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
// Construct the actual lucene search query string from JSON structure
|
|
224
|
-
if (this.query.string) {
|
|
225
|
-
build(this.query.string, (key, value) => {
|
|
226
|
-
if (!value) {
|
|
227
|
-
return null;
|
|
228
|
-
}
|
|
229
|
-
value = builder.preprocess(value, {
|
|
230
|
-
escape: true,
|
|
231
|
-
lowercase: true,
|
|
232
|
-
type: "string",
|
|
233
|
-
});
|
|
234
|
-
return `${key}:${value}*`;
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
if (this.query.range) {
|
|
238
|
-
build(this.query.range, (key, value) => {
|
|
239
|
-
if (!value) {
|
|
240
|
-
return null;
|
|
241
|
-
}
|
|
242
|
-
if (value.low == null || value.low === "") {
|
|
243
|
-
return null;
|
|
244
|
-
}
|
|
245
|
-
if (value.high == null || value.high === "") {
|
|
246
|
-
return null;
|
|
247
|
-
}
|
|
248
|
-
const low = builder.preprocess(value.low, allPreProcessingOpts);
|
|
249
|
-
const high = builder.preprocess(value.high, allPreProcessingOpts);
|
|
250
|
-
return `${key}:[${low} TO ${high}]`;
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
if (this.query.fuzzy) {
|
|
254
|
-
build(this.query.fuzzy, (key, value) => {
|
|
255
|
-
if (!value) {
|
|
256
|
-
return null;
|
|
257
|
-
}
|
|
258
|
-
value = builder.preprocess(value, {
|
|
259
|
-
escape: true,
|
|
260
|
-
lowercase: true,
|
|
261
|
-
type: "fuzzy",
|
|
262
|
-
});
|
|
263
|
-
return `${key}:${value}~`;
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
if (this.query.equal) {
|
|
267
|
-
build(this.query.equal, equal);
|
|
268
|
-
}
|
|
269
|
-
if (this.query.notEqual) {
|
|
270
|
-
build(this.query.notEqual, (key, value) => {
|
|
271
|
-
if (!value) {
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
return `!${key}:${builder.preprocess(value, allPreProcessingOpts)}`;
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
if (this.query.empty) {
|
|
278
|
-
build(this.query.empty, (key) => `!${key}:["" TO *]`);
|
|
279
|
-
}
|
|
280
|
-
if (this.query.notEmpty) {
|
|
281
|
-
build(this.query.notEmpty, (key) => `${key}:["" TO *]`);
|
|
282
|
-
}
|
|
283
|
-
if (this.query.oneOf) {
|
|
284
|
-
build(this.query.oneOf, oneOf);
|
|
285
|
-
}
|
|
286
|
-
if (this.query.contains) {
|
|
287
|
-
build(this.query.contains, contains);
|
|
288
|
-
}
|
|
289
|
-
if (this.query.notContains) {
|
|
290
|
-
build(this.query.notContains, notContains);
|
|
291
|
-
}
|
|
292
|
-
if (this.query.containsAny) {
|
|
293
|
-
build(this.query.containsAny, containsAny);
|
|
294
|
-
}
|
|
295
|
-
// make sure table ID is always added as an AND
|
|
296
|
-
if (tableId) {
|
|
297
|
-
query = `(${query})`;
|
|
298
|
-
allOr = false;
|
|
299
|
-
build({ tableId }, equal);
|
|
300
|
-
}
|
|
301
|
-
return query;
|
|
302
|
-
}
|
|
303
|
-
buildSearchBody() {
|
|
304
|
-
let body = {
|
|
305
|
-
q: this.buildSearchQuery(),
|
|
306
|
-
limit: Math.min(this.limit, 200),
|
|
307
|
-
include_docs: this.includeDocs,
|
|
308
|
-
};
|
|
309
|
-
if (this.bookmark) {
|
|
310
|
-
body.bookmark = this.bookmark;
|
|
311
|
-
}
|
|
312
|
-
if (this.sort) {
|
|
313
|
-
const order = this.sortOrder === "descending" ? "-" : "";
|
|
314
|
-
const type = `<${this.sortType}>`;
|
|
315
|
-
body.sort = `${order}${this.sort.replace(/ /g, "_")}${type}`;
|
|
316
|
-
}
|
|
317
|
-
return body;
|
|
318
|
-
}
|
|
319
|
-
run() {
|
|
320
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
321
|
-
const appId = backend_core_1.context.getAppId();
|
|
322
|
-
const { url, cookie } = backend_core_1.db.getCouchInfo();
|
|
323
|
-
const fullPath = `${url}/${appId}/_design/database/_search/${utils_1.SearchIndexes.ROWS}`;
|
|
324
|
-
const body = this.buildSearchBody();
|
|
325
|
-
return yield runQuery(fullPath, body, cookie);
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
exports.QueryBuilder = QueryBuilder;
|
|
330
|
-
/**
|
|
331
|
-
* Executes a lucene search query.
|
|
332
|
-
* @param url The query URL
|
|
333
|
-
* @param body The request body defining search criteria
|
|
334
|
-
* @param cookie The auth cookie for CouchDB
|
|
335
|
-
* @returns {Promise<{rows: []}>}
|
|
336
|
-
*/
|
|
337
|
-
const runQuery = (url, body, cookie) => __awaiter(void 0, void 0, void 0, function* () {
|
|
338
|
-
const response = yield (0, node_fetch_1.default)(url, {
|
|
339
|
-
body: JSON.stringify(body),
|
|
340
|
-
method: "POST",
|
|
341
|
-
headers: {
|
|
342
|
-
Authorization: cookie,
|
|
343
|
-
},
|
|
344
|
-
});
|
|
345
|
-
const json = yield response.json();
|
|
346
|
-
let output = {
|
|
347
|
-
rows: [],
|
|
348
|
-
};
|
|
349
|
-
if (json.rows != null && json.rows.length > 0) {
|
|
350
|
-
output.rows = json.rows.map((row) => row.doc);
|
|
351
|
-
}
|
|
352
|
-
if (json.bookmark) {
|
|
353
|
-
output.bookmark = json.bookmark;
|
|
354
|
-
}
|
|
355
|
-
return output;
|
|
356
|
-
});
|
|
357
|
-
/**
|
|
358
|
-
* Gets round the fixed limit of 200 results from a query by fetching as many
|
|
359
|
-
* pages as required and concatenating the results. This recursively operates
|
|
360
|
-
* until enough results have been found.
|
|
361
|
-
* @param query {object} The JSON query structure
|
|
362
|
-
* @param params {object} The search params including:
|
|
363
|
-
* tableId {string} The table ID to search
|
|
364
|
-
* sort {string} The sort column
|
|
365
|
-
* sortOrder {string} The sort order ("ascending" or "descending")
|
|
366
|
-
* sortType {string} Whether to treat sortable values as strings or
|
|
367
|
-
* numbers. ("string" or "number")
|
|
368
|
-
* limit {number} The number of results to fetch
|
|
369
|
-
* bookmark {string|null} Current bookmark in the recursive search
|
|
370
|
-
* rows {array|null} Current results in the recursive search
|
|
371
|
-
* @returns {Promise<*[]|*>}
|
|
372
|
-
*/
|
|
373
|
-
function recursiveSearch(query, params) {
|
|
374
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
375
|
-
const bookmark = params.bookmark;
|
|
376
|
-
const rows = params.rows || [];
|
|
377
|
-
if (rows.length >= params.limit) {
|
|
378
|
-
return rows;
|
|
379
|
-
}
|
|
380
|
-
let pageSize = 200;
|
|
381
|
-
if (rows.length > params.limit - 200) {
|
|
382
|
-
pageSize = params.limit - rows.length;
|
|
383
|
-
}
|
|
384
|
-
const page = yield new QueryBuilder(query)
|
|
385
|
-
.setVersion(params.version)
|
|
386
|
-
.setTable(params.tableId)
|
|
387
|
-
.setBookmark(bookmark)
|
|
388
|
-
.setLimit(pageSize)
|
|
389
|
-
.setSort(params.sort)
|
|
390
|
-
.setSortOrder(params.sortOrder)
|
|
391
|
-
.setSortType(params.sortType)
|
|
392
|
-
.run();
|
|
393
|
-
if (!page.rows.length) {
|
|
394
|
-
return rows;
|
|
395
|
-
}
|
|
396
|
-
if (page.rows.length < 200) {
|
|
397
|
-
return [...rows, ...page.rows];
|
|
398
|
-
}
|
|
399
|
-
const newParams = Object.assign(Object.assign({}, params), { bookmark: page.bookmark, rows: [...rows, ...page.rows] });
|
|
400
|
-
return yield recursiveSearch(query, newParams);
|
|
401
|
-
});
|
|
402
|
-
}
|
|
403
|
-
/**
|
|
404
|
-
* Performs a paginated search. A bookmark will be returned to allow the next
|
|
405
|
-
* page to be fetched. There is a max limit off 200 results per page in a
|
|
406
|
-
* paginated search.
|
|
407
|
-
* @param query {object} The JSON query structure
|
|
408
|
-
* @param params {object} The search params including:
|
|
409
|
-
* tableId {string} The table ID to search
|
|
410
|
-
* sort {string} The sort column
|
|
411
|
-
* sortOrder {string} The sort order ("ascending" or "descending")
|
|
412
|
-
* sortType {string} Whether to treat sortable values as strings or
|
|
413
|
-
* numbers. ("string" or "number")
|
|
414
|
-
* limit {number} The desired page size
|
|
415
|
-
* bookmark {string} The bookmark to resume from
|
|
416
|
-
* @returns {Promise<{hasNextPage: boolean, rows: *[]}>}
|
|
417
|
-
*/
|
|
14
|
+
const types_1 = require("@budibase/types");
|
|
418
15
|
function paginatedSearch(query, params) {
|
|
419
16
|
return __awaiter(this, void 0, void 0, function* () {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
limit = 50;
|
|
423
|
-
}
|
|
424
|
-
limit = Math.min(limit, 200);
|
|
425
|
-
const search = new QueryBuilder(query)
|
|
426
|
-
.setVersion(params.version)
|
|
427
|
-
.setTable(params.tableId)
|
|
428
|
-
.setSort(params.sort)
|
|
429
|
-
.setSortOrder(params.sortOrder)
|
|
430
|
-
.setSortType(params.sortType);
|
|
431
|
-
const searchResults = yield search
|
|
432
|
-
.setBookmark(params.bookmark)
|
|
433
|
-
.setLimit(limit)
|
|
434
|
-
.run();
|
|
435
|
-
// Try fetching 1 row in the next page to see if another page of results
|
|
436
|
-
// exists or not
|
|
437
|
-
const nextResults = yield search
|
|
438
|
-
.setTable(params.tableId)
|
|
439
|
-
.setBookmark(searchResults.bookmark)
|
|
440
|
-
.setLimit(1)
|
|
441
|
-
.run();
|
|
442
|
-
return Object.assign(Object.assign({}, searchResults), { hasNextPage: nextResults.rows && nextResults.rows.length > 0 });
|
|
17
|
+
const appId = backend_core_1.context.getAppId();
|
|
18
|
+
return backend_core_1.db.paginatedSearch(appId, types_1.SearchIndex.ROWS, query, params);
|
|
443
19
|
});
|
|
444
20
|
}
|
|
445
21
|
exports.paginatedSearch = paginatedSearch;
|
|
446
|
-
/**
|
|
447
|
-
* Performs a full search, fetching multiple pages if required to return the
|
|
448
|
-
* desired amount of results. There is a limit of 1000 results to avoid
|
|
449
|
-
* heavy performance hits, and to avoid client components breaking from
|
|
450
|
-
* handling too much data.
|
|
451
|
-
* @param query {object} The JSON query structure
|
|
452
|
-
* @param params {object} The search params including:
|
|
453
|
-
* tableId {string} The table ID to search
|
|
454
|
-
* sort {string} The sort column
|
|
455
|
-
* sortOrder {string} The sort order ("ascending" or "descending")
|
|
456
|
-
* sortType {string} Whether to treat sortable values as strings or
|
|
457
|
-
* numbers. ("string" or "number")
|
|
458
|
-
* limit {number} The desired number of results
|
|
459
|
-
* @returns {Promise<{rows: *}>}
|
|
460
|
-
*/
|
|
461
22
|
function fullSearch(query, params) {
|
|
462
23
|
return __awaiter(this, void 0, void 0, function* () {
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
limit = 1000;
|
|
466
|
-
}
|
|
467
|
-
params.limit = Math.min(limit, 1000);
|
|
468
|
-
const rows = yield recursiveSearch(query, params);
|
|
469
|
-
return { rows };
|
|
24
|
+
const appId = backend_core_1.context.getAppId();
|
|
25
|
+
return backend_core_1.db.fullSearch(appId, types_1.SearchIndex.ROWS, query, params);
|
|
470
26
|
});
|
|
471
27
|
}
|
|
472
28
|
exports.fullSearch = fullSearch;
|
|
@@ -35,14 +35,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
35
35
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
36
|
};
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.cleanExportRows = exports.validate = exports.findRow = exports.getDatasourceAndQuery =
|
|
38
|
+
exports.cleanExportRows = exports.validate = exports.findRow = exports.getDatasourceAndQuery = void 0;
|
|
39
39
|
const utils_1 = require("../../../db/utils");
|
|
40
40
|
const userController = __importStar(require("../user"));
|
|
41
41
|
const constants_1 = require("../../../constants");
|
|
42
42
|
const backend_core_1 = require("@budibase/backend-core");
|
|
43
43
|
const query_1 = require("../../../integrations/base/query");
|
|
44
|
-
var utils_2 = require("../../../integrations/base/utils");
|
|
45
|
-
Object.defineProperty(exports, "removeKeyNumbering", { enumerable: true, get: function () { return utils_2.removeKeyNumbering; } });
|
|
46
44
|
const validateJs = require("validate.js");
|
|
47
45
|
const { cloneDeep } = require("lodash/fp");
|
|
48
46
|
const exporters_1 = require("../view/exporters");
|
|
@@ -40,7 +40,7 @@ router
|
|
|
40
40
|
.get("/api/automations/definitions/list", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), controller.getDefinitionList)
|
|
41
41
|
.get("/api/automations", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), controller.fetch)
|
|
42
42
|
.get("/api/automations/:id", (0, resourceId_1.paramResource)("id"), (0, authorized_1.default)(backend_core_1.permissions.BUILDER), controller.find)
|
|
43
|
-
.put("/api/automations", (0, resourceId_1.bodyResource)("_id"), (0, authorized_1.default)(backend_core_1.permissions.BUILDER), (0, validators_1.automationValidator)(
|
|
43
|
+
.put("/api/automations", (0, resourceId_1.bodyResource)("_id"), (0, authorized_1.default)(backend_core_1.permissions.BUILDER), (0, validators_1.automationValidator)(false), controller.update)
|
|
44
44
|
.post("/api/automations", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), (0, validators_1.automationValidator)(false), controller.create)
|
|
45
45
|
.post("/api/automations/logs/search", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), controller.logSearch)
|
|
46
46
|
.delete("/api/automations/logs", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), controller.clearLogError)
|
|
@@ -11,7 +11,7 @@ const read = [], write = [];
|
|
|
11
11
|
* @openapi
|
|
12
12
|
* /applications:
|
|
13
13
|
* post:
|
|
14
|
-
* operationId:
|
|
14
|
+
* operationId: appCreate
|
|
15
15
|
* summary: Create an application
|
|
16
16
|
* tags:
|
|
17
17
|
* - applications
|
|
@@ -39,7 +39,7 @@ write.push(new Endpoint_1.default("post", "/applications", applications_1.defaul
|
|
|
39
39
|
* @openapi
|
|
40
40
|
* /applications/{appId}:
|
|
41
41
|
* put:
|
|
42
|
-
* operationId:
|
|
42
|
+
* operationId: appUpdate
|
|
43
43
|
* summary: Update an application
|
|
44
44
|
* tags:
|
|
45
45
|
* - applications
|
|
@@ -67,7 +67,7 @@ write.push(new Endpoint_1.default("put", "/applications/:appId", applications_1.
|
|
|
67
67
|
* @openapi
|
|
68
68
|
* /applications/{appId}:
|
|
69
69
|
* delete:
|
|
70
|
-
* operationId:
|
|
70
|
+
* operationId: appDestroy
|
|
71
71
|
* summary: Delete an application
|
|
72
72
|
* tags:
|
|
73
73
|
* - applications
|
|
@@ -89,7 +89,7 @@ write.push(new Endpoint_1.default("delete", "/applications/:appId", applications
|
|
|
89
89
|
* @openapi
|
|
90
90
|
* /applications/{appId}/unpublish:
|
|
91
91
|
* post:
|
|
92
|
-
* operationId:
|
|
92
|
+
* operationId: appUnpublish
|
|
93
93
|
* summary: Unpublish an application
|
|
94
94
|
* tags:
|
|
95
95
|
* - applications
|
|
@@ -104,7 +104,7 @@ write.push(new Endpoint_1.default("post", "/applications/:appId/unpublish", appl
|
|
|
104
104
|
* @openapi
|
|
105
105
|
* /applications/{appId}/publish:
|
|
106
106
|
* post:
|
|
107
|
-
* operationId:
|
|
107
|
+
* operationId: appPublish
|
|
108
108
|
* summary: Unpublish an application
|
|
109
109
|
* tags:
|
|
110
110
|
* - applications
|
|
@@ -126,7 +126,7 @@ write.push(new Endpoint_1.default("post", "/applications/:appId/publish", applic
|
|
|
126
126
|
* @openapi
|
|
127
127
|
* /applications/{appId}:
|
|
128
128
|
* get:
|
|
129
|
-
* operationId:
|
|
129
|
+
* operationId: appGetById
|
|
130
130
|
* summary: Retrieve an application
|
|
131
131
|
* tags:
|
|
132
132
|
* - applications
|
|
@@ -148,7 +148,7 @@ read.push(new Endpoint_1.default("get", "/applications/:appId", applications_1.d
|
|
|
148
148
|
* @openapi
|
|
149
149
|
* /applications/search:
|
|
150
150
|
* post:
|
|
151
|
-
* operationId:
|
|
151
|
+
* operationId: appSearch
|
|
152
152
|
* summary: Search for applications
|
|
153
153
|
* description: Based on application properties (currently only name) search for applications.
|
|
154
154
|
* tags:
|
|
@@ -11,7 +11,7 @@ const read = [], write = [];
|
|
|
11
11
|
* @openapi
|
|
12
12
|
* /queries/{queryId}:
|
|
13
13
|
* post:
|
|
14
|
-
* operationId:
|
|
14
|
+
* operationId: queryExecute
|
|
15
15
|
* summary: Execute a query
|
|
16
16
|
* description: Queries which have been created within a Budibase app can be executed using this,
|
|
17
17
|
* tags:
|
|
@@ -44,7 +44,7 @@ write.push(new Endpoint_1.default("post", "/queries/:queryId", queries_1.default
|
|
|
44
44
|
* @openapi
|
|
45
45
|
* /queries/search:
|
|
46
46
|
* post:
|
|
47
|
-
* operationId:
|
|
47
|
+
* operationId: querySearch
|
|
48
48
|
* summary: Search for queries
|
|
49
49
|
* description: Based on query properties (currently only name) search for queries.
|
|
50
50
|
* tags:
|
|
@@ -11,7 +11,7 @@ const read = [], write = [];
|
|
|
11
11
|
* @openapi
|
|
12
12
|
* /tables/{tableId}/rows:
|
|
13
13
|
* post:
|
|
14
|
-
* operationId:
|
|
14
|
+
* operationId: rowCreate
|
|
15
15
|
* summary: Create a row
|
|
16
16
|
* description: Creates a row within the specified table.
|
|
17
17
|
* tags:
|
|
@@ -45,7 +45,7 @@ write.push(new Endpoint_1.default("post", "/tables/:tableId/rows", rows_1.defaul
|
|
|
45
45
|
* @openapi
|
|
46
46
|
* /tables/{tableId}/rows/{rowId}:
|
|
47
47
|
* put:
|
|
48
|
-
* operationId:
|
|
48
|
+
* operationId: rowUpdate
|
|
49
49
|
* summary: Update a row
|
|
50
50
|
* description: Updates a row within the specified table.
|
|
51
51
|
* tags:
|
|
@@ -79,7 +79,7 @@ write.push(new Endpoint_1.default("put", "/tables/:tableId/rows/:rowId", rows_1.
|
|
|
79
79
|
* @openapi
|
|
80
80
|
* /tables/{tableId}/rows/{rowId}:
|
|
81
81
|
* delete:
|
|
82
|
-
* operationId:
|
|
82
|
+
* operationId: rowDestroy
|
|
83
83
|
* summary: Delete a row
|
|
84
84
|
* description: Deletes a row within the specified table.
|
|
85
85
|
* tags:
|
|
@@ -104,7 +104,7 @@ write.push(new Endpoint_1.default("delete", "/tables/:tableId/rows/:rowId", rows
|
|
|
104
104
|
* @openapi
|
|
105
105
|
* /tables/{tableId}/rows/{rowId}:
|
|
106
106
|
* get:
|
|
107
|
-
* operationId:
|
|
107
|
+
* operationId: rowGetById
|
|
108
108
|
* summary: Retrieve a row
|
|
109
109
|
* description: This gets a single row, it will be enriched with the full related rows, rather than
|
|
110
110
|
* the squashed "primaryDisplay" format returned by the search endpoint.
|
|
@@ -130,7 +130,7 @@ read.push(new Endpoint_1.default("get", "/tables/:tableId/rows/:rowId", rows_1.d
|
|
|
130
130
|
* @openapi
|
|
131
131
|
* /tables/{tableId}/rows/search:
|
|
132
132
|
* post:
|
|
133
|
-
* operationId:
|
|
133
|
+
* operationId: rowSearch
|
|
134
134
|
* summary: Search for rows
|
|
135
135
|
* tags:
|
|
136
136
|
* - rows
|
|
@@ -11,7 +11,7 @@ const read = [], write = [];
|
|
|
11
11
|
* @openapi
|
|
12
12
|
* /tables:
|
|
13
13
|
* post:
|
|
14
|
-
* operationId:
|
|
14
|
+
* operationId: tableCreate
|
|
15
15
|
* summary: Create a table
|
|
16
16
|
* description: Create a table, this could be internal or external.
|
|
17
17
|
* tags:
|
|
@@ -43,7 +43,7 @@ write.push(new Endpoint_1.default("post", "/tables", tables_1.default.create).ad
|
|
|
43
43
|
* @openapi
|
|
44
44
|
* /tables/{tableId}:
|
|
45
45
|
* put:
|
|
46
|
-
* operationId:
|
|
46
|
+
* operationId: tableUpdate
|
|
47
47
|
* summary: Update a table
|
|
48
48
|
* description: Update a table, this could be internal or external.
|
|
49
49
|
* tags:
|
|
@@ -75,7 +75,7 @@ write.push(new Endpoint_1.default("put", "/tables/:tableId", tables_1.default.up
|
|
|
75
75
|
* @openapi
|
|
76
76
|
* /tables/{tableId}:
|
|
77
77
|
* delete:
|
|
78
|
-
* operationId:
|
|
78
|
+
* operationId: tableDestroy
|
|
79
79
|
* summary: Delete a table
|
|
80
80
|
* description: Delete a table, this could be internal or external.
|
|
81
81
|
* tags:
|
|
@@ -99,7 +99,7 @@ write.push(new Endpoint_1.default("delete", "/tables/:tableId", tables_1.default
|
|
|
99
99
|
* @openapi
|
|
100
100
|
* /tables/{tableId}:
|
|
101
101
|
* get:
|
|
102
|
-
* operationId:
|
|
102
|
+
* operationId: tableGetById
|
|
103
103
|
* summary: Retrieve a table
|
|
104
104
|
* description: Lookup a table, this could be internal or external.
|
|
105
105
|
* tags:
|
|
@@ -123,7 +123,7 @@ read.push(new Endpoint_1.default("get", "/tables/:tableId", tables_1.default.rea
|
|
|
123
123
|
* @openapi
|
|
124
124
|
* /tables/search:
|
|
125
125
|
* post:
|
|
126
|
-
* operationId:
|
|
126
|
+
* operationId: tableSearch
|
|
127
127
|
* summary: Search for tables
|
|
128
128
|
* description: Based on table properties (currently only name) search for tables. This could be
|
|
129
129
|
* an internal or an external table.
|