adminforth 1.0.73 → 1.0.74

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.
@@ -1,7 +1,6 @@
1
1
  import dayjs from 'dayjs';
2
2
  import { MongoClient } from 'mongodb';
3
- import { AdminForthFilterOperators, AdminForthSortDirections, AdminForthTypes } from '../types.js';
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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, AdminForthTypes } from '../types.js';
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 = AdminForthTypes.INTEGER;
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 = AdminForthTypes.FLOAT;
80
+ field.type = AdminForthDataTypes.FLOAT;
80
81
  field._underlineType = 'float';
81
82
 
82
83
  } else if (baseType.includes('bool')) {
83
- field.type = AdminForthTypes.BOOLEAN;
84
+ field.type = AdminForthDataTypes.BOOLEAN;
84
85
  field._underlineType = 'bool';
85
86
 
86
87
  } else if (baseType == 'uuid') {
87
- field.type = AdminForthTypes.STRING;
88
+ field.type = AdminForthDataTypes.STRING;
88
89
  field._underlineType = 'uuid';
89
90
 
90
91
  } else if (baseType.includes('character varying')) {
91
- field.type = AdminForthTypes.STRING;
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 = AdminForthTypes.TEXT;
98
+ field.type = AdminForthDataTypes.TEXT;
98
99
  field._underlineType = 'text';
99
100
 
100
101
  } else if (baseType.includes('decimal(')) {
101
- field.type = AdminForthTypes.DECIMAL;
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 = AdminForthTypes.FLOAT;
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 = AdminForthTypes.DATETIME;
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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.filter(c=> !c.virtual).map((col) => `"${col.name}"`).join(', ');
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('🗨️ PG selectQuery:', selectQuery, 'params:', d);
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;
@@ -1,5 +1,6 @@
1
1
  import betterSqlite3 from 'better-sqlite3';
2
- import { AdminForthTypes, AdminForthFilterOperators, AdminForthSortDirections } from '../types.js';
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 = AdminForthTypes.INTEGER;
25
+ field.type = AdminForthDataTypes.INTEGER;
25
26
  field._underlineType = 'int';
26
27
  } else if (baseType.includes('varchar(')) {
27
- field.type = AdminForthTypes.STRING;
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 = AdminForthTypes.TEXT;
33
+ field.type = AdminForthDataTypes.TEXT;
33
34
  field._underlineType = 'text';
34
35
  } else if (baseType.includes('decimal(')) {
35
- field.type = AdminForthTypes.DECIMAL;
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 = AdminForthTypes.FLOAT; //8-byte IEEE floating point number. It
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 = AdminForthTypes.DATETIME;
45
+ field.type = AdminForthDataTypes.DATETIME;
45
46
  field._underlineType = 'timestamp';
46
47
  } else if (baseType == 'boolean') {
47
- field.type = AdminForthTypes.BOOLEAN;
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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, AdminForthTypes } from '../types.js';
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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, AdminForthTypes } from '../types.js';
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 = AdminForthTypes.INTEGER;
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 = AdminForthTypes.FLOAT;
80
+ field.type = AdminForthDataTypes.FLOAT;
81
81
  field._underlineType = 'float';
82
82
  }
83
83
  else if (baseType.includes('bool')) {
84
- field.type = AdminForthTypes.BOOLEAN;
84
+ field.type = AdminForthDataTypes.BOOLEAN;
85
85
  field._underlineType = 'bool';
86
86
  }
87
87
  else if (baseType == 'uuid') {
88
- field.type = AdminForthTypes.STRING;
88
+ field.type = AdminForthDataTypes.STRING;
89
89
  field._underlineType = 'uuid';
90
90
  }
91
91
  else if (baseType.includes('character varying')) {
92
- field.type = AdminForthTypes.STRING;
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 = AdminForthTypes.TEXT;
98
+ field.type = AdminForthDataTypes.TEXT;
99
99
  field._underlineType = 'text';
100
100
  }
101
101
  else if (baseType.includes('decimal(')) {
102
- field.type = AdminForthTypes.DECIMAL;
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 = AdminForthTypes.FLOAT;
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 = AdminForthTypes.DATETIME;
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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.filter(c => !c.virtual).map((col) => `"${col.name}"`).join(', ');
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('🗨️ PG selectQuery:', selectQuery, 'params:', d);
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 { AdminForthTypes, AdminForthFilterOperators, AdminForthSortDirections } from '../types.js';
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 = AdminForthTypes.INTEGER;
44
+ field.type = AdminForthDataTypes.INTEGER;
45
45
  field._underlineType = 'int';
46
46
  }
