@jd-data-limited/easy-fm 4.0.16 → 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.
Files changed (63) hide show
  1. package/package.json +12 -6
  2. package/src/FMError.d.ts +2 -2
  3. package/src/FMError.js +507 -508
  4. package/src/FMError.ts +510 -511
  5. package/src/connection/FMHost.d.ts +23 -5
  6. package/src/connection/FMHost.js +42 -26
  7. package/src/connection/FMHost.ts +63 -49
  8. package/src/connection/HostBase.d.ts +3 -3
  9. package/src/connection/HostBase.ts +5 -5
  10. package/src/connection/database.d.ts +50 -17
  11. package/src/connection/database.js +94 -66
  12. package/src/connection/database.ts +125 -105
  13. package/src/connection/databaseBase.d.ts +11 -6
  14. package/src/connection/databaseBase.ts +9 -8
  15. package/src/connection/generateAuthorizationHeaders.d.ts +1 -1
  16. package/src/connection/generateAuthorizationHeaders.js +10 -10
  17. package/src/connection/generateAuthorizationHeaders.ts +21 -21
  18. package/src/databaseStructure.d.ts +2 -4
  19. package/src/databaseStructure.ts +3 -5
  20. package/src/index.d.ts +17 -17
  21. package/src/index.js +13 -13
  22. package/src/index.ts +24 -24
  23. package/src/layouts/layout.d.ts +17 -6
  24. package/src/layouts/layout.js +19 -8
  25. package/src/layouts/layout.ts +33 -23
  26. package/src/layouts/layoutBase.d.ts +5 -5
  27. package/src/layouts/layoutBase.ts +6 -6
  28. package/src/layouts/layoutInterface.d.ts +3 -5
  29. package/src/layouts/layoutInterface.ts +4 -6
  30. package/src/layouts/layoutRecordManager.d.ts +29 -6
  31. package/src/layouts/layoutRecordManager.js +32 -9
  32. package/src/layouts/layoutRecordManager.ts +42 -19
  33. package/src/layouts/recordFieldsMap.d.ts +2 -4
  34. package/src/layouts/recordFieldsMap.ts +2 -4
  35. package/src/models/apiResults.d.ts +7 -13
  36. package/src/models/apiResults.ts +58 -58
  37. package/src/records/field.d.ts +42 -12
  38. package/src/records/field.js +69 -59
  39. package/src/records/field.ts +102 -81
  40. package/src/records/getOperations/recordGetOperation.d.ts +44 -24
  41. package/src/records/getOperations/recordGetOperation.js +87 -61
  42. package/src/records/getOperations/recordGetOperation.ts +127 -108
  43. package/src/records/layoutRecord.d.ts +28 -14
  44. package/src/records/layoutRecord.js +69 -60
  45. package/src/records/layoutRecord.ts +121 -119
  46. package/src/records/layoutRecordBase.d.ts +2 -2
  47. package/src/records/layoutRecordBase.ts +3 -3
  48. package/src/records/portal.d.ts +19 -5
  49. package/src/records/portal.js +19 -5
  50. package/src/records/portal.ts +28 -16
  51. package/src/records/portalBase.d.ts +5 -5
  52. package/src/records/portalBase.ts +6 -6
  53. package/src/records/portalRecord.d.ts +16 -8
  54. package/src/records/portalRecord.js +16 -6
  55. package/src/records/portalRecord.ts +29 -19
  56. package/src/records/recordBase.d.ts +17 -7
  57. package/src/records/recordBase.js +23 -16
  58. package/src/records/recordBase.ts +41 -37
  59. package/src/types.d.ts +21 -24
  60. package/src/types.ts +55 -59
  61. package/src/utils/query.d.ts +7 -7
  62. package/src/utils/query.js +10 -10
  63. package/src/utils/query.ts +19 -20
@@ -2,39 +2,53 @@
2
2
  * Copyright (c) 2023-2024. See LICENSE file for more information
