payload 3.32.0-internal.f2e77bd → 3.33.0-internal.d1efdd8

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 (98) hide show
  1. package/dist/admin/forms/Form.d.ts +12 -1
  2. package/dist/admin/forms/Form.d.ts.map +1 -1
  3. package/dist/admin/forms/Form.js.map +1 -1
  4. package/dist/admin/functions/index.d.ts +1 -0
  5. package/dist/admin/functions/index.d.ts.map +1 -1
  6. package/dist/admin/functions/index.js.map +1 -1
  7. package/dist/bin/generateImportMap/index.js +3 -3
  8. package/dist/bin/generateImportMap/index.js.map +1 -1
  9. package/dist/bin/generateTypes.js +3 -3
  10. package/dist/bin/generateTypes.js.map +1 -1
  11. package/dist/collections/config/sanitize.d.ts.map +1 -1
  12. package/dist/collections/config/sanitize.js.map +1 -1
  13. package/dist/collections/config/types.d.ts +11 -0
  14. package/dist/collections/config/types.d.ts.map +1 -1
  15. package/dist/collections/config/types.js.map +1 -1
  16. package/dist/config/orderable/fractional-indexing.d.ts +31 -0
  17. package/dist/config/orderable/fractional-indexing.d.ts.map +1 -0
  18. package/dist/config/orderable/fractional-indexing.js +295 -0
  19. package/dist/config/orderable/fractional-indexing.js.map +1 -0
  20. package/dist/config/orderable/index.d.ts +28 -0
  21. package/dist/config/orderable/index.d.ts.map +1 -0
  22. package/dist/config/orderable/index.js +259 -0
  23. package/dist/config/orderable/index.js.map +1 -0
  24. package/dist/config/sanitize.d.ts.map +1 -1
  25. package/dist/config/sanitize.js +3 -0
  26. package/dist/config/sanitize.js.map +1 -1
  27. package/dist/database/defaultUpdateJobs.d.ts.map +1 -1
  28. package/dist/database/defaultUpdateJobs.js +1 -4
  29. package/dist/database/defaultUpdateJobs.js.map +1 -1
  30. package/dist/database/types.d.ts +6 -0
  31. package/dist/database/types.d.ts.map +1 -1
  32. package/dist/database/types.js.map +1 -1
  33. package/dist/fields/config/types.d.ts +12 -1
  34. package/dist/fields/config/types.d.ts.map +1 -1
  35. package/dist/fields/config/types.js.map +1 -1
  36. package/dist/index.d.ts +3 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +1 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/queues/config/types/index.d.ts +15 -1
  41. package/dist/queues/config/types/index.d.ts.map +1 -1
  42. package/dist/queues/config/types/index.js.map +1 -1
  43. package/dist/queues/config/types/workflowTypes.d.ts +1 -1
  44. package/dist/queues/config/types/workflowTypes.d.ts.map +1 -1
  45. package/dist/queues/config/types/workflowTypes.js.map +1 -1
  46. package/dist/queues/localAPI.d.ts +12 -1
  47. package/dist/queues/localAPI.d.ts.map +1 -1
  48. package/dist/queues/localAPI.js +2 -0
  49. package/dist/queues/localAPI.js.map +1 -1
  50. package/dist/queues/operations/runJobs/index.d.ts +15 -2
  51. package/dist/queues/operations/runJobs/index.d.ts.map +1 -1
  52. package/dist/queues/operations/runJobs/index.js +30 -4
  53. package/dist/queues/operations/runJobs/index.js.map +1 -1
  54. package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.d.ts.map +1 -1
  55. package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js +5 -1
  56. package/dist/queues/operations/runJobs/runJob/getRunTaskFunction.js.map +1 -1
  57. package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.d.ts.map +1 -1
  58. package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js +14 -1
  59. package/dist/queues/operations/runJobs/runJob/getUpdateJobFunction.js.map +1 -1
  60. package/dist/queues/operations/runJobs/runJob/index.d.ts.map +1 -1
  61. package/dist/queues/operations/runJobs/runJob/index.js +2 -0
  62. package/dist/queues/operations/runJobs/runJob/index.js.map +1 -1
  63. package/dist/queues/utilities/updateJob.d.ts.map +1 -1
  64. package/dist/queues/utilities/updateJob.js +10 -9
  65. package/dist/queues/utilities/updateJob.js.map +1 -1
  66. package/dist/uploads/deleteAssociatedFiles.js +3 -3
  67. package/dist/uploads/deleteAssociatedFiles.js.map +1 -1
  68. package/dist/uploads/fileExists.js +2 -2
  69. package/dist/uploads/fileExists.js.map +1 -1
  70. package/dist/uploads/generateFileData.d.ts.map +1 -1
  71. package/dist/uploads/generateFileData.js +4 -5
  72. package/dist/uploads/generateFileData.js.map +1 -1
  73. package/dist/uploads/getFileByPath.js +3 -3
  74. package/dist/uploads/getFileByPath.js.map +1 -1
  75. package/dist/uploads/getImageSize.js +2 -2
  76. package/dist/uploads/getImageSize.js.map +1 -1
  77. package/dist/uploads/imageResizer.js +2 -2
  78. package/dist/uploads/imageResizer.js.map +1 -1
  79. package/dist/uploads/saveBufferToFile.js +2 -2
  80. package/dist/uploads/saveBufferToFile.js.map +1 -1
  81. package/dist/uploads/tempFile.js +4 -4
  82. package/dist/uploads/tempFile.js.map +1 -1
  83. package/dist/uploads/unlinkTempFiles.d.ts.map +1 -1
  84. package/dist/uploads/unlinkTempFiles.js +2 -4
  85. package/dist/uploads/unlinkTempFiles.js.map +1 -1
  86. package/dist/utilities/configToJSONSchema.js +3 -3
  87. package/dist/utilities/configToJSONSchema.js.map +1 -1
  88. package/dist/utilities/configToJSONSchema.spec.js +29 -0
  89. package/dist/utilities/configToJSONSchema.spec.js.map +1 -1
  90. package/dist/utilities/flattenAllFields.d.ts +5 -0
  91. package/dist/utilities/flattenAllFields.d.ts.map +1 -1
  92. package/dist/utilities/flattenAllFields.js +5 -1
  93. package/dist/utilities/flattenAllFields.js.map +1 -1
  94. package/package.json +2 -2
  95. package/dist/queues/utilities/sanitizeUpdateData.d.ts +0 -9
  96. package/dist/queues/utilities/sanitizeUpdateData.d.ts.map +0 -1
  97. package/dist/queues/utilities/sanitizeUpdateData.js +0 -25
  98. package/dist/queues/utilities/sanitizeUpdateData.js.map +0 -1
