adminforth 1.0.73 → 1.0.75
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/dataConnectors/mongo.ts +5 -6
- package/dataConnectors/postgres.ts +16 -15
- package/dataConnectors/sqlite.ts +17 -12
- package/dist/dataConnectors/mongo.js +5 -5
- package/dist/dataConnectors/postgres.js +15 -15
- package/dist/dataConnectors/sqlite.js +15 -12
- package/dist/index.js +36 -13
- package/dist/modules/codeInjector.js +33 -7
- package/dist/servers/express.js +6 -8
- package/dist/spa/spa/src/main.ts +1 -1
- package/dist/spa/spa/src/utils.ts +11 -0
- package/dist/spa/spa/src/views/LoginView.vue +5 -2
- package/dist/types/AdminForthConfig.js +33 -1
- package/index.ts +40 -17
- package/modules/codeInjector.ts +38 -7
- package/package.json +2 -1
- package/plugins/base.ts +4 -5
- package/servers/express.ts +7 -9
- package/spa/src/main.ts +1 -1
- package/spa/src/utils.ts +11 -0
- package/spa/src/views/LoginView.vue +5 -2
- package/types/AdminForthConfig.ts +53 -14
- package/types.ts +0 -36
package/dataConnectors/mongo.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import dayjs from 'dayjs';
|
|
2
2
|
import { MongoClient } from 'mongodb';
|
|
3
|
-
import { AdminForthFilterOperators, AdminForthSortDirections
|
|
4
|
-
|
|
3
|
+
import { AdminForthDataTypes, AdminForthFilterOperators, AdminForthSortDirections } from '../types/AdminForthConfig.js';
|
|
5
4
|
|
|
6
5
|
class MongoConnector {
|
|
7
6
|
db: MongoClient
|
|
@@ -65,7 +64,7 @@ class MongoConnector {
|
|
|
65
64
|
}
|
|
66
65
|
|
|
67
66
|
getFieldValue(field, value) {
|
|
68
|
-
if (field.type ==
|
|
67
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
69
68
|
if (!value) {
|
|
70
69
|
return null;
|
|
71
70
|
}
|
|
@@ -76,7 +75,7 @@ class MongoConnector {
|
|
|
76
75
|
} else {
|
|
77
76
|
throw new Error(`AdminForth does not support row type: ${field._underlineType} for timestamps, use VARCHAR (with iso strings) or TIMESTAMP/INT (with unix timestamps)`);
|
|
78
77
|
}
|
|
79
|
-
} else if (field.type ==
|
|
78
|
+
} else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
80
79
|
return !!value;
|
|
81
80
|
}
|
|
82
81
|
return value;
|
|
@@ -103,7 +102,7 @@ class MongoConnector {
|
|
|
103
102
|
}
|
|
104
103
|
|
|
105
104
|
setFieldValue(field, value) {
|
|
106
|
-
if (field.type ==
|
|
105
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
107
106
|
if (!value) {
|
|
108
107
|
return null;
|
|
109
108
|
}
|
|
@@ -114,7 +113,7 @@ class MongoConnector {
|
|
|
114
113
|
// value is iso string now, convert to unix timestamp
|
|
115
114
|
return dayjs(value).toISOString();
|
|
116
115
|
}
|
|
117
|
-
} else if (field.type ==
|
|
116
|
+
} else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
118
117
|
return value ? 1 : 0;
|
|
119
118
|
}
|
|
120
119
|
return value;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import dayjs from 'dayjs';
|
|
2
2
|
import pkg from 'pg';
|
|
3
|
-
import { AdminForthFilterOperators, AdminForthSortDirections
|
|
3
|
+
import { AdminForthDataTypes, AdminForthFilterOperators, AdminForthSortDirections } from '../types/AdminForthConfig.js';
|
|
4
|
+
|
|
4
5
|
const { Client } = pkg;
|
|
5
6
|
|
|
6
7
|
|
|
@@ -72,44 +73,44 @@ class PostgresConnector {
|
|
|
72
73
|
const field: any = {};
|
|
73
74
|
const baseType = row.type.toLowerCase();
|
|
74
75
|
if (baseType == 'int') {
|
|
75
|
-
field.type =
|
|
76
|
+
field.type = AdminForthDataTypes.INTEGER;
|
|
76
77
|
field._underlineType = 'int';
|
|
77
78
|
|
|
78
79
|
} else if (baseType.includes('float') || baseType.includes('double')) {
|
|
79
|
-
field.type =
|
|
80
|
+
field.type = AdminForthDataTypes.FLOAT;
|
|
80
81
|
field._underlineType = 'float';
|
|
81
82
|
|
|
82
83
|
} else if (baseType.includes('bool')) {
|
|
83
|
-
field.type =
|
|
84
|
+
field.type = AdminForthDataTypes.BOOLEAN;
|
|
84
85
|
field._underlineType = 'bool';
|
|
85
86
|
|
|
86
87
|
} else if (baseType == 'uuid') {
|
|
87
|
-
field.type =
|
|
88
|
+
field.type = AdminForthDataTypes.STRING;
|
|
88
89
|
field._underlineType = 'uuid';
|
|
89
90
|
|
|
90
91
|
} else if (baseType.includes('character varying')) {
|
|
91
|
-
field.type =
|
|
92
|
+
field.type = AdminForthDataTypes.STRING;
|
|
92
93
|
field._underlineType = 'varchar';
|
|
93
94
|
const length = baseType.match(/\d+/);
|
|
94
95
|
field.maxLength = length ? parseInt(length[0]) : null;
|
|
95
96
|
|
|
96
97
|
} else if (baseType == 'text') {
|
|
97
|
-
field.type =
|
|
98
|
+
field.type = AdminForthDataTypes.TEXT;
|
|
98
99
|
field._underlineType = 'text';
|
|
99
100
|
|
|
100
101
|
} else if (baseType.includes('decimal(')) {
|
|
101
|
-
field.type =
|
|
102
|
+
field.type = AdminForthDataTypes.DECIMAL;
|
|
102
103
|
field._underlineType = 'decimal';
|
|
103
104
|
const [precision, scale] = baseType.match(/\d+/g);
|
|
104
105
|
field.precision = parseInt(precision);
|
|
105
106
|
field.scale = parseInt(scale);
|
|
106
107
|
|
|
107
108
|
} else if (baseType == 'real') {
|
|
108
|
-
field.type =
|
|
109
|
+
field.type = AdminForthDataTypes.FLOAT;
|
|
109
110
|
field._underlineType = 'real';
|
|
110
111
|
|
|
111
112
|
} else if (baseType.includes('date') || baseType.includes('time')) {
|
|
112
|
-
field.type =
|
|
113
|
+
field.type = AdminForthDataTypes.DATETIME;
|
|
113
114
|
field._underlineType = 'timestamp';
|
|
114
115
|
|
|
115
116
|
} else {
|
|
@@ -125,7 +126,7 @@ class PostgresConnector {
|
|
|
125
126
|
}
|
|
126
127
|
|
|
127
128
|
getFieldValue(field, value) {
|
|
128
|
-
if (field.type ==
|
|
129
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
129
130
|
if (!value) {
|
|
130
131
|
return null;
|
|
131
132
|
}
|
|
@@ -165,7 +166,7 @@ class PostgresConnector {
|
|
|
165
166
|
}
|
|
166
167
|
|
|
167
168
|
setFieldValue(field, value) {
|
|
168
|
-
if (field.type ==
|
|
169
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
169
170
|
if (!value) {
|
|
170
171
|
return null;
|
|
171
172
|
}
|
|
@@ -174,14 +175,14 @@ class PostgresConnector {
|
|
|
174
175
|
} else if (field._underlineType == 'varchar') {
|
|
175
176
|
return dayjs(value).toISOString();
|
|
176
177
|
}
|
|
177
|
-
} else if (field.type ==
|
|
178
|
+
} else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
178
179
|
return value ? 1 : 0;
|
|
179
180
|
}
|
|
180
181
|
return value;
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
async getData({ resource, limit, offset, sort, filters }) {
|
|
184
|
-
const columns = resource.dataSourceColumns.
|
|
185
|
+
const columns = resource.dataSourceColumns.map((col) => `"${col.name}"`).join(', ');
|
|
185
186
|
const tableName = resource.table;
|
|
186
187
|
|
|
187
188
|
let totalCounter = 1;
|
|
@@ -229,7 +230,7 @@ class PostgresConnector {
|
|
|
229
230
|
const orderBy = sort.length ? `ORDER BY ${sort.map((s) => `${s.field} ${this.SortDirectionsMap[s.direction]}`).join(', ')}` : '';
|
|
230
231
|
const selectQuery = `SELECT ${columns} FROM ${tableName} ${where} ${orderBy} ${limitOffset}`;
|
|
231
232
|
if (process.env.HEAVY_DEBUG) {
|
|
232
|
-
console.log('
|
|
233
|
+
console.log('🪲 PG selectQuery:', selectQuery, 'params:', d);
|
|
233
234
|
}
|
|
234
235
|
const stmt = await this.db.query(selectQuery, d);
|
|
235
236
|
const rows = stmt.rows;
|
package/dataConnectors/sqlite.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import betterSqlite3 from 'better-sqlite3';
|
|
2
|
-
import {
|
|
2
|
+
import { AdminForthDataTypes, AdminForthFilterOperators, AdminForthSortDirections } from '../types/AdminForthConfig.js';
|
|
3
|
+
|
|
3
4
|
import dayjs from 'dayjs';
|
|
4
5
|
|
|
5
6
|
class SQLiteConnector {
|
|
@@ -21,30 +22,30 @@ class SQLiteConnector {
|
|
|
21
22
|
const field: any = {};
|
|
22
23
|
const baseType = row.type.toLowerCase();
|
|
23
24
|
if (baseType == 'int') {
|
|
24
|
-
field.type =
|
|
25
|
+
field.type = AdminForthDataTypes.INTEGER;
|
|
25
26
|
field._underlineType = 'int';
|
|
26
27
|
} else if (baseType.includes('varchar(')) {
|
|
27
|
-
field.type =
|
|
28
|
+
field.type = AdminForthDataTypes.STRING;
|
|
28
29
|
field._underlineType = 'varchar';
|
|
29
30
|
const length = baseType.match(/\d+/);
|
|
30
31
|
field.maxLength = length ? parseInt(length[0]) : null;
|
|
31
32
|
} else if (baseType == 'text') {
|
|
32
|
-
field.type =
|
|
33
|
+
field.type = AdminForthDataTypes.TEXT;
|
|
33
34
|
field._underlineType = 'text';
|
|
34
35
|
} else if (baseType.includes('decimal(')) {
|
|
35
|
-
field.type =
|
|
36
|
+
field.type = AdminForthDataTypes.DECIMAL;
|
|
36
37
|
field._underlineType = 'decimal';
|
|
37
38
|
const [precision, scale] = baseType.match(/\d+/g);
|
|
38
39
|
field.precision = parseInt(precision);
|
|
39
40
|
field.scale = parseInt(scale);
|
|
40
41
|
} else if (baseType == 'real') {
|
|
41
|
-
field.type =
|
|
42
|
+
field.type = AdminForthDataTypes.FLOAT; //8-byte IEEE floating point number. It
|
|
42
43
|
field._underlineType = 'real';
|
|
43
44
|
} else if (baseType == 'timestamp') {
|
|
44
|
-
field.type =
|
|
45
|
+
field.type = AdminForthDataTypes.DATETIME;
|
|
45
46
|
field._underlineType = 'timestamp';
|
|
46
47
|
} else if (baseType == 'boolean') {
|
|
47
|
-
field.type =
|
|
48
|
+
field.type = AdminForthDataTypes.BOOLEAN;
|
|
48
49
|
field._underlineType = 'boolean';
|
|
49
50
|
} else {
|
|
50
51
|
field.type = 'unknown'
|
|
@@ -67,7 +68,7 @@ class SQLiteConnector {
|
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
getFieldValue(field, value) {
|
|
70
|
-
if (field.type ==
|
|
71
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
71
72
|
if (!value) {
|
|
72
73
|
return null;
|
|
73
74
|
}
|
|
@@ -78,7 +79,7 @@ class SQLiteConnector {
|
|
|
78
79
|
} else {
|
|
79
80
|
throw new Error(`AdminForth does not support row type: ${field._underlineType} for timestamps, use VARCHAR (with iso strings) or TIMESTAMP/INT (with unix timestamps). Issue in field "${field.name}"`);
|
|
80
81
|
}
|
|
81
|
-
} else if (field.type ==
|
|
82
|
+
} else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
82
83
|
return !!value;
|
|
83
84
|
}
|
|
84
85
|
return value;
|
|
@@ -100,7 +101,7 @@ class SQLiteConnector {
|
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
setFieldValue(field, value) {
|
|
103
|
-
if (field.type ==
|
|
104
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
104
105
|
if (!value) {
|
|
105
106
|
return null;
|
|
106
107
|
}
|
|
@@ -111,7 +112,7 @@ class SQLiteConnector {
|
|
|
111
112
|
// value is iso string now, convert to unix timestamp
|
|
112
113
|
return dayjs(value).toISOString();
|
|
113
114
|
}
|
|
114
|
-
} else if (field.type ==
|
|
115
|
+
} else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
115
116
|
return value ? 1 : 0;
|
|
116
117
|
}
|
|
117
118
|
|
|
@@ -183,6 +184,10 @@ class SQLiteConnector {
|
|
|
183
184
|
const q = `SELECT ${columns} FROM ${tableName} ${where} ${orderBy} LIMIT ? OFFSET ?`;
|
|
184
185
|
const stmt = this.db.prepare(q);
|
|
185
186
|
const d = [...filterValues, limit, offset];
|
|
187
|
+
|
|
188
|
+
if (process.env.HEAVY_DEBUG) {
|
|
189
|
+
console.log('🪲 SQLITE Query', q, 'params:', d);
|
|
190
|
+
}
|
|
186
191
|
const rows = stmt.all(d);
|
|
187
192
|
|
|
188
193
|
const total = this.db.prepare(`SELECT COUNT(*) FROM ${tableName} ${where}`).get([...filterValues])['COUNT(*)'];
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import dayjs from 'dayjs';
|
|
11
11
|
import { MongoClient } from 'mongodb';
|
|
12
|
-
import { AdminForthFilterOperators, AdminForthSortDirections
|
|
12
|
+
import { AdminForthDataTypes, AdminForthFilterOperators, AdminForthSortDirections } from '../types/AdminForthConfig.js';
|
|
13
13
|
class MongoConnector {
|
|
14
14
|
constructor({ url }) {
|
|
15
15
|
this.OperatorsMap = {
|
|
@@ -67,7 +67,7 @@ class MongoConnector {
|
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
69
|
getFieldValue(field, value) {
|
|
70
|
-
if (field.type ==
|
|
70
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
71
71
|
if (!value) {
|
|
72
72
|
return null;
|
|
73
73
|
}
|
|
@@ -81,7 +81,7 @@ class MongoConnector {
|
|
|
81
81
|
throw new Error(`AdminForth does not support row type: ${field._underlineType} for timestamps, use VARCHAR (with iso strings) or TIMESTAMP/INT (with unix timestamps)`);
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
else if (field.type ==
|
|
84
|
+
else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
85
85
|
return !!value;
|
|
86
86
|
}
|
|
87
87
|
return value;
|
|
@@ -108,7 +108,7 @@ class MongoConnector {
|
|
|
108
108
|
});
|
|
109
109
|
}
|
|
110
110
|
setFieldValue(field, value) {
|
|
111
|
-
if (field.type ==
|
|
111
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
112
112
|
if (!value) {
|
|
113
113
|
return null;
|
|
114
114
|
}
|
|
@@ -121,7 +121,7 @@ class MongoConnector {
|
|
|
121
121
|
return dayjs(value).toISOString();
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
|
-
else if (field.type ==
|
|
124
|
+
else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
125
125
|
return value ? 1 : 0;
|
|
126
126
|
}
|
|
127
127
|
return value;
|
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
};
|
|
10
10
|
import dayjs from 'dayjs';
|
|
11
11
|
import pkg from 'pg';
|
|
12
|
-
import { AdminForthFilterOperators, AdminForthSortDirections
|
|
12
|
+
import { AdminForthDataTypes, AdminForthFilterOperators, AdminForthSortDirections } from '../types/AdminForthConfig.js';
|
|
13
13
|
const { Client } = pkg;
|
|
14
14
|
class PostgresConnector {
|
|
15
15
|
constructor({ url }) {
|
|
@@ -73,44 +73,44 @@ class PostgresConnector {
|
|
|
73
73
|
const field = {};
|
|
74
74
|
const baseType = row.type.toLowerCase();
|
|
75
75
|
if (baseType == 'int') {
|
|
76
|
-
field.type =
|
|
76
|
+
field.type = AdminForthDataTypes.INTEGER;
|
|
77
77
|
field._underlineType = 'int';
|
|
78
78
|
}
|
|
79
79
|
else if (baseType.includes('float') || baseType.includes('double')) {
|
|
80
|
-
field.type =
|
|
80
|
+
field.type = AdminForthDataTypes.FLOAT;
|
|
81
81
|
field._underlineType = 'float';
|
|
82
82
|
}
|
|
83
83
|
else if (baseType.includes('bool')) {
|
|
84
|
-
field.type =
|
|
84
|
+
field.type = AdminForthDataTypes.BOOLEAN;
|
|
85
85
|
field._underlineType = 'bool';
|
|
86
86
|
}
|
|
87
87
|
else if (baseType == 'uuid') {
|
|
88
|
-
field.type =
|
|
88
|
+
field.type = AdminForthDataTypes.STRING;
|
|
89
89
|
field._underlineType = 'uuid';
|
|
90
90
|
}
|
|
91
91
|
else if (baseType.includes('character varying')) {
|
|
92
|
-
field.type =
|
|
92
|
+
field.type = AdminForthDataTypes.STRING;
|
|
93
93
|
field._underlineType = 'varchar';
|
|
94
94
|
const length = baseType.match(/\d+/);
|
|
95
95
|
field.maxLength = length ? parseInt(length[0]) : null;
|
|
96
96
|
}
|
|
97
97
|
else if (baseType == 'text') {
|
|
98
|
-
field.type =
|
|
98
|
+
field.type = AdminForthDataTypes.TEXT;
|
|
99
99
|
field._underlineType = 'text';
|
|
100
100
|
}
|
|
101
101
|
else if (baseType.includes('decimal(')) {
|
|
102
|
-
field.type =
|
|
102
|
+
field.type = AdminForthDataTypes.DECIMAL;
|
|
103
103
|
field._underlineType = 'decimal';
|
|
104
104
|
const [precision, scale] = baseType.match(/\d+/g);
|
|
105
105
|
field.precision = parseInt(precision);
|
|
106
106
|
field.scale = parseInt(scale);
|
|
107
107
|
}
|
|
108
108
|
else if (baseType == 'real') {
|
|
109
|
-
field.type =
|
|
109
|
+
field.type = AdminForthDataTypes.FLOAT;
|
|
110
110
|
field._underlineType = 'real';
|
|
111
111
|
}
|
|
112
112
|
else if (baseType.includes('date') || baseType.includes('time')) {
|
|
113
|
-
field.type =
|
|
113
|
+
field.type = AdminForthDataTypes.DATETIME;
|
|
114
114
|
field._underlineType = 'timestamp';
|
|
115
115
|
}
|
|
116
116
|
else {
|
|
@@ -126,7 +126,7 @@ class PostgresConnector {
|
|
|
126
126
|
});
|
|
127
127
|
}
|
|
128
128
|
getFieldValue(field, value) {
|
|
129
|
-
if (field.type ==
|
|
129
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
130
130
|
if (!value) {
|
|
131
131
|
return null;
|
|
132
132
|
}
|
|
@@ -166,7 +166,7 @@ class PostgresConnector {
|
|
|
166
166
|
});
|
|
167
167
|
}
|
|
168
168
|
setFieldValue(field, value) {
|
|
169
|
-
if (field.type ==
|
|
169
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
170
170
|
if (!value) {
|
|
171
171
|
return null;
|
|
172
172
|
}
|
|
@@ -177,14 +177,14 @@ class PostgresConnector {
|
|
|
177
177
|
return dayjs(value).toISOString();
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
-
else if (field.type ==
|
|
180
|
+
else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
181
181
|
return value ? 1 : 0;
|
|
182
182
|
}
|
|
183
183
|
return value;
|
|
184
184
|
}
|
|
185
185
|
getData(_a) {
|
|
186
186
|
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters }) {
|
|
187
|
-
const columns = resource.dataSourceColumns.
|
|
187
|
+
const columns = resource.dataSourceColumns.map((col) => `"${col.name}"`).join(', ');
|
|
188
188
|
const tableName = resource.table;
|
|
189
189
|
let totalCounter = 1;
|
|
190
190
|
const where = filters.length ? `WHERE ${filters.map((f, i) => {
|
|
@@ -232,7 +232,7 @@ class PostgresConnector {
|
|
|
232
232
|
const orderBy = sort.length ? `ORDER BY ${sort.map((s) => `${s.field} ${this.SortDirectionsMap[s.direction]}`).join(', ')}` : '';
|
|
233
233
|
const selectQuery = `SELECT ${columns} FROM ${tableName} ${where} ${orderBy} ${limitOffset}`;
|
|
234
234
|
if (process.env.HEAVY_DEBUG) {
|
|
235
|
-
console.log('
|
|
235
|
+
console.log('🪲 PG selectQuery:', selectQuery, 'params:', d);
|
|
236
236
|
}
|
|
237
237
|
const stmt = yield this.db.query(selectQuery, d);
|
|
238
238
|
const rows = stmt.rows;
|
|
@@ -8,7 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
10
|
import betterSqlite3 from 'better-sqlite3';
|
|
11
|
-
import {
|
|
11
|
+
import { AdminForthDataTypes, AdminForthFilterOperators, AdminForthSortDirections } from '../types/AdminForthConfig.js';
|
|
12
12
|
import dayjs from 'dayjs';
|
|
13
13
|
class SQLiteConnector {
|
|
14
14
|
constructor({ url }) {
|
|
@@ -41,36 +41,36 @@ class SQLiteConnector {
|
|
|
41
41
|
const field = {};
|
|
42
42
|
const baseType = row.type.toLowerCase();
|
|
43
43
|
if (baseType == 'int') {
|
|
44
|
-
field.type =
|
|
44
|
+
field.type = AdminForthDataTypes.INTEGER;
|
|
45
45
|
field._underlineType = 'int';
|
|
46
46
|
}
|
|
47
47
|
else if (baseType.includes('varchar(')) {
|
|
48
|
-
field.type =
|
|
48
|
+
field.type = AdminForthDataTypes.STRING;
|
|
49
49
|
field._underlineType = 'varchar';
|
|
50
50
|
const length = baseType.match(/\d+/);
|
|
51
51
|
field.maxLength = length ? parseInt(length[0]) : null;
|
|
52
52
|
}
|
|
53
53
|
else if (baseType == 'text') {
|
|
54
|
-
field.type =
|
|
54
|
+
field.type = AdminForthDataTypes.TEXT;
|
|
55
55
|
field._underlineType = 'text';
|
|
56
56
|
}
|
|
57
57
|
else if (baseType.includes('decimal(')) {
|
|
58
|
-
field.type =
|
|
58
|
+
field.type = AdminForthDataTypes.DECIMAL;
|
|
59
59
|
field._underlineType = 'decimal';
|
|
60
60
|
const [precision, scale] = baseType.match(/\d+/g);
|
|
61
61
|
field.precision = parseInt(precision);
|
|
62
62
|
field.scale = parseInt(scale);
|
|
63
63
|
}
|
|
64
64
|
else if (baseType == 'real') {
|
|
65
|
-
field.type =
|
|
65
|
+
field.type = AdminForthDataTypes.FLOAT; //8-byte IEEE floating point number. It
|
|
66
66
|
field._underlineType = 'real';
|
|
67
67
|
}
|
|
68
68
|
else if (baseType == 'timestamp') {
|
|
69
|
-
field.type =
|
|
69
|
+
field.type = AdminForthDataTypes.DATETIME;
|
|
70
70
|
field._underlineType = 'timestamp';
|
|
71
71
|
}
|
|
72
72
|
else if (baseType == 'boolean') {
|
|
73
|
-
field.type =
|
|
73
|
+
field.type = AdminForthDataTypes.BOOLEAN;
|
|
74
74
|
field._underlineType = 'boolean';
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
@@ -93,7 +93,7 @@ class SQLiteConnector {
|
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
getFieldValue(field, value) {
|
|
96
|
-
if (field.type ==
|
|
96
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
97
97
|
if (!value) {
|
|
98
98
|
return null;
|
|
99
99
|
}
|
|
@@ -107,7 +107,7 @@ class SQLiteConnector {
|
|
|
107
107
|
throw new Error(`AdminForth does not support row type: ${field._underlineType} for timestamps, use VARCHAR (with iso strings) or TIMESTAMP/INT (with unix timestamps). Issue in field "${field.name}"`);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
|
-
else if (field.type ==
|
|
110
|
+
else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
111
111
|
return !!value;
|
|
112
112
|
}
|
|
113
113
|
return value;
|
|
@@ -129,7 +129,7 @@ class SQLiteConnector {
|
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
setFieldValue(field, value) {
|
|
132
|
-
if (field.type ==
|
|
132
|
+
if (field.type == AdminForthDataTypes.DATETIME) {
|
|
133
133
|
if (!value) {
|
|
134
134
|
return null;
|
|
135
135
|
}
|
|
@@ -142,7 +142,7 @@ class SQLiteConnector {
|
|
|
142
142
|
return dayjs(value).toISOString();
|
|
143
143
|
}
|
|
144
144
|
}
|
|
145
|
-
else if (field.type ==
|
|
145
|
+
else if (field.type == AdminForthDataTypes.BOOLEAN) {
|
|
146
146
|
return value ? 1 : 0;
|
|
147
147
|
}
|
|
148
148
|
return value;
|
|
@@ -188,6 +188,9 @@ class SQLiteConnector {
|
|
|
188
188
|
const q = `SELECT ${columns} FROM ${tableName} ${where} ${orderBy} LIMIT ? OFFSET ?`;
|
|
189
189
|
const stmt = this.db.prepare(q);
|
|
190
190
|
const d = [...filterValues, limit, offset];
|
|
191
|
+
if (process.env.HEAVY_DEBUG) {
|
|
192
|
+
console.log('🪲 SQLITE Query', q, 'params:', d);
|
|
193
|
+
}
|
|
191
194
|
const rows = stmt.all(d);
|
|
192
195
|
const total = this.db.prepare(`SELECT COUNT(*) FROM ${tableName} ${where}`).get([...filterValues])['COUNT(*)'];
|
|
193
196
|
// run all fields via getFieldValue
|
package/dist/index.js
CHANGED
|
@@ -23,8 +23,9 @@ import ExpressServer from './servers/express.js';
|
|
|
23
23
|
import { v1 as uuid } from 'uuid';
|
|
24
24
|
import fs from 'fs';
|
|
25
25
|
import { ADMINFORTH_VERSION } from './modules/utils.js';
|
|
26
|
-
import { AdminForthFilterOperators,
|
|
26
|
+
import { AdminForthFilterOperators, AdminForthDataTypes } from './types/AdminForthConfig.js';
|
|
27
27
|
import { getFunctionList } from './modules/utils.js';
|
|
28
|
+
import path from 'path';
|
|
28
29
|
const AVAILABLE_SHOW_IN = ['list', 'edit', 'create', 'filter', 'show'];
|
|
29
30
|
const DEFAULT_ALLOWED_ACTIONS = { create: true, edit: true, show: true, delete: true };
|
|
30
31
|
class AdminForth {
|
|
@@ -51,8 +52,18 @@ class AdminForth {
|
|
|
51
52
|
}
|
|
52
53
|
;
|
|
53
54
|
}
|
|
55
|
+
checkCustomFileExists(filePath) {
|
|
56
|
+
if (filePath.startsWith('@@/')) {
|
|
57
|
+
const checkPath = path.join(this.config.customization.customComponentsDir, filePath.replace('@@/', ''));
|
|
58
|
+
if (!fs.existsSync(checkPath)) {
|
|
59
|
+
return [`File file ${filePath} does not exist in ${this.config.customization.customComponentsDir}`];
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return [];
|
|
63
|
+
}
|
|
54
64
|
validateConfig() {
|
|
55
65
|
var _b;
|
|
66
|
+
const errors = [];
|
|
56
67
|
if (this.config.rootUser) {
|
|
57
68
|
if (!this.config.rootUser.username) {
|
|
58
69
|
throw new Error('rootUser.username is required');
|
|
@@ -69,6 +80,12 @@ class AdminForth {
|
|
|
69
80
|
if (!this.config.auth.passwordHashField) {
|
|
70
81
|
throw new Error('No config.auth.passwordHashField defined');
|
|
71
82
|
}
|
|
83
|
+
if (!this.config.auth.usernameField) {
|
|
84
|
+
throw new Error('No config.auth.usernameField defined');
|
|
85
|
+
}
|
|
86
|
+
if (this.config.auth.loginBackgroundImage) {
|
|
87
|
+
errors.push(...this.checkCustomFileExists(this.config.auth.loginBackgroundImage));
|
|
88
|
+
}
|
|
72
89
|
const userResource = this.config.resources.find((res) => res.resourceId === this.config.auth.resourceId);
|
|
73
90
|
if (!userResource) {
|
|
74
91
|
throw new Error(`Resource with id "${this.config.auth.resourceId}" not found`);
|
|
@@ -80,7 +97,6 @@ class AdminForth {
|
|
|
80
97
|
if (!this.config.customization.customComponentsDir) {
|
|
81
98
|
this.config.customization.customComponentsDir = './custom';
|
|
82
99
|
}
|
|
83
|
-
const errors = [];
|
|
84
100
|
if (!this.config.baseUrl) {
|
|
85
101
|
this.config.baseUrl = '';
|
|
86
102
|
}
|
|
@@ -88,10 +104,7 @@ class AdminForth {
|
|
|
88
104
|
this.config.customization.brandName = 'AdminForth';
|
|
89
105
|
}
|
|
90
106
|
if (this.config.customization.brandLogo) {
|
|
91
|
-
|
|
92
|
-
errors.push(`Brand logo must start with @@ and be placed in custom directory`);
|
|
93
|
-
}
|
|
94
|
-
// todo check file exist
|
|
107
|
+
errors.push(...this.checkCustomFileExists(this.config.customization.brandLogo));
|
|
95
108
|
}
|
|
96
109
|
if (!this.config.customization.datesFormat) {
|
|
97
110
|
this.config.customization.datesFormat = 'MMM D, YYYY HH:mm:ss';
|
|
@@ -356,6 +369,16 @@ class AdminForth {
|
|
|
356
369
|
throw new Error('No config.auth defined');
|
|
357
370
|
}
|
|
358
371
|
const userResource = this.config.resources.find((res) => res.resourceId === this.config.auth.resourceId);
|
|
372
|
+
// if there is no passwordHashField, in columns, add it, with backendOnly and showIn: []
|
|
373
|
+
if (!userResource.dataSourceColumns.find((col) => col.name === this.config.auth.passwordHashField)) {
|
|
374
|
+
userResource.dataSourceColumns.push({
|
|
375
|
+
name: this.config.auth.passwordHashField,
|
|
376
|
+
backendOnly: true,
|
|
377
|
+
showIn: [],
|
|
378
|
+
type: _a.Types.STRING,
|
|
379
|
+
});
|
|
380
|
+
console.log('Adding passwordHashField to userResource', userResource);
|
|
381
|
+
}
|
|
359
382
|
const userRecord = (_c = (yield this.connectors[userResource.dataSource].getData({
|
|
360
383
|
resource: userResource,
|
|
361
384
|
filters: [
|
|
@@ -680,12 +703,12 @@ class AdminForth {
|
|
|
680
703
|
const item = yield this.connectors[resource.dataSource].getMinMaxForColumns({
|
|
681
704
|
resource,
|
|
682
705
|
columns: resource.columns.filter((col) => [
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
706
|
+
AdminForthDataTypes.INTEGER,
|
|
707
|
+
AdminForthDataTypes.FLOAT,
|
|
708
|
+
AdminForthDataTypes.DATE,
|
|
709
|
+
AdminForthDataTypes.DATETIME,
|
|
710
|
+
AdminForthDataTypes.TIME,
|
|
711
|
+
AdminForthDataTypes.DECIMAL,
|
|
689
712
|
].includes(col.type) && col.allowMinMaxQuery === true),
|
|
690
713
|
});
|
|
691
714
|
return item;
|
|
@@ -883,7 +906,7 @@ class AdminForth {
|
|
|
883
906
|
}
|
|
884
907
|
}
|
|
885
908
|
_a = AdminForth, _AdminForth_defaultConfig = new WeakMap();
|
|
886
|
-
AdminForth.Types =
|
|
909
|
+
AdminForth.Types = AdminForthDataTypes;
|
|
887
910
|
AdminForth.Utils = {
|
|
888
911
|
generatePasswordHash: (password) => __awaiter(void 0, void 0, void 0, function* () {
|
|
889
912
|
return yield Auth.generatePasswordHash(password);
|