@jd-data-limited/easy-fm 3.2.7 → 4.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 +36 -24
- package/package.json +15 -8
- package/src/FMError.d.ts +1 -1
- package/src/FMError.js +7 -2
- package/src/FMError.ts +3 -3
- package/src/connection/FMHost.d.ts +3 -2
- package/src/connection/FMHost.js +37 -47
- package/src/connection/FMHost.ts +6 -6
- package/src/connection/HostBase.d.ts +1 -1
- package/src/connection/HostBase.js +1 -1
- package/src/connection/HostBase.ts +2 -4
- package/src/connection/database.d.ts +12 -9
- package/src/connection/database.js +93 -116
- package/src/connection/database.ts +79 -90
- package/src/connection/databaseBase.d.ts +5 -2
- package/src/connection/databaseBase.js +1 -1
- package/src/connection/databaseBase.ts +5 -4
- package/src/databaseStructure.d.ts +6 -0
- package/src/databaseStructure.js +4 -0
- package/src/databaseStructure.ts +12 -0
- package/src/index.d.ts +3 -6
- package/src/index.js +3 -5
- package/src/index.ts +4 -9
- package/src/layouts/layout.d.ts +5 -19
- package/src/layouts/layout.js +27 -69
- package/src/layouts/layout.ts +26 -65
- package/src/layouts/layoutBase.d.ts +4 -4
- package/src/layouts/layoutBase.js +1 -1
- package/src/layouts/layoutBase.ts +5 -5
- package/src/layouts/layoutInterface.d.ts +1 -1
- package/src/layouts/layoutInterface.js +1 -1
- package/src/layouts/layoutInterface.ts +2 -2
- package/src/layouts/layoutRecordManager.d.ts +5 -6
- package/src/layouts/layoutRecordManager.js +20 -39
- package/src/layouts/layoutRecordManager.ts +20 -41
- package/src/layouts/recordFieldsMap.d.ts +2 -2
- package/src/layouts/recordFieldsMap.js +1 -1
- package/src/layouts/recordFieldsMap.ts +3 -3
- package/src/models/apiResults.d.ts +103 -0
- package/src/models/apiResults.js +28 -0
- package/src/models/apiResults.ts +112 -0
- package/src/records/field.d.ts +3 -22
- package/src/records/field.js +4 -177
- package/src/records/field.ts +4 -187
- package/src/records/fieldBase.d.ts +30 -0
- package/src/records/fieldBase.js +154 -0
- package/src/records/fieldBase.ts +174 -0
- package/src/records/getOperations/recordGetOperation.d.ts +47 -11
- package/src/records/getOperations/recordGetOperation.js +144 -30
- package/src/records/getOperations/recordGetOperation.ts +172 -30
- package/src/records/layoutRecord.d.ts +8 -7
- package/src/records/layoutRecord.js +107 -153
- package/src/records/layoutRecord.ts +117 -141
- package/src/records/portal.d.ts +6 -5
- package/src/records/portal.js +4 -1
- package/src/records/portal.ts +7 -7
- package/src/records/portalBase.d.ts +5 -4
- package/src/records/portalBase.js +1 -1
- package/src/records/portalBase.ts +6 -6
- package/src/records/portalRecord.d.ts +6 -6
- package/src/records/portalRecord.js +5 -3
- package/src/records/portalRecord.ts +5 -5
- package/src/records/recordBase.d.ts +7 -12
- package/src/records/recordBase.js +12 -11
- package/src/records/recordBase.ts +10 -15
- package/src/types.d.ts +18 -19
- package/src/types.js +7 -1
- package/src/types.ts +20 -21
- package/.expo/README.md +0 -15
- package/.expo/settings.json +0 -8
- package/.idea/compiler.xml +0 -7
- package/.idea/copyright/JD_Data.xml +0 -6
- package/.idea/copyright/profiles_settings.xml +0 -7
- package/.idea/discord.xml +0 -7
- package/.idea/easy-fm.iml +0 -8
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/php.xml +0 -18
- package/.idea/vcs.xml +0 -6
- package/decs.d.ts +0 -7
- package/dist/index.min.js +0 -2
- package/dist/index.min.js.LICENSE.txt +0 -3
- package/docs/classes/FileMakerConnection.md +0 -86
- package/docs/classes/layout.md +0 -0
- package/examples/test.js +0 -7
- package/fmErrors.json +0 -1010
- package/img.png +0 -0
- package/src/records/getOperations/find.d.ts +0 -15
- package/src/records/getOperations/find.js +0 -90
- package/src/records/getOperations/find.ts +0 -88
- package/src/records/getOperations/recordGetRange.d.ts +0 -13
- package/src/records/getOperations/recordGetRange.js +0 -95
- package/src/records/getOperations/recordGetRange.ts +0 -84
- package/src/records/portalRecordBase.d.ts +0 -4
- package/src/records/portalRecordBase.js +0 -6
- package/test.d.ts +0 -2
- package/test.js +0 -30
- package/test.ts +0 -33
- package/test2.d.ts +0 -1
- package/test2.js +0 -15
- package/tsconfig.json +0 -16
- package/webpack.config.cjs +0 -20
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023. See LICENSE file for more information
|
|
3
|
+
*/
|
|
4
|
+
export var ApiFieldTypes;
|
|
5
|
+
(function (ApiFieldTypes) {
|
|
6
|
+
ApiFieldTypes["NORMAL"] = "normal";
|
|
7
|
+
ApiFieldTypes["CALCULATION"] = "calculation";
|
|
8
|
+
ApiFieldTypes["SUMMARY"] = "summary";
|
|
9
|
+
})(ApiFieldTypes || (ApiFieldTypes = {}));
|
|
10
|
+
export var ApiFieldDisplayTypes;
|
|
11
|
+
(function (ApiFieldDisplayTypes) {
|
|
12
|
+
ApiFieldDisplayTypes["EDIT_TEXT"] = "editText";
|
|
13
|
+
ApiFieldDisplayTypes["POPUP_LIST"] = "popupList";
|
|
14
|
+
ApiFieldDisplayTypes["CHECKBOX"] = "checkBox";
|
|
15
|
+
ApiFieldDisplayTypes["RADIO_BUTTONS"] = "radioButtons";
|
|
16
|
+
ApiFieldDisplayTypes["SELECTION_LIST"] = "selectionList";
|
|
17
|
+
ApiFieldDisplayTypes["CALENDAR"] = "calendar";
|
|
18
|
+
ApiFieldDisplayTypes["SECURE_TEXT"] = "secureText";
|
|
19
|
+
})(ApiFieldDisplayTypes || (ApiFieldDisplayTypes = {}));
|
|
20
|
+
export var ApiFieldResultTypes;
|
|
21
|
+
(function (ApiFieldResultTypes) {
|
|
22
|
+
ApiFieldResultTypes["TEXT"] = "text";
|
|
23
|
+
ApiFieldResultTypes["NUMBER"] = "number";
|
|
24
|
+
ApiFieldResultTypes["DATE"] = "date";
|
|
25
|
+
ApiFieldResultTypes["TIME"] = "time";
|
|
26
|
+
ApiFieldResultTypes["TIMESTAMP"] = "timeStamp";
|
|
27
|
+
ApiFieldResultTypes["CONTAINER"] = "container";
|
|
28
|
+
})(ApiFieldResultTypes || (ApiFieldResultTypes = {}));
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023. See LICENSE file for more information
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as stream from "stream";
|
|
6
|
+
|
|
7
|
+
export enum ApiFieldTypes {
|
|
8
|
+
NORMAL = "normal",
|
|
9
|
+
CALCULATION = "calculation",
|
|
10
|
+
SUMMARY = "summary"
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export enum ApiFieldDisplayTypes {
|
|
14
|
+
EDIT_TEXT = "editText",
|
|
15
|
+
POPUP_LIST = "popupList",
|
|
16
|
+
CHECKBOX = "checkBox",
|
|
17
|
+
RADIO_BUTTONS = "radioButtons",
|
|
18
|
+
SELECTION_LIST = "selectionList",
|
|
19
|
+
CALENDAR = "calendar",
|
|
20
|
+
SECURE_TEXT = "secureText"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export enum ApiFieldResultTypes {
|
|
24
|
+
TEXT = "text",
|
|
25
|
+
NUMBER = "number",
|
|
26
|
+
DATE = "date",
|
|
27
|
+
TIME = "time",
|
|
28
|
+
TIMESTAMP = "timeStamp",
|
|
29
|
+
CONTAINER = "container"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface ApiMessage {
|
|
33
|
+
code: string,
|
|
34
|
+
message: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ApiResults<T = unknown> {
|
|
38
|
+
response?: null | T & {scriptError? : string},
|
|
39
|
+
messages: ApiMessage[],
|
|
40
|
+
httpStatus: number
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface ApiLayout {
|
|
44
|
+
name: string,
|
|
45
|
+
isFolder: boolean,
|
|
46
|
+
folderLayoutNames: string[]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export interface ApiLayoutMetadata {
|
|
50
|
+
fieldMetaData: ApiFieldMetadata[],
|
|
51
|
+
portalMetaData: {[key: string]: ApiFieldMetadata[]},
|
|
52
|
+
valueLists: ApiValueList[]
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface ApiFieldMetadata {
|
|
56
|
+
name: string,
|
|
57
|
+
type: ApiFieldTypes,
|
|
58
|
+
displayType: ApiFieldDisplayTypes,
|
|
59
|
+
result: ApiFieldResultTypes,
|
|
60
|
+
global: boolean,
|
|
61
|
+
autoEnter: boolean,
|
|
62
|
+
fourDigitYear: boolean,
|
|
63
|
+
maxRepeat: number,
|
|
64
|
+
maxCharacters: number,
|
|
65
|
+
notEmpty: boolean,
|
|
66
|
+
numeric: boolean,
|
|
67
|
+
repetitions: number,
|
|
68
|
+
timeOfDay: boolean,
|
|
69
|
+
valueList: string
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export interface ApiValueList {
|
|
73
|
+
name: string,
|
|
74
|
+
type: string,
|
|
75
|
+
values: {value: string, displayName: string}[]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export interface ApiScriptResult {
|
|
79
|
+
scriptError: string,
|
|
80
|
+
scriptResult?: string
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface ApiRecordResponseObj {
|
|
84
|
+
data: ApiRowDataDef[],
|
|
85
|
+
dataInfo: ApiResultSetObj
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface ApiFieldData {[key: string]: string}
|
|
89
|
+
|
|
90
|
+
export interface ApiPortalData {[key: string]: ApiFieldData[]}
|
|
91
|
+
|
|
92
|
+
export interface ApiResultSetObj {
|
|
93
|
+
database: string,
|
|
94
|
+
layout: string,
|
|
95
|
+
table: string,
|
|
96
|
+
totalRecordCount: number,
|
|
97
|
+
foundCount: number,
|
|
98
|
+
returnedCount: number
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface ApiRowDataDef {
|
|
102
|
+
fieldData: ApiFieldData,
|
|
103
|
+
portalData: ApiPortalData,
|
|
104
|
+
modId: string,
|
|
105
|
+
recordId: string,
|
|
106
|
+
portalDataInfo: {
|
|
107
|
+
database: string,
|
|
108
|
+
table: string,
|
|
109
|
+
foundCount: number,
|
|
110
|
+
returnedCount: number
|
|
111
|
+
}[]
|
|
112
|
+
}
|
package/src/records/field.d.ts
CHANGED
|
@@ -1,24 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import * as http from "http";
|
|
5
|
-
import { ContainerBufferResult, DOWNLOAD_MODES, FieldMetaData } from "../types.js";
|
|
6
|
-
export type FieldValue = string | number | Date | Container;
|
|
7
|
-
export type Container = null;
|
|
8
|
-
export declare class Field<T extends FieldValue> {
|
|
1
|
+
import { RecordBase } from "./recordBase";
|
|
2
|
+
import { FieldBase, FieldValue } from "./fieldBase";
|
|
3
|
+
export declare class Field<T extends FieldValue> extends FieldBase<T> {
|
|
9
4
|
record: RecordBase<any>;
|
|
10
|
-
id: string;
|
|
11
|
-
protected _value: T;
|
|
12
|
-
edited: boolean;
|
|
13
|
-
constructor(record: any, id: any, contents: any);
|
|
14
|
-
set(content: string | number | Date | undefined | null): void;
|
|
15
|
-
get metadata(): FieldMetaData;
|
|
16
|
-
get value(): T;
|
|
17
|
-
set value(value: T);
|
|
18
|
-
get string(): string;
|
|
19
|
-
get date(): Date;
|
|
20
|
-
get number(): number;
|
|
21
|
-
upload(buffer: Buffer, filename: string, mime: string): Promise<void>;
|
|
22
|
-
download(mode: DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage>;
|
|
23
|
-
download(mode: DOWNLOAD_MODES.Buffer): Promise<ContainerBufferResult>;
|
|
24
5
|
}
|
package/src/records/field.js
CHANGED
|
@@ -1,180 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) 2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
8
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
9
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
10
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
11
|
-
});
|
|
12
|
-
};
|
|
13
|
-
import { RecordTypes } from "./recordBase.js";
|
|
14
|
-
import fetch, { File, FormData } from "node-fetch";
|
|
15
|
-
import { DOWNLOAD_MODES } from "../types.js";
|
|
16
|
-
import { FMError } from "../FMError.js";
|
|
17
|
-
export class Field {
|
|
18
|
-
constructor(record, id, contents) {
|
|
19
|
-
this.record = record;
|
|
20
|
-
this.id = id;
|
|
21
|
-
this._value = contents;
|
|
22
|
-
this.edited = false;
|
|
23
|
-
}
|
|
24
|
-
set(content) {
|
|
25
|
-
if (this.metadata.result === "container")
|
|
26
|
-
throw "Cannot set container value using set(). Use upload() instead.";
|
|
27
|
-
if ((this.metadata.result === "timeStamp" ||
|
|
28
|
-
this.metadata.result === "date" ||
|
|
29
|
-
this.metadata.result === "time")
|
|
30
|
-
&& !(content instanceof Date) && !!content) {
|
|
31
|
-
throw "Value was not an instance of Date: " + content;
|
|
32
|
-
}
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
if (!content)
|
|
35
|
-
this._value = "";
|
|
36
|
-
// @ts-ignore
|
|
37
|
-
else
|
|
38
|
-
this._value = content;
|
|
39
|
-
this.edited = true;
|
|
40
|
-
}
|
|
41
|
-
get metadata() {
|
|
42
|
-
if (!this.record.layout.metadata) {
|
|
43
|
-
// Default to a regular text field
|
|
44
|
-
return {
|
|
45
|
-
name: this.id.toString(),
|
|
46
|
-
type: 'normal',
|
|
47
|
-
displayType: 'editText',
|
|
48
|
-
result: 'text',
|
|
49
|
-
global: false,
|
|
50
|
-
autoEnter: true,
|
|
51
|
-
fourDigitYear: false,
|
|
52
|
-
maxRepeat: 1,
|
|
53
|
-
maxCharacters: 0,
|
|
54
|
-
notEmpty: false,
|
|
55
|
-
numeric: false,
|
|
56
|
-
timeOfDay: false,
|
|
57
|
-
repetitionStart: 1,
|
|
58
|
-
repetitionEnd: 1
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
if (this.record.type === RecordTypes.PORTAL) {
|
|
62
|
-
// @ts-ignore
|
|
63
|
-
return this.record.layout.metadata.portalMetaData[this.record.portal.name || "portal not attached"].find(i => i.name === this.id) || {
|
|
64
|
-
name: this.id.toString(),
|
|
65
|
-
type: 'normal',
|
|
66
|
-
displayType: 'editText',
|
|
67
|
-
result: 'text',
|
|
68
|
-
global: false,
|
|
69
|
-
autoEnter: true,
|
|
70
|
-
fourDigitYear: false,
|
|
71
|
-
maxRepeat: 1,
|
|
72
|
-
maxCharacters: 0,
|
|
73
|
-
notEmpty: false,
|
|
74
|
-
numeric: false,
|
|
75
|
-
timeOfDay: false,
|
|
76
|
-
repetitionStart: 1,
|
|
77
|
-
repetitionEnd: 1
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
return this.record.layout.metadata.fieldMetaData.find(i => i.name === this.id) || {
|
|
82
|
-
name: this.id.toString(),
|
|
83
|
-
type: 'normal',
|
|
84
|
-
displayType: 'editText',
|
|
85
|
-
result: 'text',
|
|
86
|
-
global: false,
|
|
87
|
-
autoEnter: true,
|
|
88
|
-
fourDigitYear: false,
|
|
89
|
-
maxRepeat: 1,
|
|
90
|
-
maxCharacters: 0,
|
|
91
|
-
notEmpty: false,
|
|
92
|
-
numeric: false,
|
|
93
|
-
timeOfDay: false,
|
|
94
|
-
repetitionStart: 1,
|
|
95
|
-
repetitionEnd: 1
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
get value() {
|
|
100
|
-
// if (this.metadata.result === "container") throw "Use await field.stream() to get the contents of a container field, instead of field.value"
|
|
101
|
-
return this._value;
|
|
102
|
-
}
|
|
103
|
-
set value(value) {
|
|
104
|
-
this._value = value;
|
|
105
|
-
}
|
|
106
|
-
get string() {
|
|
107
|
-
if (typeof this._value === "string") {
|
|
108
|
-
return this._value;
|
|
109
|
-
}
|
|
110
|
-
throw "Field value is not a string";
|
|
111
|
-
}
|
|
112
|
-
get date() {
|
|
113
|
-
if (this._value instanceof Date) {
|
|
114
|
-
return this._value;
|
|
115
|
-
}
|
|
116
|
-
throw "Field value is not a date";
|
|
117
|
-
}
|
|
118
|
-
get number() {
|
|
119
|
-
if (typeof this._value === "number") {
|
|
120
|
-
return this._value;
|
|
121
|
-
}
|
|
122
|
-
throw "Field value is not a number";
|
|
123
|
-
}
|
|
124
|
-
upload(buffer, filename, mime) {
|
|
125
|
-
let trace = new Error();
|
|
126
|
-
if (this.metadata.result !== "container")
|
|
127
|
-
throw "Cannot upload a file to the field; " + this.id + " (not a container field)";
|
|
128
|
-
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
129
|
-
let form = new FormData();
|
|
130
|
-
form.append("upload", new File([buffer], filename, { type: mime }));
|
|
131
|
-
let _fetch = yield fetch(`${this.record.endpoint}/containers/${this.id}/1`, {
|
|
132
|
-
method: "POST",
|
|
133
|
-
// @ts-ignore
|
|
134
|
-
headers: { "Authorization": "Bearer " + this.record.layout.database.token },
|
|
135
|
-
body: form
|
|
136
|
-
}).then(res => res.json())
|
|
137
|
-
.then(data => {
|
|
138
|
-
let _res = data;
|
|
139
|
-
if (_res.messages[0].code === "0") {
|
|
140
|
-
resolve();
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
reject(new FMError(_res.messages[0].code, _res.status, data, trace));
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
.catch(e => {
|
|
147
|
-
reject(e);
|
|
148
|
-
});
|
|
149
|
-
}));
|
|
150
|
-
}
|
|
151
|
-
download(mode = DOWNLOAD_MODES.Stream) {
|
|
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
|
-
});
|
|
178
|
-
});
|
|
179
|
-
}
|
|
4
|
+
import { FieldBase } from "./fieldBase";
|
|
5
|
+
export class Field extends FieldBase {
|
|
6
|
+
record;
|
|
180
7
|
}
|
package/src/records/field.ts
CHANGED
|
@@ -1,193 +1,10 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c)
|
|
2
|
+
* Copyright (c) 2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {RecordBase
|
|
6
|
-
import
|
|
7
|
-
import * as http from "http";
|
|
8
|
-
import {ContainerBufferResult, DOWNLOAD_MODES, FieldMetaData} from "../types.js";
|
|
9
|
-
import {FMError} from "../FMError.js";
|
|
5
|
+
import {RecordBase} from "./recordBase";
|
|
6
|
+
import {FieldBase, FieldValue} from "./fieldBase";
|
|
10
7
|
|
|
11
|
-
export
|
|
12
|
-
export type Container = null
|
|
13
|
-
|
|
14
|
-
export class Field<T extends FieldValue> {
|
|
8
|
+
export class Field<T extends FieldValue> extends FieldBase<T> {
|
|
15
9
|
record: RecordBase<any>;
|
|
16
|
-
id: string;
|
|
17
|
-
protected _value: T;
|
|
18
|
-
edited: boolean;
|
|
19
|
-
|
|
20
|
-
constructor(record, id, contents) {
|
|
21
|
-
this.record = record
|
|
22
|
-
this.id = id
|
|
23
|
-
this._value = contents
|
|
24
|
-
this.edited = false
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
set(content: string | number | Date | undefined | null) {
|
|
28
|
-
if (this.metadata.result === "container") throw "Cannot set container value using set(). Use upload() instead."
|
|
29
|
-
if (
|
|
30
|
-
(this.metadata.result === "timeStamp" ||
|
|
31
|
-
this.metadata.result === "date" ||
|
|
32
|
-
this.metadata.result === "time")
|
|
33
|
-
&& !(content instanceof Date) && !!content
|
|
34
|
-
) {
|
|
35
|
-
throw "Value was not an instance of Date: " + content
|
|
36
|
-
}
|
|
37
|
-
// @ts-ignore
|
|
38
|
-
if (!content) this._value = ""
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
else this._value = content
|
|
41
|
-
this.edited = true
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
get metadata(): FieldMetaData {
|
|
45
|
-
if (!this.record.layout.metadata) {
|
|
46
|
-
// Default to a regular text field
|
|
47
|
-
return {
|
|
48
|
-
name: this.id.toString(),
|
|
49
|
-
type: 'normal',
|
|
50
|
-
displayType: 'editText',
|
|
51
|
-
result: 'text',
|
|
52
|
-
global: false,
|
|
53
|
-
autoEnter: true,
|
|
54
|
-
fourDigitYear: false,
|
|
55
|
-
maxRepeat: 1,
|
|
56
|
-
maxCharacters: 0,
|
|
57
|
-
notEmpty: false,
|
|
58
|
-
numeric: false,
|
|
59
|
-
timeOfDay: false,
|
|
60
|
-
repetitionStart: 1,
|
|
61
|
-
repetitionEnd: 1
|
|
62
|
-
} as FieldMetaData
|
|
63
|
-
}
|
|
64
|
-
if (this.record.type === RecordTypes.PORTAL) {
|
|
65
|
-
// @ts-ignore
|
|
66
|
-
return this.record.layout.metadata.portalMetaData[this.record.portal.name || "portal not attached"].find(i => i.name === this.id) as FieldMetaData || {
|
|
67
|
-
name: this.id.toString(),
|
|
68
|
-
type: 'normal',
|
|
69
|
-
displayType: 'editText',
|
|
70
|
-
result: 'text',
|
|
71
|
-
global: false,
|
|
72
|
-
autoEnter: true,
|
|
73
|
-
fourDigitYear: false,
|
|
74
|
-
maxRepeat: 1,
|
|
75
|
-
maxCharacters: 0,
|
|
76
|
-
notEmpty: false,
|
|
77
|
-
numeric: false,
|
|
78
|
-
timeOfDay: false,
|
|
79
|
-
repetitionStart: 1,
|
|
80
|
-
repetitionEnd: 1
|
|
81
|
-
} as FieldMetaData
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
return this.record.layout.metadata.fieldMetaData.find(i => i.name === this.id) as FieldMetaData || {
|
|
85
|
-
name: this.id.toString(),
|
|
86
|
-
type: 'normal',
|
|
87
|
-
displayType: 'editText',
|
|
88
|
-
result: 'text',
|
|
89
|
-
global: false,
|
|
90
|
-
autoEnter: true,
|
|
91
|
-
fourDigitYear: false,
|
|
92
|
-
maxRepeat: 1,
|
|
93
|
-
maxCharacters: 0,
|
|
94
|
-
notEmpty: false,
|
|
95
|
-
numeric: false,
|
|
96
|
-
timeOfDay: false,
|
|
97
|
-
repetitionStart: 1,
|
|
98
|
-
repetitionEnd: 1
|
|
99
|
-
} as FieldMetaData
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
get value(): T {
|
|
104
|
-
// if (this.metadata.result === "container") throw "Use await field.stream() to get the contents of a container field, instead of field.value"
|
|
105
|
-
return this._value
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
set value(value: T) {
|
|
109
|
-
this._value = value
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
get string(): string {
|
|
113
|
-
if (typeof this._value === "string") {
|
|
114
|
-
return this._value
|
|
115
|
-
}
|
|
116
|
-
throw "Field value is not a string"
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
get date(): Date {
|
|
120
|
-
if (this._value instanceof Date) {
|
|
121
|
-
return this._value
|
|
122
|
-
}
|
|
123
|
-
throw "Field value is not a date"
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
get number(): number {
|
|
127
|
-
if (typeof this._value === "number") {
|
|
128
|
-
return this._value
|
|
129
|
-
}
|
|
130
|
-
throw "Field value is not a number"
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
upload(buffer: Buffer, filename: string, mime: string): Promise<void> {
|
|
134
|
-
let trace = new Error()
|
|
135
|
-
if (this.metadata.result !== "container") throw "Cannot upload a file to the field; " + this.id + " (not a container field)"
|
|
136
|
-
return new Promise(async (resolve, reject) => {
|
|
137
|
-
let form = new FormData()
|
|
138
|
-
form.append("upload", new File([buffer], filename, {type: mime}))
|
|
139
|
-
|
|
140
|
-
let _fetch = await fetch(`${this.record.endpoint}/containers/${this.id}/1`, {
|
|
141
|
-
method: "POST",
|
|
142
|
-
// @ts-ignore
|
|
143
|
-
headers: {"Authorization": "Bearer " + this.record.layout.database.token},
|
|
144
|
-
body: form
|
|
145
|
-
}).then(res => res.json())
|
|
146
|
-
.then(data => {
|
|
147
|
-
let _res = data as any
|
|
148
|
-
if (_res.messages[0].code === "0") {
|
|
149
|
-
resolve()
|
|
150
|
-
}
|
|
151
|
-
else {
|
|
152
|
-
reject(new FMError(_res.messages[0].code, _res.status, data, trace))
|
|
153
|
-
}
|
|
154
|
-
})
|
|
155
|
-
.catch(e => {
|
|
156
|
-
reject(e)
|
|
157
|
-
})
|
|
158
|
-
})
|
|
159
|
-
}
|
|
160
|
-
|
|
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
|
-
}
|
|
172
|
-
|
|
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
|
-
})
|
|
192
|
-
}
|
|
193
10
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
+
import * as http from "http";
|
|
4
|
+
import { ContainerBufferResult, DOWNLOAD_MODES, RecordTypes } from "../types.js";
|
|
5
|
+
import { ApiFieldMetadata } from "../models/apiResults.js";
|
|
6
|
+
import { LayoutBase } from "../layouts/layoutBase.js";
|
|
7
|
+
export type FieldValue = string | number | Date | Container;
|
|
8
|
+
export type Container = null;
|
|
9
|
+
export type Parentable = {
|
|
10
|
+
layout: LayoutBase;
|
|
11
|
+
type: RecordTypes;
|
|
12
|
+
endpoint: string;
|
|
13
|
+
};
|
|
14
|
+
export declare class FieldBase<T extends FieldValue> {
|
|
15
|
+
parent: Parentable;
|
|
16
|
+
id: string;
|
|
17
|
+
protected _value: T;
|
|
18
|
+
edited: boolean;
|
|
19
|
+
constructor(record: Parentable, id: string, contents: T);
|
|
20
|
+
set(content: string | number | Date | undefined | null): void;
|
|
21
|
+
get metadata(): ApiFieldMetadata;
|
|
22
|
+
get value(): T;
|
|
23
|
+
set value(value: T);
|
|
24
|
+
get string(): string;
|
|
25
|
+
get date(): Date;
|
|
26
|
+
get number(): number;
|
|
27
|
+
upload(buffer: Buffer, filename: string, mime: string): Promise<void>;
|
|
28
|
+
download(mode: DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage>;
|
|
29
|
+
download(mode: DOWNLOAD_MODES.Buffer): Promise<ContainerBufferResult>;
|
|
30
|
+
}
|