@unchainedshop/core 4.6.0 → 4.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bulk-exporter/createBulkExporter.d.ts +33 -0
- package/lib/bulk-exporter/createBulkExporter.js +46 -0
- package/lib/bulk-exporter/handlers/exportAssortmentsHandler.d.ts +38 -0
- package/lib/bulk-exporter/handlers/exportAssortmentsHandler.js +137 -0
- package/lib/bulk-exporter/handlers/exportFiltersHandler.d.ts +26 -0
- package/lib/bulk-exporter/handlers/exportFiltersHandler.js +88 -0
- package/lib/bulk-exporter/handlers/exportProductsHandler.d.ts +40 -0
- package/lib/bulk-exporter/handlers/exportProductsHandler.js +238 -0
- package/lib/bulk-exporter/handlers/exportUsersHandler.d.ts +40 -0
- package/lib/bulk-exporter/handlers/exportUsersHandler.js +340 -0
- package/lib/bulk-exporter/handlers/generateCSVFileAndUrl.d.ts +13 -0
- package/lib/bulk-exporter/handlers/generateCSVFileAndUrl.js +21 -0
- package/lib/bulk-exporter/handlers/toCSV.d.ts +2 -0
- package/lib/bulk-exporter/handlers/toCSV.js +5 -0
- package/lib/bulk-exporter/index.d.ts +3 -0
- package/lib/bulk-exporter/index.js +3 -0
- package/lib/core-index.d.ts +7 -1
- package/lib/core-index.js +5 -1
- package/lib/directors/FileDirector.d.ts +10 -0
- package/lib/directors/FileDirector.js +25 -0
- package/lib/directors/WorkerAdapter.d.ts +2 -0
- package/lib/errors/common.d.ts +568 -0
- package/lib/errors/common.js +789 -0
- package/lib/errors/index.d.ts +1 -0
- package/lib/errors/index.js +1 -0
- package/lib/plugins/PluginRegistry.d.ts +42 -0
- package/lib/plugins/PluginRegistry.js +113 -0
- package/lib/services/addCartDiscount.d.ts +10 -0
- package/lib/services/addCartDiscount.js +27 -0
- package/lib/services/addCartItem.d.ts +15 -0
- package/lib/services/addCartItem.js +41 -0
- package/lib/services/addCartQuotation.d.ts +16 -0
- package/lib/services/addCartQuotation.js +52 -0
- package/lib/services/addEmail.d.ts +7 -0
- package/lib/services/addEmail.js +17 -0
- package/lib/services/addProductAssignment.d.ts +3 -0
- package/lib/services/addProductAssignment.js +63 -0
- package/lib/services/authenticateWithPassword.d.ts +15 -0
- package/lib/services/authenticateWithPassword.js +34 -0
- package/lib/services/changePassword.d.ts +10 -0
- package/lib/services/changePassword.js +19 -0
- package/lib/services/countOrdersWithFilters.d.ts +3 -0
- package/lib/services/countOrdersWithFilters.js +25 -0
- package/lib/services/createAssortment.d.ts +7 -0
- package/lib/services/createAssortment.js +10 -0
- package/lib/services/createBookmark.d.ts +8 -0
- package/lib/services/createBookmark.js +21 -0
- package/lib/services/createDeliveryProvider.d.ts +6 -0
- package/lib/services/createDeliveryProvider.js +19 -0
- package/lib/services/createEnrollment.d.ts +17 -0
- package/lib/services/createEnrollment.js +33 -0
- package/lib/services/createProduct.d.ts +7 -0
- package/lib/services/createProduct.js +8 -0
- package/lib/services/createProductBundleItem.d.ts +5 -0
- package/lib/services/createProductBundleItem.js +25 -0
- package/lib/services/createProductReview.d.ts +8 -0
- package/lib/services/createProductReview.js +12 -0
- package/lib/services/deliverOrder.d.ts +5 -0
- package/lib/services/deliverOrder.js +26 -0
- package/lib/services/findActiveWorkTypes.d.ts +2 -0
- package/lib/services/findActiveWorkTypes.js +6 -0
- package/lib/services/findDeliveryInterfaces.d.ts +7 -0
- package/lib/services/findDeliveryInterfaces.js +13 -0
- package/lib/services/findOrdersWithFilters.d.ts +9 -0
- package/lib/services/findOrdersWithFilters.js +25 -0
- package/lib/services/findPaymentInterfaces.d.ts +7 -0
- package/lib/services/findPaymentInterfaces.js +13 -0
- package/lib/services/findWarehousingInterfaces.d.ts +7 -0
- package/lib/services/findWarehousingInterfaces.js +13 -0
- package/lib/services/getDeliveryDiscounts.d.ts +8 -0
- package/lib/services/getDeliveryDiscounts.js +14 -0
- package/lib/services/getPaymentDiscounts.d.ts +8 -0
- package/lib/services/getPaymentDiscounts.js +14 -0
- package/lib/services/getShopInfo.d.ts +25 -0
- package/lib/services/getShopInfo.js +47 -0
- package/lib/services/impersonateUser.d.ts +8 -0
- package/lib/services/impersonateUser.js +20 -0
- package/lib/services/loginAsGuest.d.ts +10 -0
- package/lib/services/loginAsGuest.js +19 -0
- package/lib/services/obfuscateWorkerData.d.ts +4 -0
- package/lib/services/obfuscateWorkerData.js +4 -0
- package/lib/services/orderPricingAccessors.d.ts +18 -0
- package/lib/services/orderPricingAccessors.js +29 -0
- package/lib/services/payOrder.d.ts +5 -0
- package/lib/services/payOrder.js +25 -0
- package/lib/services/registerUser.d.ts +14 -0
- package/lib/services/registerUser.js +44 -0
- package/lib/services/removeBookmark.d.ts +6 -0
- package/lib/services/removeBookmark.js +10 -0
- package/lib/services/removeCartItem.d.ts +6 -0
- package/lib/services/removeCartItem.js +19 -0
- package/lib/services/resetPasswordWithMigration.d.ts +14 -0
- package/lib/services/resetPasswordWithMigration.js +31 -0
- package/lib/services/resolveWorkType.d.ts +1 -0
- package/lib/services/resolveWorkType.js +7 -0
- package/lib/services/searchProductsWithAssortment.d.ts +19 -0
- package/lib/services/searchProductsWithAssortment.js +17 -0
- package/lib/services/toggleBookmark.d.ts +8 -0
- package/lib/services/toggleBookmark.js +33 -0
- package/lib/services/updateCart.d.ts +15 -0
- package/lib/services/updateCart.js +27 -0
- package/lib/services/updateCartItem.d.ts +11 -0
- package/lib/services/updateCartItem.js +37 -0
- package/lib/services/updateEnrollment.d.ts +13 -0
- package/lib/services/updateEnrollment.js +36 -0
- package/lib/services/verifyEmailWithMigration.d.ts +15 -0
- package/lib/services/verifyEmailWithMigration.js +23 -0
- package/lib/utils/getFileAdapter.d.ts +1 -0
- package/lib/utils/getFileAdapter.js +7 -0
- package/package.json +1 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { UnchainedCore } from '../../core-index.ts';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const UserExportPayloadSchema: z.ZodObject<{
|
|
4
|
+
exportReviews: z.ZodOptional<z.ZodBoolean>;
|
|
5
|
+
exportOrders: z.ZodOptional<z.ZodBoolean>;
|
|
6
|
+
exportBookmarks: z.ZodOptional<z.ZodBoolean>;
|
|
7
|
+
exportEvents: z.ZodOptional<z.ZodBoolean>;
|
|
8
|
+
exportQuotations: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
exportEnrollments: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
userId: z.ZodOptional<z.ZodString>;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export interface UserExportParams {
|
|
13
|
+
exportReviews?: boolean;
|
|
14
|
+
exportOrders?: boolean;
|
|
15
|
+
exportBookmarks?: boolean;
|
|
16
|
+
exportEvents?: boolean;
|
|
17
|
+
exportQuotations?: boolean;
|
|
18
|
+
exportEnrollments?: boolean;
|
|
19
|
+
userId: string;
|
|
20
|
+
}
|
|
21
|
+
declare const exportUsersHandler: {
|
|
22
|
+
({ userId, ...options }: UserExportParams, _: any, unchainedAPI: UnchainedCore): Promise<{
|
|
23
|
+
user: import("./generateCSVFileAndUrl.ts").CSVFileResult;
|
|
24
|
+
bookmarks: import("./generateCSVFileAndUrl.ts").CSVFileResult | null;
|
|
25
|
+
orders: import("./generateCSVFileAndUrl.ts").CSVFileResult | null;
|
|
26
|
+
reviews: import("./generateCSVFileAndUrl.ts").CSVFileResult | null;
|
|
27
|
+
quotations: import("./generateCSVFileAndUrl.ts").CSVFileResult | null;
|
|
28
|
+
enrollments: import("./generateCSVFileAndUrl.ts").CSVFileResult | null;
|
|
29
|
+
}>;
|
|
30
|
+
payloadSchema: z.ZodObject<{
|
|
31
|
+
exportReviews: z.ZodOptional<z.ZodBoolean>;
|
|
32
|
+
exportOrders: z.ZodOptional<z.ZodBoolean>;
|
|
33
|
+
exportBookmarks: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
exportEvents: z.ZodOptional<z.ZodBoolean>;
|
|
35
|
+
exportQuotations: z.ZodOptional<z.ZodBoolean>;
|
|
36
|
+
exportEnrollments: z.ZodOptional<z.ZodBoolean>;
|
|
37
|
+
userId: z.ZodOptional<z.ZodString>;
|
|
38
|
+
}, z.core.$strip>;
|
|
39
|
+
};
|
|
40
|
+
export default exportUsersHandler;
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import generateCSVFileAndURL from "./generateCSVFileAndUrl.js";
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { EXPORTS_DIRECTORY } from "../createBulkExporter.js";
|
|
4
|
+
export const UserExportPayloadSchema = z.object({
|
|
5
|
+
exportReviews: z.boolean().optional(),
|
|
6
|
+
exportOrders: z.boolean().optional(),
|
|
7
|
+
exportBookmarks: z.boolean().optional(),
|
|
8
|
+
exportEvents: z.boolean().optional(),
|
|
9
|
+
exportQuotations: z.boolean().optional(),
|
|
10
|
+
exportEnrollments: z.boolean().optional(),
|
|
11
|
+
userId: z.string().optional(),
|
|
12
|
+
});
|
|
13
|
+
const USER_CSV_SCHEMA = {
|
|
14
|
+
userFields: [
|
|
15
|
+
'_id',
|
|
16
|
+
'emailAddresses',
|
|
17
|
+
'tags',
|
|
18
|
+
'roles',
|
|
19
|
+
'username',
|
|
20
|
+
'created',
|
|
21
|
+
'isGuest',
|
|
22
|
+
'displayName',
|
|
23
|
+
'birthday',
|
|
24
|
+
'phoneMobile',
|
|
25
|
+
'gender',
|
|
26
|
+
'address.addressLine',
|
|
27
|
+
'address.addressLine2',
|
|
28
|
+
'address.city',
|
|
29
|
+
'address.company',
|
|
30
|
+
'address.countryCode',
|
|
31
|
+
'address.firstName',
|
|
32
|
+
'address.lastName',
|
|
33
|
+
'address.postalCode',
|
|
34
|
+
'address.regionCode',
|
|
35
|
+
'meta',
|
|
36
|
+
'lastBillingAddress',
|
|
37
|
+
'lastContact',
|
|
38
|
+
'lastLogin',
|
|
39
|
+
],
|
|
40
|
+
bookmarkFields: ['_id', 'productId', 'userId'],
|
|
41
|
+
orderFields: [
|
|
42
|
+
'_id',
|
|
43
|
+
'userId',
|
|
44
|
+
'orderNumber',
|
|
45
|
+
'status',
|
|
46
|
+
'billingAddress',
|
|
47
|
+
'contact',
|
|
48
|
+
'countryCode',
|
|
49
|
+
'currencyCode',
|
|
50
|
+
'deliveryId',
|
|
51
|
+
'paymentId',
|
|
52
|
+
'confirmed',
|
|
53
|
+
'ordered',
|
|
54
|
+
'fulfilled',
|
|
55
|
+
'products',
|
|
56
|
+
],
|
|
57
|
+
reviewFields: [
|
|
58
|
+
'_id',
|
|
59
|
+
'productId',
|
|
60
|
+
'authorId',
|
|
61
|
+
'rating',
|
|
62
|
+
'title',
|
|
63
|
+
'review',
|
|
64
|
+
'vote.type',
|
|
65
|
+
'vote.timestamp',
|
|
66
|
+
'vote.meta',
|
|
67
|
+
'meta',
|
|
68
|
+
],
|
|
69
|
+
quotationFields: [
|
|
70
|
+
'_id',
|
|
71
|
+
'userId',
|
|
72
|
+
'quotationNumber',
|
|
73
|
+
'productId',
|
|
74
|
+
'status',
|
|
75
|
+
'price',
|
|
76
|
+
'expires',
|
|
77
|
+
'fulfilled',
|
|
78
|
+
'rejected',
|
|
79
|
+
'deleted',
|
|
80
|
+
'meta',
|
|
81
|
+
'configuration',
|
|
82
|
+
],
|
|
83
|
+
enrollmentFields: [
|
|
84
|
+
'_id',
|
|
85
|
+
'userId',
|
|
86
|
+
'productId',
|
|
87
|
+
'enrollmentNumber',
|
|
88
|
+
'status',
|
|
89
|
+
'countryCode',
|
|
90
|
+
'currencyCode',
|
|
91
|
+
'quantity',
|
|
92
|
+
'created',
|
|
93
|
+
'deleted',
|
|
94
|
+
'expires',
|
|
95
|
+
'configuration',
|
|
96
|
+
'billingAddress',
|
|
97
|
+
'contact.emailAddress',
|
|
98
|
+
'contact.telNumber',
|
|
99
|
+
'delivery.providerId',
|
|
100
|
+
'payment.providerId',
|
|
101
|
+
'delivery.meta',
|
|
102
|
+
'payment.meta',
|
|
103
|
+
'meta',
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
const exportUsersHandler = async ({ userId, ...options }, _, unchainedAPI) => {
|
|
107
|
+
const { modules } = unchainedAPI;
|
|
108
|
+
const user = await modules.users.findUserById(userId);
|
|
109
|
+
const userRows = [];
|
|
110
|
+
const orderRows = [];
|
|
111
|
+
const bookmarkRows = [];
|
|
112
|
+
const quotationRows = [];
|
|
113
|
+
const reviewRows = [];
|
|
114
|
+
const enrollmentRows = [];
|
|
115
|
+
if (!user)
|
|
116
|
+
throw new Error(`User with ID ${userId} not found`);
|
|
117
|
+
userRows.push({
|
|
118
|
+
_id: user._id,
|
|
119
|
+
emailAddresses: user.emails ? user.emails.map((email) => email.address).join('; ') : '',
|
|
120
|
+
created: new Date(user.created).getTime(),
|
|
121
|
+
isGuest: user.guest || false,
|
|
122
|
+
tags: user.tags ? user.tags.join('; ') : '',
|
|
123
|
+
roles: user.roles ? user.roles.join('; ') : '',
|
|
124
|
+
username: user.username || '',
|
|
125
|
+
displayName: user.profile?.displayName || '',
|
|
126
|
+
birthday: user.profile?.birthday ? new Date(user.profile?.birthday).getTime() : '',
|
|
127
|
+
phoneMobile: user.profile?.phoneMobile || '',
|
|
128
|
+
gender: user.profile?.gender || '',
|
|
129
|
+
'address.addressLine': user.profile?.address?.addressLine || '',
|
|
130
|
+
'address.addressLine2': user.profile?.address?.addressLine2 || '',
|
|
131
|
+
'address.city': user.profile?.address?.city || '',
|
|
132
|
+
'address.company': user.profile?.address?.company || '',
|
|
133
|
+
'address.countryCode': user.profile?.address?.countryCode || '',
|
|
134
|
+
'address.firstName': user.profile?.address?.firstName || '',
|
|
135
|
+
'address.lastName': user.profile?.address?.lastName || '',
|
|
136
|
+
'address.postalCode': user.profile?.address?.postalCode || '',
|
|
137
|
+
'address.regionCode': user.profile?.address?.regionCode || '',
|
|
138
|
+
meta: user.meta ? JSON.stringify(user.meta) : '',
|
|
139
|
+
lastBillingAddress: user.lastBillingAddress ? JSON.stringify(user.lastBillingAddress) : '',
|
|
140
|
+
lastContact: user.lastContact ? JSON.stringify(user.lastContact) : '',
|
|
141
|
+
lastLogin: user.lastLogin ? JSON.stringify(user.lastLogin) : '',
|
|
142
|
+
});
|
|
143
|
+
if (options.exportBookmarks) {
|
|
144
|
+
const bookmarks = await modules.bookmarks.findBookmarksByUserId(userId);
|
|
145
|
+
for (const bookmark of bookmarks) {
|
|
146
|
+
const row = {};
|
|
147
|
+
USER_CSV_SCHEMA.bookmarkFields.forEach((field) => {
|
|
148
|
+
row[field] = bookmark[field] || '';
|
|
149
|
+
});
|
|
150
|
+
bookmarkRows.push(row);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
if (options.exportOrders) {
|
|
154
|
+
const orders = await modules.orders.findOrders({ userId });
|
|
155
|
+
for await (const order of orders) {
|
|
156
|
+
const positions = await modules.orders.positions.findOrderPositions({ orderId: order._id });
|
|
157
|
+
const row = {};
|
|
158
|
+
USER_CSV_SCHEMA.orderFields.forEach((field) => {
|
|
159
|
+
if ((field === 'ordered' || field === 'confirmed' || field === 'fulfilled') && order[field]) {
|
|
160
|
+
row[field] = new Date(order[field]).getTime();
|
|
161
|
+
}
|
|
162
|
+
else if (field === 'products') {
|
|
163
|
+
row[field] = positions.map((pos) => `${pos.productId}~${pos.quantity}`).join('; ');
|
|
164
|
+
}
|
|
165
|
+
else if (field === 'billingAddress' && order.billingAddress) {
|
|
166
|
+
row[field] = JSON.stringify(order.billingAddress);
|
|
167
|
+
}
|
|
168
|
+
else if (field === 'contact' && order.contact) {
|
|
169
|
+
row[field] = JSON.stringify(order.contact);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
row[field] = order[field] || '';
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
orderRows.push(row);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (options.exportReviews) {
|
|
179
|
+
const reviews = await modules.products.reviews.findProductReviews({
|
|
180
|
+
authorId: userId,
|
|
181
|
+
});
|
|
182
|
+
for (const review of reviews) {
|
|
183
|
+
const row = {};
|
|
184
|
+
USER_CSV_SCHEMA.reviewFields.forEach((field) => {
|
|
185
|
+
if (field.startsWith('vote.')) {
|
|
186
|
+
const voteField = field.split('.')[1];
|
|
187
|
+
if (voteField === 'timestamp' && review.votes[0][voteField]) {
|
|
188
|
+
row[field] = new Date(review.votes[0][voteField]).getTime();
|
|
189
|
+
}
|
|
190
|
+
else if (voteField === 'meta' && review.votes[0][voteField]) {
|
|
191
|
+
row[field] = JSON.stringify(review.votes[0][voteField]);
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
row[field] = review.votes[0][voteField] || '';
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
if (field === 'meta' && review.meta) {
|
|
199
|
+
row[field] = JSON.stringify(review.meta);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
row[field] = review[field] || '';
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
reviewRows.push(row);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (options.exportQuotations) {
|
|
210
|
+
const quotations = await modules.quotations.findQuotations({
|
|
211
|
+
userId,
|
|
212
|
+
});
|
|
213
|
+
for (const quotation of quotations) {
|
|
214
|
+
const row = {};
|
|
215
|
+
USER_CSV_SCHEMA.quotationFields.forEach((field) => {
|
|
216
|
+
if ((field === 'expires' ||
|
|
217
|
+
field === 'fulfilled' ||
|
|
218
|
+
field === 'rejected' ||
|
|
219
|
+
field === 'deleted') &&
|
|
220
|
+
quotation[field]) {
|
|
221
|
+
row[field] = new Date(quotation[field]).getTime();
|
|
222
|
+
}
|
|
223
|
+
else if (field === 'configuration' || (field === 'meta' && quotation[field])) {
|
|
224
|
+
row[field] = JSON.stringify(quotation.configuration);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
row[field] = quotation[field] || '';
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
quotationRows.push(row);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (options.exportEnrollments) {
|
|
234
|
+
const enrollments = await modules.enrollments.findEnrollments({
|
|
235
|
+
userId,
|
|
236
|
+
});
|
|
237
|
+
for (const enrollment of enrollments) {
|
|
238
|
+
const row = {};
|
|
239
|
+
USER_CSV_SCHEMA.enrollmentFields.forEach((field) => {
|
|
240
|
+
if ((field === 'created' || field === 'deleted' || field === 'expires') && enrollment[field]) {
|
|
241
|
+
row[field] = new Date(enrollment[field]).getTime();
|
|
242
|
+
}
|
|
243
|
+
else if (field === 'billingAddress' && enrollment[field]) {
|
|
244
|
+
row[field] = JSON.stringify(enrollment[field]);
|
|
245
|
+
}
|
|
246
|
+
else if (field === 'contact.emailAddress' && enrollment.contact) {
|
|
247
|
+
row[field] = enrollment.contact.emailAddress || '';
|
|
248
|
+
}
|
|
249
|
+
else if (field === 'contact.telNumber' && enrollment.contact) {
|
|
250
|
+
row[field] = enrollment.contact.telNumber || '';
|
|
251
|
+
}
|
|
252
|
+
else if (field === 'delivery.providerId' && enrollment.delivery) {
|
|
253
|
+
row[field] = enrollment.delivery.deliveryProviderId || '';
|
|
254
|
+
}
|
|
255
|
+
else if (field === 'payment.providerId' && enrollment.payment) {
|
|
256
|
+
row[field] = enrollment.payment.paymentProviderId || '';
|
|
257
|
+
}
|
|
258
|
+
else if (field === 'delivery.meta' && enrollment.delivery) {
|
|
259
|
+
row[field] = enrollment.delivery.meta
|
|
260
|
+
? JSON.stringify(enrollment.delivery.meta)
|
|
261
|
+
: '';
|
|
262
|
+
}
|
|
263
|
+
else if (field === 'payment.meta' && enrollment.payment) {
|
|
264
|
+
row[field] = enrollment.payment.meta
|
|
265
|
+
? JSON.stringify(enrollment.payment.meta)
|
|
266
|
+
: '';
|
|
267
|
+
}
|
|
268
|
+
else if (field === 'configuration' || (field === 'meta' && enrollment[field])) {
|
|
269
|
+
row[field] = JSON.stringify(enrollment.configuration);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
row[field] = enrollment[field] || '';
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
enrollmentRows.push(row);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const userCSV = await generateCSVFileAndURL({
|
|
279
|
+
headers: USER_CSV_SCHEMA.userFields,
|
|
280
|
+
rows: userRows,
|
|
281
|
+
directoryName: EXPORTS_DIRECTORY,
|
|
282
|
+
fileName: 'user_export.csv',
|
|
283
|
+
unchainedAPI,
|
|
284
|
+
});
|
|
285
|
+
const reviewCSV = options.exportReviews
|
|
286
|
+
? await generateCSVFileAndURL({
|
|
287
|
+
headers: USER_CSV_SCHEMA.reviewFields,
|
|
288
|
+
rows: reviewRows,
|
|
289
|
+
directoryName: EXPORTS_DIRECTORY,
|
|
290
|
+
fileName: 'user_reviews_export.csv',
|
|
291
|
+
unchainedAPI,
|
|
292
|
+
})
|
|
293
|
+
: null;
|
|
294
|
+
const quotationCSV = options.exportQuotations
|
|
295
|
+
? await generateCSVFileAndURL({
|
|
296
|
+
headers: USER_CSV_SCHEMA.quotationFields,
|
|
297
|
+
rows: quotationRows,
|
|
298
|
+
directoryName: EXPORTS_DIRECTORY,
|
|
299
|
+
fileName: 'user_quotations_export.csv',
|
|
300
|
+
unchainedAPI,
|
|
301
|
+
})
|
|
302
|
+
: null;
|
|
303
|
+
const bookmarksCSV = options.exportBookmarks
|
|
304
|
+
? await generateCSVFileAndURL({
|
|
305
|
+
headers: USER_CSV_SCHEMA.bookmarkFields,
|
|
306
|
+
rows: bookmarkRows,
|
|
307
|
+
directoryName: EXPORTS_DIRECTORY,
|
|
308
|
+
fileName: 'user_bookmarks_export.csv',
|
|
309
|
+
unchainedAPI,
|
|
310
|
+
})
|
|
311
|
+
: null;
|
|
312
|
+
const ordersCSV = options.exportOrders
|
|
313
|
+
? await generateCSVFileAndURL({
|
|
314
|
+
headers: USER_CSV_SCHEMA.orderFields,
|
|
315
|
+
rows: orderRows,
|
|
316
|
+
directoryName: EXPORTS_DIRECTORY,
|
|
317
|
+
fileName: 'user_orders_export.csv',
|
|
318
|
+
unchainedAPI,
|
|
319
|
+
})
|
|
320
|
+
: null;
|
|
321
|
+
const enrollmentCSV = options.exportEnrollments
|
|
322
|
+
? await generateCSVFileAndURL({
|
|
323
|
+
headers: USER_CSV_SCHEMA.enrollmentFields,
|
|
324
|
+
rows: enrollmentRows,
|
|
325
|
+
directoryName: EXPORTS_DIRECTORY,
|
|
326
|
+
fileName: 'user_enrollments_export.csv',
|
|
327
|
+
unchainedAPI,
|
|
328
|
+
})
|
|
329
|
+
: null;
|
|
330
|
+
return {
|
|
331
|
+
user: userCSV,
|
|
332
|
+
bookmarks: bookmarksCSV,
|
|
333
|
+
orders: ordersCSV,
|
|
334
|
+
reviews: reviewCSV,
|
|
335
|
+
quotations: quotationCSV,
|
|
336
|
+
enrollments: enrollmentCSV,
|
|
337
|
+
};
|
|
338
|
+
};
|
|
339
|
+
export default exportUsersHandler;
|
|
340
|
+
exportUsersHandler.payloadSchema = UserExportPayloadSchema;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { UnchainedCore } from '../../core-index.ts';
|
|
2
|
+
export interface CSVFileResult {
|
|
3
|
+
url: string;
|
|
4
|
+
expires: number;
|
|
5
|
+
}
|
|
6
|
+
declare const generateCSVFileAndURL: ({ rows, headers, directoryName, fileName, unchainedAPI, }: {
|
|
7
|
+
rows: Record<string, unknown>[];
|
|
8
|
+
headers: string[];
|
|
9
|
+
directoryName: string;
|
|
10
|
+
fileName: string;
|
|
11
|
+
unchainedAPI: UnchainedCore;
|
|
12
|
+
}, expires?: number) => Promise<CSVFileResult>;
|
|
13
|
+
export default generateCSVFileAndURL;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import toCSV from "./toCSV.js";
|
|
2
|
+
const generateCSVFileAndURL = async ({ rows, headers, directoryName, fileName, unchainedAPI, }, expires = 3600000) => {
|
|
3
|
+
if (!rows.length)
|
|
4
|
+
return { url: '', expires: 0 };
|
|
5
|
+
const csvString = toCSV(headers, rows);
|
|
6
|
+
const uploaded = await unchainedAPI.services.files.uploadFileFromStream({
|
|
7
|
+
directoryName,
|
|
8
|
+
rawFile: { filename: fileName, buffer: Buffer.from(csvString).toString('base64') },
|
|
9
|
+
meta: { isPrivate: true },
|
|
10
|
+
});
|
|
11
|
+
const expiresAt = Date.now() + expires;
|
|
12
|
+
const url = await unchainedAPI.services.files.createFileDownloadURL({
|
|
13
|
+
file: uploaded,
|
|
14
|
+
expires: expiresAt,
|
|
15
|
+
});
|
|
16
|
+
if (!url) {
|
|
17
|
+
throw new Error(`Failed to generate download URL for ${fileName}`);
|
|
18
|
+
}
|
|
19
|
+
return { url, expires: expiresAt };
|
|
20
|
+
};
|
|
21
|
+
export default generateCSVFileAndURL;
|
package/lib/core-index.d.ts
CHANGED
|
@@ -3,10 +3,12 @@ import { type CustomServices, type Services } from './services/index.ts';
|
|
|
3
3
|
import { type Modules, type ModuleOptions } from './modules.ts';
|
|
4
4
|
import { type BulkImporter, type BulkImportHandler } from './bulk-importer/index.ts';
|
|
5
5
|
import type { IBaseAdapter } from '@unchainedshop/utils';
|
|
6
|
+
import { type BulkExporter, type BulkExportHandler } from './bulk-exporter/index.ts';
|
|
6
7
|
export * from './bulk-importer/index.ts';
|
|
7
8
|
export * from './services/index.ts';
|
|
8
9
|
export * from './directors/index.ts';
|
|
9
10
|
export * from './factory/index.ts';
|
|
11
|
+
export * from './bulk-exporter/index.ts';
|
|
10
12
|
export { default as schedule, type ScheduleData } from './utils/schedule.ts';
|
|
11
13
|
export interface UnchainedCoreOptions {
|
|
12
14
|
db: mongodb.Db;
|
|
@@ -14,6 +16,9 @@ export interface UnchainedCoreOptions {
|
|
|
14
16
|
bulkImporter?: {
|
|
15
17
|
handlers?: Record<string, BulkImportHandler<UnchainedCore>>;
|
|
16
18
|
};
|
|
19
|
+
bulkExporter?: {
|
|
20
|
+
handlers?: Record<string, BulkExportHandler<UnchainedCore>>;
|
|
21
|
+
};
|
|
17
22
|
modules?: Record<string, {
|
|
18
23
|
configure: (params: ModuleInput<any>) => any;
|
|
19
24
|
}>;
|
|
@@ -25,6 +30,7 @@ export interface UnchainedCore {
|
|
|
25
30
|
services: Services;
|
|
26
31
|
bulkImporter: BulkImporter;
|
|
27
32
|
options: ModuleOptions;
|
|
33
|
+
bulkExporter: BulkExporter;
|
|
28
34
|
}
|
|
29
|
-
export declare const initCore: ({ db, migrationRepository, bulkImporter: bulkImporterOptions, modules: customModules, services: customServices, options, }: UnchainedCoreOptions) => Promise<UnchainedCore>;
|
|
35
|
+
export declare const initCore: ({ db, migrationRepository, bulkImporter: bulkImporterOptions, modules: customModules, services: customServices, options, bulkExporter: bulkExporterOptions, }: UnchainedCoreOptions) => Promise<UnchainedCore>;
|
|
30
36
|
export declare const getAllAdapters: () => IBaseAdapter[];
|
package/lib/core-index.js
CHANGED
|
@@ -3,13 +3,16 @@ import initServices, {} from "./services/index.js";
|
|
|
3
3
|
import initModules, {} from "./modules.js";
|
|
4
4
|
import createBulkImporterFactory, {} from "./bulk-importer/index.js";
|
|
5
5
|
import { WorkerDirector, DeliveryDirector, DeliveryPricingDirector, EnrollmentDirector, FilterDirector, OrderDiscountDirector, OrderPricingDirector, PaymentDirector, PaymentPricingDirector, ProductDiscountDirector, ProductPricingDirector, QuotationDirector, WarehousingDirector, } from "./directors/index.js";
|
|
6
|
+
import createBulkExporterFactory, {} from "./bulk-exporter/index.js";
|
|
6
7
|
export * from "./bulk-importer/index.js";
|
|
7
8
|
export * from "./services/index.js";
|
|
8
9
|
export * from "./directors/index.js";
|
|
9
10
|
export * from "./factory/index.js";
|
|
11
|
+
export * from "./bulk-exporter/index.js";
|
|
10
12
|
export { default as schedule } from "./utils/schedule.js";
|
|
11
|
-
export const initCore = async ({ db, migrationRepository, bulkImporter: bulkImporterOptions = {}, modules: customModules = {}, services: customServices = {}, options = {}, }) => {
|
|
13
|
+
export const initCore = async ({ db, migrationRepository, bulkImporter: bulkImporterOptions = {}, modules: customModules = {}, services: customServices = {}, options = {}, bulkExporter: bulkExporterOptions = {}, }) => {
|
|
12
14
|
const bulkImporter = createBulkImporterFactory(db, bulkImporterOptions);
|
|
15
|
+
const bulkExporter = createBulkExporterFactory(bulkExporterOptions);
|
|
13
16
|
const modules = await initModules({ db, migrationRepository, options }, customModules);
|
|
14
17
|
const services = initServices(modules, customServices);
|
|
15
18
|
return {
|
|
@@ -17,6 +20,7 @@ export const initCore = async ({ db, migrationRepository, bulkImporter: bulkImpo
|
|
|
17
20
|
services,
|
|
18
21
|
bulkImporter,
|
|
19
22
|
options,
|
|
23
|
+
bulkExporter,
|
|
20
24
|
};
|
|
21
25
|
};
|
|
22
26
|
export const getAllAdapters = () => {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { IFileAdapter, UploadedFile } from '@unchainedshop/core-files';
|
|
2
|
+
export type UploadFileCallback<UnchainedAPI = unknown> = (file: UploadedFile, unchainedAPI: UnchainedAPI) => Promise<void>;
|
|
3
|
+
export declare const FileDirector: {
|
|
4
|
+
getAdapter: (key: string) => IFileAdapter<unknown> | null;
|
|
5
|
+
getAdapters: (options?: {
|
|
6
|
+
adapterFilter?: (adapter: IFileAdapter) => boolean;
|
|
7
|
+
}) => IFileAdapter<unknown>[];
|
|
8
|
+
registerFileUploadCallback<UnchainedAPI>(directoryName: string, fn: UploadFileCallback<UnchainedAPI>): void;
|
|
9
|
+
getFileUploadCallback(directoryName: string): UploadFileCallback<unknown> | null;
|
|
10
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BaseDirector } from '@unchainedshop/utils';
|
|
2
|
+
import { FileAdapter } from '@unchainedshop/core-files';
|
|
3
|
+
import { pluginRegistry } from "../plugins/PluginRegistry.js";
|
|
4
|
+
const FileUploadRegistry = new Map();
|
|
5
|
+
const baseDirector = BaseDirector('FileDirector');
|
|
6
|
+
export const FileDirector = {
|
|
7
|
+
...baseDirector,
|
|
8
|
+
getAdapter: (key) => {
|
|
9
|
+
const adapters = pluginRegistry.getAdapters(FileAdapter.adapterType);
|
|
10
|
+
return adapters.find((adapter) => adapter.key === key) || null;
|
|
11
|
+
},
|
|
12
|
+
getAdapters: (options) => {
|
|
13
|
+
const { adapterFilter } = options || {};
|
|
14
|
+
const adapters = pluginRegistry.getAdapters(FileAdapter.adapterType);
|
|
15
|
+
return adapters.filter(adapterFilter || (() => true));
|
|
16
|
+
},
|
|
17
|
+
registerFileUploadCallback(directoryName, fn) {
|
|
18
|
+
if (!FileUploadRegistry.has(directoryName)) {
|
|
19
|
+
FileUploadRegistry.set(directoryName, fn);
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
getFileUploadCallback(directoryName) {
|
|
23
|
+
return FileUploadRegistry.get(directoryName) || null;
|
|
24
|
+
},
|
|
25
|
+
};
|
|
@@ -3,6 +3,7 @@ import type { WorkResult } from '@unchainedshop/core-worker';
|
|
|
3
3
|
import type { ModuleOptions, Modules } from '../modules.ts';
|
|
4
4
|
import type { Services } from '../services/index.ts';
|
|
5
5
|
import type { BulkImporter } from '../bulk-importer/index.ts';
|
|
6
|
+
import type { BulkExporter } from '../bulk-exporter/index.ts';
|
|
6
7
|
export type IWorkerAdapter<Input, Output> = IBaseAdapter & {
|
|
7
8
|
type: string;
|
|
8
9
|
external: boolean;
|
|
@@ -12,6 +13,7 @@ export type IWorkerAdapter<Input, Output> = IBaseAdapter & {
|
|
|
12
13
|
services: Services;
|
|
13
14
|
bulkImporter: BulkImporter;
|
|
14
15
|
options: ModuleOptions;
|
|
16
|
+
bulkExporter: BulkExporter;
|
|
15
17
|
}, workId: string) => Promise<WorkResult<Output>>;
|
|
16
18
|
};
|
|
17
19
|
export declare const WorkerAdapter: Omit<IWorkerAdapter<any, void>, 'key' | 'label' | 'type' | 'version'>;
|