@jd-data-limited/easy-fm 4.0.14 → 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.
Files changed (65) hide show
  1. package/package.json +12 -6
  2. package/src/FMError.d.ts +2 -2
  3. package/src/FMError.js +507 -508
  4. package/src/FMError.ts +510 -511
  5. package/src/bin/cli.js +7 -5
  6. package/src/bin/generateTypes.js +215 -121
  7. package/src/connection/FMHost.d.ts +28 -6
  8. package/src/connection/FMHost.js +52 -25
  9. package/src/connection/FMHost.ts +75 -43
  10. package/src/connection/HostBase.d.ts +7 -3
  11. package/src/connection/HostBase.ts +8 -4
  12. package/src/connection/database.d.ts +50 -17
  13. package/src/connection/database.js +94 -66
  14. package/src/connection/database.ts +125 -105
  15. package/src/connection/databaseBase.d.ts +11 -6
  16. package/src/connection/databaseBase.ts +9 -8
  17. package/src/connection/generateAuthorizationHeaders.d.ts +1 -1
  18. package/src/connection/generateAuthorizationHeaders.js +10 -10
  19. package/src/connection/generateAuthorizationHeaders.ts +21 -21
  20. package/src/databaseStructure.d.ts +2 -4
  21. package/src/databaseStructure.ts +3 -5
  22. package/src/index.d.ts +17 -17
  23. package/src/index.js +14 -14
  24. package/src/index.ts +28 -25
  25. package/src/layouts/layout.d.ts +17 -6
  26. package/src/layouts/layout.js +19 -8
  27. package/src/layouts/layout.ts +33 -23
  28. package/src/layouts/layoutBase.d.ts +5 -5
  29. package/src/layouts/layoutBase.ts +6 -6
  30. package/src/layouts/layoutInterface.d.ts +3 -5
  31. package/src/layouts/layoutInterface.ts +4 -6
  32. package/src/layouts/layoutRecordManager.d.ts +29 -6
  33. package/src/layouts/layoutRecordManager.js +32 -9
  34. package/src/layouts/layoutRecordManager.ts +42 -19
  35. package/src/layouts/recordFieldsMap.d.ts +2 -4
  36. package/src/layouts/recordFieldsMap.ts +2 -4
  37. package/src/models/apiResults.d.ts +7 -13
  38. package/src/models/apiResults.ts +58 -58
  39. package/src/records/field.d.ts +42 -12
  40. package/src/records/field.js +69 -59
  41. package/src/records/field.ts +102 -81
  42. package/src/records/getOperations/recordGetOperation.d.ts +44 -24
  43. package/src/records/getOperations/recordGetOperation.js +89 -58
  44. package/src/records/getOperations/recordGetOperation.ts +137 -108
  45. package/src/records/layoutRecord.d.ts +28 -14
  46. package/src/records/layoutRecord.js +75 -65
  47. package/src/records/layoutRecord.ts +126 -123
  48. package/src/records/layoutRecordBase.d.ts +2 -2
  49. package/src/records/layoutRecordBase.ts +3 -3
  50. package/src/records/portal.d.ts +19 -5
  51. package/src/records/portal.js +19 -5
  52. package/src/records/portal.ts +28 -16
  53. package/src/records/portalBase.d.ts +5 -5
  54. package/src/records/portalBase.ts +6 -6
  55. package/src/records/portalRecord.d.ts +16 -8
  56. package/src/records/portalRecord.js +16 -6
  57. package/src/records/portalRecord.ts +29 -19
  58. package/src/records/recordBase.d.ts +17 -7
  59. package/src/records/recordBase.js +32 -22
  60. package/src/records/recordBase.ts +50 -43
  61. package/src/types.d.ts +21 -24
  62. package/src/types.ts +55 -59
  63. package/src/utils/query.d.ts +12 -5
  64. package/src/utils/query.js +28 -9
  65. package/src/utils/query.ts +40 -15
@@ -2,35 +2,31 @@
2
2
  * Copyright (c) 2023-2024. See LICENSE file for more information
3
3
  */
4
4
 
