@jd-data-limited/easy-fm 4.0.16 → 4.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/package.json +12 -6
- 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 +50 -17
- package/src/connection/database.js +94 -66
- package/src/connection/database.ts +125 -105
- package/src/connection/databaseBase.d.ts +11 -6
- package/src/connection/databaseBase.ts +9 -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 +42 -12
- package/src/records/field.js +69 -59
- package/src/records/field.ts +102 -81
- package/src/records/getOperations/recordGetOperation.d.ts +44 -24
- package/src/records/getOperations/recordGetOperation.js +87 -61
- package/src/records/getOperations/recordGetOperation.ts +127 -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 +17 -7
- package/src/records/recordBase.js +23 -16
- package/src/records/recordBase.ts +41 -37
- package/src/types.d.ts +21 -24
- package/src/types.ts +55 -59
- package/src/utils/query.d.ts +7 -7
- package/src/utils/query.js +10 -10
- package/src/utils/query.ts +19 -20
|
@@ -1,30 +1,53 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
|
-
import { LayoutRecord } from
|
|
5
|
-
import { RecordGetOperation } from
|
|
4
|
+
import { LayoutRecord } from '../records/layoutRecord.js';
|
|
5
|
+
import { RecordGetOperation } from '../records/getOperations/recordGetOperation.js';
|
|
6
|
+
/**
|
|
7
|
+
* Manager class for handling layout records.
|
|
8
|
+
*/
|
|
6
9
|
export class LayoutRecordManager {
|
|
7
10
|
layout;
|
|
8
11
|
constructor(layout) {
|
|
9
12
|
this.layout = layout;
|
|
10
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new layout record with the provided options.
|
|
16
|
+
*
|
|
17
|
+
* @param {OPTIONS} options - The options for creating the layout record.
|
|
18
|
+
* @return {Promise<LayoutRecord<PickPortals<T, OPTIONS['portals'][number]>>>}
|
|
19
|
+
* The newly created layout record.
|
|
20
|
+
*/
|
|
11
21
|
async create(options) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
for (
|
|
15
|
-
fields[_field.name] =
|
|
22
|
+
const metadata = await this.layout.getLayoutMeta();
|
|
23
|
+
const fields = {};
|
|
24
|
+
for (const _field of metadata.fieldMetaData) {
|
|
25
|
+
fields[_field.name] = '';
|
|
16
26
|
}
|
|
17
|
-
|
|
18
|
-
for (
|
|
27
|
+
const portals = {};
|
|
28
|
+
for (const _portal of Object.keys(metadata.portalMetaData))
|
|
19
29
|
portals[_portal] = [];
|
|
20
30
|
return new LayoutRecord(this.layout, -1, 0, fields, portals);
|
|
21
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Retrieves a layout record based on the given recordId.
|
|
34
|
+
*
|
|
35
|
+
* @param {number} recordId - The identifier of the record to retrieve.
|
|
36
|
+
*
|
|
37
|
+
* @returns {Promise<LayoutRecord<PickPortals<T, never>>>} - A Promise that resolves with the retrieved layout record.
|
|
38
|
+
*/
|
|
22
39
|
async get(recordId) {
|
|
23
40
|
await this.layout.getLayoutMeta();
|
|
24
|
-
|
|
41
|
+
const record = new LayoutRecord(this.layout, recordId);
|
|
25
42
|
await record.get();
|
|
26
43
|
return record;
|
|
27
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Creates a new instance of RecordGetOperation with the given options.
|
|
47
|
+
*
|
|
48
|
+
* @param {Array} options - An array of options for the operation.
|
|
49
|
+
* @return {RecordGetOperation} - A new instance of RecordGetOperation.
|
|
50
|
+
*/
|
|
28
51
|
list(options) {
|
|
29
52
|
return new RecordGetOperation(this.layout, options);
|
|
30
53
|
}
|
|
@@ -2,42 +2,65 @@
|
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {LayoutRecord} from
|
|
6
|
-
import {LayoutInterface} from
|
|
7
|
-
import {LayoutBase} from
|
|
8
|
-
import {GetOperationOptions, RecordGetOperation} from
|
|
9
|
-
import {PickPortals, RecordFetchOptions} from
|
|
10
|
-
import {ApiFieldData} from
|
|
5
|
+
import {LayoutRecord} from '../records/layoutRecord.js'
|
|
6
|
+
import {type LayoutInterface} from './layoutInterface.js'
|
|
7
|
+
import {type LayoutBase} from './layoutBase.js'
|
|
8
|
+
import {type GetOperationOptions, RecordGetOperation} from '../records/getOperations/recordGetOperation.js'
|
|
9
|
+
import {type PickPortals, type RecordFetchOptions} from '../types.js'
|
|
10
|
+
import {type ApiFieldData} from '../models/apiResults.js'
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Manager class for handling layout records.
|
|
14
|
+
*/
|
|
12
15
|
export class LayoutRecordManager<T extends LayoutInterface> {
|
|
13
|
-
readonly layout: LayoutBase
|
|
14
|
-
constructor(layout: LayoutBase) {
|
|
16
|
+
readonly layout: LayoutBase
|
|
17
|
+
constructor (layout: LayoutBase) {
|
|
15
18
|
this.layout = layout
|
|
16
19
|
}
|
|
17
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new layout record with the provided options.
|
|
23
|
+
*
|
|
24
|
+
* @param {OPTIONS} options - The options for creating the layout record.
|
|
25
|
+
* @return {Promise<LayoutRecord<PickPortals<T, OPTIONS['portals'][number]>>>}
|
|
26
|
+
* The newly created layout record.
|
|
27
|
+
*/
|
|
18
28
|
async create<OPTIONS extends RecordFetchOptions>(options: OPTIONS): Promise<LayoutRecord<
|
|
19
|
-
|
|
29
|
+
PickPortals<T, OPTIONS['portals'][number]>
|
|
20
30
|
>> {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
for (
|
|
24
|
-
fields[_field.name] =
|
|
31
|
+
const metadata = await this.layout.getLayoutMeta()
|
|
32
|
+
const fields: ApiFieldData = {}
|
|
33
|
+
for (const _field of metadata.fieldMetaData) {
|
|
34
|
+
fields[_field.name] = ''
|
|
25
35
|
}
|
|
26
|
-
|
|
27
|
-
for (
|
|
36
|
+
const portals: Record<string, []> = {}
|
|
37
|
+
for (const _portal of Object.keys(metadata.portalMetaData)) portals[_portal] = []
|
|
28
38
|
return new LayoutRecord(this.layout, -1, 0, fields, portals)
|
|
29
39
|
}
|
|
30
40
|
|
|
31
|
-
|
|
32
|
-
|
|
41
|
+
/**
|
|
42
|
+
* Retrieves a layout record based on the given recordId.
|
|
43
|
+
*
|
|
44
|
+
* @param {number} recordId - The identifier of the record to retrieve.
|
|
45
|
+
*
|
|
46
|
+
* @returns {Promise<LayoutRecord<PickPortals<T, never>>>} - A Promise that resolves with the retrieved layout record.
|
|
47
|
+
*/
|
|
48
|
+
async get (recordId: number): Promise<LayoutRecord<
|
|
49
|
+
PickPortals<T, never>
|
|
33
50
|
>> {
|
|
34
51
|
await this.layout.getLayoutMeta()
|
|
35
|
-
|
|
52
|
+
const record = new LayoutRecord<PickPortals<T, never>>(this.layout, recordId)
|
|
36
53
|
await record.get()
|
|
37
54
|
return record
|
|
38
55
|
}
|
|
39
56
|
|
|
57
|
+
/**
|
|
58
|
+
* Creates a new instance of RecordGetOperation with the given options.
|
|
59
|
+
*
|
|
60
|
+
* @param {Array} options - An array of options for the operation.
|
|
61
|
+
* @return {RecordGetOperation} - A new instance of RecordGetOperation.
|
|
62
|
+
*/
|
|
40
63
|
list<OPTIONS extends GetOperationOptions<T>>(options: OPTIONS) {
|
|
41
64
|
return new RecordGetOperation<T, OPTIONS>(this.layout, options)
|
|
42
65
|
}
|
|
43
|
-
}
|
|
66
|
+
}
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
import { Field, FieldValue } from
|
|
2
|
-
export
|
|
3
|
-
[fieldName: string]: Field<FieldValue>;
|
|
4
|
-
}
|
|
1
|
+
import { type Field, type FieldValue } from '../records/field.js';
|
|
2
|
+
export type RecordFieldsMap = Record<string, Field<FieldValue>>;
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {Field, FieldValue} from
|
|
5
|
+
import {type Field, type FieldValue} from '../records/field.js'
|
|
6
6
|
|
|
7
|
-
export
|
|
8
|
-
[fieldName: string]: Field<FieldValue>
|
|
9
|
-
}
|
|
7
|
+
export type RecordFieldsMap = Record<string, Field<FieldValue>>
|
|
@@ -38,9 +38,7 @@ export interface ApiLayout {
|
|
|
38
38
|
}
|
|
39
39
|
export interface ApiLayoutMetadata {
|
|
40
40
|
fieldMetaData: ApiFieldMetadata[];
|
|
41
|
-
portalMetaData:
|
|
42
|
-
[key: string]: ApiFieldMetadata[];
|
|
43
|
-
};
|
|
41
|
+
portalMetaData: Record<string, ApiFieldMetadata[]>;
|
|
44
42
|
valueLists: ApiValueList[];
|
|
45
43
|
}
|
|
46
44
|
export interface ApiFieldMetadata {
|
|
@@ -62,10 +60,10 @@ export interface ApiFieldMetadata {
|
|
|
62
60
|
export interface ApiValueList {
|
|
63
61
|
name: string;
|
|
64
62
|
type: string;
|
|
65
|
-
values: {
|
|
63
|
+
values: Array<{
|
|
66
64
|
value: string;
|
|
67
65
|
displayName: string;
|
|
68
|
-
}
|
|
66
|
+
}>;
|
|
69
67
|
}
|
|
70
68
|
export interface ApiScriptResult {
|
|
71
69
|
scriptError: string;
|
|
@@ -75,12 +73,8 @@ export interface ApiRecordResponseObj {
|
|
|
75
73
|
data: ApiRowDataDef[];
|
|
76
74
|
dataInfo: ApiResultSetObj;
|
|
77
75
|
}
|
|
78
|
-
export type ApiFieldData =
|
|
79
|
-
|
|
80
|
-
};
|
|
81
|
-
export interface ApiPortalData {
|
|
82
|
-
[key: string]: ApiFieldData[];
|
|
83
|
-
}
|
|
76
|
+
export type ApiFieldData = Record<string, string | number>;
|
|
77
|
+
export type ApiPortalData = Record<string, ApiFieldData[]>;
|
|
84
78
|
export interface ApiResultSetObj {
|
|
85
79
|
database: string;
|
|
86
80
|
layout: string;
|
|
@@ -94,10 +88,10 @@ export interface ApiRowDataDef {
|
|
|
94
88
|
portalData: ApiPortalData;
|
|
95
89
|
modId: string;
|
|
96
90
|
recordId: string;
|
|
97
|
-
portalDataInfo?: {
|
|
91
|
+
portalDataInfo?: Array<{
|
|
98
92
|
database: string;
|
|
99
93
|
table: string;
|
|
100
94
|
foundCount: number;
|
|
101
95
|
returnedCount: number;
|
|
102
|
-
}
|
|
96
|
+
}>;
|
|
103
97
|
}
|
package/src/models/apiResults.ts
CHANGED
|
@@ -3,108 +3,108 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
export enum ApiFieldTypes {
|
|
6
|
-
NORMAL =
|
|
7
|
-
CALCULATION =
|
|
8
|
-
SUMMARY =
|
|
6
|
+
NORMAL = 'normal',
|
|
7
|
+
CALCULATION = 'calculation',
|
|
8
|
+
SUMMARY = 'summary'
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export enum ApiFieldDisplayTypes {
|
|
12
|
-
EDIT_TEXT =
|
|
13
|
-
POPUP_LIST =
|
|
14
|
-
CHECKBOX =
|
|
15
|
-
RADIO_BUTTONS =
|
|
16
|
-
SELECTION_LIST =
|
|
17
|
-
CALENDAR =
|
|
18
|
-
SECURE_TEXT =
|
|
12
|
+
EDIT_TEXT = 'editText',
|
|
13
|
+
POPUP_LIST = 'popupList',
|
|
14
|
+
CHECKBOX = 'checkBox',
|
|
15
|
+
RADIO_BUTTONS = 'radioButtons',
|
|
16
|
+
SELECTION_LIST = 'selectionList',
|
|
17
|
+
CALENDAR = 'calendar',
|
|
18
|
+
SECURE_TEXT = 'secureText'
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export enum ApiFieldResultTypes {
|
|
22
|
-
TEXT =
|
|
23
|
-
NUMBER =
|
|
24
|
-
DATE =
|
|
25
|
-
TIME =
|
|
26
|
-
TIMESTAMP =
|
|
27
|
-
CONTAINER =
|
|
22
|
+
TEXT = 'text',
|
|
23
|
+
NUMBER = 'number',
|
|
24
|
+
DATE = 'date',
|
|
25
|
+
TIME = 'time',
|
|
26
|
+
TIMESTAMP = 'timeStamp',
|
|
27
|
+
CONTAINER = 'container'
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
export interface ApiMessage {
|
|
31
|
-
code: string
|
|
31
|
+
code: string
|
|
32
32
|
message: string
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export interface ApiResults<T = unknown> {
|
|
36
|
-
response?: null | T & {scriptError
|
|
37
|
-
messages: ApiMessage[]
|
|
36
|
+
response?: null | T & { scriptError?: string }
|
|
37
|
+
messages: ApiMessage[]
|
|
38
38
|
httpStatus: number
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
export interface ApiLayout {
|
|
42
|
-
name: string
|
|
43
|
-
isFolder?: boolean
|
|
42
|
+
name: string
|
|
43
|
+
isFolder?: boolean
|
|
44
44
|
folderLayoutNames?: ApiLayout[]
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
export interface ApiLayoutMetadata {
|
|
48
|
-
fieldMetaData: ApiFieldMetadata[]
|
|
49
|
-
portalMetaData:
|
|
48
|
+
fieldMetaData: ApiFieldMetadata[]
|
|
49
|
+
portalMetaData: Record<string, ApiFieldMetadata[]>
|
|
50
50
|
valueLists: ApiValueList[]
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
export interface ApiFieldMetadata {
|
|
54
|
-
name: string
|
|
55
|
-
type: ApiFieldTypes
|
|
56
|
-
displayType: ApiFieldDisplayTypes
|
|
57
|
-
result: ApiFieldResultTypes
|
|
58
|
-
global: boolean
|
|
59
|
-
autoEnter: boolean
|
|
60
|
-
fourDigitYear: boolean
|
|
61
|
-
maxRepeat: number
|
|
62
|
-
maxCharacters: number
|
|
63
|
-
notEmpty: boolean
|
|
64
|
-
numeric: boolean
|
|
65
|
-
repetitions: number
|
|
66
|
-
timeOfDay: boolean
|
|
54
|
+
name: string
|
|
55
|
+
type: ApiFieldTypes
|
|
56
|
+
displayType: ApiFieldDisplayTypes
|
|
57
|
+
result: ApiFieldResultTypes
|
|
58
|
+
global: boolean
|
|
59
|
+
autoEnter: boolean
|
|
60
|
+
fourDigitYear: boolean
|
|
61
|
+
maxRepeat: number
|
|
62
|
+
maxCharacters: number
|
|
63
|
+
notEmpty: boolean
|
|
64
|
+
numeric: boolean
|
|
65
|
+
repetitions: number
|
|
66
|
+
timeOfDay: boolean
|
|
67
67
|
valueList: string
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export interface ApiValueList {
|
|
71
|
-
name: string
|
|
72
|
-
type: string
|
|
73
|
-
values: {value: string, displayName: string}
|
|
71
|
+
name: string
|
|
72
|
+
type: string
|
|
73
|
+
values: Array<{ value: string, displayName: string }>
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
export interface ApiScriptResult {
|
|
77
|
-
scriptError: string
|
|
77
|
+
scriptError: string
|
|
78
78
|
scriptResult?: string
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
export interface ApiRecordResponseObj {
|
|
82
|
-
data: ApiRowDataDef[]
|
|
82
|
+
data: ApiRowDataDef[]
|
|
83
83
|
dataInfo: ApiResultSetObj
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
export type ApiFieldData =
|
|
86
|
+
export type ApiFieldData = Record<string, string | number>
|
|
87
87
|
|
|
88
|
-
export
|
|
88
|
+
export type ApiPortalData = Record<string, ApiFieldData[]>
|
|
89
89
|
|
|
90
90
|
export interface ApiResultSetObj {
|
|
91
|
-
database: string
|
|
92
|
-
layout: string
|
|
93
|
-
table: string
|
|
94
|
-
totalRecordCount: number
|
|
95
|
-
foundCount: number
|
|
91
|
+
database: string
|
|
92
|
+
layout: string
|
|
93
|
+
table: string
|
|
94
|
+
totalRecordCount: number
|
|
95
|
+
foundCount: number
|
|
96
96
|
returnedCount: number
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
export interface ApiRowDataDef {
|
|
100
|
-
fieldData: ApiFieldData
|
|
101
|
-
portalData: ApiPortalData
|
|
102
|
-
modId: string
|
|
103
|
-
recordId: string
|
|
104
|
-
portalDataInfo?: {
|
|
105
|
-
database: string
|
|
106
|
-
table: string
|
|
107
|
-
foundCount: number
|
|
100
|
+
fieldData: ApiFieldData
|
|
101
|
+
portalData: ApiPortalData
|
|
102
|
+
modId: string
|
|
103
|
+
recordId: string
|
|
104
|
+
portalDataInfo?: Array<{
|
|
105
|
+
database: string
|
|
106
|
+
table: string
|
|
107
|
+
foundCount: number
|
|
108
108
|
returnedCount: number
|
|
109
|
-
}
|
|
110
|
-
}
|
|
109
|
+
}>
|
|
110
|
+
}
|
package/src/records/field.d.ts
CHANGED
|
@@ -1,31 +1,61 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
2
|
/// <reference types="node" resolution-mode="require"/>
|
|
3
|
-
import * as http from
|
|
4
|
-
import { ContainerBufferResult, DownloadModes, RecordTypes } from
|
|
5
|
-
import { ApiFieldMetadata } from
|
|
6
|
-
import { LayoutBase } from
|
|
7
|
-
import { Moment } from
|
|
3
|
+
import type * as http from 'http';
|
|
4
|
+
import { type ContainerBufferResult, DownloadModes, RecordTypes } from '../types.js';
|
|
5
|
+
import { type ApiFieldMetadata } from '../models/apiResults.js';
|
|
6
|
+
import { type LayoutBase } from '../layouts/layoutBase.js';
|
|
7
|
+
import { type Moment } from 'moment';
|
|
8
8
|
export type FieldValue = string | number | Moment | Container;
|
|
9
9
|
export type Container = null;
|
|
10
|
-
export
|
|
10
|
+
export interface Parentable {
|
|
11
11
|
layout: LayoutBase;
|
|
12
12
|
type: RecordTypes;
|
|
13
13
|
endpoint: string;
|
|
14
|
-
|
|
14
|
+
portal?: {
|
|
15
|
+
name: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A class representing a field in a record.
|
|
20
|
+
*
|
|
21
|
+
* @template T - The type of the field value.
|
|
22
|
+
*/
|
|
15
23
|
export declare class Field<T extends FieldValue> {
|
|
16
24
|
parent: Parentable;
|
|
17
25
|
id: string;
|
|
18
|
-
protected _value: T;
|
|
26
|
+
protected _value: T | null;
|
|
19
27
|
edited: boolean;
|
|
20
28
|
constructor(record: Parentable, id: string, contents: T);
|
|
21
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Sets the value of the field.
|
|
31
|
+
*
|
|
32
|
+
* @param {T | null} content - The new content value to be set. Can be either the type T or null.
|
|
33
|
+
* @throws {Error} Cannot set container value using set(). Use upload() instead, if the result is a 'container'.
|
|
34
|
+
*/
|
|
35
|
+
set(content: T | null): void;
|
|
22
36
|
get metadata(): ApiFieldMetadata;
|
|
23
|
-
get value(): T;
|
|
37
|
+
get value(): T | null;
|
|
24
38
|
set value(value: T);
|
|
25
39
|
get string(): string;
|
|
26
|
-
|
|
27
|
-
|
|
40
|
+
/**
|
|
41
|
+
* Uploads a file to the container field.
|
|
42
|
+
*
|
|
43
|
+
* @param {Buffer} buffer - The file content as a buffer.
|
|
44
|
+
* @param {string} filename - The filename of the file.
|
|
45
|
+
* @param {string} mime - The MIME type of the file.
|
|
46
|
+
*
|
|
47
|
+
* @throws {Error} - Cannot upload a file to the field if it's not a container field.
|
|
48
|
+
* @throws {Error} - Upload failed with HTTP error.
|
|
49
|
+
*
|
|
50
|
+
* @returns {Promise<void>} - A promise that resolves when the file is successfully uploaded.
|
|
51
|
+
*/
|
|
28
52
|
upload(buffer: Buffer, filename: string, mime: string): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Downloads a resource from the server using the specified download mode.
|
|
55
|
+
*
|
|
56
|
+
* @param {DownloadModes} mode - The mode to use for downloading the resource.
|
|
57
|
+
* @return {Promise<http.IncomingMessage>} - A promise that resolves with the incoming message representing the downloaded resource.
|
|
58
|
+
*/
|
|
29
59
|
download(mode: DownloadModes.Stream): Promise<http.IncomingMessage>;
|
|
30
60
|
download(mode: DownloadModes.Buffer): Promise<ContainerBufferResult>;
|
|
31
61
|
}
|
package/src/records/field.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Copyright (c) 2023-2024. See LICENSE file for more information
|
|
3
3
|
*/
|
|
4
|
-
import { DownloadModes, RecordTypes } from
|
|
5
|
-
import { ApiFieldDisplayTypes, ApiFieldResultTypes, ApiFieldTypes } from
|
|
4
|
+
import { DownloadModes, RecordTypes } from '../types.js';
|
|
5
|
+
import { ApiFieldDisplayTypes, ApiFieldResultTypes, ApiFieldTypes } from '../models/apiResults.js';
|
|
6
|
+
/**
|
|
7
|
+
* A class representing a field in a record.
|
|
8
|
+
*
|
|
9
|
+
* @template T - The type of the field value.
|
|
10
|
+
*/
|
|
6
11
|
export class Field {
|
|
7
12
|
parent;
|
|
8
13
|
id;
|
|
@@ -14,13 +19,15 @@ export class Field {
|
|
|
14
19
|
this._value = contents;
|
|
15
20
|
this.edited = false;
|
|
16
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* Sets the value of the field.
|
|
24
|
+
*
|
|
25
|
+
* @param {T | null} content - The new content value to be set. Can be either the type T or null.
|
|
26
|
+
* @throws {Error} Cannot set container value using set(). Use upload() instead, if the result is a 'container'.
|
|
27
|
+
*/
|
|
17
28
|
set(content) {
|
|
18
|
-
if (this.metadata.result ===
|
|
19
|
-
throw
|
|
20
|
-
// @ts-ignore
|
|
21
|
-
if (!content)
|
|
22
|
-
this._value = "";
|
|
23
|
-
// @ts-ignore
|
|
29
|
+
if (this.metadata.result === 'container')
|
|
30
|
+
throw new Error('Cannot set container value using set(). Use upload() instead.');
|
|
24
31
|
else
|
|
25
32
|
this._value = content;
|
|
26
33
|
this.edited = true;
|
|
@@ -42,30 +49,30 @@ export class Field {
|
|
|
42
49
|
numeric: false,
|
|
43
50
|
timeOfDay: false,
|
|
44
51
|
repetitions: 1,
|
|
45
|
-
valueList:
|
|
52
|
+
valueList: ''
|
|
46
53
|
};
|
|
47
54
|
}
|
|
48
|
-
if (this.parent.type === RecordTypes.PORTAL) {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
55
|
+
if (this.parent.type === RecordTypes.PORTAL && this.parent.portal) {
|
|
56
|
+
return this.parent.layout.metadata.portalMetaData[this.parent.portal.name || 'portal not attached'].find(i => i.name === this.id) ??
|
|
57
|
+
{
|
|
58
|
+
name: this.id.toString(),
|
|
59
|
+
type: ApiFieldTypes.NORMAL,
|
|
60
|
+
displayType: ApiFieldDisplayTypes.EDIT_TEXT,
|
|
61
|
+
result: ApiFieldResultTypes.TEXT,
|
|
62
|
+
global: false,
|
|
63
|
+
autoEnter: true,
|
|
64
|
+
fourDigitYear: false,
|
|
65
|
+
maxRepeat: 1,
|
|
66
|
+
maxCharacters: 0,
|
|
67
|
+
notEmpty: false,
|
|
68
|
+
numeric: false,
|
|
69
|
+
timeOfDay: false,
|
|
70
|
+
repetitions: 1,
|
|
71
|
+
valueList: ''
|
|
72
|
+
};
|
|
66
73
|
}
|
|
67
74
|
else {
|
|
68
|
-
return this.parent.layout.metadata.fieldMetaData.find(i => i.name === this.id)
|
|
75
|
+
return this.parent.layout.metadata.fieldMetaData.find(i => i.name === this.id) ?? {
|
|
69
76
|
name: this.id.toString(),
|
|
70
77
|
type: ApiFieldTypes.NORMAL,
|
|
71
78
|
displayType: ApiFieldDisplayTypes.EDIT_TEXT,
|
|
@@ -79,7 +86,7 @@ export class Field {
|
|
|
79
86
|
numeric: false,
|
|
80
87
|
timeOfDay: false,
|
|
81
88
|
repetitions: 1,
|
|
82
|
-
valueList:
|
|
89
|
+
valueList: ''
|
|
83
90
|
};
|
|
84
91
|
}
|
|
85
92
|
}
|
|
@@ -91,32 +98,35 @@ export class Field {
|
|
|
91
98
|
this._value = value;
|
|
92
99
|
}
|
|
93
100
|
get string() {
|
|
94
|
-
if (typeof this._value ===
|
|
95
|
-
return this._value;
|
|
96
|
-
}
|
|
97
|
-
throw "Field value is not a string";
|
|
98
|
-
}
|
|
99
|
-
get date() {
|
|
100
|
-
if (this._value instanceof Date) {
|
|
101
|
+
if (typeof this._value === 'string') {
|
|
101
102
|
return this._value;
|
|
102
103
|
}
|
|
103
|
-
throw
|
|
104
|
-
}
|
|
105
|
-
get number() {
|
|
106
|
-
if (typeof this._value === "number") {
|
|
107
|
-
return this._value;
|
|
108
|
-
}
|
|
109
|
-
throw "Field value is not a number";
|
|
104
|
+
throw new Error('Field value is not a string');
|
|
110
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Uploads a file to the container field.
|
|
108
|
+
*
|
|
109
|
+
* @param {Buffer} buffer - The file content as a buffer.
|
|
110
|
+
* @param {string} filename - The filename of the file.
|
|
111
|
+
* @param {string} mime - The MIME type of the file.
|
|
112
|
+
*
|
|
113
|
+
* @throws {Error} - Cannot upload a file to the field if it's not a container field.
|
|
114
|
+
* @throws {Error} - Upload failed with HTTP error.
|
|
115
|
+
*
|
|
116
|
+
* @returns {Promise<void>} - A promise that resolves when the file is successfully uploaded.
|
|
117
|
+
*/
|
|
111
118
|
async upload(buffer, filename, mime) {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
form.append(
|
|
117
|
-
|
|
118
|
-
method:
|
|
119
|
-
|
|
119
|
+
if (this.metadata.result !== 'container') {
|
|
120
|
+
throw new Error('Cannot upload a file to the field; ' + this.id + ' (not a container field)');
|
|
121
|
+
}
|
|
122
|
+
const form = new FormData();
|
|
123
|
+
form.append('upload', new File([buffer], filename, { type: mime }));
|
|
124
|
+
const res = await this.parent.layout.database._apiRequestRaw(`${this.parent.endpoint}/containers/${this.id}/1`, {
|
|
125
|
+
method: 'POST',
|
|
126
|
+
headers: {
|
|
127
|
+
Authorization: 'Bearer ' + this.parent.layout.database.token,
|
|
128
|
+
'Content-Type': 'multipart/form-data'
|
|
129
|
+
},
|
|
120
130
|
body: form
|
|
121
131
|
});
|
|
122
132
|
if (!res.ok)
|
|
@@ -124,23 +134,23 @@ export class Field {
|
|
|
124
134
|
}
|
|
125
135
|
async download(mode = DownloadModes.Stream) {
|
|
126
136
|
if (this.metadata.result !== ApiFieldResultTypes.CONTAINER)
|
|
127
|
-
throw new Error(
|
|
128
|
-
|
|
137
|
+
throw new Error('Cannot perform download() on a non-container field');
|
|
138
|
+
const stream = await this.parent.layout.database.streamURL(this.string);
|
|
129
139
|
if (mode === DownloadModes.Stream) {
|
|
130
140
|
return stream;
|
|
131
141
|
}
|
|
132
|
-
|
|
133
|
-
return new Promise((resolve, reject) => {
|
|
134
|
-
stream.on(
|
|
142
|
+
const body = [];
|
|
143
|
+
return await new Promise((resolve, reject) => {
|
|
144
|
+
stream.on('data', (chunk) => {
|
|
135
145
|
body.push(chunk);
|
|
136
146
|
});
|
|
137
|
-
stream.on(
|
|
147
|
+
stream.on('error', (e) => {
|
|
138
148
|
reject(e);
|
|
139
149
|
});
|
|
140
|
-
stream.on(
|
|
150
|
+
stream.on('end', () => {
|
|
141
151
|
resolve({
|
|
142
152
|
buffer: Buffer.concat(body),
|
|
143
|
-
mime: stream.headers[
|
|
153
|
+
mime: stream.headers['content-type'],
|
|
144
154
|
request: stream
|
|
145
155
|
});
|
|
146
156
|
});
|