@budibase/server 2.4.38 → 2.4.40
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/builder/assets/{index.7c263eae.js → index.07ed2ead.js} +249 -250
- package/builder/index.html +1 -1
- package/dist/api/controllers/datasource.js +1 -2
- package/dist/api/controllers/row/external.js +8 -16
- package/dist/api/controllers/row/index.js +1 -5
- package/dist/api/controllers/row/internal.js +10 -1
- package/dist/api/controllers/row/utils.js +4 -3
- package/dist/api/controllers/table/external.js +12 -16
- package/dist/api/controllers/table/utils.js +1 -15
- package/dist/constants/index.js +1 -2
- package/dist/integrations/googlesheets.js +59 -125
- package/dist/integrations/utils.js +2 -17
- package/dist/package.json +7 -7
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +8 -8
- package/src/api/controllers/datasource.ts +1 -2
- package/src/api/controllers/row/external.ts +16 -26
- package/src/api/controllers/row/index.ts +2 -7
- package/src/api/controllers/row/internal.ts +7 -0
- package/src/api/controllers/row/utils.ts +4 -3
- package/src/api/controllers/table/external.ts +17 -24
- package/src/api/controllers/table/index.ts +9 -9
- package/src/api/controllers/table/utils.ts +2 -18
- package/src/constants/index.ts +0 -1
- package/src/integrations/googlesheets.ts +71 -143
- package/src/integrations/utils.ts +4 -16
package/builder/index.html
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap"
|
|
11
11
|
rel="stylesheet"
|
|
12
12
|
/>
|
|
13
|
-
<script type="module" crossorigin src="/builder/assets/index.
|
|
13
|
+
<script type="module" crossorigin src="/builder/assets/index.07ed2ead.js"></script>
|
|
14
14
|
<link rel="stylesheet" href="/builder/assets/index.b0e3aca6.css">
|
|
15
15
|
</head>
|
|
16
16
|
<body id="app">
|
|
@@ -74,8 +74,7 @@ function buildSchemaFromDb(ctx) {
|
|
|
74
74
|
setDefaultDisplayColumns(datasource);
|
|
75
75
|
const dbResp = yield db.put(datasource);
|
|
76
76
|
datasource._rev = dbResp.rev;
|
|
77
|
-
const
|
|
78
|
-
const response = { datasource: cleanedDatasource };
|
|
77
|
+
const response = { datasource };
|
|
79
78
|
if (error) {
|
|
80
79
|
response.error = error;
|
|
81
80
|
}
|
|
@@ -46,7 +46,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
46
46
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
47
|
};
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
-
exports.fetchEnrichedRow = exports.exportRows = exports.search = exports.bulkDestroy = exports.destroy = exports.find = exports.fetch = exports.fetchView = exports.save = exports.patch = exports.handleRequest = void 0;
|
|
49
|
+
exports.fetchEnrichedRow = exports.exportRows = exports.validate = exports.search = exports.bulkDestroy = exports.destroy = exports.find = exports.fetch = exports.fetchView = exports.save = exports.patch = exports.handleRequest = void 0;
|
|
50
50
|
const constants_1 = require("../../../constants");
|
|
51
51
|
const utils_1 = require("../../../integrations/utils");
|
|
52
52
|
const ExternalRequest_1 = require("./ExternalRequest");
|
|
@@ -54,7 +54,6 @@ const exporters = __importStar(require("../view/exporters"));
|
|
|
54
54
|
const fileSystem_1 = require("../../../utilities/fileSystem");
|
|
55
55
|
const types_1 = require("@budibase/types");
|
|
56
56
|
const sdk_1 = __importDefault(require("../../../sdk"));
|
|
57
|
-
const utils = __importStar(require("./utils"));
|
|
58
57
|
const { cleanExportRows } = require("./utils");
|
|
59
58
|
function handleRequest(operation, tableId, opts) {
|
|
60
59
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -84,13 +83,6 @@ function patch(ctx) {
|
|
|
84
83
|
const id = inputs._id;
|
|
85
84
|
// don't save the ID to db
|
|
86
85
|
delete inputs._id;
|
|
87
|
-
const validateResult = yield utils.validate({
|
|
88
|
-
row: inputs,
|
|
89
|
-
tableId,
|
|
90
|
-
});
|
|
91
|
-
if (!validateResult.valid) {
|
|
92
|
-
throw { validation: validateResult.errors };
|
|
93
|
-
}
|
|
94
86
|
return handleRequest(types_1.Operation.UPDATE, tableId, {
|
|
95
87
|
id: (0, utils_1.breakRowIdField)(id),
|
|
96
88
|
row: inputs,
|
|
@@ -103,13 +95,6 @@ function save(ctx) {
|
|
|
103
95
|
return __awaiter(this, void 0, void 0, function* () {
|
|
104
96
|
const inputs = ctx.request.body;
|
|
105
97
|
const tableId = ctx.params.tableId;
|
|
106
|
-
const validateResult = yield utils.validate({
|
|
107
|
-
row: inputs,
|
|
108
|
-
tableId,
|
|
109
|
-
});
|
|
110
|
-
if (!validateResult.valid) {
|
|
111
|
-
throw { validation: validateResult.errors };
|
|
112
|
-
}
|
|
113
98
|
return handleRequest(types_1.Operation.CREATE, tableId, {
|
|
114
99
|
row: inputs,
|
|
115
100
|
includeSqlRelationships: types_1.IncludeRelationship.EXCLUDE,
|
|
@@ -240,6 +225,13 @@ function search(ctx) {
|
|
|
240
225
|
});
|
|
241
226
|
}
|
|
242
227
|
exports.search = search;
|
|
228
|
+
function validate(ctx) {
|
|
229
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
230
|
+
// can't validate external right now - maybe in future
|
|
231
|
+
return { valid: true };
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
exports.validate = validate;
|
|
243
235
|
function exportRows(ctx) {
|
|
244
236
|
return __awaiter(this, void 0, void 0, function* () {
|
|
245
237
|
const { datasourceId, tableName } = (0, utils_1.breakExternalTableId)(ctx.params.tableId);
|
|
@@ -37,7 +37,6 @@ const pro_1 = require("@budibase/pro");
|
|
|
37
37
|
const internal = __importStar(require("./internal"));
|
|
38
38
|
const external = __importStar(require("./external"));
|
|
39
39
|
const utils_1 = require("../../../integrations/utils");
|
|
40
|
-
const utils = __importStar(require("./utils"));
|
|
41
40
|
function pickApi(tableId) {
|
|
42
41
|
if ((0, utils_1.isExternalTable)(tableId)) {
|
|
43
42
|
return external;
|
|
@@ -172,10 +171,7 @@ exports.search = search;
|
|
|
172
171
|
function validate(ctx) {
|
|
173
172
|
return __awaiter(this, void 0, void 0, function* () {
|
|
174
173
|
const tableId = getTableId(ctx);
|
|
175
|
-
ctx.body = yield
|
|
176
|
-
row: ctx.request.body,
|
|
177
|
-
tableId,
|
|
178
|
-
});
|
|
174
|
+
ctx.body = yield pickApi(tableId).validate(ctx);
|
|
179
175
|
});
|
|
180
176
|
}
|
|
181
177
|
exports.validate = validate;
|
|
@@ -46,7 +46,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
46
46
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
47
|
};
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
-
exports.fetchEnrichedRow = exports.exportRows = exports.search = exports.bulkDestroy = exports.destroy = exports.find = exports.fetch = exports.fetchView = exports.save = exports.patch = void 0;
|
|
49
|
+
exports.fetchEnrichedRow = exports.exportRows = exports.validate = exports.search = exports.bulkDestroy = exports.destroy = exports.find = exports.fetch = exports.fetchView = exports.save = exports.patch = void 0;
|
|
50
50
|
const linkRows = __importStar(require("../../../db/linkedRows"));
|
|
51
51
|
const utils_1 = require("../../../db/utils");
|
|
52
52
|
const userController = __importStar(require("../user"));
|
|
@@ -392,6 +392,15 @@ function search(ctx) {
|
|
|
392
392
|
});
|
|
393
393
|
}
|
|
394
394
|
exports.search = search;
|
|
395
|
+
function validate(ctx) {
|
|
396
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
397
|
+
return utils.validate({
|
|
398
|
+
tableId: ctx.params.tableId,
|
|
399
|
+
row: ctx.request.body,
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
exports.validate = validate;
|
|
395
404
|
function exportRows(ctx) {
|
|
396
405
|
return __awaiter(this, void 0, void 0, function* () {
|
|
397
406
|
const db = backend_core_1.context.getAppDB();
|
|
@@ -41,10 +41,10 @@ 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
|
-
const exporters_1 = require("../view/exporters");
|
|
45
|
-
const sdk_1 = __importDefault(require("../../../sdk"));
|
|
46
44
|
const validateJs = require("validate.js");
|
|
47
45
|
const { cloneDeep } = require("lodash/fp");
|
|
46
|
+
const exporters_1 = require("../view/exporters");
|
|
47
|
+
const sdk_1 = __importDefault(require("../../../sdk"));
|
|
48
48
|
validateJs.extend(validateJs.validators.datetime, {
|
|
49
49
|
parse: function (value) {
|
|
50
50
|
return new Date(value).getTime();
|
|
@@ -88,7 +88,8 @@ function validate({ tableId, row, table, }) {
|
|
|
88
88
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89
89
|
let fetchedTable;
|
|
90
90
|
if (!table) {
|
|
91
|
-
|
|
91
|
+
const db = backend_core_1.context.getAppDB();
|
|
92
|
+
fetchedTable = yield db.get(tableId);
|
|
92
93
|
}
|
|
93
94
|
else {
|
|
94
95
|
fetchedTable = table;
|
|
@@ -150,16 +150,16 @@ function isRelationshipSetup(column) {
|
|
|
150
150
|
}
|
|
151
151
|
function save(ctx) {
|
|
152
152
|
return __awaiter(this, void 0, void 0, function* () {
|
|
153
|
-
const
|
|
154
|
-
const renamed =
|
|
153
|
+
const table = ctx.request.body;
|
|
154
|
+
const renamed = table === null || table === void 0 ? void 0 : table._rename;
|
|
155
155
|
// can't do this right now
|
|
156
|
-
delete
|
|
156
|
+
delete table.rows;
|
|
157
157
|
const datasourceId = getDatasourceId(ctx.request.body);
|
|
158
158
|
// table doesn't exist already, note that it is created
|
|
159
|
-
if (!
|
|
160
|
-
|
|
159
|
+
if (!table._id) {
|
|
160
|
+
table.created = true;
|
|
161
161
|
}
|
|
162
|
-
let tableToSave = Object.assign({ type: "table", _id: (0, utils_1.buildExternalTableId)(datasourceId,
|
|
162
|
+
let tableToSave = Object.assign({ type: "table", _id: (0, utils_1.buildExternalTableId)(datasourceId, table.name) }, table);
|
|
163
163
|
let oldTable;
|
|
164
164
|
if (ctx.request.body && ctx.request.body._id) {
|
|
165
165
|
oldTable = yield sdk_1.default.tables.getTable(ctx.request.body._id);
|
|
@@ -172,8 +172,6 @@ function save(ctx) {
|
|
|
172
172
|
if (!datasource.entities) {
|
|
173
173
|
datasource.entities = {};
|
|
174
174
|
}
|
|
175
|
-
// GSheets is a specific case - only ever has a static primary key
|
|
176
|
-
tableToSave = (0, utils_2.setStaticSchemas)(datasource, tableToSave);
|
|
177
175
|
const oldTables = cloneDeep(datasource.entities);
|
|
178
176
|
const tables = datasource.entities;
|
|
179
177
|
const extraTablesToUpdate = [];
|
|
@@ -189,7 +187,7 @@ function save(ctx) {
|
|
|
189
187
|
const relatedColumnName = schema.fieldName;
|
|
190
188
|
const relationType = schema.relationshipType;
|
|
191
189
|
if (relationType === types_1.RelationshipTypes.MANY_TO_MANY) {
|
|
192
|
-
const junctionTable = generateManyLinkSchema(datasource, schema,
|
|
190
|
+
const junctionTable = generateManyLinkSchema(datasource, schema, table, relatedTable);
|
|
193
191
|
if (tables[junctionTable.name]) {
|
|
194
192
|
throw "Junction table already exists, cannot create another relationship.";
|
|
195
193
|
}
|
|
@@ -197,10 +195,8 @@ function save(ctx) {
|
|
|
197
195
|
extraTablesToUpdate.push(junctionTable);
|
|
198
196
|
}
|
|
199
197
|
else {
|
|
200
|
-
const fkTable = relationType === types_1.RelationshipTypes.ONE_TO_MANY
|
|
201
|
-
|
|
202
|
-
: relatedTable;
|
|
203
|
-
const foreignKey = generateLinkSchema(schema, tableToSave, relatedTable, relationType);
|
|
198
|
+
const fkTable = relationType === types_1.RelationshipTypes.ONE_TO_MANY ? table : relatedTable;
|
|
199
|
+
const foreignKey = generateLinkSchema(schema, table, relatedTable, relationType);
|
|
204
200
|
fkTable.schema[foreignKey] = (0, utils_2.foreignKeyStructure)(foreignKey);
|
|
205
201
|
if (fkTable.constrained == null) {
|
|
206
202
|
fkTable.constrained = [];
|
|
@@ -209,11 +205,11 @@ function save(ctx) {
|
|
|
209
205
|
fkTable.constrained.push(foreignKey);
|
|
210
206
|
}
|
|
211
207
|
// foreign key is in other table, need to save it to external
|
|
212
|
-
if (fkTable._id !==
|
|
208
|
+
if (fkTable._id !== table._id) {
|
|
213
209
|
extraTablesToUpdate.push(fkTable);
|
|
214
210
|
}
|
|
215
211
|
}
|
|
216
|
-
generateRelatedSchema(schema, relatedTable,
|
|
212
|
+
generateRelatedSchema(schema, relatedTable, table, relatedColumnName);
|
|
217
213
|
schema.main = true;
|
|
218
214
|
}
|
|
219
215
|
cleanupRelationships(tableToSave, tables, oldTable);
|
|
@@ -268,7 +264,7 @@ function bulkImport(ctx) {
|
|
|
268
264
|
if (!rows || !(0, schema_1.isRows)(rows) || !(0, schema_1.isSchema)(schema)) {
|
|
269
265
|
ctx.throw(400, "Provided data import information is invalid.");
|
|
270
266
|
}
|
|
271
|
-
const parsedRows = (0, schema_1.parse)(rows, schema);
|
|
267
|
+
const parsedRows = yield (0, schema_1.parse)(rows, schema);
|
|
272
268
|
yield (0, external_1.handleRequest)(types_1.Operation.BULK_CREATE, table._id, {
|
|
273
269
|
rows: parsedRows,
|
|
274
270
|
});
|
|
@@ -12,7 +12,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
12
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.TableSaveFunctions = exports.
|
|
15
|
+
exports.TableSaveFunctions = exports.hasTypeChanged = exports.areSwitchableTypes = exports.foreignKeyStructure = exports.generateJunctionTableName = exports.generateForeignKey = exports.checkForViewUpdates = exports.checkStaticTables = exports.handleSearchIndexes = exports.handleDataImport = exports.importToRows = exports.makeSureTableUpToDate = exports.checkForColumnUpdates = exports.clearColumns = void 0;
|
|
16
16
|
const schema_1 = require("../../../utilities/schema");
|
|
17
17
|
const utils_1 = require("../../../db/utils");
|
|
18
18
|
const lodash_1 = require("lodash");
|
|
@@ -24,7 +24,6 @@ const viewBuilder_1 = __importDefault(require("../view/viewBuilder"));
|
|
|
24
24
|
const fp_1 = require("lodash/fp");
|
|
25
25
|
const pro_1 = require("@budibase/pro");
|
|
26
26
|
const backend_core_1 = require("@budibase/backend-core");
|
|
27
|
-
const types_1 = require("@budibase/types");
|
|
28
27
|
function clearColumns(table, columnNames) {
|
|
29
28
|
return __awaiter(this, void 0, void 0, function* () {
|
|
30
29
|
const db = backend_core_1.context.getAppDB();
|
|
@@ -357,18 +356,5 @@ function hasTypeChanged(table, oldTable) {
|
|
|
357
356
|
return false;
|
|
358
357
|
}
|
|
359
358
|
exports.hasTypeChanged = hasTypeChanged;
|
|
360
|
-
// used for external tables, some of them will have static schemas that need
|
|
361
|
-
// to be hard set
|
|
362
|
-
function setStaticSchemas(datasource, table) {
|
|
363
|
-
var _a;
|
|
364
|
-
// GSheets is a specific case - only ever has a static primary key
|
|
365
|
-
if (table && datasource.source === types_1.SourceName.GOOGLE_SHEETS) {
|
|
366
|
-
table.primary = [constants_1.GOOGLE_SHEETS_PRIMARY_KEY];
|
|
367
|
-
// if there is an id column, remove it, should never exist in GSheets
|
|
368
|
-
(_a = table.schema) === null || _a === void 0 ? true : delete _a.id;
|
|
369
|
-
}
|
|
370
|
-
return table;
|
|
371
|
-
}
|
|
372
|
-
exports.setStaticSchemas = setStaticSchemas;
|
|
373
359
|
const _TableSaveFunctions = TableSaveFunctions;
|
|
374
360
|
exports.TableSaveFunctions = _TableSaveFunctions;
|
package/dist/constants/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.MAX_AUTOMATION_RECURRING_ERRORS = exports.ObjectStoreBuckets = exports.AutomationErrors = exports.BuildSchemaErrors = exports.InvalidColumns = exports.MetadataTypes = exports.BaseQueryVerbs = exports.OBJ_STORE_DIRECTORY = exports.AutoFieldDefaultNames = exports.AutoFieldSubTypes = exports.USERS_TABLE_SCHEMA = exports.SortDirection = exports.DatasourceAuthTypes = exports.DataSourceOperation = exports.AuthTypes = exports.FormulaTypes = exports.SwitchableTypes = exports.CanSwitchTypes = exports.NoEmptyFilterStrings = exports.FilterTypes = exports.RelationshipTypes = exports.FieldTypes = void 0;
|
|
4
4
|
const backend_core_1 = require("@budibase/backend-core");
|
|
5
5
|
var types_1 = require("@budibase/types");
|
|
6
6
|
Object.defineProperty(exports, "FieldTypes", { enumerable: true, get: function () { return types_1.FieldType; } });
|
|
@@ -178,4 +178,3 @@ var AutomationErrors;
|
|
|
178
178
|
// pass through the list from the auth/core lib
|
|
179
179
|
exports.ObjectStoreBuckets = backend_core_1.objectStore.ObjectStoreBuckets;
|
|
180
180
|
exports.MAX_AUTOMATION_RECURRING_ERRORS = 5;
|
|
181
|
-
exports.GOOGLE_SHEETS_PRIMARY_KEY = "rowNumber";
|
|
@@ -15,21 +15,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const types_1 = require("@budibase/types");
|
|
16
16
|
const google_auth_library_1 = require("google-auth-library");
|
|
17
17
|
const utils_1 = require("./utils");
|
|
18
|
+
const constants_1 = require("../constants");
|
|
18
19
|
const google_spreadsheet_1 = require("google-spreadsheet");
|
|
19
20
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
20
21
|
const backend_core_1 = require("@budibase/backend-core");
|
|
21
22
|
const shared_core_1 = require("@budibase/shared-core");
|
|
22
|
-
const constants_1 = require("../constants");
|
|
23
|
-
const ALLOWED_TYPES = [
|
|
24
|
-
types_1.FieldType.STRING,
|
|
25
|
-
types_1.FieldType.FORMULA,
|
|
26
|
-
types_1.FieldType.NUMBER,
|
|
27
|
-
types_1.FieldType.LONGFORM,
|
|
28
|
-
types_1.FieldType.DATETIME,
|
|
29
|
-
types_1.FieldType.OPTIONS,
|
|
30
|
-
types_1.FieldType.BOOLEAN,
|
|
31
|
-
types_1.FieldType.BARCODEQR,
|
|
32
|
-
];
|
|
33
23
|
const SCHEMA = {
|
|
34
24
|
plus: true,
|
|
35
25
|
auth: {
|
|
@@ -145,7 +135,6 @@ class GoogleSheetsIntegration {
|
|
|
145
135
|
});
|
|
146
136
|
}
|
|
147
137
|
connect() {
|
|
148
|
-
var _a;
|
|
149
138
|
return __awaiter(this, void 0, void 0, function* () {
|
|
150
139
|
try {
|
|
151
140
|
// Initialise oAuth client
|
|
@@ -170,36 +159,12 @@ class GoogleSheetsIntegration {
|
|
|
170
159
|
yield this.client.loadInfo();
|
|
171
160
|
}
|
|
172
161
|
catch (err) {
|
|
173
|
-
// this happens for xlsx imports
|
|
174
|
-
if ((_a = err.message) === null || _a === void 0 ? void 0 : _a.includes("operation is not supported")) {
|
|
175
|
-
err.message =
|
|
176
|
-
"This operation is not supported - XLSX sheets must be converted.";
|
|
177
|
-
}
|
|
178
162
|
console.error("Error connecting to google sheets", err);
|
|
179
163
|
throw err;
|
|
180
164
|
}
|
|
181
165
|
});
|
|
182
166
|
}
|
|
183
|
-
|
|
184
|
-
// base table
|
|
185
|
-
const table = {
|
|
186
|
-
name: title,
|
|
187
|
-
primary: [constants_1.GOOGLE_SHEETS_PRIMARY_KEY],
|
|
188
|
-
schema: {},
|
|
189
|
-
};
|
|
190
|
-
if (id) {
|
|
191
|
-
table._id = id;
|
|
192
|
-
}
|
|
193
|
-
// build schema from headers
|
|
194
|
-
for (let header of headerValues) {
|
|
195
|
-
table.schema[header] = {
|
|
196
|
-
name: header,
|
|
197
|
-
type: types_1.FieldType.STRING,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
return table;
|
|
201
|
-
}
|
|
202
|
-
buildSchema(datasourceId, entities) {
|
|
167
|
+
buildSchema(datasourceId) {
|
|
203
168
|
return __awaiter(this, void 0, void 0, function* () {
|
|
204
169
|
yield this.connect();
|
|
205
170
|
const sheets = this.client.sheetsByIndex;
|
|
@@ -207,47 +172,56 @@ class GoogleSheetsIntegration {
|
|
|
207
172
|
for (let sheet of sheets) {
|
|
208
173
|
// must fetch rows to determine schema
|
|
209
174
|
yield sheet.getRows();
|
|
210
|
-
|
|
211
|
-
|
|
175
|
+
// build schema
|
|
176
|
+
const schema = {};
|
|
177
|
+
// build schema from headers
|
|
178
|
+
for (let header of sheet.headerValues) {
|
|
179
|
+
schema[header] = {
|
|
180
|
+
name: header,
|
|
181
|
+
type: constants_1.FieldTypes.STRING,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// create tables
|
|
185
|
+
tables[sheet.title] = {
|
|
186
|
+
_id: (0, utils_1.buildExternalTableId)(datasourceId, sheet.title),
|
|
187
|
+
name: sheet.title,
|
|
188
|
+
primary: ["rowNumber"],
|
|
189
|
+
schema,
|
|
190
|
+
};
|
|
212
191
|
}
|
|
213
|
-
|
|
214
|
-
this.tables = final.tables;
|
|
215
|
-
this.schemaErrors = final.errors;
|
|
192
|
+
this.tables = tables;
|
|
216
193
|
});
|
|
217
194
|
}
|
|
218
195
|
query(json) {
|
|
219
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
220
196
|
return __awaiter(this, void 0, void 0, function* () {
|
|
221
197
|
const sheet = json.endpoint.entityId;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
case types_1.Operation.READ:
|
|
228
|
-
return this.read(Object.assign(Object.assign({}, json), { sheet }));
|
|
229
|
-
case types_1.Operation.UPDATE:
|
|
198
|
+
const handlers = {
|
|
199
|
+
[constants_1.DataSourceOperation.CREATE]: () => this.create({ sheet, row: json.body }),
|
|
200
|
+
[constants_1.DataSourceOperation.READ]: () => this.read(Object.assign(Object.assign({}, json), { sheet })),
|
|
201
|
+
[constants_1.DataSourceOperation.UPDATE]: () => {
|
|
202
|
+
var _a, _b, _c;
|
|
230
203
|
return this.update({
|
|
231
204
|
// exclude the header row and zero index
|
|
232
205
|
rowIndex: ((_c = (_b = (_a = json.extra) === null || _a === void 0 ? void 0 : _a.idFilter) === null || _b === void 0 ? void 0 : _b.equal) === null || _c === void 0 ? void 0 : _c.rowNumber) - 2,
|
|
233
206
|
sheet,
|
|
234
207
|
row: json.body,
|
|
235
208
|
});
|
|
236
|
-
|
|
209
|
+
},
|
|
210
|
+
[constants_1.DataSourceOperation.DELETE]: () => {
|
|
211
|
+
var _a, _b, _c;
|
|
237
212
|
return this.delete({
|
|
238
213
|
// exclude the header row and zero index
|
|
239
|
-
rowIndex: ((
|
|
214
|
+
rowIndex: ((_c = (_b = (_a = json.extra) === null || _a === void 0 ? void 0 : _a.idFilter) === null || _b === void 0 ? void 0 : _b.equal) === null || _c === void 0 ? void 0 : _c.rowNumber) - 2,
|
|
240
215
|
sheet,
|
|
241
216
|
});
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
217
|
+
},
|
|
218
|
+
[constants_1.DataSourceOperation.CREATE_TABLE]: () => { var _a; return this.createTable((_a = json === null || json === void 0 ? void 0 : json.table) === null || _a === void 0 ? void 0 : _a.name); },
|
|
219
|
+
[constants_1.DataSourceOperation.UPDATE_TABLE]: () => this.updateTable(json.table),
|
|
220
|
+
[constants_1.DataSourceOperation.DELETE_TABLE]: () => { var _a; return this.deleteTable((_a = json === null || json === void 0 ? void 0 : json.table) === null || _a === void 0 ? void 0 : _a.name); },
|
|
221
|
+
};
|
|
222
|
+
// @ts-ignore
|
|
223
|
+
const internalQueryMethod = handlers[json.endpoint.operation];
|
|
224
|
+
return yield internalQueryMethod();
|
|
251
225
|
});
|
|
252
226
|
}
|
|
253
227
|
buildRowObject(headers, values, rowNumber) {
|
|
@@ -260,12 +234,9 @@ class GoogleSheetsIntegration {
|
|
|
260
234
|
}
|
|
261
235
|
createTable(name) {
|
|
262
236
|
return __awaiter(this, void 0, void 0, function* () {
|
|
263
|
-
if (!name) {
|
|
264
|
-
throw new Error("Must provide name for new sheet.");
|
|
265
|
-
}
|
|
266
237
|
try {
|
|
267
238
|
yield this.connect();
|
|
268
|
-
return yield this.client.addSheet({ title: name, headerValues: [
|
|
239
|
+
return yield this.client.addSheet({ title: name, headerValues: ["test"] });
|
|
269
240
|
}
|
|
270
241
|
catch (err) {
|
|
271
242
|
console.error("Error creating new table in google sheets", err);
|
|
@@ -275,53 +246,34 @@ class GoogleSheetsIntegration {
|
|
|
275
246
|
}
|
|
276
247
|
updateTable(table) {
|
|
277
248
|
return __awaiter(this, void 0, void 0, function* () {
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
249
|
+
try {
|
|
250
|
+
yield this.connect();
|
|
251
|
+
const sheet = this.client.sheetsByTitle[table.name];
|
|
252
|
+
yield sheet.loadHeaderRow();
|
|
253
|
+
if (table._rename) {
|
|
254
|
+
const headers = [];
|
|
255
|
+
for (let header of sheet.headerValues) {
|
|
256
|
+
if (header === table._rename.old) {
|
|
257
|
+
headers.push(table._rename.updated);
|
|
258
|
+
}
|
|
259
|
+
else {
|
|
260
|
+
headers.push(header);
|
|
261
|
+
}
|
|
289
262
|
}
|
|
290
|
-
}
|
|
291
|
-
try {
|
|
292
263
|
yield sheet.setHeaderRow(headers);
|
|
293
264
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
else {
|
|
300
|
-
const updatedHeaderValues = [...sheet.headerValues];
|
|
301
|
-
// add new column - doesn't currently exist
|
|
302
|
-
for (let [key, column] of Object.entries(table.schema)) {
|
|
303
|
-
if (!ALLOWED_TYPES.includes(column.type)) {
|
|
304
|
-
throw new Error(`Column type: ${column.type} not allowed for GSheets integration.`);
|
|
305
|
-
}
|
|
306
|
-
if (!sheet.headerValues.includes(key) &&
|
|
307
|
-
column.type !== types_1.FieldType.FORMULA) {
|
|
308
|
-
updatedHeaderValues.push(key);
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
// clear out deleted columns
|
|
312
|
-
for (let key of sheet.headerValues) {
|
|
313
|
-
if (!Object.keys(table.schema).includes(key)) {
|
|
314
|
-
const idx = updatedHeaderValues.indexOf(key);
|
|
315
|
-
updatedHeaderValues.splice(idx, 1);
|
|
265
|
+
else {
|
|
266
|
+
const updatedHeaderValues = [...sheet.headerValues];
|
|
267
|
+
const newField = Object.keys(table.schema).find(key => !sheet.headerValues.includes(key));
|
|
268
|
+
if (newField) {
|
|
269
|
+
updatedHeaderValues.push(newField);
|
|
316
270
|
}
|
|
317
|
-
}
|
|
318
|
-
try {
|
|
319
271
|
yield sheet.setHeaderRow(updatedHeaderValues);
|
|
320
272
|
}
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
console.error("Error updating table in google sheets", err);
|
|
276
|
+
throw err;
|
|
325
277
|
}
|
|
326
278
|
});
|
|
327
279
|
}
|
|
@@ -355,24 +307,6 @@ class GoogleSheetsIntegration {
|
|
|
355
307
|
}
|
|
356
308
|
});
|
|
357
309
|
}
|
|
358
|
-
createBulk(query) {
|
|
359
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
360
|
-
try {
|
|
361
|
-
yield this.connect();
|
|
362
|
-
const sheet = this.client.sheetsByTitle[query.sheet];
|
|
363
|
-
let rowsToInsert = [];
|
|
364
|
-
for (let row of query.rows) {
|
|
365
|
-
rowsToInsert.push(typeof row === "string" ? JSON.parse(row) : row);
|
|
366
|
-
}
|
|
367
|
-
const rows = yield sheet.addRows(rowsToInsert);
|
|
368
|
-
return rows.map(row => this.buildRowObject(sheet.headerValues, row._rawData, row._rowNumber));
|
|
369
|
-
}
|
|
370
|
-
catch (err) {
|
|
371
|
-
console.error("Error bulk writing to google sheets", err);
|
|
372
|
-
throw err;
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
}
|
|
376
310
|
read(query) {
|
|
377
311
|
return __awaiter(this, void 0, void 0, function* () {
|
|
378
312
|
try {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.finaliseExternalTables = exports.
|
|
3
|
+
exports.finaliseExternalTables = exports.isIsoDateString = exports.isSQL = exports.getSqlQuery = exports.convertSqlType = exports.breakRowIdField = exports.convertRowId = exports.isRowId = exports.generateRowIdField = exports.breakExternalTableId = exports.buildExternalTableId = exports.isExternalTable = exports.SqlClient = void 0;
|
|
4
4
|
const types_1 = require("@budibase/types");
|
|
5
5
|
const utils_1 = require("../db/utils");
|
|
6
6
|
const constants_1 = require("../constants");
|
|
7
7
|
const DOUBLE_SEPARATOR = `${utils_1.SEPARATOR}${utils_1.SEPARATOR}`;
|
|
8
8
|
const ROW_ID_REGEX = /^\[.*]$/g;
|
|
9
|
-
const ENCODED_SPACE = encodeURIComponent(" ");
|
|
10
9
|
const SQL_NUMBER_TYPE_MAP = {
|
|
11
10
|
integer: constants_1.FieldTypes.NUMBER,
|
|
12
11
|
int: constants_1.FieldTypes.NUMBER,
|
|
@@ -68,10 +67,6 @@ function isExternalTable(tableId) {
|
|
|
68
67
|
}
|
|
69
68
|
exports.isExternalTable = isExternalTable;
|
|
70
69
|
function buildExternalTableId(datasourceId, tableName) {
|
|
71
|
-
// encode spaces
|
|
72
|
-
if (tableName.includes(" ")) {
|
|
73
|
-
tableName = encodeURIComponent(tableName);
|
|
74
|
-
}
|
|
75
70
|
return `${datasourceId}${DOUBLE_SEPARATOR}${tableName}`;
|
|
76
71
|
}
|
|
77
72
|
exports.buildExternalTableId = buildExternalTableId;
|
|
@@ -83,10 +78,6 @@ function breakExternalTableId(tableId) {
|
|
|
83
78
|
let datasourceId = parts.shift();
|
|
84
79
|
// if they need joined
|
|
85
80
|
let tableName = parts.join(DOUBLE_SEPARATOR);
|
|
86
|
-
// if contains encoded spaces, decode it
|
|
87
|
-
if (tableName.includes(ENCODED_SPACE)) {
|
|
88
|
-
tableName = decodeURIComponent(tableName);
|
|
89
|
-
}
|
|
90
81
|
return { datasourceId, tableName };
|
|
91
82
|
}
|
|
92
83
|
exports.breakExternalTableId = breakExternalTableId;
|
|
@@ -202,7 +193,6 @@ function shouldCopyRelationship(column, tableIds) {
|
|
|
202
193
|
column.tableId &&
|
|
203
194
|
tableIds.includes(column.tableId));
|
|
204
195
|
}
|
|
205
|
-
exports.shouldCopyRelationship = shouldCopyRelationship;
|
|
206
196
|
/**
|
|
207
197
|
* Similar function to the shouldCopyRelationship function, but instead this looks for options and boolean
|
|
208
198
|
* types. It is possible to switch a string -> options and a number -> boolean (and vice versus) need to make
|
|
@@ -227,7 +217,6 @@ function shouldCopySpecialColumn(column, fetchedColumn) {
|
|
|
227
217
|
return (specialTypes.indexOf(column.type) !== -1 ||
|
|
228
218
|
(fetchedIsNumber && column.type === constants_1.FieldTypes.BOOLEAN));
|
|
229
219
|
}
|
|
230
|
-
exports.shouldCopySpecialColumn = shouldCopySpecialColumn;
|
|
231
220
|
/**
|
|
232
221
|
* Looks for columns which need to be copied over into the new table definitions, like relationships
|
|
233
222
|
* and options types.
|
|
@@ -237,14 +226,10 @@ exports.shouldCopySpecialColumn = shouldCopySpecialColumn;
|
|
|
237
226
|
* @param tableIds The IDs of the tables which exist now, to check if anything has been removed.
|
|
238
227
|
*/
|
|
239
228
|
function copyExistingPropsOver(tableName, table, entities, tableIds) {
|
|
240
|
-
var _a, _b, _c;
|
|
241
229
|
if (entities && entities[tableName]) {
|
|
242
|
-
if (
|
|
230
|
+
if (entities[tableName].primaryDisplay) {
|
|
243
231
|
table.primaryDisplay = entities[tableName].primaryDisplay;
|
|
244
232
|
}
|
|
245
|
-
if ((_b = entities[tableName]) === null || _b === void 0 ? void 0 : _b.created) {
|
|
246
|
-
table.created = (_c = entities[tableName]) === null || _c === void 0 ? void 0 : _c.created;
|
|
247
|
-
}
|
|
248
233
|
const existingTableSchema = entities[tableName].schema;
|
|
249
234
|
for (let key in existingTableSchema) {
|
|
250
235
|
if (!existingTableSchema.hasOwnProperty(key)) {
|
package/dist/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "2.4.
|
|
4
|
+
"version": "2.4.39",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -43,12 +43,12 @@
|
|
|
43
43
|
"license": "GPL-3.0",
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@apidevtools/swagger-parser": "10.0.3",
|
|
46
|
-
"@budibase/backend-core": "^2.4.
|
|
47
|
-
"@budibase/client": "^2.4.
|
|
48
|
-
"@budibase/pro": "2.4.
|
|
49
|
-
"@budibase/shared-core": "^2.4.
|
|
50
|
-
"@budibase/string-templates": "^2.4.
|
|
51
|
-
"@budibase/types": "^2.4.
|
|
46
|
+
"@budibase/backend-core": "^2.4.39",
|
|
47
|
+
"@budibase/client": "^2.4.39",
|
|
48
|
+
"@budibase/pro": "2.4.39",
|
|
49
|
+
"@budibase/shared-core": "^2.4.39",
|
|
50
|
+
"@budibase/string-templates": "^2.4.39",
|
|
51
|
+
"@budibase/types": "^2.4.39",
|
|
52
52
|
"@bull-board/api": "3.7.0",
|
|
53
53
|
"@bull-board/koa": "3.9.4",
|
|
54
54
|
"@elastic/elasticsearch": "7.10.0",
|