47
47
  else if (baseType.includes('varchar(')) {
48
- field.type = AdminForthTypes.STRING;
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 = AdminForthTypes.TEXT;
54
+ field.type = AdminForthDataTypes.TEXT;
55
55
  field._underlineType = 'text';
56
56
  }
57
57
  else if (baseType.includes('decimal(')) {
58
- field.type = AdminForthTypes.DECIMAL;
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 = AdminForthTypes.FLOAT; //8-byte IEEE floating point number. It
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 = AdminForthTypes.DATETIME;
69
+ field.type = AdminForthDataTypes.DATETIME;
70
70
  field._underlineType = 'timestamp';
71
71
  }
72
72
  else if (baseType == 'boolean') {
73
- field.type = AdminForthTypes.BOOLEAN;
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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 == AdminForthTypes.DATETIME) {
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 == AdminForthTypes.BOOLEAN) {
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, AdminForthTypes } from './types.js';
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
- if (!this.config.customization.brandLogo.startsWith('@@/')) {
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
- AdminForthTypes.INTEGER,
684
- AdminForthTypes.FLOAT,
685
- AdminForthTypes.DATE,
686
- AdminForthTypes.DATETIME,
687
- AdminForthTypes.TIME,
688
- AdminForthTypes.DECIMAL,
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 = AdminForthTypes;
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);
@@ -29,10 +29,29 @@ function hashify(obj) {
29
29
  return crypto.createHash('sha256').update(JSON.stringify(obj)).digest('hex');
30
30
  }
31
31
  class CodeInjector {
32
+ cleanup() {
33
+ console.log('Cleaning up...');
34
+ this.allWatchers.forEach((watcher) => {
35
+ watcher.removeAll();
36
+ });
37
+ }
32
38
  constructor(adminforth) {
39
+ this.allWatchers = [];
33
40
  this.allComponentNames = {};
34
41
  this.srcFoldersToSync = {};
35
42
  this.adminforth = adminforth;
43
+ process.on('SIGINT', () => {
44
+ console.log('Received SIGINT.');
45
+ this.cleanup();
46
+ });
47
+ process.on('SIGTERM', () => {
48
+ console.log('Received SIGTERM.');
49
+ this.cleanup();
50
+ });
51
+ process.on('exit', () => {
52
+ console.log('Exiting.');
53
+ this.cleanup();
54
+ });
36
55
  }
37
56
  // async runShell({command, verbose = false}) {
38
57
  // console.log(`⚙️ Running shell ${command}...`);
@@ -154,6 +173,13 @@ class CodeInjector {
154
173
  if (process.env.HEAVY_DEBUG) {
155
174
  console.log(`🪲 await fsExtra.copy from ${path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'spa')}, ${CodeInjector.SPA_TMP_PATH}`);
156
175
  }
176
+ // try to rm SPA_TMP_PATH/src/types directory
177
+ try {
178
+ yield fs.promises.rm(path.join(CodeInjector.SPA_TMP_PATH, 'src', 'types'), { recursive: true });
179
+ }
180
+ catch (e) {
181
+ // ignore
182
+ }
157
183
  yield fsExtra.copy(path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'spa'), CodeInjector.SPA_TMP_PATH, {
158
184
  filter: (src) => {
159
185
  if (process.env.HEAVY_DEBUG) {
@@ -162,6 +188,7 @@ class CodeInjector {
162
188
  return !src.includes('/adminforth/spa/node_modules') && !src.includes('/adminforth/spa/dist');
163
189
  },
164
190
  overwrite: true,
191
+ dereference: true, // needed to dereference types
165
192
  });
166
193
  // copy whole custom directory
167
194
  if ((_b = this.adminforth.config.customization) === null || _b === void 0 ? void 0 : _b.customComponentsDir) {
@@ -358,9 +385,7 @@ class CodeInjector {
358
385
  console.log(`File ${file} changed, preparing sources...`);
359
386
  yield this.prepareSources({ filesUpdated: [file.replace(spaPath + '/', '')] });
360
387
  }));
361
- process.on('exit', () => {
362
- watcher.removeAll();
363
- });
388
+ this.allWatchers.push(watcher);
364
389
  });
365
390
  }
