@jd-data-limited/easy-fm 1.1.3-alpha4 → 1.1.5-alpha1

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/.idea/php.xml ADDED
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project version="4">
3
+ <component name="MessDetectorOptionsConfiguration">
4
+ <option name="transferred" value="true" />
5
+ </component>
6
+ <component name="PHPCSFixerOptionsConfiguration">
7
+ <option name="transferred" value="true" />
8
+ </component>
9
+ <component name="PHPCodeSnifferOptionsConfiguration">
10
+ <option name="transferred" value="true" />
11
+ </component>
12
+ <component name="PhpStanOptionsConfiguration">
13
+ <option name="transferred" value="true" />
14
+ </component>
15
+ <component name="PsalmOptionsConfiguration">
16
+ <option name="transferred" value="true" />
17
+ </component>
18
+ </project>
package/README.md CHANGED
@@ -1,8 +1,11 @@
1
1
  # easy-fm
2
2
 
3
+ Making NodeJS + FileMaker easier than ever
4
+
3
5
  easy-fm is a Node.js module that allows you to interact with
4
6
  a [FileMaker database](https://www.claris.com/filemaker/) stored on
5
- a [FileMaker server](https://www.claris.com/filemaker/server/). This module interacts with your server using the
7
+ a [FileMaker server](https://www.claris.com/filemaker/server/)
8
+ or [FileMaker Cloud](https://store.claris.com/filemaker-cloud). This module interacts with your server using the
6
9
  [FileMaker Data API](https://help.claris.com/en/data-api-guide/content/index.html).
7
10
 
8
11
  ## FileMaker setup instructions
@@ -17,6 +20,10 @@ a [FileMaker server](https://www.claris.com/filemaker/server/). This module inte
17
20
  ## Table of contents
18
21
 
19
22
  1. [Connecting to a database](#connecting-to-a-database)
23
+ 1. [Username and password](#username-and-password)
24
+ 2. [Token](#token)
25
+ 3. [OAuth](#oauth)
26
+ 4. [Claris Account (FileMaker Cloud)](#claris-account--filemaker-cloud-)
20
27
  2. [Working with records](#working-with-records)
21
28
  3. [Performing find requests](#perform-find-requests)
22
29
  4. [Scripts](#scripts)
@@ -31,13 +38,101 @@ FileMaker authentication.
31
38
 
32
39
  ```javascript
33
40
  import fm, {FMError} from "easy-fm"; // Import the module
34
- const connection = new fm(); // This variable will be used for interacting with the server
35
-
36
- connection.login(hostname, database, username, password).then(async token => { // Login
41
+ const connection = new fm(
42
+ // Connection options (see below)
43
+ );
37
44
 
45
+ connection.login().then(token => {
46
+ // Record operations can only be performed after a successful login
38
47
  })
39
48
  ```
40
49
 
50
+ > **NOTE:** A connection will only give you access to the layouts in the database you are connected to, and not the
51
+ > layouts
52
+ > in
53
+ > the external sources that you have specified.
54
+ >
55
+ > If you need to interact with layouts on multiple databases, you need to open one connection per database.
56
+
57
+ ## Username and password
58
+
59
+ This method allows you to use a generic FileMaker account to connect to the database.
60
+
61
+ ```javascript
62
+ new fm({
63
+ hostname: "localhost",
64
+ database: {
65
+ database: "MyDatabase", // Do not include the .fmp12 file extension
66
+ method: "filemaker",
67
+ username: "node",
68
+ password: "node123"
69
+ },
70
+ externalSources: []
71
+ })
72
+ ```
73
+
74
+ **Supports auto relogin?** Yes
75
+
76
+ ## Token
77
+
78
+ If you have already created a session with the FileMaker Data API, you can use this to import your session.
79
+
80
+ ```javascript
81
+ new fm({
82
+ hostname: "localhost",
83
+ database: {
84
+ database: "MyDatabase", // Do not include the .fmp12 file extension
85
+ method: "token",
86
+ token: "API token goes here"
87
+ },
88
+ externalSources: []
89
+ })
90
+ ```
91
+
92
+ **Supports auto relogin?** No
93
+
94
+ ## OAuth
95
+
96
+ (untested) If your FileMaker server has OAuth configured, you can login using this method.
97
+
98
+ ```javascript
99
+ new fm({
100
+ hostname: "localhost",
101
+ database: {
102
+ f
103
+ database: "MyDatabase", // Do not include the .fmp12 file extension
104
+ method: "oauth",
105
+ oauth: {
106
+ requestId: "oauth request ID",
107
+ requestIdentifier: "oatuh identifier"
108
+ }
109
+ },
110
+ externalSources: []
111
+ })
112
+ ```
113
+
114
+ **Supports auto relogin?** No
115
+
116
+ ## Claris Account (FileMaker Cloud)
117
+
118
+ (untested) If you'd prefer to use a claris account to login, you can
119
+
120
+ ```javascript
121
+ new fm({
122
+ hostname: "localhost",
123
+ database: {
124
+ database: "MyDatabase", // Do not include the .fmp12 file extension
125
+ method: "claris",
126
+ fmid: "" // The FileMaker token provided by Claris
127
+ },
128
+ externalSources: []
129
+ })
130
+ ```
131
+
132
+ Read more [here](https://help.claris.com/en/data-api-guide/content/log-in-database-session-claris-id.html)
133
+
134
+ **Supports auto relogin?** No
135
+
41
136
  ---
42
137
 
43
138
  ## Working with records
@@ -49,7 +144,10 @@ use
49
144
  let layout = connection.getLayout("layout1") // Get the layout known as 'layout1'
50
145
  ```
51
146
 
52
- Once you have the layout, you can perform a multitude of tasks
147
+ Once you have the layout, you can perform tasks on that layout
148
+
149
+ > **Note:** You will only be able to get and modify fields that are on that layout. If a field is not on the layout, you
150
+ > cannot see or modify it's contents.
53
151
 
54
152
  ### Get a single record using its RecordID
55
153
 
@@ -78,11 +176,10 @@ record.getField("field1").set("This is a value")
78
176
  record.getField("field2").set("This is also a value")
79
177
  await record.commit()
80
178
  ```
179
+ > **NOTE:** A commit will also commit any changes made to portal records.
81
180
 
82
181
  ### Create a new record
83
182
 
84
- WARNING: The record is not created on the database until a commit is done
85
-
86
183
  ```javascript
87
184
  let record = await layout.createRecord()
88
185
  record.getField("field1").set("ABC")
@@ -90,6 +187,8 @@ record.getField("field2").set("DEF")
90
187
  await record.commit()
91
188
  ```
92
189
 
190
+ > **WARNING:** The record is *not* created on the database server until a `commit()` step is done.x
191
+
93
192
  ### Downloading container field files
94
193
 
95
194
  ```javascript
@@ -112,7 +211,6 @@ container.download().then(stream => {
112
211
  When uploading files, they should be uploaded as a [Buffer](https://nodejs.org/api/buffer.html) object, along with a
113
212
  filename (string) and MIME (also string)
114
213
 
115
- MIME types are not currently automatically detected
116
214
 
117
215
  ```javascript
118
216
  const fs = require("fs")
@@ -129,7 +227,8 @@ container.upload(buffer, filename, mime).then(() => {
129
227
  console.log("UPLOAD SUCCESSFUL!")
130
228
  })
131
229
  ```
132
- [(Mozilla) Common MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types)
230
+
231
+ > Mozilla has a list of common MIME types on their website; [(Mozilla) Common MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types)
133
232
 
134
233
  ### Read and modify portal information
135
234
 
@@ -155,7 +254,7 @@ for (let _record of portal.records) {
155
254
  }
156
255
  ```
157
256
 
158
- **WARNING**: Commiting a related portal record will also commit any changes to the parent record as well as any other
257
+ > **WARNING**: Commiting a related portal record will also commit any changes to the parent record as well as any other
159
258
  portal records.
160
259
 
161
260
  ---
@@ -178,7 +277,7 @@ find.addRequests( // Specify the find criteria
178
277
  )
179
278
 
180
279
  find.addSort("CreatedBy", "ascend") // Sort the results in ascending order
181
- let records = await find.find() // Perform the find
280
+ let records = await find.run() // Perform the find
182
281
  console.log(records)
183
282
  ```
184
283
 
@@ -199,9 +298,6 @@ console.log(result)
199
298
 
200
299
  ## Classes and methods
201
300
 
202
-
203
-
204
-
205
301
  ---
206
302
 
207
303
  ## Index
package/index.js CHANGED
@@ -143,7 +143,7 @@ export default class FileMakerConnection extends EventEmitter {
143
143
  get endpoint() {
144
144
  return `https://${this.hostname}/fmi/data/v2/databases/${this.name}`;
145
145
  }
146
- apiRequest(url, options = {}) {
146
+ apiRequest(url, options = {}, autoRelogin = true) {
147
147
  return __awaiter(this, void 0, void 0, function* () {
148
148
  if (!options.headers)
149
149
  options.headers = {};
@@ -152,6 +152,12 @@ export default class FileMakerConnection extends EventEmitter {
152
152
  options.rejectUnauthorized = this.rejectUnauthroized;
153
153
  let _fetch = yield fetch(url, options);
154
154
  let data = yield _fetch.json();
155
+ console.log(data.messages[0]);
156
+ if (data.messages[0].code == 952 && autoRelogin) {
157
+ this._token = null;
158
+ yield this.login();
159
+ return yield this.apiRequest(url, options, false);
160
+ }
155
161
  return data;
156
162
  });
157
163
  }
package/index.ts CHANGED
@@ -216,7 +216,7 @@ export default class FileMakerConnection extends EventEmitter {
216
216
  return `https://${this.hostname}/fmi/data/v2/databases/${this.name}`
217
217
  }
218
218
 
219
- async apiRequest(url: string | Request, options: any = {}): Promise<any> {
219
+ async apiRequest(url: string | Request, options: any = {}, autoRelogin = true): Promise<any> {
220
220
  if (!options.headers) options.headers = {}
221
221
  options.headers["content-type"] = options.headers["content-type"] ? options.headers["content-type"] : "application/json"
222
222
  options.headers["authorization"] = "Bearer " + this._token
@@ -224,6 +224,12 @@ export default class FileMakerConnection extends EventEmitter {
224
224
 
225
225
  let _fetch = await fetch(url, options)
226
226
  let data = await _fetch.json()
227
+ console.log(data.messages[0])
228
+ if (data.messages[0].code == 952 && autoRelogin) {
229
+ this._token = null
230
+ await this.login()
231
+ return await this.apiRequest(url, options,false)
232
+ }
227
233
  return (data as any)
228
234
  }
229
235
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jd-data-limited/easy-fm",
3
- "version": "1.1.3alpha4",
3
+ "version": "1.1.5alpha1",
4
4
  "dependencies": {
5
5
  "@types/btoa": "^1.2.3",
6
6
  "@types/events": "^3.0.0",