@budibase/server 2.6.16-alpha.4 → 2.6.16-alpha.5
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.8bf0a95b.js → index.b9eeb2a8.js} +202 -202
- package/builder/index.html +1 -1
- package/dist/api/controllers/datasource.js +70 -39
- package/dist/api/controllers/integration.js +2 -2
- package/dist/api/routes/datasource.js +1 -0
- package/dist/db/dynamoClient.js +1 -1
- package/dist/integrations/airtable.js +28 -2
- package/dist/integrations/arangodb.js +19 -3
- package/dist/integrations/couchdb.js +16 -1
- package/dist/integrations/dynamodb.js +16 -0
- package/dist/integrations/elasticsearch.js +15 -0
- package/dist/integrations/firebase.js +15 -0
- package/dist/integrations/googlesheets.js +16 -0
- package/dist/integrations/index.js +5 -2
- package/dist/integrations/microsoftSqlServer.js +16 -0
- package/dist/integrations/mongodb.js +16 -0
- package/dist/integrations/mysql.js +21 -5
- package/dist/integrations/oracle.js +29 -0
- package/dist/integrations/postgres.js +26 -7
- package/dist/integrations/redis.js +20 -1
- package/dist/integrations/s3.js +23 -4
- package/dist/integrations/snowflake.js +15 -0
- package/dist/migrations/functions/backfill/app/queries.js +1 -2
- package/dist/sdk/app/datasources/datasources.js +10 -3
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +10 -9
- package/src/api/controllers/datasource.ts +88 -49
- package/src/api/controllers/integration.ts +3 -3
- package/src/api/routes/datasource.ts +5 -0
- package/src/db/dynamoClient.ts +1 -1
- package/src/integration-test/postgres.spec.ts +0 -1
- package/src/integrations/airtable.ts +31 -4
- package/src/integrations/arangodb.ts +18 -2
- package/src/integrations/couchdb.ts +18 -4
- package/src/integrations/dynamodb.ts +34 -5
- package/src/integrations/elasticsearch.ts +16 -1
- package/src/integrations/firebase.ts +15 -0
- package/src/integrations/googlesheets.ts +16 -0
- package/src/integrations/index.ts +12 -7
- package/src/integrations/microsoftSqlServer.ts +16 -0
- package/src/integrations/mongodb.ts +16 -0
- package/src/integrations/mysql.ts +27 -16
- package/src/integrations/oracle.ts +28 -6
- package/src/integrations/postgres.ts +21 -3
- package/src/integrations/redis.ts +26 -3
- package/src/integrations/s3.ts +19 -3
- package/src/integrations/snowflake.ts +20 -1
- package/src/migrations/functions/backfill/app/queries.ts +1 -1
- package/src/sdk/app/datasources/datasources.ts +7 -1
package/builder/index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@400;600;700&display=swap"
|
|
10
10
|
rel="stylesheet" />
|
|
11
|
-
<script type="module" crossorigin src="/builder/assets/index.
|
|
11
|
+
<script type="module" crossorigin src="/builder/assets/index.b9eeb2a8.js"></script>
|
|
12
12
|
<link rel="stylesheet" href="/builder/assets/index.07382a47.css">
|
|
13
13
|
</head>
|
|
14
14
|
|
|
@@ -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.query = exports.find = exports.destroy = exports.save = exports.update = exports.buildSchemaFromDb = exports.fetch = void 0;
|
|
15
|
+
exports.query = exports.find = exports.destroy = exports.save = exports.update = exports.buildSchemaFromDb = exports.verify = exports.fetch = void 0;
|
|
16
16
|
const utils_1 = require("../../db/utils");
|
|
17
17
|
const internal_1 = require("./table/internal");
|
|
18
18
|
const constants_1 = require("../../constants");
|
|
@@ -21,6 +21,52 @@ const utils_2 = require("./row/utils");
|
|
|
21
21
|
const utils_3 = require("../../threads/utils");
|
|
22
22
|
const backend_core_1 = require("@budibase/backend-core");
|
|
23
23
|
const sdk_1 = __importDefault(require("../../sdk"));
|
|
24
|
+
function getErrorTables(errors, errorType) {
|
|
25
|
+
return Object.entries(errors)
|
|
26
|
+
.filter(entry => entry[1] === errorType)
|
|
27
|
+
.map(([name]) => name);
|
|
28
|
+
}
|
|
29
|
+
function updateError(error, newError, tables) {
|
|
30
|
+
if (!error) {
|
|
31
|
+
error = "";
|
|
32
|
+
}
|
|
33
|
+
if (error.length > 0) {
|
|
34
|
+
error += "\n";
|
|
35
|
+
}
|
|
36
|
+
error += `${newError} ${tables.join(", ")}`;
|
|
37
|
+
return error;
|
|
38
|
+
}
|
|
39
|
+
function getConnector(datasource) {
|
|
40
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
41
|
+
const Connector = yield (0, integrations_1.getIntegration)(datasource.source);
|
|
42
|
+
// can't enrich if it doesn't have an ID yet
|
|
43
|
+
if (datasource._id) {
|
|
44
|
+
datasource = yield sdk_1.default.datasources.enrich(datasource);
|
|
45
|
+
}
|
|
46
|
+
// Connect to the DB and build the schema
|
|
47
|
+
return new Connector(datasource.config);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function buildSchemaHelper(datasource) {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
const connector = (yield getConnector(datasource));
|
|
53
|
+
yield connector.buildSchema(datasource._id, datasource.entities);
|
|
54
|
+
const errors = connector.schemaErrors;
|
|
55
|
+
let error = null;
|
|
56
|
+
if (errors && Object.keys(errors).length > 0) {
|
|
57
|
+
const noKey = getErrorTables(errors, constants_1.BuildSchemaErrors.NO_KEY);
|
|
58
|
+
const invalidCol = getErrorTables(errors, constants_1.BuildSchemaErrors.INVALID_COLUMN);
|
|
59
|
+
if (noKey.length) {
|
|
60
|
+
error = updateError(error, "No primary key constraint found for the following:", noKey);
|
|
61
|
+
}
|
|
62
|
+
if (invalidCol.length) {
|
|
63
|
+
const invalidCols = Object.values(constants_1.InvalidColumns).join(", ");
|
|
64
|
+
error = updateError(error, `Cannot use columns ${invalidCols} found in following:`, invalidCol);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return { tables: connector.tables, error };
|
|
68
|
+
});
|
|
69
|
+
}
|
|
24
70
|
function fetch(ctx) {
|
|
25
71
|
return __awaiter(this, void 0, void 0, function* () {
|
|
26
72
|
// Get internal tables
|
|
@@ -52,6 +98,29 @@ function fetch(ctx) {
|
|
|
52
98
|
});
|
|
53
99
|
}
|
|
54
100
|
exports.fetch = fetch;
|
|
101
|
+
function verify(ctx) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const { datasource } = ctx.request.body;
|
|
104
|
+
let existingDatasource;
|
|
105
|
+
if (datasource._id) {
|
|
106
|
+
existingDatasource = yield sdk_1.default.datasources.get(datasource._id);
|
|
107
|
+
}
|
|
108
|
+
let enrichedDatasource = datasource;
|
|
109
|
+
if (existingDatasource) {
|
|
110
|
+
enrichedDatasource = sdk_1.default.datasources.mergeConfigs(datasource, existingDatasource);
|
|
111
|
+
}
|
|
112
|
+
const connector = yield getConnector(enrichedDatasource);
|
|
113
|
+
if (!connector.testConnection) {
|
|
114
|
+
ctx.throw(400, "Connection information verification not supported");
|
|
115
|
+
}
|
|
116
|
+
const response = yield connector.testConnection();
|
|
117
|
+
ctx.body = {
|
|
118
|
+
connected: response.connected,
|
|
119
|
+
error: response.error,
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
exports.verify = verify;
|
|
55
124
|
function buildSchemaFromDb(ctx) {
|
|
56
125
|
return __awaiter(this, void 0, void 0, function* () {
|
|
57
126
|
const db = backend_core_1.context.getAppDB();
|
|
@@ -266,41 +335,3 @@ function query(ctx) {
|
|
|
266
335
|
});
|
|
267
336
|
}
|
|
268
337
|
exports.query = query;
|
|
269
|
-
function getErrorTables(errors, errorType) {
|
|
270
|
-
return Object.entries(errors)
|
|
271
|
-
.filter(entry => entry[1] === errorType)
|
|
272
|
-
.map(([name]) => name);
|
|
273
|
-
}
|
|
274
|
-
function updateError(error, newError, tables) {
|
|
275
|
-
if (!error) {
|
|
276
|
-
error = "";
|
|
277
|
-
}
|
|
278
|
-
if (error.length > 0) {
|
|
279
|
-
error += "\n";
|
|
280
|
-
}
|
|
281
|
-
error += `${newError} ${tables.join(", ")}`;
|
|
282
|
-
return error;
|
|
283
|
-
}
|
|
284
|
-
function buildSchemaHelper(datasource) {
|
|
285
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
286
|
-
const Connector = yield (0, integrations_1.getIntegration)(datasource.source);
|
|
287
|
-
datasource = yield sdk_1.default.datasources.enrich(datasource);
|
|
288
|
-
// Connect to the DB and build the schema
|
|
289
|
-
const connector = new Connector(datasource.config);
|
|
290
|
-
yield connector.buildSchema(datasource._id, datasource.entities);
|
|
291
|
-
const errors = connector.schemaErrors;
|
|
292
|
-
let error = null;
|
|
293
|
-
if (errors && Object.keys(errors).length > 0) {
|
|
294
|
-
const noKey = getErrorTables(errors, constants_1.BuildSchemaErrors.NO_KEY);
|
|
295
|
-
const invalidCol = getErrorTables(errors, constants_1.BuildSchemaErrors.INVALID_COLUMN);
|
|
296
|
-
if (noKey.length) {
|
|
297
|
-
error = updateError(error, "No primary key constraint found for the following:", noKey);
|
|
298
|
-
}
|
|
299
|
-
if (invalidCol.length) {
|
|
300
|
-
const invalidCols = Object.values(constants_1.InvalidColumns).join(", ");
|
|
301
|
-
error = updateError(error, `Cannot use columns ${invalidCols} found in following:`, invalidCol);
|
|
302
|
-
}
|
|
303
|
-
}
|
|
304
|
-
return { tables: connector.tables, error };
|
|
305
|
-
});
|
|
306
|
-
}
|
|
@@ -20,9 +20,9 @@ function fetch(ctx) {
|
|
|
20
20
|
exports.fetch = fetch;
|
|
21
21
|
function find(ctx) {
|
|
22
22
|
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
-
const
|
|
23
|
+
const def = yield (0, integrations_1.getDefinition)(ctx.params.type);
|
|
24
|
+
ctx.body = def;
|
|
24
25
|
ctx.status = 200;
|
|
25
|
-
ctx.body = defs[ctx.params.type];
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
exports.find = find;
|
|
@@ -34,6 +34,7 @@ const validators_1 = require("./utils/validators");
|
|
|
34
34
|
const router = new router_1.default();
|
|
35
35
|
router
|
|
36
36
|
.get("/api/datasources", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), datasourceController.fetch)
|
|
37
|
+
.post("/api/datasources/verify", (0, authorized_1.default)(backend_core_1.permissions.BUILDER), datasourceController.verify)
|
|
37
38
|
.get("/api/datasources/:datasourceId", (0, authorized_1.default)(backend_core_1.permissions.PermissionType.TABLE, backend_core_1.permissions.PermissionLevel.READ), datasourceController.find)
|
|
38
39
|
.put("/api/datasources/:datasourceId", (0, authorized_1.default)(backend_core_1.permissions.PermissionType.TABLE, backend_core_1.permissions.PermissionLevel.READ), datasourceController.update)
|
|
39
40
|
.post("/api/datasources/query", (0, authorized_1.default)(backend_core_1.permissions.PermissionType.TABLE, backend_core_1.permissions.PermissionLevel.READ), (0, validators_1.datasourceQueryValidator)(), datasourceController.query)
|
package/dist/db/dynamoClient.js
CHANGED
|
@@ -117,7 +117,7 @@ function init(endpoint) {
|
|
|
117
117
|
docClient = new AWS.DynamoDB.DocumentClient(docClientParams);
|
|
118
118
|
}
|
|
119
119
|
exports.init = init;
|
|
120
|
-
if (!environment_1.default.isProd()) {
|
|
120
|
+
if (!environment_1.default.isProd() && !environment_1.default.isJest()) {
|
|
121
121
|
environment_1.default._set("AWS_ACCESS_KEY_ID", "KEY_ID");
|
|
122
122
|
environment_1.default._set("AWS_SECRET_ACCESS_KEY", "SECRET_KEY");
|
|
123
123
|
init("http://localhost:8333");
|
|
@@ -8,14 +8,18 @@ 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
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
const types_1 = require("@budibase/types");
|
|
13
|
-
const
|
|
16
|
+
const airtable_1 = __importDefault(require("airtable"));
|
|
14
17
|
const SCHEMA = {
|
|
15
18
|
docs: "https://airtable.com/api",
|
|
16
19
|
description: "Airtable is a spreadsheet-database hybrid, with the features of a database but applied to a spreadsheet.",
|
|
17
20
|
friendlyName: "Airtable",
|
|
18
21
|
type: "Spreadsheet",
|
|
22
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
19
23
|
datasource: {
|
|
20
24
|
apiKey: {
|
|
21
25
|
type: types_1.DatasourceFieldType.PASSWORD,
|
|
@@ -79,7 +83,29 @@ const SCHEMA = {
|
|
|
79
83
|
class AirtableIntegration {
|
|
80
84
|
constructor(config) {
|
|
81
85
|
this.config = config;
|
|
82
|
-
this.client = new
|
|
86
|
+
this.client = new airtable_1.default(config).base(config.base);
|
|
87
|
+
}
|
|
88
|
+
testConnection() {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
const mockTable = Date.now().toString();
|
|
91
|
+
try {
|
|
92
|
+
yield this.client.makeRequest({
|
|
93
|
+
path: `/${mockTable}`,
|
|
94
|
+
});
|
|
95
|
+
return { connected: true };
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
if (e.message ===
|
|
99
|
+
`Could not find table ${mockTable} in application ${this.config.base}`) {
|
|
100
|
+
// The request managed to check the application, so the credentials are valid
|
|
101
|
+
return { connected: true };
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
connected: false,
|
|
105
|
+
error: e.message,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
});
|
|
83
109
|
}
|
|
84
110
|
create(query) {
|
|
85
111
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -10,12 +10,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
const types_1 = require("@budibase/types");
|
|
13
|
-
const
|
|
13
|
+
const arangojs_1 = require("arangojs");
|
|
14
14
|
const SCHEMA = {
|
|
15
15
|
docs: "https://github.com/arangodb/arangojs",
|
|
16
16
|
friendlyName: "ArangoDB",
|
|
17
17
|
type: "Non-relational",
|
|
18
18
|
description: "ArangoDB is a scalable open-source multi-model database natively supporting graph, document and search. All supported data models & access patterns can be combined in queries allowing for maximal flexibility. ",
|
|
19
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
19
20
|
datasource: {
|
|
20
21
|
url: {
|
|
21
22
|
type: types_1.DatasourceFieldType.STRING,
|
|
@@ -61,7 +62,22 @@ class ArangoDBIntegration {
|
|
|
61
62
|
},
|
|
62
63
|
};
|
|
63
64
|
this.config = config;
|
|
64
|
-
this.client = new Database(newConfig);
|
|
65
|
+
this.client = new arangojs_1.Database(newConfig);
|
|
66
|
+
}
|
|
67
|
+
testConnection() {
|
|
68
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
const response = {
|
|
70
|
+
connected: false,
|
|
71
|
+
};
|
|
72
|
+
try {
|
|
73
|
+
yield this.client.get();
|
|
74
|
+
response.connected = true;
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
response.error = e.message;
|
|
78
|
+
}
|
|
79
|
+
return response;
|
|
80
|
+
});
|
|
65
81
|
}
|
|
66
82
|
read(query) {
|
|
67
83
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -83,7 +99,7 @@ class ArangoDBIntegration {
|
|
|
83
99
|
return __awaiter(this, void 0, void 0, function* () {
|
|
84
100
|
const clc = this.client.collection(this.config.collection);
|
|
85
101
|
try {
|
|
86
|
-
const result = yield this.client.query(aql `INSERT ${query.json} INTO ${clc} RETURN NEW`);
|
|
102
|
+
const result = yield this.client.query((0, arangojs_1.aql) `INSERT ${query.json} INTO ${clc} RETURN NEW`);
|
|
87
103
|
return result.all();
|
|
88
104
|
}
|
|
89
105
|
catch (err) {
|
|
@@ -16,6 +16,7 @@ const SCHEMA = {
|
|
|
16
16
|
friendlyName: "CouchDB",
|
|
17
17
|
type: "Non-relational",
|
|
18
18
|
description: "Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang.",
|
|
19
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
19
20
|
datasource: {
|
|
20
21
|
url: {
|
|
21
22
|
type: types_1.DatasourceFieldType.STRING,
|
|
@@ -59,9 +60,23 @@ const SCHEMA = {
|
|
|
59
60
|
};
|
|
60
61
|
class CouchDBIntegration {
|
|
61
62
|
constructor(config) {
|
|
62
|
-
this.config = config;
|
|
63
63
|
this.client = backend_core_1.db.DatabaseWithConnection(config.database, config.url);
|
|
64
64
|
}
|
|
65
|
+
testConnection() {
|
|
66
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
67
|
+
const response = {
|
|
68
|
+
connected: false,
|
|
69
|
+
};
|
|
70
|
+
try {
|
|
71
|
+
const result = yield this.query("exists", "validation error", {});
|
|
72
|
+
response.connected = result === true;
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
response.error = e.message;
|
|
76
|
+
}
|
|
77
|
+
return response;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
65
80
|
query(command, errorMsg, query) {
|
|
66
81
|
return __awaiter(this, void 0, void 0, function* () {
|
|
67
82
|
try {
|
|
@@ -20,6 +20,7 @@ const SCHEMA = {
|
|
|
20
20
|
description: "Amazon DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale.",
|
|
21
21
|
friendlyName: "DynamoDB",
|
|
22
22
|
type: "Non-relational",
|
|
23
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
23
24
|
datasource: {
|
|
24
25
|
region: {
|
|
25
26
|
type: types_1.DatasourceFieldType.STRING,
|
|
@@ -135,6 +136,21 @@ class DynamoDBIntegration {
|
|
|
135
136
|
this.config = Object.assign(Object.assign({}, this.config), { currentClockSkew: true, region: config.region || dynamoClient_1.AWS_REGION, endpoint: config.endpoint || undefined });
|
|
136
137
|
this.client = new aws_sdk_1.default.DynamoDB.DocumentClient(this.config);
|
|
137
138
|
}
|
|
139
|
+
testConnection() {
|
|
140
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
141
|
+
const response = {
|
|
142
|
+
connected: false,
|
|
143
|
+
};
|
|
144
|
+
try {
|
|
145
|
+
const scanRes = yield new aws_sdk_1.default.DynamoDB(this.config).listTables().promise();
|
|
146
|
+
response.connected = !!scanRes.$response;
|
|
147
|
+
}
|
|
148
|
+
catch (e) {
|
|
149
|
+
response.error = e.message;
|
|
150
|
+
}
|
|
151
|
+
return response;
|
|
152
|
+
});
|
|
153
|
+
}
|
|
138
154
|
create(query) {
|
|
139
155
|
return __awaiter(this, void 0, void 0, function* () {
|
|
140
156
|
const params = Object.assign({ TableName: query.table }, query.json);
|
|
@@ -16,6 +16,7 @@ const SCHEMA = {
|
|
|
16
16
|
description: "Elasticsearch is a search engine based on the Lucene library. It provides a distributed, multitenant-capable full-text search engine with an HTTP web interface and schema-free JSON documents.",
|
|
17
17
|
friendlyName: "ElasticSearch",
|
|
18
18
|
type: "Non-relational",
|
|
19
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
19
20
|
datasource: {
|
|
20
21
|
url: {
|
|
21
22
|
type: types_1.DatasourceFieldType.STRING,
|
|
@@ -102,6 +103,20 @@ class ElasticSearchIntegration {
|
|
|
102
103
|
}
|
|
103
104
|
this.client = new elasticsearch_1.Client(clientConfig);
|
|
104
105
|
}
|
|
106
|
+
testConnection() {
|
|
107
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
try {
|
|
109
|
+
yield this.client.info();
|
|
110
|
+
return { connected: true };
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
return {
|
|
114
|
+
connected: false,
|
|
115
|
+
error: e.message,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
105
120
|
create(query) {
|
|
106
121
|
return __awaiter(this, void 0, void 0, function* () {
|
|
107
122
|
const { index, json } = query;
|
|
@@ -16,6 +16,7 @@ const SCHEMA = {
|
|
|
16
16
|
friendlyName: "Firestore",
|
|
17
17
|
type: "Non-relational",
|
|
18
18
|
description: "Cloud Firestore is a flexible, scalable database for mobile, web, and server development from Firebase and Google Cloud.",
|
|
19
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
19
20
|
datasource: {
|
|
20
21
|
email: {
|
|
21
22
|
type: types_1.DatasourceFieldType.STRING,
|
|
@@ -93,6 +94,20 @@ class FirebaseIntegration {
|
|
|
93
94
|
},
|
|
94
95
|
});
|
|
95
96
|
}
|
|
97
|
+
testConnection() {
|
|
98
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
+
try {
|
|
100
|
+
yield this.client.listCollections();
|
|
101
|
+
return { connected: true };
|
|
102
|
+
}
|
|
103
|
+
catch (e) {
|
|
104
|
+
return {
|
|
105
|
+
connected: false,
|
|
106
|
+
error: e.message,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
}
|
|
96
111
|
create(query) {
|
|
97
112
|
return __awaiter(this, void 0, void 0, function* () {
|
|
98
113
|
try {
|
|
@@ -40,6 +40,7 @@ const SCHEMA = {
|
|
|
40
40
|
description: "Create and collaborate on online spreadsheets in real-time and from any device. ",
|
|
41
41
|
friendlyName: "Google Sheets",
|
|
42
42
|
type: "Spreadsheet",
|
|
43
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
43
44
|
datasource: {
|
|
44
45
|
spreadsheetId: {
|
|
45
46
|
display: "Google Sheet URL",
|
|
@@ -110,6 +111,21 @@ class GoogleSheetsIntegration {
|
|
|
110
111
|
const spreadsheetId = this.cleanSpreadsheetUrl(this.config.spreadsheetId);
|
|
111
112
|
this.client = new google_spreadsheet_1.GoogleSpreadsheet(spreadsheetId);
|
|
112
113
|
}
|
|
114
|
+
testConnection() {
|
|
115
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
116
|
+
try {
|
|
117
|
+
yield this.connect();
|
|
118
|
+
yield this.client.loadInfo();
|
|
119
|
+
return { connected: true };
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
return {
|
|
123
|
+
connected: false,
|
|
124
|
+
error: e.message,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
113
129
|
getBindingIdentifier() {
|
|
114
130
|
return "";
|
|
115
131
|
}
|
|
@@ -50,6 +50,7 @@ const DEFINITIONS = {
|
|
|
50
50
|
[types_1.SourceName.GOOGLE_SHEETS]: googlesheets_1.default.schema,
|
|
51
51
|
[types_1.SourceName.REDIS]: redis_1.default.schema,
|
|
52
52
|
[types_1.SourceName.SNOWFLAKE]: snowflake_1.default.schema,
|
|
53
|
+
[types_1.SourceName.ORACLE]: undefined,
|
|
53
54
|
};
|
|
54
55
|
const INTEGRATIONS = {
|
|
55
56
|
[types_1.SourceName.POSTGRES]: postgres_1.default.integration,
|
|
@@ -68,6 +69,7 @@ const INTEGRATIONS = {
|
|
|
68
69
|
[types_1.SourceName.REDIS]: redis_1.default.integration,
|
|
69
70
|
[types_1.SourceName.FIRESTORE]: firebase_1.default.integration,
|
|
70
71
|
[types_1.SourceName.SNOWFLAKE]: snowflake_1.default.integration,
|
|
72
|
+
[types_1.SourceName.ORACLE]: undefined,
|
|
71
73
|
};
|
|
72
74
|
// optionally add oracle integration if the oracle binary can be installed
|
|
73
75
|
if (process.arch &&
|
|
@@ -79,8 +81,9 @@ if (process.arch &&
|
|
|
79
81
|
function getDefinition(source) {
|
|
80
82
|
return __awaiter(this, void 0, void 0, function* () {
|
|
81
83
|
// check if its integrated, faster
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
const definition = DEFINITIONS[source];
|
|
85
|
+
if (definition) {
|
|
86
|
+
return definition;
|
|
84
87
|
}
|
|
85
88
|
const allDefinitions = yield getDefinitions();
|
|
86
89
|
return allDefinitions[source];
|
|
@@ -23,6 +23,7 @@ const SCHEMA = {
|
|
|
23
23
|
description: "Microsoft SQL Server is a relational database management system developed by Microsoft. ",
|
|
24
24
|
friendlyName: "MS SQL Server",
|
|
25
25
|
type: "Relational",
|
|
26
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
26
27
|
datasource: {
|
|
27
28
|
user: {
|
|
28
29
|
type: types_1.DatasourceFieldType.STRING,
|
|
@@ -94,6 +95,21 @@ class SqlServerIntegration extends sql_1.default {
|
|
|
94
95
|
this.pool = new sqlServer.ConnectionPool(clientCfg);
|
|
95
96
|
}
|
|
96
97
|
}
|
|
98
|
+
testConnection() {
|
|
99
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
100
|
+
const response = {
|
|
101
|
+
connected: false,
|
|
102
|
+
};
|
|
103
|
+
try {
|
|
104
|
+
yield this.connect();
|
|
105
|
+
response.connected = true;
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
response.error = e.message;
|
|
109
|
+
}
|
|
110
|
+
return response;
|
|
111
|
+
});
|
|
112
|
+
}
|
|
97
113
|
getBindingIdentifier() {
|
|
98
114
|
return `@p${this.index++}`;
|
|
99
115
|
}
|
|
@@ -28,6 +28,7 @@ const getSchema = () => {
|
|
|
28
28
|
friendlyName: "MongoDB",
|
|
29
29
|
type: "Non-relational",
|
|
30
30
|
description: "MongoDB is a general purpose, document-based, distributed database built for modern application developers and for the cloud era.",
|
|
31
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
31
32
|
datasource: {
|
|
32
33
|
connectionString: {
|
|
33
34
|
type: types_1.DatasourceFieldType.STRING,
|
|
@@ -340,6 +341,21 @@ class MongoIntegration {
|
|
|
340
341
|
};
|
|
341
342
|
this.client = new mongodb_1.MongoClient(config.connectionString, options);
|
|
342
343
|
}
|
|
344
|
+
testConnection() {
|
|
345
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
346
|
+
const response = {
|
|
347
|
+
connected: false,
|
|
348
|
+
};
|
|
349
|
+
try {
|
|
350
|
+
yield this.connect();
|
|
351
|
+
response.connected = true;
|
|
352
|
+
}
|
|
353
|
+
catch (e) {
|
|
354
|
+
response.error = e.message;
|
|
355
|
+
}
|
|
356
|
+
return response;
|
|
357
|
+
});
|
|
358
|
+
}
|
|
343
359
|
connect() {
|
|
344
360
|
return __awaiter(this, void 0, void 0, function* () {
|
|
345
361
|
return this.client.connect();
|
|
@@ -17,13 +17,14 @@ const utils_1 = require("./utils");
|
|
|
17
17
|
const dayjs_1 = __importDefault(require("dayjs"));
|
|
18
18
|
const utilities_1 = require("../utilities");
|
|
19
19
|
const sql_1 = __importDefault(require("./base/sql"));
|
|
20
|
-
const
|
|
20
|
+
const promise_1 = __importDefault(require("mysql2/promise"));
|
|
21
21
|
const SCHEMA = {
|
|
22
22
|
docs: "https://github.com/sidorares/node-mysql2",
|
|
23
23
|
plus: true,
|
|
24
24
|
friendlyName: "MySQL",
|
|
25
25
|
type: "Relational",
|
|
26
26
|
description: "MySQL Database Service is a fully managed database service to deploy cloud-native applications. ",
|
|
27
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
27
28
|
datasource: {
|
|
28
29
|
host: {
|
|
29
30
|
type: types_1.DatasourceFieldType.STRING,
|
|
@@ -74,7 +75,6 @@ const SCHEMA = {
|
|
|
74
75
|
},
|
|
75
76
|
},
|
|
76
77
|
};
|
|
77
|
-
const TimezoneAwareDateTypes = ["timestamp"];
|
|
78
78
|
function bindingTypeCoerce(bindings) {
|
|
79
79
|
for (let i = 0; i < bindings.length; i++) {
|
|
80
80
|
const binding = bindings[i];
|
|
@@ -108,7 +108,8 @@ class MySQLIntegration extends sql_1.default {
|
|
|
108
108
|
// make sure this defaults to true
|
|
109
109
|
if (config.rejectUnauthorized != null &&
|
|
110
110
|
!config.rejectUnauthorized &&
|
|
111
|
-
config.ssl
|
|
111
|
+
config.ssl &&
|
|
112
|
+
typeof config.ssl !== "string") {
|
|
112
113
|
config.ssl.rejectUnauthorized = config.rejectUnauthorized;
|
|
113
114
|
}
|
|
114
115
|
// @ts-ignore
|
|
@@ -127,6 +128,21 @@ class MySQLIntegration extends sql_1.default {
|
|
|
127
128
|
return next();
|
|
128
129
|
} });
|
|
129
130
|
}
|
|
131
|
+
testConnection() {
|
|
132
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
133
|
+
const response = {
|
|
134
|
+
connected: false,
|
|
135
|
+
};
|
|
136
|
+
try {
|
|
137
|
+
const [result] = yield this.internalQuery({ sql: "SELECT 1+1 AS checkRes" }, { connect: true });
|
|
138
|
+
response.connected = (result === null || result === void 0 ? void 0 : result.checkRes) == 2;
|
|
139
|
+
}
|
|
140
|
+
catch (e) {
|
|
141
|
+
response.error = e.message;
|
|
142
|
+
}
|
|
143
|
+
return response;
|
|
144
|
+
});
|
|
145
|
+
}
|
|
130
146
|
getBindingIdentifier() {
|
|
131
147
|
return "?";
|
|
132
148
|
}
|
|
@@ -135,7 +151,7 @@ class MySQLIntegration extends sql_1.default {
|
|
|
135
151
|
}
|
|
136
152
|
connect() {
|
|
137
153
|
return __awaiter(this, void 0, void 0, function* () {
|
|
138
|
-
this.client = yield
|
|
154
|
+
this.client = yield promise_1.default.createConnection(this.config);
|
|
139
155
|
});
|
|
140
156
|
}
|
|
141
157
|
disconnect() {
|
|
@@ -161,7 +177,7 @@ class MySQLIntegration extends sql_1.default {
|
|
|
161
177
|
return response[0];
|
|
162
178
|
}
|
|
163
179
|
finally {
|
|
164
|
-
if (opts === null || opts === void 0 ? void 0 : opts.connect) {
|
|
180
|
+
if ((opts === null || opts === void 0 ? void 0 : opts.connect) && this.client) {
|
|
165
181
|
yield this.disconnect();
|
|
166
182
|
}
|
|
167
183
|
}
|
|
@@ -30,6 +30,7 @@ const SCHEMA = {
|
|
|
30
30
|
friendlyName: "Oracle",
|
|
31
31
|
type: "Relational",
|
|
32
32
|
description: "Oracle Database is an object-relational database management system developed by Oracle Corporation",
|
|
33
|
+
features: [types_1.DatasourceFeature.CONNECTION_CHECKING],
|
|
33
34
|
datasource: {
|
|
34
35
|
host: {
|
|
35
36
|
type: types_1.DatasourceFieldType.STRING,
|
|
@@ -271,6 +272,34 @@ class OracleIntegration extends sql_1.default {
|
|
|
271
272
|
this.schemaErrors = final.errors;
|
|
272
273
|
});
|
|
273
274
|
}
|
|
275
|
+
testConnection() {
|
|
276
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
277
|
+
const response = {
|
|
278
|
+
connected: false,
|
|
279
|
+
};
|
|
280
|
+
let connection;
|
|
281
|
+
try {
|
|
282
|
+
connection = yield this.getConnection();
|
|
283
|
+
response.connected = true;
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
response.connected = false;
|
|
287
|
+
response.error = err.message;
|
|
288
|
+
}
|
|
289
|
+
finally {
|
|
290
|
+
if (connection) {
|
|
291
|
+
try {
|
|
292
|
+
yield connection.close();
|
|
293
|
+
}
|
|
294
|
+
catch (err) {
|
|
295
|
+
response.connected = false;
|
|
296
|
+
response.error = err.message;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
return response;
|
|
301
|
+
});
|
|
302
|
+
}
|
|
274
303
|
internalQuery(query) {
|
|
275
304
|
return __awaiter(this, void 0, void 0, function* () {
|
|
276
305
|
let connection;
|