@jd-data-limited/easy-fm 4.0.3 → 4.0.5

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 (48) hide show
  1. package/package.json +6 -1
  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.js +4 -4
  15. package/src/connection/database.ts +5 -5
  16. package/src/index.d.ts +2 -1
  17. package/src/index.js +2 -1
  18. package/src/index.ts +4 -1
  19. package/src/layouts/layout.d.ts +1 -1
  20. package/src/layouts/layout.js +7 -2
  21. package/src/layouts/layout.ts +5 -2
  22. package/src/layouts/layoutRecordManager.js +3 -3
  23. package/src/layouts/layoutRecordManager.ts +3 -3
  24. package/src/models/apiResults.d.ts +1 -1
  25. package/src/models/apiResults.ts +1 -1
  26. package/src/records/field.d.ts +2 -1
  27. package/src/records/field.js +4 -0
  28. package/src/records/getOperations/recordGetOperation.d.ts +2 -1
  29. package/src/records/getOperations/recordGetOperation.js +33 -26
  30. package/src/records/getOperations/recordGetOperation.ts +39 -33
  31. package/src/records/layoutRecord.d.ts +3 -2
  32. package/src/records/layoutRecord.js +53 -8
  33. package/src/records/layoutRecord.ts +56 -9
  34. package/src/records/portal.d.ts +1 -1
  35. package/src/records/portal.js +3 -3
  36. package/src/records/portal.ts +3 -3
  37. package/src/records/portalRecord.d.ts +3 -2
  38. package/src/records/portalRecord.js +2 -4
  39. package/src/records/portalRecord.ts +7 -11
  40. package/src/records/recordBase.d.ts +3 -4
  41. package/src/records/recordBase.js +3 -32
  42. package/src/records/recordBase.ts +5 -37
  43. package/src/utils/fmQuery.d.ts +4 -0
  44. package/src/utils/fmQuery.js +20 -0
  45. package/src/utils/query.d.ts +4 -0
  46. package/src/utils/query.js +20 -0
  47. package/src/utils/query.ts +25 -0
  48. package/src/records/field.ts +0 -10
@@ -7,7 +7,7 @@ import {generateAuthorizationHeaders} from "./generateAuthorizationHeaders.js";
7
7
  import {FMError} from "../FMError.js";
8
8
  import {LayoutInterface} from "../layouts/layoutInterface.js";
9
9
  import {Layout} from "../layouts/layout.js";
10
- import * as HTTP_REDIRECT from "follow-redirects"
10
+ import HTTP_REDIRECT from "follow-redirects"
11
11
  import {
12
12
  databaseOptionsBase,
13
13
  databaseOptionsWithExternalSources,
@@ -118,7 +118,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
118
118
 
119
119
  let _fetch = await fetch(url, options)
120
120
  if (_fetch.headers.get('set-cookie')) {
121
- for (let cookie of _fetch.headers.get('set-cookie')) {
121
+ for (let cookie of _fetch.headers.get('set-cookie') || []) {
122
122
  let cookie_split = cookie.split("=")
123
123
  this.cookies[cookie_split[0]] = cookie_split[1]
124
124
  }
@@ -126,7 +126,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
126
126
  let data = await _fetch.json() as ApiResults<T>
127
127
 
128
128
  // Remove response if it is empty. This makes checking for an empty response easier
129
- if (Object.keys(data.response).length === 0) delete data.response
129
+ if (data.response && Object.keys(data.response).length === 0) delete data.response
130
130
 
131
131
  // console.log(data.messages[0])
132
132
  if (data.messages[0].code === "952" && autoRelogin) {
@@ -195,14 +195,14 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
195
195
  let cookie_split = cookie.split("=")
196
196
  this.cookies[cookie_split[0]] = cookie_split[1]
197
197
  }
198
- res.headers['set-cookie'] = null
198
+ res.headers['set-cookie'] = undefined
199
199
  }
200
200
  }
201
201
 
202
202
  // Automatically switch between the http and https modules, based on which is needed
203
203
  (url.startsWith("https") ? HTTP_REDIRECT.https : HTTP_REDIRECT.http).get(url, {
204
204
  headers,
205
- beforeRedirect: (options, res) => check_for_cookies(res)
205
+ beforeRedirect: (options: any, res: any) => check_for_cookies(res)
206
206
  }, (res) => {
207
207
  check_for_cookies(res)
208
208
 
package/src/index.d.ts CHANGED
@@ -13,5 +13,6 @@ import { Container, FieldBase } from "./records/fieldBase.js";
13
13
  import { RecordGetOperation } from "./records/getOperations/recordGetOperation.js";
14
14
  import { LayoutRecordManager } from "./layouts/layoutRecordManager.js";
15
15
  import { RecordFieldsMap } from "./layouts/recordFieldsMap.js";
16
+ import { query, queryEscape } from "./utils/query.js";
16
17
  export default FMHost;
17
- export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, LayoutInterface, RecordFieldsMap, PortalInterface, PortalRecord, Portal, FieldBase, RecordGetOperation, LayoutRecordManager, Container, PickPortals };
18
+ export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, LayoutInterface, RecordFieldsMap, PortalInterface, PortalRecord, Portal, FieldBase, RecordGetOperation, LayoutRecordManager, Container, PickPortals, query, queryEscape };
package/src/index.js CHANGED
@@ -13,5 +13,6 @@ import { Portal } from "./records/portal.js";
13
13
  import { FieldBase } from "./records/fieldBase.js";
14
14
  import { RecordGetOperation } from "./records/getOperations/recordGetOperation.js";
15
15
  import { LayoutRecordManager } from "./layouts/layoutRecordManager.js";
16
+ import { query, queryEscape } from "./utils/query.js";
16
17
  export default FMHost;
17
- export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, PortalRecord, Portal, FieldBase, RecordGetOperation, LayoutRecordManager };
18
+ export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, PortalRecord, Portal, FieldBase, RecordGetOperation, LayoutRecordManager, query, queryEscape };
package/src/index.ts CHANGED
@@ -17,6 +17,7 @@ import {Container, FieldBase} from "./records/fieldBase.js";
17
17
  import {RecordGetOperation} from "./records/getOperations/recordGetOperation.js";
