@jd-data-limited/easy-fm 4.0.16 → 4.1.1
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/package.json +16 -7
- package/src/FMError.d.ts +2 -2
- package/src/FMError.js +507 -508
- package/src/FMError.ts +510 -511
- package/src/connection/FMHost.d.ts +23 -5
- package/src/connection/FMHost.js +42 -26
- package/src/connection/FMHost.ts +63 -49
- package/src/connection/HostBase.d.ts +3 -3
- package/src/connection/HostBase.ts +5 -5
- package/src/connection/database.d.ts +53 -20
- package/src/connection/database.js +107 -90
- package/src/connection/database.ts +133 -121
- package/src/connection/databaseBase.d.ts +11 -7
- package/src/connection/databaseBase.ts +8 -8
- package/src/connection/generateAuthorizationHeaders.d.ts +1 -1
- package/src/connection/generateAuthorizationHeaders.js +10 -10
- package/src/connection/generateAuthorizationHeaders.ts +21 -21
- package/src/databaseStructure.d.ts +2 -4
- package/src/databaseStructure.ts +3 -5
- package/src/index.d.ts +17 -17
- package/src/index.js +13 -13
- package/src/index.ts +24 -24
- package/src/layouts/layout.d.ts +17 -6
- package/src/layouts/layout.js +19 -8
- package/src/layouts/layout.ts +33 -23
- package/src/layouts/layoutBase.d.ts +5 -5
- package/src/layouts/layoutBase.ts +6 -6
- package/src/layouts/layoutInterface.d.ts +3 -5
- package/src/layouts/layoutInterface.ts +4 -6
- package/src/layouts/layoutRecordManager.d.ts +29 -6
- package/src/layouts/layoutRecordManager.js +32 -9
- package/src/layouts/layoutRecordManager.ts +42 -19
- package/src/layouts/recordFieldsMap.d.ts +2 -4
- package/src/layouts/recordFieldsMap.ts +2 -4
- package/src/models/apiResults.d.ts +7 -13
- package/src/models/apiResults.ts +58 -58
- package/src/records/field.d.ts +39 -17
- package/src/records/field.js +248 -131
- package/src/records/field.ts +160 -82
- package/src/records/getOperations/recordGetOperation.d.ts +44 -24
- package/src/records/getOperations/recordGetOperation.js +88 -61
- package/src/records/getOperations/recordGetOperation.ts +128 -108
- package/src/records/layoutRecord.d.ts +28 -14
- package/src/records/layoutRecord.js +69 -60
- package/src/records/layoutRecord.ts +121 -119
- package/src/records/layoutRecordBase.d.ts +2 -2
- package/src/records/layoutRecordBase.ts +3 -3
- package/src/records/portal.d.ts +19 -5
- package/src/records/portal.js +19 -5
- package/src/records/portal.ts +28 -16
- package/src/records/portalBase.d.ts +5 -5
- package/src/records/portalBase.ts +6 -6
- package/src/records/portalRecord.d.ts +16 -8
- package/src/records/portalRecord.js +16 -6
- package/src/records/portalRecord.ts +29 -19
- package/src/records/recordBase.d.ts +18 -8
- package/src/records/recordBase.js +23 -16
- package/src/records/recordBase.ts +41 -37
- package/src/types.d.ts +23 -30
- package/src/types.js +0 -5
- package/src/types.ts +55 -64
- package/src/utils/query.d.ts +7 -7
- package/src/utils/query.js +10 -10
- package/src/utils/query.ts +19 -20
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
|
-
import { RecordBase } from
|
|
5
|
-
import { PortalRecord } from
|
|
6
|
-
import { Portal } from
|
|
7
|
-
import { FMError } from
|
|
8
|
-
import * as moment from
|
|
4
|
+
import { RecordBase } from './recordBase.js';
|
|
5
|
+
import { PortalRecord } from './portalRecord.js';
|
|
6
|
+
import { Portal } from './portal.js';
|
|
7
|
+
import { FMError } from '../FMError.js';
|
|
8
|
+
import * as moment from 'moment/moment.js';
|
|
9
9
|
export class LayoutRecord extends RecordBase {
|
|
10
|
-
// @ts-ignore
|
|
11
10
|
portals = {};
|
|
12
11
|
portalsToInclude;
|
|
13
12
|
constructor(layout, recordId, modId = recordId, fieldData = {}, portalData = null, portalsToInclude = []) {
|
|
@@ -20,38 +19,44 @@ export class LayoutRecord extends RecordBase {
|
|
|
20
19
|
get portalsArray() {
|
|
21
20
|
return Object.values(this.portals);
|
|
22
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Asynchronously commits the changes made to the current record.
|
|
24
|
+
* @param {extraBodyOptions} extraBody - The options for the extra body elements.
|
|
25
|
+
* @returns {Promise<this>} - A promise that resolves with the modified object.
|
|
26
|
+
* @throws {FMError} - If an error occurs during the commit process.
|
|
27
|
+
*/
|
|
23
28
|
async commit(extraBody = {}) {
|
|
24
|
-
|
|
29
|
+
const data = this.toObject();
|
|
25
30
|
delete data.recordId;
|
|
26
31
|
delete data.modId;
|
|
27
32
|
if (extraBody.scripts?.after) {
|
|
28
|
-
data
|
|
33
|
+
data.script = extraBody.scripts.after.name;
|
|
29
34
|
if (extraBody.scripts.after.parameter)
|
|
30
|
-
data[
|
|
35
|
+
data['script.param'] = extraBody.scripts.after.parameter;
|
|
31
36
|
}
|
|
32
37
|
if (extraBody.scripts?.prerequest) {
|
|
33
|
-
data[
|
|
38
|
+
data['script.prerequest'] = extraBody.scripts.prerequest.name;
|
|
34
39
|
if (extraBody.scripts.prerequest.parameter)
|
|
35
|
-
data[
|
|
40
|
+
data['script.prerequest.param'] = extraBody.scripts.prerequest.parameter;
|
|
36
41
|
}
|
|
37
42
|
if (extraBody.scripts?.presort) {
|
|
38
|
-
data[
|
|
43
|
+
data['script.presort'] = extraBody.scripts.presort.name;
|
|
39
44
|
if (extraBody.scripts.presort.parameter)
|
|
40
|
-
data[
|
|
45
|
+
data['script.presort.param'] = extraBody.scripts.presort.parameter;
|
|
41
46
|
}
|
|
42
47
|
if (this.recordId === -1) {
|
|
43
48
|
// This is a new LayoutRecord
|
|
44
|
-
|
|
45
|
-
method:
|
|
49
|
+
const res = await this.layout.database._apiRequestJSON(`${this.layout.endpoint}/records`, {
|
|
50
|
+
method: 'POST',
|
|
46
51
|
body: JSON.stringify(data)
|
|
47
52
|
});
|
|
48
53
|
if (!res.response) {
|
|
49
54
|
throw new FMError(res.messages[0].code, res.httpStatus, res);
|
|
50
55
|
}
|
|
51
|
-
else if (typeof res.response.scriptError !==
|
|
56
|
+
else if (typeof res.response.scriptError !== 'undefined' && res.response.scriptError !== '0') {
|
|
52
57
|
throw new FMError(res.response.scriptError, res.httpStatus, res);
|
|
53
58
|
}
|
|
54
|
-
else if (res.messages[0].code ===
|
|
59
|
+
else if (res.messages[0].code === '0') {
|
|
55
60
|
this.recordId = parseInt(res.response.recordId);
|
|
56
61
|
this.modId = parseInt(res.response.modId);
|
|
57
62
|
return this;
|
|
@@ -61,17 +66,17 @@ export class LayoutRecord extends RecordBase {
|
|
|
61
66
|
}
|
|
62
67
|
}
|
|
63
68
|
// for (let item of Object.keys(data)) extraBody[item] = data[item]
|
|
64
|
-
|
|
65
|
-
method:
|
|
69
|
+
const res = await this.layout.database._apiRequestJSON(this.endpoint, {
|
|
70
|
+
method: 'PATCH',
|
|
66
71
|
body: JSON.stringify(data)
|
|
67
72
|
});
|
|
68
73
|
if (!res.response) {
|
|
69
74
|
throw new FMError(res.messages[0].code, res.httpStatus, res);
|
|
70
75
|
}
|
|
71
|
-
else if (typeof res.response.scriptError !==
|
|
76
|
+
else if (typeof res.response.scriptError !== 'undefined' && res.response.scriptError !== '0') {
|
|
72
77
|
throw new FMError(res.response.scriptError, res.httpStatus, res);
|
|
73
78
|
}
|
|
74
|
-
else if (res.messages[0].code ===
|
|
79
|
+
else if (res.messages[0].code === '0') {
|
|
75
80
|
this.modId = +res.response.modId;
|
|
76
81
|
this._onSave();
|
|
77
82
|
return this;
|
|
@@ -81,29 +86,36 @@ export class LayoutRecord extends RecordBase {
|
|
|
81
86
|
}
|
|
82
87
|
}
|
|
83
88
|
processPortalData(portalData) {
|
|
84
|
-
for (
|
|
85
|
-
|
|
89
|
+
for (const portalName of Object.keys(portalData)) {
|
|
90
|
+
const _portal = new Portal(this, portalName);
|
|
86
91
|
_portal.records = portalData[portalName].map(item => {
|
|
87
|
-
|
|
92
|
+
const fieldData = item;
|
|
88
93
|
delete fieldData.recordId;
|
|
89
94
|
delete fieldData.modId;
|
|
90
95
|
return new PortalRecord(this, _portal, parseInt(item.recordId), parseInt(item.modId), fieldData);
|
|
91
96
|
});
|
|
92
|
-
// @ts-
|
|
97
|
+
// @ts-expect-error - This code is actually correct, but throws a typescript error
|
|
93
98
|
this.portals[portalName] = _portal;
|
|
94
99
|
}
|
|
95
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Re-fetches the current record from the database server.
|
|
103
|
+
* Throws an error if commit() has not been called.
|
|
104
|
+
*
|
|
105
|
+
* @return {Promise<this>} A Promise that resolves to this RecordBase instance if the record is successfully retrieved.
|
|
106
|
+
* @throws {Error} If commit() has not been called.
|
|
107
|
+
* @throws {FMError} If the retrieval fails.
|
|
108
|
+
*/
|
|
96
109
|
async get() {
|
|
97
|
-
let trace = new Error();
|
|
98
110
|
if (this.recordId === -1) {
|
|
99
|
-
throw
|
|
111
|
+
throw new Error('Cannot get this RecordBase until a commit() is done.');
|
|
100
112
|
}
|
|
101
113
|
if (!this.layout.metadata)
|
|
102
114
|
await this.layout.getLayoutMeta();
|
|
103
|
-
|
|
104
|
-
method:
|
|
115
|
+
const res = await this.layout.database._apiRequestJSON(this.endpoint, {
|
|
116
|
+
method: 'GET'
|
|
105
117
|
});
|
|
106
|
-
if (res.response && res.messages[0].code ===
|
|
118
|
+
if (res.response && res.messages[0].code === '0') {
|
|
107
119
|
// console.log(res, res.response.data)
|
|
108
120
|
this.modId = +res.response.data[0].modId;
|
|
109
121
|
this.processFieldData(res.response.data[0].fieldData);
|
|
@@ -117,20 +129,20 @@ export class LayoutRecord extends RecordBase {
|
|
|
117
129
|
}
|
|
118
130
|
}
|
|
119
131
|
async duplicate() {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
method:
|
|
132
|
+
const trace = new Error();
|
|
133
|
+
const res = await this.layout.database._apiRequestJSON(this.endpoint, {
|
|
134
|
+
method: 'POST'
|
|
123
135
|
});
|
|
124
136
|
if (!res.response) {
|
|
125
137
|
throw new FMError(res.messages[0].code, res.httpStatus, res, trace);
|
|
126
138
|
}
|
|
127
|
-
else if (typeof res.response.scriptError !==
|
|
139
|
+
else if (typeof res.response.scriptError !== 'undefined' && res.response.scriptError !== '0') {
|
|
128
140
|
throw new FMError(res.response.scriptError, res.httpStatus, res, trace);
|
|
129
141
|
}
|
|
130
|
-
else if (res.messages[0].code ===
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
this.emit(
|
|
142
|
+
else if (res.messages[0].code === '0') {
|
|
143
|
+
const data = this.toObject((a) => true, (a) => true, (a) => false, (a) => false);
|
|
144
|
+
const _res = new LayoutRecord(this.layout, res.response.recordId, res.response.modId, data.fieldData, data.portalData);
|
|
145
|
+
this.emit('duplicated');
|
|
134
146
|
return _res;
|
|
135
147
|
}
|
|
136
148
|
else {
|
|
@@ -138,37 +150,34 @@ export class LayoutRecord extends RecordBase {
|
|
|
138
150
|
}
|
|
139
151
|
}
|
|
140
152
|
async delete() {
|
|
141
|
-
|
|
142
|
-
method:
|
|
153
|
+
const res = await this.layout.database._apiRequestJSON(this.endpoint, {
|
|
154
|
+
method: 'DELETE'
|
|
143
155
|
});
|
|
144
156
|
console.log(res);
|
|
145
|
-
if (typeof res.response?.scriptError !==
|
|
157
|
+
if (typeof res.response?.scriptError !== 'undefined' && res.response?.scriptError !== '0') {
|
|
146
158
|
throw new FMError(res.response.scriptError, res.httpStatus, res);
|
|
147
159
|
}
|
|
148
|
-
else if (res.messages[0].code ===
|
|
149
|
-
this.emit(
|
|
150
|
-
return;
|
|
160
|
+
else if (res.messages[0].code === '0') {
|
|
161
|
+
this.emit('deleted');
|
|
151
162
|
}
|
|
152
163
|
else {
|
|
153
164
|
throw new FMError(res.messages[0].code, res.httpStatus, res);
|
|
154
165
|
}
|
|
155
166
|
}
|
|
156
167
|
fieldsToObject(filter = (a) => a.edited) {
|
|
157
|
-
|
|
168
|
+
const fields_processed = {};
|
|
158
169
|
let field;
|
|
159
170
|
for (field of this.fieldsArray.filter(field => filter(field))) {
|
|
160
171
|
let value = field.value;
|
|
161
172
|
if (value instanceof Date) {
|
|
162
|
-
// @ts-ignore
|
|
163
173
|
let _value = moment.default(value);
|
|
164
174
|
_value = _value
|
|
165
175
|
.utcOffset(this.layout.database.host.timezoneOffsetFunc(_value));
|
|
166
|
-
// @ts-ignore
|
|
167
176
|
switch (field.metadata.result) {
|
|
168
|
-
case
|
|
177
|
+
case 'time':
|
|
169
178
|
value = _value.format(this.layout.database.host.timeFormat);
|
|
170
179
|
break;
|
|
171
|
-
case
|
|
180
|
+
case 'date':
|
|
172
181
|
value = _value.format(this.layout.database.host.dateFormat);
|
|
173
182
|
break;
|
|
174
183
|
default:
|
|
@@ -177,25 +186,25 @@ export class LayoutRecord extends RecordBase {
|
|
|
177
186
|
}
|
|
178
187
|
fields_processed[field.id] = value;
|
|
179
188
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
189
|
+
const obj = {
|
|
190
|
+
recordId: this.recordId.toString(),
|
|
191
|
+
modId: this.modId.toString(),
|
|
192
|
+
fieldData: fields_processed
|
|
184
193
|
};
|
|
185
194
|
return obj;
|
|
186
195
|
}
|
|
187
196
|
toObject(filter = (a) => a.edited, portalFilter = (a) => a.records.find(record => record.edited), portalRowFilter = (a) => a.edited, portalFieldFilter = (a) => a.edited) {
|
|
188
|
-
|
|
197
|
+
const obj = {
|
|
189
198
|
...this.fieldsToObject(filter),
|
|
190
|
-
portalData: {}
|
|
199
|
+
portalData: {}
|
|
191
200
|
};
|
|
192
201
|
// Check if there's been any edited portal information
|
|
193
|
-
|
|
202
|
+
const portals = this.portalsArray.filter(a => portalFilter(a));
|
|
194
203
|
if (portals) {
|
|
195
|
-
obj
|
|
196
|
-
for (
|
|
197
|
-
// @ts-
|
|
198
|
-
obj
|
|
204
|
+
obj.portalData = {};
|
|
205
|
+
for (const portal of portals) {
|
|
206
|
+
// @ts-expect-error
|
|
207
|
+
obj.portalData[portal.name] = portal.records.filter(a => portalRowFilter(a)).map(record => {
|
|
199
208
|
return record.toObject(portalFieldFilter);
|
|
200
209
|
});
|
|
201
210
|
}
|
|
@@ -2,135 +2,146 @@
|
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {extraBodyOptions} from
|
|
6
|
-
import {RecordBase} from
|
|
7
|
-
import {PortalRecord} from
|
|
8
|
-
import {Portal} from
|
|
9
|
-
import {LayoutInterface} from
|
|
10
|
-
import {FMError} from
|
|
11
|
-
import {LayoutRecordBase} from
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
5
|
+
import {type extraBodyOptions} from '../types.js'
|
|
6
|
+
import {RecordBase} from './recordBase.js'
|
|
7
|
+
import {PortalRecord} from './portalRecord.js'
|
|
8
|
+
import {Portal} from './portal.js'
|
|
9
|
+
import {type LayoutInterface} from '../layouts/layoutInterface.js'
|
|
10
|
+
import {FMError} from '../FMError.js'
|
|
11
|
+
import {type LayoutRecordBase} from './layoutRecordBase.js'
|
|
12
|
+
import {
|
|
13
|
+
type ApiFieldData,
|
|
14
|
+
type ApiPortalData,
|
|
15
|
+
type ApiRecordResponseObj,
|
|
16
|
+
type ApiRowDataDef
|
|
17
|
+
} from '../models/apiResults.js'
|
|
18
|
+
import {type LayoutBase} from '../layouts/layoutBase.js'
|
|
19
|
+
import * as moment from 'moment/moment.js'
|
|
20
|
+
import {type Field, type FieldValue} from './field.js'
|
|
21
|
+
|
|
22
|
+
export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT['fields']> implements LayoutRecordBase {
|
|
23
|
+
portals: LAYOUT['portals'] = {}
|
|
24
|
+
private readonly portalsToInclude: Array<string | number | symbol>
|
|
25
|
+
|
|
26
|
+
constructor (
|
|
23
27
|
layout: LayoutBase,
|
|
24
28
|
recordId: number | string,
|
|
25
29
|
modId = recordId,
|
|
26
30
|
fieldData: Record<string, string | number> = {},
|
|
27
|
-
portalData: ApiPortalData | null = null, portalsToInclude:
|
|
28
|
-
|
|
29
|
-
super(layout, parseInt(recordId as string), parseInt(modId as string), fieldData);
|
|
31
|
+
portalData: ApiPortalData | null = null, portalsToInclude: Array<keyof LAYOUT['portals']> = []) {
|
|
32
|
+
super(layout, parseInt(recordId as string), parseInt(modId as string), fieldData)
|
|
30
33
|
this.portalsToInclude = portalsToInclude
|
|
31
34
|
if (portalData) {
|
|
32
35
|
this.processPortalData(portalData)
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
|
|
36
|
-
get portalsArray(): Portal<any
|
|
39
|
+
get portalsArray (): Array<Portal<any>> {
|
|
37
40
|
return Object.values(this.portals)
|
|
38
41
|
}
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Asynchronously commits the changes made to the current record.
|
|
45
|
+
* @param {extraBodyOptions} extraBody - The options for the extra body elements.
|
|
46
|
+
* @returns {Promise<this>} - A promise that resolves with the modified object.
|
|
47
|
+
* @throws {FMError} - If an error occurs during the commit process.
|
|
48
|
+
*/
|
|
49
|
+
async commit (extraBody: extraBodyOptions = {}): Promise<this> {
|
|
50
|
+
const data: any = this.toObject()
|
|
42
51
|
delete data.recordId
|
|
43
52
|
delete data.modId
|
|
44
53
|
|
|
45
54
|
if (extraBody.scripts?.after) {
|
|
46
|
-
data
|
|
47
|
-
if (extraBody.scripts.after.parameter) data[
|
|
55
|
+
data.script = extraBody.scripts.after.name
|
|
56
|
+
if (extraBody.scripts.after.parameter) data['script.param'] = extraBody.scripts.after.parameter
|
|
48
57
|
}
|
|
49
58
|
if (extraBody.scripts?.prerequest) {
|
|
50
|
-
data[
|
|
51
|
-
if (extraBody.scripts.prerequest.parameter) data[
|
|
59
|
+
data['script.prerequest'] = extraBody.scripts.prerequest.name
|
|
60
|
+
if (extraBody.scripts.prerequest.parameter) data['script.prerequest.param'] = extraBody.scripts.prerequest.parameter
|
|
52
61
|
}
|
|
53
62
|
if (extraBody.scripts?.presort) {
|
|
54
|
-
data[
|
|
55
|
-
if (extraBody.scripts.presort.parameter) data[
|
|
63
|
+
data['script.presort'] = extraBody.scripts.presort.name
|
|
64
|
+
if (extraBody.scripts.presort.parameter) data['script.presort.param'] = extraBody.scripts.presort.parameter
|
|
56
65
|
}
|
|
57
66
|
|
|
58
67
|
if (this.recordId === -1) {
|
|
59
68
|
// This is a new LayoutRecord
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
const res = await this.layout.database._apiRequestJSON<{ recordId: string, modId: string }>(`${this.layout.endpoint}/records`, {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
body: JSON.stringify(data)
|
|
72
|
+
})
|
|
64
73
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
else {
|
|
77
|
-
throw new FMError(res.messages[0].code, res.httpStatus, res)
|
|
78
|
-
}
|
|
74
|
+
if (!res.response) {
|
|
75
|
+
throw new FMError(res.messages[0].code, res.httpStatus, res)
|
|
76
|
+
} else if (typeof res.response.scriptError !== 'undefined' && res.response.scriptError !== '0') {
|
|
77
|
+
throw new FMError(res.response.scriptError, res.httpStatus, res)
|
|
78
|
+
} else if (res.messages[0].code === '0') {
|
|
79
|
+
this.recordId = parseInt(res.response.recordId)
|
|
80
|
+
this.modId = parseInt(res.response.modId)
|
|
81
|
+
return this
|
|
82
|
+
} else {
|
|
83
|
+
throw new FMError(res.messages[0].code, res.httpStatus, res)
|
|
84
|
+
}
|
|
79
85
|
}
|
|
80
86
|
|
|
81
87
|
// for (let item of Object.keys(data)) extraBody[item] = data[item]
|
|
82
|
-
|
|
83
|
-
modId: string,
|
|
84
|
-
|
|
85
|
-
|
|
88
|
+
const res = await this.layout.database._apiRequestJSON<{
|
|
89
|
+
modId: string,
|
|
90
|
+
newPortalRecordInfo: Array<{
|
|
91
|
+
tableName: string
|
|
92
|
+
recordId: string
|
|
86
93
|
modId: string
|
|
87
|
-
}
|
|
94
|
+
}>
|
|
88
95
|
}>(this.endpoint, {
|
|
89
|
-
method:
|
|
96
|
+
method: 'PATCH',
|
|
90
97
|
body: JSON.stringify(data)
|
|
91
98
|
})
|
|
92
99
|
if (!res.response) {
|
|
93
100
|
throw new FMError(res.messages[0].code, res.httpStatus, res)
|
|
94
|
-
}
|
|
95
|
-
else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
|
|
101
|
+
} else if (typeof res.response.scriptError !== 'undefined' && res.response.scriptError !== '0') {
|
|
96
102
|
throw new FMError(res.response.scriptError, res.httpStatus, res)
|
|
97
|
-
}
|
|
98
|
-
else if (res.messages[0].code === "0") {
|
|
103
|
+
} else if (res.messages[0].code === '0') {
|
|
99
104
|
this.modId = +res.response.modId
|
|
100
105
|
this._onSave()
|
|
101
106
|
return this
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
107
|
+
} else {
|
|
104
108
|
throw new FMError(res.messages[0].code, res.httpStatus, res)
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
|
|
108
|
-
protected processPortalData(portalData: ApiPortalData): void {
|
|
109
|
-
for (
|
|
110
|
-
|
|
112
|
+
protected processPortalData (portalData: ApiPortalData): void {
|
|
113
|
+
for (const portalName of Object.keys(portalData)) {
|
|
114
|
+
const _portal = new Portal(this, portalName)
|
|
111
115
|
_portal.records = portalData[portalName].map(item => {
|
|
112
|
-
|
|
113
|
-
delete fieldData.recordId
|
|
114
|
-
delete fieldData.modId
|
|
115
|
-
return new PortalRecord(this, _portal, parseInt(item.recordId as string), parseInt(item.modId as string), fieldData)
|
|
116
|
+
const fieldData = item
|
|
117
|
+
delete fieldData.recordId
|
|
118
|
+
delete fieldData.modId
|
|
119
|
+
return new PortalRecord(this, _portal, parseInt(item.recordId as string), parseInt(item.modId as string), fieldData)
|
|
116
120
|
})
|
|
117
121
|
|
|
118
|
-
// @ts-
|
|
119
|
-
this.portals[portalName] = _portal
|
|
122
|
+
// @ts-expect-error - This code is actually correct, but throws a typescript error
|
|
123
|
+
this.portals[portalName] = _portal
|
|
120
124
|
}
|
|
121
125
|
}
|
|
122
126
|
|
|
123
|
-
|
|
124
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Re-fetches the current record from the database server.
|
|
129
|
+
* Throws an error if commit() has not been called.
|
|
130
|
+
*
|
|
131
|
+
* @return {Promise<this>} A Promise that resolves to this RecordBase instance if the record is successfully retrieved.
|
|
132
|
+
* @throws {Error} If commit() has not been called.
|
|
133
|
+
* @throws {FMError} If the retrieval fails.
|
|
134
|
+
*/
|
|
135
|
+
async get (): Promise<this> {
|
|
125
136
|
if (this.recordId === -1) {
|
|
126
|
-
throw
|
|
137
|
+
throw new Error('Cannot get this RecordBase until a commit() is done.')
|
|
127
138
|
}
|
|
128
139
|
if (!this.layout.metadata) await this.layout.getLayoutMeta()
|
|
129
|
-
|
|
130
|
-
method:
|
|
140
|
+
const res = await this.layout.database._apiRequestJSON<ApiRecordResponseObj>(this.endpoint, {
|
|
141
|
+
method: 'GET'
|
|
131
142
|
})
|
|
132
143
|
|
|
133
|
-
if (res.response && res.messages[0].code ===
|
|
144
|
+
if (res.response && res.messages[0].code === '0') {
|
|
134
145
|
// console.log(res, res.response.data)
|
|
135
146
|
this.modId = +res.response.data[0].modId
|
|
136
147
|
this.processFieldData(res.response.data[0].fieldData)
|
|
@@ -142,64 +153,55 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
|
|
|
142
153
|
}
|
|
143
154
|
}
|
|
144
155
|
|
|
145
|
-
async duplicate(): Promise<LayoutRecord<LAYOUT>> {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
method:
|
|
156
|
+
async duplicate (): Promise<LayoutRecord<LAYOUT>> {
|
|
157
|
+
const trace = new Error()
|
|
158
|
+
const res = await this.layout.database._apiRequestJSON<{ recordId: string, modId: string }>(this.endpoint, {
|
|
159
|
+
method: 'POST'
|
|
149
160
|
})
|
|
150
161
|
if (!res.response) {
|
|
151
162
|
throw new FMError(res.messages[0].code, res.httpStatus, res, trace)
|
|
152
|
-
}
|
|
153
|
-
else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
|
|
163
|
+
} else if (typeof res.response.scriptError !== 'undefined' && res.response.scriptError !== '0') {
|
|
154
164
|
throw new FMError(res.response.scriptError, res.httpStatus, res, trace)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
let _res = new LayoutRecord<LAYOUT>(this.layout, res.response.recordId, res.response.modId, data.fieldData, data.portalData)
|
|
165
|
+
} else if (res.messages[0].code === '0') {
|
|
166
|
+
const data = this.toObject((a) => true, (a) => true, (a) => false, (a) => false)
|
|
167
|
+
const _res = new LayoutRecord<LAYOUT>(this.layout, res.response.recordId, res.response.modId, data.fieldData, data.portalData)
|
|
159
168
|
|
|
160
|
-
this.emit(
|
|
169
|
+
this.emit('duplicated')
|
|
161
170
|
return _res
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
171
|
+
} else {
|
|
164
172
|
throw new FMError(res.messages[0].code, res.httpStatus, res, trace)
|
|
165
173
|
}
|
|
166
174
|
}
|
|
167
175
|
|
|
168
|
-
async delete(): Promise<void> {
|
|
169
|
-
|
|
170
|
-
method:
|
|
176
|
+
async delete (): Promise<void> {
|
|
177
|
+
const res = await this.layout.database._apiRequestJSON(this.endpoint, {
|
|
178
|
+
method: 'DELETE'
|
|
171
179
|
})
|
|
172
180
|
console.log(res)
|
|
173
|
-
if (typeof res.response?.scriptError !==
|
|
181
|
+
if (typeof res.response?.scriptError !== 'undefined' && res.response?.scriptError !== '0') {
|
|
174
182
|
throw new FMError(res.response.scriptError, res.httpStatus, res)
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
return
|
|
179
|
-
}
|
|
180
|
-
else {
|
|
183
|
+
} else if (res.messages[0].code === '0') {
|
|
184
|
+
this.emit('deleted')
|
|
185
|
+
} else {
|
|
181
186
|
throw new FMError(res.messages[0].code, res.httpStatus, res)
|
|
182
187
|
}
|
|
183
188
|
}
|
|
184
189
|
|
|
185
|
-
fieldsToObject(filter = (a: Field<FieldValue>) => a.edited): Omit<ApiRowDataDef,
|
|
186
|
-
|
|
190
|
+
fieldsToObject (filter = (a: Field<FieldValue>) => a.edited): Omit<ApiRowDataDef, 'portalData'> {
|
|
191
|
+
const fields_processed: ApiFieldData = {}
|
|
187
192
|
let field: Field<FieldValue>
|
|
188
193
|
for (field of this.fieldsArray.filter(field => filter(field))) {
|
|
189
194
|
let value = field.value as string | number | Date
|
|
190
195
|
if (value instanceof Date) {
|
|
191
|
-
// @ts-ignore
|
|
192
196
|
let _value = moment.default(value)
|
|
193
197
|
_value = _value
|
|
194
198
|
.utcOffset(this.layout.database.host.timezoneOffsetFunc(_value))
|
|
195
199
|
|
|
196
|
-
// @ts-ignore
|
|
197
|
-
|
|
198
200
|
switch (field.metadata.result) {
|
|
199
|
-
case
|
|
201
|
+
case 'time':
|
|
200
202
|
value = _value.format(this.layout.database.host.timeFormat)
|
|
201
203
|
break
|
|
202
|
-
case
|
|
204
|
+
case 'date':
|
|
203
205
|
value = _value.format(this.layout.database.host.dateFormat)
|
|
204
206
|
break
|
|
205
207
|
default:
|
|
@@ -208,32 +210,32 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
|
|
|
208
210
|
}
|
|
209
211
|
fields_processed[field.id] = value
|
|
210
212
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
213
|
+
const obj = {
|
|
214
|
+
recordId: this.recordId.toString(),
|
|
215
|
+
modId: this.modId.toString(),
|
|
216
|
+
fieldData: fields_processed
|
|
215
217
|
}
|
|
216
218
|
return obj
|
|
217
219
|
}
|
|
218
220
|
|
|
219
|
-
toObject(
|
|
221
|
+
toObject (
|
|
220
222
|
filter: (a: Field<FieldValue>) => any = (a) => a.edited,
|
|
221
223
|
portalFilter: (a: Portal<any>) => any = (a) => a.records.find(record => record.edited),
|
|
222
224
|
portalRowFilter: (a: PortalRecord<never>) => any = (a) => a.edited,
|
|
223
225
|
portalFieldFilter: (a: Field<FieldValue>) => any = (a) => a.edited
|
|
224
226
|
) {
|
|
225
|
-
|
|
227
|
+
const obj: ApiRowDataDef = {
|
|
226
228
|
...this.fieldsToObject(filter),
|
|
227
|
-
portalData: {}
|
|
228
|
-
}
|
|
229
|
+
portalData: {}
|
|
230
|
+
}
|
|
229
231
|
|
|
230
232
|
// Check if there's been any edited portal information
|
|
231
|
-
|
|
233
|
+
const portals = this.portalsArray.filter(a => portalFilter(a))
|
|
232
234
|
if (portals) {
|
|
233
|
-
obj
|
|
234
|
-
for (
|
|
235
|
-
// @ts-
|
|
236
|
-
obj
|
|
235
|
+
obj.portalData = {}
|
|
236
|
+
for (const portal of portals) {
|
|
237
|
+
// @ts-expect-error
|
|
238
|
+
obj.portalData[portal.name] = portal.records.filter(a => portalRowFilter(a)).map(record => {
|
|
237
239
|
return record.toObject(portalFieldFilter)
|
|
238
240
|
})
|
|
239
241
|
}
|
|
@@ -241,4 +243,4 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
|
|
|
241
243
|
|
|
242
244
|
return obj
|
|
243
245
|
}
|
|
244
|
-
}
|
|
246
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { LayoutBase } from
|
|
1
|
+
import { type LayoutBase } from '../layouts/layoutBase.js';
|
|
2
2
|
export interface LayoutRecordBase {
|
|
3
3
|
layout: LayoutBase;
|
|
4
|
-
commit(extraBody: object)
|
|
4
|
+
commit: (extraBody: object) => Promise<this>;
|
|
5
5
|
}
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Copyright (c) 2023. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {LayoutBase} from
|
|
5
|
+
import {type LayoutBase} from '../layouts/layoutBase.js'
|
|
6
6
|
|
|
7
7
|
export interface LayoutRecordBase {
|
|
8
8
|
layout: LayoutBase
|
|
9
|
-
commit(extraBody: object)
|
|
10
|
-
}
|
|
9
|
+
commit: (extraBody: object) => Promise<this>
|
|
10
|
+
}
|