@jd-data-limited/easy-fm 3.2.7 → 3.2.9

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 (58) hide show
  1. package/package.json +11 -7
  2. package/src/FMError.d.ts +1 -1
  3. package/src/FMError.ts +1 -1
  4. package/src/connection/FMHost.d.ts +1 -1
  5. package/src/connection/FMHost.ts +3 -3
  6. package/src/connection/database.d.ts +5 -3
  7. package/src/connection/database.js +42 -49
  8. package/src/connection/database.ts +70 -82
  9. package/src/connection/databaseBase.d.ts +4 -1
  10. package/src/connection/databaseBase.ts +4 -1
  11. package/src/layouts/layout.d.ts +3 -3
  12. package/src/layouts/layout.js +15 -29
  13. package/src/layouts/layout.ts +22 -39
  14. package/src/layouts/layoutBase.d.ts +2 -2
  15. package/src/layouts/layoutBase.ts +2 -1
  16. package/src/layouts/layoutRecordManager.d.ts +1 -1
  17. package/src/layouts/layoutRecordManager.js +24 -27
  18. package/src/layouts/layoutRecordManager.ts +14 -30
  19. package/src/models/apiResults.d.ts +103 -0
  20. package/src/models/apiResults.js +28 -0
  21. package/src/models/apiResults.ts +112 -0
  22. package/src/records/field.d.ts +3 -2
  23. package/src/records/field.js +28 -43
  24. package/src/records/field.ts +46 -64
  25. package/src/records/getOperations/find.js +18 -28
  26. package/src/records/getOperations/find.ts +17 -28
  27. package/src/records/getOperations/recordGetRange.js +15 -22
  28. package/src/records/getOperations/recordGetRange.ts +17 -24
  29. package/src/records/layoutRecord.js +73 -102
  30. package/src/records/layoutRecord.ts +101 -133
  31. package/src/types.d.ts +0 -4
  32. package/src/types.ts +0 -5
  33. package/.expo/README.md +0 -15
  34. package/.expo/settings.json +0 -8
  35. package/.idea/compiler.xml +0 -7
  36. package/.idea/copyright/JD_Data.xml +0 -6
  37. package/.idea/copyright/profiles_settings.xml +0 -7
  38. package/.idea/discord.xml +0 -7
  39. package/.idea/easy-fm.iml +0 -8
  40. package/.idea/jsLibraryMappings.xml +0 -6
  41. package/.idea/modules.xml +0 -8
  42. package/.idea/php.xml +0 -18
  43. package/.idea/vcs.xml +0 -6
  44. package/decs.d.ts +0 -7
  45. package/dist/index.min.js +0 -2
  46. package/dist/index.min.js.LICENSE.txt +0 -3
  47. package/docs/classes/FileMakerConnection.md +0 -86
  48. package/docs/classes/layout.md +0 -0
  49. package/examples/test.js +0 -7
  50. package/fmErrors.json +0 -1010
  51. package/img.png +0 -0
  52. package/test.d.ts +0 -2
  53. package/test.js +0 -30
  54. package/test.ts +0 -33
  55. package/test2.d.ts +0 -1
  56. package/test2.js +0 -15
  57. package/tsconfig.json +0 -16
  58. package/webpack.config.cjs +0 -20
