@webiny/api-form-builder-so-ddb 0.0.0-mt-1
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/LICENSE +21 -0
- package/README.md +13 -0
- package/definitions/form.d.ts +8 -0
- package/definitions/form.js +110 -0
- package/definitions/settings.d.ts +8 -0
- package/definitions/settings.js +53 -0
- package/definitions/submission.d.ts +8 -0
- package/definitions/submission.js +74 -0
- package/definitions/system.d.ts +8 -0
- package/definitions/system.js +44 -0
- package/definitions/table.d.ts +7 -0
- package/definitions/table.js +29 -0
- package/index.d.ts +2 -0
- package/index.js +139 -0
- package/operations/form/fields.d.ts +3 -0
- package/operations/form/fields.js +43 -0
- package/operations/form/index.d.ts +9 -0
- package/operations/form/index.js +745 -0
- package/operations/settings/index.d.ts +7 -0
- package/operations/settings/index.js +122 -0
- package/operations/submission/fields.d.ts +3 -0
- package/operations/submission/fields.js +18 -0
- package/operations/submission/index.d.ts +9 -0
- package/operations/submission/index.js +247 -0
- package/operations/system/index.d.ts +7 -0
- package/operations/system/index.js +105 -0
- package/package.json +56 -0
- package/plugins/FormDynamoDbFieldPlugin.d.ts +4 -0
- package/plugins/FormDynamoDbFieldPlugin.js +17 -0
- package/plugins/FormSubmissionDynamoDbFieldPlugin.d.ts +4 -0
- package/plugins/FormSubmissionDynamoDbFieldPlugin.js +17 -0
- package/types.d.ts +65 -0
- package/types.js +15 -0
|
@@ -0,0 +1,745 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
|
|
5
|
+
Object.defineProperty(exports, "__esModule", {
|
|
6
|
+
value: true
|
|
7
|
+
});
|
|
8
|
+
exports.createFormStorageOperations = void 0;
|
|
9
|
+
|
|
10
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
|
+
|
|
12
|
+
var _error = _interopRequireDefault(require("@webiny/error"));
|
|
13
|
+
|
|
14
|
+
var _query = require("@webiny/db-dynamodb/utils/query");
|
|
15
|
+
|
|
16
|
+
var _cleanup = require("@webiny/db-dynamodb/utils/cleanup");
|
|
17
|
+
|
|
18
|
+
var _batchWrite = require("@webiny/db-dynamodb/utils/batchWrite");
|
|
19
|
+
|
|
20
|
+
var _filter = require("@webiny/db-dynamodb/utils/filter");
|
|
21
|
+
|
|
22
|
+
var _sort = require("@webiny/db-dynamodb/utils/sort");
|
|
23
|
+
|
|
24
|
+
var _utils = require("@webiny/utils");
|
|
25
|
+
|
|
26
|
+
var _FormDynamoDbFieldPlugin = require("../../plugins/FormDynamoDbFieldPlugin");
|
|
27
|
+
|
|
28
|
+
var _cursor = require("@webiny/db-dynamodb/utils/cursor");
|
|
29
|
+
|
|
30
|
+
var _get = require("@webiny/db-dynamodb/utils/get");
|
|
31
|
+
|
|
32
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
|
|
33
|
+
|
|
34
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
|
|
35
|
+
|
|
36
|
+
const createFormStorageOperations = params => {
|
|
37
|
+
const {
|
|
38
|
+
entity,
|
|
39
|
+
table,
|
|
40
|
+
plugins
|
|
41
|
+
} = params;
|
|
42
|
+
const formDynamoDbFields = plugins.byType(_FormDynamoDbFieldPlugin.FormDynamoDbFieldPlugin.type);
|
|
43
|
+
|
|
44
|
+
const createFormPartitionKey = params => {
|
|
45
|
+
const {
|
|
46
|
+
tenant,
|
|
47
|
+
locale
|
|
48
|
+
} = params;
|
|
49
|
+
return `T#${tenant}#L#${locale}#FB#F`;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const createFormLatestPartitionKey = params => {
|
|
53
|
+
return `${createFormPartitionKey(params)}#L`;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const createFormLatestPublishedPartitionKey = params => {
|
|
57
|
+
return `${createFormPartitionKey(params)}#LP`;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const createFormGSIPartitionKey = params => {
|
|
61
|
+
const {
|
|
62
|
+
tenant,
|
|
63
|
+
locale,
|
|
64
|
+
id: targetId
|
|
65
|
+
} = params;
|
|
66
|
+
const {
|
|
67
|
+
id
|
|
68
|
+
} = (0, _utils.parseIdentifier)(targetId);
|
|
69
|
+
return `T#${tenant}#L#${locale}#FB#F#${id}`;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const createRevisionSortKey = ({
|
|
73
|
+
id
|
|
74
|
+
}) => {
|
|
75
|
+
return `${id}`;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const createFormLatestSortKey = ({
|
|
79
|
+
id,
|
|
80
|
+
formId
|
|
81
|
+
}) => {
|
|
82
|
+
const value = (0, _utils.parseIdentifier)(id || formId);
|
|
83
|
+
return value.id;
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const createLatestPublishedSortKey = ({
|
|
87
|
+
id,
|
|
88
|
+
formId
|
|
89
|
+
}) => {
|
|
90
|
+
const value = (0, _utils.parseIdentifier)(id || formId);
|
|
91
|
+
return value.id;
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const createGSISortKey = version => {
|
|
95
|
+
return `${version}`;
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const createFormType = () => {
|
|
99
|
+
return "fb.form";
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const createFormLatestType = () => {
|
|
103
|
+
return "fb.form.latest";
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const createFormLatestPublishedType = () => {
|
|
107
|
+
return "fb.form.latestPublished";
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const createRevisionKeys = form => {
|
|
111
|
+
return {
|
|
112
|
+
PK: createFormPartitionKey(form),
|
|
113
|
+
SK: createRevisionSortKey(form)
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const createLatestKeys = form => {
|
|
118
|
+
return {
|
|
119
|
+
PK: createFormLatestPartitionKey(form),
|
|
120
|
+
SK: createFormLatestSortKey(form)
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const createLatestPublishedKeys = form => {
|
|
125
|
+
return {
|
|
126
|
+
PK: createFormLatestPublishedPartitionKey(form),
|
|
127
|
+
SK: createLatestPublishedSortKey(form)
|
|
128
|
+
};
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const createGSIKeys = form => {
|
|
132
|
+
return {
|
|
133
|
+
GSI1_PK: createFormGSIPartitionKey(form),
|
|
134
|
+
GSI1_SK: createGSISortKey(form.version)
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const createForm = async params => {
|
|
139
|
+
const {
|
|
140
|
+
form
|
|
141
|
+
} = params;
|
|
142
|
+
const revisionKeys = createRevisionKeys(form);
|
|
143
|
+
const latestKeys = createLatestKeys(form);
|
|
144
|
+
const gsiKeys = createGSIKeys(form);
|
|
145
|
+
const items = [entity.putBatch(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, form), revisionKeys), gsiKeys), {}, {
|
|
146
|
+
TYPE: createFormType()
|
|
147
|
+
})), entity.putBatch(_objectSpread(_objectSpread(_objectSpread({}, form), latestKeys), {}, {
|
|
148
|
+
TYPE: createFormLatestType()
|
|
149
|
+
}))];
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
await (0, _batchWrite.batchWriteAll)({
|
|
153
|
+
table,
|
|
154
|
+
items
|
|
155
|
+
});
|
|
156
|
+
} catch (ex) {
|
|
157
|
+
throw new _error.default(ex.message || "Could not insert form data into table.", ex.code || "CREATE_FORM_ERROR", {
|
|
158
|
+
revisionKeys,
|
|
159
|
+
latestKeys,
|
|
160
|
+
form
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return form;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const createFormFrom = async params => {
|
|
168
|
+
const {
|
|
169
|
+
form,
|
|
170
|
+
original,
|
|
171
|
+
latest
|
|
172
|
+
} = params;
|
|
173
|
+
const revisionKeys = createRevisionKeys(form);
|
|
174
|
+
const latestKeys = createLatestKeys(form);
|
|
175
|
+
const gsiKeys = createGSIKeys(form);
|
|
176
|
+
const items = [entity.putBatch(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, form), revisionKeys), gsiKeys), {}, {
|
|
177
|
+
TYPE: createFormType()
|
|
178
|
+
})), entity.putBatch(_objectSpread(_objectSpread(_objectSpread({}, form), latestKeys), {}, {
|
|
179
|
+
TYPE: createFormLatestType()
|
|
180
|
+
}))];
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
await (0, _batchWrite.batchWriteAll)({
|
|
184
|
+
table,
|
|
185
|
+
items
|
|
186
|
+
});
|
|
187
|
+
} catch (ex) {
|
|
188
|
+
throw new _error.default(ex.message || "Could not create form data in the table, from existing form.", ex.code || "CREATE_FORM_FROM_ERROR", {
|
|
189
|
+
revisionKeys,
|
|
190
|
+
latestKeys,
|
|
191
|
+
original,
|
|
192
|
+
form,
|
|
193
|
+
latest
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
return form;
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
const updateForm = async params => {
|
|
201
|
+
const {
|
|
202
|
+
form,
|
|
203
|
+
original
|
|
204
|
+
} = params;
|
|
205
|
+
const revisionKeys = createRevisionKeys(form);
|
|
206
|
+
const latestKeys = createLatestKeys(form);
|
|
207
|
+
const gsiKeys = createGSIKeys(form);
|
|
208
|
+
const {
|
|
209
|
+
formId,
|
|
210
|
+
tenant,
|
|
211
|
+
locale
|
|
212
|
+
} = form;
|
|
213
|
+
const latestForm = await getForm({
|
|
214
|
+
where: {
|
|
215
|
+
formId,
|
|
216
|
+
tenant,
|
|
217
|
+
locale,
|
|
218
|
+
latest: true
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
const isLatestForm = latestForm ? latestForm.id === form.id : false;
|
|
222
|
+
const items = [entity.putBatch(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, form), revisionKeys), gsiKeys), {}, {
|
|
223
|
+
TYPE: createFormType()
|
|
224
|
+
}))];
|
|
225
|
+
|
|
226
|
+
if (isLatestForm) {
|
|
227
|
+
items.push(entity.putBatch(_objectSpread(_objectSpread(_objectSpread({}, form), latestKeys), {}, {
|
|
228
|
+
TYPE: createFormLatestType()
|
|
229
|
+
})));
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
try {
|
|
233
|
+
await (0, _batchWrite.batchWriteAll)({
|
|
234
|
+
table,
|
|
235
|
+
items
|
|
236
|
+
});
|
|
237
|
+
} catch (ex) {
|
|
238
|
+
throw new _error.default(ex.message || "Could not update form data in the table.", ex.code || "UPDATE_FORM_ERROR", {
|
|
239
|
+
revisionKeys,
|
|
240
|
+
latestKeys,
|
|
241
|
+
original,
|
|
242
|
+
form,
|
|
243
|
+
latestForm
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return form;
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
const getForm = async params => {
|
|
251
|
+
const {
|
|
252
|
+
where
|
|
253
|
+
} = params;
|
|
254
|
+
const {
|
|
255
|
+
id,
|
|
256
|
+
formId,
|
|
257
|
+
latest,
|
|
258
|
+
published,
|
|
259
|
+
version
|
|
260
|
+
} = where;
|
|
261
|
+
|
|
262
|
+
if (latest && published) {
|
|
263
|
+
throw new _error.default("Cannot have both latest and published params.");
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
let partitionKey;
|
|
267
|
+
let sortKey;
|
|
268
|
+
|
|
269
|
+
if (latest) {
|
|
270
|
+
partitionKey = createFormLatestPartitionKey(where);
|
|
271
|
+
sortKey = createFormLatestSortKey(where);
|
|
272
|
+
} else if (published && !version) {
|
|
273
|
+
/**
|
|
274
|
+
* Because of the specifics how DynamoDB works, we must not load the published record if version is sent.
|
|
275
|
+
*/
|
|
276
|
+
partitionKey = createFormLatestPublishedPartitionKey(where);
|
|
277
|
+
sortKey = createLatestPublishedSortKey(where);
|
|
278
|
+
} else if (id || version) {
|
|
279
|
+
partitionKey = createFormPartitionKey(where);
|
|
280
|
+
sortKey = createRevisionSortKey({
|
|
281
|
+
id: id || (0, _utils.createIdentifier)({
|
|
282
|
+
id: formId,
|
|
283
|
+
version
|
|
284
|
+
})
|
|
285
|
+
});
|
|
286
|
+
} else {
|
|
287
|
+
throw new _error.default("Missing parameter to create a sort key.", "MISSING_WHERE_PARAMETER", {
|
|
288
|
+
where
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const keys = {
|
|
293
|
+
PK: partitionKey,
|
|
294
|
+
SK: sortKey
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
try {
|
|
298
|
+
const item = await (0, _get.get)({
|
|
299
|
+
entity,
|
|
300
|
+
keys
|
|
301
|
+
});
|
|
302
|
+
return (0, _cleanup.cleanupItem)(entity, item);
|
|
303
|
+
} catch (ex) {
|
|
304
|
+
throw new _error.default(ex.message || "Could not get form by keys.", ex.code || "GET_FORM_ERROR", {
|
|
305
|
+
keys
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
const listForms = async params => {
|
|
311
|
+
const {
|
|
312
|
+
sort,
|
|
313
|
+
limit,
|
|
314
|
+
where: initialWhere,
|
|
315
|
+
after
|
|
316
|
+
} = params;
|
|
317
|
+
const queryAllParams = {
|
|
318
|
+
entity,
|
|
319
|
+
partitionKey: createFormLatestPartitionKey(initialWhere),
|
|
320
|
+
options: {
|
|
321
|
+
gte: " "
|
|
322
|
+
}
|
|
323
|
+
};
|
|
324
|
+
let results;
|
|
325
|
+
|
|
326
|
+
try {
|
|
327
|
+
results = await (0, _query.queryAll)(queryAllParams);
|
|
328
|
+
} catch (ex) {
|
|
329
|
+
throw new _error.default(ex.message || "Could list forms.", ex.code || "LIST_FORMS_ERROR", {
|
|
330
|
+
where: initialWhere,
|
|
331
|
+
partitionKey: queryAllParams.partitionKey
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
const totalCount = results.length;
|
|
336
|
+
|
|
337
|
+
const where = _objectSpread({}, initialWhere);
|
|
338
|
+
/**
|
|
339
|
+
* We need to remove conditions so we do not filter by them again.
|
|
340
|
+
*/
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
delete where.tenant;
|
|
344
|
+
delete where.locale;
|
|
345
|
+
const filteredItems = (0, _filter.filterItems)({
|
|
346
|
+
plugins,
|
|
347
|
+
items: results,
|
|
348
|
+
where,
|
|
349
|
+
fields: formDynamoDbFields
|
|
350
|
+
});
|
|
351
|
+
const sortedItems = (0, _sort.sortItems)({
|
|
352
|
+
items: filteredItems,
|
|
353
|
+
sort,
|
|
354
|
+
fields: formDynamoDbFields
|
|
355
|
+
});
|
|
356
|
+
const start = (0, _cursor.decodeCursor)(after) || 0;
|
|
357
|
+
const hasMoreItems = totalCount > start + limit;
|
|
358
|
+
const end = limit > totalCount + start + limit ? undefined : start + limit;
|
|
359
|
+
const items = sortedItems.slice(start, end);
|
|
360
|
+
/**
|
|
361
|
+
* Although we do not need a cursor here, we will use it as such to keep it standardized.
|
|
362
|
+
* Number is simply encoded.
|
|
363
|
+
*/
|
|
364
|
+
|
|
365
|
+
const cursor = items.length > 0 ? (0, _cursor.encodeCursor)(start + limit) : null;
|
|
366
|
+
const meta = {
|
|
367
|
+
hasMoreItems,
|
|
368
|
+
totalCount,
|
|
369
|
+
cursor
|
|
370
|
+
};
|
|
371
|
+
return {
|
|
372
|
+
items,
|
|
373
|
+
meta
|
|
374
|
+
};
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
const listFormRevisions = async params => {
|
|
378
|
+
const {
|
|
379
|
+
where: initialWhere,
|
|
380
|
+
sort
|
|
381
|
+
} = params;
|
|
382
|
+
const {
|
|
383
|
+
id,
|
|
384
|
+
formId,
|
|
385
|
+
tenant,
|
|
386
|
+
locale
|
|
387
|
+
} = initialWhere;
|
|
388
|
+
const queryAllParams = {
|
|
389
|
+
entity,
|
|
390
|
+
partitionKey: createFormGSIPartitionKey({
|
|
391
|
+
tenant,
|
|
392
|
+
locale,
|
|
393
|
+
id: formId || id
|
|
394
|
+
}),
|
|
395
|
+
options: {
|
|
396
|
+
index: "GSI1",
|
|
397
|
+
gte: " "
|
|
398
|
+
}
|
|
399
|
+
};
|
|
400
|
+
let items = [];
|
|
401
|
+
|
|
402
|
+
try {
|
|
403
|
+
items = await (0, _query.queryAll)(queryAllParams);
|
|
404
|
+
} catch (ex) {
|
|
405
|
+
throw new _error.default(ex.message || "Could not query forms by given params.", ex.code || "QUERY_FORMS_ERROR", {
|
|
406
|
+
partitionKey: queryAllParams.partitionKey,
|
|
407
|
+
options: queryAllParams.options
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const where = _objectSpread({}, initialWhere);
|
|
412
|
+
/**
|
|
413
|
+
* We need to remove conditions so we do not filter by them again.
|
|
414
|
+
*/
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
delete where.id;
|
|
418
|
+
delete where.formId;
|
|
419
|
+
delete where.tenant;
|
|
420
|
+
delete where.locale;
|
|
421
|
+
const filteredItems = (0, _filter.filterItems)({
|
|
422
|
+
plugins,
|
|
423
|
+
items,
|
|
424
|
+
where,
|
|
425
|
+
fields: formDynamoDbFields
|
|
426
|
+
});
|
|
427
|
+
return (0, _sort.sortItems)({
|
|
428
|
+
items: filteredItems,
|
|
429
|
+
sort,
|
|
430
|
+
fields: formDynamoDbFields
|
|
431
|
+
});
|
|
432
|
+
};
|
|
433
|
+
|
|
434
|
+
const deleteForm = async params => {
|
|
435
|
+
const {
|
|
436
|
+
form
|
|
437
|
+
} = params;
|
|
438
|
+
let items;
|
|
439
|
+
/**
|
|
440
|
+
* This will find all form and submission records.
|
|
441
|
+
*/
|
|
442
|
+
|
|
443
|
+
const queryAllParams = {
|
|
444
|
+
entity,
|
|
445
|
+
partitionKey: createFormPartitionKey(form),
|
|
446
|
+
options: {
|
|
447
|
+
gte: " "
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
try {
|
|
452
|
+
items = await (0, _query.queryAll)(queryAllParams);
|
|
453
|
+
} catch (ex) {
|
|
454
|
+
throw new _error.default(ex.message || "Could not query forms and submissions by given params.", ex.code || "QUERY_FORM_AND_SUBMISSIONS_ERROR", {
|
|
455
|
+
partitionKey: queryAllParams.partitionKey,
|
|
456
|
+
options: queryAllParams.options
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
let hasLatestPublishedRecord = false;
|
|
461
|
+
const deleteItems = items.map(item => {
|
|
462
|
+
if (!hasLatestPublishedRecord && item.published) {
|
|
463
|
+
hasLatestPublishedRecord = true;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
return entity.deleteBatch({
|
|
467
|
+
PK: item.PK,
|
|
468
|
+
SK: item.SK
|
|
469
|
+
});
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
if (hasLatestPublishedRecord) {
|
|
473
|
+
deleteItems.push(entity.deleteBatch(createLatestPublishedKeys(items[0])));
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
deleteItems.push(entity.deleteBatch(createLatestKeys(items[0])));
|
|
477
|
+
|
|
478
|
+
try {
|
|
479
|
+
await (0, _batchWrite.batchWriteAll)({
|
|
480
|
+
table,
|
|
481
|
+
items: deleteItems
|
|
482
|
+
});
|
|
483
|
+
} catch (ex) {
|
|
484
|
+
throw new _error.default(ex.message || "Could not delete form and it's submissions.", ex.code || "DELETE_FORM_AND_SUBMISSIONS_ERROR");
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return form;
|
|
488
|
+
};
|
|
489
|
+
/**
|
|
490
|
+
* We need to:
|
|
491
|
+
* - delete current revision
|
|
492
|
+
* - get previously published revision and update the record if it exists or delete if it does not
|
|
493
|
+
* - update latest record if current one is the latest
|
|
494
|
+
*/
|
|
495
|
+
|
|
496
|
+
|
|
497
|
+
const deleteFormRevision = async params => {
|
|
498
|
+
const {
|
|
499
|
+
form,
|
|
500
|
+
revisions,
|
|
501
|
+
previous
|
|
502
|
+
} = params;
|
|
503
|
+
const revisionKeys = createRevisionKeys(form);
|
|
504
|
+
const latestKeys = createLatestKeys(form);
|
|
505
|
+
const latestForm = revisions[0];
|
|
506
|
+
const latestPublishedForm = revisions.find(rev => rev.published === true);
|
|
507
|
+
const isLatest = latestForm ? latestForm.id === form.id : false;
|
|
508
|
+
const isLatestPublished = latestPublishedForm ? latestPublishedForm.id === form.id : false;
|
|
509
|
+
const items = [entity.deleteBatch(revisionKeys)];
|
|
510
|
+
|
|
511
|
+
if (isLatest || isLatestPublished) {
|
|
512
|
+
/**
|
|
513
|
+
* Sort out the latest published record.
|
|
514
|
+
*/
|
|
515
|
+
if (isLatestPublished) {
|
|
516
|
+
const previouslyPublishedForm = revisions.filter(f => !!f.publishedOn && f.version !== form.version).sort((a, b) => {
|
|
517
|
+
return new Date(b.publishedOn).getTime() - new Date(a.publishedOn).getTime();
|
|
518
|
+
}).shift();
|
|
519
|
+
|
|
520
|
+
if (previouslyPublishedForm) {
|
|
521
|
+
items.push(entity.putBatch(_objectSpread(_objectSpread(_objectSpread({}, previouslyPublishedForm), createLatestPublishedKeys(previouslyPublishedForm)), {}, {
|
|
522
|
+
GSI1_PK: null,
|
|
523
|
+
GSI1_SK: null,
|
|
524
|
+
TYPE: createFormLatestPublishedType()
|
|
525
|
+
})));
|
|
526
|
+
} else {
|
|
527
|
+
items.push(entity.deleteBatch(createLatestPublishedKeys(previouslyPublishedForm)));
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Sort out the latest record.
|
|
532
|
+
*/
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
if (isLatest) {
|
|
536
|
+
items.push(entity.putBatch(_objectSpread(_objectSpread(_objectSpread({}, previous), latestKeys), {}, {
|
|
537
|
+
GSI1_PK: null,
|
|
538
|
+
GSI1_SK: null,
|
|
539
|
+
TYPE: createFormLatestType()
|
|
540
|
+
})));
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
/**
|
|
544
|
+
* Now save the batch data.
|
|
545
|
+
*/
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
try {
|
|
549
|
+
await (0, _batchWrite.batchWriteAll)({
|
|
550
|
+
table,
|
|
551
|
+
items
|
|
552
|
+
});
|
|
553
|
+
return form;
|
|
554
|
+
} catch (ex) {
|
|
555
|
+
throw new _error.default(ex.message || "Could not delete form revision from table.", ex.code || "DELETE_FORM_REVISION_ERROR", {
|
|
556
|
+
form,
|
|
557
|
+
latestForm,
|
|
558
|
+
revisionKeys,
|
|
559
|
+
latestKeys
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
};
|
|
563
|
+
/**
|
|
564
|
+
* We need to save form in:
|
|
565
|
+
* - regular form record
|
|
566
|
+
* - latest published form record
|
|
567
|
+
* - latest form record - if form is latest one
|
|
568
|
+
* - elasticsearch latest form record
|
|
569
|
+
*/
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
const publishForm = async params => {
|
|
573
|
+
const {
|
|
574
|
+
form,
|
|
575
|
+
original
|
|
576
|
+
} = params;
|
|
577
|
+
const revisionKeys = createRevisionKeys(form);
|
|
578
|
+
const latestKeys = createLatestKeys(form);
|
|
579
|
+
const latestPublishedKeys = createLatestPublishedKeys(form);
|
|
580
|
+
const gsiKeys = {
|
|
581
|
+
GSI1_PK: createFormGSIPartitionKey(form),
|
|
582
|
+
GSI1_SK: createGSISortKey(form.version)
|
|
583
|
+
};
|
|
584
|
+
const {
|
|
585
|
+
locale,
|
|
586
|
+
tenant,
|
|
587
|
+
formId
|
|
588
|
+
} = form;
|
|
589
|
+
const latestForm = await getForm({
|
|
590
|
+
where: {
|
|
591
|
+
formId,
|
|
592
|
+
tenant,
|
|
593
|
+
locale,
|
|
594
|
+
latest: true
|
|
595
|
+
}
|
|
596
|
+
});
|
|
597
|
+
const isLatestForm = latestForm ? latestForm.id === form.id : false;
|
|
598
|
+
/**
|
|
599
|
+
* Update revision and latest published records
|
|
600
|
+
*/
|
|
601
|
+
|
|
602
|
+
const items = [entity.putBatch(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, form), revisionKeys), gsiKeys), {}, {
|
|
603
|
+
TYPE: createFormType()
|
|
604
|
+
})), entity.putBatch(_objectSpread(_objectSpread(_objectSpread({}, form), latestPublishedKeys), {}, {
|
|
605
|
+
TYPE: createFormLatestPublishedType()
|
|
606
|
+
}))];
|
|
607
|
+
/**
|
|
608
|
+
* Update the latest form as well
|
|
609
|
+
*/
|
|
610
|
+
|
|
611
|
+
if (isLatestForm) {
|
|
612
|
+
items.push(entity.putBatch(_objectSpread(_objectSpread(_objectSpread({}, form), latestKeys), {}, {
|
|
613
|
+
TYPE: createFormLatestType()
|
|
614
|
+
})));
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
try {
|
|
618
|
+
await (0, _batchWrite.batchWriteAll)({
|
|
619
|
+
table,
|
|
620
|
+
items
|
|
621
|
+
});
|
|
622
|
+
} catch (ex) {
|
|
623
|
+
throw new _error.default(ex.message || "Could not publish form.", ex.code || "PUBLISH_FORM_ERROR", {
|
|
624
|
+
form,
|
|
625
|
+
original,
|
|
626
|
+
latestForm,
|
|
627
|
+
revisionKeys,
|
|
628
|
+
latestKeys,
|
|
629
|
+
latestPublishedKeys
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
return form;
|
|
634
|
+
};
|
|
635
|
+
/**
|
|
636
|
+
* We need to:
|
|
637
|
+
* - update form revision record
|
|
638
|
+
* - if latest published (LP) is current form, find the previously published record and update LP if there is some previously published, delete otherwise
|
|
639
|
+
* - if is latest update the Elasticsearch record
|
|
640
|
+
*/
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
const unpublishForm = async params => {
|
|
644
|
+
const {
|
|
645
|
+
form,
|
|
646
|
+
original
|
|
647
|
+
} = params;
|
|
648
|
+
const revisionKeys = createRevisionKeys(form);
|
|
649
|
+
const latestKeys = createLatestKeys(form);
|
|
650
|
+
const latestPublishedKeys = createLatestPublishedKeys(form);
|
|
651
|
+
const gsiKeys = createGSIKeys(form);
|
|
652
|
+
const {
|
|
653
|
+
formId,
|
|
654
|
+
tenant,
|
|
655
|
+
locale
|
|
656
|
+
} = form;
|
|
657
|
+
const latestForm = await getForm({
|
|
658
|
+
where: {
|
|
659
|
+
formId,
|
|
660
|
+
tenant,
|
|
661
|
+
locale,
|
|
662
|
+
latest: true
|
|
663
|
+
}
|
|
664
|
+
});
|
|
665
|
+
const latestPublishedForm = await getForm({
|
|
666
|
+
where: {
|
|
667
|
+
formId,
|
|
668
|
+
tenant,
|
|
669
|
+
locale,
|
|
670
|
+
published: true
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
const isLatest = latestForm ? latestForm.id === form.id : false;
|
|
674
|
+
const isLatestPublished = latestPublishedForm ? latestPublishedForm.id === form.id : false;
|
|
675
|
+
const items = [entity.putBatch(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, form), revisionKeys), gsiKeys), {}, {
|
|
676
|
+
TYPE: createFormType()
|
|
677
|
+
}))];
|
|
678
|
+
|
|
679
|
+
if (isLatest) {
|
|
680
|
+
entity.putBatch(_objectSpread(_objectSpread(_objectSpread({}, form), latestKeys), {}, {
|
|
681
|
+
TYPE: createFormLatestType()
|
|
682
|
+
}));
|
|
683
|
+
}
|
|
684
|
+
/**
|
|
685
|
+
* In case previously published revision exists, replace current one with that one.
|
|
686
|
+
* And if it does not, delete the record.
|
|
687
|
+
*/
|
|
688
|
+
|
|
689
|
+
|
|
690
|
+
if (isLatestPublished) {
|
|
691
|
+
const revisions = await listFormRevisions({
|
|
692
|
+
where: {
|
|
693
|
+
formId,
|
|
694
|
+
tenant,
|
|
695
|
+
locale,
|
|
696
|
+
version_not: form.version,
|
|
697
|
+
publishedOn_not: null
|
|
698
|
+
},
|
|
699
|
+
sort: ["savedOn_DESC"]
|
|
700
|
+
});
|
|
701
|
+
const previouslyPublishedRevision = revisions.shift();
|
|
702
|
+
|
|
703
|
+
if (previouslyPublishedRevision) {
|
|
704
|
+
items.push(entity.putBatch(_objectSpread(_objectSpread(_objectSpread({}, previouslyPublishedRevision), latestPublishedKeys), {}, {
|
|
705
|
+
TYPE: createFormLatestPublishedType()
|
|
706
|
+
})));
|
|
707
|
+
} else {
|
|
708
|
+
items.push(entity.deleteBatch(latestPublishedKeys));
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
try {
|
|
713
|
+
await (0, _batchWrite.batchWriteAll)({
|
|
714
|
+
table,
|
|
715
|
+
items
|
|
716
|
+
});
|
|
717
|
+
return form;
|
|
718
|
+
} catch (ex) {
|
|
719
|
+
throw new _error.default(ex.message || "Could not unpublish form.", ex.code || "UNPUBLISH_FORM_ERROR", {
|
|
720
|
+
form,
|
|
721
|
+
original,
|
|
722
|
+
latestForm,
|
|
723
|
+
revisionKeys,
|
|
724
|
+
latestKeys,
|
|
725
|
+
latestPublishedKeys
|
|
726
|
+
});
|
|
727
|
+
}
|
|
728
|
+
};
|
|
729
|
+
|
|
730
|
+
return {
|
|
731
|
+
createForm,
|
|
732
|
+
createFormFrom,
|
|
733
|
+
updateForm,
|
|
734
|
+
listForms,
|
|
735
|
+
listFormRevisions,
|
|
736
|
+
getForm,
|
|
737
|
+
deleteForm,
|
|
738
|
+
deleteFormRevision,
|
|
739
|
+
publishForm,
|
|
740
|
+
unpublishForm,
|
|
741
|
+
createFormPartitionKey
|
|
742
|
+
};
|
|
743
|
+
};
|
|
744
|
+
|
|
745
|
+
exports.createFormStorageOperations = createFormStorageOperations;
|