@jd-data-limited/easy-fm 4.0.16 → 4.1.1
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 +16 -7
- package/src/FMError.d.ts +2 -2
- package/src/FMError.js +507 -508
- package/src/FMError.ts +510 -511
- package/src/connection/FMHost.d.ts +23 -5
- package/src/connection/FMHost.js +42 -26
- package/src/connection/FMHost.ts +63 -49
- package/src/connection/HostBase.d.ts +3 -3
- package/src/connection/HostBase.ts +5 -5
- package/src/connection/database.d.ts +53 -20
- package/src/connection/database.js +107 -90
- package/src/connection/database.ts +133 -121
- package/src/connection/databaseBase.d.ts +11 -7
- package/src/connection/databaseBase.ts +8 -8
- package/src/connection/generateAuthorizationHeaders.d.ts +1 -1
- package/src/connection/generateAuthorizationHeaders.js +10 -10
- package/src/connection/generateAuthorizationHeaders.ts +21 -21
- package/src/databaseStructure.d.ts +2 -4
- package/src/databaseStructure.ts +3 -5
- package/src/index.d.ts +17 -17
- package/src/index.js +13 -13
- package/src/index.ts +24 -24
- package/src/layouts/layout.d.ts +17 -6
- package/src/layouts/layout.js +19 -8
- package/src/layouts/layout.ts +33 -23
- package/src/layouts/layoutBase.d.ts +5 -5
- package/src/layouts/layoutBase.ts +6 -6
- package/src/layouts/layoutInterface.d.ts +3 -5
- package/src/layouts/layoutInterface.ts +4 -6
- package/src/layouts/layoutRecordManager.d.ts +29 -6
- package/src/layouts/layoutRecordManager.js +32 -9
- package/src/layouts/layoutRecordManager.ts +42 -19
- package/src/layouts/recordFieldsMap.d.ts +2 -4
- package/src/layouts/recordFieldsMap.ts +2 -4
- package/src/models/apiResults.d.ts +7 -13
- package/src/models/apiResults.ts +58 -58
- package/src/records/field.d.ts +39 -17
- package/src/records/field.js +248 -131
- package/src/records/field.ts +160 -82
- package/src/records/getOperations/recordGetOperation.d.ts +44 -24
- package/src/records/getOperations/recordGetOperation.js +88 -61
- package/src/records/getOperations/recordGetOperation.ts +128 -108
- package/src/records/layoutRecord.d.ts +28 -14
- package/src/records/layoutRecord.js +69 -60
- package/src/records/layoutRecord.ts +121 -119
- package/src/records/layoutRecordBase.d.ts +2 -2
- package/src/records/layoutRecordBase.ts +3 -3
- package/src/records/portal.d.ts +19 -5
- package/src/records/portal.js +19 -5
- package/src/records/portal.ts +28 -16
- package/src/records/portalBase.d.ts +5 -5
- package/src/records/portalBase.ts +6 -6
- package/src/records/portalRecord.d.ts +16 -8
- package/src/records/portalRecord.js +16 -6
- package/src/records/portalRecord.ts +29 -19
- package/src/records/recordBase.d.ts +18 -8
- package/src/records/recordBase.js +23 -16
- package/src/records/recordBase.ts +41 -37
- package/src/types.d.ts +23 -30
- package/src/types.js +0 -5
- package/src/types.ts +55 -64
- package/src/utils/query.d.ts +7 -7
- package/src/utils/query.js +10 -10
- package/src/utils/query.ts +19 -20
package/src/records/field.js
CHANGED
|
@@ -1,149 +1,266 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
id;
|
|
9
|
-
_value;
|
|
10
|
-
edited;
|
|
11
|
-
constructor(record, id, contents) {
|
|
12
|
-
this.parent = record;
|
|
13
|
-
this.id = id;
|
|
14
|
-
this._value = contents;
|
|
15
|
-
this.edited = false;
|
|
4
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
5
|
+
var useValue = arguments.length > 2;
|
|
6
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
7
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
16
8
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
9
|
+
return useValue ? value : void 0;
|
|
10
|
+
};
|
|
11
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
12
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
13
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
14
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
15
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
16
|
+
var _, done = false;
|
|
17
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
18
|
+
var context = {};
|
|
19
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
20
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
21
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
22
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
23
|
+
if (kind === "accessor") {
|
|
24
|
+
if (result === void 0) continue;
|
|
25
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
26
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
27
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
28
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
29
|
+
}
|
|
30
|
+
else if (_ = accept(result)) {
|
|
31
|
+
if (kind === "field") initializers.unshift(_);
|
|
32
|
+
else descriptor[key] = _;
|
|
33
|
+
}
|
|
27
34
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
36
|
+
done = true;
|
|
37
|
+
};
|
|
38
|
+
var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
|
|
39
|
+
if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
|
|
40
|
+
return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
|
|
41
|
+
};
|
|
42
|
+
import { RecordTypes } from '../types.js';
|
|
43
|
+
import { ApiFieldDisplayTypes, ApiFieldResultTypes, ApiFieldTypes } from '../models/apiResults.js';
|
|
44
|
+
import { FMError } from "../FMError.js";
|
|
45
|
+
/**
|
|
46
|
+
* A class representing a field in a record.
|
|
47
|
+
*
|
|
48
|
+
* @template T - The type of the field value.
|
|
49
|
+
*/
|
|
50
|
+
let Field = (() => {
|
|
51
|
+
let _instanceExtraInitializers = [];
|
|
52
|
+
let _private_streamAsync_decorators;
|
|
53
|
+
let _private_streamAsync_descriptor;
|
|
54
|
+
let _arrayBuffer_decorators;
|
|
55
|
+
return class Field {
|
|
56
|
+
static {
|
|
57
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
58
|
+
_private_streamAsync_decorators = [containerDownloadFunction];
|
|
59
|
+
_arrayBuffer_decorators = [containerDownloadFunction];
|
|
60
|
+
__esDecorate(this, _private_streamAsync_descriptor = { value: __setFunctionName(async function () {
|
|
61
|
+
let req = await this.parent.layout.database._apiRequestRaw(this.string, { useCookieJar: true });
|
|
62
|
+
if (!req.ok || !req.body) {
|
|
63
|
+
throw new Error(`HTTP Error: ${req.status} (${req.statusText})`);
|
|
64
|
+
}
|
|
65
|
+
return req.body;
|
|
66
|
+
}, "#streamAsync") }, _private_streamAsync_decorators, { kind: "method", name: "#streamAsync", static: false, private: true, access: { has: obj => #streamAsync in obj, get: obj => obj.#streamAsync }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
67
|
+
__esDecorate(this, null, _arrayBuffer_decorators, { kind: "method", name: "arrayBuffer", static: false, private: false, access: { has: obj => "arrayBuffer" in obj, get: obj => obj.arrayBuffer }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
68
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
47
69
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
maxRepeat: 1,
|
|
59
|
-
maxCharacters: 0,
|
|
60
|
-
notEmpty: false,
|
|
61
|
-
numeric: false,
|
|
62
|
-
timeOfDay: false,
|
|
63
|
-
repetitionStart: 1,
|
|
64
|
-
repetitionEnd: 1
|
|
65
|
-
};
|
|
70
|
+
parent = __runInitializers(this, _instanceExtraInitializers);
|
|
71
|
+
id;
|
|
72
|
+
_value;
|
|
73
|
+
edited;
|
|
74
|
+
static firstContainerDownload = null;
|
|
75
|
+
constructor(record, id, contents) {
|
|
76
|
+
this.parent = record;
|
|
77
|
+
this.id = id;
|
|
78
|
+
this._value = contents;
|
|
79
|
+
this.edited = false;
|
|
66
80
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
numeric: false,
|
|
80
|
-
timeOfDay: false,
|
|
81
|
-
repetitions: 1,
|
|
82
|
-
valueList: ""
|
|
83
|
-
};
|
|
81
|
+
/**
|
|
82
|
+
* Sets the value of the field.
|
|
83
|
+
*
|
|
84
|
+
* @param {T | null} content - The new content value to be set. Can be either the type T or null.
|
|
85
|
+
* @throws {Error} Cannot set container value using set(). Use upload() instead, if the result is a 'container'.
|
|
86
|
+
*/
|
|
87
|
+
set(content) {
|
|
88
|
+
if (this.metadata.result === 'container')
|
|
89
|
+
throw new Error('Cannot set container value using set(). Use upload() instead.');
|
|
90
|
+
else
|
|
91
|
+
this._value = content;
|
|
92
|
+
this.edited = true;
|
|
84
93
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
get metadata() {
|
|
95
|
+
if (!this.parent.layout.metadata) {
|
|
96
|
+
// Default to a regular text field
|
|
97
|
+
return {
|
|
98
|
+
name: this.id.toString(),
|
|
99
|
+
type: ApiFieldTypes.NORMAL,
|
|
100
|
+
displayType: ApiFieldDisplayTypes.EDIT_TEXT,
|
|
101
|
+
result: ApiFieldResultTypes.TEXT,
|
|
102
|
+
global: false,
|
|
103
|
+
autoEnter: true,
|
|
104
|
+
fourDigitYear: false,
|
|
105
|
+
maxRepeat: 1,
|
|
106
|
+
maxCharacters: 0,
|
|
107
|
+
notEmpty: false,
|
|
108
|
+
numeric: false,
|
|
109
|
+
timeOfDay: false,
|
|
110
|
+
repetitions: 1,
|
|
111
|
+
valueList: ''
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (this.parent.type === RecordTypes.PORTAL && this.parent.portal) {
|
|
115
|
+
return this.parent.layout.metadata.portalMetaData[this.parent.portal.name || 'portal not attached'].find(i => i.name === this.id) ??
|
|
116
|
+
{
|
|
117
|
+
name: this.id.toString(),
|
|
118
|
+
type: ApiFieldTypes.NORMAL,
|
|
119
|
+
displayType: ApiFieldDisplayTypes.EDIT_TEXT,
|
|
120
|
+
result: ApiFieldResultTypes.TEXT,
|
|
121
|
+
global: false,
|
|
122
|
+
autoEnter: true,
|
|
123
|
+
fourDigitYear: false,
|
|
124
|
+
maxRepeat: 1,
|
|
125
|
+
maxCharacters: 0,
|
|
126
|
+
notEmpty: false,
|
|
127
|
+
numeric: false,
|
|
128
|
+
timeOfDay: false,
|
|
129
|
+
repetitions: 1,
|
|
130
|
+
valueList: ''
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
return this.parent.layout.metadata.fieldMetaData.find(i => i.name === this.id) ?? {
|
|
135
|
+
name: this.id.toString(),
|
|
136
|
+
type: ApiFieldTypes.NORMAL,
|
|
137
|
+
displayType: ApiFieldDisplayTypes.EDIT_TEXT,
|
|
138
|
+
result: ApiFieldResultTypes.TEXT,
|
|
139
|
+
global: false,
|
|
140
|
+
autoEnter: true,
|
|
141
|
+
fourDigitYear: false,
|
|
142
|
+
maxRepeat: 1,
|
|
143
|
+
maxCharacters: 0,
|
|
144
|
+
notEmpty: false,
|
|
145
|
+
numeric: false,
|
|
146
|
+
timeOfDay: false,
|
|
147
|
+
repetitions: 1,
|
|
148
|
+
valueList: ''
|
|
149
|
+
};
|
|
150
|
+
}
|
|
96
151
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
get date() {
|
|
100
|
-
if (this._value instanceof Date) {
|
|
152
|
+
get value() {
|
|
153
|
+
// if (this.metadata.result === "container") throw "Use await field.stream() to get the contents of a container field, instead of field.value"
|
|
101
154
|
return this._value;
|
|
102
155
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
get number() {
|
|
106
|
-
if (typeof this._value === "number") {
|
|
107
|
-
return this._value;
|
|
156
|
+
set value(value) {
|
|
157
|
+
this._value = value;
|
|
108
158
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
throw "Cannot upload a file to the field; " + this.id + " (not a container field)";
|
|
115
|
-
let form = new FormData();
|
|
116
|
-
form.append("upload", new File([buffer], filename, { type: mime }));
|
|
117
|
-
let res = await this.parent.layout.database.apiRequestRaw(`${this.parent.endpoint}/containers/${this.id}/1`, {
|
|
118
|
-
method: "POST",
|
|
119
|
-
// @ts-ignore
|
|
120
|
-
body: form
|
|
121
|
-
});
|
|
122
|
-
if (!res.ok)
|
|
123
|
-
throw new Error(`Upload failed with HTTP error: ${res.status} (${res.statusText})`);
|
|
124
|
-
}
|
|
125
|
-
async download(mode = DownloadModes.Stream) {
|
|
126
|
-
if (this.metadata.result !== ApiFieldResultTypes.CONTAINER)
|
|
127
|
-
throw new Error("Cannot perform download() on a non-container field");
|
|
128
|
-
let stream = await this.parent.layout.database.streamURL(this.string);
|
|
129
|
-
if (mode === DownloadModes.Stream) {
|
|
130
|
-
return stream;
|
|
159
|
+
get string() {
|
|
160
|
+
if (typeof this._value === 'string') {
|
|
161
|
+
return this._value;
|
|
162
|
+
}
|
|
163
|
+
throw new Error('Field value is not a string');
|
|
131
164
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
165
|
+
/**
|
|
166
|
+
* Uploads a file to the container field.
|
|
167
|
+
*
|
|
168
|
+
* @param {Buffer} file - The file content as a buffer.
|
|
169
|
+
*
|
|
170
|
+
* @throws {Error} - Cannot upload a file to the field if it's not a container field.
|
|
171
|
+
* @throws {Error} - Upload failed with HTTP error.
|
|
172
|
+
*
|
|
173
|
+
* @returns {Promise<void>} - A promise that resolves when the file is successfully uploaded.
|
|
174
|
+
*/
|
|
175
|
+
async upload(file) {
|
|
176
|
+
if (this.metadata.result !== 'container') {
|
|
177
|
+
throw new Error('Cannot upload a file to the field; ' + this.id + ' (not a container field)');
|
|
178
|
+
}
|
|
179
|
+
const form = new FormData();
|
|
180
|
+
form.append('upload', file);
|
|
181
|
+
console.log(`ENDPOINT: ${this.parent.endpoint}/containers/${this.id}/1`);
|
|
182
|
+
const res = await this.parent.layout.database._apiRequestRaw(`${this.parent.endpoint}/containers/${this.id}/1`, {
|
|
183
|
+
method: 'POST',
|
|
184
|
+
headers: {
|
|
185
|
+
// Authorization: 'Bearer ' + this.parent.layout.database.token,
|
|
186
|
+
// 'Content-Type': 'multipart/form-data'
|
|
187
|
+
},
|
|
188
|
+
body: form
|
|
139
189
|
});
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
190
|
+
if (!res.ok) {
|
|
191
|
+
console.log("RESULT:", await res.text());
|
|
192
|
+
throw new Error(`Upload failed with HTTP error: ${res.status} (${res.statusText})`);
|
|
193
|
+
}
|
|
194
|
+
const data = await res.json();
|
|
195
|
+
if (data.messages[0].code === "0")
|
|
196
|
+
return;
|
|
197
|
+
else {
|
|
198
|
+
console.log(data);
|
|
199
|
+
throw new FMError(data.messages[0].code, res.status, res);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
get #streamAsync() { return _private_streamAsync_descriptor.value; }
|
|
203
|
+
stream() {
|
|
204
|
+
return this.#streamAsync();
|
|
205
|
+
}
|
|
206
|
+
async arrayBuffer() {
|
|
207
|
+
console.log(this.string);
|
|
208
|
+
const req = await this.parent.layout.database._apiRequestRaw(this.string, { useCookieJar: true });
|
|
209
|
+
if (!req.ok)
|
|
210
|
+
throw new Error(`HTTP Error: ${req.status} (${req.statusText})`);
|
|
211
|
+
console.log(req);
|
|
212
|
+
return await req.arrayBuffer();
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
})();
|
|
216
|
+
export { Field };
|
|
217
|
+
function containerDownloadFunction(originalMethod, context) {
|
|
218
|
+
async function replacementMethod(...args) {
|
|
219
|
+
return ContainerDownloadExecutor.processTask(() => originalMethod.call(this, ...args));
|
|
220
|
+
}
|
|
221
|
+
return replacementMethod;
|
|
222
|
+
}
|
|
223
|
+
class ContainerDownloadExecutorClass {
|
|
224
|
+
hasDownloadedFirstContainer = 0;
|
|
225
|
+
waitingFuncs = [];
|
|
226
|
+
constructor() { }
|
|
227
|
+
async processTask(task) {
|
|
228
|
+
let isFirstTask = this.hasDownloadedFirstContainer === 0;
|
|
229
|
+
if (isFirstTask) {
|
|
230
|
+
this.hasDownloadedFirstContainer = 1;
|
|
231
|
+
let res;
|
|
232
|
+
try {
|
|
233
|
+
res = await task();
|
|
234
|
+
}
|
|
235
|
+
catch (e) {
|
|
236
|
+
this.hasDownloadedFirstContainer = 0;
|
|
237
|
+
let nextTask = this.waitingFuncs.splice(0, 1)[0];
|
|
238
|
+
if (nextTask) {
|
|
239
|
+
this.processTask(nextTask.func)
|
|
240
|
+
.then(res => nextTask.done(res))
|
|
241
|
+
.catch(e => nextTask.err(e));
|
|
242
|
+
}
|
|
243
|
+
throw e;
|
|
244
|
+
}
|
|
245
|
+
this.hasDownloadedFirstContainer = 2;
|
|
246
|
+
for (let task of this.waitingFuncs) {
|
|
247
|
+
task.func()
|
|
248
|
+
.then((res) => task.done(res))
|
|
249
|
+
.catch((e) => task.err(e));
|
|
250
|
+
}
|
|
251
|
+
return res;
|
|
252
|
+
}
|
|
253
|
+
else if (this.hasDownloadedFirstContainer === 1) {
|
|
254
|
+
return new Promise((resolve, reject) => {
|
|
255
|
+
this.waitingFuncs.push({
|
|
256
|
+
func: task,
|
|
257
|
+
done: resolve,
|
|
258
|
+
err: reject
|
|
145
259
|
});
|
|
146
260
|
});
|
|
147
|
-
}
|
|
261
|
+
}
|
|
262
|
+
else
|
|
263
|
+
return await task();
|
|
148
264
|
}
|
|
149
265
|
}
|
|
266
|
+
const ContainerDownloadExecutor = new ContainerDownloadExecutorClass();
|