@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.
- package/README.md +85 -18
- package/package.json +1 -1
- package/src/connection/FMHost.d.ts +4 -3
- package/src/connection/FMHost.ts +5 -4
- package/src/connection/HostBase.d.ts +8 -0
- package/src/connection/HostBase.js +4 -0
- package/src/connection/HostBase.ts +15 -0
- package/src/connection/database.d.ts +9 -7
- package/src/connection/database.ts +13 -8
- package/src/connection/databaseBase.d.ts +8 -0
- package/src/connection/databaseBase.js +4 -0
- package/src/connection/databaseBase.ts +17 -0
- package/src/index.d.ts +3 -1
- package/src/index.ts +3 -1
- package/src/layouts/layout.d.ts +8 -7
- package/src/layouts/layout.ts +8 -7
- package/src/layouts/layoutBase.d.ts +11 -0
- package/src/layouts/layoutBase.js +4 -0
- package/src/layouts/layoutBase.ts +16 -0
- package/src/layouts/layoutInterface.d.ts +1 -6
- package/src/layouts/layoutInterface.ts +1 -7
- package/src/layouts/layoutRecordManager.d.ts +3 -3
- package/src/layouts/layoutRecordManager.ts +3 -3
- package/src/layouts/recordFieldsMap.d.ts +4 -0
- package/src/layouts/recordFieldsMap.js +4 -0
- package/src/layouts/recordFieldsMap.ts +9 -0
- package/src/records/field.d.ts +2 -1
- package/src/records/field.js +5 -2
- package/src/records/field.ts +8 -4
- package/src/records/getOperations/find.d.ts +2 -2
- package/src/records/getOperations/find.js +3 -3
- package/src/records/getOperations/find.ts +5 -5
- package/src/records/getOperations/recordGetOperation.d.ts +3 -3
- package/src/records/getOperations/recordGetOperation.js +1 -1
- package/src/records/getOperations/recordGetOperation.ts +4 -4
- package/src/records/getOperations/recordGetRange.js +3 -3
- package/src/records/getOperations/recordGetRange.ts +3 -3
- package/src/records/layoutRecord.d.ts +4 -2
- package/src/records/layoutRecord.js +2 -0
- package/src/records/layoutRecord.ts +6 -3
- package/src/records/layoutRecordBase.d.ts +5 -0
- package/src/records/layoutRecordBase.js +4 -0
- package/src/records/layoutRecordBase.ts +10 -0
- package/src/records/portal.d.ts +4 -3
- package/src/records/portal.ts +5 -3
- package/src/records/portalBase.d.ts +8 -0
- package/src/records/portalBase.js +4 -0
- package/src/records/portalBase.ts +14 -0
- package/src/records/portalRecord.d.ts +6 -5
- package/src/records/portalRecord.js +2 -1
- package/src/records/portalRecord.ts +6 -4
- package/src/records/portalRecordBase.d.ts +4 -0
- package/src/records/portalRecordBase.js +6 -0
- package/src/records/recordBase.d.ts +9 -3
- package/src/records/recordBase.js +8 -4
- package/src/records/recordBase.ts +10 -7
- package/src/types.d.ts +7 -2
- package/src/types.ts +8 -3
- package/test.d.ts +2 -1
- package/test.js +27 -1
- package/test.ts +33 -0
- package/test2.d.ts +1 -0
- package/test2.js +15 -0
- 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
|
-
|
|
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.
|
|
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.
|
|
107
|
-
record.
|
|
108
|
-
record.
|
|
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.
|
|
120
|
-
record.
|
|
121
|
-
record.
|
|
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
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
131
|
-
|
|
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
|
-
|
|
134
|
-
|
|
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,12 +1,13 @@
|
|
|
1
1
|
import { Database } from "./database.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
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
|
}
|
package/src/connection/FMHost.ts
CHANGED
|
@@ -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,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
|
|
10
|
-
|
|
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:
|
|
13
|
+
readonly host: HostBase;
|
|
13
14
|
private connection_details;
|
|
14
15
|
private cookies;
|
|
15
16
|
readonly name: string;
|
|
16
|
-
constructor(host:
|
|
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<
|
|
23
|
-
getLayout<
|
|
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
|
|
21
|
+
import {HostBase} from "./HostBase.js"
|
|
22
|
+
import {DatabaseBase} from "./databaseBase";
|
|
22
23
|
|
|
23
|
-
|
|
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:
|
|
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:
|
|
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<
|
|
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<
|
|
146
|
-
|
|
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,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,
|
|
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,
|
|
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 {
|
package/src/layouts/layout.d.ts
CHANGED
|
@@ -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 {
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
|
|
12
|
+
readonly name: string;
|
|
12
13
|
metadata: any;
|
|
13
|
-
constructor(database:
|
|
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:
|
|
28
|
+
runScript(script: Script): Promise<ScriptResult>;
|
|
28
29
|
getLayoutMeta(): Promise<this | FMError>;
|
|
29
30
|
}
|
package/src/layouts/layout.ts
CHANGED
|
@@ -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 {
|
|
11
|
+
import {LayoutBase} from "./layoutBase.js"
|
|
12
|
+
import {DatabaseBase} from "../connection/databaseBase";
|
|
12
13
|
|
|
13
|
-
export class Layout<T extends LayoutInterface> {
|
|
14
|
-
readonly database:
|
|
14
|
+
export class Layout<T extends LayoutInterface> implements LayoutBase {
|
|
15
|
+
readonly database: DatabaseBase;
|
|
15
16
|
readonly records = new LayoutRecordManager<T>(this)
|
|
16
|
-
|
|
17
|
+
readonly name: string;
|
|
17
18
|
metadata: any;
|
|
18
19
|
|
|
19
|
-
constructor(database:
|
|
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,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 {
|
|
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 {
|
|
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:
|
|
8
|
-
constructor(layout:
|
|
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:
|
|
12
|
+
readonly layout: LayoutBase
|
|
13
13
|
|
|
14
|
-
constructor(layout:
|
|
14
|
+
constructor(layout: LayoutBase) {
|
|
15
15
|
this.layout = layout
|
|
16
16
|
}
|
|
17
17
|
|
package/src/records/field.d.ts
CHANGED
|
@@ -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
|
-
|
|
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;
|
package/src/records/field.js
CHANGED
|
@@ -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
|
|
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) {
|