@stoker-platform/utils 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/lib/src/access/collection.d.ts +9 -0
  2. package/lib/src/access/collection.js +59 -0
  3. package/lib/src/access/document.d.ts +3 -0
  4. package/lib/src/access/document.js +191 -0
  5. package/lib/src/access/getCollectionRestrictions.d.ts +7 -0
  6. package/lib/src/access/getCollectionRestrictions.js +71 -0
  7. package/lib/src/access/getRecordSubcollections.d.ts +2 -0
  8. package/lib/src/access/getRecordSubcollections.js +15 -0
  9. package/lib/src/access/getRelatedCollections.d.ts +2 -0
  10. package/lib/src/access/getRelatedCollections.js +24 -0
  11. package/lib/src/access/hasDependencyAccess.d.ts +2 -0
  12. package/lib/src/access/hasDependencyAccess.js +24 -0
  13. package/lib/src/access/isPaginationEnabled.d.ts +2 -0
  14. package/lib/src/access/isPaginationEnabled.js +35 -0
  15. package/lib/src/access/permissions.d.ts +2 -0
  16. package/lib/src/access/permissions.js +543 -0
  17. package/lib/src/access/read/getOne.d.ts +2 -0
  18. package/lib/src/access/read/getOne.js +19 -0
  19. package/lib/src/access/read/getSome.d.ts +2 -0
  20. package/lib/src/access/read/getSome.js +21 -0
  21. package/lib/src/access/roleHasOperationAccess.d.ts +2 -0
  22. package/lib/src/access/roleHasOperationAccess.js +7 -0
  23. package/lib/src/access/write/addRecord.d.ts +2 -0
  24. package/lib/src/access/write/addRecord.js +40 -0
  25. package/lib/src/access/write/deleteRecord.d.ts +2 -0
  26. package/lib/src/access/write/deleteRecord.js +26 -0
  27. package/lib/src/access/write/updateRecord.d.ts +2 -0
  28. package/lib/src/access/write/updateRecord.js +61 -0
  29. package/lib/src/getConfigValue.d.ts +12 -0
  30. package/lib/src/getConfigValue.js +83 -0
  31. package/lib/src/getCustomization.d.ts +4 -0
  32. package/lib/src/getCustomization.js +29 -0
  33. package/lib/src/getFieldCustomization.d.ts +7 -0
  34. package/lib/src/getFieldCustomization.js +3 -0
  35. package/lib/src/main.d.ts +60 -0
  36. package/lib/src/main.js +60 -0
  37. package/lib/src/operations/addInitialValues.d.ts +2 -0
  38. package/lib/src/operations/addInitialValues.js +27 -0
  39. package/lib/src/operations/addLowercaseFields.d.ts +2 -0
  40. package/lib/src/operations/addLowercaseFields.js +12 -0
  41. package/lib/src/operations/addRelationArrays.d.ts +2 -0
  42. package/lib/src/operations/addRelationArrays.js +60 -0
  43. package/lib/src/operations/addSystemFields.d.ts +2 -0
  44. package/lib/src/operations/addSystemFields.js +17 -0
  45. package/lib/src/operations/getDateRange.d.ts +5 -0
  46. package/lib/src/operations/getDateRange.js +56 -0
  47. package/lib/src/operations/getExtendedSchema.d.ts +2 -0
  48. package/lib/src/operations/getExtendedSchema.js +23 -0
  49. package/lib/src/operations/getFinalRecord.d.ts +1 -0
  50. package/lib/src/operations/getFinalRecord.js +11 -0
  51. package/lib/src/operations/getInputSchema.d.ts +15 -0
  52. package/lib/src/operations/getInputSchema.js +352 -0
  53. package/lib/src/operations/getLowercaseFields.d.ts +2 -0
  54. package/lib/src/operations/getLowercaseFields.js +15 -0
  55. package/lib/src/operations/getSingleFieldRelations.d.ts +2 -0
  56. package/lib/src/operations/getSingleFieldRelations.js +27 -0
  57. package/lib/src/operations/getZodSchema.d.ts +15 -0
  58. package/lib/src/operations/getZodSchema.js +303 -0
  59. package/lib/src/operations/isDeleteSentinel.d.ts +1 -0
  60. package/lib/src/operations/isDeleteSentinel.js +4 -0
  61. package/lib/src/operations/isSortingEnabled.d.ts +2 -0
  62. package/lib/src/operations/isSortingEnabled.js +7 -0
  63. package/lib/src/operations/isValidUniqueFieldValue.d.ts +1 -0
  64. package/lib/src/operations/isValidUniqueFieldValue.js +25 -0
  65. package/lib/src/operations/parseDate.d.ts +1 -0
  66. package/lib/src/operations/parseDate.js +4 -0
  67. package/lib/src/operations/prepareDenormalized.d.ts +8 -0
  68. package/lib/src/operations/prepareDenormalized.js +312 -0
  69. package/lib/src/operations/removeDeleteSentinels.d.ts +2 -0
  70. package/lib/src/operations/removeDeleteSentinels.js +15 -0
  71. package/lib/src/operations/removeDeletedFields.d.ts +2 -0
  72. package/lib/src/operations/removeDeletedFields.js +14 -0
  73. package/lib/src/operations/removeEmptyStrings.d.ts +2 -0
  74. package/lib/src/operations/removeEmptyStrings.js +14 -0
  75. package/lib/src/operations/removePrivateFields.d.ts +2 -0
  76. package/lib/src/operations/removePrivateFields.js +14 -0
  77. package/lib/src/operations/removeUndefined.d.ts +2 -0
  78. package/lib/src/operations/removeUndefined.js +14 -0
  79. package/lib/src/operations/retryOperation.d.ts +1 -0
  80. package/lib/src/operations/retryOperation.js +21 -0
  81. package/lib/src/operations/runHooks.d.ts +17 -0
  82. package/lib/src/operations/runHooks.js +18 -0
  83. package/lib/src/operations/sanitizeDownloadFilename.d.ts +1 -0
  84. package/lib/src/operations/sanitizeDownloadFilename.js +18 -0
  85. package/lib/src/operations/sanitizeEmailInput.d.ts +5 -0
  86. package/lib/src/operations/sanitizeEmailInput.js +73 -0
  87. package/lib/src/operations/updateFieldReference.d.ts +2 -0
  88. package/lib/src/operations/updateFieldReference.js +14 -0
  89. package/lib/src/operations/validateRecord.d.ts +2 -0
  90. package/lib/src/operations/validateRecord.js +18 -0
  91. package/lib/src/operations/validateStorageName.d.ts +1 -0
  92. package/lib/src/operations/validateStorageName.js +19 -0
  93. package/lib/src/schema/getAccessFields.d.ts +2 -0
  94. package/lib/src/schema/getAccessFields.js +62 -0
  95. package/lib/src/schema/getCollection.d.ts +2 -0
  96. package/lib/src/schema/getCollection.js +3 -0
  97. package/lib/src/schema/getDependencyFields.d.ts +6 -0
  98. package/lib/src/schema/getDependencyFields.js +22 -0
  99. package/lib/src/schema/getField.d.ts +2 -0
  100. package/lib/src/schema/getField.js +3 -0
  101. package/lib/src/schema/getFieldNames.d.ts +2 -0
  102. package/lib/src/schema/getFieldNames.js +3 -0
  103. package/lib/src/schema/getIndexFields.d.ts +9 -0
  104. package/lib/src/schema/getIndexFields.js +184 -0
  105. package/lib/src/schema/getInverseRelationType.d.ts +1 -0
  106. package/lib/src/schema/getInverseRelationType.js +15 -0
  107. package/lib/src/schema/getPathCollections.d.ts +2 -0
  108. package/lib/src/schema/getPathCollections.js +12 -0
  109. package/lib/src/schema/getRecordSystemFields.d.ts +2 -0
  110. package/lib/src/schema/getRecordSystemFields.js +11 -0
  111. package/lib/src/schema/getRelationLists.d.ts +5 -0
  112. package/lib/src/schema/getRelationLists.js +13 -0
  113. package/lib/src/schema/getSubcollections.d.ts +2 -0
  114. package/lib/src/schema/getSubcollections.js +9 -0
  115. package/lib/src/schema/getSystemFieldsSchema.d.ts +2 -0
  116. package/lib/src/schema/getSystemFieldsSchema.js +52 -0
  117. package/lib/src/schema/isDependencyField.d.ts +2 -0
  118. package/lib/src/schema/isDependencyField.js +18 -0
  119. package/lib/src/schema/isIncludedField.d.ts +2 -0
  120. package/lib/src/schema/isIncludedField.js +18 -0
  121. package/lib/src/schema/isRelationField.d.ts +2 -0
  122. package/lib/src/schema/isRelationField.js +3 -0
  123. package/lib/src/schema/system-fields.d.ts +2 -0
  124. package/lib/src/schema/system-fields.js +13 -0
  125. package/lib/tsconfig.tsbuildinfo +1 -0
  126. package/package.json +35 -0
