@jd-data-limited/easy-fm 3.2.6 → 3.2.8
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 +10 -6
- package/src/FMError.d.ts +1 -1
- package/src/FMError.js +5 -0
- package/src/FMError.ts +1 -1
- package/src/connection/FMHost.d.ts +1 -1
- package/src/connection/FMHost.js +36 -45
- package/src/connection/FMHost.ts +3 -3
- package/src/connection/database.d.ts +5 -3
- package/src/connection/database.js +90 -112
- package/src/connection/database.ts +70 -82
- package/src/connection/databaseBase.d.ts +4 -1
- package/src/connection/databaseBase.ts +4 -1
- package/src/layouts/layout.d.ts +3 -3
- package/src/layouts/layout.js +26 -50
- package/src/layouts/layout.ts +22 -39
- package/src/layouts/layoutBase.d.ts +2 -2
- package/src/layouts/layoutBase.ts +2 -1
- package/src/layouts/layoutRecordManager.d.ts +1 -1
- package/src/layouts/layoutRecordManager.js +16 -31
- package/src/layouts/layoutRecordManager.ts +14 -30
- 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 -2
- package/src/records/field.js +44 -68
- package/src/records/field.ts +46 -64
- package/src/records/getOperations/find.js +18 -38
- package/src/records/getOperations/find.ts +17 -28
- package/src/records/getOperations/recordGetOperation.js +7 -4
- package/src/records/getOperations/recordGetOperation.ts +1 -1
- package/src/records/getOperations/recordGetRange.js +16 -34
- package/src/records/getOperations/recordGetRange.ts +17 -24
- package/src/records/layoutRecord.js +103 -151
- package/src/records/layoutRecord.ts +101 -133
- package/src/records/portal.js +3 -0
- package/src/records/portalRecord.js +2 -1
- package/src/records/recordBase.js +6 -1
- package/src/types.d.ts +0 -4
- package/src/types.ts +1 -7
- 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/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,103 @@
|
|
|
1
|
+
export declare enum ApiFieldTypes {
|
|
2
|
+
NORMAL = "normal",
|
|
3
|
+
CALCULATION = "calculation",
|
|
4
|
+
SUMMARY = "summary"
|
|
5
|
+
}
|
|
6
|
+
export declare enum ApiFieldDisplayTypes {
|
|
7
|
+
EDIT_TEXT = "editText",
|
|
8
|
+
POPUP_LIST = "popupList",
|
|
9
|
+
CHECKBOX = "checkBox",
|
|
10
|
+
RADIO_BUTTONS = "radioButtons",
|
|
11
|
+
SELECTION_LIST = "selectionList",
|
|
12
|
+
CALENDAR = "calendar",
|
|
13
|
+
SECURE_TEXT = "secureText"
|
|
14
|
+
}
|
|
15
|
+
export declare enum ApiFieldResultTypes {
|
|
16
|
+
TEXT = "text",
|
|
17
|
+
NUMBER = "number",
|
|
18
|
+
DATE = "date",
|
|
19
|
+
TIME = "time",
|
|
20
|
+
TIMESTAMP = "timeStamp",
|
|
21
|
+
CONTAINER = "container"
|
|
22
|
+
}
|
|
23
|
+
export interface ApiMessage {
|
|
24
|
+
code: string;
|
|
25
|
+
message: string;
|
|
26
|
+
}
|
|
27
|
+
export interface ApiResults<T = unknown> {
|
|
28
|
+
response?: null | T & {
|
|
29
|
+
scriptError?: string;
|
|
30
|
+
};
|
|
31
|
+
messages: ApiMessage[];
|
|
32
|
+
httpStatus: number;
|
|
33
|
+
}
|
|
34
|
+
export interface ApiLayout {
|
|
35
|
+
name: string;
|
|
36
|
+
isFolder: boolean;
|
|
37
|
+
folderLayoutNames: string[];
|
|
38
|
+
}
|
|
39
|
+
export interface ApiLayoutMetadata {
|
|
40
|
+
fieldMetaData: ApiFieldMetadata[];
|
|
41
|
+
portalMetaData: {
|
|
42
|
+
[key: string]: ApiFieldMetadata[];
|
|
43
|
+
};
|
|
44
|
+
valueLists: ApiValueList[];
|
|
45
|
+
}
|
|
46
|
+
export interface ApiFieldMetadata {
|
|
47
|
+
name: string;
|
|
48
|
+
type: ApiFieldTypes;
|
|
49
|
+
displayType: ApiFieldDisplayTypes;
|
|
50
|
+
result: ApiFieldResultTypes;
|
|
51
|
+
global: boolean;
|
|
52
|
+
autoEnter: boolean;
|
|
53
|
+
fourDigitYear: boolean;
|
|
54
|
+
maxRepeat: number;
|
|
55
|
+
maxCharacters: number;
|
|
56
|
+
notEmpty: boolean;
|
|
57
|
+
numeric: boolean;
|
|
58
|
+
repetitions: number;
|
|
59
|
+
timeOfDay: boolean;
|
|
60
|
+
valueList: string;
|
|
61
|
+
}
|
|
62
|
+
export interface ApiValueList {
|
|
63
|
+
name: string;
|
|
64
|
+
type: string;
|
|
65
|
+
values: {
|
|
66
|
+
value: string;
|
|
67
|
+
displayName: string;
|
|
68
|
+
}[];
|
|
69
|
+
}
|
|
70
|
+
export interface ApiScriptResult {
|
|
71
|
+
scriptError: string;
|
|
72
|
+
scriptResult?: string;
|
|
73
|
+
}
|
|
74
|
+
export interface ApiRecordResponseObj {
|
|
75
|
+
data: ApiRowDataDef[];
|
|
76
|
+
dataInfo: ApiResultSetObj;
|
|
77
|
+
}
|
|
78
|
+
export interface ApiFieldData {
|
|
79
|
+
[key: string]: string;
|
|
80
|
+
}
|
|
81
|
+
export interface ApiPortalData {
|
|
82
|
+
[key: string]: ApiFieldData[];
|
|
83
|
+
}
|
|
84
|
+
export interface ApiResultSetObj {
|
|
85
|
+
database: string;
|
|
86
|
+
layout: string;
|
|
87
|
+
table: string;
|
|
88
|
+
totalRecordCount: number;
|
|
89
|
+
foundCount: number;
|
|
90
|
+
returnedCount: number;
|
|
91
|
+
}
|
|
92
|
+
export interface ApiRowDataDef {
|
|
93
|
+
fieldData: ApiFieldData;
|
|
94
|
+
portalData: ApiPortalData;
|
|
95
|
+
modId: string;
|
|
96
|
+
recordId: string;
|
|
97
|
+
portalDataInfo: {
|
|
98
|
+
database: string;
|
|
99
|
+
table: string;
|
|
100
|
+
foundCount: number;
|
|
101
|
+
returnedCount: number;
|
|
102
|
+
}[];
|
|
103
|
+
}
|
|
@@ -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
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
/// <reference types="node" />
|
|
3
3
|
import { RecordBase } from "./recordBase.js";
|
|
4
4
|
import * as http from "http";
|
|
5
|
-
import { ContainerBufferResult, DOWNLOAD_MODES
|
|
5
|
+
import { ContainerBufferResult, DOWNLOAD_MODES } from "../types.js";
|
|
6
|
+
import { ApiFieldMetadata } from "../models/apiResults.js";
|
|
6
7
|
export type FieldValue = string | number | Date | Container;
|
|
7
8
|
export type Container = null;
|
|
8
9
|
export declare class Field<T extends FieldValue> {
|
|
@@ -12,7 +13,7 @@ export declare class Field<T extends FieldValue> {
|
|
|
12
13
|
edited: boolean;
|
|
13
14
|
constructor(record: any, id: any, contents: any);
|
|
14
15
|
set(content: string | number | Date | undefined | null): void;
|
|
15
|
-
get metadata():
|
|
16
|
+
get metadata(): ApiFieldMetadata;
|
|
16
17
|
get value(): T;
|
|
17
18
|
set value(value: T);
|
|
18
19
|
get string(): string;
|
package/src/records/field.js
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Copyright (c) 2023. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
5
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
6
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
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
4
|
import { RecordTypes } from "./recordBase.js";
|
|
14
|
-
import
|
|
5
|
+
import { File, FormData } from "node-fetch";
|
|
15
6
|
import { DOWNLOAD_MODES } from "../types.js";
|
|
16
|
-
import {
|
|
7
|
+
import { ApiFieldDisplayTypes, ApiFieldResultTypes, ApiFieldTypes } from "../models/apiResults.js";
|
|
17
8
|
export class Field {
|
|
9
|
+
record;
|
|
10
|
+
id;
|
|
11
|
+
_value;
|
|
12
|
+
edited;
|
|
18
13
|
constructor(record, id, contents) {
|
|
19
14
|
this.record = record;
|
|
20
15
|
this.id = id;
|
|
@@ -43,9 +38,9 @@ export class Field {
|
|
|
43
38
|
// Default to a regular text field
|
|
44
39
|
return {
|
|
45
40
|
name: this.id.toString(),
|
|
46
|
-
type:
|
|
47
|
-
displayType:
|
|
48
|
-
result:
|
|
41
|
+
type: ApiFieldTypes.NORMAL,
|
|
42
|
+
displayType: ApiFieldDisplayTypes.EDIT_TEXT,
|
|
43
|
+
result: ApiFieldResultTypes.TEXT,
|
|
49
44
|
global: false,
|
|
50
45
|
autoEnter: true,
|
|
51
46
|
fourDigitYear: false,
|
|
@@ -54,8 +49,8 @@ export class Field {
|
|
|
54
49
|
notEmpty: false,
|
|
55
50
|
numeric: false,
|
|
56
51
|
timeOfDay: false,
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
repetitions: 1,
|
|
53
|
+
valueList: ""
|
|
59
54
|
};
|
|
60
55
|
}
|
|
61
56
|
if (this.record.type === RecordTypes.PORTAL) {
|
|
@@ -80,9 +75,9 @@ export class Field {
|
|
|
80
75
|
else {
|
|
81
76
|
return this.record.layout.metadata.fieldMetaData.find(i => i.name === this.id) || {
|
|
82
77
|
name: this.id.toString(),
|
|
83
|
-
type:
|
|
84
|
-
displayType:
|
|
85
|
-
result:
|
|
78
|
+
type: ApiFieldTypes.NORMAL,
|
|
79
|
+
displayType: ApiFieldDisplayTypes.EDIT_TEXT,
|
|
80
|
+
result: ApiFieldResultTypes.TEXT,
|
|
86
81
|
global: false,
|
|
87
82
|
autoEnter: true,
|
|
88
83
|
fourDigitYear: false,
|
|
@@ -91,8 +86,8 @@ export class Field {
|
|
|
91
86
|
notEmpty: false,
|
|
92
87
|
numeric: false,
|
|
93
88
|
timeOfDay: false,
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
repetitions: 1,
|
|
90
|
+
valueList: ""
|
|
96
91
|
};
|
|
97
92
|
}
|
|
98
93
|
}
|
|
@@ -121,60 +116,41 @@ export class Field {
|
|
|
121
116
|
}
|
|
122
117
|
throw "Field value is not a number";
|
|
123
118
|
}
|
|
124
|
-
upload(buffer, filename, mime) {
|
|
119
|
+
async upload(buffer, filename, mime) {
|
|
125
120
|
let trace = new Error();
|
|
126
121
|
if (this.metadata.result !== "container")
|
|
127
122
|
throw "Cannot upload a file to the field; " + this.id + " (not a container field)";
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
}));
|
|
123
|
+
let form = new FormData();
|
|
124
|
+
form.append("upload", new File([buffer], filename, { type: mime }));
|
|
125
|
+
await this.record.layout.database.apiRequest(`${this.record.endpoint}/containers/${this.id}/1`, {
|
|
126
|
+
method: "POST",
|
|
127
|
+
// @ts-ignore
|
|
128
|
+
headers: { "Authorization": "Bearer " + this.record.layout.database.token },
|
|
129
|
+
body: form
|
|
130
|
+
});
|
|
150
131
|
}
|
|
151
|
-
download(mode = DOWNLOAD_MODES.Stream) {
|
|
132
|
+
async download(mode = DOWNLOAD_MODES.Stream) {
|
|
133
|
+
if (this.metadata.result !== ApiFieldResultTypes.CONTAINER)
|
|
134
|
+
throw new Error("Cannot perform download() on a non-container field");
|
|
135
|
+
let stream = await this.record.layout.database.streamURL(this.string);
|
|
136
|
+
if (mode === DOWNLOAD_MODES.Stream) {
|
|
137
|
+
return stream;
|
|
138
|
+
}
|
|
139
|
+
let body = [];
|
|
152
140
|
return new Promise((resolve, reject) => {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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 => {
|
|
141
|
+
stream.on("data", chunk => {
|
|
142
|
+
body.push(chunk);
|
|
143
|
+
});
|
|
144
|
+
stream.on("error", (e) => {
|
|
176
145
|
reject(e);
|
|
177
146
|
});
|
|
147
|
+
stream.on("end", () => {
|
|
148
|
+
resolve({
|
|
149
|
+
buffer: Buffer.concat(body),
|
|
150
|
+
mime: stream.headers["content-type"],
|
|
151
|
+
request: stream
|
|
152
|
+
});
|
|
153
|
+
});
|
|
178
154
|
});
|
|
179
155
|
}
|
|
180
156
|
}
|
package/src/records/field.ts
CHANGED
|
@@ -7,6 +7,7 @@ import fetch, {File, FormData} from "node-fetch";
|
|
|
7
7
|
import * as http from "http";
|
|
8
8
|
import {ContainerBufferResult, DOWNLOAD_MODES, FieldMetaData} from "../types.js";
|
|
9
9
|
import {FMError} from "../FMError.js";
|
|
10
|
+
import {ApiFieldDisplayTypes, ApiFieldMetadata, ApiFieldResultTypes, ApiFieldTypes} from "../models/apiResults.js";
|
|
10
11
|
|
|
11
12
|
export type FieldValue = string | number | Date | Container
|
|
12
13
|
export type Container = null
|
|
@@ -41,14 +42,14 @@ export class Field<T extends FieldValue> {
|
|
|
41
42
|
this.edited = true
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
get metadata():
|
|
45
|
+
get metadata(): ApiFieldMetadata {
|
|
45
46
|
if (!this.record.layout.metadata) {
|
|
46
47
|
// Default to a regular text field
|
|
47
48
|
return {
|
|
48
49
|
name: this.id.toString(),
|
|
49
|
-
type:
|
|
50
|
-
displayType:
|
|
51
|
-
result:
|
|
50
|
+
type: ApiFieldTypes.NORMAL,
|
|
51
|
+
displayType: ApiFieldDisplayTypes.EDIT_TEXT,
|
|
52
|
+
result: ApiFieldResultTypes.TEXT,
|
|
52
53
|
global: false,
|
|
53
54
|
autoEnter: true,
|
|
54
55
|
fourDigitYear: false,
|
|
@@ -57,9 +58,9 @@ export class Field<T extends FieldValue> {
|
|
|
57
58
|
notEmpty: false,
|
|
58
59
|
numeric: false,
|
|
59
60
|
timeOfDay: false,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
61
|
+
repetitions: 1,
|
|
62
|
+
valueList: ""
|
|
63
|
+
}
|
|
63
64
|
}
|
|
64
65
|
if (this.record.type === RecordTypes.PORTAL) {
|
|
65
66
|
// @ts-ignore
|
|
@@ -81,11 +82,11 @@ export class Field<T extends FieldValue> {
|
|
|
81
82
|
} as FieldMetaData
|
|
82
83
|
}
|
|
83
84
|
else {
|
|
84
|
-
return this.record.layout.metadata.fieldMetaData.find(i => i.name === this.id)
|
|
85
|
+
return this.record.layout.metadata.fieldMetaData.find(i => i.name === this.id) || {
|
|
85
86
|
name: this.id.toString(),
|
|
86
|
-
type:
|
|
87
|
-
displayType:
|
|
88
|
-
result:
|
|
87
|
+
type: ApiFieldTypes.NORMAL,
|
|
88
|
+
displayType: ApiFieldDisplayTypes.EDIT_TEXT,
|
|
89
|
+
result: ApiFieldResultTypes.TEXT,
|
|
89
90
|
global: false,
|
|
90
91
|
autoEnter: true,
|
|
91
92
|
fourDigitYear: false,
|
|
@@ -94,9 +95,9 @@ export class Field<T extends FieldValue> {
|
|
|
94
95
|
notEmpty: false,
|
|
95
96
|
numeric: false,
|
|
96
97
|
timeOfDay: false,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
98
|
+
repetitions: 1,
|
|
99
|
+
valueList: ""
|
|
100
|
+
}
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
|
|
@@ -130,64 +131,45 @@ export class Field<T extends FieldValue> {
|
|
|
130
131
|
throw "Field value is not a number"
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
upload(buffer: Buffer, filename: string, mime: string): Promise<void> {
|
|
134
|
+
async upload(buffer: Buffer, filename: string, mime: string): Promise<void> {
|
|
134
135
|
let trace = new Error()
|
|
135
136
|
if (this.metadata.result !== "container") throw "Cannot upload a file to the field; " + this.id + " (not a container field)"
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
-
})
|
|
137
|
+
let form = new FormData()
|
|
138
|
+
form.append("upload", new File([buffer], filename, {type: mime}))
|
|
139
|
+
|
|
140
|
+
await this.record.layout.database.apiRequest<null>(`${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
|
|
158
145
|
})
|
|
159
146
|
}
|
|
160
147
|
|
|
161
148
|
download(mode: DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage>
|
|
162
149
|
download(mode: DOWNLOAD_MODES.Buffer): Promise<ContainerBufferResult>
|
|
163
|
-
download(mode: DOWNLOAD_MODES = DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage | ContainerBufferResult> {
|
|
150
|
+
async download(mode: DOWNLOAD_MODES = DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage | ContainerBufferResult> {
|
|
151
|
+
if (this.metadata.result !== ApiFieldResultTypes.CONTAINER) throw new Error("Cannot perform download() on a non-container field")
|
|
152
|
+
|
|
153
|
+
let stream = await this.record.layout.database.streamURL(this.string)
|
|
154
|
+
if (mode === DOWNLOAD_MODES.Stream) {
|
|
155
|
+
return stream
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
let body = []
|
|
164
159
|
return new Promise((resolve, reject) => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
stream.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
-
})
|
|
160
|
+
stream.on("data", chunk => {
|
|
161
|
+
body.push(chunk)
|
|
162
|
+
})
|
|
163
|
+
stream.on("error", (e) => {
|
|
164
|
+
reject(e)
|
|
165
|
+
})
|
|
166
|
+
stream.on("end", () => {
|
|
167
|
+
resolve({
|
|
168
|
+
buffer: Buffer.concat(body),
|
|
169
|
+
mime: stream.headers["content-type"],
|
|
170
|
+
request: stream
|
|
171
|
+
} as ContainerBufferResult)
|
|
172
|
+
})
|
|
191
173
|
})
|
|
192
174
|
}
|
|
193
175
|
}
|
|
@@ -1,19 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Copyright (c) 2023. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
5
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
6
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
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
4
|
import { RecordGetOperation } from "./recordGetOperation.js";
|
|
14
5
|
import { LayoutRecord } from "../layoutRecord.js";
|
|
15
6
|
import { FMError } from "../../FMError.js";
|
|
16
7
|
export class Find extends RecordGetOperation {
|
|
8
|
+
queries;
|
|
17
9
|
constructor(layout, start = 0, limit = 100) {
|
|
18
10
|
super(layout);
|
|
19
11
|
this.setOffset(start);
|
|
@@ -55,36 +47,24 @@ export class Find extends RecordGetOperation {
|
|
|
55
47
|
run() {
|
|
56
48
|
return this.fetch();
|
|
57
49
|
}
|
|
58
|
-
fetch() {
|
|
50
|
+
async fetch() {
|
|
59
51
|
let trace = new Error();
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
port: 443,
|
|
66
|
-
method: "POST",
|
|
67
|
-
body: JSON.stringify(this.toObject())
|
|
68
|
-
});
|
|
69
|
-
})
|
|
70
|
-
.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
71
|
-
// // console.log(res)
|
|
72
|
-
if (res.messages[0].code === "0") {
|
|
73
|
-
// console.log("RESOLVING")
|
|
74
|
-
if (!this.layout.metadata)
|
|
75
|
-
yield this.layout.getLayoutMeta();
|
|
76
|
-
let data = res.response.data.map(item => {
|
|
77
|
-
return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData);
|
|
78
|
-
});
|
|
79
|
-
resolve(data);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
reject(new FMError(res.messages[0].code, res.status, res, trace));
|
|
83
|
-
}
|
|
84
|
-
}))
|
|
85
|
-
.catch(e => {
|
|
86
|
-
reject(e);
|
|
87
|
-
});
|
|
52
|
+
await this.layout.getLayoutMeta();
|
|
53
|
+
let res = await this.layout.database.apiRequest(`${this.layout.endpoint}/_find`, {
|
|
54
|
+
port: 443,
|
|
55
|
+
method: "POST",
|
|
56
|
+
body: JSON.stringify(this.toObject())
|
|
88
57
|
});
|
|
58
|
+
if (res.messages[0].code === "0") {
|
|
59
|
+
// console.log("RESOLVING")
|
|
60
|
+
if (!this.layout.metadata)
|
|
61
|
+
await this.layout.getLayoutMeta();
|
|
62
|
+
return res.response.data.map(item => {
|
|
63
|
+
return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw new FMError(res.messages[0].code, res.httpStatus, res, trace);
|
|
68
|
+
}
|
|
89
69
|
}
|
|
90
70
|
}
|