@jd-data-limited/easy-fm 4.0.11 → 4.0.12

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 (36) hide show
  1. package/package.json +1 -1
  2. package/src/bin/cli.d.ts +2 -0
  3. package/src/bin/cli.js +17 -0
  4. package/src/bin/generateTypes.d.ts +1 -0
  5. package/src/bin/generateTypes.js +161 -0
  6. package/src/bin/generateTypes.ts +10 -7
  7. package/src/index.d.ts +3 -3
  8. package/src/index.js +2 -2
  9. package/src/index.ts +4 -4
  10. package/src/layouts/recordFieldsMap.d.ts +2 -2
  11. package/src/layouts/recordFieldsMap.ts +2 -2
  12. package/src/records/field.d.ts +16 -10
  13. package/src/records/field.js +43 -59
  14. package/src/records/{fieldBase.ts → field.ts} +4 -11
  15. package/src/records/getOperations/recordGetOperation.d.ts +5 -1
  16. package/src/records/getOperations/recordGetOperation.js +22 -4
  17. package/src/records/getOperations/recordGetOperation.ts +26 -4
  18. package/src/records/layoutRecord.d.ts +3 -3
  19. package/src/records/layoutRecord.js +1 -1
  20. package/src/records/layoutRecord.ts +6 -6
  21. package/src/records/portalRecord.d.ts +2 -2
  22. package/src/records/portalRecord.ts +2 -2
  23. package/src/records/recordBase.d.ts +2 -2
  24. package/src/records/recordBase.js +5 -5
  25. package/src/records/recordBase.ts +7 -6
  26. package/src/utils/query.d.ts +4 -5
  27. package/src/utils/query.js +11 -4
  28. package/src/utils/query.ts +14 -7
  29. package/src/records/fieldBase.d.ts +0 -30
  30. package/src/records/fieldBase.js +0 -155
  31. package/src/records/getOperations/find.d.ts +0 -15
  32. package/src/records/getOperations/find.js +0 -80
  33. package/src/records/getOperations/recordGetRange.d.ts +0 -13
  34. package/src/records/getOperations/recordGetRange.js +0 -88
  35. package/src/records/portalRecordBase.d.ts +0 -4
  36. package/src/records/portalRecordBase.js +0 -6
@@ -11,6 +11,9 @@ import {FMError} from "../../FMError.js";
11
11
  import {FindRequestSymbol, Query} from "../../utils/query.js";
12
12
 
13
13
  export type SortOrder = "ascend" | "descend"
14
+ export type FindRequestRaw = {
15
+ [key: string]: string
16
+ }
14
17
  export type FindRequest = {
15
18
  [key: string]: Query
16
19
  }
@@ -38,7 +41,7 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
38
41
  protected sortData: { fieldName: string, sortOrder: SortOrder }[] = []
39
42
  protected portals: Partial<PortalData<T>>
40
43
  protected offset: number = 1
41
- protected queries: {req: FindRequest, omit: boolean}[] = []
44
+ protected queries: {req: FindRequestRaw, omit: boolean}[] = []
42
45
 
43
46
  constructor(layout: LayoutBase, options: OPTIONS) {
44
47
  this.layout = layout
@@ -53,21 +56,23 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
53
56
  }
54
57
 
