@jd-data-limited/easy-fm 3.2.8 → 4.0.1
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 +36 -24
- package/package.json +12 -9
- package/src/FMError.js +2 -2
- package/src/FMError.ts +2 -2
- package/src/connection/FMHost.d.ts +2 -1
- package/src/connection/FMHost.js +1 -2
- package/src/connection/FMHost.ts +4 -4
- package/src/connection/HostBase.d.ts +1 -1
- package/src/connection/HostBase.js +1 -1
- package/src/connection/HostBase.ts +2 -4
- package/src/connection/database.d.ts +10 -10
- package/src/connection/database.js +6 -17
- package/src/connection/database.ts +17 -27
- package/src/connection/databaseBase.d.ts +4 -4
- package/src/connection/databaseBase.js +1 -1
- package/src/connection/databaseBase.ts +4 -6
- package/src/databaseStructure.d.ts +6 -0
- package/src/databaseStructure.js +4 -0
- package/src/databaseStructure.ts +12 -0
- package/src/index.d.ts +3 -6
- package/src/index.js +3 -5
- package/src/index.ts +4 -9
- package/src/layouts/layout.d.ts +3 -17
- package/src/layouts/layout.js +2 -20
- package/src/layouts/layout.ts +5 -27
- package/src/layouts/layoutBase.d.ts +4 -4
- package/src/layouts/layoutBase.js +1 -1
- package/src/layouts/layoutBase.ts +5 -6
- package/src/layouts/layoutInterface.d.ts +1 -1
- package/src/layouts/layoutInterface.js +1 -1
- package/src/layouts/layoutInterface.ts +2 -2
- package/src/layouts/layoutRecordManager.d.ts +5 -6
- package/src/layouts/layoutRecordManager.js +5 -9
- package/src/layouts/layoutRecordManager.ts +12 -16
- package/src/layouts/recordFieldsMap.d.ts +2 -2
- package/src/layouts/recordFieldsMap.js +1 -1
- package/src/layouts/recordFieldsMap.ts +3 -3
- package/src/models/apiResults.d.ts +3 -3
- package/src/models/apiResults.js +1 -1
- package/src/models/apiResults.ts +2 -4
- package/src/records/field.d.ts +3 -23
- package/src/records/field.js +3 -152
- package/src/records/field.ts +4 -169
- package/src/records/fieldBase.d.ts +30 -0
- package/src/records/fieldBase.js +154 -0
- package/src/records/fieldBase.ts +174 -0
- package/src/records/getOperations/recordGetOperation.d.ts +47 -11
- package/src/records/getOperations/recordGetOperation.js +142 -31
- package/src/records/getOperations/recordGetOperation.ts +172 -30
- package/src/records/layoutRecord.d.ts +14 -11
- package/src/records/layoutRecord.js +7 -8
- package/src/records/layoutRecord.ts +32 -22
- package/src/records/portal.d.ts +6 -5
- package/src/records/portal.js +1 -1
- package/src/records/portal.ts +10 -8
- package/src/records/portalBase.d.ts +5 -4
- package/src/records/portalBase.js +1 -1
- package/src/records/portalBase.ts +6 -6
- package/src/records/portalRecord.d.ts +12 -8
- package/src/records/portalRecord.js +6 -8
- package/src/records/portalRecord.ts +17 -16
- package/src/records/recordBase.d.ts +11 -15
- package/src/records/recordBase.js +9 -13
- package/src/records/recordBase.ts +17 -25
- package/src/types.d.ts +18 -15
- package/src/types.js +7 -1
- package/src/types.ts +20 -16
- package/src/records/getOperations/find.d.ts +0 -15
- package/src/records/getOperations/find.js +0 -70
- package/src/records/getOperations/find.ts +0 -77
- package/src/records/getOperations/recordGetRange.d.ts +0 -13
- package/src/records/getOperations/recordGetRange.js +0 -77
- package/src/records/getOperations/recordGetRange.ts +0 -77
- package/src/records/portalRecordBase.d.ts +0 -4
- package/src/records/portalRecordBase.js +0 -6
package/README.md
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
# easy-fm
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A [FileMaker Data API](https://help.claris.com/en/data-api-guide/content/index.html) client for NodeJS
|
|
4
4
|
|
|
5
5
|
easy-fm is a Node.js module that allows you to interact with
|
|
6
|
-
a [FileMaker database](https://www.claris.com/filemaker/) stored on
|
|
7
|
-
a [FileMaker server](https://www.claris.com/filemaker/server/)
|
|
6
|
+
a [FileMaker database](https://www.claris.com/filemaker/) stored on a [FileMaker server](https://www.claris.com/filemaker/server/)
|
|
8
7
|
or [FileMaker Cloud](https://store.claris.com/filemaker-cloud). This module interacts with your server using the
|
|
9
8
|
[FileMaker Data API](https://help.claris.com/en/data-api-guide/content/index.html).
|
|
10
9
|
<!-- TOC -->
|
|
10
|
+
|
|
11
11
|
* [easy-fm](#easy-fm)
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
21
|
* [Field names](#field-names)
|
|
22
22
|
* [Portal names](#portal-names)
|
|
23
23
|
* [Typescript Implementation](#typescript-implementation)
|
|
24
|
+
|
|
24
25
|
<!-- TOC -->
|
|
26
|
+
|
|
25
27
|
## FileMaker setup instructions
|
|
26
28
|
|
|
27
29
|
1. Enable the FileMaker Data API from the server's admin console. This setting is located
|
|
@@ -34,7 +36,8 @@ or [FileMaker Cloud](https://store.claris.com/filemaker-cloud). This module inte
|
|
|
34
36
|
## Before you begin
|
|
35
37
|
|
|
36
38
|
- You need to know what your server's UTC time offset (in minutes) is.
|
|
37
|
-
- Running `0 - (new Date()).getTimezoneOffset()` in javascript will give you the UTC time offset for your current
|
|
39
|
+
- Running `0 - (new Date()).getTimezoneOffset()` in javascript will give you the UTC time offset for your current
|
|
40
|
+
timezone.
|
|
38
41
|
|
|
39
42
|
## Connecting to a database
|
|
40
43
|
|
|
@@ -77,26 +80,34 @@ One of (if not the) most common interactions you'll need to use is fetching reco
|
|
|
77
80
|
|
|
78
81
|
```javascript
|
|
79
82
|
let layout = database.getLayout("Your layout name")
|
|
80
|
-
let
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
let query = layout.records.list({
|
|
84
|
+
portals: {
|
|
85
|
+
test: {limit: 10, offset: 1} // Include results from the 'test' portal
|
|
86
|
+
},
|
|
87
|
+
limit: 10, // Limit result set to 10 records...
|
|
88
|
+
offset: 30 // ...starting from the 30th record
|
|
89
|
+
})
|
|
84
90
|
|
|
85
|
-
let records = await
|
|
91
|
+
let records = await query.fetch()
|
|
86
92
|
console.log(records)
|
|
87
93
|
```
|
|
88
94
|
|
|
89
95
|
### Searching for records
|
|
96
|
+
Searching for records uses the same syntax as above, but with additional steps to add your search parameters.
|
|
90
97
|
|
|
91
98
|
```javascript
|
|
92
99
|
let layout = database.getLayout("Your layout name")
|
|
93
|
-
let
|
|
100
|
+
let query = layout.records.list({
|
|
101
|
+
portals: {
|
|
102
|
+
test: {limit: 10, offset: 1} // Include results from the 'test' portal
|
|
103
|
+
},
|
|
104
|
+
limit: 10, // Limit result set to 10 records...
|
|
105
|
+
offset: 30 // ...starting from the 30th record
|
|
106
|
+
})
|
|
94
107
|
|
|
95
|
-
|
|
96
|
-
find_request.setOffset(30) // Starting from the 30th matching record
|
|
97
|
-
find_request.setLimit(10) // Fetch only 10 records
|
|
108
|
+
query.addRequest({"GroupID": "=abc"}) // Add a filter
|
|
98
109
|
|
|
99
|
-
let records = await
|
|
110
|
+
let records = await query.fetch()
|
|
100
111
|
console.log(records)
|
|
101
112
|
```
|
|
102
113
|
|
|
@@ -152,7 +163,8 @@ When interacting with FileMaker, it is important to remember how FileMaker field
|
|
|
152
163
|
|
|
153
164
|
> Please read this section carefully if you are working with portals
|
|
154
165
|
|
|
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
|
|
166
|
+
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
|
|
167
|
+
a
|
|
156
168
|
portal matches the object name it was assigned in FileMaker's layout editor.
|
|
157
169
|
|
|
158
170
|
> **NOTE**: When no name has been manually assigned to it, it will default to the name of the related table.
|
package/package.json
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jd-data-limited/easy-fm",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"dependencies": {
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"follow-redirects": "^1.15.3",
|
|
8
|
-
"moment": "^2.29.4",
|
|
9
|
-
"node-fetch": "3.3.2"
|
|
5
|
+
"follow-redirects": "^1.15.5",
|
|
6
|
+
"moment": "^2.29.4"
|
|
10
7
|
},
|
|
11
8
|
"type": "module",
|
|
12
9
|
"main": "src/index.js",
|
|
@@ -36,9 +33,15 @@
|
|
|
36
33
|
"url": "https://github.com/JD-Data-Limited/easy-fm/issues"
|
|
37
34
|
},
|
|
38
35
|
"devDependencies": {
|
|
39
|
-
"
|
|
36
|
+
"@types/btoa": "^1.2.3",
|
|
37
|
+
"@types/events": "^3.0.0",
|
|
38
|
+
"@types/follow-redirects": "^1.14.4",
|
|
39
|
+
"dotenv": "^16.3.1",
|
|
40
|
+
"typescript": "^5.3.3",
|
|
40
41
|
"webpack": "^5.81.0",
|
|
41
|
-
"webpack-cli": "^5.0.2"
|
|
42
|
-
|
|
42
|
+
"webpack-cli": "^5.0.2"
|
|
43
|
+
},
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=20.9.0"
|
|
43
46
|
}
|
|
44
47
|
}
|
package/src/FMError.js
CHANGED
|
@@ -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
|
// @ts-ignore
|
|
5
5
|
export const errs = [
|
|
@@ -1021,7 +1021,7 @@ export class FMError extends Error {
|
|
|
1021
1021
|
constructor(code, httpStatus, res, trace) {
|
|
1022
1022
|
if (typeof code === "string")
|
|
1023
1023
|
code = parseInt(code);
|
|
1024
|
-
super(errs.find(err => err.e === code)
|
|
1024
|
+
super(errs.find(err => err.e === code)?.d || "Unknown error");
|
|
1025
1025
|
this.httpStatus = httpStatus;
|
|
1026
1026
|
this.res = res;
|
|
1027
1027
|
this.messages = res.messages;
|
package/src/FMError.ts
CHANGED
|
@@ -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
|
|
|
5
5
|
// @ts-ignore
|
|
@@ -1023,7 +1023,7 @@ export class FMError extends Error {
|
|
|
1023
1023
|
|
|
1024
1024
|
constructor(code: string | number, httpStatus: number, res: any, trace?: Error) {
|
|
1025
1025
|
if (typeof code === "string") code = parseInt(code)
|
|
1026
|
-
super(errs.find(err => err.e === code)
|
|
1026
|
+
super(errs.find(err => err.e === code)?.d || "Unknown error");
|
|
1027
1027
|
this.httpStatus = httpStatus
|
|
1028
1028
|
this.res = res
|
|
1029
1029
|
this.messages = res.messages
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Database } from "./database.js";
|
|
2
2
|
import { HostBase } from "./HostBase.js";
|
|
3
|
-
import { databaseOptionsWithExternalSources,
|
|
3
|
+
import { databaseOptionsWithExternalSources, FMHostMetadata, loginOptionsClaris, loginOptionsFileMaker, loginOptionsOAuth } from "../types.js";
|
|
4
|
+
import { DatabaseStructure } from "../databaseStructure.js";
|
|
4
5
|
export default class FMHost implements HostBase {
|
|
5
6
|
readonly hostname: string;
|
|
6
7
|
readonly timezoneOffset: number;
|
package/src/connection/FMHost.js
CHANGED
|
@@ -1,8 +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
|
import { generateAuthorizationHeaders } from "./generateAuthorizationHeaders.js";
|
|
5
|
-
import fetch from "node-fetch";
|
|
6
5
|
import { FMError } from "../FMError.js";
|
|
7
6
|
import { Database } from "./database.js";
|
|
8
7
|
export default class FMHost {
|
package/src/connection/FMHost.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
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
5
|
import {generateAuthorizationHeaders} from "./generateAuthorizationHeaders.js";
|
|
6
|
-
import fetch from "node-fetch";
|
|
7
6
|
import {FMError} from "../FMError.js";
|
|
8
7
|
import {Database} from "./database.js";
|
|
9
8
|
import {HostBase} from "./HostBase.js"
|
|
10
9
|
import {
|
|
11
|
-
databaseOptionsWithExternalSources,
|
|
10
|
+
databaseOptionsWithExternalSources,
|
|
12
11
|
FMHostMetadata,
|
|
13
12
|
loginOptionsClaris,
|
|
14
13
|
loginOptionsFileMaker,
|
|
15
14
|
loginOptionsOAuth
|
|
16
15
|
} from "../types.js";
|
|
17
|
-
import {ApiResults} from "../models/apiResults";
|
|
16
|
+
import {ApiResults} from "../models/apiResults.js";
|
|
17
|
+
import {DatabaseStructure} from "../databaseStructure.js";
|
|
18
18
|
|
|
19
19
|
export default class FMHost implements HostBase {
|
|
20
20
|
readonly hostname: string
|
|
@@ -1,10 +1,8 @@
|
|
|
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 {
|
|
6
|
-
FMHostMetadata
|
|
7
|
-
} from "../types";
|
|
5
|
+
import {FMHostMetadata} from "../types.js";
|
|
8
6
|
|
|
9
7
|
export interface HostBase {
|
|
10
8
|
readonly hostname: string
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
3
|
import { EventEmitter } from "events";
|
|
3
|
-
import { Request } from "node-fetch";
|
|
4
4
|
import { LayoutInterface } from "../layouts/layoutInterface.js";
|
|
5
5
|
import { Layout } from "../layouts/layout.js";
|
|
6
|
-
import
|
|
7
|
-
import { databaseOptionsWithExternalSources, DatabaseStructure, Script } from "../types.js";
|
|
6
|
+
import { databaseOptionsWithExternalSources, Script } from "../types.js";
|
|
8
7
|
import { HostBase } from "./HostBase.js";
|
|
9
|
-
import { DatabaseBase } from "./databaseBase";
|
|
10
|
-
import { ApiResults } from "../models/apiResults";
|
|
8
|
+
import { DatabaseBase } from "./databaseBase.js";
|
|
9
|
+
import { ApiResults } from "../models/apiResults.js";
|
|
10
|
+
import { DatabaseStructure } from "../databaseStructure.js";
|
|
11
|
+
import { IncomingMessage } from "http";
|
|
11
12
|
export declare class Database<T extends DatabaseStructure> extends EventEmitter implements DatabaseBase {
|
|
12
13
|
private _token;
|
|
13
14
|
readonly host: HostBase;
|
|
@@ -22,10 +23,9 @@ export declare class Database<T extends DatabaseStructure> extends EventEmitter
|
|
|
22
23
|
get endpoint(): string;
|
|
23
24
|
apiRequest<T = any>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>;
|
|
24
25
|
listLayouts(): Promise<Layout<LayoutInterface>[]>;
|
|
25
|
-
getLayout<R extends
|
|
26
|
+
getLayout<R extends keyof T["layouts"]>(name: R): Layout<T["layouts"][R]>;
|
|
26
27
|
getLayout<R extends LayoutInterface>(name: string): Layout<R>;
|
|
27
|
-
|
|
28
|
-
script(name: any, parameter?: string): Script;
|
|
28
|
+
script(name: string, parameter?: string): Script;
|
|
29
29
|
_tokenExpired(): void;
|
|
30
|
-
streamURL(url: string): Promise<
|
|
30
|
+
streamURL(url: string): Promise<IncomingMessage>;
|
|
31
31
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
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
|
import { EventEmitter } from "events";
|
|
5
|
-
import fetch from "node-fetch";
|
|
6
5
|
import { generateAuthorizationHeaders } from "./generateAuthorizationHeaders.js";
|
|
7
6
|
import { FMError } from "../FMError.js";
|
|
8
7
|
import { Layout } from "../layouts/layout.js";
|
|
9
|
-
import HTTP_REDIRECT from "follow-redirects";
|
|
8
|
+
import * as HTTP_REDIRECT from "follow-redirects";
|
|
10
9
|
export class Database extends EventEmitter {
|
|
11
10
|
_token;
|
|
12
11
|
host;
|
|
@@ -57,9 +56,9 @@ export class Database extends EventEmitter {
|
|
|
57
56
|
}
|
|
58
57
|
else {
|
|
59
58
|
console.time();
|
|
60
|
-
let
|
|
61
|
-
|
|
62
|
-
|
|
59
|
+
let url = new URL(`${this.endpoint}/sessions`);
|
|
60
|
+
url.hostname = this.host.hostname;
|
|
61
|
+
let res = await fetch(url, {
|
|
63
62
|
method: "POST",
|
|
64
63
|
headers: generateAuthorizationHeaders(this.connection_details.credentials),
|
|
65
64
|
body: JSON.stringify({
|
|
@@ -124,16 +123,6 @@ export class Database extends EventEmitter {
|
|
|
124
123
|
getLayout(name) {
|
|
125
124
|
return new Layout(this, name);
|
|
126
125
|
}
|
|
127
|
-
/*
|
|
128
|
-
@deprecated
|
|
129
|
-
*/
|
|
130
|
-
async setGlobals(globalFields) {
|
|
131
|
-
// console.log({globalFields})
|
|
132
|
-
await this.apiRequest(`${this.endpoint}/globals`, {
|
|
133
|
-
method: "PATCH",
|
|
134
|
-
body: JSON.stringify({ globalFields })
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
126
|
script(name, parameter = "") {
|
|
138
127
|
return { name, parameter };
|
|
139
128
|
}
|
|
@@ -166,7 +155,7 @@ export class Database extends EventEmitter {
|
|
|
166
155
|
// Automatically switch between the http and https modules, based on which is needed
|
|
167
156
|
(url.startsWith("https") ? HTTP_REDIRECT.https : HTTP_REDIRECT.http).get(url, {
|
|
168
157
|
headers,
|
|
169
|
-
beforeRedirect: (options, res
|
|
158
|
+
beforeRedirect: (options, res) => check_for_cookies(res)
|
|
170
159
|
}, (res) => {
|
|
171
160
|
check_for_cookies(res);
|
|
172
161
|
resolve(res);
|
|
@@ -1,24 +1,25 @@
|
|
|
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
5
|
import {EventEmitter} from "events";
|
|
6
|
-
import fetch, {HeadersInit, Request} from "node-fetch";
|
|
7
6
|
import {generateAuthorizationHeaders} from "./generateAuthorizationHeaders.js";
|
|
8
7
|
import {FMError} from "../FMError.js";
|
|
9
8
|
import {LayoutInterface} from "../layouts/layoutInterface.js";
|
|
10
9
|
import {Layout} from "../layouts/layout.js";
|
|
11
|
-
import HTTP_REDIRECT
|
|
10
|
+
import * as HTTP_REDIRECT from "follow-redirects"
|
|
12
11
|
import {
|
|
13
12
|
databaseOptionsBase,
|
|
14
|
-
databaseOptionsWithExternalSources,
|
|
13
|
+
databaseOptionsWithExternalSources,
|
|
15
14
|
loginOptionsFileMaker,
|
|
16
15
|
loginOptionsToken,
|
|
17
16
|
Script
|
|
18
17
|
} from "../types.js";
|
|
19
18
|
import {HostBase} from "./HostBase.js"
|
|
20
|
-
import {DatabaseBase} from "./databaseBase";
|
|
21
|
-
import {ApiLayout, ApiResults} from "../models/apiResults";
|
|
19
|
+
import {DatabaseBase} from "./databaseBase.js";
|
|
20
|
+
import {ApiLayout, ApiResults} from "../models/apiResults.js";
|
|
21
|
+
import {DatabaseStructure} from "../databaseStructure.js";
|
|
22
|
+
import {IncomingMessage} from "http";
|
|
22
23
|
|
|
23
24
|
type GetLayoutReturnType<T extends DatabaseStructure, R extends LayoutInterface | string> = R extends string ? T["layouts"][R] : R
|
|
24
25
|
|
|
@@ -77,9 +78,9 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
|
|
|
77
78
|
}
|
|
78
79
|
else {
|
|
79
80
|
console.time()
|
|
80
|
-
let
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
let url = new URL(`${this.endpoint}/sessions`)
|
|
82
|
+
url.hostname = this.host.hostname
|
|
83
|
+
let res = await fetch(url, {
|
|
83
84
|
method: "POST",
|
|
84
85
|
headers: generateAuthorizationHeaders(this.connection_details.credentials) as unknown as HeadersInit,
|
|
85
86
|
body: JSON.stringify({
|
|
@@ -148,24 +149,13 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
|
|
|
148
149
|
return req.response.layouts.filter(i => !i.isFolder).map(layout => new Layout(this, layout.name))
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
getLayout<R extends
|
|
152
|
+
getLayout<R extends keyof T["layouts"]>(name: R): Layout<T["layouts"][R]>
|
|
152
153
|
getLayout<R extends LayoutInterface>(name: string): Layout<R>
|
|
153
|
-
getLayout(name: string): Layout<
|
|
154
|
+
getLayout(name: string): Layout<any> {
|
|
154
155
|
return new Layout<LayoutInterface>(this, name)
|
|
155
156
|
}
|
|
156
157
|
|
|
157
|
-
|
|
158
|
-
@deprecated
|
|
159
|
-
*/
|
|
160
|
-
async setGlobals(globalFields) {
|
|
161
|
-
// console.log({globalFields})
|
|
162
|
-
await this.apiRequest(`${this.endpoint}/globals`, {
|
|
163
|
-
method: "PATCH",
|
|
164
|
-
body: JSON.stringify({globalFields})
|
|
165
|
-
})
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
script(name, parameter = ""): Script {
|
|
158
|
+
script(name: string, parameter = ""): Script {
|
|
169
159
|
return ({name, parameter} as Script)
|
|
170
160
|
}
|
|
171
161
|
|
|
@@ -173,13 +163,13 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
|
|
|
173
163
|
this.emit("token_expired")
|
|
174
164
|
}
|
|
175
165
|
|
|
176
|
-
streamURL(url: string): Promise<
|
|
166
|
+
streamURL(url: string): Promise<IncomingMessage> {
|
|
177
167
|
return new Promise((resolve, reject) => {
|
|
178
168
|
if (!url || typeof url !== "string") {
|
|
179
169
|
throw new Error("URL is empty, or has invalid value")
|
|
180
170
|
}
|
|
181
171
|
|
|
182
|
-
let headers = {}
|
|
172
|
+
let headers: {[key: string]: string} = {}
|
|
183
173
|
if (Object.keys(this.cookies).length !== 0) {
|
|
184
174
|
headers["Cookie"] = Object.keys(this.cookies)
|
|
185
175
|
.map(key => {
|
|
@@ -188,7 +178,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
|
|
|
188
178
|
.join("; ")
|
|
189
179
|
}
|
|
190
180
|
|
|
191
|
-
const check_for_cookies = (res) => {
|
|
181
|
+
const check_for_cookies = (res: HTTP_REDIRECT.ResponseDetails) => {
|
|
192
182
|
// Check for the 'set-cookie' header. If it exists, remember it and strip it for better security.
|
|
193
183
|
if (res.headers['set-cookie']) {
|
|
194
184
|
for (let cookie of res.headers['set-cookie']) {
|
|
@@ -202,7 +192,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
|
|
|
202
192
|
// Automatically switch between the http and https modules, based on which is needed
|
|
203
193
|
(url.startsWith("https") ? HTTP_REDIRECT.https : HTTP_REDIRECT.http).get(url, {
|
|
204
194
|
headers,
|
|
205
|
-
beforeRedirect: (options, res
|
|
195
|
+
beforeRedirect: (options, res) => check_for_cookies(res)
|
|
206
196
|
}, (res) => {
|
|
207
197
|
check_for_cookies(res)
|
|
208
198
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
1
2
|
import { HostBase } from "./HostBase.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import HTTP_REDIRECT from "follow-redirects";
|
|
3
|
+
import { ApiResults } from "../models/apiResults.js";
|
|
4
|
+
import { IncomingMessage } from "http";
|
|
5
5
|
export interface DatabaseBase {
|
|
6
6
|
host: HostBase;
|
|
7
7
|
readonly name: string;
|
|
8
8
|
endpoint: string;
|
|
9
9
|
apiRequest<T = unknown>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>;
|
|
10
|
-
streamURL(url: string): Promise<
|
|
10
|
+
streamURL(url: string): Promise<IncomingMessage>;
|
|
11
11
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
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
5
|
import {HostBase} from "./HostBase.js"
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {ApiResults} from "../models/apiResults";
|
|
9
|
-
import HTTP_REDIRECT from "follow-redirects"
|
|
6
|
+
import {ApiResults} from "../models/apiResults.js";
|
|
7
|
+
import {IncomingMessage} from "http";
|
|
10
8
|
|
|
11
9
|
export interface DatabaseBase {
|
|
12
10
|
host: HostBase,
|
|
@@ -16,5 +14,5 @@ export interface DatabaseBase {
|
|
|
16
14
|
// layouts: DatabaseStructure["layouts"]
|
|
17
15
|
|
|
18
16
|
apiRequest<T = unknown>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>
|
|
19
|
-
streamURL(url: string): Promise<
|
|
17
|
+
streamURL(url: string): Promise<IncomingMessage>
|
|
20
18
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2024. See LICENSE file for more information
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// import * as btoa from "btoa";
|
|
6
|
+
import {LayoutInterface} from "./layouts/layoutInterface.js";
|
|
7
|
+
|
|
8
|
+
export interface DatabaseStructure {
|
|
9
|
+
layouts: {
|
|
10
|
+
[key: string]: LayoutInterface
|
|
11
|
+
}
|
|
12
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -8,12 +8,9 @@ import { LayoutRecord } from "./records/layoutRecord.js";
|
|
|
8
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
|
-
import {
|
|
12
|
-
import { Find } from "./records/getOperations/find.js";
|
|
11
|
+
import { Container, FieldBase } from "./records/fieldBase.js";
|
|
13
12
|
import { RecordGetOperation } from "./records/getOperations/recordGetOperation.js";
|
|
14
|
-
import { RecordGetRange } from "./records/getOperations/recordGetRange.js";
|
|
15
13
|
import { LayoutRecordManager } from "./layouts/layoutRecordManager.js";
|
|
16
|
-
import { RecordFieldsMap } from "./layouts/recordFieldsMap";
|
|
17
|
-
import { Container } from "./records/field.js";
|
|
14
|
+
import { RecordFieldsMap } from "./layouts/recordFieldsMap.js";
|
|
18
15
|
export default FMHost;
|
|
19
|
-
export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, LayoutInterface, RecordFieldsMap, PortalInterface, PortalRecord, Portal,
|
|
16
|
+
export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, LayoutInterface, RecordFieldsMap, PortalInterface, PortalRecord, Portal, FieldBase, RecordGetOperation, LayoutRecordManager, Container };
|
package/src/index.js
CHANGED
|
@@ -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
|
import FMHost from "./connection/FMHost.js";
|
|
5
5
|
import { FMError } from "./FMError.js";
|
|
@@ -10,10 +10,8 @@ import { RecordBase } from "./records/recordBase.js";
|
|
|
10
10
|
import { LayoutRecord } from "./records/layoutRecord.js";
|
|
11
11
|
import { PortalRecord } from "./records/portalRecord.js";
|
|
12
12
|
import { Portal } from "./records/portal.js";
|
|
13
|
-
import {
|
|
14
|
-
import { Find } from "./records/getOperations/find.js";
|
|
13
|
+
import { FieldBase } from "./records/fieldBase.js";
|
|
15
14
|
import { RecordGetOperation } from "./records/getOperations/recordGetOperation.js";
|
|
16
|
-
import { RecordGetRange } from "./records/getOperations/recordGetRange.js";
|
|
17
15
|
import { LayoutRecordManager } from "./layouts/layoutRecordManager.js";
|
|
18
16
|
export default FMHost;
|
|
19
|
-
export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, PortalRecord, Portal,
|
|
17
|
+
export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, PortalRecord, Portal, FieldBase, RecordGetOperation, LayoutRecordManager };
|
package/src/index.ts
CHANGED
|
@@ -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
|
|
|
5
5
|
import FMHost from "./connection/FMHost.js";
|
|
@@ -12,13 +12,10 @@ import {LayoutRecord} from "./records/layoutRecord.js";
|
|
|
12
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
|
-
import {
|
|
16
|
-
import {Find} from "./records/getOperations/find.js";
|
|
15
|
+
import {Container, FieldBase} from "./records/fieldBase.js";
|
|
17
16
|
import {RecordGetOperation} from "./records/getOperations/recordGetOperation.js";
|
|
18
|
-
import {RecordGetRange} from "./records/getOperations/recordGetRange.js";
|
|
19
17
|
import {LayoutRecordManager} from "./layouts/layoutRecordManager.js";
|
|
20
|
-
import {RecordFieldsMap} from "./layouts/recordFieldsMap";
|
|
21
|
-
import {Container} from "./records/field.js";
|
|
18
|
+
import {RecordFieldsMap} from "./layouts/recordFieldsMap.js";
|
|
22
19
|
|
|
23
20
|
export default FMHost
|
|
24
21
|
export {
|
|
@@ -33,10 +30,8 @@ export {
|
|
|
33
30
|
PortalInterface,
|
|
34
31
|
PortalRecord,
|
|
35
32
|
Portal,
|
|
36
|
-
|
|
37
|
-
Find,
|
|
33
|
+
FieldBase,
|
|
38
34
|
RecordGetOperation,
|
|
39
|
-
RecordGetRange,
|
|
40
35
|
LayoutRecordManager,
|
|
41
36
|
Container
|
|
42
37
|
}
|
package/src/layouts/layout.d.ts
CHANGED
|
@@ -1,30 +1,16 @@
|
|
|
1
1
|
import { LayoutRecordManager } from "./layoutRecordManager.js";
|
|
2
|
-
import { LayoutRecord } from "../records/layoutRecord.js";
|
|
3
2
|
import { Script, ScriptResult } from "../types.js";
|
|
4
3
|
import { LayoutInterface } from "./layoutInterface.js";
|
|
5
|
-
import { Find } from "../records/getOperations/find.js";
|
|
6
4
|
import { LayoutBase } from "./layoutBase.js";
|
|
7
|
-
import { DatabaseBase } from "../connection/databaseBase";
|
|
8
|
-
import { ApiLayoutMetadata } from "../models/apiResults";
|
|
5
|
+
import { DatabaseBase } from "../connection/databaseBase.js";
|
|
6
|
+
import { ApiLayoutMetadata } from "../models/apiResults.js";
|
|
9
7
|
export declare class Layout<T extends LayoutInterface> implements LayoutBase {
|
|
10
8
|
readonly database: DatabaseBase;
|
|
11
|
-
readonly records: LayoutRecordManager<T>;
|
|
12
9
|
readonly name: string;
|
|
10
|
+
readonly records: LayoutRecordManager<T>;
|
|
13
11
|
metadata: ApiLayoutMetadata;
|
|
14
12
|
constructor(database: DatabaseBase, name: string);
|
|
15
13
|
get endpoint(): string;
|
|
16
|
-
/**
|
|
17
|
-
* @deprecated use layout.records.create() instead
|
|
18
|
-
*/
|
|
19
|
-
createRecord(): Promise<LayoutRecord<T["fields"], T["portals"]>>;
|
|
20
|
-
/**
|
|
21
|
-
* @deprecated use layout.records.get() instead
|
|
22
|
-
*/
|
|
23
|
-
getRecord(recordId: any): Promise<LayoutRecord<T["fields"], T["portals"]>>;
|
|
24
|
-
/**
|
|
25
|
-
* @deprecated use layout.records.find() instead
|
|
26
|
-
*/
|
|
27
|
-
newFind(): Find<T>;
|
|
28
14
|
runScript(script: Script): Promise<ScriptResult>;
|
|
29
15
|
getLayoutMeta(): Promise<ApiLayoutMetadata>;
|
|
30
16
|
}
|