@jd-data-limited/easy-fm 4.0.14 → 4.1.0
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 +12 -6
- package/src/FMError.d.ts +2 -2
- package/src/FMError.js +507 -508
- package/src/FMError.ts +510 -511
- package/src/bin/cli.js +7 -5
- package/src/bin/generateTypes.js +215 -121
- package/src/connection/FMHost.d.ts +28 -6
- package/src/connection/FMHost.js +52 -25
- package/src/connection/FMHost.ts +75 -43
- package/src/connection/HostBase.d.ts +7 -3
- package/src/connection/HostBase.ts +8 -4
- package/src/connection/database.d.ts +50 -17
- package/src/connection/database.js +94 -66
- package/src/connection/database.ts +125 -105
- package/src/connection/databaseBase.d.ts +11 -6
- package/src/connection/databaseBase.ts +9 -8
- package/src/connection/generateAuthorizationHeaders.d.ts +1 -1
- package/src/connection/generateAuthorizationHeaders.js +10 -10
- package/src/connection/generateAuthorizationHeaders.ts +21 -21
- package/src/databaseStructure.d.ts +2 -4
- package/src/databaseStructure.ts +3 -5
- package/src/index.d.ts +17 -17
- package/src/index.js +14 -14
- package/src/index.ts +28 -25
- package/src/layouts/layout.d.ts +17 -6
- package/src/layouts/layout.js +19 -8
- package/src/layouts/layout.ts +33 -23
- package/src/layouts/layoutBase.d.ts +5 -5
- package/src/layouts/layoutBase.ts +6 -6
- package/src/layouts/layoutInterface.d.ts +3 -5
- package/src/layouts/layoutInterface.ts +4 -6
- package/src/layouts/layoutRecordManager.d.ts +29 -6
- package/src/layouts/layoutRecordManager.js +32 -9
- package/src/layouts/layoutRecordManager.ts +42 -19
- package/src/layouts/recordFieldsMap.d.ts +2 -4
- package/src/layouts/recordFieldsMap.ts +2 -4
- package/src/models/apiResults.d.ts +7 -13
- package/src/models/apiResults.ts +58 -58
- package/src/records/field.d.ts +42 -12
- package/src/records/field.js +69 -59
- package/src/records/field.ts +102 -81
- package/src/records/getOperations/recordGetOperation.d.ts +44 -24
- package/src/records/getOperations/recordGetOperation.js +89 -58
- package/src/records/getOperations/recordGetOperation.ts +137 -108
- package/src/records/layoutRecord.d.ts +28 -14
- package/src/records/layoutRecord.js +75 -65
- package/src/records/layoutRecord.ts +126 -123
- package/src/records/layoutRecordBase.d.ts +2 -2
- package/src/records/layoutRecordBase.ts +3 -3
- package/src/records/portal.d.ts +19 -5
- package/src/records/portal.js +19 -5
- package/src/records/portal.ts +28 -16
- package/src/records/portalBase.d.ts +5 -5
- package/src/records/portalBase.ts +6 -6
- package/src/records/portalRecord.d.ts +16 -8
- package/src/records/portalRecord.js +16 -6
- package/src/records/portalRecord.ts +29 -19
- package/src/records/recordBase.d.ts +17 -7
- package/src/records/recordBase.js +32 -22
- package/src/records/recordBase.ts +50 -43
- package/src/types.d.ts +21 -24
- package/src/types.ts +55 -59
- package/src/utils/query.d.ts +12 -5
- package/src/utils/query.js +28 -9
- package/src/utils/query.ts +40 -15
|
@@ -2,149 +2,169 @@
|
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {EventEmitter} from
|
|
6
|
-
import {generateAuthorizationHeaders} from
|
|
7
|
-
import {FMError} from
|
|
8
|
-
import {LayoutInterface} from
|
|
9
|
-
import {Layout} from
|
|
10
|
-
import HTTP_REDIRECT from
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
import {IncomingMessage} from "http";
|
|
23
|
-
|
|
24
|
-
type GetLayoutReturnType<T extends DatabaseStructure, R extends LayoutInterface | string> = R extends string ? T["layouts"][R] : R
|
|
25
|
-
|
|
5
|
+
import {EventEmitter} from 'events'
|
|
6
|
+
import {generateAuthorizationHeaders} from './generateAuthorizationHeaders.js'
|
|
7
|
+
import {FMError} from '../FMError.js'
|
|
8
|
+
import {type LayoutInterface} from '../layouts/layoutInterface.js'
|
|
9
|
+
import {Layout} from '../layouts/layout.js'
|
|
10
|
+
import HTTP_REDIRECT from 'follow-redirects'
|
|
11
|
+
import {type databaseOptionsBase, type databaseOptionsWithExternalSources, type Script} from '../types.js'
|
|
12
|
+
import {type HostBase} from './HostBase.js'
|
|
13
|
+
import {type DatabaseBase} from './databaseBase.js'
|
|
14
|
+
import {type ApiLayout, type ApiResults} from '../models/apiResults.js'
|
|
15
|
+
import {type DatabaseStructure} from '../databaseStructure.js'
|
|
16
|
+
import {type IncomingMessage} from 'http'
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Represents a database connection.
|
|
20
|
+
* @template T - The structure of the database.
|
|
21
|
+
*/
|
|
26
22
|
export class Database<T extends DatabaseStructure> extends EventEmitter implements DatabaseBase {
|
|
27
|
-
private _token:
|
|
28
|
-
readonly host: HostBase
|
|
29
|
-
private connection_details: databaseOptionsWithExternalSources
|
|
30
|
-
private cookies:
|
|
31
|
-
readonly name: string
|
|
23
|
+
private _token: string = ''
|
|
24
|
+
readonly host: HostBase
|
|
25
|
+
private readonly connection_details: databaseOptionsWithExternalSources
|
|
26
|
+
private cookies: Record<string, string> = {}
|
|
27
|
+
readonly name: string
|
|
32
28
|
readonly debug: boolean
|
|
33
29
|
|
|
34
|
-
constructor(host: HostBase, conn: databaseOptionsWithExternalSources) {
|
|
30
|
+
constructor (host: HostBase, conn: databaseOptionsWithExternalSources) {
|
|
35
31
|
super()
|
|
36
32
|
this.host = host
|
|
37
33
|
this.name = conn.database
|
|
38
34
|
this.connection_details = conn
|
|
39
|
-
this.debug =
|
|
35
|
+
this.debug = conn.debug ?? false
|
|
40
36
|
}
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
39
|
+
private generateExternalSourceLogin (data: databaseOptionsBase) {
|
|
40
|
+
if (data.credentials.method === 'filemaker') {
|
|
41
|
+
const _data = data.credentials
|
|
45
42
|
return {
|
|
46
43
|
database: data.database,
|
|
47
44
|
username: _data.username,
|
|
48
45
|
password: _data.password
|
|
49
46
|
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
throw "Not yet supported login method"
|
|
47
|
+
} else {
|
|
48
|
+
throw new Error('Not yet supported login method')
|
|
53
49
|
}
|
|
54
50
|
}
|
|
55
51
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
52
|
+
/**
|
|
53
|
+
* Logs out the user by deleting the current session token.
|
|
54
|
+
* Throws an error if the user is not logged in.
|
|
55
|
+
*
|
|
56
|
+
* @returns {Promise<void>} A promise that resolves with no value once the logout is successful.
|
|
57
|
+
* @throws {Error} Throws an error if the user is not logged in.
|
|
58
|
+
*/
|
|
59
|
+
async logout (): Promise<void> {
|
|
60
|
+
if (this.token === '') throw new Error('Not logged in')
|
|
61
|
+
|
|
62
|
+
const _fetch = await fetch(`${this.endpoint}/sessions/${this.token}`, {
|
|
63
|
+
method: 'DELETE',
|
|
61
64
|
headers: {
|
|
62
|
-
|
|
65
|
+
'content-type': 'application/json'
|
|
63
66
|
}
|
|
64
67
|
})
|
|
65
|
-
|
|
68
|
+
await _fetch.json()
|
|
66
69
|
// console.log(data)
|
|
67
|
-
this._token =
|
|
70
|
+
this._token = ''
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
|
|
73
|
+
/**
|
|
74
|
+
* Logs in to the database. Not required, as this is often done automatically
|
|
75
|
+
*
|
|
76
|
+
* @param {boolean} [forceLogin=false] - Whether to force login even if already logged in.
|
|
77
|
+
* @throws {Error} - Throws an error if already logged in and forceLogin is false.
|
|
78
|
+
* @throws {FMError} - Throws an FMError if login fails.
|
|
79
|
+
* @return {Promise<string>} - Returns a promise that resolves to the access token upon successful login.
|
|
80
|
+
*/
|
|
81
|
+
async login (forceLogin = false) {
|
|
82
|
+
// console.trace()
|
|
71
83
|
// Reset cookies
|
|
72
84
|
this.cookies = {}
|
|
73
85
|
|
|
74
86
|
await this.host.getMetadata()
|
|
75
|
-
if (this.token && !forceLogin) throw new Error(
|
|
87
|
+
if (this.token !== '' && !forceLogin) throw new Error('Already logged in. Run logout() first')
|
|
76
88
|
|
|
77
|
-
if (this.connection_details.credentials.method ===
|
|
78
|
-
this._token = (
|
|
89
|
+
if (this.connection_details.credentials.method === 'token') {
|
|
90
|
+
this._token = (this.connection_details.credentials).token
|
|
79
91
|
return this.token
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
92
|
+
} else {
|
|
82
93
|
console.time()
|
|
83
|
-
|
|
94
|
+
const url = new URL(`${this.endpoint}/sessions`)
|
|
84
95
|
url.hostname = this.host.hostname
|
|
85
|
-
|
|
86
|
-
method:
|
|
96
|
+
const res = await fetch(url, {
|
|
97
|
+
method: 'POST',
|
|
87
98
|
headers: generateAuthorizationHeaders(this.connection_details.credentials) as unknown as HeadersInit,
|
|
88
99
|
body: JSON.stringify({
|
|
89
100
|
fmDataSource: this.connection_details.externalSources.map(i => {
|
|
90
|
-
|
|
101
|
+
const _i = i
|
|
91
102
|
return this.generateExternalSourceLogin(_i)
|
|
92
103
|
})
|
|
93
104
|
})
|
|
94
105
|
})
|
|
95
106
|
console.time()
|
|
96
|
-
|
|
107
|
+
const _res = (await res.json())
|
|
97
108
|
if (res.status === 200) {
|
|
98
|
-
this._token = res.headers.get('x-fm-data-access-token')
|
|
109
|
+
this._token = res.headers.get('x-fm-data-access-token') ?? ''
|
|
99
110
|
return this._token
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
|
|
111
|
+
} else {
|
|
112
|
+
throw new FMError(
|
|
113
|
+
_res.messages[0].code as string | number,
|
|
114
|
+
_res.status as number,
|
|
115
|
+
res
|
|
116
|
+
)
|
|
103
117
|
}
|
|
104
118
|
}
|
|
105
119
|
}
|
|
106
120
|
|
|
107
|
-
get token() {
|
|
121
|
+
get token () {
|
|
108
122
|
return this._token
|
|
109
123
|
}
|
|
110
124
|
|
|
111
|
-
|
|
125
|
+
/**
|
|
126
|
+
* Returns the endpoint URL for the database connection.
|
|
127
|
+
*
|
|
128
|
+
* @returns {string} The endpoint URL.
|
|
129
|
+
*/
|
|
130
|
+
get endpoint (): string {
|
|
112
131
|
return `${this.host.hostname}/fmi/data/v2/databases/${this.name}`
|
|
113
132
|
}
|
|
114
133
|
|
|
115
|
-
async
|
|
116
|
-
if (this.debug) console.log(`EASYFM DEBUG: ${
|
|
117
|
-
if (
|
|
134
|
+
async _apiRequestRaw (url: string | Request, options: RequestInit & { headers?: Record<string, string> } = {}, autoRelogin = true): Promise<Response> {
|
|
135
|
+
if (this.debug) console.log(`EASYFM DEBUG: ${JSON.stringify(options)} ${url instanceof Request ? url.url : url}`)
|
|
136
|
+
if (this.token === '') await this.login(true)
|
|
118
137
|
|
|
119
138
|
if (!options.headers) options.headers = {}
|
|
120
|
-
options.headers
|
|
121
|
-
options.rejectUnauthorized = this.host.verify
|
|
139
|
+
options.headers.authorization = 'Bearer ' + this._token
|
|
140
|
+
// options.rejectUnauthorized = this.host.verify
|
|
122
141
|
|
|
123
|
-
|
|
142
|
+
const _fetch = await fetch(url, options)
|
|
124
143
|
if (_fetch.headers.get('set-cookie')) {
|
|
125
|
-
for (
|
|
126
|
-
|
|
127
|
-
this.cookies[
|
|
144
|
+
for (const cookie of _fetch.headers.get('set-cookie') ?? []) {
|
|
145
|
+
const cookieSplit = cookie.split('=')
|
|
146
|
+
this.cookies[cookieSplit[0]] = cookieSplit[1]
|
|
128
147
|
}
|
|
129
148
|
}
|
|
130
149
|
|
|
131
150
|
if (_fetch.status === 401 && autoRelogin) {
|
|
132
151
|
await this.login(true)
|
|
133
|
-
return await this.
|
|
152
|
+
return await this._apiRequestRaw(url, options, false)
|
|
134
153
|
}
|
|
135
154
|
return _fetch
|
|
136
155
|
}
|
|
137
|
-
|
|
156
|
+
|
|
157
|
+
async _apiRequestJSON<T = any>(url: string | Request, options: RequestInit & { headers?: Record<string, string> } = {}): Promise<ApiResults<T>> {
|
|
138
158
|
if (!options.headers) options.headers = {}
|
|
139
|
-
options.headers[
|
|
140
|
-
|
|
141
|
-
|
|
159
|
+
options.headers['content-type'] = options.headers['content-type'] ? options.headers['content-type'] : 'application/json'
|
|
160
|
+
const _fetch = await this._apiRequestRaw(url, options)
|
|
161
|
+
const data = await _fetch.json() as ApiResults<T>
|
|
142
162
|
|
|
143
163
|
// Remove response if it is empty. This makes checking for an empty response easier
|
|
144
164
|
if (data.response && Object.keys(data.response).length === 0) delete data.response
|
|
145
165
|
|
|
146
166
|
// console.log(data.messages[0])
|
|
147
|
-
if (data.messages[0].code !==
|
|
167
|
+
if (data.messages[0].code !== '0') {
|
|
148
168
|
throw new FMError(data.messages[0].code, _fetch.status, data)
|
|
149
169
|
}
|
|
150
170
|
|
|
@@ -152,72 +172,72 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
|
|
|
152
172
|
return data
|
|
153
173
|
}
|
|
154
174
|
|
|
155
|
-
|
|
156
|
-
|
|
175
|
+
/**
|
|
176
|
+
* Retrieves a list of layouts in the current FileMaker database.
|
|
177
|
+
*
|
|
178
|
+
* @returns {Promise<Layout[]>} A promise that resolves to an array of Layout objects.
|
|
179
|
+
* @throws {FMError} If there was an error retrieving the layouts.
|
|
180
|
+
*/
|
|
181
|
+
async listLayouts () {
|
|
182
|
+
const req = await this._apiRequestJSON<{ layouts: ApiLayout[] }>(`${this.endpoint}/layouts?page=2`)
|
|
157
183
|
if (!req.response) throw new FMError(req.messages[0].code, req.httpStatus, req.messages[0].message)
|
|
158
184
|
|
|
159
185
|
const cycleLayoutNames = (layouts: ApiLayout[]) => {
|
|
160
|
-
let names: string[] =
|
|
161
|
-
for (
|
|
186
|
+
let names: string[] = []
|
|
187
|
+
for (const layout of layouts) {
|
|
162
188
|
if (layout.folderLayoutNames) names = names.concat(cycleLayoutNames(layout.folderLayoutNames))
|
|
163
189
|
else names.push(layout.name)
|
|
164
190
|
}
|
|
165
191
|
return names
|
|
166
192
|
}
|
|
167
|
-
let layoutNames
|
|
168
|
-
|
|
169
193
|
return cycleLayoutNames(req.response.layouts).map(layout => new Layout(this, layout))
|
|
170
194
|
}
|
|
171
195
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
196
|
+
layout<R extends keyof T['layouts']>(name: R): Layout<T['layouts'][R]>
|
|
197
|
+
layout<R extends LayoutInterface>(name: string): Layout<R>
|
|
198
|
+
layout (name: string): Layout<any> {
|
|
175
199
|
return new Layout<LayoutInterface>(this, name)
|
|
176
200
|
}
|
|
177
201
|
|
|
178
|
-
script(name: string, parameter =
|
|
179
|
-
return ({name, parameter}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
_tokenExpired() {
|
|
183
|
-
this.emit("token_expired")
|
|
202
|
+
script (name: string, parameter = ''): Script {
|
|
203
|
+
return ({ name, parameter } satisfies Script)
|
|
184
204
|
}
|
|
185
205
|
|
|
186
|
-
streamURL(url: string): Promise<IncomingMessage> {
|
|
187
|
-
return new Promise((resolve, reject) => {
|
|
188
|
-
if (!url || typeof url !==
|
|
189
|
-
throw new Error(
|
|
206
|
+
async streamURL (url: string): Promise<IncomingMessage> {
|
|
207
|
+
return await new Promise((resolve, reject) => {
|
|
208
|
+
if (!url || typeof url !== 'string') {
|
|
209
|
+
throw new Error('URL is empty, or has invalid value')
|
|
190
210
|
}
|
|
191
211
|
|
|
192
|
-
|
|
212
|
+
const headers: Record<string, string> = {}
|
|
193
213
|
if (Object.keys(this.cookies).length !== 0) {
|
|
194
|
-
headers
|
|
214
|
+
headers.Cookie = Object.keys(this.cookies)
|
|
195
215
|
.map(key => {
|
|
196
|
-
return key +
|
|
216
|
+
return key + '=' + this.cookies[key]
|
|
197
217
|
})
|
|
198
|
-
.join(
|
|
218
|
+
.join('; ')
|
|
199
219
|
}
|
|
200
220
|
|
|
201
|
-
const
|
|
221
|
+
const checkForCookies = (res: HTTP_REDIRECT.ResponseDetails) => {
|
|
202
222
|
// Check for the 'set-cookie' header. If it exists, remember it and strip it for better security.
|
|
203
223
|
if (res.headers['set-cookie']) {
|
|
204
|
-
for (
|
|
205
|
-
|
|
206
|
-
this.cookies[
|
|
224
|
+
for (const cookie of res.headers['set-cookie']) {
|
|
225
|
+
const cookieSplit = cookie.split('=')
|
|
226
|
+
this.cookies[cookieSplit[0]] = cookieSplit[1]
|
|
207
227
|
}
|
|
208
228
|
res.headers['set-cookie'] = undefined
|
|
209
229
|
}
|
|
210
230
|
}
|
|
211
231
|
|
|
212
232
|
// Automatically switch between the http and https modules, based on which is needed
|
|
213
|
-
(url.startsWith(
|
|
233
|
+
(url.startsWith('https') ? HTTP_REDIRECT.https : HTTP_REDIRECT.http).get(url, {
|
|
214
234
|
headers,
|
|
215
|
-
beforeRedirect: (options: any, res:
|
|
235
|
+
beforeRedirect: (options: any, res: HTTP_REDIRECT.ResponseDetails) => { checkForCookies(res) }
|
|
216
236
|
}, (res) => {
|
|
217
|
-
|
|
237
|
+
checkForCookies(res)
|
|
218
238
|
|
|
219
239
|
resolve(res)
|
|
220
240
|
})
|
|
221
241
|
})
|
|
222
242
|
}
|
|
223
|
-
}
|
|
243
|
+
}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
-
import { HostBase } from
|
|
3
|
-
import { ApiResults } from
|
|
4
|
-
import { IncomingMessage } from
|
|
2
|
+
import { type HostBase } from './HostBase.js';
|
|
3
|
+
import { type ApiResults } from '../models/apiResults.js';
|
|
4
|
+
import { type IncomingMessage } from 'http';
|
|
5
5
|
export interface DatabaseBase {
|
|
6
6
|
host: HostBase;
|
|
7
7
|
readonly name: string;
|
|
8
8
|
endpoint: string;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
token: string;
|
|
10
|
+
_apiRequestJSON: <T = unknown>(url: string | Request, options?: RequestInit & {
|
|
11
|
+
headers?: Record<string, string>;
|
|
12
|
+
} | undefined, autoRelogin?: boolean) => Promise<ApiResults<T>>;
|
|
13
|
+
_apiRequestRaw: (url: string | Request, options?: RequestInit & {
|
|
14
|
+
headers?: Record<string, string>;
|
|
15
|
+
} | undefined) => Promise<Response>;
|
|
16
|
+
streamURL: (url: string) => Promise<IncomingMessage>;
|
|
12
17
|
}
|
|
@@ -2,18 +2,19 @@
|
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {HostBase} from
|
|
6
|
-
import {ApiResults} from
|
|
7
|
-
import {IncomingMessage} from
|
|
5
|
+
import {type HostBase} from './HostBase.js'
|
|
6
|
+
import {type ApiResults} from '../models/apiResults.js'
|
|
7
|
+
import {type IncomingMessage} from 'http'
|
|
8
8
|
|
|
9
9
|
export interface DatabaseBase {
|
|
10
|
-
host: HostBase
|
|
10
|
+
host: HostBase
|
|
11
11
|
readonly name: string
|
|
12
12
|
endpoint: string
|
|
13
|
+
token: string
|
|
13
14
|
|
|
14
15
|
// layouts: DatabaseStructure["layouts"]
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
streamURL(url: string)
|
|
19
|
-
}
|
|
17
|
+
_apiRequestJSON: <T = unknown>(url: string | Request, options?: RequestInit & { headers?: Record<string, string> } | undefined, autoRelogin?: boolean) => Promise<ApiResults<T>>
|
|
18
|
+
_apiRequestRaw: (url: string | Request, options?: RequestInit & { headers?: Record<string, string> } | undefined) => Promise<Response>
|
|
19
|
+
streamURL: (url: string) => Promise<IncomingMessage>
|
|
20
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { AuthorizationHeaders, AuthorizationHeadersOAuth, loginOptionsClaris, loginOptionsFileMaker, loginOptionsOAuth } from
|
|
1
|
+
import { type AuthorizationHeaders, type AuthorizationHeadersOAuth, type loginOptionsClaris, type loginOptionsFileMaker, type loginOptionsOAuth } from '../types.js';
|
|
2
2
|
export declare function generateAuthorizationHeaders(credentials: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris): AuthorizationHeaders | AuthorizationHeadersOAuth;
|
|
@@ -3,21 +3,21 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export function generateAuthorizationHeaders(credentials) {
|
|
5
5
|
switch (credentials.method) {
|
|
6
|
-
case
|
|
6
|
+
case 'filemaker':
|
|
7
7
|
return {
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
'Content-Type': 'application/json',
|
|
9
|
+
Authorization: 'Basic ' + Buffer.from((credentials).username + ':' + (credentials).password).toString('base64')
|
|
10
10
|
};
|
|
11
|
-
case
|
|
11
|
+
case 'claris':
|
|
12
12
|
return {
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
Authorization: (credentials).claris.fmid
|
|
15
15
|
};
|
|
16
|
-
case
|
|
16
|
+
case 'oauth':
|
|
17
17
|
return {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
'X-FM-Data-OAuth-RequestId': (credentials).oauth.requestId,
|
|
20
|
+
'X-FM-Data-OAuth-Identifier': (credentials).oauth.requestIdentifier
|
|
21
21
|
};
|
|
22
22
|
}
|
|
23
23
|
}
|
|
@@ -3,30 +3,30 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
|
-
AuthorizationHeaders,
|
|
7
|
-
AuthorizationHeadersOAuth,
|
|
8
|
-
loginOptionsClaris,
|
|
9
|
-
loginOptionsFileMaker,
|
|
10
|
-
loginOptionsOAuth
|
|
11
|
-
} from
|
|
6
|
+
type AuthorizationHeaders,
|
|
7
|
+
type AuthorizationHeadersOAuth,
|
|
8
|
+
type loginOptionsClaris,
|
|
9
|
+
type loginOptionsFileMaker,
|
|
10
|
+
type loginOptionsOAuth
|
|
11
|
+
} from '../types.js'
|
|
12
12
|
|
|
13
|
-
export function generateAuthorizationHeaders(credentials: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris): AuthorizationHeaders | AuthorizationHeadersOAuth {
|
|
13
|
+
export function generateAuthorizationHeaders (credentials: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris): AuthorizationHeaders | AuthorizationHeadersOAuth {
|
|
14
14
|
switch (credentials.method) {
|
|
15
|
-
case
|
|
15
|
+
case 'filemaker':
|
|
16
16
|
return {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
case
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
Authorization: 'Basic ' + Buffer.from((credentials).username + ':' + (credentials).password).toString('base64')
|
|
19
|
+
} satisfies AuthorizationHeaders
|
|
20
|
+
case 'claris':
|
|
21
21
|
return {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
case
|
|
22
|
+
'Content-Type': 'application/json',
|
|
23
|
+
Authorization: (credentials).claris.fmid
|
|
24
|
+
} satisfies AuthorizationHeaders
|
|
25
|
+
case 'oauth':
|
|
26
26
|
return {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
27
|
+
'Content-Type': 'application/json',
|
|
28
|
+
'X-FM-Data-OAuth-RequestId': (credentials).oauth.requestId,
|
|
29
|
+
'X-FM-Data-OAuth-Identifier': (credentials).oauth.requestIdentifier
|
|
30
|
+
} satisfies AuthorizationHeadersOAuth
|
|
31
31
|
}
|
|
32
|
-
}
|
|
32
|
+
}
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import { LayoutInterface } from
|
|
1
|
+
import { type LayoutInterface } from './layouts/layoutInterface.js';
|
|
2
2
|
export interface DatabaseStructure {
|
|
3
|
-
layouts:
|
|
4
|
-
[key: string]: LayoutInterface;
|
|
5
|
-
};
|
|
3
|
+
layouts: Record<string, LayoutInterface>;
|
|
6
4
|
}
|
package/src/databaseStructure.ts
CHANGED
|
@@ -3,10 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
// import * as btoa from "btoa";
|
|
6
|
-
import {LayoutInterface} from
|
|
6
|
+
import {type LayoutInterface} from './layouts/layoutInterface.js'
|
|
7
7
|
|
|
8
8
|
export interface DatabaseStructure {
|
|
9
|
-
layouts:
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
}
|
|
9
|
+
layouts: Record<string, LayoutInterface>
|
|
10
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import FMHost from
|
|
2
|
-
import { FMError } from
|
|
3
|
-
import * as TYPES from
|
|
4
|
-
import { PickPortals } from
|
|
5
|
-
import { Database } from
|
|
6
|
-
import { Layout } from
|
|
7
|
-
import { RecordBase } from
|
|
8
|
-
import { LayoutRecord } from
|
|
9
|
-
import { LayoutInterface, PortalInterface } from
|
|
10
|
-
import { PortalRecord } from
|
|
11
|
-
import { Portal } from
|
|
12
|
-
import { FindRequest, FindRequestRaw, RecordGetOperation } from
|
|
13
|
-
import { LayoutRecordManager } from
|
|
14
|
-
import { RecordFieldsMap } from
|
|
15
|
-
import { query, queryEscape } from
|
|
16
|
-
import { Container, Field } from
|
|
1
|
+
import FMHost from './connection/FMHost.js';
|
|
2
|
+
import { FMError } from './FMError.js';
|
|
3
|
+
import * as TYPES from './types.js';
|
|
4
|
+
import { type PickPortals } from './types.js';
|
|
5
|
+
import { Database } from './connection/database.js';
|
|
6
|
+
import { Layout } from './layouts/layout.js';
|
|
7
|
+
import { RecordBase } from './records/recordBase.js';
|
|
8
|
+
import { LayoutRecord } from './records/layoutRecord.js';
|
|
9
|
+
import { type LayoutInterface, type PortalInterface } from './layouts/layoutInterface.js';
|
|
10
|
+
import { PortalRecord } from './records/portalRecord.js';
|
|
11
|
+
import { Portal } from './records/portal.js';
|
|
12
|
+
import { type FindRequest, type FindRequestRaw, RecordGetOperation } from './records/getOperations/recordGetOperation.js';
|
|
13
|
+
import { LayoutRecordManager } from './layouts/layoutRecordManager.js';
|
|
14
|
+
import { type RecordFieldsMap } from './layouts/recordFieldsMap.js';
|
|
15
|
+
import { asDate, asTime, asTimestamp, query, queryEscape } from './utils/query.js';
|
|
16
|
+
import { type Container, Field } from './records/field.js';
|
|
17
17
|
export default FMHost;
|
|
18
|
-
export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, LayoutInterface, RecordFieldsMap, PortalInterface, PortalRecord, Portal, Field, RecordGetOperation, LayoutRecordManager, Container, PickPortals, FindRequestRaw, FindRequest, query, queryEscape };
|
|
18
|
+
export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, type LayoutInterface, type RecordFieldsMap, type PortalInterface, PortalRecord, Portal, Field, RecordGetOperation, LayoutRecordManager, type Container, type PickPortals, type FindRequestRaw, type FindRequest, query, queryEscape, asDate, asTime, asTimestamp };
|
package/src/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
|
-
import FMHost from
|
|
5
|
-
import { FMError } from
|
|
6
|
-
import * as TYPES from
|
|
7
|
-
import { Database } from
|
|
8
|
-
import { Layout } from
|
|
9
|
-
import { RecordBase } from
|
|
10
|
-
import { LayoutRecord } from
|
|
11
|
-
import { PortalRecord } from
|
|
12
|
-
import { Portal } from
|
|
13
|
-
import { RecordGetOperation } from
|
|
14
|
-
import { LayoutRecordManager } from
|
|
15
|
-
import { query, queryEscape } from
|
|
16
|
-
import { Field } from
|
|
4
|
+
import FMHost from './connection/FMHost.js';
|
|
5
|
+
import { FMError } from './FMError.js';
|
|
6
|
+
import * as TYPES from './types.js';
|
|
7
|
+
import { Database } from './connection/database.js';
|
|
8
|
+
import { Layout } from './layouts/layout.js';
|
|
9
|
+
import { RecordBase } from './records/recordBase.js';
|
|
10
|
+
import { LayoutRecord } from './records/layoutRecord.js';
|
|
11
|
+
import { PortalRecord } from './records/portalRecord.js';
|
|
12
|
+
import { Portal } from './records/portal.js';
|
|
13
|
+
import { RecordGetOperation } from './records/getOperations/recordGetOperation.js';
|
|
14
|
+
import { LayoutRecordManager } from './layouts/layoutRecordManager.js';
|
|
15
|
+
import { asDate, asTime, asTimestamp, query, queryEscape } from './utils/query.js';
|
|
16
|
+
import { Field } from './records/field.js';
|
|
17
17
|
export default FMHost;
|
|
18
|
-
export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, PortalRecord, Portal, Field, RecordGetOperation, LayoutRecordManager, query, queryEscape };
|
|
18
|
+
export { FMError, TYPES, Database, Layout, RecordBase, LayoutRecord, PortalRecord, Portal, Field, RecordGetOperation, LayoutRecordManager, query, queryEscape, asDate, asTime, asTimestamp };
|