@unchainedshop/plugins 4.0.0-rc.14 → 4.0.0-rc.16

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 (80) hide show
  1. package/lib/files/gridfs/handler-express.d.ts.map +1 -1
  2. package/lib/files/gridfs/handler-express.js +11 -22
  3. package/lib/files/gridfs/handler-express.js.map +1 -1
  4. package/lib/files/gridfs/handler-fastify.d.ts.map +1 -1
  5. package/lib/files/gridfs/handler-fastify.js +34 -9
  6. package/lib/files/gridfs/handler-fastify.js.map +1 -1
  7. package/lib/files/minio/handler-express.d.ts.map +1 -1
  8. package/lib/files/minio/handler-express.js +3 -6
  9. package/lib/files/minio/handler-express.js.map +1 -1
  10. package/lib/files/minio/handler-fastify.js +1 -1
  11. package/lib/files/minio/handler-fastify.js.map +1 -1
  12. package/lib/filters/strict-equal.js +0 -18
  13. package/lib/filters/strict-equal.js.map +1 -1
  14. package/lib/payment/apple-iap/handler-express.d.ts.map +1 -1
  15. package/lib/payment/apple-iap/handler-express.js +3 -6
  16. package/lib/payment/apple-iap/handler-express.js.map +1 -1
  17. package/lib/payment/apple-iap/handler-fastify.js +2 -2
  18. package/lib/payment/apple-iap/handler-fastify.js.map +1 -1
  19. package/lib/payment/cryptopay/handler-express.d.ts.map +1 -1
  20. package/lib/payment/cryptopay/handler-express.js +3 -6
  21. package/lib/payment/cryptopay/handler-express.js.map +1 -1
  22. package/lib/payment/datatrans-v2/handler-express.d.ts.map +1 -1
  23. package/lib/payment/datatrans-v2/handler-express.js +5 -10
  24. package/lib/payment/datatrans-v2/handler-express.js.map +1 -1
  25. package/lib/payment/datatrans-v2/handler-fastify.js +4 -4
  26. package/lib/payment/datatrans-v2/handler-fastify.js.map +1 -1
  27. package/lib/payment/payrexx/handler-express.d.ts.map +1 -1
  28. package/lib/payment/payrexx/handler-express.js +12 -14
  29. package/lib/payment/payrexx/handler-express.js.map +1 -1
  30. package/lib/payment/payrexx/handler-fastify.d.ts.map +1 -1
  31. package/lib/payment/payrexx/handler-fastify.js +20 -14
  32. package/lib/payment/payrexx/handler-fastify.js.map +1 -1
  33. package/lib/payment/postfinance-checkout/api-client.d.ts.map +1 -1
  34. package/lib/payment/postfinance-checkout/api-client.js +7 -7
  35. package/lib/payment/postfinance-checkout/api-client.js.map +1 -1
  36. package/lib/payment/postfinance-checkout/handler-express.d.ts.map +1 -1
  37. package/lib/payment/postfinance-checkout/handler-express.js +3 -6
  38. package/lib/payment/postfinance-checkout/handler-express.js.map +1 -1
  39. package/lib/payment/postfinance-checkout/handler-fastify.js +2 -2
  40. package/lib/payment/postfinance-checkout/handler-fastify.js.map +1 -1
  41. package/lib/payment/saferpay/handler-express.d.ts.map +1 -1
  42. package/lib/payment/saferpay/handler-express.js +7 -7
  43. package/lib/payment/saferpay/handler-express.js.map +1 -1
  44. package/lib/payment/saferpay/handler-fastify.d.ts.map +1 -1
  45. package/lib/payment/saferpay/handler-fastify.js +8 -4
  46. package/lib/payment/saferpay/handler-fastify.js.map +1 -1
  47. package/lib/payment/stripe/handler-express.d.ts.map +1 -1
  48. package/lib/payment/stripe/handler-express.js +16 -16
  49. package/lib/payment/stripe/handler-express.js.map +1 -1
  50. package/lib/payment/stripe/handler-fastify.d.ts.map +1 -1
  51. package/lib/payment/stripe/handler-fastify.js +24 -11
  52. package/lib/payment/stripe/handler-fastify.js.map +1 -1
  53. package/lib/pricing/product-catalog-price.d.ts.map +1 -1
  54. package/lib/pricing/product-catalog-price.js +24 -0
  55. package/lib/pricing/product-catalog-price.js.map +1 -1
  56. package/lib/worker/bulk-import.d.ts.map +1 -1
  57. package/lib/worker/bulk-import.js +7 -30
  58. package/lib/worker/bulk-import.js.map +1 -1
  59. package/package.json +13 -15
  60. package/src/files/gridfs/handler-express.ts +11 -22
  61. package/src/files/gridfs/handler-fastify.ts +35 -10
  62. package/src/files/minio/handler-express.ts +3 -6
  63. package/src/files/minio/handler-fastify.ts +1 -1
  64. package/src/filters/strict-equal.ts +0 -21
  65. package/src/payment/apple-iap/handler-express.ts +3 -6
  66. package/src/payment/apple-iap/handler-fastify.ts +2 -2
  67. package/src/payment/cryptopay/handler-express.ts +3 -6
  68. package/src/payment/datatrans-v2/handler-express.ts +5 -10
  69. package/src/payment/datatrans-v2/handler-fastify.ts +4 -4
  70. package/src/payment/payrexx/handler-express.ts +21 -31
  71. package/src/payment/payrexx/handler-fastify.ts +28 -29
  72. package/src/payment/postfinance-checkout/api-client.ts +13 -8
  73. package/src/payment/postfinance-checkout/handler-express.ts +3 -6
  74. package/src/payment/postfinance-checkout/handler-fastify.ts +2 -2
  75. package/src/payment/saferpay/handler-express.ts +10 -12
  76. package/src/payment/saferpay/handler-fastify.ts +10 -8
  77. package/src/payment/stripe/handler-express.ts +24 -32
  78. package/src/payment/stripe/handler-fastify.ts +31 -26
  79. package/src/pricing/product-catalog-price.ts +23 -0
  80. package/src/worker/bulk-import.ts +9 -49
