dbgate-api 4.4.2 → 4.5.0

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/.env-portal CHANGED
@@ -1,6 +1,6 @@
1
1
  DEVMODE=1
2
2
 
3
- CONNECTIONS=mysql,postgres
3
+ CONNECTIONS=mysql,postgres,mongo,mongo2
4
4
 
5
5
  LABEL_mysql=MySql localhost
6
6
  SERVER_mysql=localhost
@@ -15,3 +15,13 @@ USER_postgres=postgres
15
15
  PASSWORD_postgres=test
16
16
  PORT_postgres=5433
17
17
  ENGINE_postgres=postgres@dbgate-plugin-postgres
18
+
19
+ LABEL_mongo=Mongo URL
20
+ URL_mongo=mongodb://localhost:27017
21
+ ENGINE_mongo=mongo@dbgate-plugin-mongo
22
+
23
+ LABEL_mongo2=Mongo Server
24
+ SERVER_mongo2=localhost
25
+ ENGINE_mongo2=mongo@dbgate-plugin-mongo
26
+
27
+ # docker run -p 3000:3000 -e CONNECTIONS=mongo -e URL_mongo=mongodb://localhost:27017 -e ENGINE_mongo=mongo@dbgate-plugin-mongo -e LABEL_mongo=mongo dbgate/dbgate:beta
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dbgate-api",
3
3
  "main": "src/index.js",
4
- "version": "4.4.2",
4
+ "version": "4.5.0",
5
5
  "homepage": "https://dbgate.org/",
6
6
  "repository": {
7
7
  "type": "git",
@@ -19,16 +19,15 @@
19
19
  "dependencies": {
20
20
  "async-lock": "^1.2.4",
21
21
  "axios": "^0.21.1",
22
- "better-sqlite3-with-prebuilds": "^7.1.8",
23
22
  "body-parser": "^1.19.0",
24
23
  "bufferutil": "^4.0.1",
25
24
  "byline": "^5.0.0",
26
25
  "compare-versions": "^3.6.0",
27
26
  "cors": "^2.8.5",
28
27
  "cross-env": "^6.0.3",
29
- "dbgate-query-splitter": "^4.4.2",
30
- "dbgate-sqltree": "^4.4.2",
31
- "dbgate-tools": "^4.4.2",
28
+ "dbgate-query-splitter": "^4.5.0",
29
+ "dbgate-sqltree": "^4.5.0",
30
+ "dbgate-tools": "^4.5.0",
32
31
  "diff": "^5.0.0",
33
32
  "diff2html": "^3.4.13",
34
33
  "eslint": "^6.8.0",
@@ -39,6 +38,7 @@
39
38
  "fs-reverse": "^0.0.3",
40
39
  "get-port": "^5.1.1",
41
40
  "http": "^0.0.0",
41
+ "is-electron": "^2.2.1",
42
42
  "js-yaml": "^4.1.0",
43
43
  "json-stable-stringify": "^1.0.1",
44
44
  "line-reader": "^0.4.0",
@@ -49,7 +49,6 @@
49
49
  "node-ssh-forward": "^0.7.2",
50
50
  "portfinder": "^1.0.28",
51
51
  "simple-encryptor": "^4.0.0",
52
- "socket.io": "^2.3.0",
53
52
  "tar": "^6.0.5",
54
53
  "uuid": "^3.4.0"
55
54
  },
@@ -65,7 +64,7 @@
65
64
  "devDependencies": {
66
65
  "@types/fs-extra": "^9.0.11",
67
66
  "@types/lodash": "^4.14.149",
68
- "dbgate-types": "^4.4.2",
67
+ "dbgate-types": "^4.5.0",
69
68
  "env-cmd": "^10.1.0",
70
69
  "node-loader": "^1.0.2",
71
70
  "nodemon": "^2.0.2",
@@ -74,6 +73,7 @@
74
73
  "webpack-cli": "^3.3.11"
75
74
  },
76
75
  "optionalDependencies": {
77
- "msnodesqlv8": "^2.4.0"
76
+ "better-sqlite3": "7.4.5",
77
+ "msnodesqlv8": "^2.4.4"
78
78
  }
79
79
  }
@@ -10,7 +10,7 @@ const { saveFreeTableData } = require('../utility/freeTableStorage');
10
10
  const loadFilesRecursive = require('../utility/loadFilesRecursive');