55
58
  private formatQueries() {
56
- return this.queries.map(query => {
59
+ let test = this.queries.map(query => {
57
60
  let out: any = {}
58
61
  for (let key of Object.keys(query.req)) {
59
- if (query.req[key][FindRequestSymbol]) out[key] = query.req[key][FindRequestSymbol]
62
+ if (query.req[key]) out[key] = query.req[key]
60
63
  else {out[key] = query.req[key]}
61
64
  }
62
65
  if (query.omit) out.omit = "true"
63
66
  return out
64
67
  })
68
+ return test
65
69
  }
66
70
 
67
71
  protected generateParamsBody(offset: number, limit: number) {
68
72
  const params: {[key: string]: any} = {
69
73
  limit: limit.toString(),
70
74
  offset: offset.toString(),
75
+ dateformats: 2 // Ensure dates are received in ISO8601 format
71
76
  }
72
77
  if (this.sortData.length !== 0) params.sort = this.sortData
73
78
 
@@ -96,6 +101,7 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
96
101
  const params = new URLSearchParams({
97
102
  _limit: limit.toString(),
98
103
  _offset: offset.toString(),
104
+ dateformats: "2" // Ensure dates are received in ISO8601 format
99
105
  })
100
106
  if (this.sortData.length !== 0) params.set("_sort", JSON.stringify(this.sortData))
101
107
 
@@ -128,8 +134,24 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
128
134
  return this
129
135
  }
130
136
 
137
+ private parseFindRequest<I extends FindRequest>(query: I): {[key in keyof I]: string} {
138
+ let out: any = {}
139
+ for (let key of Object.keys(query)) {
140
+ out[key] = query[key][FindRequestSymbol].map(item => {
141
+ if (typeof item === "string") return item
142
+
143
+ // Re-write date into correct format
144
+ return item
145
+ .clone()
146
+ .utcOffset(this.layout.database.host.timezoneOffset)
147
+ .format("MM/DD/YYYY HH:mm:ss")
148
+ }).join("")
149
+ }
150
+ return out
151
+ }
152
+
131
153
  addRequest(query: FindRequest, omit = false) {
132
- this.queries.push({req: query, omit})
154
+ this.queries.push({req: this.parseFindRequest(query), omit})
133
155
  return this
134
156
  }
135
157
 
@@ -6,7 +6,7 @@ import { LayoutInterface } from "../layouts/layoutInterface.js";
6
6
  import { LayoutRecordBase } from "./layoutRecordBase.js";
7
7
  import { ApiPortalData, ApiRowDataDef } from "../models/apiResults.js";
8
8
  import { LayoutBase } from "../layouts/layoutBase.js";
9
- import { FieldBase, FieldValue } from "./fieldBase.js";
9
+ import { Field, FieldValue } from "./field.js";
10
10
  export declare class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
11
11
  portals: LAYOUT["portals"];
12
12
  private readonly portalsToInclude;
@@ -17,6 +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
- 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;
20
+ fieldsToObject(filter?: (a: Field<FieldValue>) => boolean): Omit<ApiRowDataDef, "portalData">;
21
+ toObject(filter?: (a: Field<FieldValue>) => any, portalFilter?: (a: Portal<any>) => any, portalRowFilter?: (a: PortalRecord<never>) => any, portalFieldFilter?: (a: Field<FieldValue>) => any): ApiRowDataDef;
22
22
  }
@@ -186,7 +186,7 @@ export class LayoutRecord extends RecordBase {
186
186
  toObject(filter = (a) => a.edited, portalFilter = (a) => a.records.find(record => record.edited), portalRowFilter = (a) => a.edited, portalFieldFilter = (a) => a.edited) {
187
187
  let obj = {
188
188
  ...this.fieldsToObject(filter),
189
- portalData: {}
189
+ portalData: {},
190
190
  };
191
191
  // Check if there's been any edited portal information
192
192
  let portals = this.portalsArray.filter(a => portalFilter(a));
@@ -11,8 +11,8 @@ import {FMError} from "../FMError.js";
11
11
  import {LayoutRecordBase} from "./layoutRecordBase.js";
12
12
  import {ApiFieldData, ApiPortalData, ApiRecordResponseObj, ApiRowDataDef} from "../models/apiResults.js";
13
13
  import {LayoutBase} from "../layouts/layoutBase.js"
14
- import {FieldBase, FieldValue} from "./fieldBase.js";
15
14
  import * as moment from "moment/moment.js";
15
+ import {Field, FieldValue} from "./field.js";
16
16
 
17
17
  export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
18
18
  // @ts-ignore
@@ -182,9 +182,9 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
182
182
  }
183
183
  }
184
184
 
185
- fieldsToObject(filter = (a: FieldBase<FieldValue>) => a.edited): Omit<ApiRowDataDef, "portalData"> {
185
+ fieldsToObject(filter = (a: Field<FieldValue>) => a.edited): Omit<ApiRowDataDef, "portalData"> {
186
186
  let fields_processed: ApiFieldData = {}
187
- let field: FieldBase<FieldValue>
187
+ let field: Field<FieldValue>
188
188
  for (field of this.fieldsArray.filter(field => filter(field))) {
189
189
  let value = field.value as string | number | Date
190
190
  if (value instanceof Date) {
@@ -216,14 +216,14 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
216
216
  }
217
217
 
218
218
  toObject(
219
- filter: (a: FieldBase<FieldValue>) => any = (a) => a.edited,
219
+ filter: (a: Field<FieldValue>) => any = (a) => a.edited,
220
220
  portalFilter: (a: Portal<any>) => any = (a) => a.records.find(record => record.edited),
221
221
  portalRowFilter: (a: PortalRecord<never>) => any = (a) => a.edited,
222
- portalFieldFilter: (a: FieldBase<FieldValue>) => any = (a) => a.edited
222
+ portalFieldFilter: (a: Field<FieldValue>) => any = (a) => a.edited
223
223
  ) {
224
224
  let obj: ApiRowDataDef = {
225
225
  ...this.fieldsToObject(filter),
226
- portalData: {}
226
+ portalData: {},
227
227
  };
228
228
 
229
229
  // Check if there's been any edited portal information
@@ -2,14 +2,14 @@ import { RecordBase } from "./recordBase.js";
2
2
  import { extraBodyOptions, RecordTypes } from "../types.js";
3
3
  import { RecordFieldsMap } from "../layouts/recordFieldsMap.js";
4
4
  import { PortalBase } from "./portalBase.js";
5
- import { FieldBase, FieldValue } from "./fieldBase.js";
5
+ import { Field, FieldValue } from "./field.js";
6
6
  export declare class PortalRecord<T extends RecordFieldsMap> extends RecordBase<T> {
7
7
  readonly portal: PortalBase<T>;
8
8
  readonly type = RecordTypes.PORTAL;
9
9
  constructor(record: RecordBase<any>, portal: PortalBase<any>, recordId: number, modId?: number, fieldData?: {});
10
10
  _onSave(): void;
11
11
  commit(extraBody?: extraBodyOptions): Promise<import("./layoutRecord.js").LayoutRecord<import("../index.js").LayoutInterface>>;
12
- toObject(fieldFilter: (a: FieldBase<FieldValue>) => boolean): {
12
+ toObject(fieldFilter: (a: Field<FieldValue>) => boolean): {
13
13
  modId?: string;
14
14
  recordId?: string;
15
15
  } & {
@@ -7,7 +7,7 @@ import {extraBodyOptions, RecordTypes} from "../types.js";
7
7
 
8
8
  import {RecordFieldsMap} from "../layouts/recordFieldsMap.js";
9
9
  import {PortalBase} from "./portalBase.js";
10
- import {FieldBase, FieldValue} from "./fieldBase.js";
10
+ import {Field, FieldValue} from "./field.js";
11
11
 
12
12
  export class PortalRecord<T extends RecordFieldsMap> extends RecordBase<T> {
13
13
  readonly portal: PortalBase<T>;
@@ -27,7 +27,7 @@ export class PortalRecord<T extends RecordFieldsMap> extends RecordBase<T> {
27
27
  return this.portal.record.commit(extraBody)
28
28
  }
29
29
 
30
- toObject(fieldFilter: (a: FieldBase<FieldValue>) => boolean): {
30
+ toObject(fieldFilter: (a: Field<FieldValue>) => boolean): {
31
31
  modId?: string,
32
32
  recordId?: string,
33
33
  } & {[key: string]: string} {
@@ -1,10 +1,10 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  import { EventEmitter } from "events";
3
- import { FieldBase, FieldValue } from "./fieldBase.js";
4
3
  import { RecordTypes } from "../types.js";
5
4
  import { RecordFieldsMap } from "../layouts/recordFieldsMap.js";
6
5
  import { LayoutBase } from "../layouts/layoutBase.js";
7
6
  import { ApiFieldData } from "../models/apiResults.js";
7
+ import { Field, FieldValue } from "./field.js";
8
8
  export declare abstract class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
9
9
  readonly layout: LayoutBase;
10
10
  readonly type: RecordTypes;
@@ -15,7 +15,7 @@ export declare abstract class RecordBase<T extends RecordFieldsMap> extends Even
15
15
  protected constructor(layout: LayoutBase, recordId: number, modId: number | undefined, fieldData: ApiFieldData);
16
16
  get endpoint(): string;
17
17
  get edited(): boolean;
18
- get fieldsArray(): FieldBase<FieldValue>[];
18
+ get fieldsArray(): Field<FieldValue>[];
19
19
  protected processFieldData(fieldData: ApiFieldData): T;
20
20
  _onSave(): void;
21
21
  }
@@ -3,8 +3,8 @@
3
3
  */
4
4
  import { EventEmitter } from "events";
5
5
  import * as moment from "moment";
6
- import { FieldBase } from "./fieldBase.js";
7
6
  import { RecordTypes } from "../types.js";
7
+ import { Field } from "./field.js";
8
8
  export class RecordBase extends EventEmitter {
9
9
  layout;
10
10
  type = RecordTypes.UNKNOWN;
@@ -31,14 +31,14 @@ export class RecordBase extends EventEmitter {
31
31
  processFieldData(fieldData) {
32
32
  let fields = {};
33
33
  for (let key of Object.keys(fieldData)) {
34
- let _field = new FieldBase(this, key, fieldData[key]);
34
+ let _field = new Field(this, key, fieldData[key]);
35
35
  if (!!fieldData[key]) {
36
36
  if (_field.metadata.result === "timeStamp") {
37
37
  // @ts-ignore
38
38
  let date = moment.default(fieldData[key], this.layout.database.host.metadata.productInfo.timeStampFormat.replace("dd", "DD"))
39
39
  .utcOffset(this.layout.database.host.timezoneOffset, true)
40
40
  .local();
41
- _field.set(date.toDate());
41
+ _field.set(date);
42
42
  _field.edited = false;
43
43
  }
44
44
  else if (_field.metadata.result === "time") {
@@ -46,7 +46,7 @@ export class RecordBase extends EventEmitter {
46
46
  let date = moment.default(fieldData[key], this.layout.database.host.metadata.productInfo.timeFormat.replace("dd", "DD"))
47
47
  .utcOffset(this.layout.database.host.timezoneOffset, true)
48
48
  .local();
49
- _field.set(date.toDate());
49
+ _field.set(date);
50
50
  _field.edited = false;
51
51
  }
52
52
  else if (_field.metadata.result === "date") {
@@ -54,7 +54,7 @@ export class RecordBase extends EventEmitter {
54
54
  let date = moment.default(fieldData[key], this.layout.database.host.metadata.productInfo.dateFormat.replace("dd", "DD"))
55
55
  .utcOffset(this.layout.database.host.timezoneOffset, true)
56
56
  .local();
57
- _field.set(date.toDate());
57
+ _field.set(date);
58
58
  _field.edited = false;
59
59
  }
60
60
  }
@@ -4,11 +4,12 @@
4
4
 
5
5
  import {EventEmitter} from "events";
6
6
  import * as moment from "moment";
7
- import {FieldBase, FieldValue} from "./fieldBase.js";
7
+ import {Moment} from "moment";
8
8
  import {RecordTypes} from "../types.js";
9
9
  import {RecordFieldsMap} from "../layouts/recordFieldsMap.js";
10
10
  import {LayoutBase} from "../layouts/layoutBase.js";
11
11
  import {ApiFieldData} from "../models/apiResults.js";
12
+ import {Field, FieldValue} from "./field.js";
12
13
 
13
14
  export abstract class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
14
15
  readonly layout: LayoutBase;
@@ -34,7 +35,7 @@ export abstract class RecordBase<T extends RecordFieldsMap> extends EventEmitter
34
35
  return !!this.fieldsArray.find(i => i.edited)
35
36
  }
36
37
 
37
- get fieldsArray(): FieldBase<FieldValue>[] {
38
+ get fieldsArray(): Field<FieldValue>[] {
38
39
  return Object.values(this.fields)
39
40
  }
40
41
 
@@ -42,14 +43,14 @@ export abstract class RecordBase<T extends RecordFieldsMap> extends EventEmitter
42
43
  let fields: RecordFieldsMap = {}
43
44
 
44
45
  for (let key of Object.keys(fieldData)) {
45
- let _field = new FieldBase(this, key, fieldData[key])
46
+ let _field = new Field<number | string | Moment>(this, key, fieldData[key])
46
47
  if (!!fieldData[key]) {
47
48
  if (_field.metadata.result === "timeStamp") {
48
49
  // @ts-ignore
49
50
  let date = moment.default(fieldData[key], this.layout.database.host.metadata.productInfo.timeStampFormat.replace("dd", "DD"))
50
51
  .utcOffset(this.layout.database.host.timezoneOffset, true)
51
52
  .local()
52
- _field.set(date.toDate())
53
+ _field.set(date)
53
54
  _field.edited = false
54
55
 
55
56
  }
@@ -58,7 +59,7 @@ export abstract class RecordBase<T extends RecordFieldsMap> extends EventEmitter
58
59
  let date = moment.default(fieldData[key], this.layout.database.host.metadata.productInfo.timeFormat.replace("dd", "DD"))
59
60
  .utcOffset(this.layout.database.host.timezoneOffset, true)
60
61
  .local()
61
- _field.set(date.toDate())
62
+ _field.set(date)
62
63
  _field.edited = false
63
64
  }
64
65
  else if (_field.metadata.result === "date") {
@@ -66,7 +67,7 @@ export abstract class RecordBase<T extends RecordFieldsMap> extends EventEmitter
66
67
  let date = moment.default(fieldData[key], this.layout.database.host.metadata.productInfo.dateFormat.replace("dd", "DD"))
67
68
  .utcOffset(this.layout.database.host.timezoneOffset, true)
68
69
  .local()
69
- _field.set(date.toDate())
70
+ _field.set(date)
70
71
  _field.edited = false
71
72
  }
72
73
  }
@@ -1,10 +1,9 @@
1
+ import { Moment } from "moment";
1
2
  export declare const FindRequestSymbol: unique symbol;
2
- type QueryParameter = string | number | Date;
3
+ type QueryParameter = string | number | Moment;
3
4
  export type Query = {
4
- [FindRequestSymbol]: string;
5
+ [FindRequestSymbol]: (string | Moment)[];
5
6
  };
6
7
  export declare function queryEscape(str: string): string;
7
- export declare function query(strings: TemplateStringsArray, ...args: QueryParameter[]): {
8
- [FindRequestSymbol]: string;
9
- };
8
+ export declare function query(strings: TemplateStringsArray, ...args: QueryParameter[]): Query;
10
9
  export {};
@@ -1,6 +1,7 @@
1
1
  /*
2
2
  * Copyright (c) 2024. See LICENSE file for more information
3
3
  */
4
+ import moment from "moment/moment.js";
4
5
  export const FindRequestSymbol = Symbol("easyfm-findrequest");
5
6
  const SPECIAL_CHARACTERS = ["\\", "=", "<", "≤", "≥", ">", "…", "...", "//", "@", "#", "*", "\"", "~"];
6
7
  export function queryEscape(str) {
@@ -11,11 +12,17 @@ export function queryEscape(str) {
11
12
  }
12
13
  export function query(strings, ...args) {
13
14
  let argStrings = args.map(item => {
14
- return queryEscape(item.toString());
15
+ if (moment.isMoment(item))
16
+ return item;
17
+ else if (typeof item === "number") {
18
+ return queryEscape(item.toString());
19
+ }
20
+ else
21
+ return queryEscape(item);
15
22
  });
16
23
  // Zip the parameters together
17
24
  const query = strings.map((str, index) => {
18
- return str + (argStrings[index] || '');
19
- });
20
- return { [FindRequestSymbol]: query.join("") };
25
+ return [str, (argStrings[index] || '')];
26
+ }).flat(1);
27
+ return { [FindRequestSymbol]: query };
21
28
  }
@@ -2,10 +2,13 @@
2
2
  * Copyright (c) 2024. See LICENSE file for more information
3
3
  */
4
4
 
5
+ import {Moment} from "moment";
6
+ import moment from "moment/moment.js";
7
+
5
8
  export const FindRequestSymbol = Symbol("easyfm-findrequest");
6
9
  const SPECIAL_CHARACTERS = ["\\", "=", "<", "≤", "≥", ">", "…", "...", "//", "@", "#", "*", "\"", "~"]
7
- type QueryParameter = string | number | Date
8
- export type Query = {[FindRequestSymbol]: string}
10
+ type QueryParameter = string | number | Moment
11
+ export type Query = {[FindRequestSymbol]: (string | Moment)[]}
9
12
 
10
13
  export function queryEscape(str: string) {
11
14
  for (let char of SPECIAL_CHARACTERS) {
@@ -14,14 +17,18 @@ export function queryEscape(str: string) {
14
17
  return str
15
18
  }
16
19
 
17
- export function query(strings: TemplateStringsArray, ...args: QueryParameter[]) {
20
+ export function query(strings: TemplateStringsArray, ...args: QueryParameter[]): Query {
18
21
  let argStrings = args.map(item => {
19
- return queryEscape(item.toString())
22
+ if (moment.isMoment(item)) return item
23
+ else if (typeof item === "number") {
24
+ return queryEscape(item.toString())
25
+ }
26
+ else return queryEscape(item)
20
27
  })
21
28
 
22
29
  // Zip the parameters together
23
30
  const query = strings.map((str, index) => {
24
- return str + (argStrings[index] || '')
25
- })
26
- return {[FindRequestSymbol]: query.join("")}
31
+ return [str, (argStrings[index] || '')]
32
+ }).flat(1)
33
+ return {[FindRequestSymbol]: query}
27
34
  }
@@ -1,30 +0,0 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- /// <reference types="node" resolution-mode="require"/>
3
- import * as http from "http";
4
- import { ContainerBufferResult, DownloadModes, RecordTypes } from "../types.js";
5
- import { ApiFieldMetadata } from "../models/apiResults.js";
6
- import { LayoutBase } from "../layouts/layoutBase.js";
7
- export type FieldValue = string | number | Date | Container;
8
- export type Container = null;
9
- export type Parentable = {
10
- layout: LayoutBase;
11
- type: RecordTypes;
12
- endpoint: string;
13
- };
14
- export declare class FieldBase<T extends FieldValue> {
15
- parent: Parentable;
16
- id: string;
17
- protected _value: T;
18
- edited: boolean;
19
- constructor(record: Parentable, id: string, contents: T);
20
- set(content: string | number | Date | undefined | null): void;
21
- get metadata(): ApiFieldMetadata;
22
- get value(): T;
23
- set value(value: T);
24
- get string(): string;
25
- get date(): Date;
26
- get number(): number;
27
- upload(buffer: Buffer, filename: string, mime: string): Promise<void>;
28
- download(mode: DownloadModes.Stream): Promise<http.IncomingMessage>;
29
- download(mode: DownloadModes.Buffer): Promise<ContainerBufferResult>;
30
- }
@@ -1,155 +0,0 @@
1
- /*
2
- * Copyright (c) 2023-2024. See LICENSE file for more information
3
- */
4
- import { DownloadModes, RecordTypes } from "../types.js";
5
- import { ApiFieldDisplayTypes, ApiFieldResultTypes, ApiFieldTypes } from "../models/apiResults.js";
6
- export class FieldBase {
7
- parent;
8
- id;
9
- _value;
10
- edited;
11
- constructor(record, id, contents) {
12
- this.parent = record;
13
- this.id = id;
14
- this._value = contents;
15
- this.edited = false;
16
- }
17
- set(content) {
18
- if (this.metadata.result === "container")
19
- throw "Cannot set container value using set(). Use upload() instead.";
20
- if ((this.metadata.result === "timeStamp" ||
21
- this.metadata.result === "date" ||
22
- this.metadata.result === "time")
23
- && !(content instanceof Date) && !!content) {
24
- throw "Value was not an instance of Date: " + content;
25
- }
26
- // @ts-ignore
27
- if (!content)
28
- this._value = "";
29
- // @ts-ignore
30
- else
31
- this._value = content;
32
- this.edited = true;
33
- }
34
- get metadata() {
35
- if (!this.parent.layout.metadata) {
36
- // Default to a regular text field
37
- return {
38
- name: this.id.toString(),
39
- type: ApiFieldTypes.NORMAL,
40
- displayType: ApiFieldDisplayTypes.EDIT_TEXT,
41
- result: ApiFieldResultTypes.TEXT,
42
- global: false,
43
- autoEnter: true,
44
- fourDigitYear: false,
45
- maxRepeat: 1,
46
- maxCharacters: 0,
47
- notEmpty: false,
48
- numeric: false,
49
- timeOfDay: false,
50
- repetitions: 1,
51
- valueList: ""
52
- };
53
- }
54
- if (this.parent.type === RecordTypes.PORTAL) {
55
- // @ts-ignore
56
- return this.parent.layout.metadata.portalMetaData[this.parent.portal.name || "portal not attached"].find(i => i.name === this.id) || {
57
- name: this.id.toString(),
58
- type: 'normal',
59
- displayType: 'editText',
60
- result: 'text',
61
- global: false,
62
- autoEnter: true,
63
- fourDigitYear: false,
64
- maxRepeat: 1,
65
- maxCharacters: 0,
66
- notEmpty: false,
67
- numeric: false,
68
- timeOfDay: false,
69
- repetitionStart: 1,
70
- repetitionEnd: 1
71
- };
72
- }
73
- else {
74
- return this.parent.layout.metadata.fieldMetaData.find(i => i.name === this.id) || {
75
- name: this.id.toString(),
76
- type: ApiFieldTypes.NORMAL,
77
- displayType: ApiFieldDisplayTypes.EDIT_TEXT,
78
- result: ApiFieldResultTypes.TEXT,
79
- global: false,
80
- autoEnter: true,
81
- fourDigitYear: false,
82
- maxRepeat: 1,
83
- maxCharacters: 0,
84
- notEmpty: false,
85
- numeric: false,
86
- timeOfDay: false,
87
- repetitions: 1,
88
- valueList: ""
89
- };
90
- }
91
- }
92
- get value() {
93
- // if (this.metadata.result === "container") throw "Use await field.stream() to get the contents of a container field, instead of field.value"
94
- return this._value;
95
- }
96
- set value(value) {
97
- this._value = value;
98
- }
99
- get string() {
100
- if (typeof this._value === "string") {
101
- return this._value;
102
- }
103
- throw "Field value is not a string";
104
- }
105
- get date() {
106
- if (this._value instanceof Date) {
107
- return this._value;
108
- }
109
- throw "Field value is not a date";
110
- }
111
- get number() {
112
- if (typeof this._value === "number") {
113
- return this._value;
114
- }
115
- throw "Field value is not a number";
116
- }
117
- async upload(buffer, filename, mime) {
118
- let trace = new Error();
119
- if (this.metadata.result !== "container")
120
- throw "Cannot upload a file to the field; " + this.id + " (not a container field)";
121
- let form = new FormData();
122
- form.append("upload", new File([buffer], filename, { type: mime }));
123
- let res = await this.parent.layout.database.apiRequestRaw(`${this.parent.endpoint}/containers/${this.id}/1`, {
124
- method: "POST",
125
- // @ts-ignore
126
- body: form
127
- });
128
- if (!res.ok)
129
- throw new Error(`Upload failed with HTTP error: ${res.status} (${res.statusText})`);
130
- }
131
- async download(mode = DownloadModes.Stream) {
132
- if (this.metadata.result !== ApiFieldResultTypes.CONTAINER)
133
- throw new Error("Cannot perform download() on a non-container field");
134
- let stream = await this.parent.layout.database.streamURL(this.string);
135
- if (mode === DownloadModes.Stream) {
136
- return stream;
137
- }
138
- let body = [];
139
- return new Promise((resolve, reject) => {
140
- stream.on("data", chunk => {
141
- body.push(chunk);
142
- });
143
- stream.on("error", (e) => {
144
- reject(e);
145
- });
146
- stream.on("end", () => {
147
- resolve({
148
- buffer: Buffer.concat(body),
149
- mime: stream.headers["content-type"],
150
- request: stream
151
- });
152
- });
153
- });
154
- }
155
- }
@@ -1,15 +0,0 @@
1
- import { RecordGetOperation } from "./recordGetOperation.js";
2
- import { LayoutRecord } from "../layoutRecord.js";
3
- import { LayoutInterface } from "../../layouts/layoutInterface";
4
- import { LayoutBase } from "../../layouts/layoutBase.js";
5
- export declare class Find<T extends LayoutInterface> extends RecordGetOperation<T> {
6
- protected queries: object[];
7
- constructor(layout: LayoutBase, start?: number, limit?: number);
8
- private toObject;
9
- addRequests(...requests: any[]): this;
10
- /**
11
- * @deprecated in favour of .fetch()
12
- */
13
- run(): Promise<LayoutRecord<T["fields"], T["portals"]>[]>;
14
- fetch(): Promise<LayoutRecord<T["fields"], T["portals"]>[]>;
15
- }