@jd-data-limited/easy-fm 4.0.5 → 4.0.7

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 CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "@jd-data-limited/easy-fm",
3
- "version": "4.0.5",
3
+ "version": "4.0.7",
4
4
  "dependencies": {
5
5
  "follow-redirects": "^1.15.5",
6
+ "@types/follow-redirects": "^1.14.4",
6
7
  "moment": "^2.29.4"
7
8
  },
8
9
  "type": "module",
@@ -35,7 +36,6 @@
35
36
  "devDependencies": {
36
37
  "@types/btoa": "^1.2.3",
37
38
  "@types/events": "^3.0.0",
38
- "@types/follow-redirects": "^1.14.4",
39
39
  "@types/inquirer": "^9.0.7",
40
40
  "dotenv": "^16.3.1",
41
41
  "inquirer": "^9.2.13",
@@ -21,7 +21,8 @@ export declare class Database<T extends DatabaseStructure> extends EventEmitter
21
21
  login(): Promise<any>;
22
22
  get token(): any;
23
23
  get endpoint(): string;
24
- apiRequest<T = any>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>;
24
+ apiRequestRaw(url: string | Request, options?: any): Promise<Response>;
25
+ apiRequestJSON<T = any>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>;
25
26
  listLayouts(): Promise<Layout<LayoutInterface>[]>;
26
27
  getLayout<R extends keyof T["layouts"]>(name: R): Layout<T["layouts"][R]>;
27
28
  getLayout<R extends LayoutInterface>(name: string): Layout<R>;
@@ -85,7 +85,7 @@ export class Database extends EventEmitter {
85
85
  get endpoint() {
86
86
  return `${this.host.hostname}/fmi/data/v2/databases/${this.name}`;
87
87
  }
88
- async apiRequest(url, options = {}, autoRelogin = true) {
88
+ async apiRequestRaw(url, options = {}) {
89
89
  if (!options.headers)
90
90
  options.headers = {};
91
91
  options.headers["content-type"] = options.headers["content-type"] ? options.headers["content-type"] : "application/json";
@@ -98,6 +98,10 @@ export class Database extends EventEmitter {
98
98
  this.cookies[cookie_split[0]] = cookie_split[1];
99
99
  }
100
100
  }
101
+ return _fetch;
102
+ }
103
+ async apiRequestJSON(url, options = {}, autoRelogin = true) {
104
+ let _fetch = await this.apiRequestRaw(url, options);
101
105
  let data = await _fetch.json();
102
106
  // Remove response if it is empty. This makes checking for an empty response easier
103
107
  if (data.response && Object.keys(data.response).length === 0)
@@ -106,7 +110,7 @@ export class Database extends EventEmitter {
106
110
  if (data.messages[0].code === "952" && autoRelogin) {
107
111
  this._token = null;
108
112
  await this.login();
109
- return await this.apiRequest(url, options, false);
113
+ return await this.apiRequestJSON(url, options, false);
110
114
  }
111
115
  else if (data.messages[0].code !== "0") {
112
116
  throw new FMError(data.messages[0].code, _fetch.status, data);
@@ -115,7 +119,7 @@ export class Database extends EventEmitter {
115
119
  return data;
116
120
  }
117
121
  async listLayouts() {
118
- let req = await this.apiRequest(`${this.endpoint}/layouts?page=2`);
122
+ let req = await this.apiRequestJSON(`${this.endpoint}/layouts?page=2`);
119
123
  if (!req.response)
120
124
  throw new FMError(req.messages[0].code, req.httpStatus, req.messages[0].message);
121
125
  const cycleLayoutNames = (layouts) => {
@@ -110,7 +110,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
110
110
  return `${this.host.hostname}/fmi/data/v2/databases/${this.name}`
111
111
  }
112
112
 
113
- async apiRequest<T = any>(url: string | Request, options: any = {}, autoRelogin = true): Promise<ApiResults<T>> {
113
+ async apiRequestRaw(url: string | Request, options: any = {}) {
114
114
  if (!options.headers) options.headers = {}
115
115
  options.headers["content-type"] = options.headers["content-type"] ? options.headers["content-type"] : "application/json"
116
116
  options.headers["authorization"] = "Bearer " + this._token
@@ -123,6 +123,10 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
123
123
  this.cookies[cookie_split[0]] = cookie_split[1]
124
124
  }
125
125
  }
126
+ return _fetch
127
+ }
128
+ async apiRequestJSON<T = any>(url: string | Request, options: any = {}, autoRelogin = true): Promise<ApiResults<T>> {
129
+ let _fetch = await this.apiRequestRaw(url, options)
126
130
  let data = await _fetch.json() as ApiResults<T>
127
131
 
128
132
  // Remove response if it is empty. This makes checking for an empty response easier
@@ -132,7 +136,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
132
136
  if (data.messages[0].code === "952" && autoRelogin) {
133
137
  this._token = null
134
138
  await this.login()
135
- return await this.apiRequest(url, options, false)
139
+ return await this.apiRequestJSON(url, options, false)
136
140
  }
137
141
  else if (data.messages[0].code !== "0") {
138
142
  throw new FMError(data.messages[0].code, _fetch.status, data)
@@ -143,7 +147,7 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
143
147
  }
144
148
 
145
149
  async listLayouts() {
146
- let req = await this.apiRequest<{layouts: ApiLayout[]}>(`${this.endpoint}/layouts?page=2`)
150
+ let req = await this.apiRequestJSON<{layouts: ApiLayout[]}>(`${this.endpoint}/layouts?page=2`)
147
151
  if (!req.response) throw new FMError(req.messages[0].code, req.httpStatus, req.messages[0].message)
148
152
 
149
153
  const cycleLayoutNames = (layouts: ApiLayout[]) => {
@@ -6,6 +6,7 @@ export interface DatabaseBase {
6
6
  host: HostBase;
7
7
  readonly name: string;
8
8
  endpoint: string;
9
- apiRequest<T = unknown>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>;
9
+ apiRequestJSON<T = unknown>(url: string | Request, options?: RequestInit | undefined, autoRelogin?: boolean): Promise<ApiResults<T>>;
10
+ apiRequestRaw(url: string | Request, options?: RequestInit | undefined): Promise<Response>;
10
11
  streamURL(url: string): Promise<IncomingMessage>;
11
12
  }
@@ -13,6 +13,7 @@ export interface DatabaseBase {
13
13
 
14
14
  // layouts: DatabaseStructure["layouts"]
15
15
 
16
- apiRequest<T = unknown>(url: string | Request, options?: any, autoRelogin?: boolean): Promise<ApiResults<T>>
16
+ apiRequestJSON<T = unknown>(url: string | Request, options?: RequestInit | undefined, autoRelogin?: boolean): Promise<ApiResults<T>>
17
+ apiRequestRaw(url: string | Request, options?: RequestInit | undefined): Promise<Response>
17
18
  streamURL(url: string): Promise<IncomingMessage>
18
19
  }
@@ -19,8 +19,7 @@ export class Layout {
19
19
  let url = `${this.endpoint}/script/${encodeURIComponent(script.name)}`;
20
20
  if (script.parameter)
21
21
  url += "?script.param=" + encodeURIComponent(script.parameter);
22
- let res = await this.database.apiRequest(url, {
23
- port: 443,
22
+ let res = await this.database.apiRequestJSON(url, {
24
23
  method: "GET"
25
24
  });
26
25
  if (res.response && res.messages[0].code === "0") {
@@ -38,7 +37,7 @@ export class Layout {
38
37
  if (this.metadata) {
39
38
  return this.metadata;
40
39
  }
41
- let res = await this.database.apiRequest(this.endpoint);
40
+ let res = await this.database.apiRequestJSON(this.endpoint);
42
41
  if (!res.response)
43
42
  throw new FMError(res.messages[0].code, res.httpStatus, res);
44
43
  this.metadata = res.response;
@@ -29,8 +29,7 @@ export class Layout<T extends LayoutInterface> implements LayoutBase {
29
29
  async runScript(script: Script): Promise<ScriptResult> {
30
30
  let url = `${this.endpoint}/script/${encodeURIComponent(script.name)}`
31
31
  if (script.parameter) url += "?script.param=" + encodeURIComponent(script.parameter)
32
- let res = await this.database.apiRequest<ApiScriptResult>(url, {
33
- port: 443,
32
+ let res = await this.database.apiRequestJSON<ApiScriptResult>(url, {
34
33
  method: "GET"
35
34
  })
36
35
  if (res.response && res.messages[0].code === "0") {
@@ -49,7 +48,7 @@ export class Layout<T extends LayoutInterface> implements LayoutBase {
49
48
  return this.metadata
50
49
  }
51
50
 
52
- let res = await this.database.apiRequest<ApiLayoutMetadata>(this.endpoint)
51
+ let res = await this.database.apiRequestJSON<ApiLayoutMetadata>(this.endpoint)
53
52
  if (!res.response) throw new FMError(res.messages[0].code, res.httpStatus, res)
54
53
  this.metadata = res.response
55
54
  return this.metadata
@@ -120,12 +120,14 @@ export class FieldBase {
120
120
  throw "Cannot upload a file to the field; " + this.id + " (not a container field)";
121
121
  let form = new FormData();
122
122
  form.append("upload", new File([buffer], filename, { type: mime }));
123
- await this.parent.layout.database.apiRequest(`${this.parent.endpoint}/containers/${this.id}/1`, {
123
+ let res = await this.parent.layout.database.apiRequestRaw(`${this.parent.endpoint}/containers/${this.id}/1`, {
124
124
  method: "POST",
125
125
  // @ts-ignore
126
126
  headers: { "Authorization": "Bearer " + this.parent.layout.database.token },
127
127
  body: form
128
128
  });
129
+ if (!res.ok)
130
+ throw new Error(`Upload failed with HTTP error: ${res.status} (${res.statusText})`);
129
131
  }
130
132
  async download(mode = DOWNLOAD_MODES.Stream) {
131
133
  if (this.metadata.result !== ApiFieldResultTypes.CONTAINER)
@@ -136,12 +136,13 @@ export class FieldBase<T extends FieldValue> {
136
136
  let form = new FormData()
137
137
  form.append("upload", new File([buffer], filename, {type: mime}))
138
138
 
139
- await this.parent.layout.database.apiRequest<null>(`${this.parent.endpoint}/containers/${this.id}/1`, {
139
+ let res = await this.parent.layout.database.apiRequestRaw(`${this.parent.endpoint}/containers/${this.id}/1`, {
140
140
  method: "POST",
141
141
  // @ts-ignore
142
142
  headers: {"Authorization": "Bearer " + this.parent.layout.database.token},
143
143
  body: form
144
144
  })
145
+ if (!res.ok) throw new Error(`Upload failed with HTTP error: ${res.status} (${res.statusText})`)
145
146
  }
146
147
 
147
148
  download(mode: DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage>
@@ -105,7 +105,7 @@ export class RecordGetOperation {
105
105
  body: is_find ? JSON.stringify(this.generateParamsBody(offset, limit)) : undefined,
106
106
  };
107
107
  try {
108
- let res = await this.layout.database.apiRequest(endpoint, reqData);
108
+ let res = await this.layout.database.apiRequestJSON(endpoint, reqData);
109
109
  if (res.messages[0].code === "0" && res.response) {
110
110
  // console.log("RESOLVING")
111
111
  if (!this.layout.metadata)
@@ -140,7 +140,7 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
140
140
  }
141
141
 
142
142
  try {
143
- let res = await this.layout.database.apiRequest<ApiRecordResponseObj>(
143
+ let res = await this.layout.database.apiRequestJSON<ApiRecordResponseObj>(
144
144
  endpoint,
145
145
  reqData
146
146
  )
@@ -41,8 +41,7 @@ export class LayoutRecord extends RecordBase {
41
41
  }
42
42
  if (this.recordId === -1) {
43
43
  // This is a new LayoutRecord
44
- let res = await this.layout.database.apiRequest(`${this.layout.endpoint}/records`, {
45
- port: 443,
44
+ let res = await this.layout.database.apiRequestJSON(`${this.layout.endpoint}/records`, {
46
45
  method: "POST",
47
46
  body: JSON.stringify(data)
48
47
  });
@@ -62,8 +61,7 @@ export class LayoutRecord extends RecordBase {
62
61
  }
63
62
  }
64
63
  // for (let item of Object.keys(data)) extraBody[item] = data[item]
65
- let res = await this.layout.database.apiRequest(this.endpoint, {
66
- port: 443,
64
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
67
65
  method: "PATCH",
68
66
  body: JSON.stringify(data)
69
67
  });
@@ -102,8 +100,7 @@ export class LayoutRecord extends RecordBase {
102
100
  }
103
101
  if (!this.layout.metadata)
104
102
  await this.layout.getLayoutMeta();
105
- let res = await this.layout.database.apiRequest(this.endpoint, {
106
- port: 443,
103
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
107
104
  method: "GET"
108
105
  });
109
106
  if (res.response && res.messages[0].code === "0") {
@@ -121,8 +118,7 @@ export class LayoutRecord extends RecordBase {
121
118
  }
122
119
  async duplicate() {
123
120
  let trace = new Error();
124
- let res = await this.layout.database.apiRequest(this.endpoint, {
125
- port: 443,
121
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
126
122
  method: "POST"
127
123
  });
128
124
  if (!res.response) {
@@ -142,8 +138,7 @@ export class LayoutRecord extends RecordBase {
142
138
  }
143
139
  }
144
140
  async delete() {
145
- let res = await this.layout.database.apiRequest(this.endpoint, {
146
- port: 443,
141
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
147
142
  method: "DELETE"
148
143
  });
149
144
  console.log(res);
@@ -57,8 +57,7 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
57
57
 
58
58
  if (this.recordId === -1) {
59
59
  // This is a new LayoutRecord
60
- let res = await this.layout.database.apiRequest<{ recordId: string, modId: string }>(`${this.layout.endpoint}/records`, {
61
- port: 443,
60
+ let res = await this.layout.database.apiRequestJSON<{ recordId: string, modId: string }>(`${this.layout.endpoint}/records`, {
62
61
  method: "POST",
63
62
  body: JSON.stringify(data)
64
63
  })
@@ -80,14 +79,13 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
80
79
  }
81
80
 
82
81
  // for (let item of Object.keys(data)) extraBody[item] = data[item]
83
- let res = await this.layout.database.apiRequest<{
82
+ let res = await this.layout.database.apiRequestJSON<{
84
83
  modId: string, newPortalRecordInfo: {
85
84
  tableName: string,
86
85
  recordId: string,
87
86
  modId: string
88
87
  }[]
89
88
  }>(this.endpoint, {
90
- port: 443,
91
89
  method: "PATCH",
92
90
  body: JSON.stringify(data)
93
91
  })
@@ -128,8 +126,7 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
128
126
  throw "Cannot get this RecordBase until a commit() is done."
129
127
  }
130
128
  if (!this.layout.metadata) await this.layout.getLayoutMeta()
131
- let res = await this.layout.database.apiRequest<ApiRecordResponseObj>(this.endpoint, {
132
- port: 443,
129
+ let res = await this.layout.database.apiRequestJSON<ApiRecordResponseObj>(this.endpoint, {
133
130
  method: "GET"
134
131
  })
135
132
 
@@ -147,8 +144,7 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
147
144
 
148
145
  async duplicate(): Promise<LayoutRecord<LAYOUT>> {
149
146
  let trace = new Error()
150
- let res = await this.layout.database.apiRequest<{recordId: string, modId: string}>(this.endpoint, {
151
- port: 443,
147
+ let res = await this.layout.database.apiRequestJSON<{recordId: string, modId: string}>(this.endpoint, {
152
148
  method: "POST"
153
149
  })
154
150
  if (!res.response) {
@@ -170,8 +166,7 @@ export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAY
170
166
  }
171
167
 
172
168
  async delete(): Promise<void> {
173
- let res = await this.layout.database.apiRequest(this.endpoint, {
174
- port: 443,
169
+ let res = await this.layout.database.apiRequestJSON(this.endpoint, {
175
170
  method: "DELETE"
176
171
  })
177
172
  console.log(res)
@@ -1,6 +0,0 @@
1
- import { RecordBase } from "./recordBase.js";
2
- import { FieldBase, FieldValue } from "./fieldBase.js";
3
- export declare abstract class Field<T extends FieldValue> extends FieldBase<T> {
4
- record: RecordBase<any>;
5
- protected constructor(record: RecordBase<any>);
6
- }
@@ -1,11 +0,0 @@
1
- /*
2
- * Copyright (c) 2024. See LICENSE file for more information
3
- */
4
- import { FieldBase } from "./fieldBase.js";
5
- export class Field extends FieldBase {
6
- record;
7
- constructor(record) {
8
- super();
9
- this.record = record;
10
- }
11
- }