adminforth 1.2.98 → 1.2.99
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/baseConnector.ts +26 -14
- package/dataConnectors/clickhouse.ts +57 -37
- package/dataConnectors/mongo.ts +45 -14
- package/dataConnectors/postgres.ts +53 -36
- package/dataConnectors/sqlite.ts +37 -35
- package/dist/dataConnectors/baseConnector.js +16 -7
- package/dist/dataConnectors/clickhouse.js +58 -48
- package/dist/dataConnectors/mongo.js +29 -12
- package/dist/dataConnectors/postgres.js +62 -52
- package/dist/dataConnectors/sqlite.js +52 -45
- package/dist/index.js +3 -0
- package/dist/modules/operationalResource.js +88 -0
- package/dist/types/AdminForthConfig.js +37 -0
- package/index.ts +10 -2
- package/modules/operationalResource.ts +97 -0
- package/package.json +1 -1
- package/types/AdminForthConfig.ts +89 -8
|
@@ -184,36 +184,43 @@ class ClickhouseConnector extends AdminForthBaseConnector {
|
|
|
184
184
|
}
|
|
185
185
|
return value;
|
|
186
186
|
}
|
|
187
|
+
whereClause(resource, filters) {
|
|
188
|
+
return filters.length ? `WHERE ${filters.map((f, i) => {
|
|
189
|
+
const column = resource.dataSourceColumns.find((col) => col.name == f.field);
|
|
190
|
+
let placeholder = `{f${i}:${column._underlineType}}`;
|
|
191
|
+
let field = f.field;
|
|
192
|
+
let operator = this.OperatorsMap[f.operator];
|
|
193
|
+
if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
194
|
+
placeholder = `(${f.value.map((_, j) => `{p${i}_${j}:${column._underlineType}}`).join(', ')})`;
|
|
195
|
+
}
|
|
196
|
+
return `${field} ${operator} ${placeholder}`;
|
|
197
|
+
}).join(' AND ')}` : '';
|
|
198
|
+
}
|
|
199
|
+
whereParams(filters) {
|
|
200
|
+
const params = {};
|
|
201
|
+
filters.length ? filters.forEach((f, i) => {
|
|
202
|
+
// for arrays do set in map
|
|
203
|
+
const v = f.value;
|
|
204
|
+
if (f.operator == AdminForthFilterOperators.LIKE || f.operator == AdminForthFilterOperators.ILIKE) {
|
|
205
|
+
params[`f${i}`] = `%${v}%`;
|
|
206
|
+
}
|
|
207
|
+
else if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
208
|
+
v.forEach((_, j) => {
|
|
209
|
+
params[`p${i}_${j}`] = v[j];
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
params[`f${i}`] = v;
|
|
214
|
+
}
|
|
215
|
+
}) : [];
|
|
216
|
+
return params;
|
|
217
|
+
}
|
|
187
218
|
getDataWithOriginalTypes(_a) {
|
|
188
|
-
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters
|
|
219
|
+
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters }) {
|
|
189
220
|
const columns = resource.dataSourceColumns.map((col) => col.name).join(', ');
|
|
190
221
|
const tableName = resource.table;
|
|
191
|
-
const where =
|
|
192
|
-
|
|
193
|
-
let placeholder = `{f${i}:${column._underlineType}}`;
|
|
194
|
-
let field = f.field;
|
|
195
|
-
let operator = this.OperatorsMap[f.operator];
|
|
196
|
-
if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
197
|
-
placeholder = `(${f.value.map((_, j) => `{p${i}_${j}:${column._underlineType}}`).join(', ')})`;
|
|
198
|
-
}
|
|
199
|
-
return `${field} ${operator} ${placeholder}`;
|
|
200
|
-
}).join(' AND ')}` : '';
|
|
201
|
-
const params = {};
|
|
202
|
-
filters.length ? filters.forEach((f, i) => {
|
|
203
|
-
// for arrays do set in map
|
|
204
|
-
const v = f.value;
|
|
205
|
-
if (f.operator == AdminForthFilterOperators.LIKE || f.operator == AdminForthFilterOperators.ILIKE) {
|
|
206
|
-
params[`f${i}`] = `%${v}%`;
|
|
207
|
-
}
|
|
208
|
-
else if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
209
|
-
v.forEach((_, j) => {
|
|
210
|
-
params[`p${i}_${j}`] = v[j];
|
|
211
|
-
});
|
|
212
|
-
}
|
|
213
|
-
else {
|
|
214
|
-
params[`f${i}`] = v;
|
|
215
|
-
}
|
|
216
|
-
}) : [];
|
|
222
|
+
const where = this.whereClause(resource, filters);
|
|
223
|
+
const params = this.whereParams(filters);
|
|
217
224
|
const orderBy = sort.length ? `ORDER BY ${sort.map((s) => `${s.field} ${this.SortDirectionsMap[s.direction]}`).join(', ')}` : '';
|
|
218
225
|
const q = `SELECT ${columns} FROM ${tableName} ${where} ${orderBy} LIMIT {limit:Int} OFFSET {offset:Int}`;
|
|
219
226
|
const d = Object.assign(Object.assign({}, params), { limit,
|
|
@@ -224,26 +231,27 @@ class ClickhouseConnector extends AdminForthBaseConnector {
|
|
|
224
231
|
query_params: d,
|
|
225
232
|
});
|
|
226
233
|
const rows = yield stmt.json();
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
234
|
+
return rows.map((row) => {
|
|
235
|
+
const newRow = {};
|
|
236
|
+
for (const [key, value] of Object.entries(row)) {
|
|
237
|
+
newRow[key] = value;
|
|
238
|
+
}
|
|
239
|
+
return newRow;
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
getCount(_a) {
|
|
244
|
+
return __awaiter(this, arguments, void 0, function* ({ resource, filters, }) {
|
|
245
|
+
const tableName = resource.table;
|
|
246
|
+
const where = this.whereClause(resource, filters);
|
|
247
|
+
const d = this.whereParams(filters);
|
|
248
|
+
const countQ = yield this.client.query({
|
|
249
|
+
query: `SELECT COUNT(*) FROM ${tableName} ${where}`,
|
|
250
|
+
format: 'JSONEachRow',
|
|
251
|
+
query_params: d,
|
|
252
|
+
});
|
|
253
|
+
const countResp = yield countQ.json();
|
|
254
|
+
return countResp[0]['COUNT()'];
|
|
247
255
|
});
|
|
248
256
|
}
|
|
249
257
|
getMinMaxForColumnsWithOriginalTypes(_a) {
|
|
@@ -291,10 +299,12 @@ class ClickhouseConnector extends AdminForthBaseConnector {
|
|
|
291
299
|
deleteRecord(_a) {
|
|
292
300
|
return __awaiter(this, arguments, void 0, function* ({ resource, recordId }) {
|
|
293
301
|
const pkColumn = resource.dataSourceColumns.find((col) => col.primaryKey);
|
|
294
|
-
yield this.client.command({
|
|
302
|
+
const res = yield this.client.command({
|
|
295
303
|
query: `ALTER TABLE ${this.dbName}.${resource.table} DELETE WHERE ${pkColumn.name} = {recordId:${pkColumn._underlineType}}`,
|
|
296
304
|
query_params: { recordId },
|
|
297
305
|
});
|
|
306
|
+
// todo test what is in res
|
|
307
|
+
return res;
|
|
298
308
|
});
|
|
299
309
|
}
|
|
300
310
|
close() {
|
|
@@ -108,25 +108,41 @@ class MongoConnector extends AdminForthBaseConnector {
|
|
|
108
108
|
}
|
|
109
109
|
return value;
|
|
110
110
|
}
|
|
111
|
-
|
|
112
|
-
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters
|
|
113
|
-
|
|
114
|
-
const tableName = resource.table;
|
|
115
|
-
const collection = this.db.db().collection(tableName);
|
|
111
|
+
genQuery(_a) {
|
|
112
|
+
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters }) {
|
|
113
|
+
const collection = this.db.db().collection(resource.table);
|
|
116
114
|
const query = {};
|
|
117
115
|
for (const filter of filters) {
|
|
118
116
|
query[filter.field] = this.OperatorsMap[filter.operator](filter.value);
|
|
119
117
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
118
|
+
return { collection, query };
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
getDataWithOriginalTypes(_a) {
|
|
122
|
+
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters }) {
|
|
123
|
+
// const columns = resource.dataSourceColumns.filter(c=> !c.virtual).map((col) => col.name).join(', ');
|
|
124
|
+
const tableName = resource.table;
|
|
125
|
+
const collection = this.db.db().collection(tableName);
|
|
126
|
+
const query = this.genQuery({ resource, limit, offset, sort, filters });
|
|
127
|
+
const sortArray = sort.map((s) => {
|
|
128
|
+
return [s.field, this.SortDirectionsMap[s.direction]];
|
|
129
|
+
});
|
|
124
130
|
const result = yield collection.find(query)
|
|
125
|
-
.sort(
|
|
131
|
+
.sort(sortArray)
|
|
126
132
|
.skip(offset)
|
|
127
133
|
.limit(limit)
|
|
128
134
|
.toArray();
|
|
129
|
-
return
|
|
135
|
+
return result;
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
getCount(_a) {
|
|
139
|
+
return __awaiter(this, arguments, void 0, function* ({ resource, filters }) {
|
|
140
|
+
const collection = this.db.db().collection(resource.table);
|
|
141
|
+
const query = {};
|
|
142
|
+
for (const filter of filters) {
|
|
143
|
+
query[filter.field] = this.OperatorsMap[filter.operator](filter.value);
|
|
144
|
+
}
|
|
145
|
+
return yield collection.countDocuments(query);
|
|
130
146
|
});
|
|
131
147
|
}
|
|
132
148
|
getMinMaxForColumnsWithOriginalTypes(_a) {
|
|
@@ -166,7 +182,8 @@ class MongoConnector extends AdminForthBaseConnector {
|
|
|
166
182
|
return __awaiter(this, arguments, void 0, function* ({ resource, recordId }) {
|
|
167
183
|
const primaryKey = this.getPrimaryKey(resource);
|
|
168
184
|
const collection = this.db.db().collection(resource.table);
|
|
169
|
-
yield collection.deleteOne({ [primaryKey]: recordId });
|
|
185
|
+
const res = yield collection.deleteOne({ [primaryKey]: recordId });
|
|
186
|
+
return res.deletedCount > 0;
|
|
170
187
|
});
|
|
171
188
|
}
|
|
172
189
|
close() {
|
|
@@ -184,46 +184,54 @@ class PostgresConnector extends AdminForthBaseConnector {
|
|
|
184
184
|
}
|
|
185
185
|
return value;
|
|
186
186
|
}
|
|
187
|
+
whereClauseAndValues(resource, filters) {
|
|
188
|
+
let totalCounter = 1;
|
|
189
|
+
const where = filters.length ? `WHERE ${filters.map((f, i) => {
|
|
190
|
+
let placeholder = '$' + (totalCounter);
|
|
191
|
+
const fieldData = resource.dataSourceColumns.find((col) => col.name == f.field);
|
|
192
|
+
let field = f.field;
|
|
193
|
+
let operator = this.OperatorsMap[f.operator];
|
|
194
|
+
if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
195
|
+
placeholder = `(${f.value.map((_, i) => `$${totalCounter + i}`).join(', ')})`;
|
|
196
|
+
totalCounter += f.value.length;
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
totalCounter += 1;
|
|
200
|
+
}
|
|
201
|
+
if (fieldData._underlineType == 'uuid') {
|
|
202
|
+
field = `cast("${field}" as text)`;
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
field = `"${field}"`;
|
|
206
|
+
}
|
|
207
|
+
return `${field} ${operator} ${placeholder}`;
|
|
208
|
+
}).join(' AND ')}` : '';
|
|
209
|
+
const filterValues = [];
|
|
210
|
+
filters.length ? filters.forEach((f) => {
|
|
211
|
+
// for arrays do set in map
|
|
212
|
+
let v = f.value;
|
|
213
|
+
if (f.operator == AdminForthFilterOperators.LIKE || f.operator == AdminForthFilterOperators.ILIKE) {
|
|
214
|
+
filterValues.push(`%${v}%`);
|
|
215
|
+
}
|
|
216
|
+
else if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
217
|
+
filterValues.push(...v);
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
filterValues.push(v);
|
|
221
|
+
}
|
|
222
|
+
}) : [];
|
|
223
|
+
return {
|
|
224
|
+
sql: where,
|
|
225
|
+
paramsCount: totalCounter,
|
|
226
|
+
values: filterValues,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
187
229
|
getDataWithOriginalTypes(_a) {
|
|
188
|
-
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters
|
|
230
|
+
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters }) {
|
|
189
231
|
const columns = resource.dataSourceColumns.map((col) => `"${col.name}"`).join(', ');
|
|
190
232
|
const tableName = resource.table;
|
|
191
|
-
|
|
192
|
-
const
|
|
193
|
-
let placeholder = '$' + (totalCounter);
|
|
194
|
-
const fieldData = resource.dataSourceColumns.find((col) => col.name == f.field);
|
|
195
|
-
let field = f.field;
|
|
196
|
-
let operator = this.OperatorsMap[f.operator];
|
|
197
|
-
if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
198
|
-
placeholder = `(${f.value.map((_, i) => `$${totalCounter + i}`).join(', ')})`;
|
|
199
|
-
totalCounter += f.value.length;
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
totalCounter += 1;
|
|
203
|
-
}
|
|
204
|
-
if (fieldData._underlineType == 'uuid') {
|
|
205
|
-
field = `cast("${field}" as text)`;
|
|
206
|
-
}
|
|
207
|
-
else {
|
|
208
|
-
field = `"${field}"`;
|
|
209
|
-
}
|
|
210
|
-
return `${field} ${operator} ${placeholder}`;
|
|
211
|
-
}).join(' AND ')}` : '';
|
|
212
|
-
const filterValues = [];
|
|
213
|
-
filters.length ? filters.forEach((f) => {
|
|
214
|
-
// for arrays do set in map
|
|
215
|
-
let v = f.value;
|
|
216
|
-
if (f.operator == AdminForthFilterOperators.LIKE || f.operator == AdminForthFilterOperators.ILIKE) {
|
|
217
|
-
filterValues.push(`%${v}%`);
|
|
218
|
-
}
|
|
219
|
-
else if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
220
|
-
filterValues.push(...v);
|
|
221
|
-
}
|
|
222
|
-
else {
|
|
223
|
-
filterValues.push(v);
|
|
224
|
-
}
|
|
225
|
-
}) : [];
|
|
226
|
-
const limitOffset = `LIMIT $${totalCounter} OFFSET $${totalCounter + 1}`;
|
|
233
|
+
const { sql: where, paramsCount, values: filterValues } = this.whereClauseAndValues(resource, filters);
|
|
234
|
+
const limitOffset = `LIMIT $${paramsCount} OFFSET $${paramsCount + 1}`;
|
|
227
235
|
const d = [...filterValues, limit, offset];
|
|
228
236
|
const orderBy = sort.length ? `ORDER BY ${sort.map((s) => `"${s.field}" ${this.SortDirectionsMap[s.direction]}`).join(', ')}` : '';
|
|
229
237
|
const selectQuery = `SELECT ${columns} FROM ${tableName} ${where} ${orderBy} ${limitOffset}`;
|
|
@@ -232,20 +240,21 @@ class PostgresConnector extends AdminForthBaseConnector {
|
|
|
232
240
|
}
|
|
233
241
|
const stmt = yield this.db.query(selectQuery, d);
|
|
234
242
|
const rows = stmt.rows;
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
};
|
|
243
|
+
return rows.map((row) => {
|
|
244
|
+
const newRow = {};
|
|
245
|
+
for (const [key, value] of Object.entries(row)) {
|
|
246
|
+
newRow[key] = value;
|
|
247
|
+
}
|
|
248
|
+
return newRow;
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
getCount(_a) {
|
|
253
|
+
return __awaiter(this, arguments, void 0, function* ({ resource, filters }) {
|
|
254
|
+
const tableName = resource.table;
|
|
255
|
+
const { sql: where, values: filterValues } = this.whereClauseAndValues(resource, filters);
|
|
256
|
+
const stmt = yield this.db.query(`SELECT COUNT(*) FROM ${tableName} ${where}`, filterValues);
|
|
257
|
+
return stmt.rows[0].count;
|
|
249
258
|
});
|
|
250
259
|
}
|
|
251
260
|
getMinMaxForColumnsWithOriginalTypes(_a) {
|
|
@@ -283,7 +292,8 @@ class PostgresConnector extends AdminForthBaseConnector {
|
|
|
283
292
|
}
|
|
284
293
|
deleteRecord(_a) {
|
|
285
294
|
return __awaiter(this, arguments, void 0, function* ({ resource, recordId }) {
|
|
286
|
-
yield this.db.query(`DELETE FROM ${resource.table} WHERE "${this.getPrimaryKey(resource)}" = $1`, [recordId]);
|
|
295
|
+
const res = yield this.db.query(`DELETE FROM ${resource.table} WHERE "${this.getPrimaryKey(resource)}" = $1`, [recordId]);
|
|
296
|
+
return res.rowCount > 0;
|
|
287
297
|
});
|
|
288
298
|
}
|
|
289
299
|
close() {
|
|
@@ -149,39 +149,44 @@ class SQLiteConnector extends AdminForthBaseConnector {
|
|
|
149
149
|
}
|
|
150
150
|
return value;
|
|
151
151
|
}
|
|
152
|
+
whereClause(filters) {
|
|
153
|
+
return filters.length ? `WHERE ${filters.map((f, i) => {
|
|
154
|
+
let placeholder = '?';
|
|
155
|
+
let field = f.field;
|
|
156
|
+
let operator = this.OperatorsMap[f.operator];
|
|
157
|
+
if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
158
|
+
placeholder = `(${f.value.map(() => '?').join(', ')})`;
|
|
159
|
+
}
|
|
160
|
+
else if (f.operator == AdminForthFilterOperators.ILIKE) {
|
|
161
|
+
placeholder = `LOWER(?)`;
|
|
162
|
+
field = `LOWER(${f.field})`;
|
|
163
|
+
operator = 'LIKE';
|
|
164
|
+
}
|
|
165
|
+
return `${field} ${operator} ${placeholder}`;
|
|
166
|
+
}).join(' AND ')}` : '';
|
|
167
|
+
}
|
|
168
|
+
whereParams(filters) {
|
|
169
|
+
return filters.reduce((acc, f) => {
|
|
170
|
+
if (f.operator == AdminForthFilterOperators.LIKE || f.operator == AdminForthFilterOperators.ILIKE) {
|
|
171
|
+
acc.push(`%${f.value}%`);
|
|
172
|
+
}
|
|
173
|
+
else if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
174
|
+
acc.push(...f.value);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
acc.push(f.value);
|
|
178
|
+
}
|
|
179
|
+
return acc;
|
|
180
|
+
}, []);
|
|
181
|
+
}
|
|
152
182
|
getDataWithOriginalTypes(_a) {
|
|
153
|
-
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters
|
|
183
|
+
return __awaiter(this, arguments, void 0, function* ({ resource, limit, offset, sort, filters }) {
|
|
154
184
|
const columns = resource.dataSourceColumns.map((col) => col.name).join(', ');
|
|
155
185
|
const tableName = resource.table;
|
|
156
|
-
const where =
|
|
157
|
-
|
|
158
|
-
let field = f.field;
|
|
159
|
-
let operator = this.OperatorsMap[f.operator];
|
|
160
|
-
if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
161
|
-
placeholder = `(${f.value.map(() => '?').join(', ')})`;
|
|
162
|
-
}
|
|
163
|
-
else if (f.operator == AdminForthFilterOperators.ILIKE) {
|
|
164
|
-
placeholder = `LOWER(?)`;
|
|
165
|
-
field = `LOWER(${f.field})`;
|
|
166
|
-
operator = 'LIKE';
|
|
167
|
-
}
|
|
168
|
-
return `${field} ${operator} ${placeholder}`;
|
|
169
|
-
}).join(' AND ')}` : '';
|
|
170
|
-
const filterValues = [];
|
|
171
|
-
filters.length ? filters.forEach((f) => {
|
|
172
|
-
// for arrays do set in map
|
|
173
|
-
const v = f.value;
|
|
174
|
-
if (f.operator == AdminForthFilterOperators.LIKE || f.operator == AdminForthFilterOperators.ILIKE) {
|
|
175
|
-
filterValues.push(`%${v}%`);
|
|
176
|
-
}
|
|
177
|
-
else if (f.operator == AdminForthFilterOperators.IN || f.operator == AdminForthFilterOperators.NIN) {
|
|
178
|
-
filterValues.push(...v);
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
181
|
-
filterValues.push(v);
|
|
182
|
-
}
|
|
183
|
-
}) : [];
|
|
186
|
+
const where = this.whereClause(filters);
|
|
187
|
+
const filterValues = this.whereParams(filters);
|
|
184
188
|
const orderBy = sort.length ? `ORDER BY ${sort.map((s) => `${s.field} ${this.SortDirectionsMap[s.direction]}`).join(', ')}` : '';
|
|
189
|
+
console.log('🪲 SQLITE Query', `SELECT ${columns} FROM ${tableName} ${where} ${orderBy} LIMIT ? OFFSET ?`, 'params:', [...filterValues, limit, offset]);
|
|
185
190
|
const q = `SELECT ${columns} FROM ${tableName} ${where} ${orderBy} LIMIT ? OFFSET ?`;
|
|
186
191
|
const stmt = this.db.prepare(q);
|
|
187
192
|
const d = [...filterValues, limit, offset];
|
|
@@ -189,21 +194,22 @@ class SQLiteConnector extends AdminForthBaseConnector {
|
|
|
189
194
|
console.log('🪲 SQLITE Query', q, 'params:', d);
|
|
190
195
|
}
|
|
191
196
|
const rows = yield stmt.all(d);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
};
|
|
197
|
+
return rows.map((row) => {
|
|
198
|
+
const newRow = {};
|
|
199
|
+
for (const [key, value] of Object.entries(row)) {
|
|
200
|
+
newRow[key] = value;
|
|
201
|
+
}
|
|
202
|
+
return newRow;
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
getCount(_a) {
|
|
207
|
+
return __awaiter(this, arguments, void 0, function* ({ resource, filters }) {
|
|
208
|
+
const tableName = resource.table;
|
|
209
|
+
const where = this.whereClause(filters);
|
|
210
|
+
const filterValues = this.whereParams(filters);
|
|
211
|
+
const totalStmt = this.db.prepare(`SELECT COUNT(*) FROM ${tableName} ${where}`);
|
|
212
|
+
return totalStmt.get([...filterValues])['COUNT(*)'];
|
|
207
213
|
});
|
|
208
214
|
}
|
|
209
215
|
getMinMaxForColumnsWithOriginalTypes(_a) {
|
|
@@ -241,7 +247,8 @@ class SQLiteConnector extends AdminForthBaseConnector {
|
|
|
241
247
|
deleteRecord(_a) {
|
|
242
248
|
return __awaiter(this, arguments, void 0, function* ({ resource, recordId }) {
|
|
243
249
|
const q = this.db.prepare(`DELETE FROM ${resource.table} WHERE ${this.getPrimaryKey(resource)} = ?`);
|
|
244
|
-
yield q.run(recordId);
|
|
250
|
+
const res = yield q.run(recordId);
|
|
251
|
+
return res.changes > 0;
|
|
245
252
|
});
|
|
246
253
|
}
|
|
247
254
|
close() {
|
package/dist/index.js
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
// export interface IOperationalResource {
|
|
11
|
+
// get: (filters: IAdminForthFilter | IAdminForthFilter[]) => Promise<any[]>;
|
|
12
|
+
// list: (filters: IAdminForthFilter | IAdminForthFilter[], limit: number, offset: number, sort: IAdminForthSort | IAdminForthSort[]) => Promise<any[]>;
|
|
13
|
+
// count: (filters: IAdminForthFilter | IAdminForthFilter[]) => Promise<number>;
|
|
14
|
+
// create: (record: any) => Promise<any>;
|
|
15
|
+
// update: (primaryKey: any, record: any) => Promise<any>;
|
|
16
|
+
// delete: (primaryKey: any) => Promise<boolean>;
|
|
17
|
+
// deleteMany: (primaryKeys: any[]) => Promise<boolean>;
|
|
18
|
+
// }
|
|
19
|
+
// async getData({ resource, limit, offset, sort, filters }: {
|
|
20
|
+
// resource: AdminForthResource,
|
|
21
|
+
// limit: number,
|
|
22
|
+
// offset: number,
|
|
23
|
+
// sort: { field: string, direction: AdminForthSortDirections }[],
|
|
24
|
+
// filters: { field: string, operator: AdminForthFilterOperators, value: any }[]
|
|
25
|
+
// }): Promise<{ data: any[], total: number }> {
|
|
26
|
+
function filtersIfFilter(filter) {
|
|
27
|
+
return (typeof filter === 'object' ? [filter] : filter);
|
|
28
|
+
}
|
|
29
|
+
function sortsIfSort(sort) {
|
|
30
|
+
return (typeof sort === 'object' ? [sort] : sort);
|
|
31
|
+
}
|
|
32
|
+
export class OperationalResource {
|
|
33
|
+
constructor(dataConnector, resourceConfig) {
|
|
34
|
+
this.dataConnector = dataConnector;
|
|
35
|
+
this.resourceConfig = resourceConfig;
|
|
36
|
+
}
|
|
37
|
+
get(filter) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
return yield this.dataConnector.getData({
|
|
40
|
+
resource: this.resourceConfig,
|
|
41
|
+
filters: filtersIfFilter(filter),
|
|
42
|
+
limit: 1,
|
|
43
|
+
offset: 0,
|
|
44
|
+
sort: [],
|
|
45
|
+
})[0];
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
list(filter, limit, offset, sort) {
|
|
49
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
50
|
+
const { data } = yield this.dataConnector.getData({
|
|
51
|
+
resource: this.resourceConfig,
|
|
52
|
+
filters: filtersIfFilter(filter),
|
|
53
|
+
limit,
|
|
54
|
+
offset,
|
|
55
|
+
sort: sortsIfSort(sort),
|
|
56
|
+
getTotals: false,
|
|
57
|
+
});
|
|
58
|
+
return data;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
count(filter) {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
return yield this.dataConnector.getCount({
|
|
64
|
+
resource: this.resourceConfig,
|
|
65
|
+
filters: filtersIfFilter(filter),
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
create(record) {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
return yield this.dataConnector.createRecord({ resource: this.resourceConfig, record });
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
update(primaryKey, record) {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
return yield this.dataConnector.updateRecord({
|
|
77
|
+
resource: this.resourceConfig,
|
|
78
|
+
recordId: primaryKey,
|
|
79
|
+
newValues: record
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
delete(primaryKey) {
|
|
84
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
return yield this.dataConnector.deleteRecord({ resource: this.resourceConfig, recordId: primaryKey });
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -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";
|
package/index.ts
CHANGED
|
@@ -10,7 +10,9 @@ import {
|
|
|
10
10
|
type AdminForthConfig,
|
|
11
11
|
type IAdminForth,
|
|
12
12
|
type IConfigValidator,
|
|
13
|
-
|
|
13
|
+
IOperationalResource,
|
|
14
|
+
AdminForthFilterOperators,
|
|
15
|
+
AdminForthDataTypes, AdminForthResourcePages, IHttpServer,
|
|
14
16
|
BeforeSaveFunction,
|
|
15
17
|
AfterSaveFunction,
|
|
16
18
|
AdminUser,
|
|
@@ -50,7 +52,9 @@ class AdminForth implements IAdminForth {
|
|
|
50
52
|
activatedPlugins: Array<AdminForthPlugin>;
|
|
51
53
|
configValidator: IConfigValidator;
|
|
52
54
|
restApi: AdminForthRestAPI;
|
|
53
|
-
|
|
55
|
+
resourceInstances: {
|
|
56
|
+
[resourceId: string]: IOperationalResource,
|
|
57
|
+
}
|
|
54
58
|
baseUrlSlashed: string;
|
|
55
59
|
|
|
56
60
|
statuses: {
|
|
@@ -248,6 +252,10 @@ class AdminForth implements IAdminForth {
|
|
|
248
252
|
return { ok: true };
|
|
249
253
|
}
|
|
250
254
|
|
|
255
|
+
resource(resourceId: string) {
|
|
256
|
+
return this.config.resources.find((res) => res.resourceId === resourceId);
|
|
257
|
+
}
|
|
258
|
+
|
|
251
259
|
setupEndpoints(server: IHttpServer) {
|
|
252
260
|
this.restApi.registerEndpoints(server);
|
|
253
261
|
}
|