@jd-data-limited/easy-fm 1.0.2-alpha1 → 1.0.2-alpha3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.js +49 -55
  2. package/index.ts +55 -61
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -23,12 +23,7 @@ import * as https from "https";
23
23
  // @ts-ignore
24
24
  const errs = JSON.parse(fs.readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), 'fmErrors.json')).toString());
25
25
  class database {
26
- constructor(props, host = null) {
27
- this.props = props;
28
- this.name = this.props.database;
29
- if (host)
30
- this.host = host;
31
- }
26
+ constructor() { }
32
27
  get token() {
33
28
  return this.host.token;
34
29
  }
@@ -71,42 +66,29 @@ class database {
71
66
  return { name, parameter };
72
67
  }
73
68
  get endpoint() {
74
- return `https://${this.hostname || this.host.hostname}/fmi/data/v2/databases/${encodeURI(this.name)}`;
75
- }
76
- get externalLoginInfo() {
77
- // Returns an object that can be used when using this database object as an external source
78
- let out = {
79
- database: this.name,
80
- username: undefined,
81
- password: undefined,
82
- oauthRequestId: undefined,
83
- oauthIdentifier: undefined
84
- };
85
- switch (this.props.method) {
86
- case "filemaker":
87
- out.username = this.props.username;
88
- out.password = this.props.password;
89
- case "token":
90
- throw "Token logins cannot be used for connecting to external sources. Please either use no login method, or open a second connection.";
91
- case "oauth":
92
- out.oauthRequestId = this.props.oauth.requestId;
93
- out.oauthIdentifier = this.props.oauth.requestIdentifier;
94
- case "claris":
95
- throw "Claris logins cannot be used for connecting to external sources. Please either use no login method, or open a second connection.";
69
+ return `${this.host.endpoint}/${encodeURI(this.name)}`;
70
+ }
71
+ pairHost(db, details, returnConDetails = true) {
72
+ this.host = db;
73
+ this.name = details.database;
74
+ if (returnConDetails) {
75
+ if (details.method === "filemaker") {
76
+ return {
77
+ database: this.name,
78
+ username: details.username,
79
+ password: details.password
80
+ };
81
+ }
82
+ else {
83
+ throw `Authentication method used for '${this.name}' is not supported for external data source connections`;
84
+ }
96
85
  }
97
- return out;
98
86
  }
99
87
  }
100
- export default class FileMakerConnection extends database {
101
- constructor(conn, externalDataSources = [], rejectUnauthorized = true) {
102
- super(conn.database);
103
- this.host = this;
88
+ export default class FileMakerConnection {
89
+ constructor(conn, rejectUnauthorized = true) {
104
90
  this.hostname = conn.hostname;
105
- this.externalSources = externalDataSources.map(i => {
106
- let e = new database(i, this);
107
- e.external = true;
108
- return e;
109
- });
91
+ this.databaseConDetails = conn.databases;
110
92
  this.rejectUnauthroized = rejectUnauthorized;
111
93
  }
112
94
  logout() {
@@ -122,7 +104,6 @@ export default class FileMakerConnection extends database {
122
104
  let data = yield _fetch.json();
123
105
  // console.log(data)
124
106
  this._token = null;
125
- this.name = null;
126
107
  this.hostname = null;
127
108
  resolve();
128
109
  }));
@@ -131,17 +112,25 @@ export default class FileMakerConnection extends database {
131
112
  return new Promise((resolve, reject) => {
132
113
  if (this.token)
133
114
  throw new Error("Already logged in. Run logout() first");
134
- if (this.props.method === "filemaker") {
135
- this.username = this.props.username;
136
- this.name = this.props.database;
115
+ this.databases = [new database()];
116
+ this.databases[0].pairHost(this, this.databaseConDetails[0], false);
117
+ let external_sources_cons = this.databaseConDetails.slice(1).map(con => {
118
+ let db = new database();
119
+ this.databases.push(db);
120
+ return db.pairHost(this, con);
121
+ });
122
+ if (this.databaseConDetails[0].method === "filemaker") {
137
123
  fetch(`${this.endpoint}/sessions`, {
138
124
  hostname: this.hostname,
139
125
  port: 443,
140
126
  method: "POST",
141
127
  headers: {
142
128
  "Content-Type": "application/json",
143
- "Authorization": "Basic " + Buffer.from(this.username + ":" + this.props.password).toString("base64")
144
- }
129
+ "Authorization": "Basic " + Buffer.from(this.databaseConDetails[0].username + ":" + this.databaseConDetails[0].password).toString("base64")
130
+ },
131
+ body: JSON.stringify({
132
+ fmDataSource: external_sources_cons
133
+ })
145
134
  }).then((res) => __awaiter(this, void 0, void 0, function* () {
146
135
  if (res.status === 200) {
147
136
  this._token = res.headers.get('x-fm-data-access-token');
@@ -156,21 +145,21 @@ export default class FileMakerConnection extends database {
156
145
  reject(e);
157
146
  });
158
147
  }
159
- else if (this.props.method === "token") {
160
- this._token = this.props.token;
161
- this.name = this.props.database;
148
+ else if (this.databaseConDetails[0].method === "token") {
149
+ this._token = this.databaseConDetails[0].token;
162
150
  resolve(this.token);
163
151
  }
164
- else if (this.props.method === "oauth") {
165
- this.name = this.props.database;
152
+ else if (this.databaseConDetails[0].method === "oauth") {
166
153
  fetch(`${this.endpoint}/sessions`, {
167
154
  method: "POST",
168
155
  headers: {
169
156
  "Content-Type": "application/json",
170
- "X-FM-Data-OAuth-RequestId": this.props.oauth.requestId,
171
- "X-FM-Data-OAuth-Identifier": this.props.oauth.requestIdentifier
157
+ "X-FM-Data-OAuth-RequestId": this.databaseConDetails[0].oauth.requestId,
158
+ "X-FM-Data-OAuth-Identifier": this.databaseConDetails[0].oauth.requestIdentifier
172
159
  },
173
- body: "{}"
160
+ body: external_sources_cons.length === 0 ? "{}" : JSON.stringify({
161
+ fmDataSource: external_sources_cons
162
+ })
174
163
  })
175
164
  .then(res => res.json())
176
165
  .then(res => {
@@ -179,13 +168,12 @@ export default class FileMakerConnection extends database {
179
168
  resolve(this.token);
180
169
  });
181
170
  }
182
- else if (this.props.method === "claris") {
183
- this.name = this.props.database;
171
+ else if (this.databaseConDetails[0].method === "claris") {
184
172
  fetch(`${this.endpoint}/sessions`, {
185
173
  method: "POST",
186
174
  headers: {
187
175
  "Content-Type": "application/json",
188
- "Authorization": this.props.claris.fmid,
176
+ "Authorization": this.databaseConDetails[0].claris.fmid,
189
177
  },
190
178
  body: "{}"
191
179
  })
@@ -198,9 +186,15 @@ export default class FileMakerConnection extends database {
198
186
  }
199
187
  });
200
188
  }
189
+ getDatabase(database_name) {
190
+ return this.databases.find(db => db.name === database_name);
191
+ }
201
192
  get token() {
202
193
  return this._token;
203
194
  }
195
+ get endpoint() {
196
+ return `https://${this.hostname}/fmi/data/v2/databases/`;
197
+ }
204
198
  }
205
199
  class layout {
206
200
  constructor(database, name) {
package/index.ts CHANGED
@@ -33,7 +33,7 @@ interface connectionOptions {
33
33
 
34
34
  interface hostConnectionOptions {
35
35
  hostname: string
36
- database: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris | loginOptionsToken
36
+ databases: (loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris | loginOptionsToken)[]
37
37
  }
38
38
 
39
39
  interface databaseOptions {
@@ -96,11 +96,7 @@ class database {
96
96
 
97
97
  public hostname: string;
98
98
 
99
- constructor(props: databaseOptions, host: FileMakerConnection = null) {
100
- this.props = props
101
- this.name = this.props.database
102
- if (host) this.host = host
103
- }
99
+ constructor() {}
104
100
 
105
101
  get token() {
106
102
  return this.host.token
@@ -146,51 +142,36 @@ class database {
146
142
  }
147
143
 
148
144
  get endpoint(): string {
149
- return `https://${this.hostname || this.host.hostname}/fmi/data/v2/databases/${encodeURI(this.name)}`
150
- }
151
-
152
- get externalLoginInfo() {
153
- // Returns an object that can be used when using this database object as an external source
154
- let out = {
155
- database: this.name,
156
- username: undefined,
157
- password: undefined,
158
- oauthRequestId: undefined,
159
- oauthIdentifier: undefined
160
- }
161
- switch (this.props.method) {
162
- case "filemaker":
163
- out.username = (<loginOptionsFileMaker>this.props).username
164
- out.password = (<loginOptionsFileMaker>this.props).password
165
- case "token":
166
- throw "Token logins cannot be used for connecting to external sources. Please either use no login method, or open a second connection."
167
- case "oauth":
168
- out.oauthRequestId = (<loginOptionsOAuth>this.props).oauth.requestId
169
- out.oauthIdentifier = (<loginOptionsOAuth>this.props).oauth.requestIdentifier
170
-
171
- case "claris":
172
- throw "Claris logins cannot be used for connecting to external sources. Please either use no login method, or open a second connection."
145
+ return `${this.host.endpoint}/${encodeURI(this.name)}`
146
+ }
147
+
148
+ pairHost(db: FileMakerConnection, details: databaseOptions, returnConDetails = true) {
149
+ this.host = db
150
+ this.name = details.database
151
+ if (returnConDetails) {
152
+ if (details.method === "filemaker") {
153
+ return {
154
+ database: this.name,
155
+ username: (<loginOptionsFileMaker>details).username,
156
+ password: (<loginOptionsFileMaker>details).password
157
+ }
158
+ } else {
159
+ throw `Authentication method used for '${this.name}' is not supported for external data source connections`
160
+ }
173
161
  }
174
- return out
175
162
  }
176
163
  }
177
164
 
178
- export default class FileMakerConnection extends database {
165
+ export default class FileMakerConnection {
179
166
  private _token: any;
180
- private username: any;
181
- private password: any;
167
+ private hostname: string;
182
168
  public readonly rejectUnauthroized: boolean;
183
- externalSources: database[];
169
+ private databases: database[]
170
+ private databaseConDetails: (loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris | loginOptionsToken)[];
184
171
 
185
- constructor(conn: hostConnectionOptions, externalDataSources: databaseOptions[] = [], rejectUnauthorized = true) {
186
- super(conn.database);
187
- this.host = this
172
+ constructor(conn: hostConnectionOptions, rejectUnauthorized = true) {
188
173
  this.hostname = conn.hostname
189
- this.externalSources = externalDataSources.map(i => {
190
- let e = new database(i, this);
191
- e.external = true;
192
- return e;
193
- })
174
+ this.databaseConDetails = conn.databases
194
175
  this.rejectUnauthroized = rejectUnauthorized
195
176
  }
196
177
 
@@ -207,7 +188,6 @@ export default class FileMakerConnection extends database {
207
188
  let data = await _fetch.json()
208
189
  // console.log(data)
209
190
  this._token = null
210
- this.name = null
211
191
  this.hostname = null
212
192
  resolve()
213
193
  })
@@ -216,19 +196,26 @@ export default class FileMakerConnection extends database {
216
196
  login() {
217
197
  return new Promise<string>((resolve, reject) => {
218
198
  if (this.token) throw new Error("Already logged in. Run logout() first")
199
+ this.databases = [new database()]
200
+ this.databases[0].pairHost(this, this.databaseConDetails[0], false)
201
+ let external_sources_cons = this.databaseConDetails.slice(1).map(con => {
202
+ let db = new database()
203
+ this.databases.push(db)
204
+ return db.pairHost(this, con)
205
+ })
219
206
 
220
- if (this.props.method === "filemaker") {
221
- this.username = (<loginOptionsFileMaker>this.props).username
222
- this.name = this.props.database
223
-
207
+ if (this.databaseConDetails[0].method === "filemaker") {
224
208
  fetch(`${this.endpoint}/sessions`, {
225
209
  hostname: this.hostname,
226
210
  port: 443,
227
211
  method: "POST",
228
212
  headers: {
229
213
  "Content-Type": "application/json",
230
- "Authorization": "Basic " + Buffer.from(this.username + ":" + (<loginOptionsFileMaker>this.props).password).toString("base64")
231
- }
214
+ "Authorization": "Basic " + Buffer.from((<loginOptionsFileMaker>this.databaseConDetails[0]).username + ":" + (<loginOptionsFileMaker>this.databaseConDetails[0]).password).toString("base64")
215
+ },
216
+ body: JSON.stringify({
217
+ fmDataSource: external_sources_cons
218
+ })
232
219
  }).then(async res => {
233
220
  if (res.status === 200) {
234
221
  this._token = res.headers.get('x-fm-data-access-token')
@@ -241,20 +228,20 @@ export default class FileMakerConnection extends database {
241
228
  .catch(e => {
242
229
  reject(e)
243
230
  })
244
- } else if (this.props.method === "token") {
245
- this._token = (<loginOptionsToken>this.props).token
246
- this.name = this.props.database
231
+ } else if (this.databaseConDetails[0].method === "token") {
232
+ this._token = (<loginOptionsToken>this.databaseConDetails[0]).token
247
233
  resolve(this.token)
248
- } else if (this.props.method === "oauth") {
249
- this.name = this.props.database
234
+ } else if (this.databaseConDetails[0].method === "oauth") {
250
235
  fetch(`${this.endpoint}/sessions`, {
251
236
  method: "POST",
252
237
  headers: {
253
238
  "Content-Type": "application/json",
254
- "X-FM-Data-OAuth-RequestId": (<loginOptionsOAuth>this.props).oauth.requestId,
255
- "X-FM-Data-OAuth-Identifier": (<loginOptionsOAuth>this.props).oauth.requestIdentifier
239
+ "X-FM-Data-OAuth-RequestId": (<loginOptionsOAuth>this.databaseConDetails[0]).oauth.requestId,
240
+ "X-FM-Data-OAuth-Identifier": (<loginOptionsOAuth>this.databaseConDetails[0]).oauth.requestIdentifier
256
241
  },
257
- body: "{}"
242
+ body: external_sources_cons.length === 0 ? "{}" : JSON.stringify({
243
+ fmDataSource: external_sources_cons
244
+ })
258
245
  })
259
246
  .then(res => res.json())
260
247
  .then(res => {
@@ -262,13 +249,12 @@ export default class FileMakerConnection extends database {
262
249
  this._token = _res.headers["x-fm-data-access-token"]
263
250
  resolve(this.token)
264
251
  })
265
- } else if (this.props.method === "claris") {
266
- this.name = this.props.database
252
+ } else if (this.databaseConDetails[0].method === "claris") {
267
253
  fetch(`${this.endpoint}/sessions`, {
268
254
  method: "POST",
269
255
  headers: {
270
256
  "Content-Type": "application/json",
271
- "Authorization": (<loginOptionsClaris>this.props).claris.fmid,
257
+ "Authorization": (<loginOptionsClaris>this.databaseConDetails[0]).claris.fmid,
272
258
  },
273
259
  body: "{}"
274
260
  })
@@ -282,9 +268,17 @@ export default class FileMakerConnection extends database {
282
268
  })
283
269
  }
284
270
 
271
+ getDatabase(database_name) {
272
+ return this.databases.find(db => db.name === database_name)
273
+ }
274
+
285
275
  get token() {
286
276
  return this._token
287
277
  }
278
+
279
+ get endpoint(): string {
280
+ return `https://${this.hostname}/fmi/data/v2/databases/`
281
+ }
288
282
  }
289
283
 
290
284
  class layout {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jd-data-limited/easy-fm",
3
- "version": "1.0.2alpha1",
3
+ "version": "1.0.2alpha3",
4
4
  "dependencies": {
5
5
  "@types/btoa": "^1.2.3",
6
6
  "@types/events": "^3.0.0",