366
391
  watchCustomComponentsForCopy(_a) {
@@ -405,9 +430,7 @@ class CodeInjector {
405
430
  recursive: true,
406
431
  });
407
432
  }));
408
- process.on('exit', () => {
409
- watcher.removeAll();
410
- });
433
+ this.allWatchers.push(watcher);
411
434
  });
412
435
  }
413
436
  bundleNow(_a) {
@@ -1,6 +1,7 @@
1
1
  import { onMounted, ref, resolveComponent } from 'vue';
2
2
 
3
3
  import router from "./router";
4
+ import { useCoreStore } from './stores/core';
4
5
 
5
6
  export async function callApi({path, method, body=undefined} ) {
6
7
  const options = {
@@ -62,3 +63,13 @@ export const loadFile = (file: string) => {
62
63
  }
63
64
  return baseUrl;
64
65
  }
66
+
67
+ // export function checkEmptyValues(value: any, viewType:'show' | 'list' | 'create' | 'edit') {
68
+ // const config: = useCoreStore().config;
69
+ // const emptyFieldPlaceholder = config.emptyFieldPlaceholder?.[viewType] || '---';
70
+
71
+ // if (value === null || value === undefined || value === '') {
72
+ // return emptyFieldPlaceholder;
73
+ // }
74
+ // return value;
75
+ // }
@@ -7,6 +7,10 @@
7
7
  'background-blend-mode': 'darken'
8
8
  }: {}"
9
9
  >
10
+
11
+ {{ coreStore.config?.brandLogo }}
12
+ <img
13
+ :src="loadFile('@@/logo2.png')" class="w-40 h-40" alt="logo" />
10
14
  <!-- Main modal -->
11
15
  <div id="authentication-modal" tabindex="-1" class=" overflow-y-auto overflow-x-hidden z-50 min-w-[400px] justify-center items-center md:inset-0 h-[calc(100%-1rem)] max-h-full">
12
16
  <div class="relative p-4 w-full max-w-md max-h-full">
@@ -114,6 +118,7 @@ async function login() {
114
118
  } else {
115
119
  error.value = null;
116
120
  router.push('/');
121
+ await router.isReady();
117
122
  await coreStore.fetchMenuAndResource();
118
123
  setTimeout(() => {
119
124
  initFlowbite();
@@ -1 +1,33 @@
1
- export {};
1
+ export var AdminForthDataTypes;
2
+ (function (AdminForthDataTypes) {
3
+ AdminForthDataTypes["STRING"] = "string";
4
+ AdminForthDataTypes["INTEGER"] = "integer";
5
+ AdminForthDataTypes["FLOAT"] = "float";
6
+ AdminForthDataTypes["DECIMAL"] = "decimal";
7
+ AdminForthDataTypes["BOOLEAN"] = "boolean";
8
+ AdminForthDataTypes["DATE"] = "date";
9
+ AdminForthDataTypes["DATETIME"] = "datetime";
10
+ AdminForthDataTypes["TIME"] = "time";
11
+ AdminForthDataTypes["TEXT"] = "text";
12
+ AdminForthDataTypes["JSON"] = "json";
13
+ })(AdminForthDataTypes || (AdminForthDataTypes = {}));
14
+ export var AdminForthFilterOperators;
15
+ (function (AdminForthFilterOperators) {
16
+ AdminForthFilterOperators["EQ"] = "eq";
17
+ AdminForthFilterOperators["NE"] = "ne";
18
+ AdminForthFilterOperators["GT"] = "gt";
19
+ AdminForthFilterOperators["LT"] = "lt";
20
+ AdminForthFilterOperators["GTE"] = "gte";
21
+ AdminForthFilterOperators["LTE"] = "lte";
22
+ AdminForthFilterOperators["LIKE"] = "like";
23
+ AdminForthFilterOperators["ILIKE"] = "ilike";
24
+ AdminForthFilterOperators["IN"] = "in";
25
+ AdminForthFilterOperators["NIN"] = "nin";
26
+ })(AdminForthFilterOperators || (AdminForthFilterOperators = {}));
27
+ ;
28
+ export var AdminForthSortDirections;
29
+ (function (AdminForthSortDirections) {
30
+ AdminForthSortDirections["ASC"] = "asc";
31
+ AdminForthSortDirections["DESC"] = "desc";
32
+ })(AdminForthSortDirections || (AdminForthSortDirections = {}));
33
+ ;
package/index.ts CHANGED
@@ -9,9 +9,9 @@ import ExpressServer from './servers/express.js';
9
9
  import {v1 as uuid} from 'uuid';
10
10
  import fs from 'fs';
11
11
  import { ADMINFORTH_VERSION } from './modules/utils.js';
12
- import { AdminForthFilterOperators, AdminForthTypes, AdminForthTypesValues } from './types.js';
13
- import { AdminForthConfig } from './types/AdminForthConfig.js';
12
+ import { AdminForthConfig, AdminForthClass, AdminForthFilterOperators, AdminForthDataTypes } from './types/AdminForthConfig.js';
14
13
  import { getFunctionList } from './modules/utils.js';
14
+ import path from 'path';
15
15
 
16
16
  const AVAILABLE_SHOW_IN = ['list', 'edit', 'create', 'filter', 'show'];
17
17
  const DEFAULT_ALLOWED_ACTIONS = {create: true, edit: true, show: true, delete: true};
@@ -22,9 +22,8 @@ type ValidationObject = {
22
22
  message: string,
23
23
  }
24
24
 
25
- class AdminForth {
26
- static Types = AdminForthTypes;
27
-
25
+ class AdminForth implements AdminForthClass {
26
+ static Types = AdminForthDataTypes;
28
27
 
29
28
  static Utils = {
30
29
  generatePasswordHash: async (password) => {
@@ -48,7 +47,6 @@ class AdminForth {
48
47
  dbDiscover?: 'running' | 'done',
49
48
  }
50
49
 
51
-
52
50
  constructor(config: AdminForthConfig) {
53
51
  this.config = {...this.#defaultConfig,...config};
54
52
  this.codeInjector = new CodeInjector(this);
@@ -72,7 +70,19 @@ class AdminForth {
72
70
  };
73
71
  }
74
72
 
73
+ checkCustomFileExists(filePath: string): Array<string> {
74
+ if (filePath.startsWith('@@/')) {
75
+ const checkPath = path.join(this.config.customization.customComponentsDir, filePath.replace('@@/', ''));
76
+ if (!fs.existsSync(checkPath)) {
77
+ return [`File file ${filePath} does not exist in ${this.config.customization.customComponentsDir}`];
78
+ }
79
+ }
80
+ return [];
81
+ }
82
+
75
83
  validateConfig() {
84
+ const errors = [];
85
+
76
86
  if (this.config.rootUser) {
77
87
  if (!this.config.rootUser.username) {
78
88
  throw new Error('rootUser.username is required');
@@ -91,6 +101,12 @@ class AdminForth {
91
101
  if (!this.config.auth.passwordHashField) {
92
102
  throw new Error('No config.auth.passwordHashField defined');
93
103
  }
104
+ if (!this.config.auth.usernameField) {
105
+ throw new Error('No config.auth.usernameField defined');
106
+ }
107
+ if (this.config.auth.loginBackgroundImage) {
108
+ errors.push(...this.checkCustomFileExists(this.config.auth.loginBackgroundImage));
109
+ }
94
110
  const userResource = this.config.resources.find((res) => res.resourceId === this.config.auth.resourceId);
95
111
  if (!userResource) {
96
112
  throw new Error(`Resource with id "${this.config.auth.resourceId}" not found`);
@@ -106,7 +122,6 @@ class AdminForth {
106
122
  }
107
123
 
108
124
 
109
- const errors = [];
110
125
  if (!this.config.baseUrl) {
111
126
  this.config.baseUrl = '';
112
127
  }
@@ -114,10 +129,7 @@ class AdminForth {
114
129
  this.config.customization.brandName = 'AdminForth';
115
130
  }
116
131
  if (this.config.customization.brandLogo) {
117
- if (!this.config.customization.brandLogo.startsWith('@@/')) {
118
- errors.push(`Brand logo must start with @@ and be placed in custom directory`);
119
- }
120
- // todo check file exist
132
+ errors.push(...this.checkCustomFileExists(this.config.customization.brandLogo));
121
133
  }
122
134
 
123
135
 
@@ -422,6 +434,17 @@ class AdminForth {
422
434
  throw new Error('No config.auth defined');
423
435
  }
424
436
  const userResource = this.config.resources.find((res) => res.resourceId === this.config.auth.resourceId);
437
+ // if there is no passwordHashField, in columns, add it, with backendOnly and showIn: []
438
+ if (!userResource.dataSourceColumns.find((col) => col.name === this.config.auth.passwordHashField)) {
439
+ userResource.dataSourceColumns.push({
440
+ name: this.config.auth.passwordHashField,
441
+ backendOnly: true,
442
+ showIn: [],
443
+ type: AdminForth.Types.STRING,
444
+ });
445
+ console.log('Adding passwordHashField to userResource', userResource)
446
+ }
447
+
425
448
  const userRecord = (
426
449
  await this.connectors[userResource.dataSource].getData({
427
450
  resource: userResource,
@@ -775,12 +798,12 @@ class AdminForth {
775
798
  const item = await this.connectors[resource.dataSource].getMinMaxForColumns({
776
799
  resource,
777
800
  columns: resource.columns.filter((col) => [
778
- AdminForthTypes.INTEGER,
779
- AdminForthTypes.FLOAT,
780
- AdminForthTypes.DATE,
781
- AdminForthTypes.DATETIME,
782
- AdminForthTypes.TIME,
783
- AdminForthTypes.DECIMAL,
801
+ AdminForthDataTypes.INTEGER,
802
+ AdminForthDataTypes.FLOAT,
803
+ AdminForthDataTypes.DATE,
804
+ AdminForthDataTypes.DATETIME,
805
+ AdminForthDataTypes.TIME,
806
+ AdminForthDataTypes.DECIMAL,
784
807
  ].includes(col.type) && col.allowMinMaxQuery === true),
785
808
  });
786
809
  return item;
@@ -11,6 +11,7 @@ import { ADMIN_FORTH_ABSOLUTE_PATH } from './utils.js';
11
11
  import { getComponentNameFromPath } from './utils.js';
12
12
 
13
13
 
14
+
14
15
  let TMP_DIR;
15
16
 
16
17
  try {
@@ -29,14 +30,36 @@ function hashify(obj) {
29
30
 
30
31
  class CodeInjector {
31
32
 
33
+ allWatchers = [];
32
34
  adminforth: AdminForth;
33
35
  allComponentNames: { [key: string]: string } = {};
34
36
  srcFoldersToSync: { [key: string]: string } = {};
35
37
 
36
38
  static SPA_TMP_PATH = path.join(TMP_DIR, 'adminforth', 'spa_tmp');
37
39
 
40
+ cleanup() {
41
+ console.log('Cleaning up...');
42
+ this.allWatchers.forEach((watcher) => {
43
+ watcher.removeAll();
44
+ });
45
+ }
38
46
  constructor(adminforth) {
39
47
  this.adminforth = adminforth;
48
+
49
+ process.on('SIGINT', () => {
50
+ console.log('Received SIGINT.');
51
+ this.cleanup();
52
+ });
53
+
54
+ process.on('SIGTERM', () => {
55
+ console.log('Received SIGTERM.');
56
+ this.cleanup();
57
+ });
58
+
59
+ process.on('exit', () => {
60
+ console.log('Exiting.');
61
+ this.cleanup();
62
+ });
40
63
  }
41
64
 
42
65
  // async runShell({command, verbose = false}) {
@@ -164,6 +187,13 @@ class CodeInjector {
164
187
  console.log(`🪲 await fsExtra.copy from ${path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'spa')}, ${CodeInjector.SPA_TMP_PATH}`);
165
188
  }
166
189
 
190
+ // try to rm SPA_TMP_PATH/src/types directory
191
+ try {
192
+ await fs.promises.rm(path.join(CodeInjector.SPA_TMP_PATH, 'src', 'types'), { recursive: true });
193
+ } catch (e) {
194
+ // ignore
195
+ }
196
+
167
197
  await fsExtra.copy(path.join(ADMIN_FORTH_ABSOLUTE_PATH, 'spa'), CodeInjector.SPA_TMP_PATH, {
168
198
  filter: (src) => {
169
199
  if (process.env.HEAVY_DEBUG) {
@@ -173,6 +203,7 @@ class CodeInjector {
173
203
  return !src.includes('/adminforth/spa/node_modules') && !src.includes('/adminforth/spa/dist');
174
204
  },
175
205
  overwrite: true,
206
+ dereference: true, // needed to dereference types
176
207
  });
177
208
 
178
209
  // copy whole custom directory
@@ -416,9 +447,7 @@ async watchForReprepare({ verbose }) {
416
447
  await this.prepareSources({ filesUpdated: [file.replace(spaPath + '/', '')] });
417
448
  }
418
449
  )
419
- process.on('exit', () => {
420
- watcher.removeAll();
421
- });
450
+ this.allWatchers.push(watcher);
422
451
  }
423
452
 
424
453
  async watchCustomComponentsForCopy({ verbose }) {
@@ -471,9 +500,7 @@ async watchForReprepare({ verbose }) {
471
500
  });
472
501
  }
473
502
  )
474
- process.on('exit', () => {
475
- watcher.removeAll();
476
- });
503
+ this.allWatchers.push(watcher);
477
504
  }
478
505
 
479
506
  async bundleNow({hotReload = false, verbose = false}: {hotReload: boolean, verbose: boolean}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "adminforth",
3
- "version": "1.0.73",
3
+ "version": "1.0.74",
4
4
  "description": "OpenSource Vue3 powered forth-generation admin panel",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/plugins/base.ts CHANGED
@@ -1,13 +1,12 @@
1
- import { AdminForthResource } from '../types/AdminForthConfig.js';
2
- import AdminForth from '../index.js';
1
+ import { AdminForthResource, AdminForthPluginType, AdminForthClass } from '../types/AdminForthConfig.js';
3
2
  import { getComponentNameFromPath } from '../modules/utils.js';
4
3
  import { currentFileDir } from '../modules/utils.js';
5
4
  import path from 'path';
6
5
  import fs from 'fs';
7
6
 
8
- export default class AdminForthPlugin {
7
+ export default class AdminForthPlugin implements AdminForthPluginType {
9
8
 
10
- adminforth: AdminForth;
9
+ adminforth: AdminForthClass;
11
10
  pluginDir: string;
12
11
  customFolderName: string = 'custom';
13
12
 
@@ -16,7 +15,7 @@ export default class AdminForthPlugin {
16
15
  this.pluginDir = currentFileDir(metaUrl);
17
16
  }
18
17
 
19
- modifyResourceConfig(adminforth: AdminForth, resourceConfig: AdminForthResource) {
18
+ modifyResourceConfig(adminforth: AdminForthClass, resourceConfig: AdminForthResource) {
20
19
  this.adminforth = adminforth;
21
20
  }
22
21
 
package/spa/src/utils.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { onMounted, ref, resolveComponent } from 'vue';
2
2
 
3
3
  import router from "./router";
4
+ import { useCoreStore } from './stores/core';
4
5
 
5
6
  export async function callApi({path, method, body=undefined} ) {
6
7
  const options = {
@@ -62,3 +63,13 @@ export const loadFile = (file: string) => {
62
63
  }
63
64
  return baseUrl;
64
65
  }
66
+
67
+ // export function checkEmptyValues(value: any, viewType:'show' | 'list' | 'create' | 'edit') {
68
+ // const config: = useCoreStore().config;
69
+ // const emptyFieldPlaceholder = config.emptyFieldPlaceholder?.[viewType] || '---';
70
+
71
+ // if (value === null || value === undefined || value === '') {
72
+ // return emptyFieldPlaceholder;
73
+ // }
74
+ // return value;
75
+ // }
@@ -7,6 +7,10 @@
7
7
  'background-blend-mode': 'darken'
8
8
  }: {}"
9
9
  >
10
+
11
+ {{ coreStore.config?.brandLogo }}
12
+ <img
13
+ :src="loadFile('@@/logo2.png')" class="w-40 h-40" alt="logo" />
10
14
  <!-- Main modal -->
11
15
  <div id="authentication-modal" tabindex="-1" class=" overflow-y-auto overflow-x-hidden z-50 min-w-[400px] justify-center items-center md:inset-0 h-[calc(100%-1rem)] max-h-full">
12
16
  <div class="relative p-4 w-full max-w-md max-h-full">
@@ -114,6 +118,7 @@ async function login() {
114
118
  } else {
115
119
  error.value = null;
116
120
  router.push('/');
121
+ await router.isReady();
117
122
  await coreStore.fetchMenuAndResource();
118
123
  setTimeout(() => {
119
124
  initFlowbite();
@@ -1,4 +1,23 @@
1
- import AdminForthPlugin from '../plugins/base.js';
1
+
2
+
3
+ export interface CodeInjector {
4
+ srcFoldersToSync: Object;
5
+ allComponentNames: Object;
6
+ }
7
+
8
+ export interface AdminForthClass {
9
+ config: AdminForthConfig;
10
+ codeInjector: CodeInjector;
11
+ }
12
+
13
+
14
+ export interface AdminForthPluginType {
15
+ adminforth: AdminForthClass;
16
+ pluginDir: string;
17
+ customFolderName: string;
18
+ modifyResourceConfig(adminforth: AdminForthClass, resourceConfig: AdminForthResource): void;
19
+ componentPath(componentFile: string): string;
20
+ }
2
21
 
3
22
  export type AdminForthConfigMenuItem = {
4
23
  type?: 'heading' | 'group' | 'resource' | 'page' | 'gap' | 'divider',
@@ -20,7 +39,7 @@ export type AdminForthConfigMenuItem = {
20
39
  export type AdminForthResourceColumn = {
21
40
  name: string,
22
41
  label?: string,
23
- type?: AdminForthTypesValues,
42
+ type?: AdminForthDataTypes,
24
43
  primaryKey?: boolean,
25
44
  required?: boolean | { create: boolean, edit: boolean },
26
45
  editingNote?: string | { create: string, edit: string },
@@ -48,8 +67,9 @@ export type AdminForthResource = {
48
67
  table: string,
49
68
  dataSource: string,
50
69
  columns: Array<AdminForthResourceColumn>,
70
+ dataSourceColumns?: Array<AdminForthResourceColumn>,
51
71
  itemLabel?: Function,
52
- plugins?: Array<AdminForthPlugin>,
72
+ plugins?: Array<AdminForthPluginType>,
53
73
  hooks?: {
54
74
  show?: {
55
75
  beforeDatasourceRequest?: Function | Array<Function>,
@@ -153,18 +173,37 @@ export type AdminForthResourceColumnComponent = {
153
173
  list?: string,
154
174
  }
155
175
 
176
+ export enum AdminForthDataTypes {
177
+ STRING = 'string',
178
+ INTEGER = 'integer',
179
+ FLOAT = 'float',
180
+ DECIMAL = 'decimal',
181
+ BOOLEAN = 'boolean',
182
+ DATE = 'date',
183
+ DATETIME = 'datetime',
184
+ TIME = 'time',
185
+ TEXT = 'text',
186
+ JSON = 'json',
187
+ }
188
+
189
+ export enum AdminForthFilterOperators {
190
+ EQ = 'eq',
191
+ NE = 'ne',
192
+ GT = 'gt',
193
+ LT = 'lt',
194
+ GTE = 'gte',
195
+ LTE = 'lte',
196
+ LIKE = 'like',
197
+ ILIKE = 'ilike',
198
+ IN = 'in',
199
+ NIN = 'nin',
200
+ };
201
+
202
+ export enum AdminForthSortDirections {
203
+ ASC = 'asc',
204
+ DESC = 'desc',
205
+ };
156
206
 
157
- export type AdminForthTypesValues =
158
- | 'string'
159
- | 'integer'
160
- | 'float'
161
- | 'decimal'
162
- | 'boolean'
163
- | 'date'
164
- | 'datetime'
165
- | 'time'
166
- | 'text'
167
- | 'json';
168
207
 
169
208
  export type AdminForthResourceColumnEnumElement = {
170
209
  value: string | null,
package/types.ts DELETED
@@ -1,36 +0,0 @@
1
-
2
-
3
- // typical types which AdminForth supports
4
- //
5
- export const AdminForthTypes = {
6
- STRING: 'string',
7
- INTEGER: 'integer',
8
- FLOAT: 'float',
9
- DECIMAL: 'decimal',
10
- BOOLEAN: 'boolean',
11
- DATE: 'date',
12
- DATETIME: 'datetime',
13
- TIME: 'time',
14
- TEXT: 'text',
15
- JSON: 'json',
16
- }
17
-
18
- export type AdminForthTypesValues = keyof typeof AdminForthTypes;
19
-
20
- export const AdminForthFilterOperators = {
21
- EQ: 'eq',
22
- NE: 'ne',
23
- GT: 'gt',
24
- LT: 'lt',
25
- GTE: 'gte',
26
- LTE: 'lte',
27
- LIKE: 'like',
28
- ILIKE: 'ilike',
29
- IN: 'in',
30
- NIN: 'nin',
31
- };
32
-
33
- export const AdminForthSortDirections = {
34
- ASC: 'asc',
35
- DESC: 'desc',
36
- };