remult 2.7.28 → 2.7.30

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.
@@ -3,9 +3,11 @@ import { Filter } from '../src/filter/filter-interfaces.js';
3
3
  import { getHtml } from './get-remult-admin-html.js';
4
4
  import { getValueList } from '../src/remult3/RepositoryImplementation.js';
5
5
  export default function remultAdminHtml(options) {
6
- let { remult, entities, ...optionsFromServer } = { ...options };
7
- return getHtml().replace('<!--PLACE_HERE-->', `<script>
8
- const optionsFromServer = ${JSON.stringify(optionsFromServer)}
6
+ const { rootPath, head } = options;
7
+ return getHtml()
8
+ .replace('<!--PLACE_HERE_HEAD-->', head)
9
+ .replace('<!--PLACE_HERE_BODY-->', `<script>
10
+ window.optionsFromServer = ${JSON.stringify({ rootPath })}
9
11
  </script>`);
10
12
  }
11
13
  export function buildEntityInfo(options) {
@@ -20,67 +22,75 @@ export function buildEntityInfo(options) {
20
22
  for (const x of metadata.fields.toArray()) {
21
23
  if (!x.includedInApi(undefined))
22
24
  continue;
23
- let relation;
24
- let valFieldKey = x.key;
25
- const info = getRelationFieldInfo(x);
26
- if (info) {
27
- const relInfo = info.getFields();
28
- const relRepo = options.remult.repo(info.toEntity);
29
- const where = typeof info.options.findOptions === 'object' &&
30
- info.options.findOptions.where
31
- ? Filter.entityFilterToJson(relRepo.metadata, info.options.findOptions.where)
32
- : undefined;
33
- const idField = relRepo.metadata.idMetadata.field.key;
34
- if (info.type === 'reference' || info.type === 'toOne') {
35
- if (info.type == 'toOne') {
36
- for (const key in relInfo.fields) {
37
- if (Object.prototype.hasOwnProperty.call(relInfo.fields, key)) {
38
- const element = relInfo.fields[key];
39
- valFieldKey = element;
25
+ try {
26
+ let relation;
27
+ let valFieldKey = x.key;
28
+ const info = getRelationFieldInfo(x);
29
+ if (info) {
30
+ const relInfo = info.getFields();
31
+ const relRepo = options.remult.repo(info.toEntity);
32
+ const where = typeof info.options.findOptions === 'object' &&
33
+ info.options.findOptions.where
34
+ ? Filter.entityFilterToJson(relRepo.metadata, info.options.findOptions.where)
35
+ : undefined;
36
+ const idField = relRepo.metadata.idMetadata.field.key;
37
+ if (info.type === 'reference' || info.type === 'toOne') {
38
+ if (info.type == 'toOne') {
39
+ for (const key in relInfo.fields) {
40
+ if (Object.prototype.hasOwnProperty.call(relInfo.fields, key)) {
41
+ const element = relInfo.fields[key];
42
+ valFieldKey = element;
43
+ }
40
44
  }
41
45
  }
46
+ if (relRepo.metadata.apiReadAllowed) {
47
+ relation = {
48
+ ...relInfo,
49
+ where,
50
+ entityKey: relRepo.metadata.key,
51
+ idField,
52
+ captionField: relRepo.metadata.fields
53
+ .toArray()
54
+ .find((x) => x.key != idField && x.valueType == String)?.key,
55
+ };
56
+ }
42
57
  }
43
- if (relRepo.metadata.apiReadAllowed) {
44
- relation = {
45
- ...relInfo,
46
- where,
47
- entityKey: relRepo.metadata.key,
48
- idField,
49
- captionField: relRepo.metadata.fields
50
- .toArray()
51
- .find((x) => x.key != idField && x.valueType == String)?.key,
52
- };
53
- }
54
- }
55
- else if (info.type === 'toMany') {
56
- if (relRepo.metadata.apiReadAllowed) {
57
- relations.push({
58
- ...relInfo,
59
- where,
60
- entityKey: relRepo.metadata.key,
61
- });
58
+ else if (info.type === 'toMany') {
59
+ if (relRepo.metadata.apiReadAllowed) {
60
+ relations.push({
61
+ ...relInfo,
62
+ where,
63
+ entityKey: relRepo.metadata.key,
64
+ key: x.key,
65
+ caption: x.caption,
66
+ });
67
+ }
68
+ continue;
62
69
  }
63
- continue;
64
70
  }
71
+ fields.push({
72
+ key: x.key,
73
+ readOnly: !x.apiUpdateAllowed(),
74
+ values: getValueList(x),
75
+ valFieldKey,
76
+ caption: x.caption,
77
+ relationToOne: relation,
78
+ inputType: x.inputType,
79
+ type: x.valueConverter.fieldTypeInDb == 'json'
80
+ ? 'json'
81
+ : x.valueType === Number
82
+ ? 'number'
83
+ : x.valueType === Boolean
84
+ ? 'boolean'
85
+ : x.valueType === Date
86
+ ? 'date'
87
+ : 'string',
88
+ });
89
+ }
90
+ catch (error) {
91
+ console.error(`[remult-admin] Error with ${metadata.key}.${x.key} field.`);
92
+ console.error(`[remult-admin]`, error);
65
93
  }
66
- fields.push({
67
- key: x.key,
68
- readOnly: !x.apiUpdateAllowed(),
69
- values: getValueList(x),
70
- valFieldKey,
71
- caption: x.caption,
72
- relationToOne: relation,
73
- inputType: x.inputType,
74
- type: x.valueConverter.fieldTypeInDb == 'json'
75
- ? 'json'
76
- : x.valueType === Number
77
- ? 'number'
78
- : x.valueType === Boolean
79
- ? 'boolean'
80
- : x.valueType === Date
81
- ? 'date'
82
- : 'string',
83
- });
84
94
  }
85
95
  if (metadata.apiReadAllowed) {
86
96
  entities.push({
@@ -204,7 +204,10 @@ export class RemultServerImplementation {
204
204
  }, r);
205
205
  if (this.options.admin !== undefined && this.options.admin !== false) {
206
206
  const admin = () => this.process(async (remult, req, res, orig, origResponse) => {
207
- if (remult.isAllowed(this.options.admin)) {
207
+ const allowed = isOfType(this.options.admin, 'allow')
208
+ ? this.options.admin.allow
209
+ : this.options.admin;
210
+ if (remult.isAllowed(allowed)) {
208
211
  if (orig?.params?.id === '__entities-metadata') {
209
212
  res.success(buildEntityInfo({
210
213
  remult,
@@ -212,10 +215,14 @@ export class RemultServerImplementation {
212
215
  }));
213
216
  }
214
217
  else {
218
+ let head = '<title>Admin</title>';
219
+ if (isOfType(this.options.admin, 'allow') &&
220
+ this.options.admin.customHtmlHead) {
221
+ head = this.options.admin.customHtmlHead(remult);
222
+ }
215
223
  origResponse.send(remultAdminHtml({
216
- remult: remult,
217
- entities: this.options.entities,
218
- baseUrl: this.options.rootPath + '/admin',
224
+ rootPath: this.options.rootPath ?? '/api',
225
+ head,
219
226
  }));
220
227
  }
221
228
  }
@@ -720,8 +720,13 @@ export function buildFilterFromRequestParameters(entity, filterInfo) {
720
720
  }),
721
721
  });
722
722
  }
723
- if (not.length == 1 && !where.$not) {
724
- where = not[0];
723
+ if (not.length == 1) {
724
+ if (!where.$not) {
725
+ where.$not = not[0].$not;
726
+ }
727
+ else {
728
+ where.$not.push(not[0].$not);
729
+ }
725
730
  }
726
731
  else {
727
732
  addAnd({
@@ -8,6 +8,8 @@
8
8
  * @see [Active Record & EntityBase](https://remult.dev/docs/active-record)
9
9
  */
10
10
  export function getEntityRef(entity, throwException = true) {
11
+ if (entity === undefined)
12
+ throw new Error('entity is undefined');
11
13
  let x = entity[entityMember];
12
14
  if (!x && throwException)
13
15
  throw new Error('item ' +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "remult",
3
- "version": "2.7.28",
3
+ "version": "2.7.30",
4
4
  "description": "A CRUD framework for full-stack TypeScript",
5
5
  "homepage": "https://remult.dev",
6
6
  "repository": {