@jd-data-limited/easy-fm 3.2.2 → 3.2.4
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 +2 -1
- package/src/connection/database.d.ts +2 -1
- package/src/connection/database.js +22 -11
- package/src/connection/database.ts +33 -24
- package/src/connection/databaseBase.d.ts +0 -2
- package/src/connection/databaseBase.ts +0 -2
- package/src/records/field.d.ts +4 -3
- package/src/records/field.js +26 -21
- package/src/records/field.ts +31 -21
- package/src/types.d.ts +5 -2
- package/src/types.ts +4 -3
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jd-data-limited/easy-fm",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.4",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"@types/btoa": "^1.2.3",
|
|
6
6
|
"@types/events": "^3.0.0",
|
|
7
|
+
"follow-redirects": "^1.15.3",
|
|
7
8
|
"moment": "^2.29.4",
|
|
8
9
|
"node-fetch": "3.2.8",
|
|
9
10
|
"typescript": "^5.2.2",
|
|
@@ -3,6 +3,7 @@ import { EventEmitter } from "events";
|
|
|
3
3
|
import { Request } from "node-fetch";
|
|
4
4
|
import { LayoutInterface } from "../layouts/layoutInterface.js";
|
|
5
5
|
import { Layout } from "../layouts/layout.js";
|
|
6
|
+
import { http } from "follow-redirects";
|
|
6
7
|
import { databaseOptionsWithExternalSources, DatabaseStructure, Script } from "../types.js";
|
|
7
8
|
import { HostBase } from "./HostBase.js";
|
|
8
9
|
import { DatabaseBase } from "./databaseBase";
|
|
@@ -24,5 +25,5 @@ export declare class Database<T extends DatabaseStructure> extends EventEmitter
|
|
|
24
25
|
setGlobals(globalFields: any): Promise<void>;
|
|
25
26
|
script(name: any, parameter?: string): Script;
|
|
26
27
|
_tokenExpired(): void;
|
|
27
|
-
streamContainer(url: any): Promise<
|
|
28
|
+
streamContainer(field: any, url: any): Promise<http.IncomingMessage>;
|
|
28
29
|
}
|
|
@@ -15,6 +15,7 @@ import fetch from "node-fetch";
|
|
|
15
15
|
import { generateAuthorizationHeaders } from "./generateAuthorizationHeaders.js";
|
|
16
16
|
import { FMError } from "../FMError.js";
|
|
17
17
|
import { Layout } from "../layouts/layout.js";
|
|
18
|
+
import { http, https } from "follow-redirects";
|
|
18
19
|
export class Database extends EventEmitter {
|
|
19
20
|
constructor(host, conn) {
|
|
20
21
|
super();
|
|
@@ -156,8 +157,16 @@ export class Database extends EventEmitter {
|
|
|
156
157
|
_tokenExpired() {
|
|
157
158
|
this.emit("token_expired");
|
|
158
159
|
}
|
|
159
|
-
streamContainer(url) {
|
|
160
|
-
return
|
|
160
|
+
streamContainer(field, url) {
|
|
161
|
+
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
|
+
if (!url || typeof url !== "string") {
|
|
167
|
+
reject("Container is empty, or has invalid value");
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
161
170
|
let headers = {};
|
|
162
171
|
if (Object.keys(this.cookies).length !== 0) {
|
|
163
172
|
headers["Cookie"] = Object.keys(this.cookies)
|
|
@@ -167,17 +176,19 @@ export class Database extends EventEmitter {
|
|
|
167
176
|
.join("; ");
|
|
168
177
|
}
|
|
169
178
|
// Automatically switch between the http and https modules, based on which is needed
|
|
170
|
-
|
|
179
|
+
(url.startsWith("https") ? https : http).get(url, {
|
|
171
180
|
headers
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
let
|
|
176
|
-
|
|
181
|
+
}, (res) => {
|
|
182
|
+
// Check for the 'set-cookie' header. If it exists, remember it and strip it for better security.
|
|
183
|
+
if (res.headers['set-cookie']) {
|
|
184
|
+
for (let cookie of res.headers['set-cookie']) {
|
|
185
|
+
let cookie_split = cookie.split("=");
|
|
186
|
+
this.cookies[cookie_split[0]] = cookie_split[1];
|
|
187
|
+
}
|
|
188
|
+
res.headers['set-cookie'] = null;
|
|
177
189
|
}
|
|
178
|
-
res
|
|
179
|
-
}
|
|
180
|
-
return res;
|
|
190
|
+
resolve(res);
|
|
191
|
+
});
|
|
181
192
|
});
|
|
182
193
|
}
|
|
183
194
|
}
|
|
@@ -8,8 +8,7 @@ import {generateAuthorizationHeaders} from "./generateAuthorizationHeaders.js";
|
|
|
8
8
|
import {FMError} from "../FMError.js";
|
|
9
9
|
import {LayoutInterface} from "../layouts/layoutInterface.js";
|
|
10
10
|
import {Layout} from "../layouts/layout.js";
|
|
11
|
-
import
|
|
12
|
-
import * as https from "https";
|
|
11
|
+
import {http, https} from "follow-redirects"
|
|
13
12
|
import {
|
|
14
13
|
databaseOptionsBase,
|
|
15
14
|
databaseOptionsWithExternalSources, DatabaseStructure,
|
|
@@ -181,31 +180,41 @@ export class Database<T extends DatabaseStructure> extends EventEmitter implemen
|
|
|
181
180
|
this.emit("token_expired")
|
|
182
181
|
}
|
|
183
182
|
|
|
184
|
-
|
|
183
|
+
streamContainer(field, url): Promise<http.IncomingMessage> {
|
|
184
|
+
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
|
+
if (!url || typeof url !== "string") {
|
|
190
|
+
reject("Container is empty, or has invalid value")
|
|
191
|
+
return
|
|
192
|
+
}
|
|
185
193
|
|
|
194
|
+
let headers = {}
|
|
195
|
+
if (Object.keys(this.cookies).length !== 0) {
|
|
196
|
+
headers["Cookie"] = Object.keys(this.cookies)
|
|
197
|
+
.map(key => {
|
|
198
|
+
return key + "=" + this.cookies[key]
|
|
199
|
+
})
|
|
200
|
+
.join("; ")
|
|
201
|
+
}
|
|
186
202
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
203
|
+
// Automatically switch between the http and https modules, based on which is needed
|
|
204
|
+
(url.startsWith("https") ? https : http).get(url, {
|
|
205
|
+
headers
|
|
206
|
+
}, (res) => {
|
|
207
|
+
// Check for the 'set-cookie' header. If it exists, remember it and strip it for better security.
|
|
208
|
+
if (res.headers['set-cookie']) {
|
|
209
|
+
for (let cookie of res.headers['set-cookie']) {
|
|
210
|
+
let cookie_split = cookie.split("=")
|
|
211
|
+
this.cookies[cookie_split[0]] = cookie_split[1]
|
|
212
|
+
}
|
|
213
|
+
res.headers['set-cookie'] = null
|
|
214
|
+
}
|
|
195
215
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
headers
|
|
216
|
+
resolve(res)
|
|
217
|
+
})
|
|
199
218
|
})
|
|
200
|
-
|
|
201
|
-
if (res.headers.get('set-cookie')) {
|
|
202
|
-
for (let cookie of res.headers['set-cookie']) {
|
|
203
|
-
let cookie_split = cookie.split("=")
|
|
204
|
-
this.cookies[cookie_split[0]] = cookie_split[1]
|
|
205
|
-
}
|
|
206
|
-
res.headers.set('set-cookie', null)
|
|
207
|
-
}
|
|
208
|
-
return res
|
|
209
219
|
}
|
|
210
|
-
|
|
211
220
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { HostBase } from "./HostBase.js";
|
|
2
2
|
import { Request } from "node-fetch";
|
|
3
|
-
import { Response } from "node-fetch";
|
|
4
3
|
export interface DatabaseBase {
|
|
5
4
|
host: HostBase;
|
|
6
5
|
readonly name: string;
|
|
7
6
|
endpoint: string;
|
|
8
7
|
apiRequest(url: string | Request, options?: any, autoRelogin?: boolean): Promise<any>;
|
|
9
|
-
streamContainer(url: string): Promise<Response>;
|
|
10
8
|
}
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
import {HostBase} from "./HostBase.js"
|
|
6
6
|
import {Request} from "node-fetch";
|
|
7
7
|
import {DatabaseStructure} from "../types";
|
|
8
|
-
import {Response} from "node-fetch";
|
|
9
8
|
|
|
10
9
|
export interface DatabaseBase {
|
|
11
10
|
host: HostBase,
|
|
@@ -15,5 +14,4 @@ export interface DatabaseBase {
|
|
|
15
14
|
// layouts: DatabaseStructure["layouts"]
|
|
16
15
|
|
|
17
16
|
apiRequest(url: string | Request, options?: any, autoRelogin?: boolean): Promise<any>
|
|
18
|
-
streamContainer(url: string): Promise<Response>
|
|
19
17
|
}
|
package/src/records/field.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { RecordBase } from "./recordBase.js";
|
|
4
|
-
import
|
|
4
|
+
import * as http from "http";
|
|
5
|
+
import { ContainerBufferResult, DOWNLOAD_MODES, FieldMetaData } from "../types.js";
|
|
5
6
|
export type FieldValue = string | number | Date | Container;
|
|
6
7
|
export type Container = null;
|
|
7
8
|
export declare class Field<T extends FieldValue> {
|
|
@@ -18,6 +19,6 @@ export declare class Field<T extends FieldValue> {
|
|
|
18
19
|
get date(): Date;
|
|
19
20
|
get number(): number;
|
|
20
21
|
upload(buffer: Buffer, filename: string, mime: string): Promise<void>;
|
|
21
|
-
download(mode: DOWNLOAD_MODES.Stream): Promise<
|
|
22
|
-
download(mode: DOWNLOAD_MODES.Buffer): Promise<
|
|
22
|
+
download(mode: DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage>;
|
|
23
|
+
download(mode: DOWNLOAD_MODES.Buffer): Promise<ContainerBufferResult>;
|
|
23
24
|
}
|
package/src/records/field.js
CHANGED
|
@@ -149,27 +149,32 @@ export class Field {
|
|
|
149
149
|
}));
|
|
150
150
|
}
|
|
151
151
|
download(mode = DOWNLOAD_MODES.Stream) {
|
|
152
|
-
return
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
152
|
+
return new Promise((resolve, reject) => {
|
|
153
|
+
// @ts-ignore
|
|
154
|
+
this.record.layout.database.streamContainer(this, this._value)
|
|
155
|
+
.then(stream => {
|
|
156
|
+
if (mode === DOWNLOAD_MODES.Stream) {
|
|
157
|
+
resolve(stream);
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
let body = [];
|
|
161
|
+
stream.on("data", chunk => {
|
|
162
|
+
body.push(chunk);
|
|
163
|
+
});
|
|
164
|
+
stream.on("error", (e) => {
|
|
165
|
+
reject(e);
|
|
166
|
+
});
|
|
167
|
+
stream.on("end", () => {
|
|
168
|
+
resolve({
|
|
169
|
+
buffer: Buffer.concat(body),
|
|
170
|
+
mime: stream.headers["content-type"],
|
|
171
|
+
request: stream
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
})
|
|
175
|
+
.catch(e => {
|
|
176
|
+
reject(e);
|
|
177
|
+
});
|
|
173
178
|
});
|
|
174
179
|
}
|
|
175
180
|
}
|
package/src/records/field.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import {RecordBase, RecordTypes} from "./recordBase.js";
|
|
6
6
|
import fetch, {File, FormData} from "node-fetch";
|
|
7
7
|
import * as http from "http";
|
|
8
|
-
import {
|
|
8
|
+
import {ContainerBufferResult, DOWNLOAD_MODES, FieldMetaData} from "../types.js";
|
|
9
9
|
import {FMError} from "../FMError.js";
|
|
10
10
|
|
|
11
11
|
export type FieldValue = string | number | Date | Container
|
|
@@ -158,26 +158,36 @@ export class Field<T extends FieldValue> {
|
|
|
158
158
|
})
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
download(mode: DOWNLOAD_MODES.Stream): Promise<
|
|
162
|
-
download(mode: DOWNLOAD_MODES.Buffer): Promise<
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
let data: NodeJS.ReadableStream | ArrayBuffer
|
|
173
|
-
switch (mode) {
|
|
174
|
-
case DOWNLOAD_MODES.Buffer: data = await res.arrayBuffer(); break
|
|
175
|
-
case DOWNLOAD_MODES.Stream: data = res.body; break
|
|
176
|
-
}
|
|
161
|
+
download(mode: DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage>
|
|
162
|
+
download(mode: DOWNLOAD_MODES.Buffer): Promise<ContainerBufferResult>
|
|
163
|
+
download(mode: DOWNLOAD_MODES = DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage | ContainerBufferResult> {
|
|
164
|
+
return new Promise((resolve, reject) => {
|
|
165
|
+
// @ts-ignore
|
|
166
|
+
this.record.layout.database.streamContainer(this, this._value)
|
|
167
|
+
.then(stream => {
|
|
168
|
+
if (mode === DOWNLOAD_MODES.Stream) {
|
|
169
|
+
resolve(stream)
|
|
170
|
+
return
|
|
171
|
+
}
|
|
177
172
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
173
|
+
let body = []
|
|
174
|
+
stream.on("data", chunk => {
|
|
175
|
+
body.push(chunk)
|
|
176
|
+
})
|
|
177
|
+
stream.on("error", (e) => {
|
|
178
|
+
reject(e)
|
|
179
|
+
})
|
|
180
|
+
stream.on("end", () => {
|
|
181
|
+
resolve({
|
|
182
|
+
buffer: Buffer.concat(body),
|
|
183
|
+
mime: stream.headers["content-type"],
|
|
184
|
+
request: stream
|
|
185
|
+
} as ContainerBufferResult)
|
|
186
|
+
})
|
|
187
|
+
})
|
|
188
|
+
.catch(e => {
|
|
189
|
+
reject(e)
|
|
190
|
+
})
|
|
191
|
+
})
|
|
182
192
|
}
|
|
183
193
|
}
|
package/src/types.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
/// <reference types="node" />
|
|
3
|
+
import * as http from "http";
|
|
2
4
|
import { FMError } from "./FMError.js";
|
|
3
5
|
import { LayoutInterface } from "./layouts/layoutInterface";
|
|
4
6
|
export interface DatabaseStructure {
|
|
@@ -106,9 +108,10 @@ export interface ScriptResult {
|
|
|
106
108
|
scriptError?: FMError;
|
|
107
109
|
scriptResult?: string;
|
|
108
110
|
}
|
|
109
|
-
export interface
|
|
110
|
-
|
|
111
|
+
export interface ContainerBufferResult {
|
|
112
|
+
buffer: Buffer;
|
|
111
113
|
mime: string;
|
|
114
|
+
request: http.IncomingMessage;
|
|
112
115
|
}
|
|
113
116
|
export interface AuthorizationHeaders {
|
|
114
117
|
"Content-Type": "application/json";
|
package/src/types.ts
CHANGED
|
@@ -132,9 +132,10 @@ export interface ScriptResult {
|
|
|
132
132
|
scriptResult?: string
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
-
export interface
|
|
136
|
-
|
|
137
|
-
mime: string
|
|
135
|
+
export interface ContainerBufferResult {
|
|
136
|
+
buffer: Buffer,
|
|
137
|
+
mime: string,
|
|
138
|
+
request: http.IncomingMessage
|
|
138
139
|
}
|
|
139
140
|
|
|
140
141
|
//
|