adminforth 1.2.98 → 1.2.100
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/auth.ts +6 -5
- package/dataConnectors/baseConnector.ts +91 -21
- package/dataConnectors/clickhouse.ts +58 -37
- package/dataConnectors/mongo.ts +44 -14
- package/dataConnectors/postgres.ts +53 -36
- package/dataConnectors/sqlite.ts +44 -35
- package/dist/auth.js +6 -6
- package/dist/dataConnectors/baseConnector.js +75 -17
- package/dist/dataConnectors/clickhouse.js +59 -48
- package/dist/dataConnectors/mongo.js +28 -12
- package/dist/dataConnectors/postgres.js +62 -52
- package/dist/dataConnectors/sqlite.js +62 -45
- package/dist/index.js +52 -33
- package/dist/modules/configValidator.js +25 -16
- package/dist/modules/operationalResource.js +88 -0
- package/dist/modules/restApi.js +106 -96
- package/dist/modules/utils.js +16 -0
- package/dist/types/AdminForthConfig.js +37 -0
- package/index.ts +76 -43
- package/modules/configValidator.ts +26 -21
- package/modules/operationalResource.ts +91 -0
- package/modules/restApi.ts +91 -80
- package/modules/utils.ts +20 -0
- package/package.json +3 -2
- package/spa/src/App.vue +12 -9
- package/spa/src/components/Filters.vue +1 -1
- package/spa/src/components/ResourceForm.vue +7 -4
- package/spa/src/components/ResourceListTable.vue +124 -112
- package/spa/src/components/SkeleteLoader.vue +4 -4
- package/spa/src/components/ValueRenderer.vue +1 -1
- package/spa/src/router/index.ts +0 -8
- package/spa/src/spa_types/core.ts +1 -0
- package/spa/src/stores/filters.ts +3 -2
- package/spa/src/views/ListView.vue +16 -25
- package/spa/src/views/LoginView.vue +26 -9
- package/types/AdminForthConfig.ts +140 -38
package/dist/modules/restApi.js
CHANGED
|
@@ -47,67 +47,58 @@ export default class AdminForthRestAPI {
|
|
|
47
47
|
const { username, password } = body;
|
|
48
48
|
let adminUser;
|
|
49
49
|
let toReturn = { ok: true, allowedLogin: true };
|
|
50
|
-
|
|
51
|
-
if (this.adminforth.config.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
};
|
|
93
|
-
const beforeLoginConfirmation = this.adminforth.config.auth.beforeLoginConfirmation;
|
|
94
|
-
if (beforeLoginConfirmation === null || beforeLoginConfirmation === void 0 ? void 0 : beforeLoginConfirmation.length) {
|
|
95
|
-
for (const hook of beforeLoginConfirmation) {
|
|
96
|
-
const resp = yield hook({ adminUser, response });
|
|
97
|
-
if ((_c = resp === null || resp === void 0 ? void 0 : resp.body) === null || _c === void 0 ? void 0 : _c.redirectTo) {
|
|
98
|
-
toReturn = { ok: resp.ok, redirectTo: (_d = resp === null || resp === void 0 ? void 0 : resp.body) === null || _d === void 0 ? void 0 : _d.redirectTo, allowedLogin: (_e = resp === null || resp === void 0 ? void 0 : resp.body) === null || _e === void 0 ? void 0 : _e.allowedLogin };
|
|
99
|
-
break;
|
|
100
|
-
}
|
|
50
|
+
// get resource from db
|
|
51
|
+
if (!this.adminforth.config.auth) {
|
|
52
|
+
throw new Error('No config.auth defined we need it to find user, please follow the docs');
|
|
53
|
+
}
|
|
54
|
+
const userResource = this.adminforth.config.resources.find((res) => res.resourceId === this.adminforth.config.auth.usersResourceId);
|
|
55
|
+
// if there is no passwordHashField, in columns, add it, with backendOnly and showIn: []
|
|
56
|
+
if (!userResource.dataSourceColumns.find((col) => col.name === this.adminforth.config.auth.passwordHashField)) {
|
|
57
|
+
userResource.dataSourceColumns.push({
|
|
58
|
+
name: this.adminforth.config.auth.passwordHashField,
|
|
59
|
+
backendOnly: true,
|
|
60
|
+
showIn: [],
|
|
61
|
+
type: AdminForthDataTypes.STRING,
|
|
62
|
+
});
|
|
63
|
+
console.log('Adding passwordHashField to userResource', userResource);
|
|
64
|
+
}
|
|
65
|
+
const userRecord = (_b = (yield this.adminforth.connectors[userResource.dataSource].getData({
|
|
66
|
+
resource: userResource,
|
|
67
|
+
filters: [
|
|
68
|
+
{ field: this.adminforth.config.auth.usernameField, operator: AdminForthFilterOperators.EQ, value: username },
|
|
69
|
+
],
|
|
70
|
+
limit: 1,
|
|
71
|
+
offset: 0,
|
|
72
|
+
sort: [],
|
|
73
|
+
})).data) === null || _b === void 0 ? void 0 : _b[0];
|
|
74
|
+
if (!userRecord) {
|
|
75
|
+
return { error: 'User not found' };
|
|
76
|
+
}
|
|
77
|
+
const passwordHash = userRecord[this.adminforth.config.auth.passwordHashField];
|
|
78
|
+
const valid = yield AdminForthAuth.verifyPassword(password, passwordHash);
|
|
79
|
+
if (valid) {
|
|
80
|
+
adminUser = {
|
|
81
|
+
dbUser: userRecord,
|
|
82
|
+
pk: userRecord[userResource.columns.find((col) => col.primaryKey).name],
|
|
83
|
+
username,
|
|
84
|
+
};
|
|
85
|
+
const beforeLoginConfirmation = this.adminforth.config.auth.beforeLoginConfirmation;
|
|
86
|
+
if (beforeLoginConfirmation === null || beforeLoginConfirmation === void 0 ? void 0 : beforeLoginConfirmation.length) {
|
|
87
|
+
for (const hook of beforeLoginConfirmation) {
|
|
88
|
+
const resp = yield hook({ adminUser, response });
|
|
89
|
+
if ((_c = resp === null || resp === void 0 ? void 0 : resp.body) === null || _c === void 0 ? void 0 : _c.redirectTo) {
|
|
90
|
+
toReturn = { ok: resp.ok, redirectTo: (_d = resp === null || resp === void 0 ? void 0 : resp.body) === null || _d === void 0 ? void 0 : _d.redirectTo, allowedLogin: (_e = resp === null || resp === void 0 ? void 0 : resp.body) === null || _e === void 0 ? void 0 : _e.allowedLogin };
|
|
91
|
+
break;
|
|
101
92
|
}
|
|
102
93
|
}
|
|
103
|
-
if (toReturn.allowedLogin) {
|
|
104
|
-
this.adminforth.auth.setAuthCookie({ response, username, pk: userRecord[userResource.columns.find((col) => col.primaryKey).name] });
|
|
105
|
-
}
|
|
106
94
|
}
|
|
107
|
-
|
|
108
|
-
|
|
95
|
+
if (toReturn.allowedLogin) {
|
|
96
|
+
this.adminforth.auth.setAuthCookie({ response, username, pk: userRecord[userResource.columns.find((col) => col.primaryKey).name] });
|
|
109
97
|
}
|
|
110
98
|
}
|
|
99
|
+
else {
|
|
100
|
+
return { error: INVALID_MESSAGE };
|
|
101
|
+
}
|
|
111
102
|
return toReturn;
|
|
112
103
|
})
|
|
113
104
|
});
|
|
@@ -138,12 +129,13 @@ export default class AdminForthRestAPI {
|
|
|
138
129
|
throw new Error('No config.auth defined');
|
|
139
130
|
}
|
|
140
131
|
const usernameField = this.adminforth.config.auth.usernameField;
|
|
141
|
-
const resource = this.adminforth.config.resources.find((res) => res.resourceId === this.adminforth.config.auth.
|
|
132
|
+
const resource = this.adminforth.config.resources.find((res) => res.resourceId === this.adminforth.config.auth.usersResourceId);
|
|
142
133
|
const usernameColumn = resource.columns.find((col) => col.name === usernameField);
|
|
143
134
|
return {
|
|
144
135
|
brandName: this.adminforth.config.customization.brandName,
|
|
145
136
|
usernameFieldName: usernameColumn.label,
|
|
146
137
|
loginBackgroundImage: this.adminforth.config.auth.loginBackgroundImage,
|
|
138
|
+
loginBackgroundPosition: this.adminforth.config.auth.loginBackgroundPosition,
|
|
147
139
|
title: (_j = this.adminforth.config.customization) === null || _j === void 0 ? void 0 : _j.title,
|
|
148
140
|
demoCredentials: this.adminforth.config.auth.demoCredentials,
|
|
149
141
|
loginPromptHTML: this.adminforth.config.auth.loginPromptHTML,
|
|
@@ -154,18 +146,12 @@ export default class AdminForthRestAPI {
|
|
|
154
146
|
method: 'GET',
|
|
155
147
|
path: '/get_base_config',
|
|
156
148
|
handler: (_k) => __awaiter(this, [_k], void 0, function* ({ input, adminUser, cookies }) {
|
|
157
|
-
var _l, _m, _o, _p
|
|
149
|
+
var _l, _m, _o, _p;
|
|
158
150
|
let username = '';
|
|
159
151
|
let userFullName = '';
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
}
|
|
164
|
-
else {
|
|
165
|
-
const dbUser = adminUser.dbUser;
|
|
166
|
-
username = dbUser[this.adminforth.config.auth.usernameField];
|
|
167
|
-
userFullName = dbUser[this.adminforth.config.auth.userFullNameField];
|
|
168
|
-
}
|
|
152
|
+
const dbUser = adminUser.dbUser;
|
|
153
|
+
username = dbUser[this.adminforth.config.auth.usernameField];
|
|
154
|
+
userFullName = dbUser[this.adminforth.config.auth.userFullNameField];
|
|
169
155
|
const userData = {
|
|
170
156
|
[this.adminforth.config.auth.usernameField]: username,
|
|
171
157
|
[this.adminforth.config.auth.userFullNameField]: userFullName
|
|
@@ -213,7 +199,7 @@ export default class AdminForthRestAPI {
|
|
|
213
199
|
yield processMenuItem(newMenuItem);
|
|
214
200
|
newMenu.push(newMenuItem);
|
|
215
201
|
}
|
|
216
|
-
const announcementBadge = (
|
|
202
|
+
const announcementBadge = (_m = (_l = this.adminforth.config.customization).announcementBadge) === null || _m === void 0 ? void 0 : _m.call(_l, adminUser);
|
|
217
203
|
return {
|
|
218
204
|
user: userData,
|
|
219
205
|
resources: this.adminforth.config.resources.map((res) => ({
|
|
@@ -223,13 +209,14 @@ export default class AdminForthRestAPI {
|
|
|
223
209
|
menu: newMenu,
|
|
224
210
|
config: {
|
|
225
211
|
brandName: this.adminforth.config.customization.brandName,
|
|
212
|
+
showBrandNameInSidebar: this.adminforth.config.customization.showBrandNameInSidebar,
|
|
226
213
|
brandLogo: this.adminforth.config.customization.brandLogo,
|
|
227
214
|
datesFormat: this.adminforth.config.customization.datesFormat,
|
|
228
215
|
deleteConfirmation: this.adminforth.config.deleteConfirmation,
|
|
229
216
|
auth: this.adminforth.config.auth,
|
|
230
217
|
usernameField: this.adminforth.config.auth.usernameField,
|
|
231
|
-
title: (
|
|
232
|
-
emptyFieldPlaceholder: (
|
|
218
|
+
title: (_o = this.adminforth.config.customization) === null || _o === void 0 ? void 0 : _o.title,
|
|
219
|
+
emptyFieldPlaceholder: (_p = this.adminforth.config.customization) === null || _p === void 0 ? void 0 : _p.emptyFieldPlaceholder,
|
|
233
220
|
announcementBadge,
|
|
234
221
|
},
|
|
235
222
|
adminUser,
|
|
@@ -247,7 +234,7 @@ export default class AdminForthRestAPI {
|
|
|
247
234
|
server.endpoint({
|
|
248
235
|
method: 'POST',
|
|
249
236
|
path: '/get_resource',
|
|
250
|
-
handler: (
|
|
237
|
+
handler: (_q) => __awaiter(this, [_q], void 0, function* ({ body, adminUser }) {
|
|
251
238
|
const { resourceId } = body;
|
|
252
239
|
if (!this.adminforth.statuses.dbDiscover) {
|
|
253
240
|
return { error: 'Database discovery not started' };
|
|
@@ -278,8 +265,8 @@ export default class AdminForthRestAPI {
|
|
|
278
265
|
server.endpoint({
|
|
279
266
|
method: 'POST',
|
|
280
267
|
path: '/get_resource_data',
|
|
281
|
-
handler: (
|
|
282
|
-
var _t, _u, _v
|
|
268
|
+
handler: (_r) => __awaiter(this, [_r], void 0, function* ({ body, adminUser }) {
|
|
269
|
+
var _s, _t, _u, _v;
|
|
283
270
|
const { resourceId, source } = body;
|
|
284
271
|
if (['show', 'list'].includes(source) === false) {
|
|
285
272
|
return { error: 'Invalid source, should be list or show' };
|
|
@@ -299,7 +286,7 @@ export default class AdminForthRestAPI {
|
|
|
299
286
|
if (!allowed) {
|
|
300
287
|
return { error };
|
|
301
288
|
}
|
|
302
|
-
for (const hook of listify((
|
|
289
|
+
for (const hook of listify((_t = (_s = resource.hooks) === null || _s === void 0 ? void 0 : _s[source]) === null || _t === void 0 ? void 0 : _t.beforeDatasourceRequest)) {
|
|
303
290
|
const resp = yield hook({ resource, query: body, adminUser });
|
|
304
291
|
if (!resp || (!resp.ok && !resp.error)) {
|
|
305
292
|
throw new Error(`Hook must return object with {ok: true} or { error: 'Error' } `);
|
|
@@ -332,6 +319,7 @@ export default class AdminForthRestAPI {
|
|
|
332
319
|
offset,
|
|
333
320
|
filters,
|
|
334
321
|
sort,
|
|
322
|
+
getTotals: true,
|
|
335
323
|
});
|
|
336
324
|
// for foreign keys, add references
|
|
337
325
|
yield Promise.all(resource.columns.filter((col) => col.foreignResource).map((col) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -378,7 +366,7 @@ export default class AdminForthRestAPI {
|
|
|
378
366
|
item._label = resource.recordLabel(item);
|
|
379
367
|
});
|
|
380
368
|
// only after adminforth made all post processing, give user ability to edit it
|
|
381
|
-
for (const hook of listify((
|
|
369
|
+
for (const hook of listify((_v = (_u = resource.hooks) === null || _u === void 0 ? void 0 : _u[source]) === null || _v === void 0 ? void 0 : _v.afterDatasourceResponse)) {
|
|
382
370
|
const resp = yield hook({ resource, response: data.data, adminUser });
|
|
383
371
|
if (!resp || (!resp.ok && !resp.error)) {
|
|
384
372
|
throw new Error(`Hook must return object with {ok: true} or { error: 'Error' } `);
|
|
@@ -393,8 +381,8 @@ export default class AdminForthRestAPI {
|
|
|
393
381
|
server.endpoint({
|
|
394
382
|
method: 'POST',
|
|
395
383
|
path: '/get_resource_foreign_data',
|
|
396
|
-
handler: (
|
|
397
|
-
var _y, _z, _0
|
|
384
|
+
handler: (_w) => __awaiter(this, [_w], void 0, function* ({ body, adminUser }) {
|
|
385
|
+
var _x, _y, _z, _0;
|
|
398
386
|
const { resourceId, column } = body;
|
|
399
387
|
if (!this.adminforth.statuses.dbDiscover) {
|
|
400
388
|
return { error: 'Database discovery not started' };
|
|
@@ -415,7 +403,7 @@ export default class AdminForthRestAPI {
|
|
|
415
403
|
}
|
|
416
404
|
const targetResourceId = columnConfig.foreignResource.resourceId;
|
|
417
405
|
const targetResource = this.adminforth.config.resources.find((res) => res.resourceId == targetResourceId);
|
|
418
|
-
for (const hook of listify((
|
|
406
|
+
for (const hook of listify((_y = (_x = columnConfig.foreignResource.hooks) === null || _x === void 0 ? void 0 : _x.dropdownList) === null || _y === void 0 ? void 0 : _y.beforeDatasourceRequest)) {
|
|
419
407
|
const resp = yield hook({ query: body, adminUser, resource: targetResource });
|
|
420
408
|
if (!resp || (!resp.ok && !resp.error)) {
|
|
421
409
|
throw new Error(`Hook must return object with {ok: true} or { error: 'Error' } `);
|
|
@@ -444,7 +432,7 @@ export default class AdminForthRestAPI {
|
|
|
444
432
|
const response = {
|
|
445
433
|
items
|
|
446
434
|
};
|
|
447
|
-
for (const hook of listify((
|
|
435
|
+
for (const hook of listify((_0 = (_z = columnConfig.foreignResource.hooks) === null || _z === void 0 ? void 0 : _z.dropdownList) === null || _0 === void 0 ? void 0 : _0.afterDatasourceResponse)) {
|
|
448
436
|
const resp = yield hook({ response, adminUser, resource: targetResource });
|
|
449
437
|
if (!resp || (!resp.ok && !resp.error)) {
|
|
450
438
|
throw new Error(`Hook must return object with {ok: true} or { error: 'Error' } `);
|
|
@@ -459,7 +447,7 @@ export default class AdminForthRestAPI {
|
|
|
459
447
|
server.endpoint({
|
|
460
448
|
method: 'POST',
|
|
461
449
|
path: '/get_min_max_for_columns',
|
|
462
|
-
handler: (
|
|
450
|
+
handler: (_1) => __awaiter(this, [_1], void 0, function* ({ body }) {
|
|
463
451
|
const { resourceId } = body;
|
|
464
452
|
if (!this.adminforth.statuses.dbDiscover) {
|
|
465
453
|
return { error: 'Database discovery not started' };
|
|
@@ -488,7 +476,7 @@ export default class AdminForthRestAPI {
|
|
|
488
476
|
server.endpoint({
|
|
489
477
|
method: 'POST',
|
|
490
478
|
path: '/create_record',
|
|
491
|
-
handler: (
|
|
479
|
+
handler: (_2) => __awaiter(this, [_2], void 0, function* ({ body, adminUser }) {
|
|
492
480
|
const resource = this.adminforth.config.resources.find((res) => res.resourceId == body['resourceId']);
|
|
493
481
|
if (!resource) {
|
|
494
482
|
return { error: `Resource '${body['resourceId']}' not found` };
|
|
@@ -501,19 +489,20 @@ export default class AdminForthRestAPI {
|
|
|
501
489
|
const { record } = body;
|
|
502
490
|
const response = yield this.adminforth.createResourceRecord({ resource, record, adminUser });
|
|
503
491
|
if (response.error) {
|
|
504
|
-
return { error: response.error };
|
|
492
|
+
return { error: response.error, ok: false };
|
|
505
493
|
}
|
|
506
494
|
const connector = this.adminforth.connectors[resource.dataSource];
|
|
507
495
|
return {
|
|
508
|
-
newRecordId:
|
|
496
|
+
newRecordId: response.createdRecord[connector.getPrimaryKey(resource)],
|
|
497
|
+
ok: true
|
|
509
498
|
};
|
|
510
499
|
})
|
|
511
500
|
});
|
|
512
501
|
server.endpoint({
|
|
513
502
|
method: 'POST',
|
|
514
503
|
path: '/update_record',
|
|
515
|
-
handler: (
|
|
516
|
-
var _5, _6, _7
|
|
504
|
+
handler: (_3) => __awaiter(this, [_3], void 0, function* ({ body, adminUser }) {
|
|
505
|
+
var _4, _5, _6, _7;
|
|
517
506
|
const resource = this.adminforth.config.resources.find((res) => res.resourceId == body['resourceId']);
|
|
518
507
|
if (!resource) {
|
|
519
508
|
return { error: `Resource '${body['resourceId']}' not found` };
|
|
@@ -532,8 +521,13 @@ export default class AdminForthRestAPI {
|
|
|
532
521
|
return { error };
|
|
533
522
|
}
|
|
534
523
|
// execute hook if needed
|
|
535
|
-
for (const hook of listify((
|
|
536
|
-
const resp = yield hook({
|
|
524
|
+
for (const hook of listify((_5 = (_4 = resource.hooks) === null || _4 === void 0 ? void 0 : _4.edit) === null || _5 === void 0 ? void 0 : _5.beforeSave)) {
|
|
525
|
+
const resp = yield hook({
|
|
526
|
+
recordId,
|
|
527
|
+
resource,
|
|
528
|
+
record,
|
|
529
|
+
adminUser
|
|
530
|
+
});
|
|
537
531
|
if (!resp || (!resp.ok && !resp.error)) {
|
|
538
532
|
throw new Error(`Hook beforeSave must return object with {ok: true} or { error: 'Error' } `);
|
|
539
533
|
}
|
|
@@ -559,8 +553,14 @@ export default class AdminForthRestAPI {
|
|
|
559
553
|
yield connector.updateRecord({ resource, recordId, newValues });
|
|
560
554
|
}
|
|
561
555
|
// execute hook if needed
|
|
562
|
-
for (const hook of listify((
|
|
563
|
-
const resp = yield hook({
|
|
556
|
+
for (const hook of listify((_7 = (_6 = resource.hooks) === null || _6 === void 0 ? void 0 : _6.edit) === null || _7 === void 0 ? void 0 : _7.afterSave)) {
|
|
557
|
+
const resp = yield hook({
|
|
558
|
+
resource,
|
|
559
|
+
record,
|
|
560
|
+
adminUser,
|
|
561
|
+
oldRecord,
|
|
562
|
+
recordId,
|
|
563
|
+
});
|
|
564
564
|
if (!resp || (!resp.ok && !resp.error)) {
|
|
565
565
|
throw new Error(`Hook afterSave must return object with {ok: true} or { error: 'Error' } `);
|
|
566
566
|
}
|
|
@@ -576,8 +576,8 @@ export default class AdminForthRestAPI {
|
|
|
576
576
|
server.endpoint({
|
|
577
577
|
method: 'POST',
|
|
578
578
|
path: '/delete_record',
|
|
579
|
-
handler: (
|
|
580
|
-
var _10, _11, _12
|
|
579
|
+
handler: (_8) => __awaiter(this, [_8], void 0, function* ({ body, adminUser }) {
|
|
580
|
+
var _9, _10, _11, _12;
|
|
581
581
|
const resource = this.adminforth.config.resources.find((res) => res.resourceId == body['resourceId']);
|
|
582
582
|
const record = yield this.adminforth.connectors[resource.dataSource].getRecordByPrimaryKey(resource, body['primaryKey']);
|
|
583
583
|
if (!resource) {
|
|
@@ -595,8 +595,13 @@ export default class AdminForthRestAPI {
|
|
|
595
595
|
return { error };
|
|
596
596
|
}
|
|
597
597
|
// execute hook if needed
|
|
598
|
-
for (const hook of listify((
|
|
599
|
-
const resp = yield hook({
|
|
598
|
+
for (const hook of listify((_10 = (_9 = resource.hooks) === null || _9 === void 0 ? void 0 : _9.delete) === null || _10 === void 0 ? void 0 : _10.beforeSave)) {
|
|
599
|
+
const resp = yield hook({
|
|
600
|
+
resource,
|
|
601
|
+
record,
|
|
602
|
+
adminUser,
|
|
603
|
+
recordId: body['primaryKey']
|
|
604
|
+
});
|
|
600
605
|
if (!resp || (!resp.ok && !resp.error)) {
|
|
601
606
|
throw new Error(`Hook beforeSave must return object with {ok: true} or { error: 'Error' } `);
|
|
602
607
|
}
|
|
@@ -607,8 +612,13 @@ export default class AdminForthRestAPI {
|
|
|
607
612
|
const connector = this.adminforth.connectors[resource.dataSource];
|
|
608
613
|
yield connector.deleteRecord({ resource, recordId: body['primaryKey'] });
|
|
609
614
|
// execute hook if needed
|
|
610
|
-
for (const hook of listify((
|
|
611
|
-
const resp = yield hook({
|
|
615
|
+
for (const hook of listify((_12 = (_11 = resource.hooks) === null || _11 === void 0 ? void 0 : _11.delete) === null || _12 === void 0 ? void 0 : _12.afterSave)) {
|
|
616
|
+
const resp = yield hook({
|
|
617
|
+
resource,
|
|
618
|
+
record,
|
|
619
|
+
adminUser,
|
|
620
|
+
recordId: body['primaryKey']
|
|
621
|
+
});
|
|
612
622
|
if (!resp || (!resp.ok && !resp.error)) {
|
|
613
623
|
throw new Error(`Hook afterSave must return object with {ok: true} or { error: 'Error' } `);
|
|
614
624
|
}
|
|
@@ -624,7 +634,7 @@ export default class AdminForthRestAPI {
|
|
|
624
634
|
server.endpoint({
|
|
625
635
|
method: 'POST',
|
|
626
636
|
path: '/start_bulk_action',
|
|
627
|
-
handler: (
|
|
637
|
+
handler: (_13) => __awaiter(this, [_13], void 0, function* ({ body, adminUser }) {
|
|
628
638
|
const { resourceId, actionId, recordIds } = body;
|
|
629
639
|
const resource = this.adminforth.config.resources.find((res) => res.resourceId == resourceId);
|
|
630
640
|
if (!resource) {
|
package/dist/modules/utils.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { fileURLToPath } from 'url';
|
|
3
3
|
import fs from 'fs';
|
|
4
|
+
import Fuse from 'fuse.js';
|
|
4
5
|
// @ts-ignore-next-line
|
|
5
6
|
const csscolors = {
|
|
6
7
|
"aliceblue": "#f0f8ff",
|
|
@@ -307,3 +308,18 @@ export function inverseRGBA(rgba) {
|
|
|
307
308
|
let brightness = (r * 299 + g * 587 + b * 114) / 1000;
|
|
308
309
|
return brightness > 128 ? 'rgba(0,0,0,1)' : 'rgba(255,255,255,1)';
|
|
309
310
|
}
|
|
311
|
+
export function suggestIfTypo(names, name) {
|
|
312
|
+
if (!name) {
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
const options = {
|
|
316
|
+
includeScore: true, // Includes score in the results to see how close matches are
|
|
317
|
+
threshold: 0.3, // Defines the fuzziness (lower values mean stricter matches)
|
|
318
|
+
};
|
|
319
|
+
const fuse = new Fuse(names.filter((n) => !!n), options);
|
|
320
|
+
// Search for a resource
|
|
321
|
+
const result = fuse.search(name);
|
|
322
|
+
if (result.length > 0) {
|
|
323
|
+
return result[0].item;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
@@ -53,6 +53,43 @@ export var AdminForthResourcePages;
|
|
|
53
53
|
AdminForthResourcePages["create"] = "create";
|
|
54
54
|
AdminForthResourcePages["filter"] = "filter";
|
|
55
55
|
})(AdminForthResourcePages || (AdminForthResourcePages = {}));
|
|
56
|
+
export class Filters {
|
|
57
|
+
static EQ(field, value) {
|
|
58
|
+
return { field, operator: AdminForthFilterOperators.EQ, value };
|
|
59
|
+
}
|
|
60
|
+
static NEQ(field, value) {
|
|
61
|
+
return { field, operator: AdminForthFilterOperators.NE, value };
|
|
62
|
+
}
|
|
63
|
+
static GT(field, value) {
|
|
64
|
+
return { field, operator: AdminForthFilterOperators.GT, value };
|
|
65
|
+
}
|
|
66
|
+
static GTE(field, value) {
|
|
67
|
+
return { field, operator: AdminForthFilterOperators.GTE, value };
|
|
68
|
+
}
|
|
69
|
+
static LT(field, value) {
|
|
70
|
+
return { field, operator: AdminForthFilterOperators.LT, value };
|
|
71
|
+
}
|
|
72
|
+
static LTE(field, value) {
|
|
73
|
+
return { field, operator: AdminForthFilterOperators.LTE, value };
|
|
74
|
+
}
|
|
75
|
+
static IN(field, value) {
|
|
76
|
+
return { field, operator: AdminForthFilterOperators.IN, value };
|
|
77
|
+
}
|
|
78
|
+
static NOT_IN(field, value) {
|
|
79
|
+
return { field, operator: AdminForthFilterOperators.NIN, value };
|
|
80
|
+
}
|
|
81
|
+
static LIKE(field, value) {
|
|
82
|
+
return { field, operator: AdminForthFilterOperators.LIKE, value };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export class Sorts {
|
|
86
|
+
static ASC(field) {
|
|
87
|
+
return { field, direction: AdminForthSortDirections.asc };
|
|
88
|
+
}
|
|
89
|
+
static DESC(field) {
|
|
90
|
+
return { field, direction: AdminForthSortDirections.desc };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
56
93
|
export var AllowedActionsEnum;
|
|
57
94
|
(function (AllowedActionsEnum) {
|
|
58
95
|
AllowedActionsEnum["show"] = "show";
|