@@ -0,0 +1,303 @@
1
+ import { z } from "zod";
2
+ import { isRelationField } from "../schema/isRelationField.js";
3
+ import { getSingleFieldRelations } from "./getSingleFieldRelations.js";
4
+ import { getLowercaseFields } from "./getLowercaseFields.js";
5
+ const isTimestamp = () => {
6
+ return z.any().refine((data) => {
7
+ return (data &&
8
+ ((data.seconds !== undefined && data.nanoseconds !== undefined) ||
9
+ (data._seconds !== undefined && data._nanoseconds !== undefined)));
10
+ }, {
11
+ message: "Value is not a valid timestamp",
12
+ });
13
+ };
14
+ const isServerTimestamp = () => {
15
+ return z
16
+ .any()
17
+ .refine((data) => data &&
18
+ (data._methodName === "serverTimestamp" || data.constructor.name === "ServerTimestampTransform"), {
19
+ message: "Value is not a valid server timestamp",
20
+ });
21
+ };
22
+ /* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
23
+ const isRelationSingle = (field, schema) => {
24
+ const includeFields = {};
25
+ if (field.includeFields) {
26
+ const relationCollection = schema.collections[field.collection];
27
+ if (!relationCollection)
28
+ return z.record(z.any());
29
+ field.includeFields.forEach((includeField) => {
30
+ const relationField = relationCollection.fields.find((field) => field.name === includeField);
31
+ if (!relationField) {
32
+ throw new Error(`Field ${includeField} not found in collection ${field.collection}`);
33
+ }
34
+ // eslint-disable-next-line security/detect-object-injection
35
+ includeFields[includeField] = getFieldSchema(relationCollection, relationField);
36
+ const lowercaseFields = getLowercaseFields(relationCollection, [relationField]);
37
+ if (lowercaseFields.size === 1) {
38
+ includeFields[`${includeField}_Lowercase`] = getFieldSchema(relationCollection, relationField, true);
39
+ }
40
+ });
41
+ }
42
+ return z.object({
43
+ Collection_Path: z.array(z.string()),
44
+ ...includeFields,
45
+ });
46
+ };
47
+ const isRelationObject = (field, schema) => {
48
+ let fieldSchema = z.record(isRelationSingle(field, schema));
49
+ if (!field.required) {
50
+ fieldSchema = fieldSchema.optional();
51
+ }
52
+ return fieldSchema;
53
+ };
54
+ const isRelationArray = (field) => {
55
+ let fieldSchema = z.array(z.union([z.string().length(20), z.string().length(28)]));
56
+ if (["OneToOne", "OneToMany"].includes(field.type)) {
57
+ fieldSchema = fieldSchema.max(1);
58
+ }
59
+ else {
60
+ if (field.min) {
61
+ fieldSchema = fieldSchema.min(field.min);
62
+ }
63
+ if (field.max) {
64
+ fieldSchema = fieldSchema.max(field.max);
65
+ }
66
+ if (field.length) {
67
+ fieldSchema = fieldSchema.length(field.length);
68
+ }
69
+ }
70
+ if (!field.required) {
71
+ fieldSchema = fieldSchema.optional();
72
+ }
73
+ else {
74
+ fieldSchema = fieldSchema.nonempty();
75
+ }
76
+ return fieldSchema;
77
+ };
78
+ const getFieldSchema = (collection, field, lowercase) => {
79
+ const { softDelete } = collection;
80
+ const softDeleteTimestampField = softDelete?.timestampField;
81
+ let fieldSchema;
82
+ switch (field.type) {
83
+ case "String":
84
+ fieldSchema = z.string();
85
+ if (field.length) {
86
+ fieldSchema = fieldSchema.length(field.length);
87
+ }
88
+ if (field.minlength) {
89
+ fieldSchema = fieldSchema.min(field.minlength);
90
+ }
91
+ if (field.maxlength) {
92
+ fieldSchema = fieldSchema.max(field.maxlength);
93
+ }
94
+ if (field.email) {
95
+ fieldSchema = fieldSchema.email();
96
+ }
97
+ if (field.uuid) {
98
+ fieldSchema = fieldSchema.uuid();
99
+ }
100
+ if (field.url) {
101
+ fieldSchema = fieldSchema.url();
102
+ }
103
+ if (field.emoji) {
104
+ fieldSchema = fieldSchema.emoji();
105
+ }
106
+ if (field.ip) {
107
+ fieldSchema = fieldSchema.ip();
108
+ }
109
+ if (field.pattern) {
110
+ // eslint-disable-next-line security/detect-non-literal-regexp
111
+ fieldSchema = fieldSchema.regex(new RegExp(field.pattern));
112
+ }
113
+ if (lowercase) {
114
+ fieldSchema = fieldSchema.toLowerCase();
115
+ }
116
+ if (field.values) {
117
+ if (lowercase) {
118
+ const lowercaseValues = field.values.map((value) => value.toLowerCase());
119
+ fieldSchema = z.enum(lowercaseValues);
120
+ }
121
+ else {
122
+ fieldSchema = z.enum(field.values);
123
+ }
124
+ }
125
+ break;
126
+ case "Boolean":
127
+ fieldSchema = z.boolean();
128
+ break;
129
+ case "Number":
130
+ if (field.autoIncrement) {
131
+ fieldSchema = z.union([z.literal("Pending"), z.number().int()]);
132
+ }
133
+ else {
134
+ fieldSchema = z.number();
135
+ if (field.min) {
136
+ fieldSchema = fieldSchema.min(field.min);
137
+ }
138
+ if (field.max) {
139
+ fieldSchema = fieldSchema.max(field.max);
140
+ }
141
+ if (!field.decimal) {
142
+ fieldSchema = fieldSchema.int();
143
+ }
144
+ else {
145
+ fieldSchema = fieldSchema.refine((data) => {
146
+ if (!field.decimal)
147
+ return false;
148
+ const decimalPlaces = data.toString().split(".")[1]?.length || 0;
149
+ return decimalPlaces <= field.decimal;
150
+ }, {
151
+ message: `Value must have ${field.decimal} or fewer decimal places`,
152
+ });
153
+ }
154
+ if (field.values) {
155
+ fieldSchema = fieldSchema.refine((data) => field.values?.includes(data), {
156
+ message: "Value is not an allowed value",
157
+ });
158
+ }
159
+ }
160
+ break;
161
+ case "Timestamp":
162
+ if (field.name === softDeleteTimestampField) {
163
+ fieldSchema = z
164
+ .any()
165
+ .refine((data) => data &&
166
+ (data._methodName === "serverTimestamp" ||
167
+ data.constructor.name === "ServerTimestampTransform" ||
168
+ (data.seconds !== undefined && data.nanoseconds !== undefined) ||
169
+ (data._seconds !== undefined && data._nanoseconds !== undefined)), {
170
+ message: "Value is not a valid timestamp",
171
+ });
172
+ }
173
+ else {
174
+ fieldSchema = isTimestamp();
175
+ if (field.min) {
176
+ fieldSchema = fieldSchema.refine((data) => data.toMillis() >= field.min, {
177
+ message: `Value is less than the minimum allowed value of ${field.min}`,
178
+ });
179
+ }
180
+ if (field.max) {
181
+ fieldSchema = fieldSchema.refine((data) => data.toMillis() <= field.max, {
182
+ message: `Value is greater than the maximum allowed value of ${field.max}`,
183
+ });
184
+ }
185
+ }
186
+ break;
187
+ case "Array":
188
+ fieldSchema = z.array(z.any());
189
+ if (field.length) {
190
+ fieldSchema = fieldSchema.length(field.length);
191
+ }
192
+ if (field.minlength) {
193
+ fieldSchema = fieldSchema.min(field.minlength);
194
+ }
195
+ else if (field.required) {
196
+ fieldSchema = fieldSchema.nonempty();
197
+ }
198
+ if (field.maxlength) {
199
+ fieldSchema = fieldSchema.max(field.maxlength);
200
+ }
201
+ if (field.values) {
202
+ fieldSchema = fieldSchema.refine((data) => {
203
+ let valid = true;
204
+ data.forEach((value) => {
205
+ if (field.values && !field.values.includes(value)) {
206
+ valid = false;
207
+ }
208
+ });
209
+ return valid;
210
+ }, { message: "Value is not an allowed value" });
211
+ }
212
+ break;
213
+ case "Map":
214
+ fieldSchema = z.record(z.any());
215
+ if (field.required) {
216
+ fieldSchema = fieldSchema.refine((data) => data && typeof data === "object" && Object.keys(data).length > 0, {
217
+ message: "Value must have at least one object property",
218
+ });
219
+ }
220
+ break;
221
+ case "Embedding":
222
+ fieldSchema = z.any();
223
+ break;
224
+ }
225
+ if (!isRelationField(field) && field.nullable) {
226
+ fieldSchema = fieldSchema.nullable();
227
+ }
228
+ if (!field.required) {
229
+ fieldSchema = fieldSchema.optional();
230
+ }
231
+ return fieldSchema;
232
+ };
233
+ export const getZodSchema = (operation, collection, schema) => {
234
+ const fields = {
235
+ Collection_Path: z.array(z.string()),
236
+ Last_Write_App: z.string(),
237
+ Last_Write_At: isTimestamp(),
238
+ Last_Save_At: isServerTimestamp(),
239
+ Last_Write_By: z.union([z.string().length(28), z.literal("System")]),
240
+ Last_Write_Connection_Status: z.enum(["Online", "Offline"]),
241
+ Last_Write_Version: z.number().int(),
242
+ id: z.string().regex(new RegExp("^[a-zA-Z0-9]+$")).length(20),
243
+ Created_At: isTimestamp(),
244
+ Created_By: z.union([z.string().length(28), z.literal("System")]),
245
+ };
246
+ if (operation === "create") {
247
+ fields.Saved_At = isServerTimestamp();
248
+ }
249
+ if (operation === "update") {
250
+ fields.Saved_At = isTimestamp();
251
+ fields.Collection_Path = fields.Collection_Path.optional();
252
+ fields.id = fields.id.optional();
253
+ fields.Created_At = fields.Created_At.optional();
254
+ fields.Saved_At = fields.Saved_At.optional();
255
+ fields.Created_By = fields.Created_By.optional();
256
+ }
257
+ const singleFieldRelations = getSingleFieldRelations(collection, collection.fields);
258
+ const singleFieldRelationsNames = Array.from(singleFieldRelations).map((field) => field.name);
259
+ collection.fields.forEach((field) => {
260
+ if (isRelationField(field)) {
261
+ fields[field.name] = isRelationObject(field, schema);
262
+ fields[`${field.name}_Array`] = isRelationArray(field);
263
+ if (singleFieldRelationsNames.includes(field.name)) {
264
+ fields[`${field.name}_Single`] = isRelationSingle(field, schema);
265
+ if (!field.required) {
266
+ fields[`${field.name}_Single`] = fields[`${field.name}_Single`].optional();
267
+ }
268
+ }
269
+ if (field.length) {
270
+ fields[field.name] = fields[field.name].refine((data) => field.length && data && Object.keys(data).length === field.length, {
271
+ message: `Value must contain ${field.length} item(s)`,
272
+ });
273
+ }
274
+ if (field.min) {
275
+ fields[field.name] = fields[field.name].refine((data) => field.min && data && Object.keys(data).length >= field.min, {
276
+ message: `Value must contain at least ${field.min} item(s)`,
277
+ });
278
+ }
279
+ if (field.max) {
280
+ fields[field.name] = fields[field.name].refine((data) => field.max && (!data || Object.keys(data).length <= field.max), {
281
+ message: `Value must contain at most ${field.max} item(s)`,
282
+ });
283
+ }
284
+ }
285
+ else if (field.type !== "Computed") {
286
+ fields[field.name] = getFieldSchema(collection, field);
287
+ }
288
+ });
289
+ const lowercaseFields = getLowercaseFields(collection, collection.fields);
290
+ lowercaseFields.forEach((field) => {
291
+ if (fields[field.name]) {
292
+ fields[`${field.name}_Lowercase`] = getFieldSchema(collection, field, true);
293
+ }
294
+ });
295
+ const record = z.object(fields);
296
+ if (collection.allowSchemalessFields) {
297
+ return record.passthrough();
298
+ }
299
+ else {
300
+ return record.strict();
301
+ }
302
+ };
303
+ /* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-non-null-assertion */
@@ -0,0 +1 @@
1
+ export declare const isDeleteSentinel: (value: any) => any;
@@ -0,0 +1,4 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2
+ export const isDeleteSentinel = (value) => {
3
+ return value && (value._methodName === "deleteField" || value.constructor.name === "DeleteTransform");
4
+ };
@@ -0,0 +1,2 @@
1
+ import { CollectionField, StokerPermissions } from "@stoker-platform/types";
2
+ export declare function isSortingEnabled(field: CollectionField, permissions: StokerPermissions | null): boolean | undefined;
@@ -0,0 +1,7 @@
1
+ export function isSortingEnabled(field, permissions) {
2
+ if (!permissions?.Role)
3
+ throw new Error("PERMISSION_DENIED");
4
+ return (field.sorting &&
5
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
6
+ (field.sorting === true || !field.sorting.roles || field.sorting.roles.includes(permissions.Role)));
7
+ }
@@ -0,0 +1 @@
1
+ export declare const isValidUniqueFieldValue: (input: string | number) => boolean;
@@ -0,0 +1,25 @@
1
+ export const isValidUniqueFieldValue = (input) => {
2
+ input = input.toString();
3
+ // Check for invalid characters or patterns
4
+ const invalidPattern = /[/]|^\.+$|^__.*__$/;
5
+ if (invalidPattern.test(input)) {
6
+ return false;
7
+ }
8
+ // Check for valid UTF-8 by encoding and decoding the string
9
+ try {
10
+ const encoded = new TextEncoder().encode(input);
11
+ const decoded = new TextDecoder().decode(encoded);
12
+ if (input !== decoded) {
13
+ return false;
14
+ }
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ // Check for length in bytes
20
+ const lengthInBytes = new Blob([input]).size;
21
+ if (lengthInBytes > 1500) {
22
+ return false;
23
+ }
24
+ return true;
25
+ };
@@ -0,0 +1 @@
1
+ export declare const parseDate: (dateString: string) => number;
@@ -0,0 +1,4 @@
1
+ import { DateTime } from "luxon";
2
+ export const parseDate = (dateString) => {
3
+ return DateTime.fromFormat(dateString, "MMMM d, yyyy '@' h:mm a").toMillis();
4
+ };
@@ -0,0 +1,8 @@
1
+ import { CollectionField, CollectionSchema, CollectionsSchema, RelationField, StokerCollection, StokerRecord, StokerRole } from "@stoker-platform/types";
2
+ export declare const prepareDenormalized: (operation: "create" | "update" | "delete", batch: any, path: string[], docId: string, record: StokerRecord, schema: CollectionsSchema, collectionSchema: CollectionSchema, options: any, allRoleGroups: Record<StokerCollection, Set<{
3
+ key: string;
4
+ roles: StokerRole[];
5
+ fields: CollectionField[];
6
+ }>>, arrayUnion: (docid: string) => unknown, arrayRemove: (docid: string) => unknown, deleteField: () => unknown, dependencyRef: (field: CollectionField) => unknown, uniqueRef: (field: CollectionField, uniqueValue: string) => unknown, privateRef: (role: StokerRole) => unknown, twoWayIncludeRef: (path: string[], id: string) => unknown, twoWayDependencyRef: (field: RelationField, dependencyField: string, id: string) => unknown, twoWayPrivateRef: (field: RelationField, role: StokerRole, id: string) => unknown, originalRecord?: StokerRecord, noDelete?: Map<string, string[]>, batchSize?: {
7
+ size: number;
8
+ }) => void;