@webiny/api-form-builder-so-ddb 0.0.0-ee-vpcs.549378cf03

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