5
- import {LayoutInterface} from "../../layouts/layoutInterface.js";
6
- import {PickPortals, ScriptRequestData} from "../../types.js";
7
- import {LayoutBase} from "../../layouts/layoutBase.js"
8
- import {LayoutRecord} from "../layoutRecord.js";
9
- import {ApiRecordResponseObj} from "../../models/apiResults.js";
10
- import {FMError} from "../../FMError.js";
11
- import {FindRequestSymbol, Query} from "../../utils/query.js";
12
-
13
- export type SortOrder = "ascend" | "descend"
14
- export type FindRequestRaw = {
15
- [key: string]: string
16
- }
17
- export type FindRequest = {
18
- [key: string]: Query
19
- }
20
-
21
- export type PortalRequest = {
22
- name: string,
5
+ import {type LayoutInterface} from '../../layouts/layoutInterface.js'
6
+ import {type PickPortals, type ScriptRequestData} from '../../types.js'
7
+ import {type LayoutBase} from '../../layouts/layoutBase.js'
8
+ import {LayoutRecord} from '../layoutRecord.js'
9
+ import {type ApiRecordResponseObj} from '../../models/apiResults.js'
10
+ import {FMError} from '../../FMError.js'
11
+ import {FindRequestSymbol, type Query} from '../../utils/query.js'
12
+
13
+ export type SortOrder = 'ascend' | 'descend'
14
+ export type FindRequestRaw = Record<string, string>
15
+ export type FindRequest = Record<string, Query>
16
+
17
+ export interface PortalRequest {
18
+ name: string
23
19
  }
24
20
 
25
21
  type PortalData<T extends LayoutInterface> = {
26
- [key in keyof T["portals"]]: {
27
- limit: number,
22
+ [key in keyof T['portals']]: {
23
+ limit: number
28
24
  offset: number
29
25
  }
30
26
  }
31
- export type GetOperationOptions<T extends LayoutInterface> = {
32
- portals: Partial<PortalData<T>>,
33
- limit?: number,
27
+ export interface GetOperationOptions<T extends LayoutInterface> {
28
+ portals: Partial<PortalData<T>>
29
+ limit?: number
34
30
  offset?: number
35
31
  }
36
32
 
@@ -38,158 +34,192 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
38
34
  protected layout: LayoutBase
39
35
  protected limit: number = 100
40
36
  protected scriptData: ScriptRequestData = {}
41
- protected sortData: { fieldName: string, sortOrder: SortOrder }[] = []
37
+ protected sortData: Array<{ fieldName: string, sortOrder: SortOrder }> = []
42
38
  protected portals: Partial<PortalData<T>>
43
39
  protected offset: number = 1
44
- protected queries: {req: FindRequestRaw, omit: boolean}[] = []
40
+ protected queries: Array<{ req: FindRequestRaw, omit: boolean }> = []
45
41
 
46
- constructor(layout: LayoutBase, options: OPTIONS) {
42
+ constructor (layout: LayoutBase, options: OPTIONS) {
47
43
  this.layout = layout
48
44
  this.sortData = []
49
45
  this.portals = options.portals
50
- this.offset = options.offset || 1 // Offset refers to the starting record. offset 1 is the same as no offset.
51
- this.limit = options.limit || 100
46
+ this.offset = options.offset ?? 1 // Offset refers to the starting record. offset 1 is the same as no offset.
47
+ this.limit = options.limit ?? 100
52
48
  }
53
49
 
54
- get isFindRequest() {
50
+ get isFindRequest () {
55
51
  return this.queries.length !== 0
56
52
  }
57
53
 
58
- private formatQueries() {
59
- let test = this.queries.map(query => {
60
- let out: any = {}
61
- for (let key of Object.keys(query.req)) {
54
+ private formatQueries () {
55
+ const test = this.queries.map(query => {
56
+ const out: any = {}
57
+ for (const key of Object.keys(query.req)) {
62
58
  if (query.req[key]) out[key] = query.req[key]
63
- else {out[key] = query.req[key]}
59
+ else {
60
+ out[key] = query.req[key]
61
+ }
64
62
  }
65
- if (query.omit) out.omit = "true"
63
+ if (query.omit) out.omit = 'true'
66
64
  return out
67
65
  })
68
66
  return test
69
67
  }
70
68
 
71
- protected generateParamsBody(offset: number, limit: number) {
72
- const params: {[key: string]: any} = {
69
+ protected generateParamsBody (offset: number, limit: number) {
70
+ const params: Record<string, any> = {
73
71
  limit: limit.toString(),
74
72
  offset: offset.toString(),
75
73
  dateformats: 2 // Ensure dates are received in ISO8601 format
76
74
  }
77
75
  if (this.sortData.length !== 0) params.sort = this.sortData
78
76
 
77
+ if (this.scriptData.after) params.script = this.scriptData.after.name
78
+ if (this.scriptData.after?.parameter) params['script.param'] = this.scriptData.after.parameter
79
79
 
80
- if (this.scriptData.after) params["script"] = this.scriptData.after.name
81
- if (this.scriptData.after?.parameter) params["script.param"] = this.scriptData.after.parameter
82
-
83
- if (this.scriptData.presort) params["script.presort"] = this.scriptData.presort.name
84
- if (this.scriptData.presort?.parameter) params["script.presort.param"] = this.scriptData.presort.parameter
80
+ if (this.scriptData.presort) params['script.presort'] = this.scriptData.presort.name
81
+ if (this.scriptData.presort?.parameter) params['script.presort.param'] = this.scriptData.presort.parameter
85
82
 
86
- if (this.scriptData.prerequest) params["script.prerequest"] = this.scriptData.prerequest.name
87
- if (this.scriptData.prerequest?.parameter) params["script.prerequest.param"] = this.scriptData.prerequest.parameter
83
+ if (this.scriptData.prerequest) params['script.prerequest'] = this.scriptData.prerequest.name
84
+ if (this.scriptData.prerequest?.parameter) params['script.prerequest.param'] = this.scriptData.prerequest.parameter
88
85
 
89
- if (this.queries.length !== 0) params["query"] = this.formatQueries()
86
+ if (this.queries.length !== 0) params.query = this.formatQueries()
90
87
 
91
- let portals: (keyof typeof this.portals)[] = Object.keys(this.portals)
92
- params["portal"] = portals
93
- for (let portal of portals) {
88
+ const portals: Array<keyof typeof this.portals> = Object.keys(this.portals)
89
+ params.portal = portals
90
+ for (const portal of portals) {
94
91
  params[`offset.${portal.toString()}`] = this.portals[portal]?.offset
95
92
  params[`limit.${portal.toString()}`] = this.portals[portal]?.limit
96
93
  }
97
94
 
98
95
  return params
99
96
  }
100
- protected generateParamsURL(offset: number, limit: number) {
97
+
98
+ protected generateParamsURL (offset: number, limit: number) {
101
99
  const params = new URLSearchParams({
102
100
  _limit: limit.toString(),
103
101
  _offset: offset.toString(),
104
- dateformats: "2" // Ensure dates are received in ISO8601 format
102
+ dateformats: '2' // Ensure dates are received in ISO8601 format
105
103
  })
106
- if (this.sortData.length !== 0) params.set("_sort", JSON.stringify(this.sortData))
104
+ if (this.sortData.length !== 0) params.set('_sort', JSON.stringify(this.sortData))
107
105
 
108
- if (this.scriptData.after) params.set("script", this.scriptData.after.name)
109
- if (this.scriptData.after?.parameter) params.set("script.param", this.scriptData.after.parameter)
106
+ if (this.scriptData.after) params.set('script', this.scriptData.after.name)
107
+ if (this.scriptData.after?.parameter) params.set('script.param', this.scriptData.after.parameter)
110
108
 
111
- if (this.scriptData.presort) params.set("script.presort", this.scriptData.presort.name)
112
- if (this.scriptData.presort?.parameter) params.set("script.presort.param", this.scriptData.presort.parameter)
109
+ if (this.scriptData.presort) params.set('script.presort', this.scriptData.presort.name)
110
+ if (this.scriptData.presort?.parameter) params.set('script.presort.param', this.scriptData.presort.parameter)
113
111
 
114
- if (this.scriptData.prerequest) params.set("script.prerequest", this.scriptData.prerequest.name)
115
- if (this.scriptData.prerequest?.parameter) params.set("script.prerequest.param", this.scriptData.prerequest.parameter)
112
+ if (this.scriptData.prerequest) params.set('script.prerequest', this.scriptData.prerequest.name)
113
+ if (this.scriptData.prerequest?.parameter) params.set('script.prerequest.param', this.scriptData.prerequest.parameter)
116
114
 
117
- let portals: (keyof typeof this.portals)[] = Object.keys(this.portals)
118
- for (let portal of portals) {
119
- params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.limit || "").toString())
120
- params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.offset || "").toString())
115
+ const portals: Array<keyof typeof this.portals> = Object.keys(this.portals)
116
+ for (const portal of portals) {
117
+ params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.limit ?? '').toString())
118
+ params.set(`_offset.${portal.toString()}`, (this.portals[portal]?.offset ?? '').toString())
121
119
  }
122
120
  params.set('portal', JSON.stringify(portals))
123
121
 
124
122
  return params
125
123
  }
126
124
 
127
- scripts(scripts: ScriptRequestData) {
128
- this.scriptData = scripts;
125
+ /**
126
+ * Configures any FileMaker scripts to be run as a part of the request
127
+ *
128
+ * @param {ScriptRequestData} scripts - The script request data to set.
129
+ * @return {this} - The current instance of the class.
130
+ */
131
+ scripts (scripts: ScriptRequestData) {
132
+ this.scriptData = scripts
129
133
  return this
130
134
  }
131
135
 
132
- sort(fieldName: string, sortOrder: SortOrder) {
136
+ /**
137
+ * Sorts the data based on the given field name and sort order.
138
+ *
139
+ * @param {string} fieldName - The name of the field by which the data should be sorted.
140
+ * @param {SortOrder} sortOrder - The sort order to be applied (either "asc" for ascending or "desc" for descending).
141
+ *
142
+ * @return {this} - Returns the current instance of the object.
143
+ */
144
+ sort (fieldName: string, sortOrder: SortOrder) {
133
145
  this.sortData.push({fieldName, sortOrder})
134
146
  return this
135
147
  }
136
148
 
137
- private parseFindRequest<I extends FindRequest>(query: I): {[key in keyof I]: string} {
138
- let out: any = {}
139
- for (let key of Object.keys(query)) {
149
+ private parseFindRequest<I extends FindRequest>(query: I): { [key in keyof I]: string } {
150
+ const out: any = {}
151
+ for (const key of Object.keys(query)) {
140
152
  out[key] = query[key][FindRequestSymbol].map(item => {
141
- if (typeof item === "string") return item
153
+ if (typeof item === 'string') return item
142
154
 
143
155
  // Re-write date into correct format
144
156
  return item
157
+ .moment
145
158
  .clone()
146
- .utcOffset(this.layout.database.host.timezoneOffset)
147
- .format("MM/DD/YYYY HH:mm:ss")
148
- }).join("")
159
+ .utcOffset(this.layout.database.host.timezoneOffsetFunc(item.moment))
160
+ .format(
161
+ item.type === 'date'
162
+ ? this.layout.database.host.dateFormat
163
+ : item.type == 'time'
164
+ ? this.layout.database.host.timeFormat
165
+ : this.layout.database.host.timeStampFormat
166
+ )
167
+ }).join('')
149
168
  }
150
169
  return out
151
170
  }
152
171
 
153
- addRequest(query: FindRequest, omit = false) {
172
+ /**
173
+ * Adds a new request/query to the list of queries.
174
+ *
175
+ * @param {FindRequest} query - The find request to be added.
176
+ * @param {boolean} [omit=false] - Flag to indicate if the find request should be omitted.
177
+ * @return {Object} - The current object instance.
178
+ */
179
+ addRequest (query: FindRequest, omit = false) {
154
180
  this.queries.push({req: this.parseFindRequest(query), omit})
155
181
  return this
156
182
  }
157
183
 
158
- fetch() {
159
- return this.performFind(this.offset, this.limit)
184
+ /**
185
+ * Perform a fetch operation.
186
+ *
187
+ * @returns {Promise} A promise that resolves with the result of the fetch operation.
188
+ */
189
+ async fetch () {
190
+ return await this.performFind(this.offset, this.limit)
160
191
  }
161
192
 
162
- private async performFind(offset: number, limit: number): Promise<LayoutRecord<
163
- PickPortals<T, keyof OPTIONS["portals"]>
164
- >[]> {
165
- let trace = new Error()
193
+ private async performFind (offset: number, limit: number): Promise<Array<LayoutRecord<
194
+ PickPortals<T, keyof OPTIONS['portals']>
195
+ >>> {
196
+ const trace = new Error()
166
197
  await this.layout.getLayoutMeta()
167
198
 
168
- const is_find = this.isFindRequest
169
- let endpoint = this.layout.endpoint + (is_find ? "/_find" : "/records")
170
- if (!is_find) endpoint += "?" + new URLSearchParams(this.generateParamsURL(offset, limit)).toString()
199
+ const isFind = this.isFindRequest
200
+ let endpoint = this.layout.endpoint + (isFind ? '/_find' : '/records')
201
+ if (!isFind) endpoint += '?' + new URLSearchParams(this.generateParamsURL(offset, limit)).toString()
171
202
  const reqData = {
172
203
  // port: 443,
173
- method: is_find ? "POST" : "GET",
174
- body: is_find ? JSON.stringify(this.generateParamsBody(offset, limit)) : undefined,
204
+ method: isFind ? 'POST' : 'GET',
205
+ body: isFind ? JSON.stringify(this.generateParamsBody(offset, limit)) : undefined
175
206
  }
176
207
 
177
208
  try {
178
- let res = await this.layout.database.apiRequestJSON<ApiRecordResponseObj>(
209
+ const res = await this.layout.database._apiRequestJSON<ApiRecordResponseObj>(
179
210
  endpoint,
180
211
  reqData
181
212
  )
182
- if (res.messages[0].code === "0" && res.response) {
213
+ if (res.messages[0].code === '0' && res.response) {
183
214
  // console.log("RESOLVING")
184
215
  if (!this.layout.metadata) await this.layout.getLayoutMeta()
185
216
  return res.response.data.map(item => {
186
217
  return new LayoutRecord(this.layout, item.recordId, item.modId, item.fieldData, item.portalData)
187
218
  })
188
- }
189
- else {
219
+ } else {
190
220
  throw new FMError(res.messages[0].code, res.httpStatus, res, trace)
191
221
  }
192
- } catch(e) {
222
+ } catch (e) {
193
223
  if (e instanceof FMError) {
194
224
  if (e.code === 401) {
195
225
  // No records found, so return empty set
@@ -200,40 +230,39 @@ export class RecordGetOperation<T extends LayoutInterface, OPTIONS extends GetOp
200
230
  }
201
231
  }
202
232
 
203
- [Symbol.asyncIterator]() {
233
+ [Symbol.asyncIterator] () {
204
234
  let nextOffset = this.offset
205
- let startOffset: number = JSON.parse(JSON.stringify(this.offset))
206
- let limit = this.limit
235
+ const startOffset: number = JSON.parse(JSON.stringify(this.offset))
236
+ const limit = this.limit
207
237
 
208
- let exit_after_last_record = false
209
- let records: LayoutRecord<PickPortals<T, keyof OPTIONS["portals"]>>[] = []
238
+ let exitAfterLastRecord = false
239
+ let records: Array<LayoutRecord<PickPortals<T, keyof OPTIONS['portals']>>> = []
210
240
 
211
241
  const fetch = async () => {
212
- const theoretical_limit = (limit - nextOffset) + startOffset
213
- if (theoretical_limit === 0) {
214
- exit_after_last_record = true
242
+ const theoreticalLimit = (limit - nextOffset) + startOffset
243
+ if (theoreticalLimit === 0) {
244
+ exitAfterLastRecord = true
215
245
  records = []
216
246
  return
217
247
  }
218
- records = await this.performFind(nextOffset, theoretical_limit < 100 ? theoretical_limit : 100);
219
- nextOffset += 100;
220
- if (records.length < 100) exit_after_last_record = true
248
+ records = await this.performFind(nextOffset, theoreticalLimit < 100 ? theoreticalLimit : 100)
249
+ nextOffset += 100
250
+ if (records.length < 100) exitAfterLastRecord = true
221
251
  }
222
252
 
223
253
  return {
224
254
  next: async () => {
225
- if (records.length === 0 && !exit_after_last_record) {
226
- await fetch();
255
+ if (records.length === 0 && !exitAfterLastRecord) {
256
+ await fetch()
227
257
  }
228
258
 
229
- if (records.length === 0 && exit_after_last_record) {
230
- return {done: true, value: undefined};
231
- }
232
- else {
259
+ if (records.length === 0 && exitAfterLastRecord) {
260
+ return {done: true, value: undefined}
261
+ } else {
233
262
  const record = records.shift()
234
- return {done: false, value: record};
263
+ return {done: false, value: record}
235
264
  }
236
265
  }
237
- };
266
+ }
238
267
  }
239
- }
268
+ }
@@ -1,22 +1,36 @@
1
- import { extraBodyOptions } from "../types.js";
2
- import { RecordBase } from "./recordBase.js";
3
- import { PortalRecord } from "./portalRecord.js";
4
- import { Portal } from "./portal.js";
5
- import { LayoutInterface } from "../layouts/layoutInterface.js";
6
- import { LayoutRecordBase } from "./layoutRecordBase.js";
7
- import { ApiPortalData, ApiRowDataDef } from "../models/apiResults.js";
8
- import { LayoutBase } from "../layouts/layoutBase.js";
9
- import { Field, FieldValue } from "./field.js";
10
- export declare class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT["fields"]> implements LayoutRecordBase {
11
- portals: LAYOUT["portals"];
1
+ import { type extraBodyOptions } from '../types.js';
2
+ import { RecordBase } from './recordBase.js';
3
+ import { PortalRecord } from './portalRecord.js';
4
+ import { Portal } from './portal.js';
5
+ import { type LayoutInterface } from '../layouts/layoutInterface.js';
6
+ import { type LayoutRecordBase } from './layoutRecordBase.js';
7
+ import { type ApiPortalData, type ApiRowDataDef } from '../models/apiResults.js';
8
+ import { type LayoutBase } from '../layouts/layoutBase.js';
9
+ import { type Field, type FieldValue } from './field.js';
10
+ export declare class LayoutRecord<LAYOUT extends LayoutInterface> extends RecordBase<LAYOUT['fields']> implements LayoutRecordBase {
11
+ portals: LAYOUT['portals'];
12
12
  private readonly portalsToInclude;
13
- constructor(layout: LayoutBase, recordId: number | string, modId?: string | number, fieldData?: Record<string, string | number>, portalData?: ApiPortalData | null, portalsToInclude?: (keyof LAYOUT["portals"])[]);
14
- get portalsArray(): Portal<any>[];
13
+ constructor(layout: LayoutBase, recordId: number | string, modId?: string | number, fieldData?: Record<string, string | number>, portalData?: ApiPortalData | null, portalsToInclude?: Array<keyof LAYOUT['portals']>);
14
+ get portalsArray(): Array<Portal<any>>;
15
+ /**
16
+ * Asynchronously commits the changes made to the current record.
17
+ * @param {extraBodyOptions} extraBody - The options for the extra body elements.
18
+ * @returns {Promise<this>} - A promise that resolves with the modified object.
19
+ * @throws {FMError} - If an error occurs during the commit process.
20
+ */
15
21
  commit(extraBody?: extraBodyOptions): Promise<this>;
16
22
  protected processPortalData(portalData: ApiPortalData): void;
23
+ /**
24
+ * Re-fetches the current record from the database server.
25
+ * Throws an error if commit() has not been called.
26
+ *
27
+ * @return {Promise<this>} A Promise that resolves to this RecordBase instance if the record is successfully retrieved.
28
+ * @throws {Error} If commit() has not been called.
29
+ * @throws {FMError} If the retrieval fails.
30
+ */
17
31
  get(): Promise<this>;
18
32
  duplicate(): Promise<LayoutRecord<LAYOUT>>;
19
33
  delete(): Promise<void>;
20
- fieldsToObject(filter?: (a: Field<FieldValue>) => boolean): Omit<ApiRowDataDef, "portalData">;
34
+ fieldsToObject(filter?: (a: Field<FieldValue>) => boolean): Omit<ApiRowDataDef, 'portalData'>;
21
35
  toObject(filter?: (a: Field<FieldValue>) => any, portalFilter?: (a: Portal<any>) => any, portalRowFilter?: (a: PortalRecord<never>) => any, portalFieldFilter?: (a: Field<FieldValue>) => any): ApiRowDataDef;
22
36
  }