@@ -20,24 +20,22 @@ export const payrexxHandler: RouteHandlerMethod = async (
20
20
  type: Object.keys(request.body).join(','),
21
21
  });
22
22
  reply.status(200);
23
- return reply.send(
24
- JSON.stringify({
25
- ignored: true,
26
- message: `Unhandled event type: ${Object.keys(request.body).join(',')}. Supported type: transaction`,
27
- }),
28
- );
23
+ return reply.send({
24
+ success: false,
25
+ ignored: true,
26
+ message: `Unhandled event type: ${Object.keys(request.body).join(',')}. Supported type: transaction`,
27
+ });
29
28
  }
30
29
  if (transaction.referenceId === '__IGNORE_WEBHOOK__' || transaction.status === 'waiting') {
31
30
  // Ignore confirmed transactions, because those hooks are generated through calling the confirm()
32
31
  // method in the payment adapter and could lead to double bookings.
33
32
  logger.info(`unhandled transaction state: ${transaction.status}`);
34
33
  reply.status(200);
35
- return reply.send(
36
- JSON.stringify({
37
- ignored: true,
38
- message: `Unhandled transaction state: ${transaction.status}`,
39
- }),
40
- );
34
+ return reply.send({
35
+ success: false,
36
+ ignored: true,
37
+ message: `Unhandled transaction state: ${transaction.status}`,
38
+ });
41
39
  }
42
40
 
