@wix/bex-core 2.328.0 → 2.330.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 (254) hide show
  1. package/dist/cjs/assets/locale/messages_ar.json +12 -0
  2. package/dist/cjs/assets/locale/messages_bg.json +12 -0
  3. package/dist/cjs/assets/locale/messages_ca.json +12 -0
  4. package/dist/cjs/assets/locale/messages_cs.json +12 -0
  5. package/dist/cjs/assets/locale/messages_da.json +17 -5
  6. package/dist/cjs/assets/locale/messages_de.json +12 -0
  7. package/dist/cjs/assets/locale/messages_el.json +12 -0
  8. package/dist/cjs/assets/locale/messages_en.json +12 -0
  9. package/dist/cjs/assets/locale/messages_es.json +16 -4
  10. package/dist/cjs/assets/locale/messages_fi.json +12 -0
  11. package/dist/cjs/assets/locale/messages_fr.json +12 -0
  12. package/dist/cjs/assets/locale/messages_he.json +12 -0
  13. package/dist/cjs/assets/locale/messages_hi.json +17 -5
  14. package/dist/cjs/assets/locale/messages_hu.json +12 -0
  15. package/dist/cjs/assets/locale/messages_id.json +17 -5
  16. package/dist/cjs/assets/locale/messages_it.json +17 -5
  17. package/dist/cjs/assets/locale/messages_ja.json +12 -0
  18. package/dist/cjs/assets/locale/messages_ko.json +17 -5
  19. package/dist/cjs/assets/locale/messages_lt.json +12 -0
  20. package/dist/cjs/assets/locale/messages_ms.json +12 -0
  21. package/dist/cjs/assets/locale/messages_nl.json +16 -4
  22. package/dist/cjs/assets/locale/messages_no.json +12 -0
  23. package/dist/cjs/assets/locale/messages_pl.json +12 -0
  24. package/dist/cjs/assets/locale/messages_pt.json +16 -4
  25. package/dist/cjs/assets/locale/messages_ro.json +12 -0
  26. package/dist/cjs/assets/locale/messages_ru.json +12 -0
  27. package/dist/cjs/assets/locale/messages_sk.json +12 -0
  28. package/dist/cjs/assets/locale/messages_sl.json +12 -0
  29. package/dist/cjs/assets/locale/messages_sv.json +17 -5
  30. package/dist/cjs/assets/locale/messages_th.json +17 -5
  31. package/dist/cjs/assets/locale/messages_tl.json +12 -0
  32. package/dist/cjs/assets/locale/messages_tr.json +17 -5
  33. package/dist/cjs/assets/locale/messages_uk.json +12 -0
  34. package/dist/cjs/assets/locale/messages_vi.json +17 -5
  35. package/dist/cjs/assets/locale/messages_zh.json +12 -0
  36. package/dist/cjs/assets/locale/version_file +1 -1
  37. package/dist/cjs/assets/visual-e2e-locale/messages_visuale2e.json +5 -1
  38. package/dist/cjs/hooks/useImport.js +7 -5
  39. package/dist/cjs/hooks/useImport.js.map +1 -1
  40. package/dist/cjs/hooks/useImportConfig.js.map +1 -1
  41. package/dist/cjs/index.js +5 -2
  42. package/dist/cjs/index.js.map +1 -1
  43. package/dist/cjs/services/DataExtensionFieldOperationsService.js +3 -3
  44. package/dist/cjs/services/DataExtensionFieldOperationsService.js.map +1 -1
  45. package/dist/cjs/services/translations.js.map +1 -1
  46. package/dist/cjs/state/ArchiveFieldModalState.js +5 -8
  47. package/dist/cjs/state/ArchiveFieldModalState.js.map +1 -1
  48. package/dist/cjs/state/CustomFieldModalBiReporter.js +5 -9
  49. package/dist/cjs/state/CustomFieldModalBiReporter.js.map +1 -1
  50. package/dist/cjs/state/CustomFieldModalState.js +32 -71
  51. package/dist/cjs/state/CustomFieldModalState.js.map +1 -1
  52. package/dist/cjs/state/DataExtensionState.js +0 -12
  53. package/dist/cjs/state/DataExtensionState.js.map +1 -1
  54. package/dist/cjs/state/DeleteFieldModalState.js +9 -11
  55. package/dist/cjs/state/DeleteFieldModalState.js.map +1 -1
  56. package/dist/cjs/state/{DataExtensionStateBIReporter.js → FieldOperationsBIReporter.js} +7 -32
  57. package/dist/cjs/state/FieldOperationsBIReporter.js.map +1 -0
  58. package/dist/cjs/state/ImportState/ImportState.js +383 -109
  59. package/dist/cjs/state/ImportState/ImportState.js.map +1 -1
  60. package/dist/cjs/state/ImportState/__tests__/ImportState.engine.spec.js +610 -0
  61. package/dist/cjs/state/ImportState/__tests__/ImportState.engine.spec.js.map +1 -0
  62. package/dist/cjs/state/ImportState/__tests__/hubJobClient.spec.js +209 -0
  63. package/dist/cjs/state/ImportState/__tests__/hubJobClient.spec.js.map +1 -0
  64. package/dist/cjs/state/ImportState/__tests__/importJobPoller.spec.js +86 -0
  65. package/dist/cjs/state/ImportState/__tests__/importJobPoller.spec.js.map +1 -0
  66. package/dist/cjs/state/ImportState/__tests__/parseCsv.spec.js +52 -0
  67. package/dist/cjs/state/ImportState/__tests__/parseCsv.spec.js.map +1 -0
  68. package/dist/cjs/state/ImportState/__tests__/rewriteCsv.spec.js +81 -0
  69. package/dist/cjs/state/ImportState/__tests__/rewriteCsv.spec.js.map +1 -0
  70. package/dist/cjs/state/ImportState/fieldEdit.js +46 -0
  71. package/dist/cjs/state/ImportState/fieldEdit.js.map +1 -0
  72. package/dist/cjs/state/ImportState/hubJobClient.js +101 -0
  73. package/dist/cjs/state/ImportState/hubJobClient.js.map +1 -0
  74. package/dist/cjs/state/ImportState/importJobPoller.js +44 -0
  75. package/dist/cjs/state/ImportState/importJobPoller.js.map +1 -0
  76. package/dist/cjs/state/ImportState/index.js +12 -0
  77. package/dist/cjs/state/ImportState/index.js.map +1 -1
  78. package/dist/cjs/state/ImportState/parseCsv.js +39 -10
  79. package/dist/cjs/state/ImportState/parseCsv.js.map +1 -1
  80. package/dist/cjs/state/ImportState/rewriteCsv.js +46 -0
  81. package/dist/cjs/state/ImportState/rewriteCsv.js.map +1 -0
  82. package/dist/cjs/state/formatPermissionsForBi.js +36 -0
  83. package/dist/cjs/state/formatPermissionsForBi.js.map +1 -0
  84. package/dist/cjs/testkit/WixPatternsContainer.driver.js +4 -1
  85. package/dist/cjs/testkit/WixPatternsContainer.driver.js.map +1 -1
  86. package/dist/cjs/testkit/client.js +6 -0
  87. package/dist/cjs/testkit/client.js.map +1 -1
  88. package/dist/cjs/testkit/hubJobImportMocks.js +166 -0
  89. package/dist/cjs/testkit/hubJobImportMocks.js.map +1 -0
  90. package/dist/cjs/testkit/index.js +6 -0
  91. package/dist/cjs/testkit/index.js.map +1 -1
  92. package/dist/cjs/types/FieldsSource.js +4 -0
  93. package/dist/cjs/types/FieldsSource.js.map +1 -0
  94. package/dist/cjs/types/Schema.js.map +1 -1
  95. package/dist/cjs/types/SchemaSource.js +81 -0
  96. package/dist/cjs/types/SchemaSource.js.map +1 -0
  97. package/dist/esm/assets/locale/messages_ar.json +12 -0
  98. package/dist/esm/assets/locale/messages_bg.json +12 -0
  99. package/dist/esm/assets/locale/messages_ca.json +12 -0
  100. package/dist/esm/assets/locale/messages_cs.json +12 -0
  101. package/dist/esm/assets/locale/messages_da.json +17 -5
  102. package/dist/esm/assets/locale/messages_de.json +12 -0
  103. package/dist/esm/assets/locale/messages_el.json +12 -0
  104. package/dist/esm/assets/locale/messages_en.json +12 -0
  105. package/dist/esm/assets/locale/messages_es.json +16 -4
  106. package/dist/esm/assets/locale/messages_fi.json +12 -0
  107. package/dist/esm/assets/locale/messages_fr.json +12 -0
  108. package/dist/esm/assets/locale/messages_he.json +12 -0
  109. package/dist/esm/assets/locale/messages_hi.json +17 -5
  110. package/dist/esm/assets/locale/messages_hu.json +12 -0
  111. package/dist/esm/assets/locale/messages_id.json +17 -5
  112. package/dist/esm/assets/locale/messages_it.json +17 -5
  113. package/dist/esm/assets/locale/messages_ja.json +12 -0
  114. package/dist/esm/assets/locale/messages_ko.json +17 -5
  115. package/dist/esm/assets/locale/messages_lt.json +12 -0
  116. package/dist/esm/assets/locale/messages_ms.json +12 -0
  117. package/dist/esm/assets/locale/messages_nl.json +16 -4
  118. package/dist/esm/assets/locale/messages_no.json +12 -0
  119. package/dist/esm/assets/locale/messages_pl.json +12 -0
  120. package/dist/esm/assets/locale/messages_pt.json +16 -4
  121. package/dist/esm/assets/locale/messages_ro.json +12 -0
  122. package/dist/esm/assets/locale/messages_ru.json +12 -0
  123. package/dist/esm/assets/locale/messages_sk.json +12 -0
  124. package/dist/esm/assets/locale/messages_sl.json +12 -0
  125. package/dist/esm/assets/locale/messages_sv.json +17 -5
  126. package/dist/esm/assets/locale/messages_th.json +17 -5
  127. package/dist/esm/assets/locale/messages_tl.json +12 -0
  128. package/dist/esm/assets/locale/messages_tr.json +17 -5
  129. package/dist/esm/assets/locale/messages_uk.json +12 -0
  130. package/dist/esm/assets/locale/messages_vi.json +17 -5
  131. package/dist/esm/assets/locale/messages_zh.json +12 -0
  132. package/dist/esm/assets/locale/version_file +1 -1
  133. package/dist/esm/assets/visual-e2e-locale/messages_visuale2e.json +5 -1
  134. package/dist/esm/hooks/useImport.js +5 -4
  135. package/dist/esm/hooks/useImport.js.map +1 -1
  136. package/dist/esm/hooks/useImportConfig.js.map +1 -1
  137. package/dist/esm/index.js +1 -0
  138. package/dist/esm/index.js.map +1 -1
  139. package/dist/esm/services/DataExtensionFieldOperationsService.js +3 -3
  140. package/dist/esm/services/DataExtensionFieldOperationsService.js.map +1 -1
  141. package/dist/esm/state/ArchiveFieldModalState.js +4 -7
  142. package/dist/esm/state/ArchiveFieldModalState.js.map +1 -1
  143. package/dist/esm/state/CustomFieldModalBiReporter.js +5 -8
  144. package/dist/esm/state/CustomFieldModalBiReporter.js.map +1 -1
  145. package/dist/esm/state/CustomFieldModalState.js +28 -52
  146. package/dist/esm/state/CustomFieldModalState.js.map +1 -1
  147. package/dist/esm/state/DataExtensionState.js +0 -10
  148. package/dist/esm/state/DataExtensionState.js.map +1 -1
  149. package/dist/esm/state/DeleteFieldModalState.js +7 -10
  150. package/dist/esm/state/DeleteFieldModalState.js.map +1 -1
  151. package/dist/esm/state/{DataExtensionStateBIReporter.js → FieldOperationsBIReporter.js} +5 -25
  152. package/dist/esm/state/FieldOperationsBIReporter.js.map +1 -0
  153. package/dist/esm/state/ImportState/ImportState.js +314 -101
  154. package/dist/esm/state/ImportState/ImportState.js.map +1 -1
  155. package/dist/esm/state/ImportState/__tests__/ImportState.engine.spec.js +434 -0
  156. package/dist/esm/state/ImportState/__tests__/ImportState.engine.spec.js.map +1 -0
  157. package/dist/esm/state/ImportState/__tests__/hubJobClient.spec.js +139 -0
  158. package/dist/esm/state/ImportState/__tests__/hubJobClient.spec.js.map +1 -0
  159. package/dist/esm/state/ImportState/__tests__/importJobPoller.spec.js +62 -0
  160. package/dist/esm/state/ImportState/__tests__/importJobPoller.spec.js.map +1 -0
  161. package/dist/esm/state/ImportState/__tests__/parseCsv.spec.js +59 -0
  162. package/dist/esm/state/ImportState/__tests__/parseCsv.spec.js.map +1 -0
  163. package/dist/esm/state/ImportState/__tests__/rewriteCsv.spec.js +68 -0
  164. package/dist/esm/state/ImportState/__tests__/rewriteCsv.spec.js.map +1 -0
  165. package/dist/esm/state/ImportState/fieldEdit.js +33 -0
  166. package/dist/esm/state/ImportState/fieldEdit.js.map +1 -0
  167. package/dist/esm/state/ImportState/hubJobClient.js +43 -0
  168. package/dist/esm/state/ImportState/hubJobClient.js.map +1 -0
  169. package/dist/esm/state/ImportState/importJobPoller.js +34 -0
  170. package/dist/esm/state/ImportState/importJobPoller.js.map +1 -0
  171. package/dist/esm/state/ImportState/index.js +2 -0
  172. package/dist/esm/state/ImportState/index.js.map +1 -1
  173. package/dist/esm/state/ImportState/parseCsv.js +34 -10
  174. package/dist/esm/state/ImportState/parseCsv.js.map +1 -1
  175. package/dist/esm/state/ImportState/rewriteCsv.js +39 -0
  176. package/dist/esm/state/ImportState/rewriteCsv.js.map +1 -0
  177. package/dist/esm/state/formatPermissionsForBi.js +26 -0
  178. package/dist/esm/state/formatPermissionsForBi.js.map +1 -0
  179. package/dist/esm/testkit/WixPatternsContainer.driver.js +4 -1
  180. package/dist/esm/testkit/WixPatternsContainer.driver.js.map +1 -1
  181. package/dist/esm/testkit/client.js +1 -0
  182. package/dist/esm/testkit/client.js.map +1 -1
  183. package/dist/esm/testkit/hubJobImportMocks.js +173 -0
  184. package/dist/esm/testkit/hubJobImportMocks.js.map +1 -0
  185. package/dist/esm/testkit/index.js +1 -0
  186. package/dist/esm/testkit/index.js.map +1 -1
  187. package/dist/esm/types/FieldsSource.js +2 -0
  188. package/dist/esm/types/FieldsSource.js.map +1 -0
  189. package/dist/esm/types/SchemaSource.js +52 -0
  190. package/dist/esm/types/SchemaSource.js.map +1 -0
  191. package/dist/types/hooks/useImport.d.ts +5 -3
  192. package/dist/types/hooks/useImport.d.ts.map +1 -1
  193. package/dist/types/hooks/useImportConfig.d.ts +2 -3
  194. package/dist/types/hooks/useImportConfig.d.ts.map +1 -1
  195. package/dist/types/index.d.ts +4 -1
  196. package/dist/types/index.d.ts.map +1 -1
  197. package/dist/types/services/translations.d.ts +1 -1
  198. package/dist/types/services/translations.d.ts.map +1 -1
  199. package/dist/types/state/ArchiveFieldModalState.d.ts +7 -5
  200. package/dist/types/state/ArchiveFieldModalState.d.ts.map +1 -1
  201. package/dist/types/state/CustomFieldModalBiReporter.d.ts +4 -3
  202. package/dist/types/state/CustomFieldModalBiReporter.d.ts.map +1 -1
  203. package/dist/types/state/CustomFieldModalState.d.ts +12 -6
  204. package/dist/types/state/CustomFieldModalState.d.ts.map +1 -1
  205. package/dist/types/state/DataExtensionState.d.ts +0 -2
  206. package/dist/types/state/DataExtensionState.d.ts.map +1 -1
  207. package/dist/types/state/DeleteFieldModalState.d.ts +8 -5
  208. package/dist/types/state/DeleteFieldModalState.d.ts.map +1 -1
  209. package/dist/types/state/{DataExtensionStateBIReporter.d.ts → FieldOperationsBIReporter.d.ts} +4 -5
  210. package/dist/types/state/FieldOperationsBIReporter.d.ts.map +1 -0
  211. package/dist/types/state/ImportState/ImportState.d.ts +120 -20
  212. package/dist/types/state/ImportState/ImportState.d.ts.map +1 -1
  213. package/dist/types/state/ImportState/__tests__/ImportState.engine.spec.d.ts +2 -0
  214. package/dist/types/state/ImportState/__tests__/ImportState.engine.spec.d.ts.map +1 -0
  215. package/dist/types/state/ImportState/__tests__/hubJobClient.spec.d.ts +2 -0
  216. package/dist/types/state/ImportState/__tests__/hubJobClient.spec.d.ts.map +1 -0
  217. package/dist/types/state/ImportState/__tests__/importJobPoller.spec.d.ts +2 -0
  218. package/dist/types/state/ImportState/__tests__/importJobPoller.spec.d.ts.map +1 -0
  219. package/dist/types/state/ImportState/__tests__/parseCsv.spec.d.ts +2 -0
  220. package/dist/types/state/ImportState/__tests__/parseCsv.spec.d.ts.map +1 -0
  221. package/dist/types/state/ImportState/__tests__/rewriteCsv.spec.d.ts +2 -0
  222. package/dist/types/state/ImportState/__tests__/rewriteCsv.spec.d.ts.map +1 -0
  223. package/dist/types/state/ImportState/fieldEdit.d.ts +10 -0
  224. package/dist/types/state/ImportState/fieldEdit.d.ts.map +1 -0
  225. package/dist/types/state/ImportState/hubJobClient.d.ts +47 -0
  226. package/dist/types/state/ImportState/hubJobClient.d.ts.map +1 -0
  227. package/dist/types/state/ImportState/importJobPoller.d.ts +20 -0
  228. package/dist/types/state/ImportState/importJobPoller.d.ts.map +1 -0
  229. package/dist/types/state/ImportState/index.d.ts +2 -0
  230. package/dist/types/state/ImportState/index.d.ts.map +1 -1
  231. package/dist/types/state/ImportState/parseCsv.d.ts +7 -0
  232. package/dist/types/state/ImportState/parseCsv.d.ts.map +1 -1
  233. package/dist/types/state/ImportState/rewriteCsv.d.ts +25 -0
  234. package/dist/types/state/ImportState/rewriteCsv.d.ts.map +1 -0
  235. package/dist/types/state/formatPermissionsForBi.d.ts +7 -0
  236. package/dist/types/state/formatPermissionsForBi.d.ts.map +1 -0
  237. package/dist/types/testkit/WixPatternsContainer.driver.d.ts +22 -0
  238. package/dist/types/testkit/WixPatternsContainer.driver.d.ts.map +1 -1
  239. package/dist/types/testkit/client.d.ts +1 -0
  240. package/dist/types/testkit/client.d.ts.map +1 -1
  241. package/dist/types/testkit/hubJobImportMocks.d.ts +40 -0
  242. package/dist/types/testkit/hubJobImportMocks.d.ts.map +1 -0
  243. package/dist/types/testkit/index.d.ts +1 -0
  244. package/dist/types/testkit/index.d.ts.map +1 -1
  245. package/dist/types/types/FieldsSource.d.ts +116 -0
  246. package/dist/types/types/FieldsSource.d.ts.map +1 -0
  247. package/dist/types/types/Schema.d.ts +28 -11
  248. package/dist/types/types/Schema.d.ts.map +1 -1
  249. package/dist/types/types/SchemaSource.d.ts +60 -0
  250. package/dist/types/types/SchemaSource.d.ts.map +1 -0
  251. package/package.json +4 -4
  252. package/dist/cjs/state/DataExtensionStateBIReporter.js.map +0 -1
  253. package/dist/esm/state/DataExtensionStateBIReporter.js.map +0 -1
  254. package/dist/types/state/DataExtensionStateBIReporter.d.ts.map +0 -1
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.hubJobImportMocks = hubJobImportMocks;
5
+ var _http = require("@wix/bex-utils/@wix/ambassador-hub-v1-job/http");
6
+ var _types = require("@wix/bex-utils/@wix/ambassador-hub-v1-job/types");
7
+ const UPLOAD_BASE = 'https://import-upload.test';
8
+ const UPLOAD_PATH = '/file';
9
+ const FILE_ID = 'file-1';
10
+ const JOB_ID = 'job-1';
11
+ /**
12
+ * Test mocks for the data-hub Hub Job import lifecycle, mirroring
13
+ * `exportServiceMocks`. Auto-included in the test container's httpClient
14
+ * scenarios so every import test drives a fake server. Behavior is controllable
15
+ * per test via `setOutcome` / `setInProgressPolls`, and the uploaded (aligned)
16
+ * CSV + the submitted job request are captured for assertions.
17
+ */
18
+ function hubJobImportMocks(whenRequest, when) {
19
+ const state = {
20
+ outcome: 'completed',
21
+ succeeded: 0,
22
+ failed: 0,
23
+ /** number of IN_PROGRESS polls before the job goes terminal */
24
+ inProgressPolls: 0,
25
+ /** csvRows indices reported as failed via movement logs */
26
+ failedRowIndices: [],
27
+ /** the raw body PUT to the signed upload URL (the aligned CSV File) */
28
+ uploadedBody: undefined,
29
+ /** the SubmitJobRequest payload */
30
+ submittedRequest: undefined,
31
+ submittedJobId: undefined,
32
+ terminatedJobIds: []
33
+ };
34
+ const pollCounts = new Map();
35
+ const terminalStatus = () => state.outcome === 'failed' ? _types.JobStatus.FAILED : state.outcome === 'partial' ? _types.JobStatus.PARTIALLY_SUCCESSFUL : _types.JobStatus.COMPLETED;
36
+ const total = () => state.succeeded + state.failed;
37
+ const terminalJob = id => ({
38
+ id,
39
+ status: terminalStatus(),
40
+ progress: {
41
+ current: total(),
42
+ total: total(),
43
+ itemsSuccessful: state.succeeded,
44
+ itemsRejected: state.failed
45
+ },
46
+ ...(state.outcome === 'failed' && {
47
+ error: {
48
+ code: 'import_failed',
49
+ description: 'Import job failed'
50
+ }
51
+ })
52
+ });
53
+ return {
54
+ state,
55
+ /** Set the job's terminal outcome and its success/failure counts. */
56
+ setOutcome(outcome, counts = {}) {
57
+ state.outcome = outcome;
58
+ state.succeeded = counts.succeeded ?? 0;
59
+ state.failed = counts.failed ?? 0;
60
+ },
61
+ /** Make the job report IN_PROGRESS for `n` polls before going terminal. */
62
+ setInProgressPolls(n) {
63
+ state.inProgressPolls = n;
64
+ },
65
+ /** Row indices `listMovementLogs` reports as failed (sourceItemId). */
66
+ setFailedRowIndices(indices) {
67
+ state.failedRowIndices = indices;
68
+ },
69
+ /** The aligned CSV uploaded to the signed URL, as text. */
70
+ async getUploadedCsv() {
71
+ const body = state.uploadedBody;
72
+ if (body == null) {
73
+ return '';
74
+ }
75
+ if (typeof body === 'string') {
76
+ return body;
77
+ }
78
+ const blob = body;
79
+ // jsdom's File implements neither text() nor arrayBuffer() here, so fall
80
+ // back to FileReader.
81
+ if (typeof blob.text === 'function') {
82
+ return blob.text();
83
+ }
84
+ if (typeof blob.arrayBuffer === 'function') {
85
+ return new TextDecoder().decode(await blob.arrayBuffer());
86
+ }
87
+ return new Promise((resolve, reject) => {
88
+ const reader = new FileReader();
89
+ reader.onload = () => resolve(String(reader.result));
90
+ reader.onerror = () => reject(reader.error);
91
+ reader.readAsText(blob);
92
+ });
93
+ },
94
+ reset() {
95
+ state.outcome = 'completed';
96
+ state.succeeded = 0;
97
+ state.failed = 0;
98
+ state.inProgressPolls = 0;
99
+ state.failedRowIndices = [];
100
+ state.uploadedBody = undefined;
101
+ state.submittedRequest = undefined;
102
+ state.submittedJobId = undefined;
103
+ state.terminatedJobIds = [];
104
+ pollCounts.clear();
105
+ },
106
+ mocks: [whenRequest(_http.createFileUploadUrl).reply(200, {
107
+ uploadUrl: `${UPLOAD_BASE}${UPLOAD_PATH}`,
108
+ fileId: FILE_ID
109
+ }).persist(), when(UPLOAD_BASE).put(UPLOAD_PATH).reply(200, data => {
110
+ state.uploadedBody = data;
111
+ return {};
112
+ }).persist(), whenRequest(_http.submitJob).reply(200, payload => {
113
+ state.submittedRequest = payload;
114
+ state.submittedJobId = JOB_ID;
115
+ pollCounts.set(JOB_ID, 0);
116
+ return {
117
+ job: {
118
+ id: JOB_ID,
119
+ status: _types.JobStatus.INITIALIZING,
120
+ progress: {
121
+ current: 0,
122
+ total: total()
123
+ }
124
+ }
125
+ };
126
+ }).persist(), whenRequest(_http.getJob).reply(200, payload => {
127
+ const seen = pollCounts.get(payload.jobId) ?? 0;
128
+ pollCounts.set(payload.jobId, seen + 1);
129
+ if (seen < state.inProgressPolls) {
130
+ // No `total` here so ImportState keeps its initial CSV-row total;
131
+ // `current` is 0-based so the first poll reports nothing processed.
132
+ return {
133
+ job: {
134
+ id: payload.jobId,
135
+ status: _types.JobStatus.IN_PROGRESS,
136
+ progress: {
137
+ current: seen,
138
+ itemsSuccessful: seen,
139
+ itemsRejected: 0
140
+ }
141
+ }
142
+ };
143
+ }
144
+ return {
145
+ job: terminalJob(payload.jobId)
146
+ };
147
+ }).persist(), whenRequest(_http.terminateJob).reply(200, payload => {
148
+ state.terminatedJobIds.push(payload.jobId);
149
+ return {};
150
+ }).persist(), whenRequest(_http.listMovementLogs).reply(200, () => ({
151
+ // data-hub formats a CSV item's sourceItemId as "row N", where N is
152
+ // the 1-based file line (header is line 1) — so csvRows[i] is "row i+2".
153
+ logs: state.failedRowIndices.map(index => ({
154
+ sourceItemId: `row ${index + 2}`,
155
+ failure: {
156
+ code: 'row_failed',
157
+ description: 'Invalid row'
158
+ }
159
+ })),
160
+ pagingMetadata: {
161
+ hasNext: false
162
+ }
163
+ })).persist()]
164
+ };
165
+ }
166
+ //# sourceMappingURL=hubJobImportMocks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_http","require","_types","UPLOAD_BASE","UPLOAD_PATH","FILE_ID","JOB_ID","hubJobImportMocks","whenRequest","when","state","outcome","succeeded","failed","inProgressPolls","failedRowIndices","uploadedBody","undefined","submittedRequest","submittedJobId","terminatedJobIds","pollCounts","Map","terminalStatus","JobStatus","FAILED","PARTIALLY_SUCCESSFUL","COMPLETED","total","terminalJob","id","status","progress","current","itemsSuccessful","itemsRejected","error","code","description","setOutcome","counts","setInProgressPolls","n","setFailedRowIndices","indices","getUploadedCsv","body","blob","text","arrayBuffer","TextDecoder","decode","Promise","resolve","reject","reader","FileReader","onload","String","result","onerror","readAsText","reset","clear","mocks","createFileUploadUrl","reply","uploadUrl","fileId","persist","put","data","submitJob","payload","set","job","INITIALIZING","getJob","seen","get","jobId","IN_PROGRESS","terminateJob","push","listMovementLogs","logs","map","index","sourceItemId","failure","pagingMetadata","hasNext"],"sources":["../../../src/testkit/hubJobImportMocks.ts"],"sourcesContent":["import {\n createFileUploadUrl,\n submitJob,\n getJob,\n terminateJob,\n listMovementLogs,\n} from '@wix/bex-utils/@wix/ambassador-hub-v1-job/http';\nimport {\n JobStatus,\n type DataMovementJob,\n type SubmitJobRequest,\n} from '@wix/bex-utils/@wix/ambassador-hub-v1-job/types';\n\nconst UPLOAD_BASE = 'https://import-upload.test';\nconst UPLOAD_PATH = '/file';\nconst FILE_ID = 'file-1';\nconst JOB_ID = 'job-1';\n\nexport type ImportJobOutcome = 'completed' | 'partial' | 'failed';\n\n/**\n * Test mocks for the data-hub Hub Job import lifecycle, mirroring\n * `exportServiceMocks`. Auto-included in the test container's httpClient\n * scenarios so every import test drives a fake server. Behavior is controllable\n * per test via `setOutcome` / `setInProgressPolls`, and the uploaded (aligned)\n * CSV + the submitted job request are captured for assertions.\n */\nexport function hubJobImportMocks(\n whenRequest: typeof import('@wix/http-client-testkit/client').whenRequest,\n when: typeof import('@wix/http-client-testkit/client').when,\n) {\n const state = {\n outcome: 'completed' as ImportJobOutcome,\n succeeded: 0,\n failed: 0,\n /** number of IN_PROGRESS polls before the job goes terminal */\n inProgressPolls: 0,\n /** csvRows indices reported as failed via movement logs */\n failedRowIndices: [] as number[],\n /** the raw body PUT to the signed upload URL (the aligned CSV File) */\n uploadedBody: undefined as unknown,\n /** the SubmitJobRequest payload */\n submittedRequest: undefined as SubmitJobRequest | undefined,\n submittedJobId: undefined as string | undefined,\n terminatedJobIds: [] as string[],\n };\n\n const pollCounts = new Map<string, number>();\n\n const terminalStatus = (): JobStatus =>\n state.outcome === 'failed'\n ? JobStatus.FAILED\n : state.outcome === 'partial'\n ? JobStatus.PARTIALLY_SUCCESSFUL\n : JobStatus.COMPLETED;\n\n const total = () => state.succeeded + state.failed;\n\n const terminalJob = (id: string): DataMovementJob => ({\n id,\n status: terminalStatus(),\n progress: {\n current: total(),\n total: total(),\n itemsSuccessful: state.succeeded,\n itemsRejected: state.failed,\n },\n ...(state.outcome === 'failed' && {\n error: { code: 'import_failed', description: 'Import job failed' },\n }),\n });\n\n return {\n state,\n\n /** Set the job's terminal outcome and its success/failure counts. */\n setOutcome(\n outcome: ImportJobOutcome,\n counts: { succeeded?: number; failed?: number } = {},\n ) {\n state.outcome = outcome;\n state.succeeded = counts.succeeded ?? 0;\n state.failed = counts.failed ?? 0;\n },\n\n /** Make the job report IN_PROGRESS for `n` polls before going terminal. */\n setInProgressPolls(n: number) {\n state.inProgressPolls = n;\n },\n\n /** Row indices `listMovementLogs` reports as failed (sourceItemId). */\n setFailedRowIndices(indices: number[]) {\n state.failedRowIndices = indices;\n },\n\n /** The aligned CSV uploaded to the signed URL, as text. */\n async getUploadedCsv(): Promise<string> {\n const body = state.uploadedBody;\n if (body == null) {\n return '';\n }\n if (typeof body === 'string') {\n return body;\n }\n const blob = body as Blob;\n // jsdom's File implements neither text() nor arrayBuffer() here, so fall\n // back to FileReader.\n if (typeof blob.text === 'function') {\n return blob.text();\n }\n if (typeof blob.arrayBuffer === 'function') {\n return new TextDecoder().decode(await blob.arrayBuffer());\n }\n return new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onload = () => resolve(String(reader.result));\n reader.onerror = () => reject(reader.error);\n reader.readAsText(blob);\n });\n },\n\n reset() {\n state.outcome = 'completed';\n state.succeeded = 0;\n state.failed = 0;\n state.inProgressPolls = 0;\n state.failedRowIndices = [];\n state.uploadedBody = undefined;\n state.submittedRequest = undefined;\n state.submittedJobId = undefined;\n state.terminatedJobIds = [];\n pollCounts.clear();\n },\n\n mocks: [\n whenRequest(createFileUploadUrl)\n .reply(200, {\n uploadUrl: `${UPLOAD_BASE}${UPLOAD_PATH}`,\n fileId: FILE_ID,\n })\n .persist(),\n\n when(UPLOAD_BASE)\n .put(UPLOAD_PATH)\n .reply(200, (data: unknown) => {\n state.uploadedBody = data;\n return {};\n })\n .persist(),\n\n whenRequest(submitJob)\n .reply(200, (payload: SubmitJobRequest) => {\n state.submittedRequest = payload;\n state.submittedJobId = JOB_ID;\n pollCounts.set(JOB_ID, 0);\n return {\n job: {\n id: JOB_ID,\n status: JobStatus.INITIALIZING,\n progress: { current: 0, total: total() },\n },\n };\n })\n .persist(),\n\n whenRequest(getJob)\n .reply(200, (payload: { jobId: string }) => {\n const seen = pollCounts.get(payload.jobId) ?? 0;\n pollCounts.set(payload.jobId, seen + 1);\n\n if (seen < state.inProgressPolls) {\n // No `total` here so ImportState keeps its initial CSV-row total;\n // `current` is 0-based so the first poll reports nothing processed.\n return {\n job: {\n id: payload.jobId,\n status: JobStatus.IN_PROGRESS,\n progress: {\n current: seen,\n itemsSuccessful: seen,\n itemsRejected: 0,\n },\n },\n };\n }\n\n return { job: terminalJob(payload.jobId) };\n })\n .persist(),\n\n whenRequest(terminateJob)\n .reply(200, (payload: { jobId: string }) => {\n state.terminatedJobIds.push(payload.jobId);\n return {};\n })\n .persist(),\n\n whenRequest(listMovementLogs)\n .reply(200, () => ({\n // data-hub formats a CSV item's sourceItemId as \"row N\", where N is\n // the 1-based file line (header is line 1) — so csvRows[i] is \"row i+2\".\n logs: state.failedRowIndices.map((index) => ({\n sourceItemId: `row ${index + 2}`,\n failure: { code: 'row_failed', description: 'Invalid row' },\n })),\n pagingMetadata: { hasNext: false },\n }))\n .persist(),\n ] as import('@wix/http-client-testkit').AnyScenario[],\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -25,6 +25,12 @@ Object.keys(_exportServiceMocks).forEach(function (key) {
25
25
  if (key in exports && exports[key] === _exportServiceMocks[key]) return;
