@jd-data-limited/easy-fm 4.0.4 → 4.0.7

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.
Files changed (53) hide show
  1. package/package.json +7 -2
  2. package/src/FMError.d.ts +0 -1
  3. package/src/FMError.js +0 -1
  4. package/src/FMError.ts +0 -1
  5. package/src/bin/cli.d.ts +2 -0
  6. package/src/bin/cli.js +19 -0
  7. package/src/bin/cli.ts +22 -0
  8. package/src/bin/example.xml +0 -0
  9. package/src/bin/generateTypes.d.ts +1 -0
  10. package/src/bin/generateTypes.js +250 -0
  11. package/src/bin/generateTypes.ts +186 -0
  12. package/src/connection/FMHost.js +12 -3
  13. package/src/connection/FMHost.ts +12 -3
  14. package/src/connection/database.d.ts +2 -1
  15. package/src/connection/database.js +10 -6
  16. package/src/connection/database.ts +11 -7
  17. package/src/connection/databaseBase.d.ts +2 -1
  18. package/src/connection/databaseBase.ts +2 -1
  19. package/src/index.d.ts +2 -1
  20. package/src/index.js +2 -1
  21. package/src/index.ts +4 -1
  22. package/src/layouts/layout.d.ts +1 -1
  23. package/src/layouts/layout.js +9 -5
  24. package/src/layouts/layout.ts +7 -5
  25. package/src/layouts/layoutRecordManager.js +3 -3
  26. package/src/layouts/layoutRecordManager.ts +3 -3
  27. package/src/models/apiResults.d.ts +1 -1
  28. package/src/models/apiResults.ts +1 -1
  29. package/src/records/fieldBase.js +3 -1
  30. package/src/records/fieldBase.ts +2 -1
  31. package/src/records/getOperations/recordGetOperation.d.ts +2 -1
  32. package/src/records/getOperations/recordGetOperation.js +33 -26
  33. package/src/records/getOperations/recordGetOperation.ts +39 -33
  34. package/src/records/layoutRecord.d.ts +3 -2
  35. package/src/records/layoutRecord.js +58 -18
  36. package/src/records/layoutRecord.ts +61 -19
  37. package/src/records/portal.d.ts +1 -1
  38. package/src/records/portal.js +3 -3
  39. package/src/records/portal.ts +3 -3
  40. package/src/records/portalRecord.d.ts +3 -2
  41. package/src/records/portalRecord.js +2 -4
  42. package/src/records/portalRecord.ts +7 -11
  43. package/src/records/recordBase.d.ts +3 -4
  44. package/src/records/recordBase.js +3 -32
  45. package/src/records/recordBase.ts +5 -37
  46. package/src/utils/fmQuery.d.ts +4 -0
  47. package/src/utils/fmQuery.js +20 -0
  48. package/src/utils/query.d.ts +4 -0
  49. package/src/utils/query.js +20 -0
  50. package/src/utils/query.ts +25 -0
  51. package/src/records/field.d.ts +0 -5
  52. package/src/records/field.js +0 -7
  53. package/src/records/field.ts +0 -10
@@ -5,13 +5,13 @@ import { RecordBase } from "./recordBase.js";
5
5
  import { PortalRecord } from "./portalRecord.js";
6
6
  import { Portal } from "./portal.js";
7
7
  import { FMError } from "../FMError.js";
