@jd-data-limited/easy-fm 3.0.10 → 3.1.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/.idea/compiler.xml +7 -0
- package/.idea/discord.xml +7 -0
- package/dist/index.min.js +2 -0
- package/dist/index.min.js.LICENSE.txt +3 -0
- package/examples/test.js +7 -0
- package/img.png +0 -0
- package/package.json +1 -1
- package/src/FMError.d.ts +12 -0
- package/src/FMError.js +1028 -0
- package/src/FMError.ts +1035 -0
- package/src/connection/FMHost.d.ts +12 -0
- package/src/connection/FMHost.js +68 -0
- package/src/connection/FMHost.ts +75 -0
- package/src/connection/database.d.ts +26 -0
- package/src/connection/database.js +195 -0
- package/src/connection/database.ts +216 -0
- package/src/connection/generateAuthorizationHeaders.d.ts +2 -0
- package/src/connection/generateAuthorizationHeaders.js +23 -0
- package/src/connection/generateAuthorizationHeaders.ts +32 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +5 -2076
- package/src/index.ts +3 -2324
- package/src/layouts/layout.d.ts +29 -0
- package/src/layouts/layout.js +84 -0
- package/src/layouts/layout.ts +92 -0
- package/src/layouts/layoutInterface.d.ts +13 -0
- package/src/layouts/layoutInterface.js +4 -0
- package/src/layouts/layoutInterface.ts +21 -0
- package/src/layouts/layoutRecordManager.d.ts +13 -0
- package/src/layouts/layoutRecordManager.js +50 -0
- package/src/layouts/layoutRecordManager.ts +59 -0
- package/src/records/field.d.ts +21 -0
- package/src/records/field.js +177 -0
- package/src/records/field.ts +189 -0
- package/src/records/getOperations/find.d.ts +15 -0
- package/src/records/getOperations/find.js +90 -0
- package/src/records/getOperations/find.ts +88 -0
- package/src/records/getOperations/recordGetOperation.d.ts +17 -0
- package/src/records/getOperations/recordGetOperation.js +43 -0
- package/src/records/getOperations/recordGetOperation.ts +54 -0
- package/src/records/getOperations/recordGetRange.d.ts +13 -0
- package/src/records/getOperations/recordGetRange.js +95 -0
- package/src/records/getOperations/recordGetRange.ts +84 -0
- package/src/records/layoutRecord.d.ts +16 -0
- package/src/records/layoutRecord.js +211 -0
- package/src/records/layoutRecord.ts +220 -0
- package/src/records/portal.d.ts +10 -0
- package/src/records/portal.js +19 -0
- package/src/records/portal.ts +28 -0
- package/src/records/portalRecord.d.ts +12 -0
- package/src/records/portalRecord.js +32 -0
- package/src/records/portalRecord.ts +43 -0
- package/src/records/recordBase.d.ts +20 -0
- package/src/records/recordBase.js +95 -0
- package/src/records/recordBase.ts +121 -0
- package/src/types.d.ts +117 -0
- package/src/types.js +8 -0
- package/src/types.ts +151 -0
- package/test.d.ts +1 -0
- package/test.js +4 -0
- package/tsconfig.json +4 -0
- package/TEMP/FILEMAKER.txt +0 -218
- package/TEMP/WEBAPP.txt +0 -92
- package/TEMP/config.yaml +0 -40
- package/TEMP/data.json +0 -19837
- package/temp2/1.19.2-forge-43.2.8.json +0 -347
- package/temp2/Quinn-1.19.2-forge-43.2.8.json +0 -347
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023. See LICENSE file for more information
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {RecordBase} from "./recordBase";
|
|
6
|
+
import fetch, {File, FormData} from "node-fetch";
|
|
7
|
+
import * as http from "http";
|
|
8
|
+
import {ContainerBufferResult, DOWNLOAD_MODES, FieldMetaData} from "../types.js";
|
|
9
|
+
import {PortalRecord} from "./portalRecord";
|
|
10
|
+
import {FieldValue} from "../layouts/layoutInterface";
|
|
11
|
+
import {FMError} from "../FMError";
|
|
12
|
+
|
|
13
|
+
export class Field<T extends FieldValue> {
|
|
14
|
+
record: RecordBase<any>;
|
|
15
|
+
id: string;
|
|
16
|
+
protected _value: T;
|
|
17
|
+
edited: boolean;
|
|
18
|
+
|
|
19
|
+
constructor(record, id, contents) {
|
|
20
|
+
this.record = record
|
|
21
|
+
this.id = id
|
|
22
|
+
this._value = contents
|
|
23
|
+
this.edited = false
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
set(content: string | number | Date | undefined | null) {
|
|
27
|
+
if (this.metadata.result === "container") throw "Cannot set container value using set(). Use upload() instead."
|
|
28
|
+
if (
|
|
29
|
+
(this.metadata.result === "timeStamp" ||
|
|
30
|
+
this.metadata.result === "date" ||
|
|
31
|
+
this.metadata.result === "time")
|
|
32
|
+
&& !(content instanceof Date) && !!content
|
|
33
|
+
) {
|
|
34
|
+
throw "Value was not an instance of Date: " + content
|
|
35
|
+
}
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
if (!content) this._value = ""
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
else this._value = content
|
|
40
|
+
this.edited = true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
get metadata(): FieldMetaData {
|
|
44
|
+
if (!this.record.layout.metadata) {
|
|
45
|
+
// Default to a regular text field
|
|
46
|
+
return {
|
|
47
|
+
name: this.id.toString(),
|
|
48
|
+
type: 'normal',
|
|
49
|
+
displayType: 'editText',
|
|
50
|
+
result: 'text',
|
|
51
|
+
global: false,
|
|
52
|
+
autoEnter: true,
|
|
53
|
+
fourDigitYear: false,
|
|
54
|
+
maxRepeat: 1,
|
|
55
|
+
maxCharacters: 0,
|
|
56
|
+
notEmpty: false,
|
|
57
|
+
numeric: false,
|
|
58
|
+
timeOfDay: false,
|
|
59
|
+
repetitionStart: 1,
|
|
60
|
+
repetitionEnd: 1
|
|
61
|
+
} as FieldMetaData
|
|
62
|
+
}
|
|
63
|
+
if (this.record instanceof PortalRecord) {
|
|
64
|
+
return this.record.layout.metadata.portalMetaData[this.record.portal.name || "portal not attached"].find(i => i.name === this.id) as FieldMetaData || {
|
|
65
|
+
name: this.id.toString(),
|
|
66
|
+
type: 'normal',
|
|
67
|
+
displayType: 'editText',
|
|
68
|
+
result: 'text',
|
|
69
|
+
global: false,
|
|
70
|
+
autoEnter: true,
|
|
71
|
+
fourDigitYear: false,
|
|
72
|
+
maxRepeat: 1,
|
|
73
|
+
maxCharacters: 0,
|
|
74
|
+
notEmpty: false,
|
|
75
|
+
numeric: false,
|
|
76
|
+
timeOfDay: false,
|
|
77
|
+
repetitionStart: 1,
|
|
78
|
+
repetitionEnd: 1
|
|
79
|
+
} as FieldMetaData
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
return this.record.layout.metadata.fieldMetaData.find(i => i.name === this.id) as FieldMetaData || {
|
|
83
|
+
name: this.id.toString(),
|
|
84
|
+
type: 'normal',
|
|
85
|
+
displayType: 'editText',
|
|
86
|
+
result: 'text',
|
|
87
|
+
global: false,
|
|
88
|
+
autoEnter: true,
|
|
89
|
+
fourDigitYear: false,
|
|
90
|
+
maxRepeat: 1,
|
|
91
|
+
maxCharacters: 0,
|
|
92
|
+
notEmpty: false,
|
|
93
|
+
numeric: false,
|
|
94
|
+
timeOfDay: false,
|
|
95
|
+
repetitionStart: 1,
|
|
96
|
+
repetitionEnd: 1
|
|
97
|
+
} as FieldMetaData
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
get value(): T {
|
|
102
|
+
// if (this.metadata.result === "container") throw "Use await field.stream() to get the contents of a container field, instead of field.value"
|
|
103
|
+
return this._value
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
set value(value: T) {
|
|
107
|
+
this._value = value
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get string(): string {
|
|
111
|
+
if (typeof this._value === "string") {
|
|
112
|
+
return this._value
|
|
113
|
+
}
|
|
114
|
+
throw "Field value is not a string"
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
get date(): Date {
|
|
118
|
+
if (this._value instanceof Date) {
|
|
119
|
+
return this._value
|
|
120
|
+
}
|
|
121
|
+
throw "Field value is not a date"
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
get number(): number {
|
|
125
|
+
if (typeof this._value === "number") {
|
|
126
|
+
return this._value
|
|
127
|
+
}
|
|
128
|
+
throw "Field value is not a number"
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
upload(buffer: Buffer, filename: string, mime: string): Promise<void> {
|
|
132
|
+
let trace = new Error()
|
|
133
|
+
if (this.metadata.result !== "container") throw "Cannot upload a file to the field; " + this.id + " (not a container field)"
|
|
134
|
+
return new Promise(async (resolve, reject) => {
|
|
135
|
+
let form = new FormData()
|
|
136
|
+
form.append("upload", new File([buffer], filename, {type: mime}))
|
|
137
|
+
|
|
138
|
+
let _fetch = await fetch(`${this.record.endpoint}/containers/${this.id}/1`, {
|
|
139
|
+
method: "POST",
|
|
140
|
+
headers: {"Authorization": "Bearer " + this.record.layout.database.token},
|
|
141
|
+
body: form
|
|
142
|
+
}).then(res => res.json())
|
|
143
|
+
.then(data => {
|
|
144
|
+
let _res = data as any
|
|
145
|
+
if (_res.messages[0].code === "0") {
|
|
146
|
+
resolve()
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
reject(new FMError(_res.messages[0].code, _res.status, data, trace))
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
.catch(e => {
|
|
153
|
+
reject(e)
|
|
154
|
+
})
|
|
155
|
+
})
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
download(mode: DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage>
|
|
159
|
+
download(mode: DOWNLOAD_MODES.Buffer): Promise<ContainerBufferResult>
|
|
160
|
+
download(mode: DOWNLOAD_MODES = DOWNLOAD_MODES.Stream): Promise<http.IncomingMessage | ContainerBufferResult> {
|
|
161
|
+
return new Promise((resolve, reject) => {
|
|
162
|
+
this.record.layout.database.streamContainer(this, this._value)
|
|
163
|
+
.then(stream => {
|
|
164
|
+
if (mode === DOWNLOAD_MODES.Stream) {
|
|
165
|
+
resolve(stream)
|
|
166
|
+
return
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let body = []
|
|
170
|
+
stream.on("data", chunk => {
|
|
171
|
+
body.push(chunk)
|
|
172
|
+
})
|
|
173
|
+
stream.on("error", (e) => {
|
|
174
|
+
reject(e)
|
|
175
|
+
})
|
|
176
|
+
stream.on("end", () => {
|
|
177
|
+
resolve({
|
|
178
|
+
buffer: Buffer.concat(body),
|
|
179
|
+
mime: stream.headers["content-type"],
|
|
180
|
+
request: stream
|
|
181
|
+
} as ContainerBufferResult)
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
.catch(e => {
|
|
185
|
+
reject(e)
|
|
186
|
+
})
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { RecordGetOperation } from "./recordGetOperation";
|
|
2
|
+
import { LayoutRecord } from "../layoutRecord";
|
|
3
|
+
import { LayoutInterface } from "../../layouts/layoutInterface";
|
|
4
|
+
import { Layout } from "../../layouts/layout";
|
|
5
|
+
export declare class Find<T extends LayoutInterface> extends RecordGetOperation<T> {
|
|
6
|
+
protected queries: object[];
|
|
7
|
+
constructor(layout: Layout<T>, start?: number, limit?: number);
|
|
8
|
+
private toObject;
|
|
9
|
+
addRequests(...requests: any[]): this;
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated in favour of .fetch()
|
|
12
|
+
*/
|
|
13
|
+
run(): Promise<LayoutRecord<T["fields"], T["portals"]>[]>;
|
|
14
|
+
fetch(): Promise<LayoutRecord<T["fields"], T["portals"]>[]>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023. See LICENSE file for more information
|
|
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
|
+
import { RecordGetOperation } from "./recordGetOperation";
|
|
14
|
+
import { LayoutRecord } from "../layoutRecord";
|
|
15
|
+
import { FMError } from "../../FMError";
|
|
16
|
+
export class Find extends RecordGetOperation {
|
|
17
|
+
constructor(layout, start = 0, limit = 100) {
|
|
18
|
+
super(layout);
|
|
19
|
+
this.setOffset(start);
|
|
20
|
+
this.setLimit(limit);
|
|
21
|
+
this.queries = [];
|
|
22
|
+
}
|
|
23
|
+
toObject() {
|
|
24
|
+
let out = { query: this.queries, sort: undefined };
|
|
25
|
+
if (this.sort.length !== 0)
|
|
26
|
+
out.sort = this.sort;
|
|
27
|
+
for (let item of Object.keys(this.scripts)) {
|
|
28
|
+
if (this.scripts[item]) {
|
|
29
|
+
out[item] = this.scripts[item].name;
|
|
30
|
+
if (this.scripts[item].parameter)
|
|
31
|
+
out[item + ".param"] = this.scripts[item].parameter;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (this.limit !== 100)
|
|
35
|
+
out["limit"] = this.limit;
|
|
36
|
+
if (this.offset !== 0)
|
|
37
|
+
out["offset"] = this.offset;
|
|
38
|
+
if (this.limitPortals.length > 0) {
|
|
39
|
+
out["portal"] = this.limitPortals.map(p => p.portal.name);
|
|
40
|
+
for (let item of this.limitPortals) {
|
|
41
|
+
out["offset." + item.portal.name.replace(/[^0-9A-z]/g, "")] = item.offset;
|
|
42
|
+
out["limit." + item.portal.name.replace(/[^0-9A-z]/g, "")] = item.limit;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
addRequests(...requests) {
|
|
48
|
+
for (let item of requests)
|
|
49
|
+
this.queries.push(item);
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* @deprecated in favour of .fetch()
|
|
54
|
+
*/
|
|
55
|
+
run() {
|
|
56
|
+
return this.fetch();
|
|
57
|
+
}
|
|
58
|
+
fetch() {
|
|
59
|
+
let trace = new Error();
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
// console.log(this.#toObject())
|
|
62
|
+
this.layout.getLayoutMeta()
|
|
63
|
+
.then(() => {
|
|
64
|
+
return this.layout.database.apiRequest(`${this.layout.endpoint}/_find`, {
|
|
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
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023. See LICENSE file for more information
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {RecordGetOperation} from "./recordGetOperation";
|
|
6
|
+
import {LayoutRecord} from "../layoutRecord";
|
|
7
|
+
import {LayoutInterface} from "../../layouts/layoutInterface";
|
|
8
|
+
import {Layout} from "../../layouts/layout";
|
|
9
|
+
import {FMError} from "../../FMError";
|
|
10
|
+
|
|
11
|
+
export class Find<T extends LayoutInterface> extends RecordGetOperation<T> {
|
|
12
|
+
protected queries: object[]
|
|
13
|
+
|
|
14
|
+
constructor(layout: Layout<T>, start = 0, limit = 100) {
|
|
15
|
+
super(layout)
|
|
16
|
+
this.setOffset(start)
|
|
17
|
+
this.setLimit(limit)
|
|
18
|
+
this.queries = []
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
private toObject() {
|
|
22
|
+
let out = {query: this.queries, sort: undefined}
|
|
23
|
+
if (this.sort.length !== 0) out.sort = this.sort
|
|
24
|
+
|
|
25
|
+
for (let item of Object.keys(this.scripts)) {
|
|
26
|
+
if (this.scripts[item]) {
|
|
27
|
+
out[item] = this.scripts[item].name
|
|
28
|
+
if (this.scripts[item].parameter) out[item + ".param"] = this.scripts[item].parameter
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (this.limit !== 100) out["limit"] = this.limit
|
|
33
|
+
if (this.offset !== 0) out["offset"] = this.offset
|
|
34
|
+
if (this.limitPortals.length > 0) {
|
|
35
|
+
out["portal"] = this.limitPortals.map(p => p.portal.name)
|
|
36
|
+
for (let item of this.limitPortals) {
|
|
37
|
+
out["offset." + item.portal.name.replace(/[^0-9A-z]/g, "")] = item.offset
|
|
38
|
+
out["limit." + item.portal.name.replace(/[^0-9A-z]/g, "")] = item.limit
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return out
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
addRequests(...requests) {
|
|
46
|
+
for (let item of requests) this.queries.push(item)
|
|
47
|
+
return this
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @deprecated in favour of .fetch()
|
|
52
|
+
*/
|
|
53
|
+
run() {
|
|
54
|
+
return this.fetch()
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fetch(): Promise<LayoutRecord<T["fields"], T["portals"]>[]> {
|
|
58
|
+
let trace = new Error()
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
// console.log(this.#toObject())
|
|
61
|
+
this.layout.getLayoutMeta()
|
|
62
|
+
.then(() => {
|
|
63
|
+
return this.layout.database.apiRequest(`${this.layout.endpoint}/_find`, {
|
|
64
|
+
port: 443,
|
|
65
|
+
method: "POST",
|
|
66
|
+
body: JSON.stringify(this.toObject())
|
|
67
|
+
})
|
|
68
|
+
})
|
|
69
|
+
.then(async res => {
|
|
70
|
+
// // console.log(res)
|
|
71
|
+
if (res.messages[0].code === "0") {
|
|
72
|
+
// console.log("RESOLVING")
|
|
73
|
+
if (!this.layout.metadata) await this.layout.getLayoutMeta()
|
|
74
|
+
let data = res.response.data.map(item => {
|
|
75
|
+
return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData)
|
|
76
|
+
})
|
|
77
|
+
resolve(data)
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
reject(new FMError(res.messages[0].code, res.status, res, trace))
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
.catch(e => {
|
|
84
|
+
reject(e)
|
|
85
|
+
})
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { LayoutInterface } from "../../layouts/layoutInterface";
|
|
2
|
+
import { Layout } from "../../layouts/layout";
|
|
3
|
+
import { Portal } from "../portal";
|
|
4
|
+
import { limitPortalsInterface } from "../../types.js";
|
|
5
|
+
export declare class RecordGetOperation<T extends LayoutInterface> {
|
|
6
|
+
protected layout: Layout<T>;
|
|
7
|
+
protected limit: number;
|
|
8
|
+
protected scripts: object;
|
|
9
|
+
protected sort: object[];
|
|
10
|
+
protected limitPortals: limitPortalsInterface[];
|
|
11
|
+
protected offset: number;
|
|
12
|
+
constructor(layout: Layout<T>);
|
|
13
|
+
addToPortalLimit(portal: Portal<any>, offset?: number, limit?: number): this;
|
|
14
|
+
setLimit(limit: number): this;
|
|
15
|
+
addSort(fieldName: any, sortOrder: any): this;
|
|
16
|
+
setOffset(offset: number): this;
|
|
17
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023. See LICENSE file for more information
|
|
3
|
+
*/
|
|
4
|
+
export class RecordGetOperation {
|
|
5
|
+
constructor(layout) {
|
|
6
|
+
this.limit = 100;
|
|
7
|
+
this.limitPortals = [];
|
|
8
|
+
this.offset = 0;
|
|
9
|
+
this.layout = layout;
|
|
10
|
+
this.scripts = {
|
|
11
|
+
"script": null,
|
|
12
|
+
"script.prerequeset": null,
|
|
13
|
+
"script.presort": null // Runs before the sort
|
|
14
|
+
};
|
|
15
|
+
this.sort = [];
|
|
16
|
+
}
|
|
17
|
+
/*
|
|
18
|
+
addToPortalLimit() will adjust the results of the get request so that if a layout has multiple portals in it,
|
|
19
|
+
only data from the specified ones will be read. This may help reduce load on your FileMaker API
|
|
20
|
+
*/
|
|
21
|
+
addToPortalLimit(portal, offset = 0, limit = 100) {
|
|
22
|
+
if (offset < 0)
|
|
23
|
+
throw "Portal offset cannot be less than 0";
|
|
24
|
+
this.limitPortals.push({ portal, offset, limit });
|
|
25
|
+
return this;
|
|
26
|
+
}
|
|
27
|
+
setLimit(limit) {
|
|
28
|
+
if (limit < 1)
|
|
29
|
+
throw "Record limit too low";
|
|
30
|
+
this.limit = limit;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
addSort(fieldName, sortOrder) {
|
|
34
|
+
this.sort.push({ fieldName, sortOrder });
|
|
35
|
+
return this;
|
|
36
|
+
}
|
|
37
|
+
setOffset(offset) {
|
|
38
|
+
if (offset < 0)
|
|
39
|
+
throw "Record offset too low";
|
|
40
|
+
this.limit = offset;
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023. See LICENSE file for more information
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import {LayoutInterface} from "../../layouts/layoutInterface";
|
|
6
|
+
import {Layout} from "../../layouts/layout";
|
|
7
|
+
import {Portal} from "../portal";
|
|
8
|
+
import {limitPortalsInterface} from "../../types.js";
|
|
9
|
+
|
|
10
|
+
export class RecordGetOperation<T extends LayoutInterface> {
|
|
11
|
+
protected layout: Layout<T>
|
|
12
|
+
protected limit: number = 100
|
|
13
|
+
protected scripts: object
|
|
14
|
+
protected sort: object[]
|
|
15
|
+
protected limitPortals: limitPortalsInterface[] = []
|
|
16
|
+
protected offset: number = 0
|
|
17
|
+
|
|
18
|
+
constructor(layout: Layout<T>) {
|
|
19
|
+
this.layout = layout
|
|
20
|
+
this.scripts = {
|
|
21
|
+
"script": null, // Runs after everything
|
|
22
|
+
"script.prerequeset": null, // Runs before the request
|
|
23
|
+
"script.presort": null // Runs before the sort
|
|
24
|
+
}
|
|
25
|
+
this.sort = []
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/*
|
|
29
|
+
addToPortalLimit() will adjust the results of the get request so that if a layout has multiple portals in it,
|
|
30
|
+
only data from the specified ones will be read. This may help reduce load on your FileMaker API
|
|
31
|
+
*/
|
|
32
|
+
addToPortalLimit(portal: Portal<any>, offset = 0, limit = 100) {
|
|
33
|
+
if (offset < 0) throw "Portal offset cannot be less than 0"
|
|
34
|
+
this.limitPortals.push({portal, offset, limit})
|
|
35
|
+
return this
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
setLimit(limit: number) {
|
|
39
|
+
if (limit < 1) throw "Record limit too low"
|
|
40
|
+
this.limit = limit
|
|
41
|
+
return this
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
addSort(fieldName, sortOrder) {
|
|
45
|
+
this.sort.push({fieldName, sortOrder})
|
|
46
|
+
return this
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
setOffset(offset: number) {
|
|
50
|
+
if (offset < 0) throw "Record offset too low"
|
|
51
|
+
this.limit = offset
|
|
52
|
+
return this
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { LayoutInterface } from "../../layouts/layoutInterface";
|
|
2
|
+
import { RecordGetOperation } from "./recordGetOperation";
|
|
3
|
+
import { LayoutRecord } from "../layoutRecord";
|
|
4
|
+
import { extraBodyOptions } from "../../types.js";
|
|
5
|
+
export declare class RecordGetRange<T extends LayoutInterface> extends RecordGetOperation<T> {
|
|
6
|
+
constructor(layout: any, start?: number, limit?: number);
|
|
7
|
+
private generateQueryParams;
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated in favour of .fetch()
|
|
10
|
+
*/
|
|
11
|
+
run(extraBody?: extraBodyOptions): Promise<LayoutRecord<T["fields"], T["portals"]>[]>;
|
|
12
|
+
fetch(extraBody?: extraBodyOptions): Promise<LayoutRecord<T["fields"], T["portals"]>[]>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023. See LICENSE file for more information
|
|
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
|
+
import { RecordGetOperation } from "./recordGetOperation";
|
|
14
|
+
import { LayoutRecord } from "../layoutRecord";
|
|
15
|
+
import { FMError } from "../../FMError";
|
|
16
|
+
export class RecordGetRange extends RecordGetOperation {
|
|
17
|
+
constructor(layout, start = 0, limit = 100) {
|
|
18
|
+
super(layout);
|
|
19
|
+
this.setOffset(start);
|
|
20
|
+
this.setLimit(limit);
|
|
21
|
+
}
|
|
22
|
+
generateQueryParams(extraBody = {}) {
|
|
23
|
+
let params = [];
|
|
24
|
+
if (this.limit !== 100)
|
|
25
|
+
params.push("_limit=" + this.limit);
|
|
26
|
+
if (this.offset !== 0)
|
|
27
|
+
params.push("_offset=" + this.offset);
|
|
28
|
+
if (this.sort.length > 0)
|
|
29
|
+
params.push("_sort=" + encodeURI(JSON.stringify(this.sort)));
|
|
30
|
+
if (this.limitPortals.length > 0) {
|
|
31
|
+
params.push("portal=" + encodeURI(JSON.stringify(this.limitPortals.map(p => p.portal.name))));
|
|
32
|
+
for (let item of this.limitPortals) {
|
|
33
|
+
if (item.offset !== 0)
|
|
34
|
+
params.push("_offset." + item.portal.name.replace(/[^0-9A-z]/g, "") + "=" + item.offset);
|
|
35
|
+
if (item.limit !== 100)
|
|
36
|
+
params.push("_limit." + item.portal.name.replace(/[^0-9A-z]/g, "") + "=" + item.limit);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (extraBody.scripts) {
|
|
40
|
+
if (extraBody.scripts.prerequest) {
|
|
41
|
+
params.push("script.prerequest=" + extraBody.scripts.prerequest.name);
|
|
42
|
+
if (extraBody.scripts.prerequest.parameter)
|
|
43
|
+
params.push("script.prerequest.param=" + extraBody.scripts.prerequest.parameter);
|
|
44
|
+
}
|
|
45
|
+
if (extraBody.scripts.presort) {
|
|
46
|
+
params.push("script.presort=" + extraBody.scripts.presort.name);
|
|
47
|
+
if (extraBody.scripts.presort.parameter)
|
|
48
|
+
params.push("script.presort.param=" + extraBody.scripts.presort.parameter);
|
|
49
|
+
}
|
|
50
|
+
if (extraBody.scripts.after) {
|
|
51
|
+
params.push("script=" + extraBody.scripts.after.name);
|
|
52
|
+
if (extraBody.scripts.after.parameter)
|
|
53
|
+
params.push("script.param=" + extraBody.scripts.after.parameter);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (params.length === 0)
|
|
57
|
+
return "";
|
|
58
|
+
return "?" + params.join("&");
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* @deprecated in favour of .fetch()
|
|
62
|
+
*/
|
|
63
|
+
run(extraBody = {}) {
|
|
64
|
+
return this.fetch(extraBody);
|
|
65
|
+
}
|
|
66
|
+
fetch(extraBody = {}) {
|
|
67
|
+
let trace = new Error();
|
|
68
|
+
return new Promise((resolve, reject) => {
|
|
69
|
+
// console.log(this.#toObject())
|
|
70
|
+
this.layout.getLayoutMeta().then(() => {
|
|
71
|
+
return this.layout.database.apiRequest(`${this.layout.endpoint}/records${this.generateQueryParams(extraBody)}`, {
|
|
72
|
+
method: "GET"
|
|
73
|
+
});
|
|
74
|
+
})
|
|
75
|
+
.then((res) => __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
// // console.log(res)
|
|
77
|
+
if (res.messages[0].code === "0") {
|
|
78
|
+
// console.log("RESOLVING")
|
|
79
|
+
if (!this.layout.metadata)
|
|
80
|
+
yield this.layout.getLayoutMeta();
|
|
81
|
+
let data = res.response.data.map(item => {
|
|
82
|
+
return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData);
|
|
83
|
+
});
|
|
84
|
+
resolve(data);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
reject(new FMError(res.messages[0].code, res.status, res, trace));
|
|
88
|
+
}
|
|
89
|
+
}))
|
|
90
|
+
.catch(e => {
|
|
91
|
+
reject(e);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
}
|