43
41
  logger.info(`Processing event`, {
@@ -58,19 +56,14 @@ export const payrexxHandler: RouteHandlerMethod = async (
58
56
  userId,
59
57
  });
60
58
  reply.status(200);
61
- return reply.send(
62
- JSON.stringify({
63
- message: 'registration successful',
64
- paymentProviderId,
65
- userId,
66
- }),
67
- );
59
+ return reply.send({
60
+ success: true,
61
+ paymentProviderId,
62
+ userId,
63
+ });
68
64
  } else {
69
65
  const { referenceId: orderPaymentId, invoice } = transaction;
70
66
  logger.info(`checkout with orderPaymentId: ${orderPaymentId}`);
71
- await modules.orders.payments.logEvent(orderPaymentId, {
72
- transactionId: transaction.id,
73
- });
74
67
  const orderPayment = await modules.orders.payments.findOrderPayment({
75
68
  orderPaymentId,
76
69
  });
@@ -78,6 +71,10 @@ export const payrexxHandler: RouteHandlerMethod = async (
78
71
  throw new Error(`order payment not found with orderPaymentId: ${orderPaymentId}`);
79
72
  }
80
73
 
74
+ await modules.orders.payments.logEvent(orderPaymentId, {
75
+ transactionId: transaction.id,
76
+ });
77
+
81
78
  const order = await services.orders.checkoutOrder(orderPayment.orderId, {
82
79
  paymentContext: {
83
80
  gatewayId: invoice.paymentRequestId,
@@ -88,18 +85,20 @@ export const payrexxHandler: RouteHandlerMethod = async (
88
85
  orderId: order._id,
89
86
  });
90
87
  reply.status(200);
91
- return reply.send(
92
- JSON.stringify({
93
- message: 'checkout successful',
94
- orderId: order._id,
95
- }),
96
- );
88
+ return reply.send({
89
+ success: true,
90
+ orderId: order._id,
91
+ });
97
92
  }
98
93
  } catch (error) {
99
94
  logger.error(error, {
100
95
  transactionId: transaction.id,
101
96
  });
102
97
  reply.status(500);
103
- return reply.send(error.message);
98
+ return reply.send({
99
+ success: false,
100
+ message: error.message,
101
+ name: error.name,
102
+ });
104
103
  }
105
104
  };
@@ -1,5 +1,3 @@
1
- import crypto from 'crypto';
2
-
3
1
  const API_BASE_URL = 'https://checkout.postfinance.ch/api';
4
2
 
