@jd-data-limited/easy-fm 4.0.14 → 4.1.0
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 +12 -6
- package/src/FMError.d.ts +2 -2
- package/src/FMError.js +507 -508
- package/src/FMError.ts +510 -511
- package/src/bin/cli.js +7 -5
- package/src/bin/generateTypes.js +215 -121
- package/src/connection/FMHost.d.ts +28 -6
- package/src/connection/FMHost.js +52 -25
- package/src/connection/FMHost.ts +75 -43
- package/src/connection/HostBase.d.ts +7 -3
- package/src/connection/HostBase.ts +8 -4
- package/src/connection/database.d.ts +50 -17
- package/src/connection/database.js +94 -66
- package/src/connection/database.ts +125 -105
- package/src/connection/databaseBase.d.ts +11 -6
- package/src/connection/databaseBase.ts +9 -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 +14 -14
- package/src/index.ts +28 -25
- 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 +42 -12
- package/src/records/field.js +69 -59
- package/src/records/field.ts +102 -81
- package/src/records/getOperations/recordGetOperation.d.ts +44 -24
- package/src/records/getOperations/recordGetOperation.js +89 -58
- package/src/records/getOperations/recordGetOperation.ts +137 -108
- package/src/records/layoutRecord.d.ts +28 -14
- package/src/records/layoutRecord.js +75 -65
- package/src/records/layoutRecord.ts +126 -123
- 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 +17 -7
- package/src/records/recordBase.js +32 -22
- package/src/records/recordBase.ts +50 -43
- package/src/types.d.ts +21 -24
- package/src/types.ts +55 -59
- package/src/utils/query.d.ts +12 -5
- package/src/utils/query.js +28 -9
- package/src/utils/query.ts +40 -15
|
@@ -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,63 +150,61 @@ 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
|
-
|
|
163
|
-
|
|
164
|
-
.utcOffset(this.layout.database.host.
|
|
165
|
-
// @ts-ignore
|
|
173
|
+
let _value = moment.default(value);
|
|
174
|
+
_value = _value
|
|
175
|
+
.utcOffset(this.layout.database.host.timezoneOffsetFunc(_value));
|
|
166
176
|
switch (field.metadata.result) {
|
|
167
|
-
case
|
|
168
|
-
value = _value.format(this.layout.database.host.
|
|
177
|
+
case 'time':
|
|
178
|
+
value = _value.format(this.layout.database.host.timeFormat);
|
|
169
179
|
break;
|
|
170
|
-
case
|
|
171
|
-
value = _value.format(this.layout.database.host.
|
|
180
|
+
case 'date':
|
|
181
|
+
value = _value.format(this.layout.database.host.dateFormat);
|
|
172
182
|
break;
|
|
173
183
|
default:
|
|
174
|
-
value = _value.format(this.layout.database.host.
|
|
184
|
+
value = _value.format(this.layout.database.host.timeStampFormat);
|
|
175
185
|
}
|
|
176
186
|
}
|
|
177
187
|
fields_processed[field.id] = value;
|
|
178
188
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
189
|
+
const obj = {
|
|
190
|
+
recordId: this.recordId.toString(),
|
|
191
|
+
modId: this.modId.toString(),
|
|
192
|
+
fieldData: fields_processed
|
|
183
193
|
};
|
|
184
194
|
return obj;
|
|
185
195
|
}
|
|
186
196
|
toObject(filter = (a) => a.edited, portalFilter = (a) => a.records.find(record => record.edited), portalRowFilter = (a) => a.edited, portalFieldFilter = (a) => a.edited) {
|
|
187
|
-
|
|
197
|
+
const obj = {
|
|
188
198
|
...this.fieldsToObject(filter),
|
|
189
|
-
portalData: {}
|
|
199
|
+
portalData: {}
|
|
190
200
|
};
|
|
191
201
|
// Check if there's been any edited portal information
|
|
192
|
-
|
|
202
|
+
const portals = this.portalsArray.filter(a => portalFilter(a));
|
|
193
203
|
if (portals) {
|
|
194
|
-
obj
|
|
195
|
-
for (
|
|
196
|
-
// @ts-
|
|
197
|
-
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 => {
|
|
198
208
|
return record.toObject(portalFieldFilter);
|
|
199
209
|
});
|
|
200
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,97 +153,89 @@ 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
|
-
|
|
194
|
-
|
|
195
|
-
// @ts-ignore
|
|
197
|
+
_value = _value
|
|
198
|
+
.utcOffset(this.layout.database.host.timezoneOffsetFunc(_value))
|
|
196
199
|
|
|
197
200
|
switch (field.metadata.result) {
|
|
198
|
-
case
|
|
199
|
-
value = _value.format(this.layout.database.host.
|
|
201
|
+
case 'time':
|
|
202
|
+
value = _value.format(this.layout.database.host.timeFormat)
|
|
200
203
|
break
|
|
201
|
-
case
|
|
202
|
-
value = _value.format(this.layout.database.host.
|
|
204
|
+
case 'date':
|
|
205
|
+
value = _value.format(this.layout.database.host.dateFormat)
|
|
203
206
|
break
|
|
204
207
|
default:
|
|
205
|
-
value = _value.format(this.layout.database.host.
|
|
208
|
+
value = _value.format(this.layout.database.host.timeStampFormat)
|
|
206
209
|
}
|
|
207
210
|
}
|
|
208
211
|
fields_processed[field.id] = value
|
|
209
212
|
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
213
|
+
const obj = {
|
|
214
|
+
recordId: this.recordId.toString(),
|
|
215
|
+
modId: this.modId.toString(),
|
|
216
|
+
fieldData: fields_processed
|
|
214
217
|
}
|
|
215
218
|
return obj
|
|
216
219
|
}
|
|
217
220
|
|
|
218
|
-
toObject(
|
|
221
|
+
toObject (
|
|
219
222
|
filter: (a: Field<FieldValue>) => any = (a) => a.edited,
|
|
220
223
|
portalFilter: (a: Portal<any>) => any = (a) => a.records.find(record => record.edited),
|
|
221
224
|
portalRowFilter: (a: PortalRecord<never>) => any = (a) => a.edited,
|
|
222
225
|
portalFieldFilter: (a: Field<FieldValue>) => any = (a) => a.edited
|
|
223
226
|
) {
|
|
224
|
-
|
|
227
|
+
const obj: ApiRowDataDef = {
|
|
225
228
|
...this.fieldsToObject(filter),
|
|
226
|
-
portalData: {}
|
|
227
|
-
}
|
|
229
|
+
portalData: {}
|
|
230
|
+
}
|
|
228
231
|
|
|
229
232
|
// Check if there's been any edited portal information
|
|
230
|
-
|
|
233
|
+
const portals = this.portalsArray.filter(a => portalFilter(a))
|
|
231
234
|
if (portals) {
|
|
232
|
-
obj
|
|
233
|
-
for (
|
|
234
|
-
// @ts-
|
|
235
|
-
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 => {
|
|
236
239
|
return record.toObject(portalFieldFilter)
|
|
237
240
|
})
|
|
238
241
|
}
|
|
@@ -240,4 +243,4 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
|
|
|
240
243
|
|
|
241
244
|
return obj
|
|
242
245
|
}
|
|
243
|
-
}
|
|
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
|
}
|