8
+ import * as moment from "moment/moment.js";
8
9
  export class LayoutRecord extends RecordBase {
9
10
  // @ts-ignore
10
11
  portals = {};
11
12
  portalsToInclude;
12
13
  constructor(layout, recordId, modId = recordId, fieldData = {}, portalData = null, portalsToInclude = []) {
13
- super(layout, parseInt(recordId), parseInt(modId));
14
- this.processFieldData(fieldData);
14
+ super(layout, parseInt(recordId), parseInt(modId), fieldData);
15
15
  this.portalsToInclude = portalsToInclude;
16
16
  if (portalData) {
17
17
  this.processPortalData(portalData);
@@ -30,7 +30,7 @@ export class LayoutRecord extends RecordBase {
30
30
  data["script.param"] = extraBody.scripts.after.parameter;
31
31
  }
32
32
  if (extraBody.scripts?.prerequest) {
33
- data["script.prerequest"] = extraBody.scripts.after.name;
33
+ data["script.prerequest"] = extraBody.scripts.prerequest.name;
34
34
  if (extraBody.scripts.prerequest.parameter)
35
35
  data["script.prerequest.param"] = extraBody.scripts.prerequest.parameter;
36
36
  }
@@ -41,12 +41,14 @@ export class LayoutRecord extends RecordBase {
41
41
  }
42
42
  if (this.recordId === -1) {
43
43
  // This is a new LayoutRecord
44
- let res = await this.layout.database.apiRequest(`${this.layout.endpoint}/records`, {
45
- port: 443,
44
+ let res = await this.layout.database.apiRequestJSON(`${this.layout.endpoint}/records`, {
46
45
  method: "POST",
47
46
  body: JSON.stringify(data)
48
47
  });
49
- if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
48
+ if (!res.response) {
49
+ throw new FMError(res.messages[0].code, res.httpStatus, res);
50
+ }
51
+ else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
50
52
  throw new FMError(res.response.scriptError, res.httpStatus, res);
51
53
  }
52
54
  else if (res.messages[0].code === "0") {
@@ -59,12 +61,14 @@ export class LayoutRecord extends RecordBase {
59
61
  }
60
62
  }
61
63
  // for (let item of Object.keys(data)) extraBody[item] = data[item]
62
- let res = await this.layout.database.apiRequest(this.endpoint, {
63
- port: 443,
64
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
64
65
  method: "PATCH",
65
66
  body: JSON.stringify(data)
66
67
  });
67
- if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
68
+ if (!res.response) {
69
+ throw new FMError(res.messages[0].code, res.httpStatus, res);
70
+ }
71
+ else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
68
72
  throw new FMError(res.response.scriptError, res.httpStatus, res);
69
73
  }
70
74
  else if (res.messages[0].code === "0") {
@@ -96,11 +100,10 @@ export class LayoutRecord extends RecordBase {
96
100
  }
97
101
  if (!this.layout.metadata)
98
102
  await this.layout.getLayoutMeta();
99
- let res = await this.layout.database.apiRequest(this.endpoint, {
100
- port: 443,
103
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
101
104
  method: "GET"
102
105
  });
103
- if (res.messages[0].code === "0") {
106
+ if (res.response && res.messages[0].code === "0") {
104
107
  // console.log(res, res.response.data)
105
108
  this.modId = +res.response.data[0].modId;
106
109
  this.processFieldData(res.response.data[0].fieldData);
@@ -109,14 +112,19 @@ export class LayoutRecord extends RecordBase {
109
112
  this.processPortalData(res.response.data[0].portalData);
110
113
  return this;
111
114
  }
115
+ else {
116
+ throw new FMError(res.messages[0].code, res.httpStatus, res);
117
+ }
112
118
  }
113
119
  async duplicate() {
114
120
  let trace = new Error();
115
- let res = await this.layout.database.apiRequest(this.endpoint, {
116
- port: 443,
121
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
117
122
  method: "POST"
118
123
  });
119
- if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
124
+ if (!res.response) {
125
+ throw new FMError(res.messages[0].code, res.httpStatus, res, trace);
126
+ }
127
+ else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
120
128
  throw new FMError(res.response.scriptError, res.httpStatus, res, trace);
121
129
  }
122
130
  else if (res.messages[0].code === "0") {
@@ -130,8 +138,7 @@ export class LayoutRecord extends RecordBase {
130
138
  }
131
139
  }
132
140
  async delete() {
133
- let res = await this.layout.database.apiRequest(this.endpoint, {
134
- port: 443,
141
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
135
142
  method: "DELETE"
136
143
  });
137
144
  console.log(res);
@@ -146,8 +153,41 @@ export class LayoutRecord extends RecordBase {
146
153
  throw new FMError(res.messages[0].code, res.httpStatus, res);
147
154
  }
148
155
  }
156
+ fieldsToObject(filter = (a) => a.edited) {
157
+ let fields_processed = {};
158
+ let field;
159
+ for (field of this.fieldsArray.filter(field => filter(field))) {
160
+ let value = field.value;
161
+ if (value instanceof Date) {
162
+ // @ts-ignore
163
+ let _value = moment.default(value)
164
+ .utcOffset(this.layout.database.host.timezoneOffset);
165
+ // @ts-ignore
166
+ switch (field.metadata.result) {
167
+ case "time":
168
+ value = _value.format(this.layout.database.host.metadata.productInfo.timeFormat.replace("dd", "DD"));
169
+ break;
170
+ case "date":
171
+ value = _value.format(this.layout.database.host.metadata.productInfo.dateFormat.replace("dd", "DD"));
172
+ break;
173
+ default:
174
+ value = _value.format(this.layout.database.host.metadata.productInfo.timeStampFormat.replace("dd", "DD"));
175
+ }
176
+ }
177
+ fields_processed[field.id] = value;
178
+ }
179
+ let obj = {
180
+ "recordId": this.recordId.toString(),
181
+ "modId": this.modId.toString(),
182
+ "fieldData": fields_processed
183
+ };
184
+ return obj;
185
+ }
149
186
  toObject(filter = (a) => a.edited, portalFilter = (a) => a.records.find(record => record.edited), portalRowFilter = (a) => a.edited, portalFieldFilter = (a) => a.edited) {
150
- let obj = super.toObject(filter);
187
+ let obj = {
188
+ ...this.fieldsToObject(filter),
189
+ portalData: {}
190
+ };
151
191
  // Check if there's been any edited portal information
152
192
  let portals = this.portalsArray.filter(a => portalFilter(a));
153
193
  if (portals) {
@@ -9,9 +9,10 @@ import {Portal} from "./portal.js";
9
9
  import {LayoutInterface} from "../layouts/layoutInterface.js";
10
10
  import {FMError} from "../FMError.js";
11
11
  import {LayoutRecordBase} from "./layoutRecordBase.js";
12
- import {ApiPortalData, ApiRecordResponseObj} from "../models/apiResults.js";
12
+ import {ApiFieldData, ApiPortalData, ApiRecordResponseObj, ApiRowDataDef} from "../models/apiResults.js";
13
13
  import {LayoutBase} from "../layouts/layoutBase.js"
14
14
  import {FieldBase, FieldValue} from "./fieldBase.js";
15
+ import * as moment from "moment/moment.js";
15
16
 
16
17
  export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
17
18
  // @ts-ignore
@@ -25,8 +26,7 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
25
26
  fieldData: Record<string, string | number> = {},
26
27
  portalData: ApiPortalData | null = null, portalsToInclude: (keyof LAYOUT["portals"])[] = [])
27
28
  {
28
- super(layout, parseInt(recordId as string), parseInt(modId as string));
29
- this.processFieldData(fieldData)
29
+ super(layout, parseInt(recordId as string), parseInt(modId as string), fieldData);
30
30
  this.portalsToInclude = portalsToInclude
31
31
  if (portalData) {
32
32
  this.processPortalData(portalData)
@@ -47,7 +47,7 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
47
47
  if (extraBody.scripts.after.parameter) data["script.param"] = extraBody.scripts.after.parameter
48
48
  }
49
49
  if (extraBody.scripts?.prerequest) {
50
- data["script.prerequest"] = extraBody.scripts.after.name
50
+ data["script.prerequest"] = extraBody.scripts.prerequest.name
51
51
  if (extraBody.scripts.prerequest.parameter) data["script.prerequest.param"] = extraBody.scripts.prerequest.parameter
52
52
  }
53
53
  if (extraBody.scripts?.presort) {
@@ -57,13 +57,15 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
57
57
 
58
58
  if (this.recordId === -1) {
59
59
  // This is a new LayoutRecord
60
- let res = await this.layout.database.apiRequest<{ recordId: string, modId: string }>(`${this.layout.endpoint}/records`, {
61
- port: 443,
60
+ let res = await this.layout.database.apiRequestJSON<{ recordId: string, modId: string }>(`${this.layout.endpoint}/records`, {
62
61
  method: "POST",
63
62
  body: JSON.stringify(data)
64
63
  })
65
64
 
66
- if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
65
+ if (!res.response) {
66
+ throw new FMError(res.messages[0].code, res.httpStatus, res)
67
+ }
68
+ else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
67
69
  throw new FMError(res.response.scriptError, res.httpStatus, res)
68
70
  }
69
71
  else if (res.messages[0].code === "0") {
@@ -77,18 +79,20 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
77
79
  }
78
80
 
79
81
  // for (let item of Object.keys(data)) extraBody[item] = data[item]
80
- let res = await this.layout.database.apiRequest<{
82
+ let res = await this.layout.database.apiRequestJSON<{
81
83
  modId: string, newPortalRecordInfo: {
82
84
  tableName: string,
83
85
  recordId: string,
84
86
  modId: string
85
87
  }[]
86
88
  }>(this.endpoint, {
87
- port: 443,
88
89
  method: "PATCH",
89
90
  body: JSON.stringify(data)
90
91
  })
91
- if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
92
+ if (!res.response) {
93
+ throw new FMError(res.messages[0].code, res.httpStatus, res)
94
+ }
95
+ else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
92
96
  throw new FMError(res.response.scriptError, res.httpStatus, res)
93
97
  }
94
98
  else if (res.messages[0].code === "0") {
@@ -122,28 +126,31 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
122
126
  throw "Cannot get this RecordBase until a commit() is done."
123
127
  }
124
128
  if (!this.layout.metadata) await this.layout.getLayoutMeta()
125
- let res = await this.layout.database.apiRequest<ApiRecordResponseObj>(this.endpoint, {
126
- port: 443,
129
+ let res = await this.layout.database.apiRequestJSON<ApiRecordResponseObj>(this.endpoint, {
127
130
  method: "GET"
128
131
  })
129
132
 
130
- if (res.messages[0].code === "0") {
133
+ if (res.response && res.messages[0].code === "0") {
131
134
  // console.log(res, res.response.data)
132
135
  this.modId = +res.response.data[0].modId
133
136
  this.processFieldData(res.response.data[0].fieldData)
134
137
  this.portalData = []
135
138
  if (res.response.data[0].portalData) this.processPortalData(res.response.data[0].portalData)
136
139
  return this
140
+ } else {
141
+ throw new FMError(res.messages[0].code, res.httpStatus, res)
137
142
  }
138
143
  }
139
144
 
140
145
  async duplicate(): Promise<LayoutRecord<LAYOUT>> {
141
146
  let trace = new Error()
142
- let res = await this.layout.database.apiRequest<{recordId: string, modId: string}>(this.endpoint, {
143
- port: 443,
147
+ let res = await this.layout.database.apiRequestJSON<{recordId: string, modId: string}>(this.endpoint, {
144
148
  method: "POST"
145
149
  })
146
- if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
150
+ if (!res.response) {
151
+ throw new FMError(res.messages[0].code, res.httpStatus, res, trace)
152
+ }
153
+ else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
147
154
  throw new FMError(res.response.scriptError, res.httpStatus, res, trace)
148
155
  }
149
156
  else if (res.messages[0].code === "0") {
@@ -159,8 +166,7 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
159
166
  }
160
167
 
161
168
  async delete(): Promise<void> {
162
- let res = await this.layout.database.apiRequest(this.endpoint, {
163
- port: 443,
169
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
164
170
  method: "DELETE"
165
171
  })
166
172
  console.log(res)
@@ -176,13 +182,49 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
176
182
  }
177
183
  }
178
184
 
185
+ fieldsToObject(filter = (a: FieldBase<FieldValue>) => a.edited): Omit<ApiRowDataDef, "portalData"> {
186
+ let fields_processed: ApiFieldData = {}
187
+ let field: FieldBase<FieldValue>
188
+ for (field of this.fieldsArray.filter(field => filter(field))) {
189
+ let value = field.value as string | number | Date
190
+ if (value instanceof Date) {
191
+ // @ts-ignore
192
+ let _value = moment.default(value)
193
+ .utcOffset(this.layout.database.host.timezoneOffset)
194
+
195
+ // @ts-ignore
196
+
197
+ switch (field.metadata.result) {
198
+ case "time":
199
+ value = _value.format(this.layout.database.host.metadata.productInfo.timeFormat.replace("dd", "DD"))
200
+ break
201
+ case "date":
202
+ value = _value.format(this.layout.database.host.metadata.productInfo.dateFormat.replace("dd", "DD"))
203
+ break
204
+ default:
205
+ value = _value.format(this.layout.database.host.metadata.productInfo.timeStampFormat.replace("dd", "DD"))
206
+ }
207
+ }
208
+ fields_processed[field.id] = value
209
+ }
210
+ let obj = {
211
+ "recordId": this.recordId.toString(),
212
+ "modId": this.modId.toString(),
213
+ "fieldData": fields_processed
214
+ }
215
+ return obj
216
+ }
217
+
179
218
  toObject(
180
219
  filter: (a: FieldBase<FieldValue>) => any = (a) => a.edited,
181
220
  portalFilter: (a: Portal<any>) => any = (a) => a.records.find(record => record.edited),
182
221
  portalRowFilter: (a: PortalRecord<never>) => any = (a) => a.edited,
183
222
  portalFieldFilter: (a: FieldBase<FieldValue>) => any = (a) => a.edited
184
223
  ) {
185
- let obj = super.toObject(filter);
224
+ let obj: ApiRowDataDef = {
225
+ ...this.fieldsToObject(filter),
226
+ portalData: {}
227
+ };
186
228
 
187
229
  // Check if there's been any edited portal information
188
230
  let portals = this.portalsArray.filter(a => portalFilter(a))
@@ -7,5 +7,5 @@ export declare class Portal<T extends RecordFieldsMap> implements PortalBase<T>
7
7
  readonly name: string;
8
8
  records: PortalRecord<T>[];
9
9
  constructor(record: LayoutRecord<any>, name: string);
10
- create(): PortalRecord<T>;
10
+ create(): Promise<PortalRecord<T>>;
11
11
  }
@@ -5,14 +5,14 @@ import { PortalRecord } from "./portalRecord.js";
5
5
  export class Portal {
6
6
  record;
7
7
  name;
8
- records;
8
+ records = [];
9
9
  constructor(record, name) {
10
10
  this.record = record;
11
11
  this.name = name;
12
12
  }
13
- create() {
13
+ async create() {
14
14
  let fields = {};
15
- for (let _field of this.record.layout.metadata.portalMetaData[this.name]) {
15
+ for (let _field of (await this.record.layout.getLayoutMeta()).portalMetaData[this.name]) {
16
16
  fields[_field.name] = "";
17
17
  }
18
18
  let record = new PortalRecord(this.record, this, -1, -1, fields);
@@ -10,18 +10,18 @@ import {LayoutRecord} from "./layoutRecord.js";
10
10
  export class Portal<T extends RecordFieldsMap> implements PortalBase<T> {
11
11
  readonly record: LayoutRecord<any>;
12
12
  readonly name: string;
13
- public records: PortalRecord<T>[];
13
+ public records: PortalRecord<T>[] = [];
14
14
 
15
15
  constructor(record: LayoutRecord<any>, name: string) {
16
16
  this.record = record
17
17
  this.name = name
18
18
  }
19
19
 
20
- create() {
20
+ async create() {
21
21
  let fields: {
22
22
  [key: string]: string
23
23
  } = {}
24
- for (let _field of this.record.layout.metadata.portalMetaData[this.name]) {
24
+ for (let _field of (await this.record.layout.getLayoutMeta()).portalMetaData[this.name]) {
25
25
  fields[_field.name] = ""
26
26
  }
27
27
  let record = new PortalRecord<T>(this.record, this, -1, -1, fields)
@@ -10,8 +10,9 @@ export declare class PortalRecord<T extends RecordFieldsMap> extends RecordBase<
10
10
  _onSave(): void;
11
11
  commit(extraBody?: extraBodyOptions): Promise<import("./layoutRecord.js").LayoutRecord<import("../index.js").LayoutInterface>>;
12
12
  toObject(fieldFilter: (a: FieldBase<FieldValue>) => boolean): {
13
+ modId?: string;
14
+ recordId?: string;
15
+ } & {
13
16
  [key: string]: string;
14
- modId: string;
15
- recordId: string;
16
17
  };
17
18
  }
@@ -7,9 +7,8 @@ export class PortalRecord extends RecordBase {
7
7
  portal;
8
8
  type = RecordTypes.PORTAL;
9
9
  constructor(record, portal, recordId, modId = recordId, fieldData = {}) {
10
- super(record.layout, recordId, modId);
10
+ super(record.layout, recordId, modId, fieldData);
11
11
  this.portal = portal;
12
- this.processFieldData(fieldData);
13
12
  }
14
13
  _onSave() {
15
14
  super._onSave();
@@ -19,13 +18,12 @@ export class PortalRecord extends RecordBase {
19
18
  return this.portal.record.commit(extraBody);
20
19
  }
21
20
  toObject(fieldFilter) {
22
- super.toObject();
23
21
  let res = {
24
22
  recordId: this.recordId === -1 ? undefined : this.recordId.toString(),
25
23
  modId: this.modId === -1 ? undefined : this.modId.toString()
26
24
  };
27
25
  for (let field of this.fieldsArray.filter(a => fieldFilter(a)))
28
- res[field.id] = field.value.toString();
26
+ res[field.id] = field.value?.toString();
29
27
  // console.log(res)
30
28
  return res;
31
29
  }
@@ -14,10 +14,8 @@ export class PortalRecord<T extends RecordFieldsMap> extends RecordBase<T> {
14
14
  readonly type = RecordTypes.PORTAL
15
15
 
16
16
  constructor(record: RecordBase<any>, portal: PortalBase<any>, recordId: number, modId = recordId, fieldData = {}) {
17
- super(record.layout, recordId, modId);
18
-
17
+ super(record.layout, recordId, modId, fieldData);
19
18
  this.portal = portal
20
- this.processFieldData(fieldData)
21
19
  }
22
20
 
23
21
  _onSave() {
@@ -29,17 +27,15 @@ export class PortalRecord<T extends RecordFieldsMap> extends RecordBase<T> {
29
27
  return this.portal.record.commit(extraBody)
30
28
  }
31
29
 
32
- toObject(fieldFilter: (a: FieldBase<FieldValue>) => boolean) {
33
- super.toObject()
34
- let res: {
35
- "modId": string,
36
- "recordId": string
37
- [key: string]: string
38
- } = {
30
+ toObject(fieldFilter: (a: FieldBase<FieldValue>) => boolean): {
31
+ modId?: string,
32
+ recordId?: string,
33
+ } & {[key: string]: string} {
34
+ let res: any = {
39
35
  recordId: this.recordId === -1 ? undefined : this.recordId.toString(),
40
36
  modId: this.modId === -1 ? undefined : this.modId.toString()
41
37
  }
42
- for (let field of this.fieldsArray.filter(a => fieldFilter(a))) res[field.id] = field.value.toString()
38
+ for (let field of this.fieldsArray.filter(a => fieldFilter(a))) res[field.id] = field.value?.toString()
43
39
  // console.log(res)
44
40
  return res
45
41
  }
@@ -4,19 +4,18 @@ import { FieldBase, FieldValue } from "./fieldBase.js";
4
4
  import { RecordTypes } from "../types.js";
5
5
  import { RecordFieldsMap } from "../layouts/recordFieldsMap.js";
6
6
  import { LayoutBase } from "../layouts/layoutBase.js";
7
- import { ApiFieldData, ApiRowDataDef } from "../models/apiResults.js";
8
- export declare class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
7
+ import { ApiFieldData } from "../models/apiResults.js";
8
+ export declare abstract class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
9
9
  readonly layout: LayoutBase;
10
10
  readonly type: RecordTypes;
11
11
  recordId: number;
12
12
  modId: number;
13
13
  fields: T;
14
14
  protected portalData: any[];
15
- constructor(layout: LayoutBase, recordId: number, modId?: number);
15
+ protected constructor(layout: LayoutBase, recordId: number, modId: number | undefined, fieldData: ApiFieldData);
16
16
  get endpoint(): string;
17
17
  get edited(): boolean;
18
18
  get fieldsArray(): FieldBase<FieldValue>[];
19
19
  protected processFieldData(fieldData: ApiFieldData): T;
20
20
  _onSave(): void;
21
- toObject(filter?: (a: FieldBase<FieldValue>) => boolean): Partial<Omit<ApiRowDataDef, "portalDataInfo">>;
22
21
  }
@@ -11,12 +11,13 @@ export class RecordBase extends EventEmitter {
11
11
  recordId;
12
12
  modId;
13
13
  fields;
14
- portalData;
15
- constructor(layout, recordId, modId = recordId) {
14
+ portalData = [];
15
+ constructor(layout, recordId, modId = recordId, fieldData) {
16
16
  super();
17
17
  this.layout = layout;
18
18
  this.recordId = recordId;
19
19
  this.modId = modId;
20
+ this.fields = this.processFieldData(fieldData);
20
21
  }
21
22
  get endpoint() {
22
23
  return `${this.layout.endpoint}/records/${this.recordId}`;
@@ -67,34 +68,4 @@ export class RecordBase extends EventEmitter {
67
68
  for (let field of this.fieldsArray)
68
69
  field.edited = false;
69
70
  }
70
- toObject(filter = (a) => a.edited) {
71
- let fields_processed = {};
72
- let field;
73
- for (field of this.fieldsArray.filter(field => filter(field))) {
74
- let value = field.value;
75
- if (value instanceof Date) {
76
- // @ts-ignore
77
- let _value = moment.default(value)
78
- .utcOffset(this.layout.database.host.timezoneOffset);
79
- // @ts-ignore
80
- switch (field.metadata.result) {
81
- case "time":
82
- value = _value.format(this.layout.database.host.metadata.productInfo.timeFormat.replace("dd", "DD"));
83
- break;
84
- case "date":
85
- value = _value.format(this.layout.database.host.metadata.productInfo.dateFormat.replace("dd", "DD"));
86
- break;
87
- default:
88
- value = _value.format(this.layout.database.host.metadata.productInfo.timeStampFormat.replace("dd", "DD"));
89
- }
90
- }
91
- fields_processed[field.id] = value;
92
- }
93
- let obj = {
94
- "recordId": this.recordId.toString(),
95
- "modId": this.modId.toString(),
96
- "fieldData": fields_processed
97
- };
98
- return obj;
99
- }
100
71
  }
@@ -8,21 +8,22 @@ import {FieldBase, FieldValue} from "./fieldBase.js";
8
8
  import {RecordTypes} from "../types.js";
9
9
  import {RecordFieldsMap} from "../layouts/recordFieldsMap.js";
10
10
  import {LayoutBase} from "../layouts/layoutBase.js";
11
- import {ApiFieldData, ApiRowDataDef} from "../models/apiResults.js";
11
+ import {ApiFieldData} from "../models/apiResults.js";
12
12
 
13
- export class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
13
+ export abstract class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
14
14
  readonly layout: LayoutBase;
15
15
  readonly type: RecordTypes = RecordTypes.UNKNOWN;
16
16
  public recordId: number;
17
17
  modId: number;
18
18
  fields: T;
19
- protected portalData: any[];
19
+ protected portalData: any[] = [];
20
20
 
21
- constructor(layout: LayoutBase, recordId: number, modId = recordId) {
21
+ protected constructor(layout: LayoutBase, recordId: number, modId = recordId, fieldData: ApiFieldData) {
22
22
  super();
23
23
  this.layout = layout
24
24
  this.recordId = recordId
25
25
  this.modId = modId
26
+ this.fields = this.processFieldData(fieldData)
26
27
  }
27
28
 
28
29
  get endpoint(): string {
@@ -79,37 +80,4 @@ export class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
79
80
  this.emit("saved")
80
81
  for (let field of this.fieldsArray) field.edited = false
81
82
  }
82
-
83
- toObject(filter = (a: FieldBase<FieldValue>) => a.edited): Partial<Omit<ApiRowDataDef, "portalDataInfo">> {
84
- let fields_processed: ApiFieldData = {}
85
- let field: FieldBase<FieldValue>
86
- for (field of this.fieldsArray.filter(field => filter(field))) {
87
- let value = field.value
88
- if (value instanceof Date) {
89
- // @ts-ignore
90
- let _value = moment.default(value)
91
- .utcOffset(this.layout.database.host.timezoneOffset)
92
-
93
- // @ts-ignore
94
-
95
- switch (field.metadata.result) {
96
- case "time":
97
- value = _value.format(this.layout.database.host.metadata.productInfo.timeFormat.replace("dd", "DD"))
98
- break
99
- case "date":
100
- value = _value.format(this.layout.database.host.metadata.productInfo.dateFormat.replace("dd", "DD"))
101
- break
102
- default:
103
- value = _value.format(this.layout.database.host.metadata.productInfo.timeStampFormat.replace("dd", "DD"))
104
- }
105
- }
106
- fields_processed[field.id] = value
107
- }
108
- let obj = {
109
- "recordId": this.recordId.toString(),
110
- "modId": this.modId.toString(),
111
- "fieldData": fields_processed
112
- }
113
- return obj
114
- }
115
83
  }
@@ -0,0 +1,4 @@
1
+ type QueryParameter = string | number | Date;
2
+ export declare function fmQueryEscape(str: string): string;
3
+ export declare function fmQuery(strings: TemplateStringsArray, ...args: QueryParameter[]): string;
4
+ export {};
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright (c) 2024. See LICENSE file for more information
3
+ */
4
+ const SPECIAL_CHARACTERS = ["\\", "=", "<", "≤", "≥", ">", "…", "...", "//", "@", "#", "*", "\"", "~"];
5
+ export function fmQueryEscape(str) {
6
+ for (let char of SPECIAL_CHARACTERS) {
7
+ str = str.replace(char, `\\${char}`);
8
+ }
9
+ return str;
10
+ }
11
+ export function fmQuery(strings, ...args) {
12
+ let argStrings = args.map(item => {
13
+ return fmQueryEscape(item.toString());
14
+ });
15
+ // Zip the parameters together
16
+ const query = strings.map((str, index) => {
17
+ return str + (args[index] || '');
18
+ });
19
+ return query.join("");
20
+ }
@@ -0,0 +1,4 @@
1
+ type QueryParameter = string | number | Date;
2
+ export declare function queryEscape(str: string): string;
3
+ export declare function query(strings: TemplateStringsArray, ...args: QueryParameter[]): string;
4
+ export {};
@@ -0,0 +1,20 @@
1
+ /*
2
+ * Copyright (c) 2024. See LICENSE file for more information
3
+ */
4
+ const SPECIAL_CHARACTERS = ["\\", "=", "<", "≤", "≥", ">", "…", "...", "//", "@", "#", "*", "\"", "~"];
5
+ export function queryEscape(str) {
6
+ for (let char of SPECIAL_CHARACTERS) {
7
+ str = str.replace(char, `\\${char}`);
8
+ }
9
+ return str;
10
+ }
11
+ export function query(strings, ...args) {
12
+ let argStrings = args.map(item => {
13
+ return queryEscape(item.toString());
14
+ });
15
+ // Zip the parameters together
16
+ const query = strings.map((str, index) => {
17
+ return str + (argStrings[index] || '');
18
+ });
19
+ return query.join("");
20
+ }