@jd-data-limited/easy-fm 4.1.6 → 4.1.9

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.
Files changed (86) hide show
  1. package/dist/bin/cli.js +17 -0
  2. package/dist/bin/generateTypes.js +161 -0
  3. package/{src → dist}/connection/FMHost.js +3 -2
  4. package/{src → dist}/connection/database.d.ts +0 -1
  5. package/{src → dist}/connection/database.js +22 -39
  6. package/dist/index.d.ts +18 -0
  7. package/dist/index.js +16 -0
  8. package/{src → dist}/records/field.d.ts +0 -1
  9. package/{src → dist}/records/getOperations/recordGetOperation.d.ts +6 -2
  10. package/{src → dist}/records/getOperations/recordGetOperation.js +9 -5
  11. package/{src → dist}/records/layoutRecord.d.ts +1 -1
  12. package/{src → dist}/records/layoutRecord.js +5 -6
  13. package/{src → dist}/records/recordBase.d.ts +0 -1
  14. package/{src → dist}/types.d.ts +0 -2
  15. package/package.json +18 -10
  16. package/src/FMError.ts +0 -1033
  17. package/src/bin/cli.js +0 -17
  18. package/src/bin/cli.ts +0 -22
  19. package/src/bin/generateTypes.d.ts +0 -1
  20. package/src/bin/generateTypes.js +0 -161
  21. package/src/bin/generateTypes.ts +0 -189
  22. package/src/connection/FMHost.ts +0 -123
  23. package/src/connection/HostBase.ts +0 -18
  24. package/src/connection/database.ts +0 -257
  25. package/src/connection/databaseBase.ts +0 -19
  26. package/src/connection/generateAuthorizationHeaders.ts +0 -32
  27. package/src/connection/requestHoldable.d.ts +0 -10
  28. package/src/connection/requestHoldable.js +0 -44
  29. package/src/databaseStructure.ts +0 -10
  30. package/src/index.d.ts +0 -18
  31. package/src/index.js +0 -18
  32. package/src/index.ts +0 -47
  33. package/src/layouts/layout.ts +0 -66
  34. package/src/layouts/layoutBase.ts +0 -16
  35. package/src/layouts/layoutInterface.ts +0 -13
  36. package/src/layouts/layoutRecordManager.ts +0 -66
  37. package/src/layouts/recordFieldsMap.ts +0 -7
  38. package/src/models/apiResults.ts +0 -110
  39. package/src/records/field.ts +0 -235
  40. package/src/records/getOperations/recordGetOperation.ts +0 -268
  41. package/src/records/layoutRecord.ts +0 -247
  42. package/src/records/layoutRecordBase.ts +0 -10
  43. package/src/records/portal.ts +0 -43
  44. package/src/records/portalBase.ts +0 -14
  45. package/src/records/portalRecord.ts +0 -52
  46. package/src/records/recordBase.ts +0 -91
  47. package/src/types.ts +0 -162
  48. package/src/utils/query.ts +0 -59
  49. /package/{src → dist}/FMError.d.ts +0 -0
  50. /package/{src → dist}/FMError.js +0 -0
  51. /package/{src → dist}/bin/cli.d.ts +0 -0
  52. /package/{src/bin/dist → dist}/bin/generateTypes.d.ts +0 -0
  53. /package/{src → dist}/connection/FMHost.d.ts +0 -0
  54. /package/{src → dist}/connection/HostBase.d.ts +0 -0
  55. /package/{src → dist}/connection/HostBase.js +0 -0
  56. /package/{src → dist}/connection/databaseBase.d.ts +0 -0
  57. /package/{src → dist}/connection/databaseBase.js +0 -0
  58. /package/{src → dist}/connection/generateAuthorizationHeaders.d.ts +0 -0
  59. /package/{src → dist}/connection/generateAuthorizationHeaders.js +0 -0
  60. /package/{src → dist}/databaseStructure.d.ts +0 -0
  61. /package/{src → dist}/databaseStructure.js +0 -0
  62. /package/{src → dist}/layouts/layout.d.ts +0 -0
  63. /package/{src → dist}/layouts/layout.js +0 -0
  64. /package/{src → dist}/layouts/layoutBase.d.ts +0 -0
  65. /package/{src → dist}/layouts/layoutBase.js +0 -0
  66. /package/{src → dist}/layouts/layoutInterface.d.ts +0 -0
  67. /package/{src → dist}/layouts/layoutInterface.js +0 -0
  68. /package/{src → dist}/layouts/layoutRecordManager.d.ts +0 -0
  69. /package/{src → dist}/layouts/layoutRecordManager.js +0 -0
  70. /package/{src → dist}/layouts/recordFieldsMap.d.ts +0 -0
  71. /package/{src → dist}/layouts/recordFieldsMap.js +0 -0
  72. /package/{src → dist}/models/apiResults.d.ts +0 -0
  73. /package/{src → dist}/models/apiResults.js +0 -0
  74. /package/{src → dist}/records/field.js +0 -0
  75. /package/{src → dist}/records/layoutRecordBase.d.ts +0 -0
  76. /package/{src → dist}/records/layoutRecordBase.js +0 -0
  77. /package/{src → dist}/records/portal.d.ts +0 -0
  78. /package/{src → dist}/records/portal.js +0 -0
  79. /package/{src → dist}/records/portalBase.d.ts +0 -0
  80. /package/{src → dist}/records/portalBase.js +0 -0
  81. /package/{src → dist}/records/portalRecord.d.ts +0 -0
  82. /package/{src → dist}/records/portalRecord.js +0 -0
  83. /package/{src → dist}/records/recordBase.js +0 -0
  84. /package/{src → dist}/types.js +0 -0
  85. /package/{src → dist}/utils/query.d.ts +0 -0
  86. /package/{src → dist}/utils/query.js +0 -0