26
26
  exports[key] = _exportServiceMocks[key];
27
27
  });
28
+ var _hubJobImportMocks = require("./hubJobImportMocks");
29
+ Object.keys(_hubJobImportMocks).forEach(function (key) {
30
+ if (key === "default" || key === "__esModule") return;
31
+ if (key in exports && exports[key] === _hubJobImportMocks[key]) return;
32
+ exports[key] = _hubJobImportMocks[key];
33
+ });
28
34
  var _flush = require("../test-utils/flush");
29
35
  Object.keys(_flush).forEach(function (key) {
30
36
  if (key === "default" || key === "__esModule") return;
@@ -1 +1 @@
1
- {"version":3,"names":["_product","require","Object","keys","forEach","key","exports","_productFilters","_createProductsBackend","_exportServiceMocks","_flush","_folder","_createFoldersBackend","_country","_createCountriesBackend","_appSettingsMocks"],"sources":["../../../src/testkit/index.ts"],"sourcesContent":["export * from './product';\nexport * from './productFilters';\nexport * from './createProductsBackend';\nexport * from './exportServiceMocks';\nexport * from '../test-utils/flush';\nexport * from './folder';\nexport * from './createFoldersBackend';\nexport * from './country';\nexport * from './createCountriesBackend';\nexport * from './appSettingsMocks';\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_product","require","Object","keys","forEach","key","exports","_productFilters","_createProductsBackend","_exportServiceMocks","_hubJobImportMocks","_flush","_folder","_createFoldersBackend","_country","_createCountriesBackend","_appSettingsMocks"],"sources":["../../../src/testkit/index.ts"],"sourcesContent":["export * from './product';\nexport * from './productFilters';\nexport * from './createProductsBackend';\nexport * from './exportServiceMocks';\nexport * from './hubJobImportMocks';\nexport * from '../test-utils/flush';\nexport * from './folder';\nexport * from './createFoldersBackend';\nexport * from './country';\nexport * from './createCountriesBackend';\nexport * from './appSettingsMocks';\n"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ //# sourceMappingURL=FieldsSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":[],"sources":["../../../src/types/FieldsSource.ts"],"sourcesContent":["import type { Field, PatternsFieldType } from './Field';\nimport type { FieldActions } from './Schema';\n\n/** A field the source has archived. Sources without archiving omit `archive`. */\nexport interface ArchivedFieldItem {\n id: string;\n label: string;\n isPii?: boolean;\n}\n\n/** A field type a source allows creating, with display metadata for the modal. */\nexport interface FieldTypeOption {\n /** Stored on the draft; the source maps it back to its native type. */\n id: string;\n label: string;\n namePlaceholder?: string;\n /** Drives the type icon in the modal. */\n patternsType: PatternsFieldType;\n}\n\n/** Read/write permission defaults a source supports, per audience. */\nexport interface FieldPermissions {\n installedApps?: {\n hide?: boolean;\n defaultRead?: boolean;\n defaultWrite?: boolean;\n };\n siteVisitors?: {\n hide?: boolean;\n defaultRead?: boolean;\n defaultWrite?: boolean;\n };\n}\n\n/** The values the add/edit field modal collects, source-neutral. */\nexport interface FieldDraft {\n type?: string;\n key: string;\n name: string;\n readApps: boolean;\n readUsers: boolean;\n writeApps: boolean;\n writeUsers: boolean;\n containsPii: boolean;\n}\n\n/** Add/edit/delete capability a source exposes. Present ⇒ field management UI shows. */\nexport interface FieldManagement {\n /** False ⇒ the add-field CTA is hidden entirely. */\n canAddFields: boolean;\n /** True ⇒ the add-field CTA renders but is disabled. */\n addFieldDisabled: boolean;\n /** Hint text shown beneath the add-field CTA while it is disabled. */\n addFieldDisabledHint?: string;\n canEditField(field: Field): boolean;\n /** `origin` is the UI surface the delete was triggered from; used for BI. */\n deleteField(fieldId: string, origin: string): Promise<void>;\n\n /** Field types the source allows creating, shown in the add/edit modal. */\n creatableFieldTypes: FieldTypeOption[];\n /** Existing field keys, used by the add modal to reject duplicates. */\n existingFieldKeys: string[];\n /** True when no more fields can be added because a limit is reached. */\n maxReached?: boolean;\n /** Permission defaults; absent ⇒ the modal hides the permissions section. */\n permissions?: FieldPermissions;\n /** True when the source supports marking a field as PII. */\n supportsPii?: boolean;\n addField(draft: FieldDraft): Promise<void>;\n editField(fieldId: string, draft: FieldDraft): Promise<void>;\n /** Current values for an existing field, to prefill the edit modal. */\n getFieldDraft(fieldId: string): FieldDraft | undefined;\n}\n\n/** Archiving capability a source exposes. Present ⇒ archive/restore UI shows. */\nexport interface FieldArchive {\n items: ArchivedFieldItem[];\n shouldDisplay: boolean;\n /** Whether the archived-items panel is currently open. */\n isOpen: boolean;\n openPanel(): void;\n closePanel(): void;\n /** `origin` is the UI surface the action was triggered from; used for BI. */\n archiveField(fieldId: string, origin: string): Promise<void>;\n restoreField(fieldId: string, origin: string): Promise<void>;\n /** Display name for a field, for the confirm-dialog copy. */\n fieldName(fieldId: string): string;\n}\n\n/**\n * The source-neutral fields data a collection reads, implemented by each source\n * adapter. Rendering — field modals, filter elements — is not here; it lives in\n * the collection-page layer.\n */\nexport interface FieldsSource {\n /** Loads the fields (schema/data). The collection runs this once, tracks its\n * status, and shows a retry toast on failure. */\n load(): Promise<void>;\n\n fields: Field[];\n filterableFields: Field[];\n /** The fields the manage-fields panel lists — the source's editable fields. */\n manageableFields: Field[];\n /** Column id for a field. Sources that group fields prefix the group; flat sources use the field key. */\n columnIdForField(field: Field): string;\n /** WQL field path for a filter. Sources that group fields prefix the group; flat sources use the field key. */\n queryFieldId(field: Field): string;\n /** The value to display for a field on a row. */\n getCellValue(row: unknown, field: Field): unknown;\n /** Writes a new value for a field on a row, returning the updated row. Present when cells can be edited in place. */\n setCellValue?(row: unknown, field: Field, value: unknown): unknown;\n\n /** Present when fields can be added/edited/deleted. */\n fieldManagement?: FieldManagement;\n\n /** The collection's field-mutation actions (delete/makePrimary/duplicate/…),\n * driving the shared FieldActions menu. Absent ⇒ no per-field action menu. */\n fieldActions?: FieldActions;\n\n /** Present when the source supports archiving fields. */\n archive?: FieldArchive;\n\n /** Present when fields are grouped. Absent ⇒ flat list. */\n groups?: {\n all: string[];\n fieldsForGroup(group: string): Field[];\n };\n}\n"],"mappings":"","ignoreList":[]}
@@ -1 +1 @@
1
- {"version":3,"names":[],"sources":["../../../src/types/Schema.ts"],"sourcesContent":["import type { Field } from './Field';\nimport type { FiltersMap, OptionalFiltersMap } from '../model';\nimport type {\n OffsetFetchDataFn,\n CursorFetchDataFn,\n FetchTotalFn,\n} from '../hooks/paginationModeConfig';\n\n/** Field-management permissions. Absent when the schema's fields cannot be edited. */\nexport interface SchemaPermissions {\n createField: boolean;\n updateField: boolean;\n deleteField: boolean;\n}\n\n/** Item-level CRUD permissions. */\nexport interface ItemPermissions {\n createItem: boolean;\n updateItem: boolean;\n deleteItem: boolean;\n}\n\n/**\n * A source-neutral description of a collection — data only, no behavior.\n * Item access is in `CollectionBackend`, field mutations in `FieldActions`.\n */\nexport interface Schema {\n id: string;\n fields: Record<string, Field | undefined>;\n /** The field that best represents the entity (titles/selections). */\n displayField: string;\n /** The identifier field (e.g. '_id'). */\n idField: string;\n /** Absent when the schema's fields cannot be edited. */\n schemaPermissions?: SchemaPermissions;\n itemPermissions?: ItemPermissions;\n}\n\nexport interface BackupConfig {\n create: () => Promise<{ backupId: string }>;\n waitForCompletion: (\n backupId: string,\n options?: { signal?: AbortSignal },\n ) => Promise<void>;\n cancel?: (backupId: string) => Promise<void>;\n restore?: (backupId: string) => Promise<{ restorationId: string }>;\n waitForRestoration?: (\n restorationId: string,\n options?: { signal?: AbortSignal },\n ) => Promise<void>;\n}\n\nexport interface BulkInsertError {\n rowIndex: number;\n message?: string;\n code?: string;\n}\n\nexport interface BulkInsertResult {\n succeeded?: number;\n failed?: number;\n errors?: BulkInsertError[];\n}\n\n/** Item data access shared by both pagination modes. */\nexport interface CollectionBackendBase<T = Record<string, unknown>> {\n get: (entityId: string) => Promise<T>;\n create: (entity: Partial<T>) => Promise<T>;\n update: (entity: T) => Promise<T>;\n delete: (entityId: string) => Promise<void>;\n bulkDelete: (entityIds: string[]) => Promise<void>;\n move?: (\n id: string,\n params: { moveAfterId: string | null | undefined },\n ) => Promise<void>;\n backup?: BackupConfig;\n bulkInsert?: (entities: Partial<T>[]) => Promise<BulkInsertResult>;\n}\n\n/**\n * A source's item data access. The source declares its `paginationMode`\n * (offset by default) together with the matching `find`, same as core's\n * `PaginationModeConfig`.\n */\nexport type CollectionBackend<\n T = Record<string, unknown>,\n F extends FiltersMap = OptionalFiltersMap,\n> = CollectionBackendBase<T> &\n (\n | { paginationMode?: 'offset'; find: OffsetFetchDataFn<T, F> }\n | {\n paginationMode: 'cursor';\n find: CursorFetchDataFn<T, F>;\n fetchTotal?: FetchTotalFn;\n }\n );\n\n/** Field-management actions. All optional — a read-only source provides none. */\nexport interface FieldActions {\n addField?: (field: Field) => Promise<void>;\n editField?: (fieldId: string, updates: Partial<Field>) => Promise<void>;\n deleteField?: (fieldId: string) => Promise<void>;\n renameField?: (fieldId: string, newName: string) => Promise<void>;\n makePrimary?: (fieldId: string) => Promise<void>;\n duplicateField?: (fieldId: string) => Promise<void>;\n duplicateFieldWithContent?: (fieldId: string) => Promise<void>;\n}\n\n/** Everything a source provides for a collection. */\nexport interface LoadedSchema<T = Record<string, unknown>> {\n schema: Schema;\n backend: CollectionBackend<T>;\n fieldActions?: FieldActions;\n}\n\n/**\n * Loads a collection's `LoadedSchema`. Sources that need dependencies expose a\n * factory that returns this type (e.g. `createCmsSchemaLoader(deps)`).\n */\nexport type SchemaLoader<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = (collectionId: string) => Promise<LoadedSchema<T>>;\n"],"mappings":"","ignoreList":[]}
1
+ {"version":3,"names":[],"sources":["../../../src/types/Schema.ts"],"sourcesContent":["import type { Field } from './Field';\nimport type { FiltersMap, OptionalFiltersMap } from '../model';\nimport type {\n OffsetQuery,\n OffsetQueryResult,\n CursorQuery,\n CursorQueryResult,\n FetchTotalFn,\n} from '../hooks/paginationModeConfig';\n\n/** Field-management permissions. Absent when the schema's fields cannot be edited. */\nexport interface SchemaPermissions {\n createField: boolean;\n updateField: boolean;\n deleteField: boolean;\n}\n\n/** Item-level CRUD permissions. */\nexport interface ItemPermissions {\n createItem: boolean;\n updateItem: boolean;\n deleteItem: boolean;\n}\n\n/**\n * A source-neutral description of a collection — data only, no behavior.\n * Item access is in `CollectionBackend`, field mutations in `FieldActions`.\n */\nexport interface Schema {\n id: string;\n fields: Record<string, Field | undefined>;\n /** The field that best represents the entity (titles/selections). */\n displayField: string;\n /** The identifier field. */\n idField: string;\n /** Absent when the schema's fields cannot be edited. */\n schemaPermissions?: SchemaPermissions;\n itemPermissions?: ItemPermissions;\n}\n\nexport interface BackupConfig {\n create: () => Promise<{ backupId: string }>;\n waitForCompletion: (\n backupId: string,\n options?: { signal?: AbortSignal },\n ) => Promise<void>;\n cancel?: (backupId: string) => Promise<void>;\n restore?: (backupId: string) => Promise<{ restorationId: string }>;\n waitForRestoration?: (\n restorationId: string,\n options?: { signal?: AbortSignal },\n ) => Promise<void>;\n}\n\nexport interface BulkInsertError {\n rowIndex: number;\n message?: string;\n code?: string;\n}\n\nexport interface BulkInsertResult {\n succeeded?: number;\n failed?: number;\n errors?: BulkInsertError[];\n}\n\n/** Item data access shared by both pagination modes. */\nexport interface CollectionBackendBase<T = Record<string, unknown>> {\n get: (entityId: string) => Promise<T>;\n create: (entity: Partial<T>) => Promise<T>;\n update: (entity: T) => Promise<T>;\n delete: (entityId: string) => Promise<void>;\n bulkDelete: (entityIds: string[]) => Promise<void>;\n move?: (\n id: string,\n params: { moveAfterId: string | null | undefined },\n ) => Promise<void>;\n backup?: BackupConfig;\n bulkInsert?: (entities: Partial<T>[]) => Promise<BulkInsertResult>;\n}\n\n/** Per-call search scope the query layer passes to a backend's `find`. */\nexport interface FindOptions {\n searchableFieldIds?: string[];\n}\n\n/**\n * The query-layer fetch-data fns plus the optional `find` options the runtime\n * already accepts. Kept separate so the shared `OffsetFetchDataFn`/\n * `CursorFetchDataFn` used by `fetchData` stay unchanged.\n */\ntype OffsetFindFn<T, F extends FiltersMap> = (\n query: OffsetQuery<F>,\n options?: FindOptions,\n) => Promise<OffsetQueryResult<T>>;\ntype CursorFindFn<T, F extends FiltersMap> = (\n query: CursorQuery<F>,\n options?: FindOptions,\n) => Promise<CursorQueryResult<T>>;\n\n/**\n * A source's item data access. The source declares its `paginationMode`\n * (offset by default) together with the matching `find`, same as core's\n * `PaginationModeConfig`.\n */\nexport type CollectionBackend<\n T = Record<string, unknown>,\n F extends FiltersMap = OptionalFiltersMap,\n> = CollectionBackendBase<T> &\n (\n | { paginationMode?: 'offset'; find: OffsetFindFn<T, F> }\n | {\n paginationMode: 'cursor';\n find: CursorFindFn<T, F>;\n fetchTotal?: FetchTotalFn;\n }\n );\n\n/** Field-management actions. All optional — a read-only source provides none. */\nexport interface FieldActions {\n /**\n * Field-mutating actions return the collection's updated fields map so the\n * caller can merge its local state from the response, without reloading the\n * schema. (`renameField` is the exception — nothing consumes its result yet.)\n */\n addField?: (field: Field) => Promise<Schema['fields']>;\n editField?: (\n fieldId: string,\n updates: Partial<Field>,\n ) => Promise<Schema['fields']>;\n deleteField?: (fieldId: string) => Promise<Schema['fields']>;\n renameField?: (fieldId: string, newName: string) => Promise<void>;\n makePrimary?: (fieldId: string) => Promise<Schema['fields']>;\n duplicateField?: (fieldId: string) => Promise<Schema['fields']>;\n duplicateFieldWithContent?: (fieldId: string) => Promise<Schema['fields']>;\n}\n\n/** Everything a source provides for a collection. */\nexport interface LoadedSchema<T = Record<string, unknown>> {\n schema: Schema;\n backend: CollectionBackend<T>;\n fieldActions?: FieldActions;\n}\n\n/**\n * Loads a collection's `LoadedSchema`. Sources that need dependencies expose a\n * factory that returns this type.\n */\nexport type SchemaLoader<\n T extends Record<string, unknown> = Record<string, unknown>,\n> = (collectionId: string) => Promise<LoadedSchema<T>>;\n"],"mappings":"","ignoreList":[]}
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.defineSchemaSource = defineSchemaSource;
5
+ /** A field type a source allows creating. The label keys are resolved to text by the UI. */
6
+
7
+ /** Collection-query config derived from a source, ready to spread into a collection hook. */
8
+
9
+ /** What a caller passes. Only `collectionId` and `loadSchema` are required. */
10
+
11
+ /** The resolved source: defaults filled, `loadSchema` memoized. */
12
+
13
+ /** Fills source-neutral defaults over `input` and memoizes the load so the collection
14
+ * query and the table columns share a single fetch. */
15
+ function defineSchemaSource(input) {
16
+ const {
17
+ collectionId,
18
+ paginationMode = 'offset',
19
+ creatableFieldTypes = [],
20
+ fieldPermissions,
21
+ supportsPii = false
22
+ } = input;
23
+ let loaded;
24
+ let schema;
25
+ const loadSchema = () => loaded ?? (loaded = input.loadSchema().then(result => {
26
+ schema = result.schema;
27
+ return result;
28
+ }).catch(error => {
29
+ loaded = undefined;
30
+ throw error;
31
+ }));
32
+ const searchableFieldIds = input.searchableFieldIds ?? (s => [s.displayField]);
33
+ const itemKey = input.itemKey ?? (item => {
34
+ var _schema;
35
+ return String(item[((_schema = schema) == null ? void 0 : _schema.idField) ?? '_id'] ?? '');
36
+ });
37
+ const itemName = input.itemName ?? (item => {
38
+ var _schema2;
39
+ return String(item[((_schema2 = schema) == null ? void 0 : _schema2.displayField) ?? '_id'] ?? '');
40
+ });
41
+ const canAddFields = input.canAddFields ?? (s => {
42
+ var _s$schemaPermissions;
43
+ return ((_s$schemaPermissions = s.schemaPermissions) == null ? void 0 : _s$schemaPermissions.createField) ?? false;
44
+ });
45
+ const canEditField = input.canEditField ?? ((field, s) => {
46
+ var _s$schemaPermissions2;
47
+ return (((_s$schemaPermissions2 = s.schemaPermissions) == null ? void 0 : _s$schemaPermissions2.updateField) ?? false) && !field.isSystem;
48
+ });
49
+ const canDeleteField = input.canDeleteField ?? ((field, s) => {
50
+ var _s$schemaPermissions3;
51
+ return (((_s$schemaPermissions3 = s.schemaPermissions) == null ? void 0 : _s$schemaPermissions3.deleteField) ?? false) && !field.isSystem;
52
+ });
53
+ const fetchData = async query => {
54
+ const {
55
+ backend,
56
+ schema: loadedSchema
57
+ } = await loadSchema();
58
+ return backend.find(query, {
59
+ searchableFieldIds: searchableFieldIds(loadedSchema)
60
+ });
61
+ };
62
+ return {
63
+ collectionId,
64
+ loadSchema,
65
+ collectionConfig: {
66
+ queryName: collectionId,
67
+ paginationMode,
68
+ fetchData,
69
+ itemKey,
70
+ itemName
71
+ },
72
+ creatableFieldTypes,
73
+ searchableFieldIds,
74
+ canAddFields,
75
+ canEditField,
76
+ canDeleteField,
77
+ fieldPermissions,
78
+ supportsPii
79
+ };
80
+ }
81
+ //# sourceMappingURL=SchemaSource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["defineSchemaSource","input","collectionId","paginationMode","creatableFieldTypes","fieldPermissions","supportsPii","loaded","schema","loadSchema","then","result","catch","error","undefined","searchableFieldIds","s","displayField","itemKey","item","_schema","String","idField","itemName","_schema2","canAddFields","_s$schemaPermissions","schemaPermissions","createField","canEditField","field","_s$schemaPermissions2","updateField","isSystem","canDeleteField","_s$schemaPermissions3","deleteField","fetchData","query","backend","loadedSchema","find","collectionConfig","queryName"],"sources":["../../../src/types/SchemaSource.ts"],"sourcesContent":["import type { Field, PatternsFieldType } from './Field';\nimport type { Schema, LoadedSchema, FindOptions } from './Schema';\nimport type { FieldPermissions } from './FieldsSource';\nimport type {\n OffsetQuery,\n OffsetQueryResult,\n} from '../hooks/paginationModeConfig';\nimport type { TranslationsKeys } from '../services/translations';\n\n/** A field type a source allows creating. The label keys are resolved to text by the UI. */\nexport interface CreatableFieldType {\n patternsType: PatternsFieldType;\n labelKey: TranslationsKeys;\n namePlaceholderKey?: TranslationsKeys;\n}\n\n/** Collection-query config derived from a source, ready to spread into a collection hook. */\nexport interface SchemaCollectionConfig<T> {\n queryName: string;\n paginationMode: 'offset';\n fetchData: (query: OffsetQuery) => Promise<OffsetQueryResult<T>>;\n itemKey: (item: T) => string;\n itemName: (item: T) => string;\n}\n\n/** What a caller passes. Only `collectionId` and `loadSchema` are required. */\nexport interface SchemaSourceInput<T> {\n collectionId: string;\n loadSchema: () => Promise<LoadedSchema<T>>;\n paginationMode?: 'offset';\n /** Stable row identity. Default: `row[idField]`. */\n itemKey?: (item: T) => string;\n /** Row display label. Default: `row[displayField]`. */\n itemName?: (item: T) => string;\n /** Fields free-text search runs against. Default: `[displayField]`. */\n searchableFieldIds?: (schema: Schema) => string[];\n /** Field types the add-field modal offers. Default: none. */\n creatableFieldTypes?: CreatableFieldType[];\n /** Default: `schemaPermissions.createField`. */\n canAddFields?: (schema: Schema) => boolean;\n /** Default: `schemaPermissions.updateField && !field.isSystem`. */\n canEditField?: (field: Field, schema: Schema) => boolean;\n /** Default: `schemaPermissions.deleteField && !field.isSystem`. */\n canDeleteField?: (field: Field, schema: Schema) => boolean;\n /** Permission defaults shown in the modal. Absent ⇒ no permissions section. */\n fieldPermissions?: FieldPermissions;\n /** Default: `false`. */\n supportsPii?: boolean;\n}\n\n/** The resolved source: defaults filled, `loadSchema` memoized. */\nexport interface SchemaSource<T> {\n readonly collectionId: string;\n loadSchema: () => Promise<LoadedSchema<T>>;\n readonly collectionConfig: SchemaCollectionConfig<T>;\n readonly creatableFieldTypes: CreatableFieldType[];\n searchableFieldIds: (schema: Schema) => string[];\n canAddFields: (schema: Schema) => boolean;\n canEditField: (field: Field, schema: Schema) => boolean;\n canDeleteField: (field: Field, schema: Schema) => boolean;\n readonly fieldPermissions?: FieldPermissions;\n readonly supportsPii: boolean;\n}\n\ntype OffsetFind<T> = (\n query: OffsetQuery,\n options?: FindOptions,\n) => Promise<OffsetQueryResult<T>>;\n\n/** Fills source-neutral defaults over `input` and memoizes the load so the collection\n * query and the table columns share a single fetch. */\nexport function defineSchemaSource<T>(\n input: SchemaSourceInput<T>,\n): SchemaSource<T> {\n const {\n collectionId,\n paginationMode = 'offset',\n creatableFieldTypes = [],\n fieldPermissions,\n supportsPii = false,\n } = input;\n\n let loaded: Promise<LoadedSchema<T>> | undefined;\n let schema: Schema | undefined;\n\n const loadSchema = () =>\n (loaded ??= input\n .loadSchema()\n .then((result) => {\n schema = result.schema;\n return result;\n })\n .catch((error) => {\n loaded = undefined;\n throw error;\n }));\n\n const searchableFieldIds =\n input.searchableFieldIds ?? ((s) => [s.displayField]);\n\n const itemKey =\n input.itemKey ??\n ((item) =>\n String(\n (item as Record<string, unknown>)[schema?.idField ?? '_id'] ?? '',\n ));\n const itemName =\n input.itemName ??\n ((item) =>\n String(\n (item as Record<string, unknown>)[schema?.displayField ?? '_id'] ?? '',\n ));\n const canAddFields =\n input.canAddFields ?? ((s) => s.schemaPermissions?.createField ?? false);\n const canEditField =\n input.canEditField ??\n ((field, s) =>\n (s.schemaPermissions?.updateField ?? false) && !field.isSystem);\n const canDeleteField =\n input.canDeleteField ??\n ((field, s) =>\n (s.schemaPermissions?.deleteField ?? false) && !field.isSystem);\n\n const fetchData = async (\n query: OffsetQuery,\n ): Promise<OffsetQueryResult<T>> => {\n const { backend, schema: loadedSchema } = await loadSchema();\n return (backend.find as OffsetFind<T>)(query, {\n searchableFieldIds: searchableFieldIds(loadedSchema),\n });\n };\n\n return {\n collectionId,\n loadSchema,\n collectionConfig: {\n queryName: collectionId,\n paginationMode,\n fetchData,\n itemKey,\n itemName,\n },\n creatableFieldTypes,\n searchableFieldIds,\n canAddFields,\n canEditField,\n canDeleteField,\n fieldPermissions,\n supportsPii,\n };\n}\n"],"mappings":"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","ignoreList":[]}
@@ -31,8 +31,10 @@
31
31
  "cairo.tags.tagsWidget.emptyState.body.asLabels": "Labels help you filter and organize your items.",
32
32
  "cairo.import.restoring": "Restoring backup...",
33
33
  "cairo.table.saveView.button": "Save View",
34
+ "cairo.import.save": "Save",
34
35
  "cairo.customFields.editCustomField.fieldType.tooltip": "The field type can’t be changed.",
35
36
  "cairo.bulkSelectedWithTotal": "{num} of {total} selected",
37
+ "cairo.import.editField": "Edit field",
36
38
  "cairo.export.cancelTheExportGoBack": "Go Back",
37
39
  "cairo.viewDropdown.category.info": "Any changes to preset views can be saved as a new view.",
38
40
  "cairo.setupWidget.error.subtitle": "There was a technical issue. Try again in a few moments.",
@@ -92,6 +94,7 @@
92
94
  "cairo.filtersPanel.numRange.maxRange.error": "‘To’ value must be greater than the ‘From’ value.",
93
95
  "cairo.import.fileReadFailed": "Couldn’t read this file. Check your internet connection and that the file hasn’t been moved or deleted.",
94
96
  "cairo.setupWidget.step.inProgress": "In progress",
97
+ "cairo.import.idCollisionLabel": "When items share the same ID",
95
98
  "cairo.errorHandler.requestID.tooltip.cta": "Copy ID",
96
99
  "cairo.tags.manageTags.modal.deleteModal.cancel.CTA": "Cancel",
97
100
  "cairo.dragAndDrop.discardChanges.CTA": "Discard",
@@ -223,6 +226,7 @@
223
226
  "cairo.manageView.CTA": "Manage View",
224
227
  "cairo.tags.manageTags.modal.toast.rename.error.asLabels": "Couldn't rename label.",
225
228
  "cairo.filtersPanel.header": "Filter",
229
+ "cairo.import.error.submitFailed": "Couldn’t start the import. Please try again.",
226
230
  "cairo.emptyState.filters.nothingFound.clearFilters.CTA": "Clear Filters",
227
231
  "cairo.toolbar.moreFiltersButton": "Filter",
228
232
  "cairo.export.exportFailedMessage": "An error occurred while trying to export your items.",
@@ -253,6 +257,7 @@
253
257
  "cairo.tags.popover.bulkItemUpdate.tooltip.asLabels": "Changes can’t be made until labels are finished updating.",
254
258
  "cairo.import.columnsFound": "Columns Found",
255
259
  "cairo.customFields.updateDataExtension.fqdn-not-found.error": "Unable to update custom field due to a technical issue on our end.",
260
+ "cairo.import.updateExistingItems": "Update the existing items",
256
261
  "cairo.export.serverErrorMessage": "Due to a temporary server error, your export could not be completed. Contact Support for assistance.",
257
262
  "cairo.toast.undone": "Action undone.",
258
263
  "cairo.entityPage.header.apply.CTA": "Apply",
@@ -273,6 +278,7 @@
273
278
  "cairo.emptyState.subtitle.nothingAvailable": "We couldn’t find anything.",
274
279
  "cairo.tags.tagsWidget.create.CTA": "Create Tags",
275
280
  "cairo.tags.manageTags.modal.title.asLabels": "Manage labels: {EntityName}",
281
+ "cairo.editableTable.array.validation.invalidSyntax": "Invalid JSON syntax",
276
282
  "cairo.fieldValidation.maxCharacter": "Enter up to {charMax, plural, one {1 character} other {# characters}} including spaces.",
277
283
  "cairo.customFields.addCustomField.modal.keyFormat.error": "Must start with an English letter and can only contain letters, numbers or underscores.",
278
284
  "cairo.picker.itemsSelected": "{total, plural, =1 {1 item selected} other {# items selected}} ({max} max)",
@@ -315,6 +321,7 @@
315
321
  "cairo.import.parseFailed": "We couldn’t parse this file. Make sure it’s a valid CSV and try again.",
316
322
  "cairo.customFields.addCustomField.modal.advancedSettings.key.placeholder": "fieldKey",
317
323
  "cairo.customFields.archive.error.toast.CTA": "Try Again",
324
+ "cairo.import.error.jobFailed": "The import couldn’t be completed. Please try again.",
318
325
  "cairo.tags.manageTags.modal.toast.delete.error.asLabels": "Couldn't delete label.",
319
326
  "cairo.manageView.Rename.modal.cancel.CTA": "Cancel",
320
327
  "cairo.filtersPanel.default.All": "All",
@@ -337,6 +344,7 @@
337
344
  "cairo.appliedFilters": "{num, plural, =0 {No filters applied} one {1 applied} other {# applied}}",
338
345
  "cairo.collectionsPage.edit.CTA": "Edit",
339
346
  "cairo.dragAndDrop.reorderMode.toast.success": "Order has been updated",
347
+ "cairo.editableTable.object.validation.invalidSyntax": "Invalid JSON syntax",
340
348
  "cairo.customFields.addCustomField.modal.sameKey.error": "This key already exists. Try a different one.",
341
349
  "cairo.entityPage.saveError-technical.toast.description": "Changes weren’t saved due to a technical issue on our side. ",
342
350
  "cairo.import.startImport": "Import",
@@ -399,6 +407,7 @@
399
407
  "cairo.tags.filterPanel.dropdown.placeholder.asLabels": "Select labels...",
400
408
  "cairo.tags.manageTags.modal.title": "Manage tags: {EntityName}",
401
409
  "cairo.sortableColumns.modal.description": "You’ve sorted this list manually. Once you sort by {columnTitle}, the current order of your items will be replaced.",
410
+ "cairo.editableTable.array.validation.invalidType": "Value must be a valid JSON array",
402
411
  "cairo.customFields.emptyState.title": "Add a custom field",
403
412
  "cairo.table.custom-columns.button.cta": "Customize",
404
413
  "cairo.customFields.addCustomField.modal.sameName.error": "A field with this name already exists. Try a different name.",
@@ -498,6 +507,7 @@
498
507
  "cairo.collectionPage.appInstall-inContext.moreActions.relatedApps.CTA": "Explore related apps",
499
508
  "cairo.table.layout.spreadsheet": "Spreadsheet",
500
509
  "cairo.tags.manageTags.modal.list.input.validation.maxLength.asLabels": "Labels must be under {count, plural, other {# characters}}",
510
+ "cairo.import.error.uploadFailed": "Couldn’t upload your file. Check your connection and try again.",
501
511
  "cairo.customFields.entityPage.emptyState.title": "No fields were filled",
502
512
  "cairo.remove-image.tooltip": "Remove image",
503
513
  "cairo.tags.collectionPage.add.CTA.asLabels": "Assign Labels",
@@ -567,6 +577,7 @@
567
577
  "cairo.manageView.saveNewView.CTA": "Save as New View",
568
578
  "cairo.tags.collectionPage.popover.manage.CTA.asLabels": "Manage Labels",
569
579
  "cairo.import.backupDescription": "Creating a backup before importing. This may take a moment.",
580
+ "cairo.editableTable.object.validation.invalidType": "Value must be a valid JSON object",
570
581
  "cair.appliedFilters.Apply.CTA": "Apply",
571
582
  "cairo.export.noPermissionsCTA": "View Roles & Permissions",
572
583
  "cairo.updatedView.collectionPage.toast.desc": "Refresh to update the view with your recent changes.",
@@ -702,6 +713,7 @@
702
713
  "cairo.customFields.addCustomField.dropdownList.emptyFieldName.error": "Add an option.",
703
714
  "cairo.customFields.addCustomField.modal.advancedSettings.externalApps": "Installed apps",
704
715
  "cairo.export.successMessage": "Your file is now being downloaded. Not working?",
716
+ "cairo.import.skipImportedItems": "Skip imported items",
705
717
  "cairo.downloadable-url.error.generic": "There was an issue downloading the file.",
706
718
  "cairo.table.custom-columns.indication.user.tooltip": "This field was created by a user",
707
719
  "cairo.table.mobile.more.button": "Actions",
@@ -31,8 +31,10 @@
31
31
  "cairo.tags.tagsWidget.emptyState.body.asLabels": "Labels help you filter and organize your items.",
32
32
  "cairo.import.restoring": "Restoring backup...",
33
33
  "cairo.table.saveView.button": "Save View",
34
+ "cairo.import.save": "Save",
34
35
  "cairo.customFields.editCustomField.fieldType.tooltip": "The field type can’t be changed.",
35
36
  "cairo.bulkSelectedWithTotal": "{num} of {total} selected",
37
+ "cairo.import.editField": "Edit field",
36
38
  "cairo.export.cancelTheExportGoBack": "Go Back",
37
39
  "cairo.viewDropdown.category.info": "Any changes to preset views can be saved as a new view.",
38
40
  "cairo.setupWidget.error.subtitle": "There was a technical issue. Try again in a few moments.",
@@ -92,6 +94,7 @@
92
94
  "cairo.filtersPanel.numRange.maxRange.error": "‘To’ value must be greater than the ‘From’ value.",
93
95
  "cairo.import.fileReadFailed": "Couldn’t read this file. Check your internet connection and that the file hasn’t been moved or deleted.",
94
96
  "cairo.setupWidget.step.inProgress": "In progress",
97
+ "cairo.import.idCollisionLabel": "When items share the same ID",
95
98
  "cairo.errorHandler.requestID.tooltip.cta": "Copy ID",
96
99
  "cairo.tags.manageTags.modal.deleteModal.cancel.CTA": "Cancel",
97
100
  "cairo.dragAndDrop.discardChanges.CTA": "Discard",
@@ -223,6 +226,7 @@
223
226
  "cairo.manageView.CTA": "Manage View",
224
227
  "cairo.tags.manageTags.modal.toast.rename.error.asLabels": "Couldn't rename label.",
225
228
  "cairo.filtersPanel.header": "Filter",
229
+ "cairo.import.error.submitFailed": "Couldn’t start the import. Please try again.",
226
230
  "cairo.emptyState.filters.nothingFound.clearFilters.CTA": "Clear Filters",
227
231
  "cairo.toolbar.moreFiltersButton": "Filter",
228
232
  "cairo.export.exportFailedMessage": "An error occurred while trying to export your items.",
@@ -253,6 +257,7 @@
253
257
  "cairo.tags.popover.bulkItemUpdate.tooltip.asLabels": "Changes can’t be made until labels are finished updating.",
254
258
  "cairo.import.columnsFound": "Columns Found",
255
259
  "cairo.customFields.updateDataExtension.fqdn-not-found.error": "Unable to update custom field due to a technical issue on our end.",
260
+ "cairo.import.updateExistingItems": "Update the existing items",
256
261
  "cairo.export.serverErrorMessage": "Due to a temporary server error, your export could not be completed. Contact Support for assistance.",
257
262
  "cairo.toast.undone": "Action undone.",
258
263
  "cairo.entityPage.header.apply.CTA": "Apply",
@@ -273,6 +278,7 @@
273
278
  "cairo.emptyState.subtitle.nothingAvailable": "We couldn’t find anything.",
274
279
  "cairo.tags.tagsWidget.create.CTA": "Create Tags",
275
280
  "cairo.tags.manageTags.modal.title.asLabels": "Manage labels: {EntityName}",
281
+ "cairo.editableTable.array.validation.invalidSyntax": "Invalid JSON syntax",
276
282
  "cairo.fieldValidation.maxCharacter": "Enter up to {charMax, plural, one {1 character} other {# characters}} including spaces.",
277
283
  "cairo.customFields.addCustomField.modal.keyFormat.error": "Must start with an English letter and can only contain letters, numbers or underscores.",
278
284
  "cairo.picker.itemsSelected": "{total, plural, =1 {1 item selected} other {# items selected}} ({max} max)",
@@ -315,6 +321,7 @@
315
321
  "cairo.import.parseFailed": "We couldn’t parse this file. Make sure it’s a valid CSV and try again.",
316
322
  "cairo.customFields.addCustomField.modal.advancedSettings.key.placeholder": "fieldKey",
317
323
  "cairo.customFields.archive.error.toast.CTA": "Try Again",
324
+ "cairo.import.error.jobFailed": "The import couldn’t be completed. Please try again.",
318
325
  "cairo.tags.manageTags.modal.toast.delete.error.asLabels": "Couldn't delete label.",
319
326
  "cairo.manageView.Rename.modal.cancel.CTA": "Cancel",
320
327
  "cairo.filtersPanel.default.All": "All",
@@ -337,6 +344,7 @@
337
344
  "cairo.appliedFilters": "{num, plural, =0 {No filters applied} one {1 applied} other {# applied}}",
338
345
  "cairo.collectionsPage.edit.CTA": "Edit",
339
346
  "cairo.dragAndDrop.reorderMode.toast.success": "Order has been updated",
347
+ "cairo.editableTable.object.validation.invalidSyntax": "Invalid JSON syntax",
340
348
  "cairo.customFields.addCustomField.modal.sameKey.error": "This key already exists. Try a different one.",
341
349
  "cairo.entityPage.saveError-technical.toast.description": "Changes weren’t saved due to a technical issue on our side. ",
342
350
  "cairo.import.startImport": "Import",
@@ -399,6 +407,7 @@
399
407
  "cairo.tags.filterPanel.dropdown.placeholder.asLabels": "Select labels...",
400
408
  "cairo.tags.manageTags.modal.title": "Manage tags: {EntityName}",
401
409
  "cairo.sortableColumns.modal.description": "You’ve sorted this list manually. Once you sort by {columnTitle}, the current order of your items will be replaced.",
410
+ "cairo.editableTable.array.validation.invalidType": "Value must be a valid JSON array",
402
411
  "cairo.customFields.emptyState.title": "Add a custom field",
403
412
  "cairo.table.custom-columns.button.cta": "Customize",
404
413
  "cairo.customFields.addCustomField.modal.sameName.error": "A field with this name already exists. Try a different name.",
@@ -498,6 +507,7 @@
498
507
  "cairo.collectionPage.appInstall-inContext.moreActions.relatedApps.CTA": "Explore related apps",
499
508
  "cairo.table.layout.spreadsheet": "Spreadsheet",
500
509
  "cairo.tags.manageTags.modal.list.input.validation.maxLength.asLabels": "Labels must be under {count, plural, other {# characters}}",
510
+ "cairo.import.error.uploadFailed": "Couldn’t upload your file. Check your connection and try again.",
501
511
  "cairo.customFields.entityPage.emptyState.title": "No fields were filled",
502
512
  "cairo.remove-image.tooltip": "Remove image",
503
513
  "cairo.tags.collectionPage.add.CTA.asLabels": "Assign Labels",
@@ -567,6 +577,7 @@
567
577
  "cairo.manageView.saveNewView.CTA": "Save as New View",
568
578
  "cairo.tags.collectionPage.popover.manage.CTA.asLabels": "Manage Labels",
569
579
  "cairo.import.backupDescription": "Creating a backup before importing. This may take a moment.",
580
+ "cairo.editableTable.object.validation.invalidType": "Value must be a valid JSON object",
570
581
  "cair.appliedFilters.Apply.CTA": "Apply",
571
582
  "cairo.export.noPermissionsCTA": "View Roles & Permissions",
572
583
  "cairo.updatedView.collectionPage.toast.desc": "Refresh to update the view with your recent changes.",
@@ -702,6 +713,7 @@
702
713
  "cairo.customFields.addCustomField.dropdownList.emptyFieldName.error": "Add an option.",
703
714
  "cairo.customFields.addCustomField.modal.advancedSettings.externalApps": "Installed apps",
704
715
  "cairo.export.successMessage": "Your file is now being downloaded. Not working?",
716
+ "cairo.import.skipImportedItems": "Skip imported items",
705
717
  "cairo.downloadable-url.error.generic": "There was an issue downloading the file.",
706
718
  "cairo.table.custom-columns.indication.user.tooltip": "This field was created by a user",
707
719
  "cairo.table.mobile.more.button": "Actions",