11
11
 
12
12
  module.exports = {
13
- folders_meta: 'get',
13
+ folders_meta: true,
14
14
  async folders() {
15
15
  const folders = await fs.readdir(archivedir());
16
16
  return [
@@ -27,14 +27,14 @@ module.exports = {
27
27
  ];
28
28
  },
29
29
 
30
- createFolder_meta: 'post',
30
+ createFolder_meta: true,
31
31
  async createFolder({ folder }) {
32
32
  await fs.mkdir(path.join(archivedir(), folder));
33
33
  socket.emitChanged('archive-folders-changed');
34
34
  return true;
35
35
  },
36
36
 
37
- createLink_meta: 'post',
37
+ createLink_meta: true,
38
38
  async createLink({ linkedFolder }) {
39
39
  const folder = await this.getNewArchiveFolder({ database: path.parse(linkedFolder).name + '.link' });
40
40
  fs.writeFile(path.join(archivedir(), folder), linkedFolder);
@@ -43,7 +43,7 @@ module.exports = {
43
43
  return folder;
44
44
  },
45
45
 
46
- files_meta: 'get',
46
+ files_meta: true,
47
47
  async files({ folder }) {
48
48
  const dir = resolveArchiveFolder(folder);
49
49
  if (!(await fs.exists(dir))) return [];
@@ -70,23 +70,23 @@ module.exports = {
70
70
  ];
71
71
  },
72
72
 
73
- refreshFiles_meta: 'post',
73
+ refreshFiles_meta: true,
74
74
  async refreshFiles({ folder }) {
75
75
  socket.emitChanged(`archive-files-changed-${folder}`);
76
76
  },
77
77
 
78
- refreshFolders_meta: 'post',
78
+ refreshFolders_meta: true,
79
79
  async refreshFolders() {
80
80
  socket.emitChanged(`archive-folders-changed`);
81
81
  },
82
82
 
83
- deleteFile_meta: 'post',
83
+ deleteFile_meta: true,
84
84
  async deleteFile({ folder, file, fileType }) {
85
85
  await fs.unlink(path.join(resolveArchiveFolder(folder), `${file}.${fileType}`));
86
86
  socket.emitChanged(`archive-files-changed-${folder}`);
87
87
  },
88
88
 
89
- renameFile_meta: 'post',
89
+ renameFile_meta: true,
90
90
  async renameFile({ folder, file, newFile, fileType }) {
91
91
  await fs.rename(
92
92
  path.join(resolveArchiveFolder(folder), `${file}.${fileType}`),
@@ -95,14 +95,14 @@ module.exports = {
95
95
  socket.emitChanged(`archive-files-changed-${folder}`);
96
96
  },
97
97
 
98
- renameFolder_meta: 'post',
98
+ renameFolder_meta: true,
99
99
  async renameFolder({ folder, newFolder }) {
100
100
  const uniqueName = await this.getNewArchiveFolder({ database: newFolder });
101
101
  await fs.rename(path.join(archivedir(), folder), path.join(archivedir(), uniqueName));
102
102
  socket.emitChanged(`archive-folders-changed`);
103
103
  },
104
104
 
105
- deleteFolder_meta: 'post',
105
+ deleteFolder_meta: true,
106
106
  async deleteFolder({ folder }) {
107
107
  if (!folder) throw new Error('Missing folder parameter');
108
108
  if (folder.endsWith('.link')) {
@@ -113,13 +113,14 @@ module.exports = {
113
113
  socket.emitChanged(`archive-folders-changed`);
114
114
  },
115
115
 
116
- saveFreeTable_meta: 'post',
116
+ saveFreeTable_meta: true,
117
117
  async saveFreeTable({ folder, file, data }) {
118
- saveFreeTableData(path.join(resolveArchiveFolder(folder), `${file}.jsonl`), data);
118
+ await saveFreeTableData(path.join(resolveArchiveFolder(folder), `${file}.jsonl`), data);
119
+ socket.emitChanged(`archive-files-changed-${folder}`);
119
120
  return true;
120
121
  },
121
122
 
122
- loadFreeTable_meta: 'post',
123
+ loadFreeTable_meta: true,
123
124
  async loadFreeTable({ folder, file }) {
124
125
  return new Promise((resolve, reject) => {
125
126
  const fileStream = fs.createReadStream(path.join(resolveArchiveFolder(folder), `${file}.jsonl`));
@@ -1,5 +1,6 @@
1
1
  const fs = require('fs-extra');
2
2
  const path = require('path');
3
+ const axios = require('axios');
3
4
  const { datadir } = require('../utility/directories');
4
5
  const hasPermission = require('../utility/hasPermission');
5
6
  const socket = require('../utility/socket');
@@ -20,7 +21,7 @@ module.exports = {
20
21
  }
21
22
  },
22
23
 
23
- get_meta: 'get',
24
+ get_meta: true,
24
25
  async get() {
25
26
  const permissions = process.env.PERMISSIONS ? process.env.PERMISSIONS.split(',') : null;
26
27
 
@@ -32,17 +33,17 @@ module.exports = {
32
33
  };
33
34
  },
34
35
 
35
- platformInfo_meta: 'get',
36
+ platformInfo_meta: true,
36
37
  async platformInfo() {
37
38
  return platformInfo;
38
39
  },
39
40
 
40
- getSettings_meta: 'get',
41
+ getSettings_meta: true,
41
42
  async getSettings() {
42
43
  return this.settingsValue;
43
44
  },
44
45
 
45
- updateSettings_meta: 'post',
46
+ updateSettings_meta: true,
46
47
  async updateSettings(values) {
47
48
  if (!hasPermission(`settings/change`)) return false;
48
49
  try {
@@ -58,4 +59,10 @@ module.exports = {
58
59
  return false;
59
60
  }
60
61
  },
62
+
63
+ changelog_meta: true,
64
+ async changelog() {
65
+ const resp = await axios.default.get('https://raw.githubusercontent.com/dbgate/dbgate/master/CHANGELOG.md');
66
+ return resp.data;
67
+ },
61
68
  };
@@ -8,6 +8,9 @@ const { datadir, filesdir } = require('../utility/directories');
8
8
  const socket = require('../utility/socket');
9
9
  const { encryptConnection } = require('../utility/crypting');
10
10
  const { handleProcessCommunication } = require('../utility/processComm');
11
+ const { pickSafeConnectionInfo } = require('../utility/crypting');
12
+
13
+ const processArgs = require('../utility/processArgs');
11
14
 
12
15
  function getNamedArgs() {
13
16
  const res = {};
@@ -37,7 +40,7 @@ function getDatabaseFileLabel(databaseFile) {
37
40
 
38
41
  function getPortalCollections() {
39
42
  if (process.env.CONNECTIONS) {
40
- return _.compact(process.env.CONNECTIONS.split(',')).map(id => ({
43
+ const connections = _.compact(process.env.CONNECTIONS.split(',')).map(id => ({
41
44
  _id: id,
42
45
  engine: process.env[`ENGINE_${id}`],
43
46
  server: process.env[`SERVER_${id}`],
@@ -45,11 +48,22 @@ function getPortalCollections() {
45
48
  password: process.env[`PASSWORD_${id}`],
46
49
  port: process.env[`PORT_${id}`],
47
50
  databaseUrl: process.env[`URL_${id}`],
51
+ useDatabaseUrl: !!process.env[`URL_${id}`],
48
52
  databaseFile: process.env[`FILE_${id}`],
49
53
  defaultDatabase: process.env[`DATABASE_${id}`],
50
54
  singleDatabase: !!process.env[`DATABASE_${id}`],
51
55
  displayName: process.env[`LABEL_${id}`],
52
56
  }));
57
+ console.log('Using connections from ENV variables:');
58
+ console.log(JSON.stringify(connections.map(pickSafeConnectionInfo), undefined, 2));
59
+ const noengine = connections.filter(x => !x.engine);
60
+ if (noengine.length > 0) {
61
+ console.log(
62
+ 'Warning: Invalid CONNECTIONS configutation, missing ENGINE for connection ID:',
63
+ noengine.map(x => x._id)
64
+ );
65
+ }
66
+ return connections;
53
67
  }
54
68
 
55
69
  const args = getNamedArgs();
@@ -126,29 +140,34 @@ module.exports = {
126
140
  }
127
141
  },
128
142
 
129
- list_meta: 'get',
143
+ list_meta: true,
130
144
  async list() {
131
145
  return portalConnections || this.datastore.find();
132
146
  },
133
147
 
134
- test_meta: {
135
- method: 'post',
136
- raw: true,
137
- },
138
- test(req, res) {
139
- const subprocess = fork(process.argv[1], ['--start-process', 'connectProcess', ...process.argv.slice(3)]);
140
- subprocess.on('message', resp => {
141
- if (handleProcessCommunication(resp, subprocess)) return;
142
- // @ts-ignore
143
- const { msgtype } = resp;
144
- if (msgtype == 'connected' || msgtype == 'error') {
145
- res.json(resp);
146
- }
148
+ test_meta: true,
149
+ test(connection) {
150
+ const subprocess = fork(global['API_PACKAGE'] || process.argv[1], [
151
+ '--is-forked-api',
152
+ '--start-process',
153
+ 'connectProcess',
154
+ ...processArgs.getPassArgs(),
155
+ // ...process.argv.slice(3),
156
+ ]);
157
+ subprocess.send(connection);
158
+ return new Promise(resolve => {
159
+ subprocess.on('message', resp => {
160
+ if (handleProcessCommunication(resp, subprocess)) return;
161
+ // @ts-ignore
162
+ const { msgtype } = resp;
163
+ if (msgtype == 'connected' || msgtype == 'error') {
164
+ resolve(resp);
165
+ }
166
+ });
147
167
  });
148
- subprocess.send(req.body);
149
168
  },
150
169
 
151
- save_meta: 'post',
170
+ save_meta: true,
152
171
  async save(connection) {
153
172
  if (portalConnections) return;
154
173
  let res;
@@ -162,7 +181,30 @@ module.exports = {
162
181
  return res;
163
182
  },
164
183
 
165
- delete_meta: 'post',
184
+ update_meta: true,
185
+ async update({ _id, values }) {
186
+ if (portalConnections) return;
187
+ const res = await this.datastore.update({ _id }, { $set: values });
188
+ socket.emitChanged('connection-list-changed');
189
+ return res;
190
+ },
191
+
192
+ updateDatabase_meta: true,
193
+ async updateDatabase({ conid, database, values }) {
194
+ if (portalConnections) return;
195
+ const conn = await this.datastore.find({ _id: conid });
196
+ let databases = conn[0].databases || [];
197
+ if (databases.find(x => x.name == database)) {
198
+ databases = databases.map(x => (x.name == database ? { ...x, ...values } : x));
199
+ } else {
200
+ databases = [...databases, { name: database, ...values }];
201
+ }
202
+ const res = await this.datastore.update({ _id: conid }, { $set: { databases } });
203
+ socket.emitChanged('connection-list-changed');
204
+ return res;
205
+ },
206
+
207
+ delete_meta: true,
166
208
  async delete(connection) {
167
209
  if (portalConnections) return;
168
210
  const res = await this.datastore.remove(_.pick(connection, '_id'));
@@ -170,14 +212,14 @@ module.exports = {
170
212
  return res;
171
213
  },
172
214
 
173
- get_meta: 'get',
215
+ get_meta: true,
174
216
  async get({ conid }) {
175
- if (portalConnections) return portalConnections.find(x => x._id == conid);
217
+ if (portalConnections) return portalConnections.find(x => x._id == conid) || null;
176
218
  const res = await this.datastore.find({ _id: conid });
177
- return res[0];
219
+ return res[0] || null;
178
220
  },
179
221
 
180
- newSqliteDatabase_meta: 'post',
222
+ newSqliteDatabase_meta: true,
181
223
  async newSqliteDatabase({ file }) {
182
224
  const sqliteDir = path.join(filesdir(), 'sqlite');
183
225
  if (!(await fs.exists(sqliteDir))) {
@@ -25,6 +25,7 @@ const requireEngineDriver = require('../utility/requireEngineDriver');
25
25
  const generateDeploySql = require('../shell/generateDeploySql');
26
26
  const { createTwoFilesPatch } = require('diff');
27
27
  const diff2htmlPage = require('../utility/diff2htmlPage');
28
+ const processArgs = require('../utility/processArgs');
28
29
 
29
30
  module.exports = {
30
31
  /** @type {import('dbgate-types').OpenedDatabaseConnection[]} */
@@ -74,10 +75,12 @@ module.exports = {
74
75
  const existing = this.opened.find(x => x.conid == conid && x.database == database);
75
76
  if (existing) return existing;
76
77
  const connection = await connections.get({ conid });
77
- const subprocess = fork(process.argv[1], [
78
+ const subprocess = fork(global['API_PACKAGE'] || process.argv[1], [
79
+ '--is-forked-api',
78
80
  '--start-process',
79
81
  'databaseConnectionProcess',
80
- ...process.argv.slice(3),
82
+ ...processArgs.getPassArgs(),
83
+ // ...process.argv.slice(3),
81
84
  ]);
82
85
  const lastClosed = this.closed[`${conid}/${database}`];
83
86
  const newOpened = {
@@ -121,7 +124,7 @@ module.exports = {
121
124
  return promise;
122
125
  },
123
126
 
124
- queryData_meta: 'post',
127
+ queryData_meta: true,
125
128
  async queryData({ conid, database, sql }) {
126
129
  console.log(`Processing query, conid=${conid}, database=${database}, sql=${sql}`);
127
130
  const opened = await this.ensureOpened(conid, database);
@@ -132,7 +135,7 @@ module.exports = {
132
135
  return res;
133
136
  },
134
137
 
135
- runScript_meta: 'post',
138
+ runScript_meta: true,
136
139
  async runScript({ conid, database, sql }) {
137
140
  console.log(`Processing script, conid=${conid}, database=${database}, sql=${sql}`);
138
141
  const opened = await this.ensureOpened(conid, database);
@@ -140,21 +143,21 @@ module.exports = {
140
143
  return res;
141
144
  },
142
145
 
143
- collectionData_meta: 'post',
146
+ collectionData_meta: true,
144
147
  async collectionData({ conid, database, options }) {
145
148
  const opened = await this.ensureOpened(conid, database);
146
149
  const res = await this.sendRequest(opened, { msgtype: 'collectionData', options });
147
150
  return res.result;
148
151
  },
149
152
 
150
- updateCollection_meta: 'post',
153
+ updateCollection_meta: true,
151
154
  async updateCollection({ conid, database, changeSet }) {
152
155
  const opened = await this.ensureOpened(conid, database);
153
156
  const res = await this.sendRequest(opened, { msgtype: 'updateCollection', changeSet });
154
157
  return res.result;
155
158
  },
156
159
 
157
- status_meta: 'get',
160
+ status_meta: true,
158
161
  async status({ conid, database }) {
159
162
  const existing = this.opened.find(x => x.conid == conid && x.database == database);
160
163
  if (existing) {
@@ -176,7 +179,7 @@ module.exports = {
176
179
  };
177
180
  },
178
181
 
179
- ping_meta: 'post',
182
+ ping_meta: true,
180
183
  async ping({ conid, database }) {
181
184
  let existing = this.opened.find(x => x.conid == conid && x.database == database);
182
185
 
@@ -192,7 +195,7 @@ module.exports = {
192
195
  };
193
196
  },
194
197
 
195
- refresh_meta: 'post',
198
+ refresh_meta: true,
196
199
  async refresh({ conid, database, keepOpen }) {
197
200
  if (!keepOpen) this.close(conid, database);
198
201
 
@@ -200,7 +203,7 @@ module.exports = {
200
203
  return { status: 'ok' };
201
204
  },
202
205
 
203
- syncModel_meta: 'post',
206
+ syncModel_meta: true,
204
207
  async syncModel({ conid, database }) {
205
208
  const conn = await this.ensureOpened(conid, database);
206
209
  conn.subprocess.send({ msgtype: 'syncModel' });
@@ -224,13 +227,13 @@ module.exports = {
224
227
  }
225
228
  },
226
229
 
227
- disconnect_meta: 'post',
230
+ disconnect_meta: true,
228
231
  async disconnect({ conid, database }) {
229
232
  await this.close(conid, database, true);
230
233
  return { status: 'ok' };
231
234
  },
232
235
 
233
- structure_meta: 'get',
236
+ structure_meta: true,
234
237
  async structure({ conid, database }) {
235
238
  if (conid == '__model') {
236
239
  const model = await importDbModel(database);
@@ -247,13 +250,14 @@ module.exports = {
247
250
  // };
248
251
  },
249
252
 
250
- serverVersion_meta: 'get',
253
+ serverVersion_meta: true,
251
254
  async serverVersion({ conid, database }) {
255
+ if (!conid) return null;
252
256
  const opened = await this.ensureOpened(conid, database);
253
- return opened.serverVersion;
257
+ return opened.serverVersion || null;
254
258
  },
255
259
 
256
- sqlPreview_meta: 'post',
260
+ sqlPreview_meta: true,
257
261
  async sqlPreview({ conid, database, objects, options }) {
258
262
  // wait for structure
259
263
  await this.structure({ conid, database });
@@ -263,7 +267,7 @@ module.exports = {
263
267
  return res;
264
268
  },
265
269
 
266
- exportModel_meta: 'post',
270
+ exportModel_meta: true,
267
271
  async exportModel({ conid, database }) {
268
272
  const archiveFolder = await archive.getNewArchiveFolder({ database });
269
273
  await fs.mkdir(path.join(archivedir(), archiveFolder));
@@ -273,10 +277,13 @@ module.exports = {
273
277
  return { archiveFolder };
274
278
  },
275
279
 
276
- generateDeploySql_meta: 'post',
280
+ generateDeploySql_meta: true,
277
281
  async generateDeploySql({ conid, database, archiveFolder }) {
278
282
  const opened = await this.ensureOpened(conid, database);
279
- const res = await this.sendRequest(opened, { msgtype: 'generateDeploySql', modelFolder: resolveArchiveFolder(archiveFolder) });
283
+ const res = await this.sendRequest(opened, {
284
+ msgtype: 'generateDeploySql',
285
+ modelFolder: resolveArchiveFolder(archiveFolder),
286
+ });
280
287
  return res;
281
288
 
282
289
  // const connection = await connections.get({ conid });
@@ -285,7 +292,7 @@ module.exports = {
285
292
  // analysedStructure: await this.structure({ conid, database }),
286
293
  // modelFolder: resolveArchiveFolder(archiveFolder),
287
294
  // });
288
-
295
+
289
296
  // const deployedModel = generateDbPairingId(await importDbModel(path.join(archivedir(), archiveFolder)));
290
297
  // const currentModel = generateDbPairingId(await this.structure({ conid, database }));
291
298
  // const currentModelPaired = matchPairedObjects(deployedModel, currentModel);
@@ -300,7 +307,7 @@ module.exports = {
300
307
  // };
301
308
  // return sql;
302
309
  },
303
- // runCommand_meta: 'post',
310
+ // runCommand_meta: true,
304
311
  // async runCommand({ conid, database, sql }) {
305
312
  // console.log(`Running SQL command , conid=${conid}, database=${database}, sql=${sql}`);
306
313
  // const opened = await this.ensureOpened(conid, database);
@@ -343,7 +350,7 @@ module.exports = {
343
350
  return res;
344
351
  },
345
352
 
346
- generateDbDiffReport_meta: 'post',
353
+ generateDbDiffReport_meta: true,
347
354
  async generateDbDiffReport({ filePath, sourceConid, sourceDatabase, targetConid, targetDatabase }) {
348
355
  const unifiedDiff = await this.getUnifiedDiff({ sourceConid, sourceDatabase, targetConid, targetDatabase });
349
356
 
@@ -20,7 +20,7 @@ function deserialize(format, text) {
20
20
  }
21
21
 
22
22
  module.exports = {
23
- list_meta: 'get',
23
+ list_meta: true,
24
24
  async list({ folder }) {
25
25
  if (!hasPermission(`files/${folder}/read`)) return [];
26
26
  const dir = path.join(filesdir(), folder);
@@ -29,7 +29,7 @@ module.exports = {
29
29
  return files;
30
30
  },
31
31
 
32
- listAll_meta: 'get',
32
+ listAll_meta: true,
33
33
  async listAll() {
34
34
  const folders = await fs.readdir(filesdir());
35
35
  const res = [];
@@ -42,7 +42,7 @@ module.exports = {
42
42
  return res;
43
43
  },
44
44
 
45
- delete_meta: 'post',
45
+ delete_meta: true,
46
46
  async delete({ folder, file }) {
47
47
  if (!hasPermission(`files/${folder}/write`)) return;
48
48
  await fs.unlink(path.join(filesdir(), folder, file));
@@ -50,7 +50,7 @@ module.exports = {
50
50
  socket.emitChanged(`all-files-changed`);
51
51
  },
52
52
 
53
- rename_meta: 'post',
53
+ rename_meta: true,
54
54
  async rename({ folder, file, newFile }) {
55
55
  if (!hasPermission(`files/${folder}/write`)) return;
56
56
  await fs.rename(path.join(filesdir(), folder, file), path.join(filesdir(), folder, newFile));
@@ -58,7 +58,7 @@ module.exports = {
58
58
  socket.emitChanged(`all-files-changed`);
59
59
  },
60
60
 
61
- copy_meta: 'post',
61
+ copy_meta: true,
62
62
  async copy({ folder, file, newFile }) {
63
63
  if (!hasPermission(`files/${folder}/write`)) return;
64
64
  await fs.copyFile(path.join(filesdir(), folder, file), path.join(filesdir(), folder, newFile));
@@ -66,7 +66,7 @@ module.exports = {
66
66
  socket.emitChanged(`all-files-changed`);
67
67
  },
68
68
 
69
- load_meta: 'post',
69
+ load_meta: true,
70
70
  async load({ folder, file, format }) {
71
71
  if (folder.startsWith('archive:')) {
72
72
  const text = await fs.readFile(path.join(resolveArchiveFolder(folder.substring('archive:'.length)), file), {
@@ -80,7 +80,7 @@ module.exports = {
80
80
  }
81
81
  },
82
82
 
83
- save_meta: 'post',
83
+ save_meta: true,
84
84
  async save({ folder, file, data, format }) {
85
85
  if (folder.startsWith('archive:')) {
86
86
  const dir = resolveArchiveFolder(folder.substring('archive:'.length));
@@ -101,12 +101,12 @@ module.exports = {
101
101
  }
102
102
  },
103
103
 
104
- saveAs_meta: 'post',
104
+ saveAs_meta: true,
105
105
  async saveAs({ filePath, data, format }) {
106
106
  await fs.writeFile(filePath, serialize(format, data));
107
107
  },
108
108
 
109
- favorites_meta: 'get',
109
+ favorites_meta: true,
110
110
  async favorites() {
111
111
  if (!hasPermission(`files/favorites/read`)) return [];
112
112
  const dir = path.join(filesdir(), 'favorites');
@@ -125,7 +125,7 @@ module.exports = {
125
125
  return res;
126
126
  },
127
127
 
128
- generateUploadsFile_meta: 'get',
128
+ generateUploadsFile_meta: true,
129
129
  async generateUploadsFile() {
130
130
  const fileName = `${uuidv1()}.html`;
131
131
  return {
@@ -134,7 +134,7 @@ module.exports = {
134
134
  };
135
135
  },
136
136
 
137
- exportChart_meta: 'post',
137
+ exportChart_meta: true,
138
138
  async exportChart({ filePath, title, config, image }) {
139
139
  const fileName = path.parse(filePath).base;
140
140
  const imageFile = fileName.replace('.html', '-preview.png');
@@ -104,7 +104,7 @@ module.exports = {
104
104
  return datastore;
105
105
  },
106
106
 
107
- getInfo_meta: 'get',
107
+ getInfo_meta: true,
108
108
  async getInfo({ jslid }) {
109
109
  const file = getJslFileName(jslid);
110
110
  const firstLine = await readFirstLine(file);
@@ -112,13 +112,13 @@ module.exports = {
112
112
  return null;
113
113
  },
114
114
 
115
- getRows_meta: 'post',
115
+ getRows_meta: true,
116
116
  async getRows({ jslid, offset, limit, filters }) {
117
117
  const datastore = await this.ensureDatastore(jslid);
118
118
  return datastore.getRows(offset, limit, _.isEmpty(filters) ? null : filters);
119
119
  },
120
120
 
121
- getStats_meta: 'get',
121
+ getStats_meta: true,
122
122
  getStats({ jslid }) {
123
123
  const file = `${getJslFileName(jslid)}.stats`;
124
124
  if (fs.existsSync(file)) {
@@ -146,7 +146,7 @@ module.exports = {
146
146
  // }
147
147
  },
148
148
 
149
- saveFreeTable_meta: 'post',
149
+ saveFreeTable_meta: true,
150
150
  async saveFreeTable({ jslid, data }) {
151
151
  saveFreeTableData(getJslFileName(jslid), data);
152
152
  return true;