5
3
  interface ApiConfig {
@@ -22,7 +20,7 @@ export class PostFinanceApiClient {
22
20
  this.config = config;
23
21
  }
24
22
 
25
- private generateMacHeaders(method: string, path: string): MacHeaders {
23
+ private async generateMacHeaders(method: string, path: string): Promise<MacHeaders> {
26
24
  const version = '1';
27
25
  const timestamp = Math.floor(Date.now() / 1000).toString();
28
26
  const userId = this.config.userId.toString();
@@ -32,10 +30,17 @@ export class PostFinanceApiClient {
32
30
 
33
31
  const dataToSign = [version, userId, timestamp, method, resourcePath].join('|');
34
32
 
35
- const macValue = crypto
36
- .createHmac('sha512', Buffer.from(this.config.apiSecret, 'base64'))
37
- .update(dataToSign, 'utf8')
38
- .digest('base64');
33
+ // Use Web Crypto API instead of crypto.createHmac
34
+ const secretBytes = Uint8Array.from(atob(this.config.apiSecret), (c) => c.charCodeAt(0));
35
+ const key = await crypto.subtle.importKey(
36
+ 'raw',
37
+ secretBytes,
38
+ { name: 'HMAC', hash: 'SHA-512' },
39
+ false,
40
+ ['sign'],
41
+ );
42
+ const signature = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(dataToSign));
43
+ const macValue = btoa(String.fromCharCode(...new Uint8Array(signature)));
39
44
 
40
45
  return {
41
46
  'x-mac-version': version,
@@ -50,7 +55,7 @@ export class PostFinanceApiClient {
50
55
  const urlObj = new URL(url);
51
56
  // Include both pathname and search (query parameters) for MAC signature
52
57
  const pathWithQuery = urlObj.pathname + urlObj.search;
53
- const macHeaders = this.generateMacHeaders(method, pathWithQuery);
58
+ const macHeaders = await this.generateMacHeaders(method, pathWithQuery);
54
59
 
55
60
  const headers: Record<string, string> = {
56
61
  ...macHeaders,
@@ -29,16 +29,13 @@ export const postfinanceCheckoutHandler = async (req, res) => {
29
29
  logger.info(
30
30
  `Transaction ${transactionCompletion.linkedTransaction} marked order payment ID ${transaction.metaData.orderPaymentId} as paid`,
31
31
  );
32
- res.writeHead(200);
33
- res.end(`Order marked as paid: ${order.orderNumber}`);
32
+ res.status(200).send(`Order marked as paid: ${order.orderNumber}`);
34
33
  } catch (e) {
35
34
  logger.error(e);
36
- res.writeHead(500);
37
- res.end(JSON.stringify({ name: e.name, code: e.code, message: e.message }));
35
+ res.status(500).send({ name: e.name, code: e.code, message: e.message });
38
36
  }
39
37
  } else {
40
38
  logger.error(`Received unknown listenerEntityTechnicalName ${data.listenerEntityTechnicalName}`);
41
- res.writeHead(404);
42
- res.end();
39
+ res.status(404).end();
43
40
  }
44
41
  };
@@ -36,11 +36,11 @@ export const postfinanceCheckoutHandler: RouteHandlerMethod = async (
36
36
  `Transaction ${transaction.id} marked order payment ID ${transaction.metaData.orderPaymentId} as paid`,
37
37
  );
38
38
  reply.status(200);
39
- return reply.send(`Order marked as paid: ${order.orderNumber}`);
39
+ return reply.send({ success: true, orderNumber: order.orderNumber });
40
40
  } catch (e) {
41
41
  logger.error(e);
42
42
  reply.status(500);
43
- return reply.send({ name: e.name, code: e.code, message: e.message });
43
+ return reply.send({ success: false, name: e.name, code: e.code, message: e.message });
44
44
  }
45
45
  } else {
46
46
  logger.error(`Received unknown listenerEntityTechnicalName ${data.listenerEntityTechnicalName}`);
@@ -22,8 +22,7 @@ export const saferpayHandler = async (request, response) => {
22
22
 
23
23
  if ((request.method !== 'GET' && request.method !== 'HEAD') || !isValidRequest) {
24
24
  logger.warn(`unhandled http method ${request.method} or orderPaymentId missing in query`);
25
- response.writeHead(404);
26
- response.end();
25
+ response.status(404).end();
27
26
  return;
28
27
  }
29
28
 
@@ -51,20 +50,19 @@ export const saferpayHandler = async (request, response) => {
51
50
  orderPaymentId,
52
51
  orderId: order._id,
53
52
  });
54
- response.writeHead(200);
55
- response.end(
56
- JSON.stringify({
57
- message: 'checkout successful',
58
- orderPaymentId,
59
- orderId: order._id,
60
- }),
61
- );
53
+ response.status(200).send({
54
+ message: 'checkout successful',
55
+ orderPaymentId,
56
+ orderId: order._id,
57
+ });
62
58
  } catch (error) {
63
59
  logger.error(error, {
64
60
  orderPaymentId,
65
61
  transactionId,
66
62
  });
67
- response.writeHead(500);
68
- response.end(error.message);
63
+ response.status(500).send({
64
+ message: error.message,
65
+ name: error.name,
66
+ });
69
67
  }
70
68
  };
@@ -57,19 +57,21 @@ export const saferpayHandler: RouteHandlerMethod = async (
57
57
  orderId: order._id,
58
58
  });
59
59
  reply.status(200);
60
- return reply.send(
61
- JSON.stringify({
62
- message: 'checkout successful',
63
- orderPaymentId,
64
- orderId: order._id,
65
- }),
66
- );
60
+ return reply.send({
61
+ success: true,
62
+ orderPaymentId,
63
+ orderId: order._id,
64
+ });
67
65
  } catch (error) {
68
66
  logger.error(error, {
69
67
  orderPaymentId,
70
68
  transactionId,
71
69
  });
72
70
  reply.status(500);
73
- return reply.send(error.message);
71
+ return reply.send({
72
+ success: false,
73
+ message: error.message,
74
+ name: error.name,
75
+ });
74
76
  }
75
77
  };
