@budibase/server 2.6.10 → 2.6.12
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/builder/assets/{index.15b5f48f.js → index.a40dcadd.js} +111 -111
- package/builder/index.html +1 -1
- package/dist/api/controllers/table/internal.js +3 -0
- package/dist/api/controllers/table/utils.js +7 -7
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/utilities/rowProcessor/index.js +1 -3
- package/dist/utilities/rowProcessor/map.js +18 -17
- package/package.json +8 -8
- package/src/api/controllers/table/index.ts +1 -0
- package/src/api/controllers/table/internal.ts +5 -0
- package/src/api/controllers/table/utils.ts +7 -7
- package/src/api/routes/tests/misc.spec.js +84 -5
- package/src/api/routes/tests/row.spec.js +57 -8
- package/src/api/routes/tests/table.spec.js +4 -1
- package/src/utilities/rowProcessor/index.ts +2 -3
- package/src/utilities/rowProcessor/map.ts +18 -16
|
@@ -151,8 +151,6 @@ exports.coerce = coerce;
|
|
|
151
151
|
*/
|
|
152
152
|
function inputProcessing(user, table, row, opts) {
|
|
153
153
|
let clonedRow = cloneDeep(row);
|
|
154
|
-
// need to copy the table so it can be differenced on way out
|
|
155
|
-
const copiedTable = cloneDeep(table);
|
|
156
154
|
const dontCleanseKeys = ["type", "_id", "_rev", "tableId"];
|
|
157
155
|
for (let [key, value] of Object.entries(clonedRow)) {
|
|
158
156
|
const field = table.schema[key];
|
|
@@ -186,7 +184,7 @@ function inputProcessing(user, table, row, opts) {
|
|
|
186
184
|
clonedRow._rev = row._rev;
|
|
187
185
|
}
|
|
188
186
|
// handle auto columns - this returns an object like {table, row}
|
|
189
|
-
return processAutoColumn(user,
|
|
187
|
+
return processAutoColumn(user, table, clonedRow, opts);
|
|
190
188
|
}
|
|
191
189
|
exports.inputProcessing = inputProcessing;
|
|
192
190
|
/**
|
|
@@ -4,6 +4,22 @@ exports.TYPE_TRANSFORM_MAP = void 0;
|
|
|
4
4
|
// @ts-nocheck
|
|
5
5
|
const constants_1 = require("../../constants");
|
|
6
6
|
const backend_core_1 = require("@budibase/backend-core");
|
|
7
|
+
const parseArrayString = value => {
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
if (value === "") {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
let result;
|
|
13
|
+
try {
|
|
14
|
+
result = JSON.parse(value.replace(/'/g, '"'));
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
backend_core_1.logging.logAlert("Could not parse row value", e);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
};
|
|
7
23
|
/**
|
|
8
24
|
* A map of how we convert various properties in rows to each other based on the row type.
|
|
9
25
|
*/
|
|
@@ -28,9 +44,9 @@ exports.TYPE_TRANSFORM_MAP = {
|
|
|
28
44
|
[undefined]: undefined,
|
|
29
45
|
},
|
|
30
46
|
[constants_1.FieldTypes.ARRAY]: {
|
|
31
|
-
"": [],
|
|
32
47
|
[null]: [],
|
|
33
48
|
[undefined]: undefined,
|
|
49
|
+
parse: parseArrayString,
|
|
34
50
|
},
|
|
35
51
|
[constants_1.FieldTypes.STRING]: {
|
|
36
52
|
"": "",
|
|
@@ -72,22 +88,7 @@ exports.TYPE_TRANSFORM_MAP = {
|
|
|
72
88
|
[constants_1.FieldTypes.ATTACHMENT]: {
|
|
73
89
|
[null]: [],
|
|
74
90
|
[undefined]: undefined,
|
|
75
|
-
parse:
|
|
76
|
-
if (typeof attachments === "string") {
|
|
77
|
-
if (attachments === "") {
|
|
78
|
-
return [];
|
|
79
|
-
}
|
|
80
|
-
let result;
|
|
81
|
-
try {
|
|
82
|
-
result = JSON.parse(attachments);
|
|
83
|
-
}
|
|
84
|
-
catch (e) {
|
|
85
|
-
backend_core_1.logging.logAlert("Could not parse attachments", e);
|
|
86
|
-
}
|
|
87
|
-
return result;
|
|
88
|
-
}
|
|
89
|
-
return attachments;
|
|
90
|
-
},
|
|
91
|
+
parse: parseArrayString,
|
|
91
92
|
},
|
|
92
93
|
[constants_1.FieldTypes.BOOLEAN]: {
|
|
93
94
|
"": null,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@budibase/server",
|
|
3
3
|
"email": "hi@budibase.com",
|
|
4
|
-
"version": "2.6.
|
|
4
|
+
"version": "2.6.12",
|
|
5
5
|
"description": "Budibase Web Server",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"repository": {
|
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
"license": "GPL-3.0",
|
|
46
46
|
"dependencies": {
|
|
47
47
|
"@apidevtools/swagger-parser": "10.0.3",
|
|
48
|
-
"@budibase/backend-core": "^2.6.
|
|
49
|
-
"@budibase/client": "^2.6.
|
|
50
|
-
"@budibase/pro": "2.6.
|
|
51
|
-
"@budibase/shared-core": "^2.6.
|
|
52
|
-
"@budibase/string-templates": "^2.6.
|
|
53
|
-
"@budibase/types": "^2.6.
|
|
48
|
+
"@budibase/backend-core": "^2.6.12",
|
|
49
|
+
"@budibase/client": "^2.6.12",
|
|
50
|
+
"@budibase/pro": "2.6.11",
|
|
51
|
+
"@budibase/shared-core": "^2.6.12",
|
|
52
|
+
"@budibase/string-templates": "^2.6.12",
|
|
53
|
+
"@budibase/types": "^2.6.12",
|
|
54
54
|
"@bull-board/api": "3.7.0",
|
|
55
55
|
"@bull-board/koa": "3.9.4",
|
|
56
56
|
"@elastic/elasticsearch": "7.10.0",
|
|
@@ -176,5 +176,5 @@
|
|
|
176
176
|
"optionalDependencies": {
|
|
177
177
|
"oracledb": "5.3.0"
|
|
178
178
|
},
|
|
179
|
-
"gitHead": "
|
|
179
|
+
"gitHead": "2b6250160a8cfad3aea51ea69d76ba023f3ebb33"
|
|
180
180
|
}
|
|
@@ -97,6 +97,7 @@ export async function bulkImport(ctx: UserCtx) {
|
|
|
97
97
|
// right now we don't trigger anything for bulk import because it
|
|
98
98
|
// can only be done in the builder, but in the future we may need to
|
|
99
99
|
// think about events for bulk items
|
|
100
|
+
|
|
100
101
|
ctx.status = 200
|
|
101
102
|
ctx.body = { message: `Bulk rows created.` }
|
|
102
103
|
}
|
|
@@ -184,8 +184,13 @@ export async function destroy(ctx: any) {
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
export async function bulkImport(ctx: any) {
|
|
187
|
+
const db = context.getAppDB()
|
|
187
188
|
const table = await sdk.tables.getTable(ctx.params.tableId)
|
|
188
189
|
const { rows } = ctx.request.body
|
|
189
190
|
await handleDataImport(ctx.user, table, rows)
|
|
191
|
+
|
|
192
|
+
// Ensure auto id and other table updates are persisted
|
|
193
|
+
await db.put(table)
|
|
194
|
+
|
|
190
195
|
return table
|
|
191
196
|
}
|
|
@@ -129,17 +129,17 @@ export function importToRows(
|
|
|
129
129
|
// the real schema of the table passed in, not the clone used for
|
|
130
130
|
// incrementing auto IDs
|
|
131
131
|
for (const [fieldName, schema] of Object.entries(originalTable.schema)) {
|
|
132
|
+
const rowVal = Array.isArray(row[fieldName])
|
|
133
|
+
? row[fieldName]
|
|
134
|
+
: [row[fieldName]]
|
|
132
135
|
if (
|
|
133
136
|
(schema.type === FieldTypes.OPTIONS ||
|
|
134
137
|
schema.type === FieldTypes.ARRAY) &&
|
|
135
|
-
row[fieldName]
|
|
136
|
-
(!schema.constraints!.inclusion ||
|
|
137
|
-
schema.constraints!.inclusion.indexOf(row[fieldName]) === -1)
|
|
138
|
+
row[fieldName]
|
|
138
139
|
) {
|
|
139
|
-
schema.constraints!.inclusion
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
]
|
|
140
|
+
let merged = [...schema.constraints!.inclusion!, ...rowVal]
|
|
141
|
+
let superSet = new Set(merged)
|
|
142
|
+
schema.constraints!.inclusion = Array.from(superSet)
|
|
143
143
|
schema.constraints!.inclusion.sort()
|
|
144
144
|
}
|
|
145
145
|
}
|
|
@@ -73,18 +73,97 @@ describe("run misc tests", () => {
|
|
|
73
73
|
type: "string",
|
|
74
74
|
},
|
|
75
75
|
},
|
|
76
|
+
e: {
|
|
77
|
+
name: "Auto ID",
|
|
78
|
+
type: "number",
|
|
79
|
+
subtype: "autoID",
|
|
80
|
+
icon: "ri-magic-line",
|
|
81
|
+
autocolumn: true,
|
|
82
|
+
constraints: {
|
|
83
|
+
type: "number",
|
|
84
|
+
presence: false,
|
|
85
|
+
numericality: {
|
|
86
|
+
greaterThanOrEqualTo: "",
|
|
87
|
+
lessThanOrEqualTo: "",
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
f: {
|
|
92
|
+
type: "array",
|
|
93
|
+
constraints: {
|
|
94
|
+
type: "array",
|
|
95
|
+
presence: {
|
|
96
|
+
"allowEmpty": true
|
|
97
|
+
},
|
|
98
|
+
inclusion: [
|
|
99
|
+
"One",
|
|
100
|
+
"Two",
|
|
101
|
+
"Three",
|
|
102
|
+
]
|
|
103
|
+
},
|
|
104
|
+
name: "Sample Tags",
|
|
105
|
+
sortable: false
|
|
106
|
+
},
|
|
107
|
+
g: {
|
|
108
|
+
type: "options",
|
|
109
|
+
constraints: {
|
|
110
|
+
type: "string",
|
|
111
|
+
presence: false,
|
|
112
|
+
inclusion: [
|
|
113
|
+
"Alpha",
|
|
114
|
+
"Beta",
|
|
115
|
+
"Gamma"
|
|
116
|
+
]
|
|
117
|
+
},
|
|
118
|
+
name: "Sample Opts"
|
|
119
|
+
}
|
|
76
120
|
},
|
|
77
121
|
})
|
|
78
|
-
|
|
122
|
+
|
|
123
|
+
// Shift specific row tests to the row spec
|
|
79
124
|
await tableUtils.handleDataImport(
|
|
80
125
|
{ userId: "test" },
|
|
81
126
|
table,
|
|
82
|
-
[
|
|
127
|
+
[
|
|
128
|
+
{ a: '1', b: '2', c: '3', d: '4', f: "['One']", g: "Alpha" },
|
|
129
|
+
{ a: '5', b: '6', c: '7', d: '8', f: "[]", g: undefined},
|
|
130
|
+
{ a: '9', b: '10', c: '11', d: '12', f: "['Two','Four']", g: ""},
|
|
131
|
+
{ a: '13', b: '14', c: '15', d: '16', g: "Omega"}
|
|
132
|
+
]
|
|
83
133
|
)
|
|
134
|
+
|
|
135
|
+
// 4 rows imported, the auto ID starts at 1
|
|
136
|
+
// We expect the handleDataImport function to update the lastID
|
|
137
|
+
expect(table.schema.e.lastID).toEqual(4);
|
|
138
|
+
|
|
139
|
+
// Array/Multi - should have added a new value to the inclusion.
|
|
140
|
+
expect(table.schema.f.constraints.inclusion).toEqual(['Four','One','Three','Two']);
|
|
141
|
+
|
|
142
|
+
// Options - should have a new value in the inclusion
|
|
143
|
+
expect(table.schema.g.constraints.inclusion).toEqual(['Alpha','Beta','Gamma','Omega']);
|
|
144
|
+
|
|
84
145
|
const rows = await config.getRows()
|
|
85
|
-
expect(rows
|
|
86
|
-
|
|
87
|
-
|
|
146
|
+
expect(rows.length).toEqual(4);
|
|
147
|
+
|
|
148
|
+
const rowOne = rows.find(row => row.e === 1)
|
|
149
|
+
expect(rowOne.a).toEqual("1")
|
|
150
|
+
expect(rowOne.f).toEqual(['One'])
|
|
151
|
+
expect(rowOne.g).toEqual('Alpha')
|
|
152
|
+
|
|
153
|
+
const rowTwo = rows.find(row => row.e === 2)
|
|
154
|
+
expect(rowTwo.a).toEqual("5")
|
|
155
|
+
expect(rowTwo.f).toEqual([])
|
|
156
|
+
expect(rowTwo.g).toEqual(undefined)
|
|
157
|
+
|
|
158
|
+
const rowThree = rows.find(row => row.e === 3)
|
|
159
|
+
expect(rowThree.a).toEqual("9")
|
|
160
|
+
expect(rowThree.f).toEqual(['Two','Four'])
|
|
161
|
+
expect(rowThree.g).toEqual(null)
|
|
162
|
+
|
|
163
|
+
const rowFour = rows.find(row => row.e === 4)
|
|
164
|
+
expect(rowFour.a).toEqual("13")
|
|
165
|
+
expect(rowFour.f).toEqual(undefined)
|
|
166
|
+
expect(rowFour.g).toEqual('Omega')
|
|
88
167
|
})
|
|
89
168
|
})
|
|
90
169
|
})
|
|
@@ -34,9 +34,9 @@ describe("/rows", () => {
|
|
|
34
34
|
row = basicRow(table._id)
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
const loadRow = async (id, status = 200) =>
|
|
37
|
+
const loadRow = async (id, tbl_Id, status = 200) =>
|
|
38
38
|
await request
|
|
39
|
-
.get(`/api/${
|
|
39
|
+
.get(`/api/${tbl_Id}/rows/${id}`)
|
|
40
40
|
.set(config.defaultHeaders())
|
|
41
41
|
.expect("Content-Type", /json/)
|
|
42
42
|
.expect(status)
|
|
@@ -182,8 +182,32 @@ describe("/rows", () => {
|
|
|
182
182
|
type: "string",
|
|
183
183
|
presence: false,
|
|
184
184
|
datetime: { earliest: "", latest: "" },
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const arrayField = {
|
|
188
|
+
type: "array",
|
|
189
|
+
constraints: {
|
|
190
|
+
type: "array",
|
|
191
|
+
presence: false,
|
|
192
|
+
inclusion: [
|
|
193
|
+
"One",
|
|
194
|
+
"Two",
|
|
195
|
+
"Three",
|
|
196
|
+
]
|
|
185
197
|
},
|
|
198
|
+
name: "Sample Tags",
|
|
199
|
+
sortable: false
|
|
186
200
|
}
|
|
201
|
+
const optsField = {
|
|
202
|
+
fieldName: "Sample Opts",
|
|
203
|
+
name: "Sample Opts",
|
|
204
|
+
type: "options",
|
|
205
|
+
constraints: {
|
|
206
|
+
type: "string",
|
|
207
|
+
presence: false,
|
|
208
|
+
inclusion: [ "Alpha", "Beta", "Gamma" ]
|
|
209
|
+
},
|
|
210
|
+
},
|
|
187
211
|
|
|
188
212
|
table = await config.createTable({
|
|
189
213
|
name: "TestTable2",
|
|
@@ -212,7 +236,15 @@ describe("/rows", () => {
|
|
|
212
236
|
attachmentNull: attachment,
|
|
213
237
|
attachmentUndefined: attachment,
|
|
214
238
|
attachmentEmpty: attachment,
|
|
215
|
-
attachmentEmptyArrayStr: attachment
|
|
239
|
+
attachmentEmptyArrayStr: attachment,
|
|
240
|
+
arrayFieldEmptyArrayStr: arrayField,
|
|
241
|
+
arrayFieldArrayStrKnown: arrayField,
|
|
242
|
+
arrayFieldNull: arrayField,
|
|
243
|
+
arrayFieldUndefined: arrayField,
|
|
244
|
+
optsFieldEmptyStr: optsField,
|
|
245
|
+
optsFieldUndefined: optsField,
|
|
246
|
+
optsFieldNull: optsField,
|
|
247
|
+
optsFieldStrKnown: optsField
|
|
216
248
|
},
|
|
217
249
|
})
|
|
218
250
|
|
|
@@ -241,11 +273,20 @@ describe("/rows", () => {
|
|
|
241
273
|
attachmentUndefined: undefined,
|
|
242
274
|
attachmentEmpty: "",
|
|
243
275
|
attachmentEmptyArrayStr: "[]",
|
|
276
|
+
arrayFieldEmptyArrayStr: "[]",
|
|
277
|
+
arrayFieldUndefined: undefined,
|
|
278
|
+
arrayFieldNull: null,
|
|
279
|
+
arrayFieldArrayStrKnown: "['One']",
|
|
280
|
+
optsFieldEmptyStr: "",
|
|
281
|
+
optsFieldUndefined: undefined,
|
|
282
|
+
optsFieldNull: null,
|
|
283
|
+
optsFieldStrKnown: 'Alpha'
|
|
244
284
|
}
|
|
245
285
|
|
|
246
|
-
const
|
|
286
|
+
const createdRow = await config.createRow(row);
|
|
287
|
+
const id = createdRow._id
|
|
247
288
|
|
|
248
|
-
const saved = (await loadRow(id)).body
|
|
289
|
+
const saved = (await loadRow(id, table._id)).body
|
|
249
290
|
|
|
250
291
|
expect(saved.stringUndefined).toBe(undefined)
|
|
251
292
|
expect(saved.stringNull).toBe("")
|
|
@@ -270,7 +311,15 @@ describe("/rows", () => {
|
|
|
270
311
|
expect(saved.attachmentNull).toEqual([])
|
|
271
312
|
expect(saved.attachmentUndefined).toBe(undefined)
|
|
272
313
|
expect(saved.attachmentEmpty).toEqual([])
|
|
273
|
-
expect(saved.attachmentEmptyArrayStr).toEqual([])
|
|
314
|
+
expect(saved.attachmentEmptyArrayStr).toEqual([])
|
|
315
|
+
expect(saved.arrayFieldEmptyArrayStr).toEqual([])
|
|
316
|
+
expect(saved.arrayFieldNull).toEqual([])
|
|
317
|
+
expect(saved.arrayFieldUndefined).toEqual(undefined)
|
|
318
|
+
expect(saved.optsFieldEmptyStr).toEqual(null)
|
|
319
|
+
expect(saved.optsFieldUndefined).toEqual(undefined)
|
|
320
|
+
expect(saved.optsFieldNull).toEqual(null)
|
|
321
|
+
expect(saved.arrayFieldArrayStrKnown).toEqual(['One'])
|
|
322
|
+
expect(saved.optsFieldStrKnown).toEqual('Alpha')
|
|
274
323
|
})
|
|
275
324
|
})
|
|
276
325
|
|
|
@@ -299,7 +348,7 @@ describe("/rows", () => {
|
|
|
299
348
|
expect(res.body.name).toEqual("Updated Name")
|
|
300
349
|
expect(res.body.description).toEqual(existing.description)
|
|
301
350
|
|
|
302
|
-
const savedRow = await loadRow(res.body._id)
|
|
351
|
+
const savedRow = await loadRow(res.body._id, table._id)
|
|
303
352
|
|
|
304
353
|
expect(savedRow.body.description).toEqual(existing.description)
|
|
305
354
|
expect(savedRow.body.name).toEqual("Updated Name")
|
|
@@ -401,7 +450,7 @@ describe("/rows", () => {
|
|
|
401
450
|
.expect(200)
|
|
402
451
|
|
|
403
452
|
expect(res.body.length).toEqual(2)
|
|
404
|
-
await loadRow(row1._id, 404)
|
|
453
|
+
await loadRow(row1._id, table._id, 404)
|
|
405
454
|
await assertRowUsage(rowUsage - 2)
|
|
406
455
|
await assertQueryUsage(queryUsage + 1)
|
|
407
456
|
})
|
|
@@ -167,7 +167,10 @@ describe("/tables", () => {
|
|
|
167
167
|
|
|
168
168
|
expect(events.table.created).not.toHaveBeenCalled()
|
|
169
169
|
expect(events.rows.imported).toBeCalledTimes(1)
|
|
170
|
-
expect(events.rows.imported).toBeCalledWith(
|
|
170
|
+
expect(events.rows.imported).toBeCalledWith(expect.objectContaining({
|
|
171
|
+
name: "TestTable",
|
|
172
|
+
_id: table._id
|
|
173
|
+
}), 1)
|
|
171
174
|
})
|
|
172
175
|
})
|
|
173
176
|
|
|
@@ -137,8 +137,7 @@ export function inputProcessing(
|
|
|
137
137
|
opts?: AutoColumnProcessingOpts
|
|
138
138
|
) {
|
|
139
139
|
let clonedRow = cloneDeep(row)
|
|
140
|
-
|
|
141
|
-
const copiedTable = cloneDeep(table)
|
|
140
|
+
|
|
142
141
|
const dontCleanseKeys = ["type", "_id", "_rev", "tableId"]
|
|
143
142
|
for (let [key, value] of Object.entries(clonedRow)) {
|
|
144
143
|
const field = table.schema[key]
|
|
@@ -175,7 +174,7 @@ export function inputProcessing(
|
|
|
175
174
|
}
|
|
176
175
|
|
|
177
176
|
// handle auto columns - this returns an object like {table, row}
|
|
178
|
-
return processAutoColumn(user,
|
|
177
|
+
return processAutoColumn(user, table, clonedRow, opts)
|
|
179
178
|
}
|
|
180
179
|
|
|
181
180
|
/**
|
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
import { FieldTypes } from "../../constants"
|
|
3
3
|
import { logging } from "@budibase/backend-core"
|
|
4
4
|
|
|
5
|
+
const parseArrayString = value => {
|
|
6
|
+
if (typeof value === "string") {
|
|
7
|
+
if (value === "") {
|
|
8
|
+
return []
|
|
9
|
+
}
|
|
10
|
+
let result
|
|
11
|
+
try {
|
|
12
|
+
result = JSON.parse(value.replace(/'/g, '"'))
|
|
13
|
+
return result
|
|
14
|
+
} catch (e) {
|
|
15
|
+
logging.logAlert("Could not parse row value", e)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return value
|
|
19
|
+
}
|
|
20
|
+
|
|
5
21
|
/**
|
|
6
22
|
* A map of how we convert various properties in rows to each other based on the row type.
|
|
7
23
|
*/
|
|
@@ -26,9 +42,9 @@ export const TYPE_TRANSFORM_MAP: any = {
|
|
|
26
42
|
[undefined]: undefined,
|
|
27
43
|
},
|
|
28
44
|
[FieldTypes.ARRAY]: {
|
|
29
|
-
"": [],
|
|
30
45
|
[null]: [],
|
|
31
46
|
[undefined]: undefined,
|
|
47
|
+
parse: parseArrayString,
|
|
32
48
|
},
|
|
33
49
|
[FieldTypes.STRING]: {
|
|
34
50
|
"": "",
|
|
@@ -70,21 +86,7 @@ export const TYPE_TRANSFORM_MAP: any = {
|
|
|
70
86
|
[FieldTypes.ATTACHMENT]: {
|
|
71
87
|
[null]: [],
|
|
72
88
|
[undefined]: undefined,
|
|
73
|
-
parse:
|
|
74
|
-
if (typeof attachments === "string") {
|
|
75
|
-
if (attachments === "") {
|
|
76
|
-
return []
|
|
77
|
-
}
|
|
78
|
-
let result
|
|
79
|
-
try {
|
|
80
|
-
result = JSON.parse(attachments)
|
|
81
|
-
} catch (e) {
|
|
82
|
-
logging.logAlert("Could not parse attachments", e)
|
|
83
|
-
}
|
|
84
|
-
return result
|
|
85
|
-
}
|
|
86
|
-
return attachments
|
|
87
|
-
},
|
|
89
|
+
parse: parseArrayString,
|
|
88
90
|
},
|
|
89
91
|
[FieldTypes.BOOLEAN]: {
|
|
90
92
|
"": null,
|