@jd-data-limited/easy-fm 3.1.5 → 3.1.7

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 (64) hide show
  1. package/README.md +85 -18
  2. package/package.json +1 -1
  3. package/src/connection/FMHost.d.ts +4 -3
  4. package/src/connection/FMHost.ts +5 -4
  5. package/src/connection/HostBase.d.ts +8 -0
  6. package/src/connection/HostBase.js +4 -0
  7. package/src/connection/HostBase.ts +15 -0
  8. package/src/connection/database.d.ts +9 -7
  9. package/src/connection/database.ts +13 -8
  10. package/src/connection/databaseBase.d.ts +8 -0
  11. package/src/connection/databaseBase.js +4 -0
  12. package/src/connection/databaseBase.ts +17 -0
  13. package/src/index.d.ts +3 -1
  14. package/src/index.ts +3 -1
  15. package/src/layouts/layout.d.ts +8 -7
  16. package/src/layouts/layout.ts +8 -7
  17. package/src/layouts/layoutBase.d.ts +11 -0
  18. package/src/layouts/layoutBase.js +4 -0
  19. package/src/layouts/layoutBase.ts +16 -0
  20. package/src/layouts/layoutInterface.d.ts +1 -6
  21. package/src/layouts/layoutInterface.ts +1 -7
  22. package/src/layouts/layoutRecordManager.d.ts +3 -3
  23. package/src/layouts/layoutRecordManager.ts +3 -3
  24. package/src/layouts/recordFieldsMap.d.ts +4 -0
  25. package/src/layouts/recordFieldsMap.js +4 -0
  26. package/src/layouts/recordFieldsMap.ts +9 -0
  27. package/src/records/field.d.ts +2 -1
  28. package/src/records/field.js +5 -2
  29. package/src/records/field.ts +8 -4
  30. package/src/records/getOperations/find.d.ts +2 -2
  31. package/src/records/getOperations/find.js +3 -3
  32. package/src/records/getOperations/find.ts +5 -5
  33. package/src/records/getOperations/recordGetOperation.d.ts +3 -3
  34. package/src/records/getOperations/recordGetOperation.js +1 -1
  35. package/src/records/getOperations/recordGetOperation.ts +4 -4
  36. package/src/records/getOperations/recordGetRange.js +3 -3
  37. package/src/records/getOperations/recordGetRange.ts +3 -3
  38. package/src/records/layoutRecord.d.ts +4 -2
  39. package/src/records/layoutRecord.js +2 -0
  40. package/src/records/layoutRecord.ts +6 -3
  41. package/src/records/layoutRecordBase.d.ts +5 -0
  42. package/src/records/layoutRecordBase.js +4 -0
  43. package/src/records/layoutRecordBase.ts +10 -0
  44. package/src/records/portal.d.ts +4 -3
  45. package/src/records/portal.ts +5 -3
  46. package/src/records/portalBase.d.ts +8 -0
  47. package/src/records/portalBase.js +4 -0
  48. package/src/records/portalBase.ts +14 -0
  49. package/src/records/portalRecord.d.ts +6 -5
  50. package/src/records/portalRecord.js +2 -1
  51. package/src/records/portalRecord.ts +6 -4
  52. package/src/records/portalRecordBase.d.ts +4 -0
  53. package/src/records/portalRecordBase.js +6 -0
  54. package/src/records/recordBase.d.ts +9 -3
  55. package/src/records/recordBase.js +8 -4
  56. package/src/records/recordBase.ts +10 -7
  57. package/src/types.d.ts +7 -2
  58. package/src/types.ts +8 -3
  59. package/test.d.ts +2 -1
  60. package/test.js +27 -1
  61. package/test.ts +33 -0
  62. package/test2.d.ts +1 -0
  63. package/test2.js +15 -0
  64. package/tsconfig.json +2 -1