3
3
  */
4
4
 
5
- import * as http from "http";
6
- import {ContainerBufferResult, DownloadModes, FieldMetaData, RecordTypes} from "../types.js";
7
- import {ApiFieldDisplayTypes, ApiFieldMetadata, ApiFieldResultTypes, ApiFieldTypes} from "../models/apiResults.js";
8
- import {LayoutBase} from "../layouts/layoutBase.js";
9
- import {Moment} from "moment";
5
+ import type * as http from 'http'
6
+ import {type ContainerBufferResult, DownloadModes, RecordTypes} from '../types.js'
7
+ import {ApiFieldDisplayTypes, type ApiFieldMetadata, ApiFieldResultTypes, ApiFieldTypes} from '../models/apiResults.js'
8
+ import {type LayoutBase} from '../layouts/layoutBase.js'
9
+ import {type Moment} from 'moment'
10
10
 
11
11
  export type FieldValue = string | number | Moment | Container
12
12
  export type Container = null
13
13
 
14
- export type Parentable = {layout: LayoutBase, type: RecordTypes, endpoint: string}
14
+ export interface Parentable {
15
+ layout: LayoutBase
16
+ type: RecordTypes
17
+ endpoint: string
18
+ portal?: { name: string }
19
+ }
20
+
21
+ /**
22
+ * A class representing a field in a record.
23
+ *
24
+ * @template T - The type of the field value.
25
+ */
15
26
  export class Field<T extends FieldValue> {
16
- parent: Parentable;
17
- id: string;
18
- protected _value: T;
19
- edited: boolean;
27
+ parent: Parentable
28
+ id: string
29
+ protected _value: T | null
30
+ edited: boolean
20
31
 
21
- constructor(record: Parentable, id: string, contents: T) {
32
+ constructor (record: Parentable, id: string, contents: T) {
22
33
  this.parent = record
23
34
  this.id = id
24
35
  this._value = contents
25
36
  this.edited = false
26
37
  }
27
38
 
28
- set(content: T) {
29
- if (this.metadata.result === "container") throw "Cannot set container value using set(). Use upload() instead."
30
- // @ts-ignore
31
- if (!content) this._value = ""
32
- // @ts-ignore
39
+ /**
40
+ * Sets the value of the field.
41
+ *
42
+ * @param {T | null} content - The new content value to be set. Can be either the type T or null.
43
+ * @throws {Error} Cannot set container value using set(). Use upload() instead, if the result is a 'container'.
44
+ */
45
+ set (content: T | null) {
46
+ if (this.metadata.result === 'container') throw new Error('Cannot set container value using set(). Use upload() instead.')
33
47
  else this._value = content
34
48
  this.edited = true
35
49
  }
36
50
 
37
- get metadata(): ApiFieldMetadata {
51
+ get metadata (): ApiFieldMetadata {
38
52
  if (!this.parent.layout.metadata) {
39
53
  // Default to a regular text field
40
54
  return {
@@ -51,30 +65,29 @@ export class Field<T extends FieldValue> {
51
65
  numeric: false,
52
66
  timeOfDay: false,
53
67
  repetitions: 1,
54
- valueList: ""
68
+ valueList: ''
55
69
  }
56
70
  }
57
- if (this.parent.type === RecordTypes.PORTAL) {
58
- // @ts-ignore
59
- return this.parent.layout.metadata.portalMetaData[this.parent.portal.name || "portal not attached"].find(i => i.name === this.id) as FieldMetaData || {
60
- name: this.id.toString(),
61
- type: 'normal',
62
- displayType: 'editText',
63
- result: 'text',
64
- global: false,
65
- autoEnter: true,
66
- fourDigitYear: false,
67
- maxRepeat: 1,
68
- maxCharacters: 0,
69
- notEmpty: false,
70
- numeric: false,
71
- timeOfDay: false,
72
- repetitionStart: 1,
73
- repetitionEnd: 1
74
- } as FieldMetaData
75
- }
76
- else {
77
- return this.parent.layout.metadata.fieldMetaData.find(i => i.name === this.id) || {
71
+ if (this.parent.type === RecordTypes.PORTAL && this.parent.portal) {
72
+ return this.parent.layout.metadata.portalMetaData[this.parent.portal.name || 'portal not attached'].find(i => i.name === this.id) ??
73
+ {
74
+ name: this.id.toString(),
75
+ type: ApiFieldTypes.NORMAL,
76
+ displayType: ApiFieldDisplayTypes.EDIT_TEXT,
77
+ result: ApiFieldResultTypes.TEXT,
78
+ global: false,
79
+ autoEnter: true,
80
+ fourDigitYear: false,
81
+ maxRepeat: 1,
82
+ maxCharacters: 0,
83
+ notEmpty: false,
84
+ numeric: false,
85
+ timeOfDay: false,
86
+ repetitions: 1,
87
+ valueList: ''
88
+ }
89
+ } else {
90
+ return this.parent.layout.metadata.fieldMetaData.find(i => i.name === this.id) ?? {
78
91
  name: this.id.toString(),
79
92
  type: ApiFieldTypes.NORMAL,
80
93
  displayType: ApiFieldDisplayTypes.EDIT_TEXT,
@@ -88,80 +101,88 @@ export class Field<T extends FieldValue> {
88
101
  numeric: false,
89
102
  timeOfDay: false,
90
103
  repetitions: 1,
91
- valueList: ""
104
+ valueList: ''
92
105
  }
93
106
  }
94
107
  }
95
108
 
96
- get value(): T {
109
+ get value (): T | null {
97
110
  // if (this.metadata.result === "container") throw "Use await field.stream() to get the contents of a container field, instead of field.value"
98
111
  return this._value
99
112
  }
100
113
 
101
- set value(value: T) {
114
+ set value (value: T) {
102
115
  this._value = value
103
116
  }
104
117
 
105
- get string(): string {
106
- if (typeof this._value === "string") {
107
- return this._value
108
- }
109
- throw "Field value is not a string"
110
- }
111
-
112
- get date(): Date {
113
- if (this._value instanceof Date) {
118
+ get string (): string {
119
+ if (typeof this._value === 'string') {
114
120
  return this._value
115
121
  }
116
- throw "Field value is not a date"
122
+ throw new Error('Field value is not a string')
117
123
  }
118
124
 
119
- get number(): number {
120
- if (typeof this._value === "number") {
121
- return this._value
125
+ /**
126
+ * Uploads a file to the container field.
127
+ *
128
+ * @param {Buffer} buffer - The file content as a buffer.
129
+ * @param {string} filename - The filename of the file.
130
+ * @param {string} mime - The MIME type of the file.
131
+ *
132
+ * @throws {Error} - Cannot upload a file to the field if it's not a container field.
133
+ * @throws {Error} - Upload failed with HTTP error.
134
+ *
135
+ * @returns {Promise<void>} - A promise that resolves when the file is successfully uploaded.
136
+ */
137
+ async upload (buffer: Buffer, filename: string, mime: string): Promise<void> {
138
+ if (this.metadata.result !== 'container') {
139
+ throw new Error('Cannot upload a file to the field; ' + this.id + ' (not a container field)')
122
140
  }
123
- throw "Field value is not a number"
124
- }
125
-
126
- async upload(buffer: Buffer, filename: string, mime: string): Promise<void> {
127
- let trace = new Error()
128
- if (this.metadata.result !== "container") throw "Cannot upload a file to the field; " + this.id + " (not a container field)"
129
- let form = new FormData()
130
- form.append("upload", new File([buffer], filename, {type: mime}))
131
-
132
- let res = await this.parent.layout.database.apiRequestRaw(`${this.parent.endpoint}/containers/${this.id}/1`, {
133
- method: "POST",
134
- // @ts-ignore
141
+ const form = new FormData()
142
+ form.append('upload', new File([buffer], filename, {type: mime}))
143
+
144
+ const res = await this.parent.layout.database._apiRequestRaw(`${this.parent.endpoint}/containers/${this.id}/1`, {
145
+ method: 'POST',
146
+ headers: {
147
+ Authorization: 'Bearer ' + this.parent.layout.database.token,
148
+ 'Content-Type': 'multipart/form-data'
149
+ },
135
150
  body: form
136
151
  })
137
152
  if (!res.ok) throw new Error(`Upload failed with HTTP error: ${res.status} (${res.statusText})`)
138
153
  }
139
154
 
140
- download(mode: DownloadModes.Stream): Promise<http.IncomingMessage>
141
- download(mode: DownloadModes.Buffer): Promise<ContainerBufferResult>
142
- async download(mode: DownloadModes = DownloadModes.Stream): Promise<http.IncomingMessage | ContainerBufferResult> {
143
- if (this.metadata.result !== ApiFieldResultTypes.CONTAINER) throw new Error("Cannot perform download() on a non-container field")
144
-
145
- let stream = await this.parent.layout.database.streamURL(this.string)
155
+ /**
156
+ * Downloads a resource from the server using the specified download mode.
157
+ *
158
+ * @param {DownloadModes} mode - The mode to use for downloading the resource.
159
+ * @return {Promise<http.IncomingMessage>} - A promise that resolves with the incoming message representing the downloaded resource.
160
+ */
161
+ download (mode: DownloadModes.Stream): Promise<http.IncomingMessage>
162
+ download (mode: DownloadModes.Buffer): Promise<ContainerBufferResult>
163
+ async download (mode: DownloadModes = DownloadModes.Stream): Promise<http.IncomingMessage | ContainerBufferResult> {
164
+ if (this.metadata.result !== ApiFieldResultTypes.CONTAINER) throw new Error('Cannot perform download() on a non-container field')
165
+
166
+ const stream = await this.parent.layout.database.streamURL(this.string)
146
167
  if (mode === DownloadModes.Stream) {
147
168
  return stream
148
169
  }
149
170
 
150
- let body: Uint8Array[] = []
151
- return new Promise((resolve, reject) => {
152
- stream.on("data", chunk => {
171
+ const body: Uint8Array[] = []
172
+ return await new Promise((resolve, reject) => {
173
+ stream.on('data', (chunk: Uint8Array) => {
153
174
  body.push(chunk)
154
175
  })
155
- stream.on("error", (e) => {
176
+ stream.on('error', (e) => {
156
177
  reject(e)
157
178
  })
158
- stream.on("end", () => {
179
+ stream.on('end', () => {
159
180
  resolve({
160
181
  buffer: Buffer.concat(body),
161
- mime: stream.headers["content-type"],
182
+ mime: stream.headers['content-type'],
162
183
  request: stream
163
- } as ContainerBufferResult)
184
+ } satisfies ContainerBufferResult)
164
185
  })
165
186
  })
166
187
  }
167
- }
188
+ }
@@ -1,54 +1,74 @@
1
- import { LayoutInterface } from "../../layouts/layoutInterface.js";
2
- import { PickPortals, ScriptRequestData } from "../../types.js";
3
- import { LayoutBase } from "../../layouts/layoutBase.js";
4
- import { LayoutRecord } from "../layoutRecord.js";
5
- import { Query } from "../../utils/query.js";
6
- export type SortOrder = "ascend" | "descend";
7
- export type FindRequestRaw = {
8
- [key: string]: string;
9
- };
10
- export type FindRequest = {
11
- [key: string]: Query;
12
- };
13
- export type PortalRequest = {
1
+ import { type LayoutInterface } from '../../layouts/layoutInterface.js';
2
+ import { type PickPortals, type ScriptRequestData } from '../../types.js';
3
+ import { type LayoutBase } from '../../layouts/layoutBase.js';
4
+ import { LayoutRecord } from '../layoutRecord.js';
5
+ import { type Query } from '../../utils/query.js';
6
+ export type SortOrder = 'ascend' | 'descend';
7
+ export type FindRequestRaw = Record<string, string>;
8
+ export type FindRequest = Record<string, Query>;
9
+ export interface PortalRequest {
14
10
  name: string;
15
- };
11
+ }
16
12
  type PortalData<T extends LayoutInterface> = {
17
- [key in keyof T["portals"]]: {
13
+ [key in keyof T['portals']]: {
18
14
  limit: number;
19
15
  offset: number;
20
16
  };
21
17
  };
22
- export type GetOperationOptions<T extends LayoutInterface> = {
18
+ export interface GetOperationOptions<T extends LayoutInterface> {
23
19
  portals: Partial<PortalData<T>>;
24
20
  limit?: number;
25
21
  offset?: number;
26
- };
22
+ }
27
23
  export declare class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOperationOptions<T>> {
28
24
  protected layout: LayoutBase;
29
25
  protected limit: number;
30
26
  protected scriptData: ScriptRequestData;
31
- protected sortData: {
27
+ protected sortData: Array<{
32
28
  fieldName: string;
33
29
  sortOrder: SortOrder;
34
- }[];
30
+ }>;
35
31
  protected portals: Partial<PortalData<T>>;
36
32
  protected offset: number;
37
- protected queries: {
33
+ protected queries: Array<{
38
34
  req: FindRequestRaw;
39
35
  omit: boolean;
40
- }[];
36
+ }>;
41
37
  constructor(layout: LayoutBase, options: OPTIONS);
42
38
  get isFindRequest(): boolean;
43
39
  private formatQueries;
44
- protected generateParamsBody(offset: number, limit: number): {
45
- [key: string]: any;
46
- };
40
+ protected generateParamsBody(offset: number, limit: number): Record<string, any>;
47
41
  protected generateParamsURL(offset: number, limit: number): URLSearchParams;
42
+ /**
43
+ * Configures any FileMaker scripts to be run as a part of the request
44
+ *
45
+ * @param {ScriptRequestData} scripts - The script request data to set.
46
+ * @return {this} - The current instance of the class.
47
+ */
48
48
  scripts(scripts: ScriptRequestData): this;
49
+ /**
50
+ * Sorts the data based on the given field name and sort order.
51
+ *
52
+ * @param {string} fieldName - The name of the field by which the data should be sorted.
53
+ * @param {SortOrder} sortOrder - The sort order to be applied (either "asc" for ascending or "desc" for descending).
54
+ *
55
+ * @return {this} - Returns the current instance of the object.
56
+ */
49
57
  sort(fieldName: string, sortOrder: SortOrder): this;
50
58
  private parseFindRequest;
59
+ /**
60
+ * Adds a new request/query to the list of queries.
61
+ *
62
+ * @param {FindRequest} query - The find request to be added.
63
+ * @param {boolean} [omit=false] - Flag to indicate if the find request should be omitted.
64
+ * @return {Object} - The current object instance.
65
+ */
51
66
  addRequest(query: FindRequest, omit?: boolean): this;
67
+ /**
68
+ * Perform a fetch operation.
69
+ *
70
+ * @returns {Promise} A promise that resolves with the result of the fetch operation.
71
+ */
52
72
  fetch(): Promise<LayoutRecord<PickPortals<T, keyof OPTIONS["portals"]>>[]>;
53
73
  private performFind;
54
74
  [Symbol.asyncIterator](): {
@@ -1,9 +1,9 @@
1
1
  /*
2
2
  * Copyright (c) 2023-2024. See LICENSE file for more information
3
3
  */
4
- import { LayoutRecord } from "../layoutRecord.js";
5
- import { FMError } from "../../FMError.js";
6
- import { FindRequestSymbol } from "../../utils/query.js";
4
+ import { LayoutRecord } from '../layoutRecord.js';
5
+ import { FMError } from '../../FMError.js';
6
+ import { FindRequestSymbol } from '../../utils/query.js';
7
7
  export class RecordGetOperation {
8
8
  layout;
9
9
  limit = 100;
@@ -16,16 +16,16 @@ export class RecordGetOperation {
16
16
  this.layout = layout;
17
17
  this.sortData = [];
18
18
  this.portals = options.portals;
19
- this.offset = options.offset || 1; // Offset refers to the starting record. offset 1 is the same as no offset.
20
- this.limit = options.limit || 100;
19
+ this.offset = options.offset ?? 1; // Offset refers to the starting record. offset 1 is the same as no offset.
20
+ this.limit = options.limit ?? 100;
21
21
  }
22
22
  get isFindRequest() {
23
23
  return this.queries.length !== 0;
24
24
  }
25
25
  formatQueries() {
26
- let test = this.queries.map(query => {
27
- let out = {};
28
- for (let key of Object.keys(query.req)) {
26
+ const test = this.queries.map(query => {
27
+ const out = {};
28
+ for (const key of Object.keys(query.req)) {
29
29
  if (query.req[key])
30
30
  out[key] = query.req[key];
31
31
  else {
@@ -33,7 +33,7 @@ export class RecordGetOperation {
33
33
  }
34
34
  }
35
35
  if (query.omit)
36
- out.omit = "true";
36
+ out.omit = 'true';
37
37
  return out;
38
38
  });
39
39
  return test;
@@ -47,22 +47,22 @@ export class RecordGetOperation {
47
47
  if (this.sortData.length !== 0)
48
48
  params.sort = this.sortData;
49
49
  if (this.scriptData.after)
50
- params["script"] = this.scriptData.after.name;
50
+ params.script = this.scriptData.after.name;
51
51
  if (this.scriptData.after?.parameter)
52
- params["script.param"] = this.scriptData.after.parameter;
52
+ params['script.param'] = this.scriptData.after.parameter;
53
53
  if (this.scriptData.presort)
54
- params["script.presort"] = this.scriptData.presort.name;
54
+ params['script.presort'] = this.scriptData.presort.name;
55
55
  if (this.scriptData.presort?.parameter)
56
- params["script.presort.param"] = this.scriptData.presort.parameter;
56
+ params['script.presort.param'] = this.scriptData.presort.parameter;
57
57
  if (this.scriptData.prerequest)
58
- params["script.prerequest"] = this.scriptData.prerequest.name;
58
+ params['script.prerequest'] = this.scriptData.prerequest.name;
59
59
  if (this.scriptData.prerequest?.parameter)
60
- params["script.prerequest.param"] = this.scriptData.prerequest.parameter;
60
+ params['script.prerequest.param'] = this.scriptData.prerequest.parameter;
61
61
  if (this.queries.length !== 0)
62
- params["query"] = this.formatQueries();
63
- let portals = Object.keys(this.portals);
64
- params["portal"] = portals;
65
- for (let portal of portals) {
62
+ params.query = this.formatQueries();
63
+ const portals = Object.keys(this.portals);
64
+ params.portal = portals;
65
+ for (const portal of portals) {
66
66
  params[`offset.${portal.toString()}`] = this.portals[portal]?.offset;
67
67
  params[`limit.${portal.toString()}`] = this.portals[portal]?.limit;
68
68
  }
@@ -72,80 +72,106 @@ export class RecordGetOperation {
72
72
  const params = new URLSearchParams({
73
73
  _limit: limit.toString(),
74
74
  _offset: offset.toString(),
75
- dateformats: "2" // Ensure dates are received in ISO8601 format
75
+ dateformats: '2' // Ensure dates are received in ISO8601 format
76
76
  });
77
77
  if (this.sortData.length !== 0)
78
- params.set("_sort", JSON.stringify(this.sortData));
78
+ params.set('_sort', JSON.stringify(this.sortData));
79
79
  if (this.scriptData.after)
80
- params.set("script", this.scriptData.after.name);
80
+ params.set('script', this.scriptData.after.name);
81
81
  if (this.scriptData.after?.parameter)
82
- params.set("script.param", this.scriptData.after.parameter);
82
+ params.set('script.param', this.scriptData.after.parameter);
83
83
  if (this.scriptData.presort)
84
- params.set("script.presort", this.scriptData.presort.name);
84
+ params.set('script.presort', this.scriptData.presort.name);
85
85
  if (this.scriptData.presort?.parameter)
86
- params.set("script.presort.param", this.scriptData.presort.parameter);
86
+ params.set('script.presort.param', this.scriptData.presort.parameter);
87
87
  if (this.scriptData.prerequest)
88
- params.set("script.prerequest", this.scriptData.prerequest.name);
88
+ params.set('script.prerequest', this.scriptData.prerequest.name);
89
89
  if (this.scriptData.prerequest?.parameter)
90
- params.set("script.prerequest.param", this.scriptData.prerequest.parameter);
91
- let portals = Object.keys(this.portals);
92
- for (let portal of portals) {
93
- params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.limit || "").toString());
94
- params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.offset || "").toString());
90
+ params.set('script.prerequest.param', this.scriptData.prerequest.parameter);
91
+ const portals = Object.keys(this.portals);
92
+ for (const portal of portals) {
93
+ params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.limit ?? '').toString());
94
+ params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.offset ?? '').toString());
95
95
  }
96
96
  params.set('portal', JSON.stringify(portals));
97
97
  return params;
98
98
  }
99
+ /**
100
+ * Configures any FileMaker scripts to be run as a part of the request
101
+ *
102
+ * @param {ScriptRequestData} scripts - The script request data to set.
103
+ * @return {this} - The current instance of the class.
104
+ */
99
105
  scripts(scripts) {
100
106
  this.scriptData = scripts;
101
107
  return this;
102
108
  }
109
+ /**
110
+ * Sorts the data based on the given field name and sort order.
111
+ *
112
+ * @param {string} fieldName - The name of the field by which the data should be sorted.
113
+ * @param {SortOrder} sortOrder - The sort order to be applied (either "asc" for ascending or "desc" for descending).
114
+ *
115
+ * @return {this} - Returns the current instance of the object.
116
+ */
103
117
  sort(fieldName, sortOrder) {
104
118
  this.sortData.push({ fieldName, sortOrder });
105
119
  return this;
106
120
  }
107
121
  parseFindRequest(query) {
108
- let out = {};
109
- for (let key of Object.keys(query)) {
122
+ const out = {};
123
+ for (const key of Object.keys(query)) {
110
124
  out[key] = query[key][FindRequestSymbol].map(item => {
111
- if (typeof item === "string")
125
+ if (typeof item === 'string')
112
126
  return item;
113
127
  // Re-write date into correct format
114
128
  return item
115
129
  .moment
116
130
  .clone()
117
131
  .utcOffset(this.layout.database.host.timezoneOffsetFunc(item.moment))
118
- .format(item.type === "date" ?
119
- this.layout.database.host.dateFormat :
120
- item.type == "time" ?
121
- this.layout.database.host.timeFormat :
122
- this.layout.database.host.timeStampFormat);
123
- }).join("");
132
+ .format(item.type === 'date'
133
+ ? this.layout.database.host.dateFormat
134
+ : item.type == 'time'
135
+ ? this.layout.database.host.timeFormat
136
+ : this.layout.database.host.timeStampFormat);
137
+ }).join('');
124
138
  }
125
139
  return out;
126
140
  }
141
+ /**
142
+ * Adds a new request/query to the list of queries.
143
+ *
144
+ * @param {FindRequest} query - The find request to be added.
145
+ * @param {boolean} [omit=false] - Flag to indicate if the find request should be omitted.
146
+ * @return {Object} - The current object instance.
147
+ */
127
148
  addRequest(query, omit = false) {
128
149
  this.queries.push({ req: this.parseFindRequest(query), omit });
129
150
  return this;
130
151
  }
131
- fetch() {
132
- return this.performFind(this.offset, this.limit);
152
+ /**
153
+ * Perform a fetch operation.
154
+ *
155
+ * @returns {Promise} A promise that resolves with the result of the fetch operation.
156
+ */
157
+ async fetch() {
158
+ return await this.performFind(this.offset, this.limit);
133
159
  }
134
160
  async performFind(offset, limit) {
135
- let trace = new Error();
161
+ const trace = new Error();
136
162
  await this.layout.getLayoutMeta();
137
- const is_find = this.isFindRequest;
138
- let endpoint = this.layout.endpoint + (is_find ? "/_find" : "/records");
139
- if (!is_find)
140
- endpoint += "?" + new URLSearchParams(this.generateParamsURL(offset, limit)).toString();
163
+ const isFind = this.isFindRequest;
164
+ let endpoint = this.layout.endpoint + (isFind ? '/_find' : '/records');
165
+ if (!isFind)
166
+ endpoint += '?' + new URLSearchParams(this.generateParamsURL(offset, limit)).toString();
141
167
  const reqData = {
142
168
  // port: 443,
143
- method: is_find ? "POST" : "GET",
144
- body: is_find ? JSON.stringify(this.generateParamsBody(offset, limit)) : undefined,
169
+ method: isFind ? 'POST' : 'GET',
170
+ body: isFind ? JSON.stringify(this.generateParamsBody(offset, limit)) : undefined
145
171
  };
146
172
  try {
147
- let res = await this.layout.database.apiRequestJSON(endpoint, reqData);
148
- if (res.messages[0].code === "0" && res.response) {
173
+ const res = await this.layout.database._apiRequestJSON(endpoint, reqData);
174
+ if (res.messages[0].code === '0' && res.response) {
149
175
  // console.log("RESOLVING")
150
176
  if (!this.layout.metadata)
151
177
  await this.layout.getLayoutMeta();
@@ -169,28 +195,28 @@ export class RecordGetOperation {
169
195
  }
170
196
  [Symbol.asyncIterator]() {
171
197
  let nextOffset = this.offset;
172
- let startOffset = JSON.parse(JSON.stringify(this.offset));
173
- let limit = this.limit;
174
- let exit_after_last_record = false;
198
+ const startOffset = JSON.parse(JSON.stringify(this.offset));
199
+ const limit = this.limit;
200
+ let exitAfterLastRecord = false;
175
201
  let records = [];
176
202
  const fetch = async () => {
177
- const theoretical_limit = (limit - nextOffset) + startOffset;
178
- if (theoretical_limit === 0) {
179
- exit_after_last_record = true;
203
+ const theoreticalLimit = (limit - nextOffset) + startOffset;
204
+ if (theoreticalLimit === 0) {
205
+ exitAfterLastRecord = true;
180
206
  records = [];
181
207
  return;
182
208
  }
183
- records = await this.performFind(nextOffset, theoretical_limit < 100 ? theoretical_limit : 100);
209
+ records = await this.performFind(nextOffset, theoreticalLimit < 100 ? theoreticalLimit : 100);
184
210
  nextOffset += 100;
185
211
  if (records.length < 100)
186
- exit_after_last_record = true;
212
+ exitAfterLastRecord = true;
187
213
  };
188
214
  return {
189
215
  next: async () => {
190
- if (records.length === 0 && !exit_after_last_record) {
216
+ if (records.length === 0 && !exitAfterLastRecord) {
191
217
  await fetch();
192
218
  }
193
- if (records.length === 0 && exit_after_last_record) {
219
+ if (records.length === 0 && exitAfterLastRecord) {
194
220
  return { done: true, value: undefined };
195
221
  }
196
222
  else {