18
18
  import {LayoutRecordManager} from "./layouts/layoutRecordManager.js";
19
19
  import {RecordFieldsMap} from "./layouts/recordFieldsMap.js";
20
+ import {query, queryEscape} from "./utils/query.js";
20
21
 
21
22
  export default FMHost
22
23
  export {
@@ -35,5 +36,7 @@ export {
35
36
  RecordGetOperation,
36
37
  LayoutRecordManager,
37
38
  Container,
38
- PickPortals
39
+ PickPortals,
40
+ query,
41
+ queryEscape
39
42
  }
@@ -8,7 +8,7 @@ export declare class Layout<T extends LayoutInterface> implements LayoutBase {
8
8
  readonly database: DatabaseBase;
9
9
  readonly name: string;
10
10
  readonly records: LayoutRecordManager<T>;
11
- metadata: ApiLayoutMetadata;
11
+ metadata: ApiLayoutMetadata | null;
12
12
  constructor(database: DatabaseBase, name: string);
13
13
  get endpoint(): string;
14
14
  runScript(script: Script): Promise<ScriptResult>;
@@ -7,7 +7,7 @@ export class Layout {
7
7
  database;
8
8
  name;
9
9
  records = new LayoutRecordManager(this);
10
- metadata;
10
+ metadata = null;
11
11
  constructor(database, name) {
12
12
  this.database = database;
13
13
  this.name = name;
@@ -23,19 +23,24 @@ export class Layout {
23
23
  port: 443,
24
24
  method: "GET"
25
25
  });
26
- if (res.messages[0].code === "0") {
26
+ if (res.response && res.messages[0].code === "0") {
27
27
  let error = parseInt(res.response.scriptError);
28
28
  return {
29
29
  scriptError: error ? new FMError(error, 200, res) : undefined,
30
30
  scriptResult: res.response.scriptResult
31
31
  };
32
32
  }
33
+ else {
34
+ throw new FMError(res.messages[0].code, res.httpStatus, res);
35
+ }
33
36
  }
34
37
  async getLayoutMeta() {
35
38
  if (this.metadata) {
36
39
  return this.metadata;
37
40
  }
38
41
  let res = await this.database.apiRequest(this.endpoint);
42
+ if (!res.response)
43
+ throw new FMError(res.messages[0].code, res.httpStatus, res);
39
44
  this.metadata = res.response;
40
45
  return this.metadata;
41
46
  }
@@ -14,7 +14,7 @@ export class Layout<T extends LayoutInterface> implements LayoutBase {
14
14
  readonly database: DatabaseBase;
15
15
  readonly name: string;
16
16
  readonly records = new LayoutRecordManager<T>(this)
17
- metadata: ApiLayoutMetadata;
17
+ metadata: ApiLayoutMetadata | null = null;
18
18
 
19
19
  constructor(database: DatabaseBase, name: string) {
20
20
  this.database = database
@@ -33,12 +33,14 @@ export class Layout<T extends LayoutInterface> implements LayoutBase {
33
33
  port: 443,
34
34
  method: "GET"
35
35
  })
36
- if (res.messages[0].code === "0") {
36
+ if (res.response && res.messages[0].code === "0") {
37
37
  let error = parseInt(res.response.scriptError)
38
38
  return {
39
39
  scriptError: error ? new FMError(error, 200, res) : undefined,
40
40
  scriptResult: res.response.scriptResult
41
41
  }
42
+ } else {
43
+ throw new FMError(res.messages[0].code, res.httpStatus, res);
42
44
  }
43
45
  }
44
46
 
@@ -48,6 +50,7 @@ export class Layout<T extends LayoutInterface> implements LayoutBase {
48
50
  }
49
51
 
50
52
  let res = await this.database.apiRequest<ApiLayoutMetadata>(this.endpoint)
53
+ if (!res.response) throw new FMError(res.messages[0].code, res.httpStatus, res)
51
54
  this.metadata = res.response
52
55
  return this.metadata
53
56
  }
@@ -9,13 +9,13 @@ export class LayoutRecordManager {
9
9
  this.layout = layout;
10
10
  }
11
11
  async create(options) {
12
- await this.layout.getLayoutMeta();
12
+ let metadata = await this.layout.getLayoutMeta();
13
13
  let fields = {};
14
- for (let _field of this.layout.metadata.fieldMetaData) {
14
+ for (let _field of metadata.fieldMetaData) {
15
15
  fields[_field.name] = "";
16
16
  }
17
17
  let portals = {};
18
- for (let _portal of Object.keys(this.layout.metadata.portalMetaData))
18
+ for (let _portal of Object.keys(metadata.portalMetaData))
19
19
  portals[_portal] = [];
20
20
  return new LayoutRecord(this.layout, -1, 0, fields, portals);
21
21
  }
@@ -18,13 +18,13 @@ export class LayoutRecordManager<T extends LayoutInterface> {
18
18
  async create<OPTIONS extends RecordFetchOptions>(options: OPTIONS): Promise<LayoutRecord<
19
19
  PickPortals<T, OPTIONS["portals"][number]>
20
20
  >> {
21
- await this.layout.getLayoutMeta()
21
+ let metadata = await this.layout.getLayoutMeta()
22
22
  let fields: ApiFieldData = {}
23
- for (let _field of this.layout.metadata.fieldMetaData) {
23
+ for (let _field of metadata.fieldMetaData) {
24
24
  fields[_field.name] = ""
25
25
  }
26
26
  let portals: {[key: string]: []} = {}
27
- for (let _portal of Object.keys(this.layout.metadata.portalMetaData)) portals[_portal] = []
27
+ for (let _portal of Object.keys(metadata.portalMetaData)) portals[_portal] = []
28
28
  return new LayoutRecord(this.layout, -1, 0, fields, portals)
29
29
  }
30
30
 
@@ -94,7 +94,7 @@ export interface ApiRowDataDef {
94
94
  portalData: ApiPortalData;
95
95
  modId: string;
96
96
  recordId: string;
97
- portalDataInfo: {
97
+ portalDataInfo?: {
98
98
  database: string;
99
99
  table: string;
100
100
  foundCount: number;
@@ -101,7 +101,7 @@ export interface ApiRowDataDef {
101
101
  portalData: ApiPortalData,
102
102
  modId: string,
103
103
  recordId: string,
104
- portalDataInfo: {
104
+ portalDataInfo?: {
105
105
  database: string,
106
106
  table: string,
107
107
  foundCount: number,
@@ -1,5 +1,6 @@
1
1
  import { RecordBase } from "./recordBase.js";
2
2
  import { FieldBase, FieldValue } from "./fieldBase.js";
3
- export declare class Field<T extends FieldValue> extends FieldBase<T> {
3
+ export declare abstract class Field<T extends FieldValue> extends FieldBase<T> {
4
4
  record: RecordBase<any>;
5
+ protected constructor(record: RecordBase<any>);
5
6
  }
@@ -4,4 +4,8 @@
4
4
  import { FieldBase } from "./fieldBase.js";
5
5
  export class Field extends FieldBase {
6
6
  record;
7
+ constructor(record) {
8
+ super();
9
+ this.record = record;
10
+ }
7
11
  }
@@ -5,6 +5,7 @@ import { LayoutRecord } from "../layoutRecord.js";
5
5
  export type SortOrder = "ascend" | "descend";
6
6
  export type FindRequest = {
7
7
  [key: string]: string;
8
+ } & {
8
9
  omit?: "true" | "false";
9
10
  };
10
11
  export type PortalRequest = {
@@ -46,7 +47,7 @@ export declare class RecordGetOperation<T extends LayoutInterface, OPTIONS exten
46
47
  [Symbol.asyncIterator](): {
47
48
  next: () => Promise<{
48
49
  done: boolean;
49
- value: LayoutRecord<PickPortals<T, keyof OPTIONS["portals"]>>;
50
+ value: LayoutRecord<PickPortals<T, keyof OPTIONS["portals"]>> | undefined;
50
51
  }>;
51
52
  };
52
53
  }
@@ -33,20 +33,20 @@ export class RecordGetOperation {
33
33
  if (this.scriptData.after?.parameter)
34
34
  params["script.param"] = this.scriptData.after.parameter;
35
35
  if (this.scriptData.presort)
36
- params["script.presort"] = this.scriptData.after.name;
36
+ params["script.presort"] = this.scriptData.presort.name;
37
37
  if (this.scriptData.presort?.parameter)
38
- params["script.presort.param"] = this.scriptData.after.parameter;
38
+ params["script.presort.param"] = this.scriptData.presort.parameter;
39
39
  if (this.scriptData.prerequest)
40
- params["script.prerequest"] = this.scriptData.after.name;
40
+ params["script.prerequest"] = this.scriptData.prerequest.name;
41
41
  if (this.scriptData.prerequest?.parameter)
42
- params["script.prerequest.param"] = this.scriptData.after.parameter;
42
+ params["script.prerequest.param"] = this.scriptData.prerequest.parameter;
43
43
  if (this.queries.length !== 0)
44
44
  params["query"] = this.queries;
45
45
  let portals = Object.keys(this.portals);
46
46
  params["portal"] = portals;
47
47
  for (let portal of portals) {
48
- params[`offset.${portal}`] = this.portals[portal].offset;
49
- params[`limit.${portal}`] = this.portals[portal].limit;
48
+ params[`offset.${portal.toString()}`] = this.portals[portal]?.offset;
49
+ params[`limit.${portal.toString()}`] = this.portals[portal]?.limit;
50
50
  }
51
51
  return params;
52
52
  }
@@ -62,17 +62,17 @@ export class RecordGetOperation {
62
62
  if (this.scriptData.after?.parameter)
63
63
  params.set("script.param", this.scriptData.after.parameter);
64
64
  if (this.scriptData.presort)
65
- params.set("script.presort", this.scriptData.after.name);
65
+ params.set("script.presort", this.scriptData.presort.name);
66
66
  if (this.scriptData.presort?.parameter)
67
- params.set("script.presort.param", this.scriptData.after.parameter);
67
+ params.set("script.presort.param", this.scriptData.presort.parameter);
68
68
  if (this.scriptData.prerequest)
69
- params.set("script.prerequest", this.scriptData.after.name);
69
+ params.set("script.prerequest", this.scriptData.prerequest.name);
70
70
  if (this.scriptData.prerequest?.parameter)
71
- params.set("script.prerequest.param", this.scriptData.after.parameter);
71
+ params.set("script.prerequest.param", this.scriptData.prerequest.parameter);
72
72
  let portals = Object.keys(this.portals);
73
73
  for (let portal of portals) {
74
- params.set(`_offset.${portal}`, this.portals[portal].limit.toString());
75
- params.set(`_offset.${portal}`, this.portals[portal].offset.toString());
74
+ params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.limit || "").toString());
75
+ params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.offset || "").toString());
76
76
  }
77
77
  params.set('portal', JSON.stringify(portals));
78
78
  return params;
@@ -104,21 +104,28 @@ export class RecordGetOperation {
104
104
  method: is_find ? "POST" : "GET",
105
105
  body: is_find ? JSON.stringify(this.generateParamsBody(offset, limit)) : undefined,
106
106
  };
107
- let res = await this.layout.database.apiRequest(endpoint, reqData);
108
- if (res.messages[0].code === "0") {
109
- // console.log("RESOLVING")
110
- if (!this.layout.metadata)
111
- await this.layout.getLayoutMeta();
112
- return res.response.data.map(item => {
113
- return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData);
114
- });
115
- }
116
- else if (res.messages[0].code == "401") {
117
- // No records found, so return empty set
118
- return [];
107
+ try {
108
+ let res = await this.layout.database.apiRequest(endpoint, reqData);
109
+ if (res.messages[0].code === "0" && res.response) {
110
+ // console.log("RESOLVING")
111
+ if (!this.layout.metadata)
112
+ await this.layout.getLayoutMeta();
113
+ return res.response.data.map(item => {
114
+ return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData);
115
+ });
116
+ }
117
+ else {
118
+ throw new FMError(res.messages[0].code, res.httpStatus, res, trace);
119
+ }
119
120
  }
120
- else {
121
- throw new FMError(res.messages[0].code, res.httpStatus, res, trace);
121
+ catch (e) {
122
+ if (e instanceof FMError) {
123
+ if (e.code === 401) {
124
+ // No records found, so return empty set
125
+ return [];
126
+ }
127
+ }
128
+ throw e;
122
129
  }
123
130
  }
124
131
  [Symbol.asyncIterator]() {
@@ -12,8 +12,8 @@ import {FMError} from "../../FMError.js";
12
12
  export type SortOrder = "ascend" | "descend"
13
13
  export type FindRequest = {
14
14
  [key: string]: string,
15
- omit?: "true" | "false"
16
- }
15
+ } & {omit?: "true" | "false"}
16
+
17
17
  export type PortalRequest = {
18
18
  name: string,
19
19
  }
@@ -62,19 +62,19 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
62
62
  if (this.scriptData.after) params["script"] = this.scriptData.after.name
63
63
  if (this.scriptData.after?.parameter) params["script.param"] = this.scriptData.after.parameter
64
64
 
65
- if (this.scriptData.presort) params["script.presort"] = this.scriptData.after.name
66
- if (this.scriptData.presort?.parameter) params["script.presort.param"] = this.scriptData.after.parameter
65
+ if (this.scriptData.presort) params["script.presort"] = this.scriptData.presort.name
66
+ if (this.scriptData.presort?.parameter) params["script.presort.param"] = this.scriptData.presort.parameter
67
67
 
68
- if (this.scriptData.prerequest) params["script.prerequest"] = this.scriptData.after.name
69
- if (this.scriptData.prerequest?.parameter) params["script.prerequest.param"] = this.scriptData.after.parameter
68
+ if (this.scriptData.prerequest) params["script.prerequest"] = this.scriptData.prerequest.name
69
+ if (this.scriptData.prerequest?.parameter) params["script.prerequest.param"] = this.scriptData.prerequest.parameter
70
70
 
71
71
  if (this.queries.length !== 0) params["query"] = this.queries
72
72
 
73
- let portals = Object.keys(this.portals)
73
+ let portals: (keyof typeof this.portals)[] = Object.keys(this.portals)
74
74
  params["portal"] = portals
75
75
  for (let portal of portals) {
76
- params[`offset.${portal}`] = this.portals[portal].offset
77
- params[`limit.${portal}`] = this.portals[portal].limit
76
+ params[`offset.${portal.toString()}`] = this.portals[portal]?.offset
77
+ params[`limit.${portal.toString()}`] = this.portals[portal]?.limit
78
78
  }
79
79
 
80
80
  return params
@@ -89,16 +89,16 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
89
89
  if (this.scriptData.after) params.set("script", this.scriptData.after.name)
90
90
  if (this.scriptData.after?.parameter) params.set("script.param", this.scriptData.after.parameter)
91
91
 
92
- if (this.scriptData.presort) params.set("script.presort", this.scriptData.after.name)
93
- if (this.scriptData.presort?.parameter) params.set("script.presort.param", this.scriptData.after.parameter)
92
+ if (this.scriptData.presort) params.set("script.presort", this.scriptData.presort.name)
93
+ if (this.scriptData.presort?.parameter) params.set("script.presort.param", this.scriptData.presort.parameter)
94
94
 
95
- if (this.scriptData.prerequest) params.set("script.prerequest", this.scriptData.after.name)
96
- if (this.scriptData.prerequest?.parameter) params.set("script.prerequest.param", this.scriptData.after.parameter)
95
+ if (this.scriptData.prerequest) params.set("script.prerequest", this.scriptData.prerequest.name)
96
+ if (this.scriptData.prerequest?.parameter) params.set("script.prerequest.param", this.scriptData.prerequest.parameter)
97
97
 
98
- let portals = Object.keys(this.portals)
98
+ let portals: (keyof typeof this.portals)[] = Object.keys(this.portals)
99
99
  for (let portal of portals) {
100
- params.set(`_offset.${portal}`, this.portals[portal].limit.toString())
101
- params.set(`_offset.${portal}`, this.portals[portal].offset.toString())
100
+ params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.limit || "").toString())
101
+ params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.offset || "").toString())
102
102
  }
103
103
  params.set('portal', JSON.stringify(portals))
104
104
 
@@ -139,23 +139,29 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
139
139
  body: is_find ? JSON.stringify(this.generateParamsBody(offset, limit)) : undefined,
140
140
  }
141
141
 
142
- let res = await this.layout.database.apiRequest<ApiRecordResponseObj>(
143
- endpoint,
144
- reqData
145
- )
146
- if (res.messages[0].code === "0") {
147
- // console.log("RESOLVING")
148
- if (!this.layout.metadata) await this.layout.getLayoutMeta()
149
- return res.response.data.map(item => {
150
- return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData)
151
- })
152
- }
153
- else if (res.messages[0].code == "401") {
154
- // No records found, so return empty set
155
- return []
156
- }
157
- else {
158
- throw new FMError(res.messages[0].code, res.httpStatus, res, trace)
142
+ try {
143
+ let res = await this.layout.database.apiRequest<ApiRecordResponseObj>(
144
+ endpoint,
145
+ reqData
146
+ )
147
+ if (res.messages[0].code === "0" && res.response) {
148
+ // console.log("RESOLVING")
149
+ if (!this.layout.metadata) await this.layout.getLayoutMeta()
150
+ return res.response.data.map(item => {
151
+ return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData)
152
+ })
153
+ }
154
+ else {
155
+ throw new FMError(res.messages[0].code, res.httpStatus, res, trace)
156
+ }
157
+ } catch(e) {
158
+ if (e instanceof FMError) {
159
+ if (e.code === 401) {
160
+ // No records found, so return empty set
161
+ return []
162
+ }
163
+ }
164
+ throw e
159
165
  }
160
166
  }
161
167
 
@@ -4,7 +4,7 @@ import { PortalRecord } from "./portalRecord.js";
4
4
  import { Portal } from "./portal.js";
5
5
  import { LayoutInterface } from "../layouts/layoutInterface.js";
6
6
  import { LayoutRecordBase } from "./layoutRecordBase.js";
7
- import { ApiPortalData } from "../models/apiResults.js";
7
+ import { ApiPortalData, ApiRowDataDef } from "../models/apiResults.js";
8
8
  import { LayoutBase } from "../layouts/layoutBase.js";
9
9
  import { FieldBase, FieldValue } from "./fieldBase.js";
10
10
  export declare class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
@@ -17,5 +17,6 @@ export declare class LayoutRecord<LAYOUT extends LayoutInterface> extends Record
17
17
  get(): Promise<this>;
18
18
  duplicate(): Promise<LayoutRecord<LAYOUT>>;
19
19
  delete(): Promise<void>;
20
- toObject(filter?: (a: FieldBase<FieldValue>) => any, portalFilter?: (a: Portal<any>) => any, portalRowFilter?: (a: PortalRecord<never>) => any, portalFieldFilter?: (a: FieldBase<FieldValue>) => any): Partial<Omit<import("../models/apiResults.js").ApiRowDataDef, "portalDataInfo">>;
20
+ fieldsToObject(filter?: (a: FieldBase<FieldValue>) => boolean): Omit<ApiRowDataDef, "portalData">;
21
+ toObject(filter?: (a: FieldBase<FieldValue>) => any, portalFilter?: (a: Portal<any>) => any, portalRowFilter?: (a: PortalRecord<never>) => any, portalFieldFilter?: (a: FieldBase<FieldValue>) => any): ApiRowDataDef;
21
22
  }
@@ -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
  }
