@balena/pinejs 17.2.0-build-joshbwlng-tasks-b246a5244eeb1c020c533c54d6fb2f112a0ed972-1 → 17.2.0-build-select-model-04b8e99a84456e8bdb6102de7527f3edad7cf0f5-1
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/.pinejs-cache.json +1 -1
- package/.versionbot/CHANGELOG.yml +20 -5
- package/CHANGELOG.md +7 -2
- package/out/bin/abstract-sql-compiler.js +4 -3
- package/out/bin/abstract-sql-compiler.js.map +1 -1
- package/out/bin/odata-compiler.js +6 -4
- package/out/bin/odata-compiler.js.map +1 -1
- package/out/bin/utils.d.ts +1 -1
- package/out/bin/utils.js +6 -2
- package/out/bin/utils.js.map +1 -1
- package/out/config-loader/env.d.ts +0 -4
- package/out/config-loader/env.js +1 -5
- package/out/config-loader/env.js.map +1 -1
- package/out/data-server/sbvr-server.d.ts +3 -2
- package/out/data-server/sbvr-server.js +347 -384
- package/out/data-server/sbvr-server.js.map +1 -1
- package/out/database-layer/db.d.ts +0 -3
- package/out/database-layer/db.js +0 -17
- package/out/database-layer/db.js.map +1 -1
- package/out/sbvr-api/sbvr-utils.d.ts +0 -1
- package/out/sbvr-api/sbvr-utils.js +1 -3
- package/out/sbvr-api/sbvr-utils.js.map +1 -1
- package/out/server-glue/module.d.ts +0 -1
- package/out/server-glue/module.js +1 -4
- package/out/server-glue/module.js.map +1 -1
- package/package.json +6 -9
- package/src/bin/abstract-sql-compiler.ts +12 -2
- package/src/bin/odata-compiler.ts +25 -5
- package/src/bin/utils.ts +6 -1
- package/src/config-loader/env.ts +1 -6
- package/src/data-server/{sbvr-server.js → sbvr-server.ts} +47 -49
- package/src/database-layer/db.ts +0 -25
- package/src/migrator/migrations.ts +1 -1
- package/src/sbvr-api/dev.ts +1 -1
- package/src/sbvr-api/sbvr-utils.ts +1 -2
- package/src/sbvr-api/user.ts +1 -1
- package/src/server-glue/module.ts +0 -3
- package/out/tasks/common.d.ts +0 -4
- package/out/tasks/common.js +0 -11
- package/out/tasks/common.js.map +0 -1
- package/out/tasks/index.d.ts +0 -7
- package/out/tasks/index.js +0 -160
- package/out/tasks/index.js.map +0 -1
- package/out/tasks/out.d.ts +0 -40
- package/out/tasks/out.js +0 -3
- package/out/tasks/out.js.map +0 -1
- package/out/tasks/tasks.sbvr +0 -55
- package/out/tasks/types.d.ts +0 -40
- package/out/tasks/types.js +0 -3
- package/out/tasks/types.js.map +0 -1
- package/out/tasks/worker.d.ts +0 -32
- package/out/tasks/worker.js +0 -204
- package/out/tasks/worker.js.map +0 -1
- package/src/tasks/common.ts +0 -9
- package/src/tasks/index.ts +0 -176
- package/src/tasks/out.ts +0 -46
- package/src/tasks/tasks.sbvr +0 -55
- package/src/tasks/types.ts +0 -44
- package/src/tasks/worker.ts +0 -282
@@ -1,5 +1,30 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
"use strict";
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
3
|
+
if (k2 === undefined) k2 = k;
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
7
|
+
}
|
8
|
+
Object.defineProperty(o, k2, desc);
|
9
|
+
}) : (function(o, m, k, k2) {
|
10
|
+
if (k2 === undefined) k2 = k;
|
11
|
+
o[k2] = m[k];
|
12
|
+
}));
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
15
|
+
}) : function(o, v) {
|
16
|
+
o["default"] = v;
|
17
|
+
});
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
26
|
+
exports.config = exports.setup = void 0;
|
27
|
+
const permissions = __importStar(require("../sbvr-api/permissions"));
|
3
28
|
const uiModel = `\
|
4
29
|
Vocabulary: ui
|
5
30
|
|
@@ -16,399 +41,337 @@ Fact type: textarea has name
|
|
16
41
|
Necessity: Each name is of exactly 1 textarea
|
17
42
|
Fact type: textarea has text
|
18
43
|
Necessity: Each textarea has exactly 1 text`;
|
19
|
-
|
20
|
-
// Middleware
|
21
44
|
const isServerOnAir = (() => {
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
45
|
+
let resolve;
|
46
|
+
let promise = new Promise(($resolve) => {
|
47
|
+
resolve = $resolve;
|
48
|
+
});
|
49
|
+
return (value) => {
|
50
|
+
if (value != null) {
|
51
|
+
if (resolve != null) {
|
52
|
+
resolve(value);
|
53
|
+
resolve = undefined;
|
54
|
+
}
|
55
|
+
else {
|
56
|
+
promise = Promise.resolve(value);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
return promise;
|
60
|
+
};
|
38
61
|
})();
|
39
|
-
|
40
|
-
/** @type { import('express').Handler } */
|
41
62
|
const serverIsOnAir = async (_req, _res, next) => {
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
63
|
+
const onAir = await isServerOnAir();
|
64
|
+
if (onAir) {
|
65
|
+
next();
|
66
|
+
}
|
67
|
+
else {
|
68
|
+
next('route');
|
69
|
+
}
|
48
70
|
};
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
71
|
+
const setup = async (app, sbvrUtils, db) => {
|
72
|
+
const uiApi = sbvrUtils.api.ui;
|
73
|
+
const devApi = sbvrUtils.api.dev;
|
74
|
+
const setupModels = async (tx) => {
|
75
|
+
try {
|
76
|
+
const uiApiTx = uiApi.clone({
|
77
|
+
passthrough: {
|
78
|
+
tx,
|
79
|
+
req: permissions.root,
|
80
|
+
},
|
81
|
+
});
|
82
|
+
await uiApiTx
|
83
|
+
.get({
|
84
|
+
resource: 'textarea',
|
85
|
+
id: {
|
86
|
+
name: 'model_area',
|
87
|
+
},
|
88
|
+
options: {
|
89
|
+
$select: 'id',
|
90
|
+
},
|
91
|
+
})
|
92
|
+
.then(async (result) => {
|
93
|
+
if (result == null) {
|
94
|
+
return await uiApiTx.post({
|
95
|
+
resource: 'textarea',
|
96
|
+
body: {
|
97
|
+
name: 'model_area',
|
98
|
+
text: ' ',
|
99
|
+
},
|
100
|
+
});
|
101
|
+
}
|
102
|
+
});
|
103
|
+
await devApi
|
104
|
+
.get({
|
105
|
+
resource: 'model',
|
106
|
+
passthrough: {
|
107
|
+
tx,
|
108
|
+
req: permissions.rootRead,
|
109
|
+
},
|
110
|
+
options: {
|
111
|
+
$select: ['is_of__vocabulary', 'model_value'],
|
112
|
+
$filter: {
|
113
|
+
model_type: 'se',
|
114
|
+
is_of__vocabulary: 'data',
|
115
|
+
},
|
116
|
+
},
|
117
|
+
})
|
118
|
+
.then(async (result) => {
|
119
|
+
if (result.length === 0) {
|
120
|
+
throw new Error('No SE data model found');
|
121
|
+
}
|
122
|
+
const instance = result[0];
|
123
|
+
const modelValue = instance.model_value;
|
124
|
+
await sbvrUtils.executeModel(tx, {
|
125
|
+
apiRoot: instance.is_of__vocabulary,
|
126
|
+
modelText: modelValue.value,
|
127
|
+
});
|
128
|
+
});
|
129
|
+
await isServerOnAir(true);
|
130
|
+
}
|
131
|
+
catch {
|
132
|
+
await isServerOnAir(false);
|
133
|
+
}
|
134
|
+
};
|
135
|
+
app.get('/onAir', async (_req, res) => {
|
136
|
+
const onAir = await isServerOnAir();
|
137
|
+
res.json(onAir);
|
138
|
+
});
|
139
|
+
app.post('/update', permissions.checkPermissionsMiddleware('all'), serverIsOnAir, (_req, res) => {
|
140
|
+
res.status(404).end();
|
141
|
+
});
|
142
|
+
app.post('/execute', permissions.checkPermissionsMiddleware('all'), async (_req, res) => {
|
143
|
+
try {
|
144
|
+
await uiApi
|
145
|
+
.get({
|
146
|
+
resource: 'textarea',
|
147
|
+
passthrough: { req: permissions.rootRead },
|
148
|
+
id: {
|
149
|
+
name: 'model_area',
|
150
|
+
},
|
151
|
+
options: {
|
152
|
+
$select: 'text',
|
153
|
+
},
|
154
|
+
})
|
155
|
+
.then(async (result) => {
|
156
|
+
if (result == null) {
|
157
|
+
throw new Error('Could not find the model to execute');
|
158
|
+
}
|
159
|
+
const modelText = result.text;
|
160
|
+
await db.transaction(async (tx) => {
|
161
|
+
await sbvrUtils.executeModel(tx, {
|
162
|
+
apiRoot: 'data',
|
163
|
+
modelText,
|
164
|
+
});
|
165
|
+
await uiApi.patch({
|
166
|
+
resource: 'textarea',
|
167
|
+
passthrough: {
|
168
|
+
tx,
|
169
|
+
req: permissions.root,
|
170
|
+
},
|
171
|
+
id: {
|
172
|
+
name: 'model_area',
|
173
|
+
},
|
174
|
+
body: {
|
175
|
+
is_disabled: true,
|
176
|
+
},
|
177
|
+
});
|
178
|
+
});
|
179
|
+
});
|
180
|
+
await isServerOnAir(true);
|
181
|
+
res.status(200).end();
|
182
|
+
}
|
183
|
+
catch (err) {
|
184
|
+
await isServerOnAir(false);
|
185
|
+
res.status(404).json(err);
|
186
|
+
}
|
187
|
+
});
|
188
|
+
app.post('/validate', permissions.checkPermissionsMiddleware('read'), async (req, res) => {
|
189
|
+
try {
|
190
|
+
const results = await sbvrUtils.runRule('data', req.body.rule);
|
191
|
+
res.json(results);
|
192
|
+
}
|
193
|
+
catch (err) {
|
194
|
+
console.log('Error validating', err);
|
195
|
+
res.status(404).end();
|
196
|
+
}
|
197
|
+
});
|
198
|
+
app.delete('/cleardb', permissions.checkPermissionsMiddleware('delete'), async (_req, res) => {
|
199
|
+
try {
|
200
|
+
await db.transaction(async (tx) => {
|
201
|
+
const result = await tx.tableList();
|
202
|
+
await Promise.all(result.rows.map((table) => tx.dropTable(table.name)));
|
203
|
+
await sbvrUtils.executeStandardModels(tx);
|
204
|
+
console.warn('DEL /cleardb is very destructive and should really be followed by a full restart/reload.');
|
205
|
+
await sbvrUtils.executeModels(tx, exports.config.models);
|
206
|
+
await setupModels(tx);
|
207
|
+
});
|
208
|
+
res.status(200).end();
|
209
|
+
}
|
210
|
+
catch (err) {
|
211
|
+
console.error('Error clearing db', err);
|
212
|
+
res.status(503).end();
|
213
|
+
}
|
214
|
+
});
|
215
|
+
app.put('/importdb', permissions.checkPermissionsMiddleware({
|
216
|
+
and: ['create', 'update', 'delete'],
|
217
|
+
}), async (req, res) => {
|
218
|
+
try {
|
219
|
+
const queries = req.body.split(';');
|
220
|
+
await db.transaction(async (tx) => {
|
221
|
+
for (let query of queries) {
|
222
|
+
query = query.trim();
|
223
|
+
if (query.length > 0) {
|
224
|
+
try {
|
225
|
+
await tx.executeSql(query);
|
226
|
+
}
|
227
|
+
catch (err) {
|
228
|
+
throw [query, err];
|
229
|
+
}
|
230
|
+
}
|
231
|
+
}
|
232
|
+
});
|
233
|
+
res.status(200).end();
|
234
|
+
}
|
235
|
+
catch (err) {
|
236
|
+
console.error('Error importing db', err);
|
237
|
+
res.status(404).end();
|
238
|
+
}
|
239
|
+
});
|
240
|
+
app.get('/exportdb', permissions.checkPermissionsMiddleware('read'), async (_req, res) => {
|
241
|
+
try {
|
242
|
+
let exported = '';
|
243
|
+
await db.transaction(async (tx) => {
|
244
|
+
const tables = await tx.tableList("name NOT LIKE '%_buk'");
|
245
|
+
await Promise.all(tables.rows.map(async (table) => {
|
246
|
+
const tableName = table.name;
|
247
|
+
exported += 'DROP TABLE IF EXISTS "' + tableName + '";\n';
|
248
|
+
exported += table.sql + ';\n';
|
249
|
+
const result = await tx.executeSql('SELECT * FROM "' + tableName + '";');
|
250
|
+
let insQuery = '';
|
251
|
+
for (const currRow of result.rows) {
|
252
|
+
let notFirst = false;
|
253
|
+
insQuery += 'INSERT INTO "' + tableName + '" (';
|
254
|
+
let valQuery = '';
|
255
|
+
for (const propName of Object.keys(currRow)) {
|
256
|
+
if (notFirst) {
|
257
|
+
insQuery += ',';
|
258
|
+
valQuery += ',';
|
259
|
+
}
|
260
|
+
else {
|
261
|
+
notFirst = true;
|
262
|
+
}
|
263
|
+
insQuery += '"' + propName + '"';
|
264
|
+
valQuery += "'" + currRow[propName] + "'";
|
265
|
+
}
|
266
|
+
insQuery += ') values (' + valQuery + ');\n';
|
267
|
+
}
|
268
|
+
exported += insQuery;
|
269
|
+
}));
|
270
|
+
});
|
271
|
+
res.json(exported);
|
272
|
+
}
|
273
|
+
catch (err) {
|
274
|
+
console.error('Error exporting db', err);
|
275
|
+
res.status(503).end();
|
276
|
+
}
|
277
|
+
});
|
278
|
+
app.post('/backupdb', permissions.checkPermissionsMiddleware('all'), serverIsOnAir, async (_req, res) => {
|
279
|
+
try {
|
280
|
+
await db.transaction(async (tx) => {
|
281
|
+
const result = await tx.tableList("name NOT LIKE '%_buk'");
|
282
|
+
await Promise.all(result.rows.map(async (currRow) => {
|
283
|
+
const tableName = currRow.name;
|
284
|
+
await tx.dropTable(tableName + '_buk', true);
|
285
|
+
await tx.executeSql('ALTER TABLE "' +
|
286
|
+
tableName +
|
287
|
+
'" RENAME TO "' +
|
288
|
+
tableName +
|
289
|
+
'_buk";');
|
290
|
+
}));
|
291
|
+
});
|
292
|
+
res.status(200).end();
|
293
|
+
}
|
294
|
+
catch (err) {
|
295
|
+
console.error('Error backing up db', err);
|
296
|
+
res.status(404).end();
|
297
|
+
}
|
298
|
+
});
|
299
|
+
app.post('/restoredb', permissions.checkPermissionsMiddleware('all'), serverIsOnAir, async (_req, res) => {
|
300
|
+
try {
|
301
|
+
await db.transaction(async (tx) => {
|
302
|
+
const result = await tx.tableList("name LIKE '%_buk'");
|
303
|
+
await Promise.all(result.rows.map(async (currRow) => {
|
304
|
+
const tableName = currRow.name;
|
305
|
+
await tx.dropTable(tableName.slice(0, -4), true);
|
306
|
+
await tx.executeSql('ALTER TABLE "' +
|
307
|
+
tableName +
|
308
|
+
'" RENAME TO "' +
|
309
|
+
tableName.slice(0, -4) +
|
310
|
+
'";');
|
311
|
+
}));
|
312
|
+
});
|
313
|
+
res.status(200).end();
|
314
|
+
}
|
315
|
+
catch (err) {
|
316
|
+
console.error('Error restoring db', err);
|
317
|
+
res.status(404).end();
|
318
|
+
}
|
319
|
+
});
|
320
|
+
app.all('/data/*', serverIsOnAir, sbvrUtils.handleODataRequest);
|
321
|
+
app.get('/Auth/*', serverIsOnAir, sbvrUtils.handleODataRequest);
|
322
|
+
app.merge('/ui/*', sbvrUtils.handleODataRequest);
|
323
|
+
app.patch('/ui/*', sbvrUtils.handleODataRequest);
|
324
|
+
app.delete('/', serverIsOnAir, async (_req, res) => {
|
325
|
+
await Promise.all([
|
326
|
+
uiApi.patch({
|
327
|
+
resource: 'textarea',
|
328
|
+
passthrough: { req: permissions.root },
|
329
|
+
id: {
|
330
|
+
name: 'model_area',
|
331
|
+
},
|
332
|
+
body: {
|
333
|
+
text: '',
|
334
|
+
is_disabled: false,
|
335
|
+
},
|
336
|
+
}),
|
337
|
+
sbvrUtils.deleteModel('data'),
|
338
|
+
]);
|
339
|
+
await isServerOnAir(false);
|
340
|
+
res.status(200).end();
|
341
|
+
});
|
342
|
+
await db.transaction(setupModels);
|
343
|
+
};
|
344
|
+
exports.setup = setup;
|
345
|
+
exports.config = {
|
346
|
+
models: [
|
347
|
+
{
|
348
|
+
modelName: 'ui',
|
349
|
+
modelText: uiModel,
|
350
|
+
apiRoot: 'ui',
|
351
|
+
customServerCode: { setup: exports.setup },
|
352
|
+
migrations: {
|
353
|
+
'11.0.0-modified-at': `\
|
60
354
|
ALTER TABLE "textarea"
|
61
355
|
ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;\
|
62
356
|
`,
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
357
|
+
'15.0.0-data-types': async (tx, sbvrUtils) => {
|
358
|
+
switch (sbvrUtils.db.engine) {
|
359
|
+
case 'mysql':
|
360
|
+
await tx.executeSql(`\
|
67
361
|
ALTER TABLE "textarea"
|
68
362
|
MODIFY "is disabled" BOOLEAN NOT NULL;`);
|
69
|
-
|
70
|
-
|
71
|
-
|
363
|
+
break;
|
364
|
+
case 'postgres':
|
365
|
+
await tx.executeSql(`\
|
72
366
|
ALTER TABLE "textarea"
|
73
367
|
ALTER COLUMN "is disabled" DROP DEFAULT,
|
74
368
|
ALTER COLUMN "is disabled" SET DATA TYPE BOOLEAN USING "is disabled"::BOOLEAN,
|
75
369
|
ALTER COLUMN "is disabled" SET DEFAULT FALSE;`);
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
],
|
370
|
+
break;
|
371
|
+
}
|
372
|
+
},
|
373
|
+
},
|
374
|
+
},
|
375
|
+
],
|
83
376
|
};
|
84
|
-
|
85
|
-
/** @type { import('../config-loader/config-loader').SetupFunction } */
|
86
|
-
export async function setup(app, sbvrUtils, db) {
|
87
|
-
const uiApi = sbvrUtils.api.ui;
|
88
|
-
const devApi = sbvrUtils.api.dev;
|
89
|
-
const setupModels = async (
|
90
|
-
/** @type { import('../database-layer/db').Tx } */ tx,
|
91
|
-
) => {
|
92
|
-
try {
|
93
|
-
const uiApiTx = uiApi.clone({
|
94
|
-
passthrough: {
|
95
|
-
tx,
|
96
|
-
req: permissions.root,
|
97
|
-
},
|
98
|
-
});
|
99
|
-
await uiApiTx
|
100
|
-
.get({
|
101
|
-
resource: 'textarea',
|
102
|
-
id: {
|
103
|
-
name: 'model_area',
|
104
|
-
},
|
105
|
-
options: {
|
106
|
-
$select: 'id',
|
107
|
-
},
|
108
|
-
})
|
109
|
-
.then(async (/** @type { { [key: string]: any } } */ result) => {
|
110
|
-
if (result == null) {
|
111
|
-
// Add a model_area entry if it doesn't already exist.
|
112
|
-
return await uiApiTx.post({
|
113
|
-
resource: 'textarea',
|
114
|
-
body: {
|
115
|
-
name: 'model_area',
|
116
|
-
text: ' ',
|
117
|
-
},
|
118
|
-
});
|
119
|
-
}
|
120
|
-
});
|
121
|
-
await devApi
|
122
|
-
.get({
|
123
|
-
resource: 'model',
|
124
|
-
passthrough: {
|
125
|
-
tx,
|
126
|
-
req: permissions.rootRead,
|
127
|
-
},
|
128
|
-
options: {
|
129
|
-
$select: ['is_of__vocabulary', 'model_value'],
|
130
|
-
$filter: {
|
131
|
-
model_type: 'se',
|
132
|
-
is_of__vocabulary: 'data',
|
133
|
-
},
|
134
|
-
},
|
135
|
-
})
|
136
|
-
.then(async (result) => {
|
137
|
-
if (result.length === 0) {
|
138
|
-
throw new Error('No SE data model found');
|
139
|
-
}
|
140
|
-
const instance = result[0];
|
141
|
-
await sbvrUtils.executeModel(tx, {
|
142
|
-
apiRoot: instance.is_of__vocabulary,
|
143
|
-
// prettier-ignore
|
144
|
-
modelText: /** @type { string } */ (instance.model_value.value),
|
145
|
-
});
|
146
|
-
});
|
147
|
-
await isServerOnAir(true);
|
148
|
-
} catch {
|
149
|
-
await isServerOnAir(false);
|
150
|
-
}
|
151
|
-
};
|
152
|
-
|
153
|
-
app.get('/onAir', async (_req, res) => {
|
154
|
-
const onAir = await isServerOnAir();
|
155
|
-
res.json(onAir);
|
156
|
-
});
|
157
|
-
|
158
|
-
app.post(
|
159
|
-
'/update',
|
160
|
-
permissions.checkPermissionsMiddleware('all'),
|
161
|
-
serverIsOnAir,
|
162
|
-
(_req, res) => {
|
163
|
-
res.status(404).end();
|
164
|
-
},
|
165
|
-
);
|
166
|
-
|
167
|
-
app.post(
|
168
|
-
'/execute',
|
169
|
-
permissions.checkPermissionsMiddleware('all'),
|
170
|
-
async (_req, res) => {
|
171
|
-
try {
|
172
|
-
await uiApi
|
173
|
-
.get({
|
174
|
-
resource: 'textarea',
|
175
|
-
passthrough: { req: permissions.rootRead },
|
176
|
-
id: {
|
177
|
-
name: 'model_area',
|
178
|
-
},
|
179
|
-
options: {
|
180
|
-
$select: 'text',
|
181
|
-
},
|
182
|
-
})
|
183
|
-
.then(async (/** @type { { [key: string]: any } } */ result) => {
|
184
|
-
if (result == null) {
|
185
|
-
throw new Error('Could not find the model to execute');
|
186
|
-
}
|
187
|
-
const modelText = result.text;
|
188
|
-
await db.transaction(async (tx) => {
|
189
|
-
await sbvrUtils.executeModel(tx, {
|
190
|
-
apiRoot: 'data',
|
191
|
-
modelText,
|
192
|
-
});
|
193
|
-
await uiApi.patch({
|
194
|
-
resource: 'textarea',
|
195
|
-
passthrough: {
|
196
|
-
tx,
|
197
|
-
req: permissions.root,
|
198
|
-
},
|
199
|
-
id: {
|
200
|
-
name: 'model_area',
|
201
|
-
},
|
202
|
-
body: {
|
203
|
-
is_disabled: true,
|
204
|
-
},
|
205
|
-
});
|
206
|
-
});
|
207
|
-
});
|
208
|
-
await isServerOnAir(true);
|
209
|
-
res.status(200).end();
|
210
|
-
} catch (err) {
|
211
|
-
await isServerOnAir(false);
|
212
|
-
res.status(404).json(err);
|
213
|
-
}
|
214
|
-
},
|
215
|
-
);
|
216
|
-
app.post(
|
217
|
-
'/validate',
|
218
|
-
permissions.checkPermissionsMiddleware('read'),
|
219
|
-
async (req, res) => {
|
220
|
-
try {
|
221
|
-
const results = await sbvrUtils.runRule('data', req.body.rule);
|
222
|
-
res.json(results);
|
223
|
-
} catch (err) {
|
224
|
-
console.log('Error validating', err);
|
225
|
-
res.status(404).end();
|
226
|
-
}
|
227
|
-
},
|
228
|
-
);
|
229
|
-
app.delete(
|
230
|
-
'/cleardb',
|
231
|
-
permissions.checkPermissionsMiddleware('delete'),
|
232
|
-
async (_req, res) => {
|
233
|
-
try {
|
234
|
-
await db.transaction(async (tx) => {
|
235
|
-
const result = await tx.tableList();
|
236
|
-
|
237
|
-
await Promise.all(
|
238
|
-
result.rows.map((table) => tx.dropTable(table.name)),
|
239
|
-
);
|
240
|
-
await sbvrUtils.executeStandardModels(tx);
|
241
|
-
// TODO: HACK: This is usually done by config-loader and should be done there
|
242
|
-
// In general cleardb is very destructive and should really go through a full "reboot" procedure to set everything up again.
|
243
|
-
console.warn(
|
244
|
-
'DEL /cleardb is very destructive and should really be followed by a full restart/reload.',
|
245
|
-
);
|
246
|
-
await sbvrUtils.executeModels(tx, exports.config.models);
|
247
|
-
await setupModels(tx);
|
248
|
-
});
|
249
|
-
res.status(200).end();
|
250
|
-
} catch (/** @type any */ err) {
|
251
|
-
console.error('Error clearing db', err);
|
252
|
-
res.status(503).end();
|
253
|
-
}
|
254
|
-
},
|
255
|
-
);
|
256
|
-
app.put(
|
257
|
-
'/importdb',
|
258
|
-
permissions.checkPermissionsMiddleware({
|
259
|
-
and: ['create', 'update', 'delete'],
|
260
|
-
}),
|
261
|
-
async (req, res) => {
|
262
|
-
try {
|
263
|
-
const queries = req.body.split(';');
|
264
|
-
await db.transaction(async (tx) => {
|
265
|
-
for (let query of queries) {
|
266
|
-
query = query.trim();
|
267
|
-
if (query.length > 0) {
|
268
|
-
try {
|
269
|
-
await tx.executeSql(query);
|
270
|
-
} catch (err) {
|
271
|
-
// TODO: Consider changing this to a custom Error
|
272
|
-
// eslint-disable-next-line no-throw-literal
|
273
|
-
throw [query, err];
|
274
|
-
}
|
275
|
-
}
|
276
|
-
}
|
277
|
-
});
|
278
|
-
res.status(200).end();
|
279
|
-
} catch (/** @type any */ err) {
|
280
|
-
console.error('Error importing db', err);
|
281
|
-
res.status(404).end();
|
282
|
-
}
|
283
|
-
},
|
284
|
-
);
|
285
|
-
app.get(
|
286
|
-
'/exportdb',
|
287
|
-
permissions.checkPermissionsMiddleware('read'),
|
288
|
-
async (_req, res) => {
|
289
|
-
try {
|
290
|
-
let exported = '';
|
291
|
-
await db.transaction(async (tx) => {
|
292
|
-
const tables = await tx.tableList("name NOT LIKE '%_buk'");
|
293
|
-
await Promise.all(
|
294
|
-
tables.rows.map(async (table) => {
|
295
|
-
const tableName = table.name;
|
296
|
-
exported += 'DROP TABLE IF EXISTS "' + tableName + '";\n';
|
297
|
-
exported += table.sql + ';\n';
|
298
|
-
const result = await tx.executeSql(
|
299
|
-
'SELECT * FROM "' + tableName + '";',
|
300
|
-
);
|
301
|
-
let insQuery = '';
|
302
|
-
for (const currRow of result.rows) {
|
303
|
-
let notFirst = false;
|
304
|
-
insQuery += 'INSERT INTO "' + tableName + '" (';
|
305
|
-
let valQuery = '';
|
306
|
-
for (const propName of Object.keys(currRow)) {
|
307
|
-
if (notFirst) {
|
308
|
-
insQuery += ',';
|
309
|
-
valQuery += ',';
|
310
|
-
} else {
|
311
|
-
notFirst = true;
|
312
|
-
}
|
313
|
-
insQuery += '"' + propName + '"';
|
314
|
-
valQuery += "'" + currRow[propName] + "'";
|
315
|
-
}
|
316
|
-
insQuery += ') values (' + valQuery + ');\n';
|
317
|
-
}
|
318
|
-
exported += insQuery;
|
319
|
-
}),
|
320
|
-
);
|
321
|
-
});
|
322
|
-
res.json(exported);
|
323
|
-
} catch (/** @type any */ err) {
|
324
|
-
console.error('Error exporting db', err);
|
325
|
-
res.status(503).end();
|
326
|
-
}
|
327
|
-
},
|
328
|
-
);
|
329
|
-
app.post(
|
330
|
-
'/backupdb',
|
331
|
-
permissions.checkPermissionsMiddleware('all'),
|
332
|
-
serverIsOnAir,
|
333
|
-
async (_req, res) => {
|
334
|
-
try {
|
335
|
-
await db.transaction(async (tx) => {
|
336
|
-
const result = await tx.tableList("name NOT LIKE '%_buk'");
|
337
|
-
await Promise.all(
|
338
|
-
result.rows.map(async (currRow) => {
|
339
|
-
const tableName = currRow.name;
|
340
|
-
await tx.dropTable(tableName + '_buk', true);
|
341
|
-
|
342
|
-
await tx.executeSql(
|
343
|
-
'ALTER TABLE "' +
|
344
|
-
tableName +
|
345
|
-
'" RENAME TO "' +
|
346
|
-
tableName +
|
347
|
-
'_buk";',
|
348
|
-
);
|
349
|
-
}),
|
350
|
-
);
|
351
|
-
});
|
352
|
-
res.status(200).end();
|
353
|
-
} catch (/** @type any */ err) {
|
354
|
-
console.error('Error backing up db', err);
|
355
|
-
res.status(404).end();
|
356
|
-
}
|
357
|
-
},
|
358
|
-
);
|
359
|
-
app.post(
|
360
|
-
'/restoredb',
|
361
|
-
permissions.checkPermissionsMiddleware('all'),
|
362
|
-
serverIsOnAir,
|
363
|
-
async (_req, res) => {
|
364
|
-
try {
|
365
|
-
await db.transaction(async (tx) => {
|
366
|
-
const result = await tx.tableList("name LIKE '%_buk'");
|
367
|
-
await Promise.all(
|
368
|
-
result.rows.map(async (currRow) => {
|
369
|
-
const tableName = currRow.name;
|
370
|
-
await tx.dropTable(tableName.slice(0, -4), true);
|
371
|
-
await tx.executeSql(
|
372
|
-
'ALTER TABLE "' +
|
373
|
-
tableName +
|
374
|
-
'" RENAME TO "' +
|
375
|
-
tableName.slice(0, -4) +
|
376
|
-
'";',
|
377
|
-
);
|
378
|
-
}),
|
379
|
-
);
|
380
|
-
});
|
381
|
-
res.status(200).end();
|
382
|
-
} catch (/** @type any */ err) {
|
383
|
-
console.error('Error restoring db', err);
|
384
|
-
res.status(404).end();
|
385
|
-
}
|
386
|
-
},
|
387
|
-
);
|
388
|
-
|
389
|
-
app.all('/data/*', serverIsOnAir, sbvrUtils.handleODataRequest);
|
390
|
-
app.get('/Auth/*', serverIsOnAir, sbvrUtils.handleODataRequest);
|
391
|
-
app.merge('/ui/*', sbvrUtils.handleODataRequest);
|
392
|
-
app.patch('/ui/*', sbvrUtils.handleODataRequest);
|
393
|
-
|
394
|
-
app.delete('/', serverIsOnAir, async (_req, res) => {
|
395
|
-
await Promise.all([
|
396
|
-
uiApi.patch({
|
397
|
-
resource: 'textarea',
|
398
|
-
passthrough: { req: permissions.root },
|
399
|
-
id: {
|
400
|
-
name: 'model_area',
|
401
|
-
},
|
402
|
-
body: {
|
403
|
-
text: '',
|
404
|
-
is_disabled: false,
|
405
|
-
},
|
406
|
-
}),
|
407
|
-
sbvrUtils.deleteModel('data'),
|
408
|
-
]);
|
409
|
-
await isServerOnAir(false);
|
410
|
-
res.status(200).end();
|
411
|
-
});
|
412
|
-
|
413
|
-
await db.transaction(setupModels);
|
414
|
-
}
|
377
|
+
//# sourceMappingURL=sbvr-server.js.map
|