@@ -1,247 +0,0 @@
1
- /*
2
- * Copyright (c) 2023-2024. See LICENSE file for more information
3
- */
4
-
5
- import {type extraBodyOptions} from '../types.js'
6
- import {RecordBase} from './recordBase.js'
7
- import {PortalRecord} from './portalRecord.js'
8
- import {Portal} from './portal.js'
9
- import {type LayoutInterface} from '../layouts/layoutInterface.js'
10
- import {FMError} from '../FMError.js'
11
- import {type LayoutRecordBase} from './layoutRecordBase.js'
12
- import {
13
- type ApiFieldData,
14
- type ApiPortalData,
15
- type ApiRecordResponseObj,
16
- type ApiRowDataDef
17
- } from '../models/apiResults.js'
18
- import {type LayoutBase} from '../layouts/layoutBase.js'
19
- import * as moment from 'moment/moment.js'
20
- import {type Field, type FieldValue} from './field.js'
21
-
22
- export class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT['fields']> implements LayoutRecordBase {
23
- portals: LAYOUT['portals'] = {}
24
- private readonly portalsToInclude: Array<string | number | symbol>
25
-
26
- constructor (
27
- layout: LayoutBase,
28
- recordId: number | string,
29
- modId = recordId,
30
- fieldData: Record<string, string | number> = {},
31
- portalData: ApiPortalData | null = null, portalsToInclude: Array<keyof LAYOUT['portals']> = []) {
32
- super(layout, parseInt(recordId as string), parseInt(modId as string), fieldData)
33
- this.portalsToInclude = portalsToInclude
34
- if (portalData) {
35
- this.processPortalData(portalData)
36
- }
37
- }
38
-
39
- get portalsArray (): Array<Portal<any>> {
40
- return Object.values(this.portals)
41
- }
42
-
43
- /**
44
- * Asynchronously commits the changes made to the current record.
45
- * @param {extraBodyOptions} extraBody - The options for the extra body elements.
46
- * @returns {Promise<this>} - A promise that resolves with the modified object.
47
- * @throws {FMError} - If an error occurs during the commit process.
48
- */
49
- async commit (extraBody: extraBodyOptions = {}): Promise<this> {
50
- const data: any = this.toObject()
51
- delete data.recordId
52
- delete data.modId
53
-
54
- if (extraBody.scripts?.after) {
55
- data.script = extraBody.scripts.after.name
56
- if (extraBody.scripts.after.parameter) data['script.param'] = extraBody.scripts.after.parameter
57
- }
58
- if (extraBody.scripts?.prerequest) {
59
- data['script.prerequest'] = extraBody.scripts.prerequest.name
60
- if (extraBody.scripts.prerequest.parameter) data['script.prerequest.param'] = extraBody.scripts.prerequest.parameter
61
- }
62
- if (extraBody.scripts?.presort) {
63
- data['script.presort'] = extraBody.scripts.presort.name
64
- if (extraBody.scripts.presort.parameter) data['script.presort.param'] = extraBody.scripts.presort.parameter
65
- }
66
- if (extraBody.options) data.options = extraBody.options
67
- if (extraBody.deleteRelatedRecords) data.fieldData.deleteRelated = extraBody.deleteRelatedRecords.map(i => `${i.table}.${i.recordId}`)
68
-
69
- if (this.recordId === -1) {
70
- // This is a new LayoutRecord
71
- const res = await this.layout.database._apiRequestJSON<{ recordId: string, modId: string }>(`${this.layout.endpoint}/records`, {
72
- method: 'POST',
73
- body: JSON.stringify(data)
74
- })
75
-
76
- if (!res.response) {
77
- throw new FMError(res.messages[0].code, res.httpStatus, res)
78
- } else if (typeof res.response.scriptError !== 'undefined' && res.response.scriptError !== '0') {
79
- throw new FMError(res.response.scriptError, res.httpStatus, res)
80
- } else if (res.messages[0].code === '0') {
81
- this.recordId = parseInt(res.response.recordId)
82
- this.modId = parseInt(res.response.modId)
83
- return this
84
- } else {
85
- throw new FMError(res.messages[0].code, res.httpStatus, res)
86
- }
87
- }
88
-
89
- // for (let item of Object.keys(data)) extraBody[item] = data[item]
90
- const res = await this.layout.database._apiRequestJSON<{
91
- modId: string,
92
- newPortalRecordInfo: Array<{
93
- tableName: string
94
- recordId: string
95
- modId: string
96
- }>
97
- }>(this.endpoint, {
98
- method: 'PATCH',
99
- body: JSON.stringify(data)
100
- })
101
- if (!res.response) {
102
- throw new FMError(res.messages[0].code, res.httpStatus, res)
103
- } else if (typeof res.response.scriptError !== 'undefined' && res.response.scriptError !== '0') {
104
- throw new FMError(res.response.scriptError, res.httpStatus, res)
105
- } else if (res.messages[0].code === '0') {
106
- this.modId = +res.response.modId
107
- this._onSave()
108
- return this
109
- } else {
110
- throw new FMError(res.messages[0].code, res.httpStatus, res)
111
- }
112
- }
113
-
114
- protected processPortalData (portalData: ApiPortalData): void {
115
- for (const portalName of Object.keys(portalData)) {
116
- const _portal = new Portal(this, portalName)
117
- _portal.records = portalData[portalName].map(item => {
118
- const fieldData = item
119
- delete fieldData.recordId
120
- delete fieldData.modId
121
- return new PortalRecord(this, _portal, parseInt(item.recordId as string), parseInt(item.modId as string), fieldData)
122
- })
123
-
124
- // @ts-expect-error - This code is actually correct, but throws a typescript error
125
- this.portals[portalName] = _portal
126
- }
127
- }
128
-
129
- /**
130
- * Re-fetches the current record from the database server.
131
- * Throws an error if commit() has not been called.
132
- *
133
- * @return {Promise<this>} A Promise that resolves to this RecordBase instance if the record is successfully retrieved.
134
- * @throws {Error} If commit() has not been called.
135
- * @throws {FMError} If the retrieval fails.
136
- */
137
- async get (): Promise<this> {
138
- if (this.recordId === -1) {
139
- throw new Error('Cannot get this RecordBase until a commit() is done.')
140
- }
141
- if (!this.layout.metadata) await this.layout.getLayoutMeta()
142
- const res = await this.layout.database._apiRequestJSON<ApiRecordResponseObj>(this.endpoint, {
143
- method: 'GET'
144
- })
145
-
146
- if (res.response && res.messages[0].code === '0') {
147
- // console.log(res, res.response.data)
148
- this.modId = +res.response.data[0].modId
149
- this.processFieldData(res.response.data[0].fieldData)
150
- this.portalData = []
151
- if (res.response.data[0].portalData) this.processPortalData(res.response.data[0].portalData)
152
- return this
153
- } else {
154
- throw new FMError(res.messages[0].code, res.httpStatus, res)
155
- }
156
- }
157
-
158
- async duplicate (): Promise<LayoutRecord<LAYOUT>> {
159
- const trace = new Error()
160
- const res = await this.layout.database._apiRequestJSON<{ recordId: string, modId: string }>(this.endpoint, {
161
- method: 'POST'
162
- })
163
- if (!res.response) {
164
- throw new FMError(res.messages[0].code, res.httpStatus, res, trace)
165
- } else if (typeof res.response.scriptError !== 'undefined' && res.response.scriptError !== '0') {
166
- throw new FMError(res.response.scriptError, res.httpStatus, res, trace)
167
- } else if (res.messages[0].code === '0') {
168
- const data = this.toObject((a) => true, (a) => true, (a) => false, (a) => false)
169
- const _res = new LayoutRecord<LAYOUT>(this.layout, res.response.recordId, res.response.modId, data.fieldData, data.portalData)
170
-
171
- this.emit('duplicated')
172
- return _res
173
- } else {
174
- throw new FMError(res.messages[0].code, res.httpStatus, res, trace)
175
- }
176
- }
177
-
178
- async delete (): Promise<void> {
179
- const res = await this.layout.database._apiRequestJSON(this.endpoint, {
180
- method: 'DELETE'
181
- })
182
- if (typeof res.response?.scriptError !== 'undefined' && res.response?.scriptError !== '0') {
183
- throw new FMError(res.response.scriptError, res.httpStatus, res)
184
- } else if (res.messages[0].code === '0') {
185
- this.emit('deleted')
186
- } else {
187
- throw new FMError(res.messages[0].code, res.httpStatus, res)
188
- }
189
- }
190
-
191
- fieldsToObject (filter = (a: Field<FieldValue>) => a.edited): Omit<ApiRowDataDef, 'portalData'> {
192
- const fields_processed: ApiFieldData = {}
193
- let field: Field<FieldValue>
194
- for (field of this.fieldsArray.filter(field => filter(field))) {
195
- let value = field.value as string | number | Date
196
- if (value instanceof Date) {
197
- let _value = moment.default(value)
198
- _value = _value
199
- .utcOffset(this.layout.database.host.timezoneOffsetFunc(_value))
200
-
201
- switch (field.metadata.result) {
202
- case 'time':
203
- value = _value.format(this.layout.database.host.timeFormat)
204
- break
205
- case 'date':
206
- value = _value.format(this.layout.database.host.dateFormat)
207
- break
208
- default:
209
- value = _value.format(this.layout.database.host.timeStampFormat)
210
- }
211
- }
212
- fields_processed[field.id] = value
213
- }
214
- const obj = {
215
- recordId: this.recordId.toString(),
216
- modId: this.modId.toString(),
217
- fieldData: fields_processed
218
- }
219
- return obj
220
- }
221
-
222
- toObject (
223
- filter: (a: Field<FieldValue>) => any = (a) => a.edited,
224
- portalFilter: (a: Portal<any>) => any = (a) => a.records.find(record => record.edited),
225
- portalRowFilter: (a: PortalRecord<never>) => any = (a) => a.edited,
226
- portalFieldFilter: (a: Field<FieldValue>) => any = (a) => a.edited
227
- ) {
228
- const obj: ApiRowDataDef = {
229
- ...this.fieldsToObject(filter),
230
- portalData: {}
231
- }
232
-
233
- // Check if there's been any edited portal information
234
- const portals = this.portalsArray.filter(a => portalFilter(a))
235
- if (portals) {
236
- obj.portalData = {}
237
- for (const portal of portals) {
238
- // @ts-expect-error
239
- obj.portalData[portal.name] = portal.records.filter(a => portalRowFilter(a)).map(record => {
240
- return record.toObject(portalFieldFilter)
241
- })
242
- }
243
- }
244
-
245
- return obj
246
- }
247
- }
@@ -1,10 +0,0 @@
1
- /*
2
- * Copyright (c) 2023. See LICENSE file for more information
3
- */
4
-
5
- import {type LayoutBase} from '../layouts/layoutBase.js'
6
-
7
- export interface LayoutRecordBase {
8
- layout: LayoutBase
9
- commit: (extraBody: object) => Promise<this>
10
- }
@@ -1,43 +0,0 @@
1
- /*
2
- * Copyright (c) 2023-2024. See LICENSE file for more information
3
- */
4
-
5
- import {PortalRecord} from './portalRecord.js'
6
- import {type RecordFieldsMap} from '../layouts/recordFieldsMap.js'
7
- import {type PortalBase} from './portalBase.js'
8
- import {type LayoutRecord} from './layoutRecord.js'
9
-
10
- /**
11
- * Represents a portal.
12
- *
13
- * @template T - The type of RecordFieldsMap.
14
- * @class
15
- * @implements {PortalBase<T>}
16
- */
17
- export class Portal<T extends RecordFieldsMap> implements PortalBase<T> {
18
- readonly record: LayoutRecord<any>
19
- readonly name: string
20
- public records: Array<PortalRecord<T>> = []
21
-
22
- constructor (record: LayoutRecord<any>, name: string) {
23
- this.record = record
24
- this.name = name
25
- }
26
-
27
- /**
28
- * Add a new record to the portal
29
- * @function create
30
- * @async
31
- * @summary Creates a new record.
32
- * @returns {Promise<PortalRecord<T>>} A Promise that resolves to the newly created record.
33
- */
34
- async create () {
35
- const fields: Record<string, string> = {}
36
- for (const _field of (await this.record.layout.getLayoutMeta()).portalMetaData[this.name]) {
37
- fields[_field.name] = ''
38
- }
39
- const record = new PortalRecord<T>(this.record, this, -1, -1, fields)
40
- this.records.push(record)
41
- return record
42
- }
43
- }
@@ -1,14 +0,0 @@
1
- /*
2
- * Copyright (c) 2023-2024. See LICENSE file for more information
3
- */
4
-
5
- import {type RecordFieldsMap} from '../layouts/recordFieldsMap.js'
6
- import {type RecordBase} from './recordBase.js'
7
- import {type LayoutRecord} from './layoutRecord.js'
8
- import {type LayoutInterface} from '../layouts/layoutInterface.js'
9
-
10
- export interface PortalBase<T extends RecordFieldsMap> {
11
- readonly record: LayoutRecord<LayoutInterface>
12
- readonly name: string
13
- records: Array<RecordBase<T>>
14
- }
@@ -1,52 +0,0 @@
1
- /*
2
- * Copyright (c) 2023-2024. See LICENSE file for more information
3
- */
4
-
5
- import {RecordBase} from './recordBase.js'
6
- import {type extraBodyOptions, RecordTypes} from '../types.js'
7
-
8
- import {type RecordFieldsMap} from '../layouts/recordFieldsMap.js'
9
- import {type PortalBase} from './portalBase.js'
10
- import {type Field, type FieldValue} from './field.js'
11
-
12
- /**
13
- * Represents a PortalRecord, which is a record in a portal within a parent record.
14
- * @template T - The type of the record's field map.
15
- */
16
- export class PortalRecord<T extends RecordFieldsMap> extends RecordBase<T> {
17
- readonly portal: PortalBase<T>
18
- readonly type = RecordTypes.PORTAL
19
-
20
- constructor (record: RecordBase<any>, portal: PortalBase<any>, recordId: number, modId = recordId, fieldData = {}) {
21
- super(record.layout, recordId, modId, fieldData)
22
- this.portal = portal
23
- }
24
-
25
- _onSave () {
26
- super._onSave()
27
- this.portal.record._onSave()
28
- }
29
-
30
- /**
31
- * Commits the parent record, and in turn this one.
32
- *
33
- * @param {extraBodyOptions} [extraBody={}] - The optional extra body options.
34
- * @returns {Promise} - A promise that resolves when the record is committed.
35
- */
36
- async commit (extraBody: extraBodyOptions = {}) {
37
- return await this.portal.record.commit(extraBody)
38
- }
39
-
40
- toObject (fieldFilter: (a: Field<FieldValue>) => boolean): {
41
- modId?: string
42
- recordId?: string
43
- } & Record<string, string> {
44
- const res: any = {
45
- recordId: this.recordId === -1 ? undefined : this.recordId.toString(),
46
- modId: this.modId === -1 ? undefined : this.modId.toString()
47
- }
48
- for (const field of this.fieldsArray.filter(a => fieldFilter(a))) res[field.id] = field.value?.toString()
49
- // console.log(res)
50
- return res
51
- }
52
- }
@@ -1,91 +0,0 @@
1
- /*
2
- * Copyright (c) 2023-2024. See LICENSE file for more information
3
- */
4
-
5
- import {EventEmitter} from 'events'
6
- import * as moment from 'moment'
7
- import {type Moment} from 'moment'
8
- import {RecordTypes} from '../types.js'
9
- import {type RecordFieldsMap} from '../layouts/recordFieldsMap.js'
10
- import {type LayoutBase} from '../layouts/layoutBase.js'
11
- import {type ApiFieldData} from '../models/apiResults.js'
12
- import {Field, type FieldValue} from './field.js'
13
-
14
- export abstract class RecordBase<T extends RecordFieldsMap> extends EventEmitter {
15
- readonly layout: LayoutBase
16
- readonly type: RecordTypes = RecordTypes.UNKNOWN
17
- public recordId: number
18
- modId: number
19
- /**
20
- * An object containing each field in this record.
21
- *
22
- * @template T - The type of the field.
23
- */
24
- fields: T
25
- protected portalData: any[] = []
26
-
27
- protected constructor (layout: LayoutBase, recordId: number, modId = recordId, fieldData: ApiFieldData) {
28
- super()
29
- this.layout = layout
30
- this.recordId = recordId
31
- this.modId = modId
32
- this.fields = this.processFieldData(fieldData)
33
- }
34
-
35
- get endpoint (): string {
36
- return `${this.layout.endpoint}/records/${this.recordId}`
37
- }
38
-
39
- /**
40
- * A boolean indicating whether this record has been modified and should be committed
41
- *
42
- * @returns {boolean} A boolean value indicating whether any of the fields have been edited.
43
- */
44
- get edited (): boolean {
45
- return !!this.fieldsArray.find(i => i.edited)
46
- }
47
-
48
- get fieldsArray (): Array<Field<FieldValue>> {
49
- return Object.values(this.fields)
50
- }
51
-
52
- protected processFieldData (fieldData: ApiFieldData) {
53
- const fields: RecordFieldsMap = {}
54
-
55
- for (const key of Object.keys(fieldData)) {
56
- const _field = new Field<number | string | Moment>(this, key, fieldData[key])
57
- if (fieldData[key]) {
58
- if (_field.metadata.result === 'timeStamp') {
59
- let date = moment.default(fieldData[key])
60
- date = date
61
- .utcOffset(this.layout.database.host.timezoneOffsetFunc(date), true)
62
- .local()
63
- _field.set(date)
64
- _field.edited = false
65
- } else if (_field.metadata.result === 'time') {
66
- let date = moment.default(fieldData[key])
67
- date = date
68
- .utcOffset(this.layout.database.host.timezoneOffsetFunc(date), true)
69
- .local()
70
- _field.set(date)
71
- _field.edited = false
72
- } else if (_field.metadata.result === 'date') {
73
- let date = moment.default(fieldData[key])
74
- date = date
75
- .utcOffset(this.layout.database.host.timezoneOffsetFunc(date), true)
76
- .local()
77
- _field.set(date)
78
- _field.edited = false
79
- }
80
- }
81
- fields[key] = _field
82
- }
83
- this.fields = fields as T
84
- return fields as T
85
- }
86
-
87
- _onSave () {
88
- this.emit('saved')
89
- for (const field of this.fieldsArray) field.edited = false
90
- }
91
- }
package/src/types.ts DELETED
@@ -1,162 +0,0 @@
1
- /*
2
- * Copyright (c) 2022-2024. See LICENSE file for more information
3
- */
4
-
5
- // const fetch = (...args) => import('node-fetch').then(({default: fetch}) => fetch(...args));
6
- import type * as http from 'http'
7
- import {type FMError} from './FMError.js'
8
- import {type LayoutInterface} from './layouts/layoutInterface.js'
9
-
10
- export type PickPortals<LAYOUT extends LayoutInterface, PORTALS extends string | number | symbol = ''> =
11
- Omit<LAYOUT, 'portals'> & { portals: Pick<LAYOUT['portals'], PORTALS> }
12
-
13
- export interface databaseOptionsBase {
14
- database: string
15
- debug?: boolean
16
- credentials: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris | loginOptionsToken
17
- }
18
-
19
- export interface databaseOptionsWithExternalSources extends databaseOptionsBase {
20
- database: string
21
- debug?: boolean
22
- credentials: loginOptionsOAuth | loginOptionsFileMaker | loginOptionsClaris | loginOptionsToken
23
- externalSources: databaseOptionsBase[]
24
- }
25
-
26
- export interface loginOptionsToken {
27
- method: 'token'
28
- token: string
29
- }
30
-
31
- export interface loginOptionsOAuth {
32
- method: 'oauth'
33
- oauth: {
34
- requestId: string
35
- requestIdentifier: string
36
- }
37
- }
38
-
39
- export interface loginOptionsFileMaker {
40
- method: 'filemaker'
41
- username: string
42
- password: string
43
- }
44
-
45
- export interface loginOptionsClaris {
46
- method: 'claris'
47
- claris: {
48
- fmid: string
49
- }
50
- }
51
-
52
- export interface portalFetchData<T = string> {
53
- portalName: T
54
- offset: number
55
- limit: number
56
- }
57
-
58
- export interface ScriptRequestData {
59
- prerequest?: Script
60
- presort?: Script
61
- after?: Script
62
- }
63
-
64
- export interface extraBodyOptions {
65
- scripts?: ScriptRequestData
66
- options?: {
67
- /**
68
- * Defines what entry mode to use (FileMaker Server 2024 and newer)
69
- * user (default) - Field validation occurs as per normal. Request is blocked if validation failed.
70
- * script - Field validation is overridden/ignored when allowed in the database schema.
71
- */
72
- entrymode: 'user' | 'script'
73
- }
74
- deleteRelatedRecords?: Array<{
75
- table: string
76
- recordId: number
77
- }>
78
- }
79
-
80
- export interface Script {
81
- name: string
82
- parameter: string
83
- }
84
-
85
- export interface recordObject {
86
- recordId: number
87
- modId: number
88
- fieldData: any
89
- portalData?: portalDataObject
90
- }
91
-
92
- export type portalDataObject = Record<string, recordObject>
93
-
94
- export interface FieldMetaData {
95
- name: string
96
- type: string
97
- displayType: string
98
- result: string
99
- global: boolean
100
- autoEnter: boolean
101
- fourDigitYear: boolean
102
- maxRepeat: number
103
- maxCharacters: number
104
- notEmpty: boolean
105
- numeric: boolean
106
- timeOfDay: false
107
- repetitionStart: number
108
- repetitionEnd: number
109
- }
110
-
111
- export interface LayoutMetaData {
112
- fieldMetaData: FieldMetaData[]
113
- portalMetaData?: Record<string, FieldMetaData[]>
114
- }
115
-
116
- export interface FMHostMetadata {
117
- productInfo: {
118
- buildDate: Date
119
- name: string
120
- version: string
121
- dateFormat: string
122
- timeFormat: string
123
- timeStampFormat: string
124
- }
125
- }
126
-
127
- export interface ScriptResult {
128
- scriptError?: FMError
129
- scriptResult?: string
130
- }
131
-
132
- export interface ContainerBufferResult {
133
- buffer: Buffer
134
- mime?: string
135
- request: http.IncomingMessage
136
- }
137
-
138
- //
139
- // module.exports = {
140
- // default: {FileMakerConnection}
141
- // }
142
-
143
- export interface AuthorizationHeaders {
144
- 'Content-Type': 'application/json'
145
- Authorization: string
146
- }
147
-
148
- export interface AuthorizationHeadersOAuth {
149
- 'Content-Type': 'application/json'
150
- 'X-FM-Data-OAuth-RequestId': string
151
- 'X-FM-Data-OAuth-Identifier': string
152
- }
153
-
154
- export interface RecordFetchOptions {
155
- readonly portals: readonly string[]
156
- }
157
-
158
- export enum RecordTypes {
159
- UNKNOWN,
160
- LAYOUT,
161
- PORTAL
162
- }
@@ -1,59 +0,0 @@
1
- /*
2
- * Copyright (c) 2024. See LICENSE file for more information
3
- */
4
-
5
- import moment, {type Moment} from 'moment'
6
-
7
- export const FindRequestSymbol = Symbol('easyfm-findrequest')
8
- const SPECIAL_CHARACTERS = ['\\', '=', '<', '≤', '≥', '>', '…', '...', '//', '@', '#', '*', '"', '~']
9
- export interface TimestampType {
10
- type: 'date' | 'time' | 'timestamp'
11
- moment: Moment
12
- }
13
- type QueryParameter = string | number | TimestampType
14
- export interface Query { [FindRequestSymbol]: Array<string | TimestampType> }
15
-
16
- export function queryEscape (str: string) {
17
- for (const char of SPECIAL_CHARACTERS) {
18
- str = str.replace(char, `\\${char}`)
19
- }
20
- return str
21
- }
22
-
23
- export function query (strings: TemplateStringsArray, ...args: QueryParameter[]): Query {
24
- const argStrings = args.map(item => {
25
- if (typeof item === 'number') {
26
- return queryEscape(item.toString())
27
- } else if (typeof item === 'string') return queryEscape(item)
28
- else return item
29
- })
30
-
31
- // Zip the parameters together
32
- const query = strings.map((str, index) => {
33
- return [str, (argStrings[index] || '')]
34
- }).flat(1)
35
- return {[FindRequestSymbol]: query}
36
- }
37
-
38
- export function asDate (date: Date | Moment): TimestampType {
39
- return {
40
- type: 'date',
41
- moment: moment(date)
42
- }
43
- }
44
-
45
- export function asTime (date: Date | Moment): TimestampType {
46
- return {
47
- type: 'time',
48
- moment: moment(date)
49
- }
50
- }
51
-
52
- export function asTimestamp (date: Date | Moment): TimestampType {
53
- return {
54
- type: 'timestamp',
55
- moment: moment(date)
56
- }
57
- }
58
-
59
- query
File without changes
File without changes
File without changes
File without changes
File without changes