@@ -0,0 +1,295 @@
1
+ // @ts-check
2
+ /**
3
+ * THIS FILE IS COPIED FROM:
4
+ * https://github.com/rocicorp/fractional-indexing/blob/main/src/index.js
5
+ *
6
+ * I AM NOT INSTALLING THAT LIBRARY BECAUSE JEST COMPLAINS ABOUT THE ESM MODULE AND THE TESTS FAIL.
7
+ * DO NOT MODIFY IT
8
+ */ // License: CC0 (no rights reserved).
9
+ // This is based on https://observablehq.com/@dgreensp/implementing-fractional-indexing
10
+ export const BASE_62_DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
11
+ // `a` may be empty string, `b` is null or non-empty string.
12
+ // `a < b` lexicographically if `b` is non-null.
13
+ // no trailing zeros allowed.
14
+ // digits is a string such as '0123456789' for base 10. Digits must be in
15
+ // ascending character code order!
16
+ /**
17
+ * @param {string} a
18
+ * @param {string | null | undefined} b
19
+ * @param {string} digits
20
+ * @returns {string}
21
+ */ function midpoint(a, b, digits) {
22
+ const zero = digits[0];
23
+ if (b != null && a >= b) {
24
+ throw new Error(a + ' >= ' + b);
25
+ }
26
+ if (a.slice(-1) === zero || b && b.slice(-1) === zero) {
27
+ throw new Error('trailing zero');
28
+ }
29
+ if (b) {
30
+ // remove longest common prefix. pad `a` with 0s as we
31
+ // go. note that we don't need to pad `b`, because it can't
32
+ // end before `a` while traversing the common prefix.
33
+ let n = 0;
34
+ while((a[n] || zero) === b[n]){
35
+ n++;
36
+ }
37
+ if (n > 0) {
38
+ return b.slice(0, n) + midpoint(a.slice(n), b.slice(n), digits);
39
+ }
40
+ }
41
+ // first digits (or lack of digit) are different
42
+ const digitA = a ? digits.indexOf(a[0]) : 0;
43
+ const digitB = b != null ? digits.indexOf(b[0]) : digits.length;
44
+ if (digitB - digitA > 1) {
45
+ const midDigit = Math.round(0.5 * (digitA + digitB));
46
+ return digits[midDigit];
47
+ } else {
48
+ // first digits are consecutive
49
+ if (b && b.length > 1) {
50
+ return b.slice(0, 1);
51
+ } else {
52
+ // `b` is null or has length 1 (a single digit).
53
+ // the first digit of `a` is the previous digit to `b`,
54
+ // or 9 if `b` is null.
55
+ // given, for example, midpoint('49', '5'), return
56
+ // '4' + midpoint('9', null), which will become
57
+ // '4' + '9' + midpoint('', null), which is '495'
58
+ return digits[digitA] + midpoint(a.slice(1), null, digits);
59
+ }
60
+ }
61
+ }
62
+ /**
63
+ * @param {string} int
64
+ * @return {void}
65
+ */ function validateInteger(int) {
66
+ if (int.length !== getIntegerLength(int[0])) {
67
+ throw new Error('invalid integer part of order key: ' + int);
68
+ }
69
+ }
70
+ /**
71
+ * @param {string} head
72
+ * @return {number}
73
+ */ function getIntegerLength(head) {
74
+ if (head >= 'a' && head <= 'z') {
75
+ return head.charCodeAt(0) - 'a'.charCodeAt(0) + 2;
76
+ } else if (head >= 'A' && head <= 'Z') {
77
+ return 'Z'.charCodeAt(0) - head.charCodeAt(0) + 2;
78
+ } else {
79
+ throw new Error('invalid order key head: ' + head);
80
+ }
81
+ }
82
+ /**
83
+ * @param {string} key
84
+ * @return {string}
85
+ */ function getIntegerPart(key) {
86
+ const integerPartLength = getIntegerLength(key[0]);
87
+ if (integerPartLength > key.length) {
88
+ throw new Error('invalid order key: ' + key);
89
+ }
90
+ return key.slice(0, integerPartLength);
91
+ }
92
+ /**
93
+ * @param {string} key
94
+ * @param {string} digits
95
+ * @return {void}
96
+ */ function validateOrderKey(key, digits) {
97
+ if (key === 'A' + digits[0].repeat(26)) {
98
+ throw new Error('invalid order key: ' + key);
99
+ }
100
+ // getIntegerPart will throw if the first character is bad,
101
+ // or the key is too short. we'd call it to check these things
102
+ // even if we didn't need the result
103
+ const i = getIntegerPart(key);
104
+ const f = key.slice(i.length);
105
+ if (f.slice(-1) === digits[0]) {
106
+ throw new Error('invalid order key: ' + key);
107
+ }
108
+ }
109
+ // note that this may return null, as there is a largest integer
110
+ /**
111
+ * @param {string} x
112
+ * @param {string} digits
113
+ * @return {string | null}
114
+ */ function incrementInteger(x, digits) {
115
+ validateInteger(x);
116
+ const [head, ...digs] = x.split('');
117
+ let carry = true;
118
+ for(let i = digs.length - 1; carry && i >= 0; i--){
119
+ const d = digits.indexOf(digs[i]) + 1;
120
+ if (d === digits.length) {
121
+ digs[i] = digits[0];
122
+ } else {
123
+ digs[i] = digits[d];
124
+ carry = false;
125
+ }
126
+ }
127
+ if (carry) {
128
+ if (head === 'Z') {
129
+ return 'a' + digits[0];
130
+ }
131
+ if (head === 'z') {
132
+ return null;
133
+ }
134
+ const h = String.fromCharCode(head.charCodeAt(0) + 1);
135
+ if (h > 'a') {
136
+ digs.push(digits[0]);
137
+ } else {
138
+ digs.pop();
139
+ }
140
+ return h + digs.join('');
141
+ } else {
142
+ return head + digs.join('');
143
+ }
144
+ }
145
+ // note that this may return null, as there is a smallest integer
146
+ /**
147
+ * @param {string} x
148
+ * @param {string} digits
149
+ * @return {string | null}
150
+ */ function decrementInteger(x, digits) {
151
+ validateInteger(x);
152
+ const [head, ...digs] = x.split('');
153
+ let borrow = true;
154
+ for(let i = digs.length - 1; borrow && i >= 0; i--){
155
+ const d = digits.indexOf(digs[i]) - 1;
156
+ if (d === -1) {
157
+ digs[i] = digits.slice(-1);
158
+ } else {
159
+ digs[i] = digits[d];
160
+ borrow = false;
161
+ }
162
+ }
163
+ if (borrow) {
164
+ if (head === 'a') {
165
+ return 'Z' + digits.slice(-1);
166
+ }
167
+ if (head === 'A') {
168
+ return null;
169
+ }
170
+ const h = String.fromCharCode(head.charCodeAt(0) - 1);
171
+ if (h < 'Z') {
172
+ digs.push(digits.slice(-1));
173
+ } else {
174
+ digs.pop();
175
+ }
176
+ return h + digs.join('');
177
+ } else {
178
+ return head + digs.join('');
179
+ }
180
+ }
181
+ // `a` is an order key or null (START).
182
+ // `b` is an order key or null (END).
183
+ // `a < b` lexicographically if both are non-null.
184
+ // digits is a string such as '0123456789' for base 10. Digits must be in
185
+ // ascending character code order!
186
+ /**
187
+ * @param {string | null | undefined} a
188
+ * @param {string | null | undefined} b
189
+ * @param {string=} digits
190
+ * @return {string}
191
+ */ export function generateKeyBetween(a, b, digits = BASE_62_DIGITS) {
192
+ if (a != null) {
193
+ validateOrderKey(a, digits);
194
+ }
195
+ if (b != null) {
196
+ validateOrderKey(b, digits);
197
+ }
198
+ if (a != null && b != null && a >= b) {
199
+ throw new Error(a + ' >= ' + b);
200
+ }
201
+ if (a == null) {
202
+ if (b == null) {
203
+ return 'a' + digits[0];
204
+ }
205
+ const ib = getIntegerPart(b);
206
+ const fb = b.slice(ib.length);
207
+ if (ib === 'A' + digits[0].repeat(26)) {
208
+ return ib + midpoint('', fb, digits);
209
+ }
210
+ if (ib < b) {
211
+ return ib;
212
+ }
213
+ const res = decrementInteger(ib, digits);
214
+ if (res == null) {
215
+ throw new Error('cannot decrement any more');
216
+ }
217
+ return res;
218
+ }
219
+ if (b == null) {
220
+ const ia = getIntegerPart(a);
221
+ const fa = a.slice(ia.length);
222
+ const i = incrementInteger(ia, digits);
223
+ return i == null ? ia + midpoint(fa, null, digits) : i;
224
+ }
225
+ const ia = getIntegerPart(a);
226
+ const fa = a.slice(ia.length);
227
+ const ib = getIntegerPart(b);
228
+ const fb = b.slice(ib.length);
229
+ if (ia === ib) {
230
+ return ia + midpoint(fa, fb, digits);
231
+ }
232
+ const i = incrementInteger(ia, digits);
233
+ if (i == null) {
234
+ throw new Error('cannot increment any more');
235
+ }
236
+ if (i < b) {
237
+ return i;
238
+ }
239
+ return ia + midpoint(fa, null, digits);
240
+ }
241
+ /**
242
+ * same preconditions as generateKeysBetween.
243
+ * n >= 0.
244
+ * Returns an array of n distinct keys in sorted order.
245
+ * If a and b are both null, returns [a0, a1, ...]
246
+ * If one or the other is null, returns consecutive "integer"
247
+ * keys. Otherwise, returns relatively short keys between
248
+ * a and b.
249
+ * @param {string | null | undefined} a
250
+ * @param {string | null | undefined} b
251
+ * @param {number} n
252
+ * @param {string} digits
253
+ * @return {string[]}
254
+ */ export function generateNKeysBetween(a, b, n, digits = BASE_62_DIGITS) {
255
+ if (n === 0) {
256
+ return [];
257
+ }
258
+ if (n === 1) {
259
+ return [
260
+ generateKeyBetween(a, b, digits)
261
+ ];
262
+ }
263
+ if (b == null) {
264
+ let c = generateKeyBetween(a, b, digits);
265
+ const result = [
266
+ c
267
+ ];
268
+ for(let i = 0; i < n - 1; i++){
269
+ c = generateKeyBetween(c, b, digits);
270
+ result.push(c);
271
+ }
272
+ return result;
273
+ }
274
+ if (a == null) {
275
+ let c = generateKeyBetween(a, b, digits);
276
+ const result = [
277
+ c
278
+ ];
279
+ for(let i = 0; i < n - 1; i++){
280
+ c = generateKeyBetween(a, c, digits);
281
+ result.push(c);
282
+ }
283
+ result.reverse();
284
+ return result;
285
+ }
286
+ const mid = Math.floor(n / 2);
287
+ const c = generateKeyBetween(a, b, digits);
288
+ return [
289
+ ...generateNKeysBetween(a, c, mid, digits),
290
+ c,
291
+ ...generateNKeysBetween(c, b, n - mid - 1, digits)
292
+ ];
293
+ }
294
+
295
+ //# sourceMappingURL=fractional-indexing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/orderable/fractional-indexing.js"],"sourcesContent":["// @ts-check\n\n/**\n * THIS FILE IS COPIED FROM:\n * https://github.com/rocicorp/fractional-indexing/blob/main/src/index.js\n *\n * I AM NOT INSTALLING THAT LIBRARY BECAUSE JEST COMPLAINS ABOUT THE ESM MODULE AND THE TESTS FAIL.\n * DO NOT MODIFY IT\n */\n\n// License: CC0 (no rights reserved).\n\n// This is based on https://observablehq.com/@dgreensp/implementing-fractional-indexing\n\nexport const BASE_62_DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'\n\n// `a` may be empty string, `b` is null or non-empty string.\n// `a < b` lexicographically if `b` is non-null.\n// no trailing zeros allowed.\n// digits is a string such as '0123456789' for base 10. Digits must be in\n// ascending character code order!\n/**\n * @param {string} a\n * @param {string | null | undefined} b\n * @param {string} digits\n * @returns {string}\n */\nfunction midpoint(a, b, digits) {\n const zero = digits[0]\n if (b != null && a >= b) {\n throw new Error(a + ' >= ' + b)\n }\n if (a.slice(-1) === zero || (b && b.slice(-1) === zero)) {\n throw new Error('trailing zero')\n }\n if (b) {\n // remove longest common prefix. pad `a` with 0s as we\n // go. note that we don't need to pad `b`, because it can't\n // end before `a` while traversing the common prefix.\n let n = 0\n while ((a[n] || zero) === b[n]) {\n n++\n }\n if (n > 0) {\n return b.slice(0, n) + midpoint(a.slice(n), b.slice(n), digits)\n }\n }\n // first digits (or lack of digit) are different\n const digitA = a ? digits.indexOf(a[0]) : 0\n const digitB = b != null ? digits.indexOf(b[0]) : digits.length\n if (digitB - digitA > 1) {\n const midDigit = Math.round(0.5 * (digitA + digitB))\n return digits[midDigit]\n } else {\n // first digits are consecutive\n if (b && b.length > 1) {\n return b.slice(0, 1)\n } else {\n // `b` is null or has length 1 (a single digit).\n // the first digit of `a` is the previous digit to `b`,\n // or 9 if `b` is null.\n // given, for example, midpoint('49', '5'), return\n // '4' + midpoint('9', null), which will become\n // '4' + '9' + midpoint('', null), which is '495'\n return digits[digitA] + midpoint(a.slice(1), null, digits)\n }\n }\n}\n\n/**\n * @param {string} int\n * @return {void}\n */\n\nfunction validateInteger(int) {\n if (int.length !== getIntegerLength(int[0])) {\n throw new Error('invalid integer part of order key: ' + int)\n }\n}\n\n/**\n * @param {string} head\n * @return {number}\n */\n\nfunction getIntegerLength(head) {\n if (head >= 'a' && head <= 'z') {\n return head.charCodeAt(0) - 'a'.charCodeAt(0) + 2\n } else if (head >= 'A' && head <= 'Z') {\n return 'Z'.charCodeAt(0) - head.charCodeAt(0) + 2\n } else {\n throw new Error('invalid order key head: ' + head)\n }\n}\n\n/**\n * @param {string} key\n * @return {string}\n */\n\nfunction getIntegerPart(key) {\n const integerPartLength = getIntegerLength(key[0])\n if (integerPartLength > key.length) {\n throw new Error('invalid order key: ' + key)\n }\n return key.slice(0, integerPartLength)\n}\n\n/**\n * @param {string} key\n * @param {string} digits\n * @return {void}\n */\n\nfunction validateOrderKey(key, digits) {\n if (key === 'A' + digits[0].repeat(26)) {\n throw new Error('invalid order key: ' + key)\n }\n // getIntegerPart will throw if the first character is bad,\n // or the key is too short. we'd call it to check these things\n // even if we didn't need the result\n const i = getIntegerPart(key)\n const f = key.slice(i.length)\n if (f.slice(-1) === digits[0]) {\n throw new Error('invalid order key: ' + key)\n }\n}\n\n// note that this may return null, as there is a largest integer\n/**\n * @param {string} x\n * @param {string} digits\n * @return {string | null}\n */\nfunction incrementInteger(x, digits) {\n validateInteger(x)\n const [head, ...digs] = x.split('')\n let carry = true\n for (let i = digs.length - 1; carry && i >= 0; i--) {\n const d = digits.indexOf(digs[i]) + 1\n if (d === digits.length) {\n digs[i] = digits[0]\n } else {\n digs[i] = digits[d]\n carry = false\n }\n }\n if (carry) {\n if (head === 'Z') {\n return 'a' + digits[0]\n }\n if (head === 'z') {\n return null\n }\n const h = String.fromCharCode(head.charCodeAt(0) + 1)\n if (h > 'a') {\n digs.push(digits[0])\n } else {\n digs.pop()\n }\n return h + digs.join('')\n } else {\n return head + digs.join('')\n }\n}\n\n// note that this may return null, as there is a smallest integer\n/**\n * @param {string} x\n * @param {string} digits\n * @return {string | null}\n */\n\nfunction decrementInteger(x, digits) {\n validateInteger(x)\n const [head, ...digs] = x.split('')\n let borrow = true\n for (let i = digs.length - 1; borrow && i >= 0; i--) {\n const d = digits.indexOf(digs[i]) - 1\n if (d === -1) {\n digs[i] = digits.slice(-1)\n } else {\n digs[i] = digits[d]\n borrow = false\n }\n }\n if (borrow) {\n if (head === 'a') {\n return 'Z' + digits.slice(-1)\n }\n if (head === 'A') {\n return null\n }\n const h = String.fromCharCode(head.charCodeAt(0) - 1)\n if (h < 'Z') {\n digs.push(digits.slice(-1))\n } else {\n digs.pop()\n }\n return h + digs.join('')\n } else {\n return head + digs.join('')\n }\n}\n\n// `a` is an order key or null (START).\n// `b` is an order key or null (END).\n// `a < b` lexicographically if both are non-null.\n// digits is a string such as '0123456789' for base 10. Digits must be in\n// ascending character code order!\n/**\n * @param {string | null | undefined} a\n * @param {string | null | undefined} b\n * @param {string=} digits\n * @return {string}\n */\nexport function generateKeyBetween(a, b, digits = BASE_62_DIGITS) {\n if (a != null) {\n validateOrderKey(a, digits)\n }\n if (b != null) {\n validateOrderKey(b, digits)\n }\n if (a != null && b != null && a >= b) {\n throw new Error(a + ' >= ' + b)\n }\n if (a == null) {\n if (b == null) {\n return 'a' + digits[0]\n }\n\n const ib = getIntegerPart(b)\n const fb = b.slice(ib.length)\n if (ib === 'A' + digits[0].repeat(26)) {\n return ib + midpoint('', fb, digits)\n }\n if (ib < b) {\n return ib\n }\n const res = decrementInteger(ib, digits)\n if (res == null) {\n throw new Error('cannot decrement any more')\n }\n return res\n }\n\n if (b == null) {\n const ia = getIntegerPart(a)\n const fa = a.slice(ia.length)\n const i = incrementInteger(ia, digits)\n return i == null ? ia + midpoint(fa, null, digits) : i\n }\n\n const ia = getIntegerPart(a)\n const fa = a.slice(ia.length)\n const ib = getIntegerPart(b)\n const fb = b.slice(ib.length)\n if (ia === ib) {\n return ia + midpoint(fa, fb, digits)\n }\n const i = incrementInteger(ia, digits)\n if (i == null) {\n throw new Error('cannot increment any more')\n }\n if (i < b) {\n return i\n }\n return ia + midpoint(fa, null, digits)\n}\n\n/**\n * same preconditions as generateKeysBetween.\n * n >= 0.\n * Returns an array of n distinct keys in sorted order.\n * If a and b are both null, returns [a0, a1, ...]\n * If one or the other is null, returns consecutive \"integer\"\n * keys. Otherwise, returns relatively short keys between\n * a and b.\n * @param {string | null | undefined} a\n * @param {string | null | undefined} b\n * @param {number} n\n * @param {string} digits\n * @return {string[]}\n */\nexport function generateNKeysBetween(a, b, n, digits = BASE_62_DIGITS) {\n if (n === 0) {\n return []\n }\n if (n === 1) {\n return [generateKeyBetween(a, b, digits)]\n }\n if (b == null) {\n let c = generateKeyBetween(a, b, digits)\n const result = [c]\n for (let i = 0; i < n - 1; i++) {\n c = generateKeyBetween(c, b, digits)\n result.push(c)\n }\n return result\n }\n if (a == null) {\n let c = generateKeyBetween(a, b, digits)\n const result = [c]\n for (let i = 0; i < n - 1; i++) {\n c = generateKeyBetween(a, c, digits)\n result.push(c)\n }\n result.reverse()\n return result\n }\n const mid = Math.floor(n / 2)\n const c = generateKeyBetween(a, b, digits)\n return [\n ...generateNKeysBetween(a, c, mid, digits),\n c,\n ...generateNKeysBetween(c, b, n - mid - 1, digits),\n ]\n}\n"],"names":["BASE_62_DIGITS","midpoint","a","b","digits","zero","Error","slice","n","digitA","indexOf","digitB","length","midDigit","Math","round","validateInteger","int","getIntegerLength","head","charCodeAt","getIntegerPart","key","integerPartLength","validateOrderKey","repeat","i","f","incrementInteger","x","digs","split","carry","d","h","String","fromCharCode","push","pop","join","decrementInteger","borrow","generateKeyBetween","ib","fb","res","ia","fa","generateNKeysBetween","c","result","reverse","mid","floor"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { CollectionConfig } from '../../collections/config/types.js';
2
+ import type { SanitizedConfig } from '../types.js';
3
+ /**
4
+ * This function creates:
5
+ * - N fields per collection, named `_order` or `_<collection>_<joinField>_order`
6
+ * - 1 hook per collection
7
+ * - 1 endpoint per app
8
+ *
9
+ * Also, if collection.defaultSort or joinField.defaultSort is not set, it will be set to the orderable field.
10
+ */
11
+ export declare const setupOrderable: (config: SanitizedConfig) => void;
12
+ export declare const addOrderableFieldsAndHook: (collection: CollectionConfig, orderableFieldNames: string[]) => void;
13
+ /**
14
+ * The body of the reorder endpoint.
15
+ * @internal
16
+ */
17
+ export type OrderableEndpointBody = {
18
+ collectionSlug: string;
19
+ docsToMove: string[];
20
+ newKeyWillBe: 'greater' | 'less';
21
+ orderableFieldName: string;
22
+ target: {
23
+ id: string;
24
+ key: string;
25
+ };
26
+ };
27
+ export declare const addOrderableEndpoint: (config: SanitizedConfig) => void;
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/orderable/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,gBAAgB,EAAE,MAAM,mCAAmC,CAAA;AAE3F,OAAO,KAAK,EAA4B,eAAe,EAAE,MAAM,aAAa,CAAA;AAM5E;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,WAAY,eAAe,SAkDrD,CAAA;AAED,eAAO,MAAM,yBAAyB,eACxB,gBAAgB,uBACP,MAAM,EAAE,SA+D9B,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,YAAY,EAAE,SAAS,GAAG,MAAM,CAAA;IAChC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAA;QACV,GAAG,EAAE,MAAM,CAAA;KACZ,CAAA;CACF,CAAA;AAED,eAAO,MAAM,oBAAoB,WAAY,eAAe,SA+H3D,CAAA"}
@@ -0,0 +1,259 @@
1
+ import executeAccess from '../../auth/executeAccess.js';
2
+ import { traverseFields } from '../../utilities/traverseFields.js';
3
+ import { generateKeyBetween, generateNKeysBetween } from './fractional-indexing.js';
4
+ /**
5
+ * This function creates:
6
+ * - N fields per collection, named `_order` or `_<collection>_<joinField>_order`
7
+ * - 1 hook per collection
8
+ * - 1 endpoint per app
9
+ *
10
+ * Also, if collection.defaultSort or joinField.defaultSort is not set, it will be set to the orderable field.
11
+ */ export const setupOrderable = (config)=>{
12
+ const fieldsToAdd = new Map();
13
+ config.collections.forEach((collection)=>{
14
+ if (collection.orderable) {
15
+ const currentFields = fieldsToAdd.get(collection) || [];
16
+ fieldsToAdd.set(collection, [
17
+ ...currentFields,
18
+ '_order'
19
+ ]);
20
+ collection.defaultSort = collection.defaultSort ?? '_order';
21
+ }
22
+ traverseFields({
23
+ callback: ({ field, parentRef, ref })=>{
24
+ if (field.type === 'array' || field.type === 'blocks') {
25
+ return false;
26
+ }
27
+ if (field.type === 'group' || field.type === 'tab') {
28
+ // @ts-expect-error ref is untyped
29
+ const parentPrefix = parentRef?.prefix ? `${parentRef.prefix}_` : '';
30
+ // @ts-expect-error ref is untyped
31
+ ref.prefix = `${parentPrefix}${field.name}`;
32
+ }
33
+ if (field.type === 'join' && field.orderable === true) {
34
+ if (Array.isArray(field.collection)) {
35
+ throw new Error('Orderable joins must target a single collection');
36
+ }
37
+ const relationshipCollection = config.collections.find((c)=>c.slug === field.collection);
38
+ if (!relationshipCollection) {
39
+ return false;
40
+ }
41
+ field.defaultSort = field.defaultSort ?? `_${field.collection}_${field.name}_order`;
42
+ const currentFields = fieldsToAdd.get(relationshipCollection) || [];
43
+ // @ts-expect-error ref is untyped
44
+ const prefix = parentRef?.prefix ? `${parentRef.prefix}_` : '';
45
+ fieldsToAdd.set(relationshipCollection, [
46
+ ...currentFields,
47
+ `_${field.collection}_${prefix}${field.name}_order`
48
+ ]);
49
+ }
50
+ },
51
+ fields: collection.fields
52
+ });
53
+ });
54
+ Array.from(fieldsToAdd.entries()).forEach(([collection, orderableFields])=>{
55
+ addOrderableFieldsAndHook(collection, orderableFields);
56
+ });
57
+ if (fieldsToAdd.size > 0) {
58
+ addOrderableEndpoint(config);
59
+ }
60
+ };
61
+ export const addOrderableFieldsAndHook = (collection, orderableFieldNames)=>{
62
+ // 1. Add field
63
+ orderableFieldNames.forEach((orderableFieldName)=>{
64
+ const orderField = {
65
+ name: orderableFieldName,
66
+ type: 'text',
67
+ admin: {
68
+ disableBulkEdit: true,
69
+ disabled: true,
70
+ disableListColumn: true,
71
+ disableListFilter: true,
72
+ hidden: true,
73
+ readOnly: true
74
+ },
75
+ index: true,
76
+ required: true,
77
+ // override the schema to make order fields optional for payload.create()
78
+ typescriptSchema: [
79
+ ()=>({
80
+ type: 'string',
81
+ required: false
82
+ })
83
+ ],
84
+ unique: true
85
+ };
86
+ collection.fields.unshift(orderField);
87
+ });
88
+ // 2. Add hook
89
+ if (!collection.hooks) {
90
+ collection.hooks = {};
91
+ }
92
+ if (!collection.hooks.beforeChange) {
93
+ collection.hooks.beforeChange = [];
94
+ }
95
+ const orderBeforeChangeHook = async ({ data, operation, req })=>{
96
+ // Only set _order on create, not on update (unless explicitly provided)
97
+ if (operation === 'create') {
98
+ for (const orderableFieldName of orderableFieldNames){
99
+ if (!data[orderableFieldName]) {
100
+ const lastDoc = await req.payload.find({
101
+ collection: collection.slug,
102
+ depth: 0,
103
+ limit: 1,
104
+ pagination: false,
105
+ req,
106
+ select: {
107
+ [orderableFieldName]: true
108
+ },
109
+ sort: `-${orderableFieldName}`
110
+ });
111
+ const lastOrderValue = lastDoc.docs[0]?.[orderableFieldName] || null;
112
+ data[orderableFieldName] = generateKeyBetween(lastOrderValue, null);
113
+ }
114
+ }
115
+ }
116
+ return data;
117
+ };
118
+ collection.hooks.beforeChange.push(orderBeforeChangeHook);
119
+ };
120
+ export const addOrderableEndpoint = (config)=>{
121
+ // 3. Add endpoint
122
+ const reorderHandler = async (req)=>{
123
+ const body = await req.json?.();
124
+ const { collectionSlug, docsToMove, newKeyWillBe, orderableFieldName, target } = body;
125
+ if (!Array.isArray(docsToMove) || docsToMove.length === 0) {
126
+ return new Response(JSON.stringify({
127
+ error: 'docsToMove must be a non-empty array'
128
+ }), {
129
+ headers: {
130
+ 'Content-Type': 'application/json'
131
+ },
132
+ status: 400
133
+ });
134
+ }
135
+ if (typeof target !== 'object' || typeof target.id !== 'string' || typeof target.key !== 'string') {
136
+ return new Response(JSON.stringify({
137
+ error: 'target must be an object with id and key'
138
+ }), {
139
+ headers: {
140
+ 'Content-Type': 'application/json'
141
+ },
142
+ status: 400
143
+ });
144
+ }
145
+ if (newKeyWillBe !== 'greater' && newKeyWillBe !== 'less') {
146
+ return new Response(JSON.stringify({
147
+ error: 'newKeyWillBe must be "greater" or "less"'
148
+ }), {
149
+ headers: {
150
+ 'Content-Type': 'application/json'
151
+ },
152
+ status: 400
153
+ });
154
+ }
155
+ const collection = config.collections.find((c)=>c.slug === collectionSlug);
156
+ if (!collection) {
157
+ return new Response(JSON.stringify({
158
+ error: `Collection ${collectionSlug} not found`
159
+ }), {
160
+ headers: {
161
+ 'Content-Type': 'application/json'
162
+ },
163
+ status: 400
164
+ });
165
+ }
166
+ if (typeof orderableFieldName !== 'string') {
167
+ return new Response(JSON.stringify({
168
+ error: 'orderableFieldName must be a string'
169
+ }), {
170
+ headers: {
171
+ 'Content-Type': 'application/json'
172
+ },
173
+ status: 400
174
+ });
175
+ }
176
+ // Prevent reordering if user doesn't have editing permissions
177
+ if (collection.access?.update) {
178
+ await executeAccess({
179
+ // Currently only one doc can be moved at a time. We should review this if we want to allow
180
+ // multiple docs to be moved at once in the future.
181
+ id: docsToMove[0],
182
+ data: {},
183
+ req
184
+ }, collection.access.update);
185
+ }
186
+ const targetId = target.id;
187
+ let targetKey = target.key;
188
+ // If targetKey = pending, we need to find its current key.
189
+ // This can only happen if the user reorders rows quickly with a slow connection.
190
+ if (targetKey === 'pending') {
191
+ const beforeDoc = await req.payload.findByID({
192
+ id: targetId,
193
+ collection: collection.slug,
194
+ depth: 0,
195
+ select: {
196
+ [orderableFieldName]: true
197
+ }
198
+ });
199
+ targetKey = beforeDoc?.[orderableFieldName] || null;
200
+ }
201
+ // The reason the endpoint does not receive this docId as an argument is that there
202
+ // are situations where the user may not see or know what the next or previous one is. For
203
+ // example, access control restrictions, if docBefore is the last one on the page, etc.
204
+ const adjacentDoc = await req.payload.find({
205
+ collection: collection.slug,
206
+ depth: 0,
207
+ limit: 1,
208
+ pagination: false,
209
+ select: {
210
+ [orderableFieldName]: true
211
+ },
212
+ sort: newKeyWillBe === 'greater' ? orderableFieldName : `-${orderableFieldName}`,
213
+ where: {
214
+ [orderableFieldName]: {
215
+ [newKeyWillBe === 'greater' ? 'greater_than' : 'less_than']: targetKey
216
+ }
217
+ }
218
+ });
219
+ const adjacentDocKey = adjacentDoc.docs?.[0]?.[orderableFieldName] || null;
220
+ // Currently N (= docsToMove.length) is always 1. Maybe in the future we will
221
+ // allow dragging and reordering multiple documents at once via the UI.
222
+ const orderValues = newKeyWillBe === 'greater' ? generateNKeysBetween(targetKey, adjacentDocKey, docsToMove.length) : generateNKeysBetween(adjacentDocKey, targetKey, docsToMove.length);
223
+ // Update each document with its new order value
224
+ for (const [index, id] of docsToMove.entries()){
225
+ await req.payload.update({
226
+ id,
227
+ collection: collection.slug,
228
+ data: {
229
+ [orderableFieldName]: orderValues[index]
230
+ },
231
+ depth: 0,
232
+ req,
233
+ select: {
234
+ id: true
235
+ }
236
+ });
237
+ }
238
+ return new Response(JSON.stringify({
239
+ orderValues,
240
+ success: true
241
+ }), {
242
+ headers: {
243
+ 'Content-Type': 'application/json'
244
+ },
245
+ status: 200
246
+ });
247
+ };
248
+ const reorderEndpoint = {
249
+ handler: reorderHandler,
250
+ method: 'post',
251
+ path: '/reorder'
252
+ };
253
+ if (!config.endpoints) {
254
+ config.endpoints = [];
255
+ }
256
+ config.endpoints.push(reorderEndpoint);
257
+ };
258
+
259
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/config/orderable/index.ts"],"sourcesContent":["import type { BeforeChangeHook, CollectionConfig } from '../../collections/config/types.js'\nimport type { Field } from '../../fields/config/types.js'\nimport type { Endpoint, PayloadHandler, SanitizedConfig } from '../types.js'\n\nimport executeAccess from '../../auth/executeAccess.js'\nimport { traverseFields } from '../../utilities/traverseFields.js'\nimport { generateKeyBetween, generateNKeysBetween } from './fractional-indexing.js'\n\n/**\n * This function creates:\n * - N fields per collection, named `_order` or `_<collection>_<joinField>_order`\n * - 1 hook per collection\n * - 1 endpoint per app\n *\n * Also, if collection.defaultSort or joinField.defaultSort is not set, it will be set to the orderable field.\n */\nexport const setupOrderable = (config: SanitizedConfig) => {\n const fieldsToAdd = new Map<CollectionConfig, string[]>()\n\n config.collections.forEach((collection) => {\n if (collection.orderable) {\n const currentFields = fieldsToAdd.get(collection) || []\n fieldsToAdd.set(collection, [...currentFields, '_order'])\n collection.defaultSort = collection.defaultSort ?? '_order'\n }\n\n traverseFields({\n callback: ({ field, parentRef, ref }) => {\n if (field.type === 'array' || field.type === 'blocks') {\n return false\n }\n if (field.type === 'group' || field.type === 'tab') {\n // @ts-expect-error ref is untyped\n const parentPrefix = parentRef?.prefix ? `${parentRef.prefix}_` : ''\n // @ts-expect-error ref is untyped\n ref.prefix = `${parentPrefix}${field.name}`\n }\n if (field.type === 'join' && field.orderable === true) {\n if (Array.isArray(field.collection)) {\n throw new Error('Orderable joins must target a single collection')\n }\n const relationshipCollection = config.collections.find((c) => c.slug === field.collection)\n if (!relationshipCollection) {\n return false\n }\n field.defaultSort = field.defaultSort ?? `_${field.collection}_${field.name}_order`\n const currentFields = fieldsToAdd.get(relationshipCollection) || []\n // @ts-expect-error ref is untyped\n const prefix = parentRef?.prefix ? `${parentRef.prefix}_` : ''\n fieldsToAdd.set(relationshipCollection, [\n ...currentFields,\n `_${field.collection}_${prefix}${field.name}_order`,\n ])\n }\n },\n fields: collection.fields,\n })\n })\n\n Array.from(fieldsToAdd.entries()).forEach(([collection, orderableFields]) => {\n addOrderableFieldsAndHook(collection, orderableFields)\n })\n\n if (fieldsToAdd.size > 0) {\n addOrderableEndpoint(config)\n }\n}\n\nexport const addOrderableFieldsAndHook = (\n collection: CollectionConfig,\n orderableFieldNames: string[],\n) => {\n // 1. Add field\n orderableFieldNames.forEach((orderableFieldName) => {\n const orderField: Field = {\n name: orderableFieldName,\n type: 'text',\n admin: {\n disableBulkEdit: true,\n disabled: true,\n disableListColumn: true,\n disableListFilter: true,\n hidden: true,\n readOnly: true,\n },\n index: true,\n required: true,\n // override the schema to make order fields optional for payload.create()\n typescriptSchema: [\n () => ({\n type: 'string',\n required: false,\n }),\n ],\n unique: true,\n }\n\n collection.fields.unshift(orderField)\n })\n\n // 2. Add hook\n if (!collection.hooks) {\n collection.hooks = {}\n }\n if (!collection.hooks.beforeChange) {\n collection.hooks.beforeChange = []\n }\n\n const orderBeforeChangeHook: BeforeChangeHook = async ({ data, operation, req }) => {\n // Only set _order on create, not on update (unless explicitly provided)\n if (operation === 'create') {\n for (const orderableFieldName of orderableFieldNames) {\n if (!data[orderableFieldName]) {\n const lastDoc = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 1,\n pagination: false,\n req,\n select: { [orderableFieldName]: true },\n sort: `-${orderableFieldName}`,\n })\n\n const lastOrderValue = lastDoc.docs[0]?.[orderableFieldName] || null\n data[orderableFieldName] = generateKeyBetween(lastOrderValue, null)\n }\n }\n }\n\n return data\n }\n\n collection.hooks.beforeChange.push(orderBeforeChangeHook)\n}\n\n/**\n * The body of the reorder endpoint.\n * @internal\n */\nexport type OrderableEndpointBody = {\n collectionSlug: string\n docsToMove: string[]\n newKeyWillBe: 'greater' | 'less'\n orderableFieldName: string\n target: {\n id: string\n key: string\n }\n}\n\nexport const addOrderableEndpoint = (config: SanitizedConfig) => {\n // 3. Add endpoint\n const reorderHandler: PayloadHandler = async (req) => {\n const body = (await req.json?.()) as OrderableEndpointBody\n\n const { collectionSlug, docsToMove, newKeyWillBe, orderableFieldName, target } = body\n\n if (!Array.isArray(docsToMove) || docsToMove.length === 0) {\n return new Response(JSON.stringify({ error: 'docsToMove must be a non-empty array' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n if (\n typeof target !== 'object' ||\n typeof target.id !== 'string' ||\n typeof target.key !== 'string'\n ) {\n return new Response(JSON.stringify({ error: 'target must be an object with id and key' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n if (newKeyWillBe !== 'greater' && newKeyWillBe !== 'less') {\n return new Response(JSON.stringify({ error: 'newKeyWillBe must be \"greater\" or \"less\"' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n const collection = config.collections.find((c) => c.slug === collectionSlug)\n if (!collection) {\n return new Response(JSON.stringify({ error: `Collection ${collectionSlug} not found` }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n if (typeof orderableFieldName !== 'string') {\n return new Response(JSON.stringify({ error: 'orderableFieldName must be a string' }), {\n headers: { 'Content-Type': 'application/json' },\n status: 400,\n })\n }\n\n // Prevent reordering if user doesn't have editing permissions\n if (collection.access?.update) {\n await executeAccess(\n {\n // Currently only one doc can be moved at a time. We should review this if we want to allow\n // multiple docs to be moved at once in the future.\n id: docsToMove[0],\n data: {},\n req,\n },\n collection.access.update,\n )\n }\n\n const targetId = target.id\n let targetKey = target.key\n\n // If targetKey = pending, we need to find its current key.\n // This can only happen if the user reorders rows quickly with a slow connection.\n if (targetKey === 'pending') {\n const beforeDoc = await req.payload.findByID({\n id: targetId,\n collection: collection.slug,\n depth: 0,\n select: { [orderableFieldName]: true },\n })\n targetKey = beforeDoc?.[orderableFieldName] || null\n }\n\n // The reason the endpoint does not receive this docId as an argument is that there\n // are situations where the user may not see or know what the next or previous one is. For\n // example, access control restrictions, if docBefore is the last one on the page, etc.\n const adjacentDoc = await req.payload.find({\n collection: collection.slug,\n depth: 0,\n limit: 1,\n pagination: false,\n select: { [orderableFieldName]: true },\n sort: newKeyWillBe === 'greater' ? orderableFieldName : `-${orderableFieldName}`,\n where: {\n [orderableFieldName]: {\n [newKeyWillBe === 'greater' ? 'greater_than' : 'less_than']: targetKey,\n },\n },\n })\n const adjacentDocKey = adjacentDoc.docs?.[0]?.[orderableFieldName] || null\n\n // Currently N (= docsToMove.length) is always 1. Maybe in the future we will\n // allow dragging and reordering multiple documents at once via the UI.\n const orderValues =\n newKeyWillBe === 'greater'\n ? generateNKeysBetween(targetKey, adjacentDocKey, docsToMove.length)\n : generateNKeysBetween(adjacentDocKey, targetKey, docsToMove.length)\n\n // Update each document with its new order value\n for (const [index, id] of docsToMove.entries()) {\n await req.payload.update({\n id,\n collection: collection.slug,\n data: {\n [orderableFieldName]: orderValues[index],\n },\n depth: 0,\n req,\n select: { id: true },\n })\n }\n\n return new Response(JSON.stringify({ orderValues, success: true }), {\n headers: { 'Content-Type': 'application/json' },\n status: 200,\n })\n }\n\n const reorderEndpoint: Endpoint = {\n handler: reorderHandler,\n method: 'post',\n path: '/reorder',\n }\n\n if (!config.endpoints) {\n config.endpoints = []\n }\n config.endpoints.push(reorderEndpoint)\n}\n"],"names":["executeAccess","traverseFields","generateKeyBetween","generateNKeysBetween","setupOrderable","config","fieldsToAdd","Map","collections","forEach","collection","orderable","currentFields","get","set","defaultSort","callback","field","parentRef","ref","type","parentPrefix","prefix","name","Array","isArray","Error","relationshipCollection","find","c","slug","fields","from","entries","orderableFields","addOrderableFieldsAndHook","size","addOrderableEndpoint","orderableFieldNames","orderableFieldName","orderField","admin","disableBulkEdit","disabled","disableListColumn","disableListFilter","hidden","readOnly","index","required","typescriptSchema","unique","unshift","hooks","beforeChange","orderBeforeChangeHook","data","operation","req","lastDoc","payload","depth","limit","pagination","select","sort","lastOrderValue","docs","push","reorderHandler","body","json","collectionSlug","docsToMove","newKeyWillBe","target","length","Response","JSON","stringify","error","headers","status","id","key","access","update","targetId","targetKey","beforeDoc","findByID","adjacentDoc","where","adjacentDocKey","orderValues","success","reorderEndpoint","handler","method","path","endpoints"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/config/sanitize.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,MAAM,EAGN,eAAe,EAEhB,MAAM,YAAY,CAAA;AA6FnB,eAAO,MAAM,cAAc,mBAA0B,MAAM,KAAG,OAAO,CAAC,eAAe,CA8SpF,CAAA"}
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/config/sanitize.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,MAAM,EAGN,eAAe,EAEhB,MAAM,YAAY,CAAA;AA8FnB,eAAO,MAAM,cAAc,mBAA0B,MAAM,KAAG,OAAO,CAAC,eAAe,CAiTpF,CAAA"}