package/README.md CHANGED
@@ -7,7 +7,21 @@ a [FileMaker database](https://www.claris.com/filemaker/) stored on
7
7
  a [FileMaker server](https://www.claris.com/filemaker/server/)
8
8
  or [FileMaker Cloud](https://store.claris.com/filemaker-cloud). This module interacts with your server using the
9
9
  [FileMaker Data API](https://help.claris.com/en/data-api-guide/content/index.html).
10
-
10
+ <!-- TOC -->
11
+ * [easy-fm](#easy-fm)
12
+ * [FileMaker setup instructions](#filemaker-setup-instructions)
13
+ * [Before you begin](#before-you-begin)
14
+ * [Connecting to a database](#connecting-to-a-database)
15
+ * [Getting records](#getting-records)
16
+ * [Fetch a range of records](#fetch-a-range-of-records)
17
+ * [Searching for records](#searching-for-records)
18
+ * [Fetch a record using its record ID (NOT RECOMMENDED)](#fetch-a-record-using-its-record-id-not-recommended)
19
+ * [Create a record](#create-a-record)
20
+ * [Modify a record](#modify-a-record)
21
+ * [Field names](#field-names)
22
+ * [Portal names](#portal-names)
23
+ * [Typescript Implementation](#typescript-implementation)
24
+ <!-- TOC -->
11
25
  ## FileMaker setup instructions
12
26
 
13
27
  1. Enable the FileMaker Data API from the server's admin console. This setting is located
@@ -20,8 +34,7 @@ or [FileMaker Cloud](https://store.claris.com/filemaker-cloud). This module inte
20
34
  ## Before you begin
21
35
 
22
36
  - You need to know what your server's UTC time offset (in minutes) is.
23
- - Running `0 - (new Date()).getTimezoneOffset()` in javascript will the UTC time offset for your current timezone.
24
-
37
+ - Running `0 - (new Date()).getTimezoneOffset()` in javascript will give you the UTC time offset for your current timezone.
25
38
 
26
39
  ## Connecting to a database
27
40
 
@@ -40,7 +53,8 @@ const database = host.database({
40
53
  method: "filemaker",
41
54
  username: "<username>",
42
55
  password: "<password>"
43
- }
56
+ },
57
+ externalSources: []
44
58
  })
45
59
 
46
60
  database.login().then(() => {
@@ -82,11 +96,11 @@ find_request.addRequests({"GroupID": "abc"}) // Find only the records with field
82
96
  find_request.setOffset(30) // Starting from the 30th matching record
83
97
  find_request.setLimit(10) // Fetch only 10 records
84
98
 
85
- let records = await range_request.run()
99
+ let records = await range_request.fetch()
86
100
  console.log(records)
87
101
  ```
88
102
 
89
- ### Fetch a record using its record ID
103
+ ### Fetch a record using its record ID (NOT RECOMMENDED)
90
104
 
91
105
  > Please note: When in FileMaker Pro, a record's ID is returned when using Get(RecordID). If you need to fetch a record
92
106
  > using a different ID, use the search method above.
@@ -103,9 +117,9 @@ console.log(record)
103
117
  let layout = database.getLayout("Your layout name")
104
118
  let record = await layout.records.create()
105
119
 
106
- record.getField("Field1").set("Value here")
107
- record.getField("Field2").set("Value here")
108
- record.getField("Field3").set("Value here")
120
+ record.fields["Field1"].value = "Value here"
121
+ record.fields["Field2"].value = "Value here"
122
+ record.fields["Field3"].value = "Value here"
109
123
 
110
124
  await record.commit()
111
125
  ```
@@ -116,19 +130,72 @@ await record.commit()
116
130
  let layout = database.getLayout("Your layout name")
117
131
  let record = await layout.records.get(164)
118
132
 
119
- record.getField("Field1").set("Value here")
120
- record.getField("Field2").set("Value here")
121
- record.getField("Field3").set("Value here")
133
+ record.fields["Field1"].value = "Value here"
134
+ record.fields["Field2"].value = "Value here"
135
+ record.fields["Field3"].value = "Value here"
122
136
 
123
137
  await record.commit()
124
138
  ```
125
139
 
126
- # Documentation
140
+ # Field names
141
+
142
+ When interacting with FileMaker, it is important to remember how FileMaker field names work.
143
+
144
+ | Field name format | Use when.... |
145
+ |-------------------------------|-----------------------------------------------------------------------------------------------------|
146
+ | `FieldName` | Use this when the field you are accessing is in the same table that the layout has been assigned to |
147
+ | `RelatedTableName::FieldName` | Use this when the field **is not** in the same table that the layout has been assigned to |
148
+
149
+ > **NOTE:** You will not be able to access any fields that are not on the layout.
150
+
151
+ # Portal names
152
+
153
+ > Please read this section carefully if you are working with portals
127
154
 
128
- ## FMHost
155
+ It is important to note that a portal's name **is not** the same as the name of the table that it links to. The name of a
156
+ portal matches the object name it was assigned in FileMaker's layout editor.
129
157
 
130
- `hostname`: string
131
- > The hostname of the server you are connecting to
158
+ > **NOTE**: When no name has been manually assigned to it, it will default to the name of the related table.
159
+
160
+ # Typescript Implementation
161
+
162
+ `easy-fm` supports the use of TypeScript. Here's an example of how this works with `easy-fm`:
163
+
164
+ ```typescript
165
+ import FMHost, {Portal, Field, Container} from "@jd-data-limited/easy-fm";
166
+
167
+ interface UsersLayout {
168
+ fields: {
169
+ // Map each field on the layout to a field type.
170
+ first_name: Field<string>
171
+ age: Field<number>
172
+ birthdate: Field<Date>
173
+ profile_picture: Field<Container>
174
+ "MyRelatedTable::MyRelatedField": Field<string>
175
+ },
176
+ portals: {
177
+ Files: {
178
+ "Files::Field1": Field<string>
179
+ }
180
+ }
181
+ }
182
+
183
+ interface DatabaseStructure {
184
+ layouts: {
185
+ users: UsersLayout
186
+ }
187
+ }
188
+
189
+ const host = new FMHost("https://example_filemaker_server.com")
190
+ const database = host.database<DatabaseStructure>({
191
+ database: "ExampleDatabase.fmp12",
192
+ credentials: {method: "filemaker", username: "test", passsword: "test"},
193
+ externalSources: []
194
+ })
195
+ await database.login()
132
196
 
133
- `timezoneOffset`: number
134
- > The server's timezone offset
197
+ const layout = database.getLayout("users") // The UsersLayout interface will be automatically applied to all records within this layout
198
+ const record = await layout.records.create()
199
+ record.fields["first_name"].value = "Joe"
200
+ record.fields["age"].value = 38
201
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jd-data-limited/easy-fm",
3
- "version": "3.1.5",
3
+ "version": "3.1.7",
4
4
  "dependencies": {
5
5
  "@types/btoa": "^1.2.3",
6
6
  "@types/events": "^3.0.0",
@@ -1,12 +1,13 @@
1
1
  import { Database } from "./database.js";
2
- import { databaseOptionsWithExternalSources, FMHostMetadata, loginOptionsClaris, loginOptionsFileMaker, loginOptionsOAuth } from "../types.js";
3
- export default class FMHost {
2
+ import { HostBase } from "./HostBase.js";
3
+ import { databaseOptionsWithExternalSources, DatabaseStructure, FMHostMetadata, loginOptionsClaris, loginOptionsFileMaker, loginOptionsOAuth } from "../types.js";
4
+ export default class FMHost implements HostBase {
4
5
  readonly hostname: string;
5
6
  readonly timezoneOffset: number;
6
7
  readonly verify: boolean;
7
8
  metadata: FMHostMetadata;
8
9
  constructor(_hostname: string, timezoneOffset?: number, verify?: boolean);
9
10
  listDatabases(credentials?: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris): Promise<any>;
10
- database(data: databaseOptionsWithExternalSources): Database;
11
+ database<T extends DatabaseStructure>(data: databaseOptionsWithExternalSources): Database<T>;
11
12
  getMetadata(): Promise<any>;
12
13
  }
@@ -6,8 +6,9 @@ import {generateAuthorizationHeaders} from "./generateAuthorizationHeaders.js";
6
6
  import fetch from "node-fetch";
7
7
  import {FMError} from "../FMError.js";
8
8
  import {Database} from "./database.js";
9
+ import {HostBase} from "./HostBase.js"
9
10
  import {
10
- databaseOptionsWithExternalSources,
11
+ databaseOptionsWithExternalSources, DatabaseStructure,
11
12
  fileMakerResponse,
12
13
  FMHostMetadata,
13
14
  loginOptionsClaris,
@@ -15,7 +16,7 @@ import {
15
16
  loginOptionsOAuth
16
17
  } from "../types.js";
17
18
 
18
- export default class FMHost {
19
+ export default class FMHost implements HostBase {
19
20
  readonly hostname: string
20
21
  readonly timezoneOffset: number
21
22
  readonly verify: boolean
@@ -50,8 +51,8 @@ export default class FMHost {
50
51
  }
51
52
  }
52
53
 
53
- database(data: databaseOptionsWithExternalSources) {
54
- return new Database(this, data)
54
+ database<T extends DatabaseStructure>(data: databaseOptionsWithExternalSources) {
55
+ return new Database<T>(this, data)
55
56
  }
56
57
 
57
58
  async getMetadata() {
@@ -0,0 +1,8 @@
1
+ import { FMHostMetadata } from "../types";
2
+ export interface HostBase {
3
+ readonly hostname: string;
4
+ readonly timezoneOffset: number;
5
+ readonly verify: boolean;
6
+ metadata: FMHostMetadata;
7
+ getMetadata(): PromiseLike<any>;
8
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ * Copyright (c) 2023. See LICENSE file for more information
3
+ */
4
+ export {};
@@ -0,0 +1,15 @@
1
+ /*
2
+ * Copyright (c) 2023. See LICENSE file for more information
3
+ */
4
+
5
+ import {
6
+ FMHostMetadata
7
+ } from "../types";
8
+
9
+ export interface HostBase {
10
+ readonly hostname: string
11
+ readonly timezoneOffset: number
12
+ readonly verify: boolean
13
+ metadata: FMHostMetadata
14
+ getMetadata(): PromiseLike<any>
15
+ }
@@ -5,22 +5,24 @@ import { Request } from "node-fetch";
5
5
  import { LayoutInterface } from "../layouts/layoutInterface.js";
6
6
  import { Layout } from "../layouts/layout.js";
7
7
  import * as http from "http";
8
- import { databaseOptionsWithExternalSources, Script } from "../types.js";
9
- import FMHost from "./FMHost.js";
10
- export declare class Database extends EventEmitter {
8
+ import { databaseOptionsWithExternalSources, DatabaseStructure, Script } from "../types.js";
9
+ import { HostBase } from "./HostBase.js";
10
+ import { DatabaseBase } from "./databaseBase";
11
+ export declare class Database<T extends DatabaseStructure> extends EventEmitter implements DatabaseBase {
11
12
  private _token;
12
- readonly host: FMHost;
13
+ readonly host: HostBase;
13
14
  private connection_details;
14
15
  private cookies;
15
16
  readonly name: string;
16
- constructor(host: FMHost, conn: databaseOptionsWithExternalSources);
17
+ constructor(host: HostBase, conn: databaseOptionsWithExternalSources);
17
18
  private generateExternalSourceLogin;
18
19
  logout(): Promise<void>;
19
20
  login(): Promise<string>;
20
21
  get token(): any;
21
22
  get endpoint(): string;
22
- apiRequest(url: string | Request, options?: any, autoRelogin?: boolean): Promise<any>;
23
- getLayout<T extends LayoutInterface>(name: any): Layout<T>;
23
+ apiRequest<T = any>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<T>;
24
+ getLayout<R extends string>(name: R): Layout<T["layouts"][R]>;
25
+ getLayout<R extends LayoutInterface>(name: string): Layout<R>;
24
26
  setGlobals(globalFields: any): Promise<void>;
25
27
  script(name: any, parameter?: string): Script;
26
28
  _tokenExpired(): void;
@@ -12,22 +12,25 @@ import * as http from "http";
12
12
  import * as https from "https";
13
13
  import {
14
14
  databaseOptionsBase,
15
- databaseOptionsWithExternalSources,
15
+ databaseOptionsWithExternalSources, DatabaseStructure,
16
16
  fileMakerResponse,
17
17
  loginOptionsFileMaker,
18
18
  loginOptionsToken,
19
19
  Script
20
20
  } from "../types.js";
21
- import FMHost from "./FMHost.js";
21
+ import {HostBase} from "./HostBase.js"
22
+ import {DatabaseBase} from "./databaseBase";
22
23
 
23
- export class Database extends EventEmitter {
24
+ type GetLayoutReturnType<T extends DatabaseStructure, R extends LayoutInterface | string> = R extends string ? T["layouts"][R] : R
25
+
26
+ export class Database<T extends DatabaseStructure> extends EventEmitter implements DatabaseBase {
24
27
  private _token: any;
25
- readonly host: FMHost;
28
+ readonly host: HostBase;
26
29
  private connection_details: databaseOptionsWithExternalSources
27
30
  private cookies: { [key: string]: string } = {}
28
31
  readonly name: string;
29
32
 
30
- constructor(host: FMHost, conn: databaseOptionsWithExternalSources) {
33
+ constructor(host: HostBase, conn: databaseOptionsWithExternalSources) {
31
34
  super()
32
35
  this.host = host
33
36
  this.name = conn.database
@@ -119,7 +122,7 @@ export class Database extends EventEmitter {
119
122
  return `${this.host.hostname}/fmi/data/v2/databases/${this.name}`
120
123
  }
121
124
 
122
- async apiRequest(url: string | Request, options: any = {}, autoRelogin = true): Promise<any> {
125
+ async apiRequest<T = any>(url: string | Request, options: any = {}, autoRelogin = true): Promise<T> {
123
126
  if (!options.headers) options.headers = {}
124
127
  options.headers["content-type"] = options.headers["content-type"] ? options.headers["content-type"] : "application/json"
125
128
  options.headers["authorization"] = "Bearer " + this._token
@@ -142,8 +145,10 @@ export class Database extends EventEmitter {
142
145
  return (data as any)
143
146
  }
144
147
 
145
- getLayout<T extends LayoutInterface>(name): Layout<T> {
146
- return new Layout(this, name)
148
+ getLayout<R extends string>(name: R): Layout<T["layouts"][R]>
149
+ getLayout<R extends LayoutInterface>(name: string): Layout<R>
150
+ getLayout(name: string): Layout<LayoutInterface> {
151
+ return new Layout<LayoutInterface>(this, name)
147
152
  }
148
153
 
149
154
  setGlobals(globalFields): Promise<void> {
@@ -0,0 +1,8 @@
1
+ import { HostBase } from "./HostBase.js";
2
+ import { Request } from "node-fetch";
3
+ export interface DatabaseBase {
4
+ host: HostBase;
5
+ readonly name: string;
6
+ endpoint: string;
7
+ apiRequest(url: string | Request, options?: any, autoRelogin?: boolean): Promise<any>;
8
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ * Copyright (c) 2023. See LICENSE file for more information
3
+ */
4
+ export {};
@@ -0,0 +1,17 @@
1
+ /*
2
+ * Copyright (c) 2023. See LICENSE file for more information
3
+ */
4
+
5
+ import {HostBase} from "./HostBase.js"
6
+ import {Request} from "node-fetch";
7
+ import {DatabaseStructure} from "../types";
8
+
9
+ export interface DatabaseBase {
10
+ host: HostBase,
11
+ readonly name: string
12
+ endpoint: string
13
+
14
+ // layouts: DatabaseStructure["layouts"]
15
+
16
+ apiRequest(url: string | Request, options?: any, autoRelogin?: boolean): Promise<any>
17
+ }
package/src/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import { Database } from "./connection/database.js";
5
5
  import { Layout } from "./layouts/layout.js";
6
6
  import { RecordBase } from "./records/recordBase.js";
7
7
  import { LayoutRecord } from "./records/layoutRecord.js";
8
- import { LayoutInterface, RecordFieldsMap, PortalInterface, Container } from "./layouts/layoutInterface.js";
8
+ import { LayoutInterface, PortalInterface } from "./layouts/layoutInterface.js";
9
9
  import { PortalRecord } from "./records/portalRecord.js";
10
10
  import { Portal } from "./records/portal.js";
11
11
  import { Field } from "./records/field.js";
@@ -13,5 +13,7 @@ import { Find } from "./records/getOperations/find.js";
13
13
  import { RecordGetOperation } from "./records/getOperations/recordGetOperation.js";
14
14
  import { RecordGetRange } from "./records/getOperations/recordGetRange.js";
15
15
  import { LayoutRecordManager } from "./layouts/layoutRecordManager.js";
16
+ import { RecordFieldsMap } from "./layouts/recordFieldsMap";
17
+ import { Container } from "./records/field.js";
16
18
  export default FMHost;
17
19
  export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, LayoutInterface, RecordFieldsMap, PortalInterface, PortalRecord, Portal, Field, Find, RecordGetOperation, RecordGetRange, LayoutRecordManager, Container };
package/src/index.ts CHANGED
@@ -9,7 +9,7 @@ import {Database} from "./connection/database.js";
9
9
  import {Layout} from "./layouts/layout.js";
10
10
  import {RecordBase} from "./records/recordBase.js";
11
11
  import {LayoutRecord} from "./records/layoutRecord.js";
12
- import {LayoutInterface, RecordFieldsMap, PortalInterface, Container} from "./layouts/layoutInterface.js";
12
+ import {LayoutInterface, PortalInterface} from "./layouts/layoutInterface.js";
13
13
  import {PortalRecord} from "./records/portalRecord.js";
14
14
  import {Portal} from "./records/portal.js";
15
15
  import {Field} from "./records/field.js";
@@ -17,6 +17,8 @@ import {Find} from "./records/getOperations/find.js";
17
17
  import {RecordGetOperation} from "./records/getOperations/recordGetOperation.js";
18
18
  import {RecordGetRange} from "./records/getOperations/recordGetRange.js";
19
19
  import {LayoutRecordManager} from "./layouts/layoutRecordManager.js";
20
+ import {RecordFieldsMap} from "./layouts/recordFieldsMap";
21
+ import {Container} from "./records/field.js";
20
22
 
21
23
  export default FMHost
22
24
  export {
@@ -1,16 +1,17 @@
1
1
  import { LayoutRecordManager } from "./layoutRecordManager.js";
2
2
  import { LayoutRecord } from "../records/layoutRecord.js";
3
- import { ScriptResult } from "../types.js";
3
+ import { Script, ScriptResult } from "../types.js";
4
4
  import { LayoutInterface } from "./layoutInterface.js";
5
5
  import { Find } from "../records/getOperations/find.js";
6
6
  import { FMError } from "../FMError.js";
7
- import { Database } from "../connection/database.js";
8
- export declare class Layout<T extends LayoutInterface> {
9
- readonly database: Database;
7
+ import { LayoutBase } from "./layoutBase.js";
8
+ import { DatabaseBase } from "../connection/databaseBase";
9
+ export declare class Layout<T extends LayoutInterface> implements LayoutBase {
10
+ readonly database: DatabaseBase;
10
11
  readonly records: LayoutRecordManager<T>;
11
- protected name: string;
12
+ readonly name: string;
12
13
  metadata: any;
13
- constructor(database: Database, name: string);
14
+ constructor(database: DatabaseBase, name: string);
14
15
  get endpoint(): string;
15
16
  /**
16
17
  * @deprecated use layout.records.create() instead
@@ -24,6 +25,6 @@ export declare class Layout<T extends LayoutInterface> {
24
25
  * @deprecated use layout.records.find() instead
25
26
  */
26
27
  newFind(): Find<T>;
27
- runScript(script: any): Promise<ScriptResult>;
28
+ runScript(script: Script): Promise<ScriptResult>;
28
29
  getLayoutMeta(): Promise<this | FMError>;
29
30
  }
@@ -4,19 +4,20 @@
4
4
 
5
5
  import {LayoutRecordManager} from "./layoutRecordManager.js";
6
6
  import {LayoutRecord} from "../records/layoutRecord.js";
7
- import {ScriptResult} from "../types.js";
7
+ import {Script, ScriptResult} from "../types.js";
8
8
  import {LayoutInterface} from "./layoutInterface.js";
9
9
  import {Find} from "../records/getOperations/find.js";
10
10
  import {FMError} from "../FMError.js";
11
- import {Database} from "../connection/database.js";
11
+ import {LayoutBase} from "./layoutBase.js"
12
+ import {DatabaseBase} from "../connection/databaseBase";
12
13
 
13
- export class Layout<T extends LayoutInterface> {
14
- readonly database: Database;
14
+ export class Layout<T extends LayoutInterface> implements LayoutBase {
15
+ readonly database: DatabaseBase;
15
16
  readonly records = new LayoutRecordManager<T>(this)
16
- protected name: string;
17
+ readonly name: string;
17
18
  metadata: any;
18
19
 
19
- constructor(database: Database, name: string) {
20
+ constructor(database: DatabaseBase, name: string) {
20
21
  this.database = database
21
22
  this.name = name
22
23
  }
@@ -46,7 +47,7 @@ export class Layout<T extends LayoutInterface> {
46
47
  return this.records.find()
47
48
  }
48
49
 
49
- runScript(script): Promise<ScriptResult> {
50
+ runScript(script: Script): Promise<ScriptResult> {
50
51
  let trace = new Error()
51
52
  return new Promise(async (resolve, reject) => {
52
53
  let url = `${this.endpoint}/script/${encodeURIComponent(script.name)}`
@@ -0,0 +1,11 @@
1
+ import { Script, ScriptResult } from "../types";
2
+ import { FMError } from "../FMError";
3
+ import { DatabaseBase } from "../connection/databaseBase";
4
+ export interface LayoutBase {
5
+ readonly name: string;
6
+ metadata: any;
7
+ endpoint: string;
8
+ runScript(script: Script): Promise<ScriptResult>;
9
+ getLayoutMeta(): Promise<this | FMError>;
10
+ database: DatabaseBase;
11
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ * Copyright (c) 2023. See LICENSE file for more information
3
+ */
4
+ export {};
@@ -0,0 +1,16 @@
1
+ /*
2
+ * Copyright (c) 2023. See LICENSE file for more information
3
+ */
4
+
5
+ import {Script, ScriptResult} from "../types";
6
+ import {FMError} from "../FMError";
7
+ import {DatabaseBase} from "../connection/databaseBase";
8
+
9
+ export interface LayoutBase {
10
+ readonly name: string
11
+ metadata: any
12
+ endpoint: string
13
+ runScript(script: Script): Promise<ScriptResult>
14
+ getLayoutMeta(): Promise<this | FMError>
15
+ database: DatabaseBase
16
+ }
@@ -1,5 +1,5 @@
1
1
  import { Portal } from "../records/portal.js";
2
- import { Field } from "../records/field.js";
2
+ import { RecordFieldsMap } from "./recordFieldsMap";
3
3
  export interface LayoutInterface {
4
4
  fields: RecordFieldsMap;
5
5
  portals: PortalInterface;
@@ -7,8 +7,3 @@ export interface LayoutInterface {
7
7
  export interface PortalInterface {
8
8
  [key: string]: Portal<RecordFieldsMap>;
9
9
  }
10
- export interface RecordFieldsMap {
11
- [fieldName: string]: Field<FieldValue>;
12
- }
13
- export type Container = null;
14
- export type FieldValue = string | number | Date | Container;
@@ -3,7 +3,7 @@
3
3
  */
4
4
 
5
5
  import {Portal} from "../records/portal.js";
6
- import {Field} from "../records/field.js";
6
+ import {RecordFieldsMap} from "./recordFieldsMap";
7
7
 
8
8
  export interface LayoutInterface {
9
9
  fields: RecordFieldsMap,
@@ -14,9 +14,3 @@ export interface PortalInterface {
14
14
  [key: string]: Portal<RecordFieldsMap>
15
15
  }
16
16
 
17
- export interface RecordFieldsMap {
18
- [fieldName: string]: Field<FieldValue>
19
- }
20
-
21
- export type Container = null
22
- export type FieldValue = string | number | Date | Container
@@ -1,11 +1,11 @@
1
1
  import { LayoutRecord } from "../records/layoutRecord.js";
2
- import { Layout } from "./layout.js";
3
2
  import { LayoutInterface } from "./layoutInterface.js";
4
3
  import { RecordGetRange } from "../records/getOperations/recordGetRange.js";
5
4
  import { Find } from "../records/getOperations/find.js";
5
+ import { LayoutBase } from "./layoutBase.js";
6
6
  export declare class LayoutRecordManager<T extends LayoutInterface> {
7
- readonly layout: Layout<T>;
8
- constructor(layout: Layout<T>);
7
+ readonly layout: LayoutBase;
8
+ constructor(layout: LayoutBase);
9
9
  create(): Promise<LayoutRecord<T["fields"], T["portals"]>>;
10
10
  get(recordId: any): Promise<LayoutRecord<T["fields"], T["portals"]>>;
11
11
  range(start?: number, limit?: number): RecordGetRange<T>;
@@ -3,15 +3,15 @@
3
3
  */
4
4
 
5
5
  import {LayoutRecord} from "../records/layoutRecord.js";
6
- import {Layout} from "./layout.js";
7
6
  import {LayoutInterface} from "./layoutInterface.js";
8
7
  import {RecordGetRange} from "../records/getOperations/recordGetRange.js";
9
8
  import {Find} from "../records/getOperations/find.js";
9
+ import {LayoutBase} from "./layoutBase.js"
10
10
 
11
11
  export class LayoutRecordManager<T extends LayoutInterface> {
12
- readonly layout: Layout<T>
12
+ readonly layout: LayoutBase
13
13
 
14
- constructor(layout: Layout<T>) {
14
+ constructor(layout: LayoutBase) {
15
15
  this.layout = layout
16
16
  }
17
17
 
@@ -0,0 +1,4 @@
1
+ import { Field, FieldValue } from "../records/field";
2
+ export interface RecordFieldsMap {
3
+ [fieldName: string]: Field<FieldValue>;
4
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ * Copyright (c) 2023. See LICENSE file for more information
3
+ */
4
+ export {};
@@ -0,0 +1,9 @@
1
+ /*
2
+ * Copyright (c) 2023. See LICENSE file for more information
3
+ */
4
+
5
+ import {Field, FieldValue} from "../records/field";
6
+
7
+ export interface RecordFieldsMap {
8
+ [fieldName: string]: Field<FieldValue>
9
+ }
@@ -3,7 +3,8 @@
3
3
  import { RecordBase } from "./recordBase.js";
4
4
  import * as http from "http";
5
5
  import { ContainerBufferResult, DOWNLOAD_MODES, FieldMetaData } from "../types.js";
6
- import { FieldValue } from "../layouts/layoutInterface.js";
6
+ export type FieldValue = string | number | Date | Container;
7
+ export type Container = null;
7
8
  export declare class Field<T extends FieldValue> {
8
9
  record: RecordBase<any>;
9
10
  id: string;
@@ -10,9 +10,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  step((generator = generator.apply(thisArg, _arguments || [])).next());
11
11
  });
12
12
  };
13
+ import { RecordTypes } from "./recordBase.js";
13
14
  import fetch, { File, FormData } from "node-fetch";
14
15
  import { DOWNLOAD_MODES } from "../types.js";
15
- import { PortalRecord } from "./portalRecord.js";
16
16
  import { FMError } from "../FMError.js";
17
17
  export class Field {
18
18
  constructor(record, id, contents) {
@@ -58,7 +58,8 @@ export class Field {
58
58
  repetitionEnd: 1
59
59
  };
60
60
  }
61
- if (this.record instanceof PortalRecord) {
61
+ if (this.record.type === RecordTypes.PORTAL) {
62
+ // @ts-ignore
62
63
  return this.record.layout.metadata.portalMetaData[this.record.portal.name || "portal not attached"].find(i => i.name === this.id) || {
63
64
  name: this.id.toString(),
64
65
  type: 'normal',
@@ -129,6 +130,7 @@ export class Field {
129
130
  form.append("upload", new File([buffer], filename, { type: mime }));
130
131
  let _fetch = yield fetch(`${this.record.endpoint}/containers/${this.id}/1`, {
131
132
  method: "POST",
133
+ // @ts-ignore
132
134
  headers: { "Authorization": "Bearer " + this.record.layout.database.token },
133
135
  body: form
134
136
  }).then(res => res.json())
@@ -148,6 +150,7 @@ export class Field {
148
150
  }
149
151
  download(mode = DOWNLOAD_MODES.Stream) {
150
152
  return new Promise((resolve, reject) => {
153
+ // @ts-ignore
151
154
  this.record.layout.database.streamContainer(this, this._value)
152
155
  .then(stream => {
153
156
  if (mode === DOWNLOAD_MODES.Stream) {