@@ -21,8 +21,10 @@ export const stripeHandler = async (request, response) => {
21
21
  event = stripe.webhooks.constructEvent(request.body, sig, process.env.STRIPE_ENDPOINT_SECRET);
22
22
  } catch (err) {
23
23
  logger.error(`Error constructing event: ${err.message}`);
24
- response.writeHead(400);
25
- response.end(err.message);
24
+ response.status(400).send({
25
+ message: err.message,
26
+ name: err.name,
27
+ });
26
28
  return;
27
29
  }
28
30
 
@@ -30,13 +32,10 @@ export const stripeHandler = async (request, response) => {
30
32
  logger.info(`unhandled event type`, {
31
33
  type: event.type,
32
34
  });
33
- response.writeHead(200);
34
- response.end(
35
- JSON.stringify({
36
- ignored: true,
37
- message: `Unhandled event type: ${event.type}. Supported types: ${Object.values(WebhookEventTypes).join(', ')}`,
38
- }),
39
- );
35
+ response.status(200).send({
36
+ ignored: true,
37
+ message: `Unhandled event type: ${event.type}. Supported types: ${Object.values(WebhookEventTypes).join(', ')}`,
38
+ });
40
39
  return;
41
40
  }
42
41
 
@@ -47,13 +46,10 @@ export const stripeHandler = async (request, response) => {
47
46
  type: event.type,
48
47
  environment: environmentInMetadata,
49
48
  });
50
- response.writeHead(200);
51
- response.end(
52
- JSON.stringify({
53
- ignored: true,
54
- message: `Unhandled event environment: ${environmentInMetadata}. Supported environment: ${environmentInEnv}`,
55
- }),
56
- );
49
+ response.status(200).send({
50
+ ignored: true,
51
+ message: `Unhandled event environment: ${environmentInMetadata}. Supported environment: ${environmentInEnv}`,
52
+ });
57
53
  return;
58
54
  }
59
55
 
@@ -89,13 +85,10 @@ export const stripeHandler = async (request, response) => {
89
85
  orderId: order._id,
90
86
  type: event.type,
91
87
  });
92
- response.writeHead(200);
93
- response.end(
94
- JSON.stringify({
95
- message: 'checkout successful',
96
- orderId: order._id,
97
- }),
98
- );
88
+ response.status(200).send({
89
+ message: 'checkout successful',
90
+ orderId: order._id,
91
+ });
99
92
  } else if (event.type === WebhookEventTypes.SETUP_INTENT_SUCCEEDED) {
100
93
  const setupIntent = event.data.object;
101
94
  const { paymentProviderId, userId } = setupIntent.metadata || {};
@@ -118,19 +111,18 @@ export const stripeHandler = async (request, response) => {
118
111
  paymentCredentialsId: paymentCredentials?._id,
119
112
  type: event.type,
120
113
  });
121
- response.writeHead(200);
122
- response.end(
123
- JSON.stringify({
124
- message: 'payment credentials registration successful',
125
- paymentCredentialsId: paymentCredentials?._id,
126
- }),
127
- );
114
+ response.status(200).send({
115
+ message: 'payment credentials registration successful',
116
+ paymentCredentialsId: paymentCredentials?._id,
117
+ });
128
118
  }
129
119
  } catch (error) {
130
120
  logger.error(error, {
131
121
  type: event.type,
132
122
  });
133
- response.writeHead(500);
134
- response.end(error.message);
123
+ response.status(500).send({
124
+ message: error.message,
125
+ name: error.name,
126
+ });
135
127
  }
136
128
  };
@@ -28,7 +28,11 @@ export const stripeHandler: RouteHandlerMethod = async (
28
28
  } catch (err) {
29
29
  logger.error(`Error constructing event: ${err.message}`);
30
30
  reply.status(400);
31
- return reply.send(err.message);
31
+ return reply.send({
32
+ success: false,
33
+ message: err.message,
34
+ name: err.name,
35
+ });
32
36
  }
33
37
 
34
38
  if (!Object.values(WebhookEventTypes).includes(event.type)) {
@@ -36,12 +40,12 @@ export const stripeHandler: RouteHandlerMethod = async (
36
40
  type: event.type,
37
41
  });
