@jd-data-limited/easy-fm 4.0.0 → 4.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jd-data-limited/easy-fm",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "dependencies": {
5
5
  "follow-redirects": "^1.15.5",
6
6
  "moment": "^2.29.4"
@@ -37,6 +37,7 @@
37
37
  "@types/events": "^3.0.0",
38
38
  "@types/follow-redirects": "^1.14.4",
39
39
  "dotenv": "^16.3.1",
40
+ "ts-morph": "^21.0.1",
40
41
  "typescript": "^5.3.3",
41
42
  "webpack": "^5.81.0",
42
43
  "webpack-cli": "^5.0.2"
@@ -25,8 +25,7 @@ export declare class Database<T extends DatabaseStructure> extends EventEmitter
25
25
  listLayouts(): Promise<Layout<LayoutInterface>[]>;
26
26
  getLayout<R extends keyof T["layouts"]>(name: R): Layout<T["layouts"][R]>;
27
27
  getLayout<R extends LayoutInterface>(name: string): Layout<R>;
28
- setGlobals(globalFields: any): Promise<void>;
29
- script(name: any, parameter?: string): Script;
28
+ script(name: string, parameter?: string): Script;
30
29
  _tokenExpired(): void;
31
30
  streamURL(url: string): Promise<IncomingMessage>;
32
31
  }
@@ -115,24 +115,25 @@ export class Database extends EventEmitter {
115
115
  return data;
116
116
  }
117
117
  async listLayouts() {
118
- let req = await this.apiRequest(`${this.endpoint}/layouts`);
118
+ let req = await this.apiRequest(`${this.endpoint}/layouts?page=2`);
119
119
  if (!req.response)
120
120
  throw new FMError(req.messages[0].code, req.httpStatus, req.messages[0].message);
121
- return req.response.layouts.filter(i => !i.isFolder).map(layout => new Layout(this, layout.name));
121
+ const cycleLayoutNames = (layouts) => {
122
+ let names = [];
123
+ for (let layout of layouts) {
124
+ if (layout.folderLayoutNames)
125
+ names = names.concat(cycleLayoutNames(layout.folderLayoutNames));
126
+ else
127
+ names.push(layout.name);
128
+ }
129
+ return names;
130
+ };
131
+ let layoutNames;
132
+ return cycleLayoutNames(req.response.layouts).map(layout => new Layout(this, layout));
122
133
  }
123
134
  getLayout(name) {
124
135
  return new Layout(this, name);
125
136
  }
126
- /*
127
- @deprecated
128
- */
129
- async setGlobals(globalFields) {
130
- // console.log({globalFields})
131
- await this.apiRequest(`${this.endpoint}/globals`, {
132
- method: "PATCH",
133
- body: JSON.stringify({ globalFields })
134
- });
135
- }
136
137
  script(name, parameter = "") {
137
138
  return { name, parameter };
138
139
  }
@@ -143,10 +143,20 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
143
143
  }
144
144
 
145
145
  async listLayouts() {
146
- let req = await this.apiRequest<{layouts: ApiLayout[]}>(`${this.endpoint}/layouts`)
146
+ let req = await this.apiRequest<{layouts: ApiLayout[]}>(`${this.endpoint}/layouts?page=2`)
147
147
  if (!req.response) throw new FMError(req.messages[0].code, req.httpStatus, req.messages[0].message)
148
148
 
149
- return req.response.layouts.filter(i => !i.isFolder).map(layout => new Layout(this, layout.name))
149
+ const cycleLayoutNames = (layouts: ApiLayout[]) => {
150
+ let names: string[] = []
151
+ for (let layout of layouts) {
152
+ if (layout.folderLayoutNames) names = names.concat(cycleLayoutNames(layout.folderLayoutNames))
153
+ else names.push(layout.name)
154
+ }
155
+ return names
156
+ }
157
+ let layoutNames
158
+
159
+ return cycleLayoutNames(req.response.layouts).map(layout => new Layout(this, layout))
150
160
  }
151
161
 
152
162
  getLayout<R extends keyof T["layouts"]>(name: R): Layout<T["layouts"][R]>
@@ -155,18 +165,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
155
165
  return new Layout<LayoutInterface>(this, name)
156
166
  }
157
167
 
158
- /*
159
- @deprecated
160
- */
161
- async setGlobals(globalFields) {
162
- // console.log({globalFields})
163
- await this.apiRequest(`${this.endpoint}/globals`, {
164
- method: "PATCH",
165
- body: JSON.stringify({globalFields})
166
- })
167
- }
168
-
169
- script(name, parameter = ""): Script {
168
+ script(name: string, parameter = ""): Script {
170
169
  return ({name, parameter} as Script)
171
170
  }
172
171
 
@@ -180,7 +179,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
180
179
  throw new Error("URL is empty, or has invalid value")
181
180
  }
182
181
 