@@ -46,7 +46,10 @@ export class LayoutRecord extends RecordBase {
46
46
  method: "POST",
47
47
  body: JSON.stringify(data)
48
48
  });
49
- if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
49
+ if (!res.response) {
50
+ throw new FMError(res.messages[0].code, res.httpStatus, res);
51
+ }
52
+ else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
50
53
  throw new FMError(res.response.scriptError, res.httpStatus, res);
51
54
  }
52
55
  else if (res.messages[0].code === "0") {
@@ -64,7 +67,10 @@ export class LayoutRecord extends RecordBase {
64
67
  method: "PATCH",
65
68
  body: JSON.stringify(data)
66
69
  });
67
- if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
70
+ if (!res.response) {
71
+ throw new FMError(res.messages[0].code, res.httpStatus, res);
72
+ }
73
+ else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
68
74
  throw new FMError(res.response.scriptError, res.httpStatus, res);
69
75
  }
70
76
  else if (res.messages[0].code === "0") {
@@ -100,7 +106,7 @@ export class LayoutRecord extends RecordBase {
100
106
  port: 443,
101
107
  method: "GET"
102
108
  });
103
- if (res.messages[0].code === "0") {
109
+ if (res.response && res.messages[0].code === "0") {
104
110
  // console.log(res, res.response.data)
105
111
  this.modId = +res.response.data[0].modId;
106
112
  this.processFieldData(res.response.data[0].fieldData);
@@ -109,6 +115,9 @@ export class LayoutRecord extends RecordBase {
109
115
  this.processPortalData(res.response.data[0].portalData);
110
116
  return this;
111
117
  }
118
+ else {
119
+ throw new FMError(res.messages[0].code, res.httpStatus, res);
120
+ }
112
121
  }
113
122
  async duplicate() {
114
123
  let trace = new Error();
@@ -116,7 +125,10 @@ export class LayoutRecord extends RecordBase {
116
125
  port: 443,
117
126
  method: "POST"
118
127
  });
119
- if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
128
+ if (!res.response) {
129
+ throw new FMError(res.messages[0].code, res.httpStatus, res, trace);
130
+ }
131
+ else if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
120
132
  throw new FMError(res.response.scriptError, res.httpStatus, res, trace);
121
133
  }