package/package.json CHANGED
@@ -1,13 +1,10 @@
1
1
  {
2
2
  "name": "@jd-data-limited/easy-fm",
3
- "version": "3.2.7",
3
+ "version": "3.2.9",
4
4
  "dependencies": {
5
- "@types/btoa": "^1.2.3",
6
- "@types/events": "^3.0.0",
5
+ "follow-redirects": "^1.15.5",
7
6
  "moment": "^2.29.4",
8
- "node-fetch": "3.2.8",
9
- "typescript": "^5.2.2",
10
- "ytdl-core": "^4.11.4"
7
+ "node-fetch": "3.3.2"
11
8
  },
12
9
  "type": "module",
13
10
  "main": "src/index.js",
@@ -16,8 +13,11 @@
16
13
  "url": "https://github.com/JD-Data-Limited/easy-fm",
17
14
  "license": "SEE LICENSE IN LICENSE",
18
15
  "description": "easy-fm is a Node.js module that allows you to interact with\r a [FileMaker database stored](https://www.claris.com/filemaker/) on\r a [FileMaker server](https://www.claris.com/filemaker/server/). This module interacts with your server using the\r [FileMaker Data API](https://help.claris.com/en/data-api-guide/content/index.html).",
16
+ "files": [
17
+ "./src/**/*"
18
+ ],
19
19
  "scripts": {
20
- "test": "echo \"Error: no test specified\" && exit 1",
20
+ "test": "node --test tests/login.js",
21
21
  "build": "webpack"
22
22
  },
23
23
  "repository": {
@@ -34,6 +34,10 @@
34
34
  "url": "https://github.com/JD-Data-Limited/easy-fm/issues"
35
35
  },
36
36
  "devDependencies": {
37
+ "@types/btoa": "^1.2.3",
38
+ "@types/events": "^3.0.0",
39
+ "dotenv": "^16.3.1",
40
+ "typescript": "^5.2.2",
37
41
  "webpack": "^5.81.0",
38
42
  "webpack-cli": "^5.0.2"
39
43
  }
package/src/FMError.d.ts CHANGED
@@ -8,5 +8,5 @@ export declare class FMError extends Error {
8
8
  readonly code: number;
9
9
  readonly message: string;
10
10
  readonly messages: string;
11
- constructor(code: any, httpStatus: any, res: any, trace?: Error);
11
+ constructor(code: string | number, httpStatus: number, res: any, trace?: Error);
12
12
  }
package/src/FMError.ts CHANGED
@@ -1021,7 +1021,7 @@ export class FMError extends Error {
1021
1021
  readonly message: string
1022
1022
  readonly messages: string
1023
1023
 
1024
- constructor(code, httpStatus, res, trace?: Error) {
1024
+ constructor(code: string | number, httpStatus: number, res: any, trace?: Error) {
1025
1025
  if (typeof code === "string") code = parseInt(code)
1026
1026
  super(errs.find(err => err.e === code).d || "Unknown error");
1027
1027
  this.httpStatus = httpStatus
@@ -9,5 +9,5 @@ export default class FMHost implements HostBase {
9
9
  constructor(_hostname: string, timezoneOffset?: number, verify?: boolean);
10
10
  listDatabases(credentials?: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris): Promise<any>;
11
11
  database<T extends DatabaseStructure>(data: databaseOptionsWithExternalSources): Database<T>;
12
- getMetadata(): Promise<any>;
12
+ getMetadata(): Promise<FMHostMetadata>;
13
13
  }
@@ -9,12 +9,12 @@ import {Database} from "./database.js";
9
9
  import {HostBase} from "./HostBase.js"
10
10
  import {
11
11
  databaseOptionsWithExternalSources, DatabaseStructure,
12
- fileMakerResponse,
13
12
  FMHostMetadata,
14
13
  loginOptionsClaris,
15
14
  loginOptionsFileMaker,
16
15
  loginOptionsOAuth
17
16
  } from "../types.js";
17
+ import {ApiResults} from "../models/apiResults";
18
18
 
19
19
  export default class FMHost implements HostBase {
20
20
  readonly hostname: string
@@ -39,7 +39,7 @@ export default class FMHost implements HostBase {
39
39
  method: "GET",
40
40
  headers
41
41
  })
42
- let data = await _fetch.json() as fileMakerResponse
42
+ let data = await _fetch.json() as ApiResults<{databases: any}>
43
43
  // console.log(data.messages[0])
44
44
 
45
45
  if (data.messages[0].code === "0") {
@@ -61,7 +61,7 @@ export default class FMHost implements HostBase {
61
61
  let _fetch = await fetch(`${this.hostname}/fmi/data/v2/productInfo`, {
62
62
  method: "GET",
63
63
  })
64
- let data = await _fetch.json() as fileMakerResponse
64
+ let data = await _fetch.json() as ApiResults<FMHostMetadata>
65
65
  // console.log(data.messages[0])
66
66
 
67
67
  if (data.messages[0].code === "0") {
@@ -7,6 +7,7 @@ import HTTP_REDIRECT from "follow-redirects";
7
7
  import { databaseOptionsWithExternalSources, DatabaseStructure, Script } from "../types.js";
8
8
  import { HostBase } from "./HostBase.js";
9
9
  import { DatabaseBase } from "./databaseBase";
10
+ import { ApiResults } from "../models/apiResults";
10
11
  export declare class Database<T extends DatabaseStructure> extends EventEmitter implements DatabaseBase {
11
12
  private _token;
12
13
  readonly host: HostBase;
@@ -16,14 +17,15 @@ export declare class Database<T extends DatabaseStructure> extends EventEmitter
16
17
  constructor(host: HostBase, conn: databaseOptionsWithExternalSources);
17
18
  private generateExternalSourceLogin;
18
19
  logout(): Promise<void>;
19
- login(): Promise<string>;
20
+ login(): Promise<any>;
20
21
  get token(): any;
21
22
  get endpoint(): string;
22
- apiRequest<T = any>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<T>;
23
+ apiRequest<T = any>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>;
24
+ listLayouts(): Promise<Layout<LayoutInterface>[]>;
23
25
  getLayout<R extends string>(name: R): Layout<T["layouts"][R]>;
24
26
  getLayout<R extends LayoutInterface>(name: string): Layout<R>;
25
27
  setGlobals(globalFields: any): Promise<void>;
26
28
  script(name: any, parameter?: string): Script;
27
29
  _tokenExpired(): void;
28
- streamContainer(field: any, url: any): Promise<HTTP_REDIRECT.http.IncomingMessage>;
30
+ streamURL(url: string): Promise<HTTP_REDIRECT.http.IncomingMessage>;
29
31
  }
@@ -38,9 +38,9 @@ export class Database extends EventEmitter {
38
38
  }
39
39
  }
40
40
  logout() {
41
- return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
41
+ return __awaiter(this, void 0, void 0, function* () {
42
42
  if (!this.token)
43
- reject(new Error("Not logged in"));
43
+ throw new Error("Not logged in");
44
44
  let _fetch = yield fetch(`${this.endpoint}/sessions/${this.token}`, {
45
45
  method: "DELETE",
46
46
  headers: {
@@ -50,28 +50,22 @@ export class Database extends EventEmitter {
50
50
  let data = yield _fetch.json();
51
51
  // console.log(data)
52
52
  this._token = null;
53
- resolve();
54
- }));
53
+ });
55
54
  }
56
55
  login() {
57
- return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
56
+ return __awaiter(this, void 0, void 0, function* () {
58
57
  // Reset cookies
59
58
  this.cookies = {};
60
- try {
61
- yield this.host.getMetadata();
62
- }
63
- catch (e) {
64
- reject(e);
65
- return;
66
- }
59
+ yield this.host.getMetadata();
67
60
  if (this.token)
68
61
  throw new Error("Already logged in. Run logout() first");
69
62
  if (this.connection_details.credentials.method === "token") {
70
63
  this._token = this.connection_details.credentials.token;
71
- resolve(this.token);
64
+ return this.token;
72
65
  }
73
66
  else {
74
- fetch(`${this.endpoint}/sessions`, {
67
+ console.time();
68
+ let res = yield fetch(`${this.endpoint}/sessions`, {
75
69
  hostname: this.host.hostname,
76
70
  port: 443,
77
71
  method: "POST",
@@ -82,21 +76,18 @@ export class Database extends EventEmitter {
82
76
  return this.generateExternalSourceLogin(_i);
83
77
  })
84
78
  })
85
- }).then((res) => __awaiter(this, void 0, void 0, function* () {
86
- let _res = (yield res.json());
87
- if (res.status === 200) {
88
- this._token = res.headers.get('x-fm-data-access-token');
89
- resolve(this._token);
90
- }
91
- else {
92
- reject(new FMError(_res.messages[0].code, _res.status, res));
93
- }
94
- }))
95
- .catch(e => {
96
- reject(e);
97
79
  });
80
+ console.time();
81
+ let _res = (yield res.json());
82
+ if (res.status === 200) {
83
+ this._token = res.headers.get('x-fm-data-access-token');
84
+ return this._token;
85
+ }
86
+ else {
87
+ throw new FMError(_res.messages[0].code, _res.status, res);
88
+ }
98
89
  }
99
- }));
90
+ });
100
91
  }
101
92
  get token() {
102
93
  return this._token;
@@ -119,35 +110,42 @@ export class Database extends EventEmitter {
119
110
  }
120
111
  }
121
112
  let data = yield _fetch.json();
113
+ // Remove response if it is empty. This makes checking for an empty response easier
114
+ if (Object.keys(data.response).length === 0)
115
+ delete data.response;
122
116
  // console.log(data.messages[0])
123
- if (data.messages[0].code == 952 && autoRelogin) {
117
+ if (data.messages[0].code === "952" && autoRelogin) {
124
118
  this._token = null;
125
119
  yield this.login();
126
120
  return yield this.apiRequest(url, options, false);
127
121
  }
122
+ else if (data.messages[0].code !== "0") {
123
+ throw new FMError(data.messages[0].code, _fetch.status, data);
124
+ }
125
+ data.httpStatus = _fetch.status;
128
126
  return data;
129
127
  });
130
128
  }
129
+ listLayouts() {
130
+ return __awaiter(this, void 0, void 0, function* () {
131
+ let req = yield this.apiRequest(`${this.endpoint}/layouts`);
132
+ if (!req.response)
133
+ throw new FMError(req.messages[0].code, req.httpStatus, req.messages[0].message);
134
+ return req.response.layouts.filter(i => !i.isFolder).map(layout => new Layout(this, layout.name));
135
+ });
136
+ }
131
137
  getLayout(name) {
132
138
  return new Layout(this, name);
133
139
  }
140
+ /*
141
+ @deprecated
142
+ */
134
143
  setGlobals(globalFields) {
135
- // console.log({globalFields})
136
- return new Promise((resolve, reject) => {
137
- this.apiRequest(`${this.endpoint}/globals`, {
144
+ return __awaiter(this, void 0, void 0, function* () {
145
+ // console.log({globalFields})
146
+ yield this.apiRequest(`${this.endpoint}/globals`, {
138
147
  method: "PATCH",
139
148
  body: JSON.stringify({ globalFields })
140
- }).then(res => {
141
- // console.log(res)
142
- if (res.messages[0].code === "0") {
143
- resolve();
144
- }
145
- else {
146
- reject((res.messages[0].code, res.status, res));
147
- }
148
- })
149
- .catch(e => {
150
- reject(e);
151
149
  });
152
150
  });
153
151
  }
@@ -157,15 +155,10 @@ export class Database extends EventEmitter {
157
155
  _tokenExpired() {
158
156
  this.emit("token_expired");
159
157
  }
160
- streamContainer(field, url) {
158
+ streamURL(url) {
161
159
  return new Promise((resolve, reject) => {
162
- if (field.metadata.result !== "container") {
163
- reject("Cannot stream the field " + field.id + " as it is not a container");
164
- return;
165
- }
166
160
  if (!url || typeof url !== "string") {
167
- reject("Container is empty, or has invalid value");
168
- return;
161
+ throw new Error("URL is empty, or has invalid value");
169
162
  }
170
163
  let headers = {};
171
164
  if (Object.keys(this.cookies).length !== 0) {
@@ -12,13 +12,13 @@ import HTTP_REDIRECT from "follow-redirects"
12
12
  import {
13
13
  databaseOptionsBase,
14
14
  databaseOptionsWithExternalSources, DatabaseStructure,
15
- fileMakerResponse,
16
15
  loginOptionsFileMaker,
17
16
  loginOptionsToken,
18
17
  Script
19
18
  } from "../types.js";
20
19
  import {HostBase} from "./HostBase.js"
21
20
  import {DatabaseBase} from "./databaseBase";
21
+ import {ApiLayout, ApiResults} from "../models/apiResults";
22
22
 
23
23
  type GetLayoutReturnType<T extends DatabaseStructure, R extends LayoutInterface | string> = R extends string ? T["layouts"][R] : R
24
24
 
@@ -50,67 +50,55 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
50
50
  }
51
51
  }
52
52
 
53
- logout(): Promise<void> {
54
- return new Promise(async (resolve, reject) => {
55
- if (!this.token) reject(new Error("Not logged in"))
53
+ async logout(): Promise<void> {
54
+ if (!this.token) throw new Error("Not logged in")
56
55
 
57
- let _fetch = await fetch(`${this.endpoint}/sessions/${this.token}`, {
58
- method: "DELETE",
59
- headers: {
60
- "content-type": "application/json"
61
- }
62
- })
63
- let data = await _fetch.json()
64
- // console.log(data)
65
- this._token = null
66
- resolve()
56
+ let _fetch = await fetch(`${this.endpoint}/sessions/${this.token}`, {
57
+ method: "DELETE",
58
+ headers: {
59
+ "content-type": "application/json"
60
+ }
67
61
  })
62
+ let data = await _fetch.json()
63
+ // console.log(data)
64
+ this._token = null
68
65
  }
69
66
 
70
- login() {
71
- return new Promise<string>(async (resolve, reject) => {
72
- // Reset cookies
73
- this.cookies = {}
67
+ async login() {
68
+ // Reset cookies
69
+ this.cookies = {}
74
70
 
75
- try {
76
- await this.host.getMetadata()
77
- } catch (e) {
78
- reject(e)
79
- return
80
- }
81
- if (this.token) throw new Error("Already logged in. Run logout() first")
71
+ await this.host.getMetadata()
72
+ if (this.token) throw new Error("Already logged in. Run logout() first")
82
73
 
83
- if (this.connection_details.credentials.method === "token") {
84
- this._token = (<loginOptionsToken>this.connection_details.credentials).token
85
- resolve(this.token)
86
- }
87
- else {
88
- fetch(`${this.endpoint}/sessions`, {
89
- hostname: this.host.hostname,
90
- port: 443,
91
- method: "POST",
92
- headers: generateAuthorizationHeaders(this.connection_details.credentials) as unknown as HeadersInit,
93
- body: JSON.stringify({
94
- fmDataSource: this.connection_details.externalSources.map(i => {
95
- let _i = <databaseOptionsBase>i
96
- return this.generateExternalSourceLogin(_i)
97
- })
74
+ if (this.connection_details.credentials.method === "token") {
75
+ this._token = (<loginOptionsToken>this.connection_details.credentials).token
76
+ return this.token
77
+ }
78
+ else {
79
+ console.time()
80
+ let res = await fetch(`${this.endpoint}/sessions`, {
81
+ hostname: this.host.hostname,
82
+ port: 443,
83
+ method: "POST",
84
+ headers: generateAuthorizationHeaders(this.connection_details.credentials) as unknown as HeadersInit,
85
+ body: JSON.stringify({
86
+ fmDataSource: this.connection_details.externalSources.map(i => {
87
+ let _i = <databaseOptionsBase>i
88
+ return this.generateExternalSourceLogin(_i)
98
89
  })
99
- }).then(async res => {
100
- let _res = <any>(await res.json())
101
- if (res.status === 200) {
102
- this._token = res.headers.get('x-fm-data-access-token')
103
- resolve(this._token)
104
- }
105
- else {
106
- reject(new FMError(_res.messages[0].code, _res.status, res))
107
- }
108
90
  })
109
- .catch(e => {
110
- reject(e)
111
- })
91
+ })
92
+ console.time()
93
+ let _res = <any>(await res.json())
94
+ if (res.status === 200) {
95
+ this._token = res.headers.get('x-fm-data-access-token')
96
+ return this._token
112
97
  }
113
- })
98
+ else {
99
+ throw new FMError(_res.messages[0].code, _res.status, res)
100
+ }
101
+ }
114
102
  }
115
103
 
116
104
  get token() {
@@ -121,7 +109,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
121
109
  return `${this.host.hostname}/fmi/data/v2/databases/${this.name}`
122
110
  }
123
111
 
124
- async apiRequest<T = any>(url: string | Request, options: any = {}, autoRelogin = true): Promise<T> {
112
+ async apiRequest<T = any>(url: string | Request, options: any = {}, autoRelogin = true): Promise<ApiResults<T>> {
125
113
  if (!options.headers) options.headers = {}
126
114
  options.headers["content-type"] = options.headers["content-type"] ? options.headers["content-type"] : "application/json"
127
115
  options.headers["authorization"] = "Bearer " + this._token
@@ -134,14 +122,30 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
134
122
  this.cookies[cookie_split[0]] = cookie_split[1]
135
123
  }
136
124
  }
137
- let data = await _fetch.json() as fileMakerResponse
125
+ let data = await _fetch.json() as ApiResults<T>
126
+
127
+ // Remove response if it is empty. This makes checking for an empty response easier
128
+ if (Object.keys(data.response).length === 0) delete data.response
129
+
138
130
  // console.log(data.messages[0])
139
- if (data.messages[0].code == 952 && autoRelogin) {
131
+ if (data.messages[0].code === "952" && autoRelogin) {
140
132
  this._token = null
141
133
  await this.login()
142
134
  return await this.apiRequest(url, options, false)
143
135
  }
144
- return (data as any)
136
+ else if (data.messages[0].code !== "0") {
137
+ throw new FMError(data.messages[0].code, _fetch.status, data)
138
+ }
139
+
140
+ data.httpStatus = _fetch.status
141
+ return data
142
+ }
143
+
144
+ async listLayouts() {
145
+ let req = await this.apiRequest<{layouts: ApiLayout[]}>(`${this.endpoint}/layouts`)
146
+ if (!req.response) throw new FMError(req.messages[0].code, req.httpStatus, req.messages[0].message)
147
+
148
+ return req.response.layouts.filter(i => !i.isFolder).map(layout => new Layout(this, layout.name))
145
149
  }
146
150
 
147
151
  getLayout<R extends string>(name: R): Layout<T["layouts"][R]>
@@ -150,25 +154,14 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
150
154
  return new Layout<LayoutInterface>(this, name)
151
155
  }
152
156
 
153
- setGlobals(globalFields): Promise<void> {
157
+ /*
158
+ @deprecated
159
+ */
160
+ async setGlobals(globalFields) {
154
161
  // console.log({globalFields})
155
- return new Promise((resolve, reject) => {
156
- this.apiRequest(`${this.endpoint}/globals`, {
157
- method: "PATCH",
158
- body: JSON.stringify({globalFields})
159
- }).then(res => {
160
- // console.log(res)
161
- if (res.messages[0].code === "0") {
162
- resolve()
163
- }
164
- else {
165
- reject(
166
- (res.messages[0].code, res.status, res))
167
- }
168
- })
169
- .catch(e => {
170
- reject(e)
171
- })
162
+ await this.apiRequest(`${this.endpoint}/globals`, {
163
+ method: "PATCH",
164
+ body: JSON.stringify({globalFields})
172
165
  })
173
166
  }
174
167
 
@@ -180,15 +173,10 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
180
173
  this.emit("token_expired")
181
174
  }
182
175
 
183
- streamContainer(field, url): Promise<HTTP_REDIRECT.http.IncomingMessage> {
176
+ streamURL(url: string): Promise<HTTP_REDIRECT.http.IncomingMessage> {
184
177
  return new Promise((resolve, reject) => {
185
- if (field.metadata.result !== "container") {
186
- reject("Cannot stream the field " + field.id + " as it is not a container")
187
- return
188
- }
189
178
  if (!url || typeof url !== "string") {
190
- reject("Container is empty, or has invalid value")
191
- return
179
+ throw new Error("URL is empty, or has invalid value")
192
180
  }
193
181
 
194
182
  let headers = {}
@@ -1,8 +1,11 @@
1
1
  import { HostBase } from "./HostBase.js";
2
2
  import { Request } from "node-fetch";
3
+ import { ApiResults } from "../models/apiResults";
4
+ import HTTP_REDIRECT from "follow-redirects";
3
5
  export interface DatabaseBase {
4
6
  host: HostBase;
5
7
  readonly name: string;
6
8
  endpoint: string;
7
- apiRequest(url: string | Request, options?: any, autoRelogin?: boolean): Promise<any>;
9
+ apiRequest<T = unknown>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>;
10
+ streamURL(url: string): Promise<HTTP_REDIRECT.http.IncomingMessage>;
8
11
  }
@@ -5,6 +5,8 @@
5
5
  import {HostBase} from "./HostBase.js"
6
6
  import {Request} from "node-fetch";
7
7
  import {DatabaseStructure} from "../types";
8
+ import {ApiResults} from "../models/apiResults";
9
+ import HTTP_REDIRECT from "follow-redirects"
8
10
 
9
11
  export interface DatabaseBase {
10
12
  host: HostBase,
@@ -13,5 +15,6 @@ export interface DatabaseBase {
13
15
 
14
16
  // layouts: DatabaseStructure["layouts"]
15
17
 
16
- apiRequest(url: string | Request, options?: any, autoRelogin?: boolean): Promise<any>
18
+ apiRequest<T = unknown>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>
19
+ streamURL(url: string): Promise<HTTP_REDIRECT.http.IncomingMessage>
17
20
  }
@@ -3,14 +3,14 @@ import { LayoutRecord } from "../records/layoutRecord.js";
3
3
  import { Script, ScriptResult } from "../types.js";
4
4
  import { LayoutInterface } from "./layoutInterface.js";
5
5
  import { Find } from "../records/getOperations/find.js";
6
- import { FMError } from "../FMError.js";
7
6
  import { LayoutBase } from "./layoutBase.js";
8
7
  import { DatabaseBase } from "../connection/databaseBase";
8
+ import { ApiLayoutMetadata } from "../models/apiResults";
9
9
  export declare class Layout<T extends LayoutInterface> implements LayoutBase {
10
10
  readonly database: DatabaseBase;
11
11
  readonly records: LayoutRecordManager<T>;
12
12
  readonly name: string;
13
- metadata: any;
13
+ metadata: ApiLayoutMetadata;
14
14
  constructor(database: DatabaseBase, name: string);
15
15
  get endpoint(): string;
16
16
  /**
@@ -26,5 +26,5 @@ export declare class Layout<T extends LayoutInterface> implements LayoutBase {
26
26
  */
27
27
  newFind(): Find<T>;
28
28
  runScript(script: Script): Promise<ScriptResult>;
29
- getLayoutMeta(): Promise<this | FMError>;
29
+ getLayoutMeta(): Promise<ApiLayoutMetadata>;
30
30
  }
@@ -40,45 +40,31 @@ export class Layout {
40
40
  return this.records.find();
41
41
  }
42
42
  runScript(script) {
43
- let trace = new Error();
44
- return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
43
+ return __awaiter(this, void 0, void 0, function* () {
45
44
  let url = `${this.endpoint}/script/${encodeURIComponent(script.name)}`;
46
45
  if (script.parameter)
47
46
  url += "?script.param=" + encodeURIComponent(script.parameter);
48
- this.database.apiRequest(url, {
47
+ let res = yield this.database.apiRequest(url, {
49
48
  port: 443,
50
49
  method: "GET"
51
- })
52
- .then(res => {
53
- if (res.messages[0].code === "0") {
54
- let error = parseInt(res.response.scriptError);
55
- let msg = {
56
- scriptError: error ? new FMError(error, 200, res, trace) : undefined,
57
- scriptResult: res.response.scriptResult
58
- };
59
- resolve(msg);
60
- }
61
- else {
62
- // console.log(res)
63
- reject(new FMError(res.messages[0].code, res.status, res, trace));
64
- }
65
- })
66
- .catch(e => {
67
- reject(e);
68
50
  });
69
- }));
51
+ if (res.messages[0].code === "0") {
52
+ let error = parseInt(res.response.scriptError);
53
+ return {
54
+ scriptError: error ? new FMError(error, 200, res) : undefined,
55
+ scriptResult: res.response.scriptResult
56
+ };
57
+ }
58
+ });
70
59
  }
71
60
  getLayoutMeta() {
72
- return new Promise((resolve, reject) => {
61
+ return __awaiter(this, void 0, void 0, function* () {
73
62
  if (this.metadata) {
74
- resolve(this.metadata);
75
- return;
63
+ return this.metadata;
76
64
  }
77
- this.database.apiRequest(this.endpoint).then(res => {
78
- this.metadata = res.response;
79
- resolve(this);
80
- })
81
- .catch(e => reject(e));
65
+ let res = yield this.database.apiRequest(this.endpoint);
66
+ this.metadata = res.response;
67
+ return this.metadata;
82
68
  });
83
69
  }
84
70
  }