38
42
  reply.status(200);
39
- return reply.send(
40
- JSON.stringify({
41
- ignored: true,
42
- message: `Unhandled event type: ${event.type}. Supported types: ${Object.values(WebhookEventTypes).join(', ')}`,
43
- }),
44
- );
43
+ return reply.send({
44
+ success: false,
45
+ ignored: true,
46
+ name: 'UNHANDLED_EVENT_TYPE',
47
+ message: `Unhandled event type: ${event.type}. Supported types: ${Object.values(WebhookEventTypes).join(', ')}`,
48
+ });
45
49
  }
46
50
 
47
51
  const environmentInMetadata = event.data?.object?.metadata?.environment || '';
@@ -52,12 +56,12 @@ export const stripeHandler: RouteHandlerMethod = async (
52
56
  environment: environmentInMetadata,
53
57
  });
54
58
  reply.status(200);
55
- return reply.send(
56
- JSON.stringify({
57
- ignored: true,
58
- message: `Unhandled event environment: ${environmentInMetadata}. Supported environment: ${environmentInEnv}`,
59
- }),
60
- );
59
+ return reply.send({
60
+ success: false,
61
+ ignored: true,
62
+ name: 'UNHANDLED_EVENT_ENVIRONMENT',
63
+ message: `Unhandled event environment: ${environmentInMetadata}. Supported environment: ${environmentInEnv}`,
64
+ });
61
65
  }
62
66
 
63
67
  logger.info(`Processing event`, {
@@ -93,12 +97,10 @@ export const stripeHandler: RouteHandlerMethod = async (
93
97
  type: event.type,
94
98
  });
95
99
  reply.status(200);
96
- return reply.send(
97
- JSON.stringify({
98
- message: 'checkout successful',
99
- orderId: order._id,
100
- }),
101
- );
100
+ return reply.send({
101
+ success: true,
102
+ orderId: order._id,
103
+ });
102
104
  } else if (event.type === WebhookEventTypes.SETUP_INTENT_SUCCEEDED) {
103
105
  const setupIntent = event.data.object;
104
106
  const { paymentProviderId, userId } = setupIntent.metadata || {};
@@ -122,18 +124,21 @@ export const stripeHandler: RouteHandlerMethod = async (
122
124
  type: event.type,
123
125
  });
124
126
  reply.status(200);
125
- return reply.send(
126
- JSON.stringify({
127
- message: 'payment credentials registration successful',
128
- paymentCredentialsId: paymentCredentials?._id,
129
- }),
130
- );
127
+ return reply.send({
128
+ success: true,
129
+ message: 'payment credentials registration successful',
130
+ paymentCredentialsId: paymentCredentials?._id,
131
+ });
131
132
  }
132
133
  } catch (error) {
133
134
  logger.error(error, {
134
135
  type: event.type,
135
136
  });
136
137
  reply.status(500);
137
- return reply.send(error.message);
138
+ return reply.send({
139
+ success: false,
140
+ message: error.message,
141
+ name: error.name,
142
+ });
138
143
  }
139
144
  };
@@ -3,6 +3,7 @@ import {
3
3
  ProductPricingAdapter,
4
4
  IProductPricingAdapter,
5
5
  } from '@unchainedshop/core';
6
+ import { ProductTypes } from '@unchainedshop/core-products';
6
7
 
7
8
  export const ProductPrice: IProductPricingAdapter = {
8
9
  ...ProductPricingAdapter,
@@ -37,6 +38,28 @@ export const ProductPrice: IProductPricingAdapter = {
37
38
  isNetPrice: price.isNetPrice,
38
39
  meta: { adapter: ProductPrice.key },
39
40
  });