183
- let headers = {}
182
+ let headers: {[key: string]: string} = {}
184
183
  if (Object.keys(this.cookies).length !== 0) {
185
184
  headers["Cookie"] = Object.keys(this.cookies)
186
185
  .map(key => {
@@ -189,7 +188,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
189
188
  .join("; ")
190
189
  }
191
190
 
192
- const check_for_cookies = (res) => {
191
+ const check_for_cookies = (res: HTTP_REDIRECT.ResponseDetails) => {
193
192
  // Check for the 'set-cookie' header. If it exists, remember it and strip it for better security.
194
193
  if (res.headers['set-cookie']) {
195
194
  for (let cookie of res.headers['set-cookie']) {
package/src/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import FMHost from "./connection/FMHost.js";
2
2
  import { FMError } from "./FMError.js";
3
3
  import * as TYPES from "./types.js";
4
+ import { PickPortals } from "./types.js";
4
5
  import { Database } from "./connection/database.js";
5
6
  import { Layout } from "./layouts/layout.js";
6
7
  import { RecordBase } from "./records/recordBase.js";
@@ -13,4 +14,4 @@ import { RecordGetOperation } from "./records/getOperations/recordGetOperation.j
13
14
  import { LayoutRecordManager } from "./layouts/layoutRecordManager.js";
14
15
  import { RecordFieldsMap } from "./layouts/recordFieldsMap.js";
15
16
  export default FMHost;
16
- export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, LayoutInterface, RecordFieldsMap, PortalInterface, PortalRecord, Portal, FieldBase, RecordGetOperation, LayoutRecordManager, Container };
17
+ export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, LayoutInterface, RecordFieldsMap, PortalInterface, PortalRecord, Portal, FieldBase, RecordGetOperation, LayoutRecordManager, Container, PickPortals };
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@
5
5
  import FMHost from "./connection/FMHost.js";
6
6
  import {FMError} from "./FMError.js";
7
7
  import * as TYPES from "./types.js"
8
+ import {PickPortals} from "./types.js"
8
9
  import {Database} from "./connection/database.js";
9
10
  import {Layout} from "./layouts/layout.js";
10
11
  import {RecordBase} from "./records/recordBase.js";
@@ -33,5 +34,6 @@ export {
33
34
  FieldBase,
34
35
  RecordGetOperation,
35
36
  LayoutRecordManager,
36
- Container
37
+ Container,
38
+ PickPortals
37
39
  }
@@ -3,7 +3,7 @@ import { DatabaseBase } from "../connection/databaseBase.js";
3
3
  import { ApiLayoutMetadata } from "../models/apiResults.js";
4
4
  export interface LayoutBase {
5
5
  readonly name: string;
6
- metadata: any;
6
+ metadata: ApiLayoutMetadata | null;
7
7
  endpoint: string;
8
8
  runScript(script: Script): Promise<ScriptResult>;
9
9
  getLayoutMeta(): Promise<ApiLayoutMetadata>;
@@ -8,7 +8,7 @@ import {ApiLayoutMetadata} from "../models/apiResults.js";
8
8
 
9
9
  export interface LayoutBase {
10
10
  readonly name: string
11
- metadata: any
11
+ metadata: ApiLayoutMetadata | null
12
12
  endpoint: string
13
13
  runScript(script: Script): Promise<ScriptResult>
14
14
  getLayoutMeta(): Promise<ApiLayoutMetadata>
@@ -5,5 +5,5 @@ export interface LayoutInterface {
5
5
  portals: PortalInterface;
6
6
  }
7
7
  export interface PortalInterface {
8
- [key: string]: Portal<RecordFieldsMap>;
8
+ [key: string | number | symbol]: Portal<RecordFieldsMap>;
9
9
  }
@@ -11,6 +11,5 @@ export interface LayoutInterface {
11
11
  }
12
12
 
13
13
  export interface PortalInterface {
14
- [key: string]: Portal<RecordFieldsMap>
15
- }
16
-
14
+ [key: string | number | symbol]: Portal<RecordFieldsMap>
15
+ }
@@ -2,11 +2,11 @@ import { LayoutRecord } from "../records/layoutRecord.js";
2
2
  import { LayoutInterface } from "./layoutInterface.js";
3
3
  import { LayoutBase } from "./layoutBase.js";
4
4
  import { GetOperationOptions, RecordGetOperation } from "../records/getOperations/recordGetOperation.js";
5
- import { RecordFetchOptions } from "../types.js";
5
+ import { PickPortals, RecordFetchOptions } from "../types.js";
6
6
  export declare class LayoutRecordManager<T extends LayoutInterface> {
7
7
  readonly layout: LayoutBase;
8
8
  constructor(layout: LayoutBase);
9
- create<OPTIONS extends RecordFetchOptions>(options: OPTIONS): Promise<LayoutRecord<T, OPTIONS["portals"][number]>>;
10
- get(recordId: number): Promise<LayoutRecord<T>>;
9
+ create<OPTIONS extends RecordFetchOptions>(options: OPTIONS): Promise<LayoutRecord<PickPortals<T, OPTIONS["portals"][number]>>>;
10
+ get(recordId: number): Promise<LayoutRecord<PickPortals<T, never>>>;
11
11
  list<OPTIONS extends GetOperationOptions<T>>(options: OPTIONS): RecordGetOperation<T, OPTIONS>;
12
12
  }
@@ -6,7 +6,8 @@ import {LayoutRecord} from "../records/layoutRecord.js";
6
6
  import {LayoutInterface} from "./layoutInterface.js";
7
7
  import {LayoutBase} from "./layoutBase.js"
8
8
  import {GetOperationOptions, RecordGetOperation} from "../records/getOperations/recordGetOperation.js";
9
- import {RecordFetchOptions} from "../types.js";
9
+ import {PickPortals, RecordFetchOptions} from "../types.js";
10
+ import {ApiFieldData} from "../models/apiResults.js";
10
11
 
11
12
  export class LayoutRecordManager<T extends LayoutInterface> {
12
13
  readonly layout: LayoutBase;
@@ -14,20 +15,24 @@ export class LayoutRecordManager<T extends LayoutInterface> {
14
15
  this.layout = layout
15
16
  }
16
17
 
17
- async create<OPTIONS extends RecordFetchOptions>(options: OPTIONS): Promise<LayoutRecord<T, OPTIONS["portals"][number]>> {
18
+ async create<OPTIONS extends RecordFetchOptions>(options: OPTIONS): Promise<LayoutRecord<
19
+ PickPortals<T, OPTIONS["portals"][number]>
20
+ >> {
18
21
  await this.layout.getLayoutMeta()
19
- let fields = {}
22
+ let fields: ApiFieldData = {}
20
23
  for (let _field of this.layout.metadata.fieldMetaData) {
21
24
  fields[_field.name] = ""
22
25
  }
23
- let portals = {}
26
+ let portals: {[key: string]: []} = {}
24
27
  for (let _portal of Object.keys(this.layout.metadata.portalMetaData)) portals[_portal] = []
25
28
  return new LayoutRecord(this.layout, -1, 0, fields, portals)
26
29
  }
27
30
 
28
- async get(recordId: number): Promise<LayoutRecord<T>> {
31
+ async get(recordId: number): Promise<LayoutRecord<
32
+ PickPortals<T, never>
33
+ >> {
29
34
  await this.layout.getLayoutMeta()
30
- let record = new LayoutRecord<T>(this.layout, recordId)
35
+ let record = new LayoutRecord<PickPortals<T, never>>(this.layout, recordId)
31
36
  await record.get()
32
37
  return record
33
38
  }
@@ -33,8 +33,8 @@ export interface ApiResults<T = unknown> {
33
33
  }
34
34
  export interface ApiLayout {
35
35
  name: string;
36
- isFolder: boolean;
37
- folderLayoutNames: string[];
36
+ isFolder?: boolean;
37
+ folderLayoutNames?: ApiLayout[];
38
38
  }
39
39
  export interface ApiLayoutMetadata {
40
40
  fieldMetaData: ApiFieldMetadata[];
@@ -75,9 +75,9 @@ export interface ApiRecordResponseObj {
75
75
  data: ApiRowDataDef[];
76
76
  dataInfo: ApiResultSetObj;
77
77
  }
78
- export interface ApiFieldData {
79
- [key: string]: string;
80
- }
78
+ export type ApiFieldData = {
79
+ [key: string]: string | number;
80
+ };
81
81
  export interface ApiPortalData {
82
82
  [key: string]: ApiFieldData[];
83
83
  }
@@ -1,5 +1,5 @@
1
1
  /*
2
- * Copyright (c) 2023. See LICENSE file for more information
2
+ * Copyright (c) 2023-2024. See LICENSE file for more information
3
3
  */
4
4
  export var ApiFieldTypes;
5
5
  (function (ApiFieldTypes) {
@@ -1,9 +1,7 @@
1
1
  /*
2
- * Copyright (c) 2023. See LICENSE file for more information
2
+ * Copyright (c) 2023-2024. See LICENSE file for more information
3
3
  */
4
4
 
5
- import * as stream from "stream";
6
-
7
5
  export enum ApiFieldTypes {
8
6
  NORMAL = "normal",
9
7
  CALCULATION = "calculation",
@@ -42,8 +40,8 @@ export interface ApiResults<T = unknown> {
42
40
 
43
41
  export interface ApiLayout {
44
42
  name: string,
45
- isFolder: boolean,
46
- folderLayoutNames: string[]
43
+ isFolder?: boolean,
44
+ folderLayoutNames?: ApiLayout[]
47
45
  }
48
46
 
49
47
  export interface ApiLayoutMetadata {
@@ -85,7 +83,7 @@ export interface ApiRecordResponseObj {
85
83
  dataInfo: ApiResultSetObj
86
84
  }
87
85
 
88
- export interface ApiFieldData {[key: string]: string}
86
+ export type ApiFieldData = {[key: string]: string | number}
89
87
 
90
88
  export interface ApiPortalData {[key: string]: ApiFieldData[]}
91
89
 
@@ -1,5 +1,5 @@
1
- import { RecordBase } from "./recordBase";
2
- import { FieldBase, FieldValue } from "./fieldBase";
1
+ import { RecordBase } from "./recordBase.js";
2
+ import { FieldBase, FieldValue } from "./fieldBase.js";
3
3
  export declare class Field<T extends FieldValue> extends FieldBase<T> {
4
4
  record: RecordBase<any>;
5
5
  }
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * Copyright (c) 2024. See LICENSE file for more information
3
3
  */
4
- import { FieldBase } from "./fieldBase";
4
+ import { FieldBase } from "./fieldBase.js";
5
5
  export class Field extends FieldBase {
6
6
  record;
7
7
  }
@@ -2,8 +2,8 @@
2
2
  * Copyright (c) 2024. See LICENSE file for more information
3
3
  */
4
4
 
5
- import {RecordBase} from "./recordBase";
6
- import {FieldBase, FieldValue} from "./fieldBase";
5
+ import {RecordBase} from "./recordBase.js";
6
+ import {FieldBase, FieldValue} from "./fieldBase.js";
7
7
 
8
8
  export class Field<T extends FieldValue> extends FieldBase<T> {
9
9
  record: RecordBase<any>;
@@ -154,7 +154,7 @@ export class FieldBase<T extends FieldValue> {
154
154
  return stream
155
155
  }
156
156
 
157
- let body = []
157
+ let body: Uint8Array[] = []
158
158
  return new Promise((resolve, reject) => {
159
159
  stream.on("data", chunk => {
160
160
  body.push(chunk)
@@ -1,5 +1,5 @@
1
1
  import { LayoutInterface } from "../../layouts/layoutInterface.js";
2
- import { ScriptRequestData } from "../../types.js";
2
+ import { PickPortals, ScriptRequestData } from "../../types.js";
3
3
  import { LayoutBase } from "../../layouts/layoutBase.js";
4
4
  import { LayoutRecord } from "../layoutRecord.js";
5
5
  export type SortOrder = "ascend" | "descend";
@@ -41,12 +41,12 @@ export declare class RecordGetOperation<T extends LayoutInterface, OPTIONS exten
41
41
  scripts(scripts: ScriptRequestData): this;
42
42
  sort(fieldName: string, sortOrder: SortOrder): this;
43
43
  addRequest(query: FindRequest): this;
44
- fetch(): Promise<LayoutRecord<T, keyof OPTIONS["portals"]>[]>;
44
+ fetch(): Promise<LayoutRecord<PickPortals<T, keyof OPTIONS["portals"]>>[]>;
45
45
  private performFind;
46
46
  [Symbol.asyncIterator](): {
47
47
  next: () => Promise<{
48
48
  done: boolean;
49
- value: LayoutRecord<T, keyof OPTIONS["portals"]>;
49
+ value: LayoutRecord<PickPortals<T, keyof OPTIONS["portals"]>>;
50
50
  }>;
51
51
  };
52
52
  }
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import {LayoutInterface} from "../../layouts/layoutInterface.js";
6
- import {ScriptRequestData} from "../../types.js";
6
+ import {PickPortals, ScriptRequestData} from "../../types.js";
7
7
  import {LayoutBase} from "../../layouts/layoutBase.js"
8
8
  import {LayoutRecord} from "../layoutRecord.js";
9
9
  import {ApiRecordResponseObj} from "../../models/apiResults.js";
@@ -124,7 +124,9 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
124
124
  return this.performFind(this.offset, this.limit)
125
125
  }
126
126
 
127
- private async performFind(offset: number, limit: number): Promise<LayoutRecord<T, keyof OPTIONS["portals"]>[]> {
127
+ private async performFind(offset: number, limit: number): Promise<LayoutRecord<
128
+ PickPortals<T, keyof OPTIONS["portals"]>
129
+ >[]> {
128
130
  let trace = new Error()
129
131
  await this.layout.getLayoutMeta()
130
132
 
@@ -163,7 +165,7 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
163
165
  let limit = this.limit
164
166
 
165
167
  let exit_after_last_record = false
166
- let records: LayoutRecord<T, keyof OPTIONS["portals"]>[] = []
168
+ let records: LayoutRecord<PickPortals<T, keyof OPTIONS["portals"]>>[] = []
167
169
 
168
170
  const fetch = async () => {
169
171
  const theoretical_limit = (limit - nextOffset) + startOffset
@@ -1,19 +1,21 @@
1
- import { extraBodyOptions, recordObject } from "../types.js";
1
+ import { extraBodyOptions } from "../types.js";
2
2
  import { RecordBase } from "./recordBase.js";
3
+ import { PortalRecord } from "./portalRecord.js";
3
4
  import { Portal } from "./portal.js";
4
5
  import { LayoutInterface } from "../layouts/layoutInterface.js";
5
6
  import { LayoutRecordBase } from "./layoutRecordBase.js";
7
+ import { ApiPortalData } from "../models/apiResults.js";
6
8
  import { LayoutBase } from "../layouts/layoutBase.js";
7
- export declare class LayoutRecord<LAYOUT extends LayoutInterface, PORTALS_TO_INCLUDE = string> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
8
- portals: Pick<LAYOUT["portals"], PORTALS_TO_INCLUDE>;
9
+ import { FieldBase, FieldValue } from "./fieldBase.js";
10
+ export declare class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
11
+ portals: LAYOUT["portals"];
9
12
  private readonly portalsToInclude;
10
- constructor(layout: LayoutBase, recordId: number | string, modId?: string | number, fieldData?: Record<string, string | number>, portalData?: any, portalsToInclude?: PORTALS_TO_INCLUDE[]);
13
+ constructor(layout: LayoutBase, recordId: number | string, modId?: string | number, fieldData?: Record<string, string | number>, portalData?: ApiPortalData | null, portalsToInclude?: (keyof LAYOUT["portals"])[]);
11
14
  get portalsArray(): Portal<any>[];
12
15
  commit(extraBody?: extraBodyOptions): Promise<this>;
13
- protected processPortalData(portalData: any): void;
16
+ protected processPortalData(portalData: ApiPortalData): void;
14
17
  get(): Promise<this>;
15
- getPortal(portal: any): Portal<any>;
16
18
  duplicate(): Promise<LayoutRecord<LAYOUT>>;
17
19
  delete(): Promise<void>;
18
- toObject(filter?: (a: any) => any, portalFilter?: (a: any) => any, portalRowFilter?: (a: any) => any, portalFieldFilter?: (a: any) => any): recordObject;
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">>;
19
21
  }
@@ -10,7 +10,7 @@ export class LayoutRecord extends RecordBase {
10
10
  portals = {};
11
11
  portalsToInclude;
12
12
  constructor(layout, recordId, modId = recordId, fieldData = {}, portalData = null, portalsToInclude = []) {
13
- super(layout, recordId, modId);
13
+ super(layout, parseInt(recordId), parseInt(modId));
14
14
  this.processFieldData(fieldData);
15
15
  this.portalsToInclude = portalsToInclude;
16
16
  if (portalData) {
@@ -83,7 +83,7 @@ export class LayoutRecord extends RecordBase {
83
83
  let fieldData = item;
84
84
  delete fieldData.recordId;
85
85
  delete fieldData.modId;
86
- return new PortalRecord(this, _portal, item.recordId, item.modId, fieldData);
86
+ return new PortalRecord(this, _portal, parseInt(item.recordId), parseInt(item.modId), fieldData);
87
87
  });
88
88
  // @ts-ignore
89
89
  this.portals[portalName] = _portal;
@@ -110,9 +110,6 @@ export class LayoutRecord extends RecordBase {
110
110
  return this;
111
111
  }
112
112
  }
113
- getPortal(portal) {
114
- return this.portalsArray.find(p => p.name === portal);
115
- }
116
113
  async duplicate() {
117
114
  let trace = new Error();
118
115
  let res = await this.layout.database.apiRequest(this.endpoint, {
@@ -150,7 +147,7 @@ export class LayoutRecord extends RecordBase {
150
147
  }
151
148
  }
152
149
  toObject(filter = (a) => a.edited, portalFilter = (a) => a.records.find(record => record.edited), portalRowFilter = (a) => a.edited, portalFieldFilter = (a) => a.edited) {
153
- let obj = super.toObject(filter, portalFilter, portalRowFilter, portalFieldFilter);
150
+ let obj = super.toObject(filter);
154
151
  // Check if there's been any edited portal information
155
152
  let portals = this.portalsArray.filter(a => portalFilter(a));
156
153
  if (portals) {
@@ -2,29 +2,30 @@
2
2
  * Copyright (c) 2023-2024. See LICENSE file for more information
3
3
  */
4
4
 
5
- import {extraBodyOptions, recordObject} from "../types.js";
5
+ import {extraBodyOptions} from "../types.js";
6
6
  import {RecordBase} from "./recordBase.js";
7
7
  import {PortalRecord} from "./portalRecord.js";
8
8
  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 {ApiRecordResponseObj} from "../models/apiResults.js";
12
+ import {ApiPortalData, ApiRecordResponseObj} from "../models/apiResults.js";
13
13
  import {LayoutBase} from "../layouts/layoutBase.js"
14
+ import {FieldBase, FieldValue} from "./fieldBase.js";
14
15
 
15
- export class LayoutRecord<LAYOUT extends LayoutInterface, PORTALS_TO_INCLUDE = string> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
16
+ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
16
17
  // @ts-ignore
17
- portals: Pick<LAYOUT["portals"], PORTALS_TO_INCLUDE> = {}
18
- private readonly portalsToInclude: PORTALS_TO_INCLUDE[]
18
+ portals: LAYOUT["portals"] = {}
19
+ private readonly portalsToInclude: (string | number | symbol)[]
19
20
 
20
21
  constructor(
21
22
  layout: LayoutBase,
22
23
  recordId: number | string,
23
24
  modId = recordId,
24
25
  fieldData: Record<string, string | number> = {},
25
- portalData = null, portalsToInclude: PORTALS_TO_INCLUDE[] = [])
26
+ portalData: ApiPortalData | null = null, portalsToInclude: (keyof LAYOUT["portals"])[] = [])
26
27
  {
27
- super(layout, recordId, modId);
28
+ super(layout, parseInt(recordId as string), parseInt(modId as string));
28
29
  this.processFieldData(fieldData)
29
30
  this.portalsToInclude = portalsToInclude
30
31
  if (portalData) {
@@ -37,7 +38,7 @@ export class LayoutRecord<LAYOUT extends LayoutInterface, PORTALS_TO_INCLUDE = s
37
38
  }
38
39
 
39
40
  async commit(extraBody: extraBodyOptions = {}): Promise<this> {
40
- let data = this.toObject()
41
+ let data: any = this.toObject()
41
42
  delete data.recordId
42
43
  delete data.modId
43
44
 
@@ -100,14 +101,14 @@ export class LayoutRecord<LAYOUT extends LayoutInterface, PORTALS_TO_INCLUDE = s
100
101
  }
101
102
  }
102
103
 
103
- protected processPortalData(portalData): void {
104
+ protected processPortalData(portalData: ApiPortalData): void {
104
105
  for (let portalName of Object.keys(portalData)) {
105
106
  let _portal = new Portal(this, portalName)
106
107
  _portal.records = portalData[portalName].map(item => {
107
108
  let fieldData = item;
108
109
  delete fieldData.recordId;
109
110
  delete fieldData.modId;
110
- return new PortalRecord(this, _portal, item.recordId, item.modId, fieldData);
111
+ return new PortalRecord(this, _portal, parseInt(item.recordId as string), parseInt(item.modId as string), fieldData);
111
112
  })
112
113
 
113
114
  // @ts-ignore
@@ -136,10 +137,6 @@ export class LayoutRecord<LAYOUT extends LayoutInterface, PORTALS_TO_INCLUDE = s
136
137
  }
137
138
  }
138
139
 
139
- getPortal(portal) {
140
- return this.portalsArray.find(p => p.name === portal)
141
- }
142
-
143
140
  async duplicate(): Promise<LayoutRecord<LAYOUT>> {
144
141
  let trace = new Error()
145
142
  let res = await this.layout.database.apiRequest<{recordId: string, modId: string}>(this.endpoint, {
@@ -179,8 +176,13 @@ export class LayoutRecord<LAYOUT extends LayoutInterface, PORTALS_TO_INCLUDE = s
179
176
  }
180
177
  }
181
178
 
182
- toObject(filter: (a) => any = (a) => a.edited, portalFilter: (a) => any = (a) => a.records.find(record => record.edited), portalRowFilter: (a) => any = (a) => a.edited, portalFieldFilter: (a) => any = (a) => a.edited): recordObject {
183
- let obj = super.toObject(filter, portalFilter, portalRowFilter, portalFieldFilter);
179
+ toObject(
180
+ filter: (a: FieldBase<FieldValue>) => any = (a) => a.edited,
181
+ portalFilter: (a: Portal<any>) => any = (a) => a.records.find(record => record.edited),
182
+ portalRowFilter: (a: PortalRecord<never>) => any = (a) => a.edited,
183
+ portalFieldFilter: (a: FieldBase<FieldValue>) => any = (a) => a.edited
184
+ ) {
185
+ let obj = super.toObject(filter);
184
186
 
185
187
  // Check if there's been any edited portal information
186
188
  let portals = this.portalsArray.filter(a => portalFilter(a))
@@ -2,11 +2,10 @@ import { PortalRecord } from "./portalRecord.js";
2
2
  import { RecordFieldsMap } from "../layouts/recordFieldsMap.js";
3
3
  import { PortalBase } from "./portalBase.js";
4
4
  import { LayoutRecord } from "./layoutRecord.js";
5
- import { LayoutInterface } from "../layouts/layoutInterface.js";
6
5
  export declare class Portal<T extends RecordFieldsMap> implements PortalBase<T> {
7
- readonly record: LayoutRecord<LayoutInterface>;
6
+ readonly record: LayoutRecord<any>;
8
7
  readonly name: string;
9
8
  records: PortalRecord<T>[];
10
- constructor(record: LayoutRecord<LayoutInterface, any>, name: string);
9
+ constructor(record: LayoutRecord<any>, name: string);
11
10
  create(): PortalRecord<T>;
12
11
  }
@@ -6,20 +6,21 @@ import {PortalRecord} from "./portalRecord.js";
6
6
  import {RecordFieldsMap} from "../layouts/recordFieldsMap.js";
7
7
  import {PortalBase} from "./portalBase.js";
8
8
  import {LayoutRecord} from "./layoutRecord.js";
9
- import {LayoutInterface} from "../layouts/layoutInterface.js";
10
9
 
11
10
  export class Portal<T extends RecordFieldsMap> implements PortalBase<T> {
12
- readonly record: LayoutRecord<LayoutInterface>;
11
+ readonly record: LayoutRecord<any>;
13
12
  readonly name: string;
14
13
  public records: PortalRecord<T>[];
15
14
 
16
- constructor(record: LayoutRecord<LayoutInterface, any>, name: string) {
15
+ constructor(record: LayoutRecord<any>, name: string) {
17
16
  this.record = record
18
17
  this.name = name
19
18
  }
20
19
 
21
20
  create() {
22
- let fields = {}
21
+ let fields: {
22
+ [key: string]: string
23
+ } = {}
23
24
  for (let _field of this.record.layout.metadata.portalMetaData[this.name]) {
24
25
  fields[_field.name] = ""
25
26
  }
@@ -2,12 +2,16 @@ 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
6
  export declare class PortalRecord<T extends RecordFieldsMap> extends RecordBase<T> {
6
7
  readonly portal: PortalBase<T>;
7
8
  readonly type = RecordTypes.PORTAL;
8
- constructor(record: any, portal: any, recordId: any, modId?: any, fieldData?: {});
9
+ constructor(record: RecordBase<any>, portal: PortalBase<any>, recordId: number, modId?: number, fieldData?: {});
9
10
  _onSave(): void;
10
- commit(extraBody?: extraBodyOptions): Promise<import("./layoutRecord.js").LayoutRecord<import("../index.js").LayoutInterface, string>>;
11
- toObject(fieldFilter: any): any;
12
- getField(field: any): import("./fieldBase.js").FieldBase<import("./fieldBase.js").FieldValue>;
11
+ commit(extraBody?: extraBodyOptions): Promise<import("./layoutRecord.js").LayoutRecord<import("../index.js").LayoutInterface>>;
12
+ toObject(fieldFilter: (a: FieldBase<FieldValue>) => boolean): {
13
+ [key: string]: string;
14
+ modId: string;
15
+ recordId: string;
16
+ };
13
17
  }
@@ -21,15 +21,12 @@ export class PortalRecord extends RecordBase {
21
21
  toObject(fieldFilter) {
22
22
  super.toObject();
23
23
  let res = {
24
- recordId: this.recordId === -1 ? undefined : this.recordId,
25
- modId: this.modId === -1 ? undefined : this.modId
24
+ recordId: this.recordId === -1 ? undefined : this.recordId.toString(),
25
+ modId: this.modId === -1 ? undefined : this.modId.toString()
26
26
  };
27
27
  for (let field of this.fieldsArray.filter(a => fieldFilter(a)))
28
- res[field.id] = field.value;
28
+ res[field.id] = field.value.toString();
29
29
  // console.log(res)
30
30
  return res;
31
31
  }
32
- getField(field) {
33
- return this.fieldsArray.find(_field => _field.id === field) || this.fieldsArray.find(_field => _field.id === this.portal.name + "::" + field);
34
- }
35
32
  }
@@ -3,16 +3,17 @@
3
3
  */
4
4
 
5
5
  import {RecordBase} from "./recordBase.js";
6
- import {extraBodyOptions, recordObject, RecordTypes} from "../types.js";
6
+ 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
11
 
11
12
  export class PortalRecord<T extends RecordFieldsMap> extends RecordBase<T> {
12
13
  readonly portal: PortalBase<T>;
13
14
  readonly type = RecordTypes.PORTAL
14
15
 
15
- constructor(record, portal, recordId, modId = recordId, fieldData = {}) {
16
+ constructor(record: RecordBase<any>, portal: PortalBase<any>, recordId: number, modId = recordId, fieldData = {}) {
16
17
  super(record.layout, recordId, modId);
17
18
 
18
19
  this.portal = portal
@@ -28,18 +29,18 @@ export class PortalRecord<T extends RecordFieldsMap> extends RecordBase<T> {
28
29
  return this.portal.record.commit(extraBody)
29
30
  }
30
31
 
31
- toObject(fieldFilter): any {
32
+ toObject(fieldFilter: (a: FieldBase<FieldValue>) => boolean) {
32
33
  super.toObject()
33
- let res = {
34
- recordId: this.recordId === -1 ? undefined : this.recordId,
35
- modId: this.modId === -1 ? undefined : this.modId
36
- } as recordObject
37
- for (let field of this.fieldsArray.filter(a => fieldFilter(a))) res[field.id] = field.value
34
+ let res: {
35
+ "modId": string,
36
+ "recordId": string
37
+ [key: string]: string
38
+ } = {
39
+ recordId: this.recordId === -1 ? undefined : this.recordId.toString(),
40
+ modId: this.modId === -1 ? undefined : this.modId.toString()
41
+ }
42
+ for (let field of this.fieldsArray.filter(a => fieldFilter(a))) res[field.id] = field.value.toString()
38
43
  // console.log(res)
39
44
  return res
40
45
  }
41
-
42
- getField(field) {
43
- return this.fieldsArray.find(_field => _field.id === field) || this.fieldsArray.find(_field => _field.id === this.portal.name + "::" + field)
44
- }
45
46
  }
@@ -1,9 +1,10 @@
1
1
  /// <reference types="node" resolution-mode="require"/>
2
2
  import { EventEmitter } from "events";
3
3
  import { FieldBase, FieldValue } from "./fieldBase.js";
4
- import { recordObject, RecordTypes } from "../types.js";
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";
7
8
  export declare class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
8
9
  readonly layout: LayoutBase;
9
10
  readonly type: RecordTypes;
@@ -11,11 +12,11 @@ export declare class RecordBase<T extends RecordFieldsMap> extends EventEmitter
11
12
  modId: number;
12
13
  fields: T;
13
14
  protected portalData: any[];
14
- constructor(layout: any, recordId: any, modId?: any);
15
+ constructor(layout: LayoutBase, recordId: number, modId?: number);
15
16
  get endpoint(): string;
16
17
  get edited(): boolean;
17
18
  get fieldsArray(): FieldBase<FieldValue>[];
18
- protected processFieldData(fieldData: any): T;
19
+ protected processFieldData(fieldData: ApiFieldData): T;
19
20
  _onSave(): void;
20
- toObject(filter?: (a: any) => any, portalFilter?: (a: any) => any, portalRowFilter?: (a: any) => any, portalFieldFilter?: (a: any) => any): recordObject;
21
+ toObject(filter?: (a: FieldBase<FieldValue>) => boolean): Partial<Omit<ApiRowDataDef, "portalDataInfo">>;
21
22
  }
@@ -67,7 +67,7 @@ export class RecordBase extends EventEmitter {
67
67
  for (let field of this.fieldsArray)
68
68
  field.edited = false;
69
69
  }
70
- toObject(filter = (a) => a.edited, portalFilter = (a) => a.records.find(record => record.edited), portalRowFilter = (a) => a.edited, portalFieldFilter = (a) => a.edited) {
70
+ toObject(filter = (a) => a.edited) {
71
71
  let fields_processed = {};
72
72
  let field;
73
73
  for (field of this.fieldsArray.filter(field => filter(field))) {
@@ -91,8 +91,8 @@ export class RecordBase extends EventEmitter {
91
91
  fields_processed[field.id] = value;
92
92
  }
93
93
  let obj = {
94
- "recordId": this.recordId,
95
- "modId": this.modId,
94
+ "recordId": this.recordId.toString(),
95
+ "modId": this.modId.toString(),
96
96
  "fieldData": fields_processed
97
97
  };
98
98
  return obj;
@@ -5,9 +5,10 @@
5
5
  import {EventEmitter} from "events";
6
6
  import * as moment from "moment";
7
7
  import {FieldBase, FieldValue} from "./fieldBase.js";
8
- import {recordObject, RecordTypes} from "../types.js";
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
12
 
12
13
  export class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
13
14
  readonly layout: LayoutBase;
@@ -17,7 +18,7 @@ export class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
17
18
  fields: T;
18
19
  protected portalData: any[];
19
20
 
20
- constructor(layout, recordId, modId = recordId) {
21
+ constructor(layout: LayoutBase, recordId: number, modId = recordId) {
21
22
  super();
22
23
  this.layout = layout
23
24
  this.recordId = recordId
@@ -36,7 +37,7 @@ export class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
36
37
  return Object.values(this.fields)
37
38
  }
38
39
 
39
- protected processFieldData(fieldData) {
40
+ protected processFieldData(fieldData: ApiFieldData) {
40
41
  let fields: RecordFieldsMap = {}
41
42
 
42
43
  for (let key of Object.keys(fieldData)) {
@@ -79,12 +80,8 @@ export class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
79
80
  for (let field of this.fieldsArray) field.edited = false
80
81
  }
81
82
 
82
- toObject(filter = (a) => a.edited,
83
- portalFilter = (a) => a.records.find(record => record.edited),
84
- portalRowFilter = (a) => a.edited,
85
- portalFieldFilter = (a) => a.edited
86
- ): recordObject {
87
- let fields_processed = {}
83
+ toObject(filter = (a: FieldBase<FieldValue>) => a.edited): Partial<Omit<ApiRowDataDef, "portalDataInfo">> {
84
+ let fields_processed: ApiFieldData = {}
88
85
  let field: FieldBase<FieldValue>
89
86
  for (field of this.fieldsArray.filter(field => filter(field))) {
90
87
  let value = field.value
@@ -109,8 +106,8 @@ export class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
109
106
  fields_processed[field.id] = value
110
107
  }
111
108
  let obj = {
112
- "recordId": this.recordId,
113
- "modId": this.modId,
109
+ "recordId": this.recordId.toString(),
110
+ "modId": this.modId.toString(),
114
111
  "fieldData": fields_processed
115
112
  }
116
113
  return obj
package/src/types.d.ts CHANGED
@@ -2,6 +2,10 @@
2
2
  /// <reference types="node" resolution-mode="require"/>
3
3
  import * as http from "http";
4
4
  import { FMError } from "./FMError.js";
5
+ import { LayoutInterface } from "./layouts/layoutInterface.js";
6
+ export type PickPortals<LAYOUT extends LayoutInterface, PORTALS extends string | number | symbol = ""> = Omit<LAYOUT, "portals"> & {
7
+ portals: Pick<LAYOUT["portals"], PORTALS>;
8
+ };
5
9
  export interface databaseOptionsBase {
6
10
  database: string;
7
11
  credentials: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris | loginOptionsToken;
package/src/types.ts CHANGED
@@ -6,6 +6,10 @@
6
6
  // @ts-ignore
7
7
  import * as http from "http";
8
8
  import {FMError} from "./FMError.js";
9
+ import {LayoutInterface} from "./layouts/layoutInterface.js";
10
+
11
+ export type PickPortals<LAYOUT extends LayoutInterface, PORTALS extends string | number | symbol = ""> =
12
+ Omit<LAYOUT, "portals"> & { portals: Pick<LAYOUT["portals"], PORTALS> }
9
13
 
10
14
  export interface databaseOptionsBase {
11
15
  database: string