@jd-data-limited/easy-fm 1.3.1 → 2.0.0
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/README.md +1 -1
- package/dist/index.js +91 -10
- package/package.json +1 -1
- package/src/index.ts +151 -33
- package/temp2/1.19.2-forge-43.2.8.json +347 -0
- package/temp2/Quinn-1.19.2-forge-43.2.8.json +347 -0
- package/test.js +23 -26
package/README.md
CHANGED
|
@@ -68,7 +68,7 @@ let range_request = layout.records.range()
|
|
|
68
68
|
range_request.setOffset(50) // Starting from the 50th record...
|
|
69
69
|
range_request.setLimit(100) // Fetch 100 records
|
|
70
70
|
|
|
71
|
-
let records = await range_request.
|
|
71
|
+
let records = await range_request.fetch()
|
|
72
72
|
console.log(records)
|
|
73
73
|
```
|
|
74
74
|
|
package/dist/index.js
CHANGED
|
@@ -12,10 +12,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
12
12
|
};
|
|
13
13
|
// const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
|
|
14
14
|
import fetch, { File, FormData } from 'node-fetch';
|
|
15
|
-
import 'node-fetch';
|
|
16
15
|
import { EventEmitter } from "events";
|
|
17
16
|
// @ts-ignore
|
|
18
17
|
import * as moment from "moment";
|
|
18
|
+
import * as http from "http";
|
|
19
|
+
import * as https from "https";
|
|
20
|
+
export var DOWNLOAD_MODES;
|
|
21
|
+
(function (DOWNLOAD_MODES) {
|
|
22
|
+
DOWNLOAD_MODES[DOWNLOAD_MODES["Stream"] = 0] = "Stream";
|
|
23
|
+
DOWNLOAD_MODES[DOWNLOAD_MODES["Buffer"] = 1] = "Buffer";
|
|
24
|
+
})(DOWNLOAD_MODES || (DOWNLOAD_MODES = {}));
|
|
19
25
|
// @ts-ignore
|
|
20
26
|
const errs = [
|
|
21
27
|
{
|
|
@@ -1082,6 +1088,7 @@ export default class FMHost {
|
|
|
1082
1088
|
export class Database extends EventEmitter {
|
|
1083
1089
|
constructor(host, conn) {
|
|
1084
1090
|
super();
|
|
1091
|
+
this.cookies = {};
|
|
1085
1092
|
this.host = host;
|
|
1086
1093
|
this.name = conn.database;
|
|
1087
1094
|
this.connection_details = conn;
|
|
@@ -1172,6 +1179,12 @@ export class Database extends EventEmitter {
|
|
|
1172
1179
|
options.headers["authorization"] = "Bearer " + this._token;
|
|
1173
1180
|
options.rejectUnauthorized = this.host.verify;
|
|
1174
1181
|
let _fetch = yield fetch(url, options);
|
|
1182
|
+
if (_fetch.headers.get('set-cookie')) {
|
|
1183
|
+
for (let cookie of _fetch.headers.get('set-cookie')) {
|
|
1184
|
+
let cookie_split = cookie.split("=");
|
|
1185
|
+
this.cookies[cookie_split[0]] = cookie_split[1];
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1175
1188
|
let data = yield _fetch.json();
|
|
1176
1189
|
// console.log(data.messages[0])
|
|
1177
1190
|
if (data.messages[0].code == 952 && autoRelogin) {
|
|
@@ -1211,6 +1224,40 @@ export class Database extends EventEmitter {
|
|
|
1211
1224
|
_tokenExpired() {
|
|
1212
1225
|
this.emit("token_expired");
|
|
1213
1226
|
}
|
|
1227
|
+
streamContainer(field, url) {
|
|
1228
|
+
return new Promise((resolve, reject) => {
|
|
1229
|
+
if (field.metadata.result !== "container") {
|
|
1230
|
+
reject("Cannot stream the field " + field.id + " as it is not a container");
|
|
1231
|
+
return;
|
|
1232
|
+
}
|
|
1233
|
+
if (!url || typeof url !== "string") {
|
|
1234
|
+
reject("Container is empty, or has invalid value");
|
|
1235
|
+
return;
|
|
1236
|
+
}
|
|
1237
|
+
let headers = {};
|
|
1238
|
+
if (Object.keys(this.cookies).length !== 0) {
|
|
1239
|
+
headers["Cookie"] = Object.keys(this.cookies)
|
|
1240
|
+
.map(key => {
|
|
1241
|
+
return key + "=" + this.cookies[key];
|
|
1242
|
+
})
|
|
1243
|
+
.join("; ");
|
|
1244
|
+
}
|
|
1245
|
+
// Automatically switch between the http and https modules, based on which is needed
|
|
1246
|
+
(url.startsWith("https") ? https : http).get(url, {
|
|
1247
|
+
headers
|
|
1248
|
+
}, (res) => {
|
|
1249
|
+
// Check for the 'set-cookie' header. If it exists, remember it and strip it for better security.
|
|
1250
|
+
if (res.headers['set-cookie']) {
|
|
1251
|
+
for (let cookie of res.headers['set-cookie']) {
|
|
1252
|
+
let cookie_split = cookie.split("=");
|
|
1253
|
+
this.cookies[cookie_split[0]] = cookie_split[1];
|
|
1254
|
+
}
|
|
1255
|
+
res.headers['set-cookie'] = null;
|
|
1256
|
+
}
|
|
1257
|
+
resolve(res);
|
|
1258
|
+
});
|
|
1259
|
+
});
|
|
1260
|
+
}
|
|
1214
1261
|
}
|
|
1215
1262
|
export class Layout {
|
|
1216
1263
|
constructor(database, name) {
|
|
@@ -1310,8 +1357,8 @@ class LayourRecordManager {
|
|
|
1310
1357
|
});
|
|
1311
1358
|
});
|
|
1312
1359
|
}
|
|
1313
|
-
range() {
|
|
1314
|
-
return new RecordGetRange(this.layout);
|
|
1360
|
+
range(start = 0, limit = 100) {
|
|
1361
|
+
return new RecordGetRange(this.layout, start, limit);
|
|
1315
1362
|
}
|
|
1316
1363
|
find() {
|
|
1317
1364
|
return new Find(this.layout);
|
|
@@ -1649,6 +1696,7 @@ export class Field {
|
|
|
1649
1696
|
}
|
|
1650
1697
|
}
|
|
1651
1698
|
get value() {
|
|
1699
|
+
// if (this.metadata.result === "container") throw "Use await field.stream() to get the contents of a container field, instead of field.value"
|
|
1652
1700
|
return this._value;
|
|
1653
1701
|
}
|
|
1654
1702
|
upload(buffer, filename, mime) {
|
|
@@ -1676,10 +1724,32 @@ export class Field {
|
|
|
1676
1724
|
});
|
|
1677
1725
|
}));
|
|
1678
1726
|
}
|
|
1679
|
-
download() {
|
|
1727
|
+
download(mode = DOWNLOAD_MODES.Stream) {
|
|
1680
1728
|
return new Promise((resolve, reject) => {
|
|
1681
|
-
|
|
1682
|
-
.then(
|
|
1729
|
+
this.record.layout.database.streamContainer(this, this._value)
|
|
1730
|
+
.then(stream => {
|
|
1731
|
+
if (mode === DOWNLOAD_MODES.Stream) {
|
|
1732
|
+
resolve(stream);
|
|
1733
|
+
return;
|
|
1734
|
+
}
|
|
1735
|
+
let body = [];
|
|
1736
|
+
stream.on("data", chunk => {
|
|
1737
|
+
body.push(chunk);
|
|
1738
|
+
});
|
|
1739
|
+
stream.on("error", (e) => {
|
|
1740
|
+
reject(e);
|
|
1741
|
+
});
|
|
1742
|
+
stream.on("end", () => {
|
|
1743
|
+
resolve({
|
|
1744
|
+
buffer: Buffer.concat(body),
|
|
1745
|
+
mime: stream.headers["content-type"],
|
|
1746
|
+
request: stream
|
|
1747
|
+
});
|
|
1748
|
+
});
|
|
1749
|
+
})
|
|
1750
|
+
.catch(e => {
|
|
1751
|
+
reject(e);
|
|
1752
|
+
});
|
|
1683
1753
|
});
|
|
1684
1754
|
}
|
|
1685
1755
|
}
|
|
@@ -1754,8 +1824,10 @@ export class RecordGetOperation {
|
|
|
1754
1824
|
}
|
|
1755
1825
|
}
|
|
1756
1826
|
export class RecordGetRange extends RecordGetOperation {
|
|
1757
|
-
constructor(layout) {
|
|
1827
|
+
constructor(layout, start = 0, limit = 100) {
|
|
1758
1828
|
super(layout);
|
|
1829
|
+
this.setOffset(start);
|
|
1830
|
+
this.setLimit(limit);
|
|
1759
1831
|
}
|
|
1760
1832
|
generateQueryParams(extraBody = {}) {
|
|
1761
1833
|
let params = [];
|
|
@@ -1795,7 +1867,13 @@ export class RecordGetRange extends RecordGetOperation {
|
|
|
1795
1867
|
return "";
|
|
1796
1868
|
return "?" + params.join("&");
|
|
1797
1869
|
}
|
|
1870
|
+
/**
|
|
1871
|
+
* @deprecated in favour of .fetch()
|
|
1872
|
+
*/
|
|
1798
1873
|
run(extraBody = {}) {
|
|
1874
|
+
return this.fetch(extraBody);
|
|
1875
|
+
}
|
|
1876
|
+
fetch(extraBody = {}) {
|
|
1799
1877
|
return new Promise((resolve, reject) => {
|
|
1800
1878
|
// console.log(this.#toObject())
|
|
1801
1879
|
this.layout.getLayoutMeta().then(() => {
|
|
@@ -1858,10 +1936,13 @@ export class Find extends RecordGetOperation {
|
|
|
1858
1936
|
this.queries.push(item);
|
|
1859
1937
|
return this;
|
|
1860
1938
|
}
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1939
|
+
/**
|
|
1940
|
+
* @deprecated in favour of .fetch()
|
|
1941
|
+
*/
|
|
1864
1942
|
run() {
|
|
1943
|
+
return this.fetch();
|
|
1944
|
+
}
|
|
1945
|
+
fetch() {
|
|
1865
1946
|
return new Promise((resolve, reject) => {
|
|
1866
1947
|
// console.log(this.#toObject())
|
|
1867
1948
|
this.layout.getLayoutMeta()
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -18,6 +18,8 @@ import fetch, {
|
|
|
18
18
|
import {EventEmitter} from "events";
|
|
19
19
|
// @ts-ignore
|
|
20
20
|
import * as moment from "moment"
|
|
21
|
+
import * as http from "http";
|
|
22
|
+
import * as https from "https";
|
|
21
23
|
|
|
22
24
|
// import * as btoa from "btoa";
|
|
23
25
|
interface databaseOptionsBase {
|
|
@@ -80,6 +82,11 @@ interface extraBodyOptions {
|
|
|
80
82
|
}
|
|
81
83
|
}
|
|
82
84
|
|
|
85
|
+
export enum DOWNLOAD_MODES {
|
|
86
|
+
Stream,
|
|
87
|
+
Buffer
|
|
88
|
+
}
|
|
89
|
+
|
|
83
90
|
// @ts-ignore
|
|
84
91
|
const errs = [
|
|
85
92
|
{
|
|
@@ -1141,6 +1148,11 @@ interface FMHostMetadata {
|
|
|
1141
1148
|
}
|
|
1142
1149
|
}
|
|
1143
1150
|
|
|
1151
|
+
export interface ContainerBufferResult {
|
|
1152
|
+
buffer: Buffer,
|
|
1153
|
+
mime: string,
|
|
1154
|
+
request: http.IncomingMessage
|
|
1155
|
+
}
|
|
1144
1156
|
export default class FMHost {
|
|
1145
1157
|
readonly hostname: string
|
|
1146
1158
|
readonly timezoneOffset: number
|
|
@@ -1169,7 +1181,8 @@ export default class FMHost {
|
|
|
1169
1181
|
|
|
1170
1182
|
if (data.messages[0].code === "0") {
|
|
1171
1183
|
return data.response.databases
|
|
1172
|
-
}
|
|
1184
|
+
}
|
|
1185
|
+
else {
|
|
1173
1186
|
// @ts-ignore
|
|
1174
1187
|
throw new FMError(data.messages[0].code, data.status, data)
|
|
1175
1188
|
}
|
|
@@ -1191,7 +1204,8 @@ export default class FMHost {
|
|
|
1191
1204
|
if (data.messages[0].code === "0") {
|
|
1192
1205
|
this.metadata = data.response
|
|
1193
1206
|
return data.response
|
|
1194
|
-
}
|
|
1207
|
+
}
|
|
1208
|
+
else {
|
|
1195
1209
|
// @ts-ignore
|
|
1196
1210
|
throw new FMError(data.messages[0].code, data.status, data)
|
|
1197
1211
|
}
|
|
@@ -1202,6 +1216,7 @@ export class Database extends EventEmitter {
|
|
|
1202
1216
|
private _token: any;
|
|
1203
1217
|
readonly host: FMHost;
|
|
1204
1218
|
private connection_details: databaseOptionsWithExternalSources
|
|
1219
|
+
private cookies: { [key: string]: string } = {}
|
|
1205
1220
|
readonly name: string;
|
|
1206
1221
|
|
|
1207
1222
|
constructor(host: FMHost, conn: databaseOptionsWithExternalSources) {
|
|
@@ -1219,7 +1234,8 @@ export class Database extends EventEmitter {
|
|
|
1219
1234
|
username: _data.username,
|
|
1220
1235
|
password: _data.password
|
|
1221
1236
|
}
|
|
1222
|
-
}
|
|
1237
|
+
}
|
|
1238
|
+
else {
|
|
1223
1239
|
throw "Not yet supported login method"
|
|
1224
1240
|
}
|
|
1225
1241
|
}
|
|
@@ -1254,7 +1270,8 @@ export class Database extends EventEmitter {
|
|
|
1254
1270
|
if (this.connection_details.credentials.method === "token") {
|
|
1255
1271
|
this._token = (<loginOptionsToken>this.connection_details.credentials).token
|
|
1256
1272
|
resolve(this.token)
|
|
1257
|
-
}
|
|
1273
|
+
}
|
|
1274
|
+
else {
|
|
1258
1275
|
fetch(`${this.endpoint}/sessions`, {
|
|
1259
1276
|
hostname: this.host.hostname,
|
|
1260
1277
|
port: 443,
|
|
@@ -1271,7 +1288,8 @@ export class Database extends EventEmitter {
|
|
|
1271
1288
|
if (res.status === 200) {
|
|
1272
1289
|
this._token = res.headers.get('x-fm-data-access-token')
|
|
1273
1290
|
resolve(this._token)
|
|
1274
|
-
}
|
|
1291
|
+
}
|
|
1292
|
+
else {
|
|
1275
1293
|
reject(new FMError(_res.messages[0].code, _res.status, res))
|
|
1276
1294
|
}
|
|
1277
1295
|
})
|
|
@@ -1297,6 +1315,12 @@ export class Database extends EventEmitter {
|
|
|
1297
1315
|
options.rejectUnauthorized = this.host.verify
|
|
1298
1316
|
|
|
1299
1317
|
let _fetch = await fetch(url, options)
|
|
1318
|
+
if (_fetch.headers.get('set-cookie')) {
|
|
1319
|
+
for (let cookie of _fetch.headers.get('set-cookie')) {
|
|
1320
|
+
let cookie_split = cookie.split("=")
|
|
1321
|
+
this.cookies[cookie_split[0]] = cookie_split[1]
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1300
1324
|
let data = await _fetch.json() as fileMakerResponse
|
|
1301
1325
|
// console.log(data.messages[0])
|
|
1302
1326
|
if (data.messages[0].code == 952 && autoRelogin) {
|
|
@@ -1321,7 +1345,8 @@ export class Database extends EventEmitter {
|
|
|
1321
1345
|
// console.log(res)
|
|
1322
1346
|
if (res.messages[0].code === "0") {
|
|
1323
1347
|
resolve()
|
|
1324
|
-
}
|
|
1348
|
+
}
|
|
1349
|
+
else {
|
|
1325
1350
|
reject(
|
|
1326
1351
|
(res.messages[0].code, res.status, res))
|
|
1327
1352
|
}
|
|
@@ -1339,6 +1364,44 @@ export class Database extends EventEmitter {
|
|
|
1339
1364
|
_tokenExpired() {
|
|
1340
1365
|
this.emit("token_expired")
|
|
1341
1366
|
}
|
|
1367
|
+
|
|
1368
|
+
streamContainer(field, url): Promise<http.IncomingMessage> {
|
|
1369
|
+
return new Promise((resolve, reject) => {
|
|
1370
|
+
if (field.metadata.result !== "container") {
|
|
1371
|
+
reject("Cannot stream the field " + field.id + " as it is not a container")
|
|
1372
|
+
return
|
|
1373
|
+
}
|
|
1374
|
+
if (!url || typeof url !== "string") {
|
|
1375
|
+
reject("Container is empty, or has invalid value")
|
|
1376
|
+
return
|
|
1377
|
+
}
|
|
1378
|
+
|
|
1379
|
+
let headers = {}
|
|
1380
|
+
if (Object.keys(this.cookies).length !== 0) {
|
|
1381
|
+
headers["Cookie"] = Object.keys(this.cookies)
|
|
1382
|
+
.map(key => {
|
|
1383
|
+
return key + "=" + this.cookies[key]
|
|
1384
|
+
})
|
|
1385
|
+
.join("; ")
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
// Automatically switch between the http and https modules, based on which is needed
|
|
1389
|
+
(url.startsWith("https") ? https : http).get(url, {
|
|
1390
|
+
headers
|
|
1391
|
+
}, (res) => {
|
|
1392
|
+
// Check for the 'set-cookie' header. If it exists, remember it and strip it for better security.
|
|
1393
|
+
if (res.headers['set-cookie']) {
|
|
1394
|
+
for (let cookie of res.headers['set-cookie']) {
|
|
1395
|
+
let cookie_split = cookie.split("=")
|
|
1396
|
+
this.cookies[cookie_split[0]] = cookie_split[1]
|
|
1397
|
+
}
|
|
1398
|
+
res.headers['set-cookie'] = null
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
resolve(res)
|
|
1402
|
+
})
|
|
1403
|
+
})
|
|
1404
|
+
}
|
|
1342
1405
|
}
|
|
1343
1406
|
|
|
1344
1407
|
export class Layout {
|
|
@@ -1388,7 +1451,8 @@ export class Layout {
|
|
|
1388
1451
|
.then(res => {
|
|
1389
1452
|
if (res.messages[0].code === "0") {
|
|
1390
1453
|
resolve(res.response)
|
|
1391
|
-
}
|
|
1454
|
+
}
|
|
1455
|
+
else {
|
|
1392
1456
|
// console.log(res)
|
|
1393
1457
|
reject(new FMError(res.messages[0].code, res.status, res))
|
|
1394
1458
|
}
|
|
@@ -1454,8 +1518,8 @@ class LayourRecordManager {
|
|
|
1454
1518
|
})
|
|
1455
1519
|
}
|
|
1456
1520
|
|
|
1457
|
-
range() {
|
|
1458
|
-
return new RecordGetRange(this.layout)
|
|
1521
|
+
range(start = 0, limit = 100) {
|
|
1522
|
+
return new RecordGetRange(this.layout, start, limit)
|
|
1459
1523
|
}
|
|
1460
1524
|
|
|
1461
1525
|
find(): Find {
|
|
@@ -1511,14 +1575,16 @@ export class RecordBase extends EventEmitter {
|
|
|
1511
1575
|
_field.set(date.toDate())
|
|
1512
1576
|
_field.edited = false
|
|
1513
1577
|
|
|
1514
|
-
}
|
|
1578
|
+
}
|
|
1579
|
+
else if (_field.metadata.result === "time") {
|
|
1515
1580
|
// @ts-ignore
|
|
1516
1581
|
let date = moment.default(fieldData[item], this.layout.database.host.metadata.productInfo.timeFormat)
|
|
1517
1582
|
.utcOffset(this.layout.database.host.timezoneOffset, true)
|
|
1518
1583
|
.local()
|
|
1519
1584
|
_field.set(date.toDate())
|
|
1520
1585
|
_field.edited = false
|
|
1521
|
-
}
|
|
1586
|
+
}
|
|
1587
|
+
else if (_field.metadata.result === "date") {
|
|
1522
1588
|
// @ts-ignore
|
|
1523
1589
|
let date = moment.default(fieldData[item], this.layout.database.host.metadata.productInfo.dateFormat)
|
|
1524
1590
|
.utcOffset(this.layout.database.host.timezoneOffset, true)
|
|
@@ -1550,7 +1616,8 @@ export class RecordBase extends EventEmitter {
|
|
|
1550
1616
|
this.portalData = []
|
|
1551
1617
|
if (res.response.data[0].portalData) this.processPortalData(res.response.data[0].portalData)
|
|
1552
1618
|
resolve(this)
|
|
1553
|
-
}
|
|
1619
|
+
}
|
|
1620
|
+
else {
|
|
1554
1621
|
reject(new FMError(res.messages[0].code, res.status, res))
|
|
1555
1622
|
}
|
|
1556
1623
|
})
|
|
@@ -1580,11 +1647,13 @@ export class RecordBase extends EventEmitter {
|
|
|
1580
1647
|
.then(res => {
|
|
1581
1648
|
if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
|
|
1582
1649
|
reject(new FMError(res.response.scriptError, res.status, res))
|
|
1583
|
-
}
|
|
1650
|
+
}
|
|
1651
|
+
else if (res.messages[0].code === "0") {
|
|
1584
1652
|
this.recordId = parseInt(res.response.recordId)
|
|
1585
1653
|
this.modId = parseInt(res.response.modId)
|
|
1586
1654
|
resolve(this)
|
|
1587
|
-
}
|
|
1655
|
+
}
|
|
1656
|
+
else {
|
|
1588
1657
|
reject(new FMError(res.messages[0].code, res.status, res))
|
|
1589
1658
|
}
|
|
1590
1659
|
})
|
|
@@ -1604,11 +1673,13 @@ export class RecordBase extends EventEmitter {
|
|
|
1604
1673
|
.then(res => {
|
|
1605
1674
|
if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
|
|
1606
1675
|
reject(new FMError(res.response.scriptError, res.status, res))
|
|
1607
|
-
}
|
|
1676
|
+
}
|
|
1677
|
+
else if (res.messages[0].code === "0") {
|
|
1608
1678
|
this.modId = res.response.modId
|
|
1609
1679
|
this._onSave()
|
|
1610
1680
|
resolve(this)
|
|
1611
|
-
}
|
|
1681
|
+
}
|
|
1682
|
+
else {
|
|
1612
1683
|
reject(new FMError(res.messages[0].code, res.status, res))
|
|
1613
1684
|
}
|
|
1614
1685
|
})
|
|
@@ -1617,7 +1688,7 @@ export class RecordBase extends EventEmitter {
|
|
|
1617
1688
|
})
|
|
1618
1689
|
})
|
|
1619
1690
|
}
|
|
1620
|
-
|
|
1691
|
+
|
|
1621
1692
|
_onSave() {
|
|
1622
1693
|
this.emit("saved")
|
|
1623
1694
|
for (let field of this.fields) field.edited = false
|
|
@@ -1640,10 +1711,12 @@ export class RecordBase extends EventEmitter {
|
|
|
1640
1711
|
.then(res => {
|
|
1641
1712
|
if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
|
|
1642
1713
|
reject(new FMError(res.response.scriptError, res.status, res))
|
|
1643
|
-
}
|
|
1714
|
+
}
|
|
1715
|
+
else if (res.messages[0].code === "0") {
|
|
1644
1716
|
this.emit("deleted")
|
|
1645
1717
|
resolve()
|
|
1646
|
-
}
|
|
1718
|
+
}
|
|
1719
|
+
else {
|
|
1647
1720
|
reject(new FMError(res.messages[0].code, res.status, res))
|
|
1648
1721
|
}
|
|
1649
1722
|
})
|
|
@@ -1662,13 +1735,15 @@ export class RecordBase extends EventEmitter {
|
|
|
1662
1735
|
.then(res => {
|
|
1663
1736
|
if (typeof res.response.scriptError !== "undefined" && res.response.scriptError !== '0') {
|
|
1664
1737
|
reject(new FMError(res.response.scriptError, res.status, res))
|
|
1665
|
-
}
|
|
1738
|
+
}
|
|
1739
|
+
else if (res.messages[0].code === "0") {
|
|
1666
1740
|
let data = this.toObject((a) => true, (a) => true, (a) => false, (a) => false)
|
|
1667
1741
|
let _res = new LayoutRecord(this.layout, res.response.recordId, res.response.modId, data.fieldData, data.portalData)
|
|
1668
1742
|
|
|
1669
1743
|
this.emit("duplicated")
|
|
1670
1744
|
resolve(_res)
|
|
1671
|
-
}
|
|
1745
|
+
}
|
|
1746
|
+
else {
|
|
1672
1747
|
reject(new FMError(res.messages[0].code, res.status, res))
|
|
1673
1748
|
}
|
|
1674
1749
|
})
|
|
@@ -1726,6 +1801,7 @@ export class RecordBase extends EventEmitter {
|
|
|
1726
1801
|
return obj
|
|
1727
1802
|
}
|
|
1728
1803
|
}
|
|
1804
|
+
|
|
1729
1805
|
export class LayoutRecord extends RecordBase {
|
|
1730
1806
|
portals: Portal[];
|
|
1731
1807
|
|
|
@@ -1742,7 +1818,7 @@ export class LayoutRecord extends RecordBase {
|
|
|
1742
1818
|
export class Field {
|
|
1743
1819
|
record: RecordBase;
|
|
1744
1820
|
id: number;
|
|
1745
|
-
|
|
1821
|
+
protected _value: string | number | Date;
|
|
1746
1822
|
edited: boolean;
|
|
1747
1823
|
|
|
1748
1824
|
constructor(record, id, contents) {
|
|
@@ -1803,7 +1879,8 @@ export class Field {
|
|
|
1803
1879
|
repetitionStart: 1,
|
|
1804
1880
|
repetitionEnd: 1
|
|
1805
1881
|
} as fieldMetaData
|
|
1806
|
-
}
|
|
1882
|
+
}
|
|
1883
|
+
else {
|
|
1807
1884
|
return this.record.layout.metadata.fieldMetaData.find(i => i.name === this.id) as fieldMetaData || {
|
|
1808
1885
|
name: this.id.toString(),
|
|
1809
1886
|
type: 'normal',
|
|
@@ -1824,6 +1901,7 @@ export class Field {
|
|
|
1824
1901
|
}
|
|
1825
1902
|
|
|
1826
1903
|
get value() {
|
|
1904
|
+
// if (this.metadata.result === "container") throw "Use await field.stream() to get the contents of a container field, instead of field.value"
|
|
1827
1905
|
return this._value
|
|
1828
1906
|
}
|
|
1829
1907
|
|
|
@@ -1842,7 +1920,8 @@ export class Field {
|
|
|
1842
1920
|
let _res = data as any
|
|
1843
1921
|
if (_res.messages[0].code === "0") {
|
|
1844
1922
|
resolve()
|
|
1845
|
-
}
|
|
1923
|
+
}
|
|
1924
|
+
else {
|
|
1846
1925
|
reject(new FMError(_res.messages[0].code, _res.status, data))
|
|
1847
1926
|
}
|
|
1848
1927
|
})
|
|
@@ -1852,10 +1931,35 @@ export class Field {
|
|
|
1852
1931
|
})
|
|
1853
1932
|
}
|
|
1854
1933
|
|
|
1855
|
-
download()
|
|
1934
|
+
download(mode: DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage>
|
|
1935
|
+
download(mode: DOWNLOAD_MODES.Buffer): Promise<ContainerBufferResult>
|
|
1936
|
+
download(mode: DOWNLOAD_MODES = DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage | ContainerBufferResult> {
|
|
1856
1937
|
return new Promise((resolve, reject) => {
|
|
1857
|
-
|
|
1858
|
-
.then(
|
|
1938
|
+
this.record.layout.database.streamContainer(this, this._value)
|
|
1939
|
+
.then(stream => {
|
|
1940
|
+
if (mode === DOWNLOAD_MODES.Stream) {
|
|
1941
|
+
resolve(stream)
|
|
1942
|
+
return
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
let body = []
|
|
1946
|
+
stream.on("data", chunk => {
|
|
1947
|
+
body.push(chunk)
|
|
1948
|
+
})
|
|
1949
|
+
stream.on("error", (e) => {
|
|
1950
|
+
reject(e)
|
|
1951
|
+
})
|
|
1952
|
+
stream.on("end", () => {
|
|
1953
|
+
resolve({
|
|
1954
|
+
buffer: Buffer.concat(body),
|
|
1955
|
+
mime: stream.headers["content-type"],
|
|
1956
|
+
request: stream
|
|
1957
|
+
} as ContainerBufferResult)
|
|
1958
|
+
})
|
|
1959
|
+
})
|
|
1960
|
+
.catch(e => {
|
|
1961
|
+
reject(e)
|
|
1962
|
+
})
|
|
1859
1963
|
})
|
|
1860
1964
|
}
|
|
1861
1965
|
}
|
|
@@ -1948,8 +2052,10 @@ export class RecordGetOperation {
|
|
|
1948
2052
|
}
|
|
1949
2053
|
|
|
1950
2054
|
export class RecordGetRange extends RecordGetOperation {
|
|
1951
|
-
constructor(layout) {
|
|
2055
|
+
constructor(layout, start = 0, limit = 100) {
|
|
1952
2056
|
super(layout)
|
|
2057
|
+
this.setOffset(start)
|
|
2058
|
+
this.setLimit(limit)
|
|
1953
2059
|
}
|
|
1954
2060
|
|
|
1955
2061
|
private generateQueryParams(extraBody: extraBodyOptions = {}) {
|
|
@@ -1983,7 +2089,14 @@ export class RecordGetRange extends RecordGetOperation {
|
|
|
1983
2089
|
return "?" + params.join("&")
|
|
1984
2090
|
}
|
|
1985
2091
|
|
|
2092
|
+
/**
|
|
2093
|
+
* @deprecated in favour of .fetch()
|
|
2094
|
+
*/
|
|
1986
2095
|
run(extraBody: extraBodyOptions = {}): Promise<RecordBase[]> {
|
|
2096
|
+
return this.fetch(extraBody)
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
fetch(extraBody: extraBodyOptions = {}): Promise<RecordBase[]> {
|
|
1987
2100
|
return new Promise((resolve, reject) => {
|
|
1988
2101
|
// console.log(this.#toObject())
|
|
1989
2102
|
this.layout.getLayoutMeta().then(() => {
|
|
@@ -2000,7 +2113,8 @@ export class RecordGetRange extends RecordGetOperation {
|
|
|
2000
2113
|
return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData)
|
|
2001
2114
|
})
|
|
2002
2115
|
resolve(data)
|
|
2003
|
-
}
|
|
2116
|
+
}
|
|
2117
|
+
else {
|
|
2004
2118
|
reject(new FMError(res.messages[0].code, res.status, res))
|
|
2005
2119
|
}
|
|
2006
2120
|
})
|
|
@@ -2048,11 +2162,14 @@ export class Find extends RecordGetOperation {
|
|
|
2048
2162
|
return this
|
|
2049
2163
|
}
|
|
2050
2164
|
|
|
2051
|
-
|
|
2052
|
-
|
|
2165
|
+
/**
|
|
2166
|
+
* @deprecated in favour of .fetch()
|
|
2167
|
+
*/
|
|
2168
|
+
run() {
|
|
2169
|
+
return this.fetch()
|
|
2053
2170
|
}
|
|
2054
2171
|
|
|
2055
|
-
|
|
2172
|
+
fetch(): Promise<RecordBase[]> {
|
|
2056
2173
|
return new Promise((resolve, reject) => {
|
|
2057
2174
|
// console.log(this.#toObject())
|
|
2058
2175
|
this.layout.getLayoutMeta()
|
|
@@ -2072,7 +2189,8 @@ export class Find extends RecordGetOperation {
|
|
|
2072
2189
|
return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData)
|
|
2073
2190
|
})
|
|
2074
2191
|
resolve(data)
|
|
2075
|
-
}
|
|
2192
|
+
}
|
|
2193
|
+
else {
|
|
2076
2194
|
reject(new FMError(res.messages[0].code, res.status, res))
|
|
2077
2195
|
}
|
|
2078
2196
|
})
|