41
+ } else if (product.type === ProductTypes.BundleProduct) {
42
+ for (const bundleItem of product.bundleItems || []) {
43
+ const bundledProduct = await modules.products.findProduct({
44
+ productId: bundleItem.productId,
45
+ });
46
+ if (bundledProduct) {
47
+ const bundleItemPrice = await modules.products.prices.price(bundledProduct, {
48
+ countryCode,
49
+ currencyCode,
50
+ quantity: bundleItem.quantity * quantity,
51
+ });
52
+ if (bundleItemPrice) {
53
+ const bundleItemTotal = bundleItemPrice.amount * bundleItem.quantity * quantity;
54
+ pricingAdapter.resultSheet().addItem({
55
+ amount: bundleItemTotal,
56
+ isTaxable: bundleItemPrice.isTaxable,
57
+ isNetPrice: bundleItemPrice.isNetPrice,
58
+ meta: { adapter: ProductPrice.key },
59
+ });
60
+ }
61
+ }
62
+ }
40
63
  }
41
64
 
42
65
  return pricingAdapter.calculate();
@@ -1,56 +1,8 @@
1
1
  import { WorkerDirector, WorkerAdapter, IWorkerAdapter } from '@unchainedshop/core';
2
2
  import { createLogger } from '@unchainedshop/logger';
3
- import JSONStream from 'JSONStream';
4
- import { EventIterator } from 'event-iterator';
5
- import { UnchainedCore } from '@unchainedshop/core';
6
3
 
7
4
  const logger = createLogger('unchained:worker:bulk-import');
8
5
 
9
- const streamPayloadToBulkImporter = async (
10
- bulkImporter,
11
- payloadId,
12
- unchainedAPI: Pick<UnchainedCore, 'bulkImporter' | 'modules' | 'services'>,
13
- ) => {
14
- logger.trace(`parseAsync start`);
15
-
16
- const readStream = await unchainedAPI.services.files.createDownloadStream({ fileId: payloadId });
17
-
18
- if (!readStream) {
19
- throw new Error(
20
- 'The current file adapter does not support streams when downloading required for streamed events. Please use a different file adapter.',
21
- );
22
- }
23
-
24
- const eventIterator = new EventIterator(
25
- (queue) => {
26
- const jsonStream = JSONStream.parse('events.*'); // rows, ANYTHING, doc
27
- jsonStream.on('data', queue.push);
28
- jsonStream.on('close', queue.stop);
29
- jsonStream.on('error', queue.fail);
30
-
31
- queue.on('highWater', () => readStream.pause());
32
- queue.on('lowWater', () => readStream.resume());
33
-
34
- readStream.pipe(jsonStream);
35
- readStream.on('error', queue.fail);
36
-
37
- return () => {
38
- jsonStream.removeListener('data', queue.push);
39
- jsonStream.removeListener('close', queue.stop);
40
- jsonStream.removeListener('error', queue.fail);
41
- jsonStream.destroy();
42
- };
43
- },
44
- { highWaterMark: 100, lowWaterMark: 5 },
45
- );
46
-
47
- for await (const event of eventIterator) {
48
- await bulkImporter.prepare(event, unchainedAPI);
49
- }
50
-
51
- logger.trace(`parseAsync done`);
52
- };
53
-
54
6
  export const BulkImportWorker: IWorkerAdapter<any, Record<string, unknown>> = {
55
7
  ...WorkerAdapter,
56
8
 
@@ -76,7 +28,15 @@ export const BulkImportWorker: IWorkerAdapter<any, Record<string, unknown>> = {
76
28
 
77
29
  if (rawPayload.payloadId) {
78
30
  // stream payload from gridfs
79
- await streamPayloadToBulkImporter(bulkImporter, rawPayload.payloadId, unchainedAPI);
31
+ const readStream = await unchainedAPI.services.files.createDownloadStream({
32
+ fileId: rawPayload.payloadId,
33
+ });
34
+ if (!readStream) {
35
+ throw new Error(
36
+ 'The current file adapter does not support streams when downloading required for streamed events. Please use a different file adapter.',
37
+ );
38
+ }
39
+ await unchainedAPI.bulkImporter.pipeEventStream(readStream, bulkImporter, unchainedAPI);
80
40
  } else {
81
41
  const { events } = rawPayload;
82
42
  if (!events?.length) throw new Error('No events submitted');