@jd-data-limited/easy-fm 4.0.1 → 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.1",
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"
@@ -115,10 +115,21 @@ 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);
@@ -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]>
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
  }
@@ -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,7 @@ 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
10
  import {ApiFieldData} from "../models/apiResults.js";
11
11
 
12
12
  export class LayoutRecordManager<T extends LayoutInterface> {
@@ -15,7 +15,9 @@ export class LayoutRecordManager<T extends LayoutInterface> {
15
15
  this.layout = layout
16
16
  }
17
17
 
18
- 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
+ >> {
19
21
  await this.layout.getLayoutMeta()
20
22
  let fields: ApiFieldData = {}
21
23
  for (let _field of this.layout.metadata.fieldMetaData) {
@@ -26,9 +28,11 @@ export class LayoutRecordManager<T extends LayoutInterface> {
26
28
  return new LayoutRecord(this.layout, -1, 0, fields, portals)
27
29
  }
28
30
 
29
- async get(recordId: number): Promise<LayoutRecord<T>> {
31
+ async get(recordId: number): Promise<LayoutRecord<
32
+ PickPortals<T, never>
33
+ >> {
30
34
  await this.layout.getLayoutMeta()
31
- let record = new LayoutRecord<T>(this.layout, recordId)
35
+ let record = new LayoutRecord<PickPortals<T, never>>(this.layout, recordId)
32
36
  await record.get()
33
37
  return record
34
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[];
@@ -40,8 +40,8 @@ export interface ApiResults<T = unknown> {
40
40
 
41
41
  export interface ApiLayout {
42
42
  name: string,
43
- isFolder: boolean,
44
- folderLayoutNames: string[]
43
+ isFolder?: boolean,
44
+ folderLayoutNames?: ApiLayout[]
45
45
  }
46
46
 
47
47
  export interface ApiLayoutMetadata {
@@ -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>;
@@ -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
@@ -7,10 +7,10 @@ import { LayoutRecordBase } from "./layoutRecordBase.js";
7
7
  import { ApiPortalData } from "../models/apiResults.js";
8
8
  import { LayoutBase } from "../layouts/layoutBase.js";
9
9
  import { FieldBase, FieldValue } from "./fieldBase.js";
10
- export declare class LayoutRecord<LAYOUT extends LayoutInterface, PORTALS_TO_INCLUDE = string> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
11
- portals: Pick<LAYOUT["portals"], PORTALS_TO_INCLUDE>;
10
+ export declare class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
11
+ portals: LAYOUT["portals"];
12
12
  private readonly portalsToInclude;
13
- constructor(layout: LayoutBase, recordId: number | string, modId?: string | number, fieldData?: Record<string, string | number>, portalData?: ApiPortalData | null, 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"])[]);
14
14
  get portalsArray(): Portal<any>[];
15
15
  commit(extraBody?: extraBodyOptions): Promise<this>;
16
16
  protected processPortalData(portalData: ApiPortalData): void;
@@ -13,17 +13,17 @@ import {ApiPortalData, ApiRecordResponseObj} from "../models/apiResults.js";
13
13
  import {LayoutBase} from "../layouts/layoutBase.js"
14
14
  import {FieldBase, FieldValue} from "./fieldBase.js";
15
15
 
16
- 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 {
17
17
  // @ts-ignore
18
- portals: Pick<LAYOUT["portals"], PORTALS_TO_INCLUDE> = {}
19
- private readonly portalsToInclude: PORTALS_TO_INCLUDE[]
18
+ portals: LAYOUT["portals"] = {}
19
+ private readonly portalsToInclude: (string | number | symbol)[]
20
20
 
21
21
  constructor(
22
22
  layout: LayoutBase,
23
23
  recordId: number | string,
24
24
  modId = recordId,
25
25
  fieldData: Record<string, string | number> = {},
26
- portalData: ApiPortalData | null = null, portalsToInclude: PORTALS_TO_INCLUDE[] = [])
26
+ portalData: ApiPortalData | null = null, portalsToInclude: (keyof LAYOUT["portals"])[] = [])
27
27
  {
28
28
  super(layout, parseInt(recordId as string), parseInt(modId as string));
29
29
  this.processFieldData(fieldData)
@@ -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,14 +6,13 @@ 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
  }
@@ -8,7 +8,7 @@ export declare class PortalRecord<T extends RecordFieldsMap> extends RecordBase<
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
- commit(extraBody?: extraBodyOptions): Promise<import("./layoutRecord.js").LayoutRecord<import("../index.js").LayoutInterface, string>>;
11
+ commit(extraBody?: extraBodyOptions): Promise<import("./layoutRecord.js").LayoutRecord<import("../index.js").LayoutInterface>>;
12
12
  toObject(fieldFilter: (a: FieldBase<FieldValue>) => boolean): {
13
13
  [key: string]: string;
14
14
  modId: string;
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