122
134
  else if (res.messages[0].code === "0") {
@@ -146,8 +158,41 @@ export class LayoutRecord extends RecordBase {
146
158
  throw new FMError(res.messages[0].code, res.httpStatus, res);
147
159
  }
148
160
  }
161
+ fieldsToObject(filter = (a) => a.edited) {
162
+ let fields_processed = {};
163
+ let field;
164
+ for (field of this.fieldsArray.filter(field => filter(field))) {
165
+ let value = field.value;
166
+ if (value instanceof Date) {
167
+ // @ts-ignore
168
+ let _value = moment.default(value)
169
+ .utcOffset(this.layout.database.host.timezoneOffset);
170
+ // @ts-ignore
171
+ switch (field.metadata.result) {
172
+ case "time":
173
+ value = _value.format(this.layout.database.host.metadata.productInfo.timeFormat.replace("dd", "DD"));
174
+ break;
175
+ case "date":
176
+ value = _value.format(this.layout.database.host.metadata.productInfo.dateFormat.replace("dd", "DD"));
177
+ break;
178
+ default:
179
+ value = _value.format(this.layout.database.host.metadata.productInfo.timeStampFormat.replace("dd", "DD"));
180
+ }
181
+ }
182
+ fields_processed[field.id] = value;
183
+ }
184
+ let obj = {
185
+ "recordId": this.recordId.toString(),
186
+ "modId": this.modId.toString(),
187
+ "fieldData": fields_processed
188
+ };
189
+ return obj;
190
+ }
149
191
  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);
192
+ let obj = {
193
+ ...this.fieldsToObject(filter),
194
+ portalData: {}
195
+ };
151
196
  // Check if there's been any edited portal information
152
197
  let portals = this.portalsArray.filter(a => portalFilter(a));
153
198
  if (portals) {