@unchainedshop/plugins 3.1.11 → 4.0.0-rc.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/delivery/pick-mup.js +0 -2
- package/lib/delivery/pick-mup.js.map +1 -1
- package/lib/files/gridfs/module.d.ts +2 -2
- package/lib/files/gridfs/module.d.ts.map +1 -1
- package/lib/filters/local-search.d.ts.map +1 -1
- package/lib/filters/local-search.js +9 -2
- package/lib/filters/local-search.js.map +1 -1
- package/lib/payment/apple-iap/adapter.js +5 -12
- package/lib/payment/apple-iap/adapter.js.map +1 -1
- package/lib/payment/apple-iap/fix-periods.d.ts.map +1 -1
- package/lib/payment/apple-iap/fix-periods.js +3 -5
- package/lib/payment/apple-iap/fix-periods.js.map +1 -1
- package/lib/payment/apple-iap/handler-express.js +3 -3
- package/lib/payment/apple-iap/handler-express.js.map +1 -1
- package/lib/payment/apple-iap/handler-fastify.js +3 -3
- package/lib/payment/apple-iap/handler-fastify.js.map +1 -1
- package/lib/payment/apple-iap/module.d.ts +2 -2
- package/lib/payment/apple-iap/module.d.ts.map +1 -1
- package/lib/payment/braintree.js +3 -4
- package/lib/payment/braintree.js.map +1 -1
- package/lib/payment/cryptopay/db/CryptopayTransactions.d.ts +1 -2
- package/lib/payment/cryptopay/db/CryptopayTransactions.d.ts.map +1 -1
- package/lib/payment/cryptopay/db/CryptopayTransactions.js.map +1 -1
- package/lib/payment/cryptopay/de.d.ts +2 -0
- package/lib/payment/cryptopay/de.d.ts.map +1 -0
- package/lib/payment/cryptopay/de.js +10 -0
- package/lib/payment/cryptopay/de.js.map +1 -0
- package/lib/payment/cryptopay/denote-amount.d.ts +25 -0
- package/lib/payment/cryptopay/denote-amount.d.ts.map +1 -0
- package/lib/payment/cryptopay/denote-amount.js +31 -0
- package/lib/payment/cryptopay/denote-amount.js.map +1 -0
- package/lib/payment/cryptopay/derive-btc-address.d.ts +3 -0
- package/lib/payment/cryptopay/derive-btc-address.d.ts.map +1 -0
- package/lib/payment/cryptopay/derive-btc-address.js +39 -0
- package/lib/payment/cryptopay/derive-btc-address.js.map +1 -0
- package/lib/payment/cryptopay/derive-btc-address.test copy.d.ts +2 -0
- package/lib/payment/cryptopay/derive-btc-address.test copy.d.ts.map +1 -0
- package/lib/payment/cryptopay/derive-btc-address.test copy.js +10 -0
- package/lib/payment/cryptopay/derive-btc-address.test copy.js.map +1 -0
- package/lib/payment/cryptopay/derive-eth-address.d.ts +3 -0
- package/lib/payment/cryptopay/derive-eth-address.d.ts.map +1 -0
- package/lib/payment/cryptopay/derive-eth-address.js +32 -0
- package/lib/payment/cryptopay/derive-eth-address.js.map +1 -0
- package/lib/payment/cryptopay/handle-webhook.d.ts +26 -0
- package/lib/payment/cryptopay/handle-webhook.d.ts.map +1 -0
- package/lib/payment/cryptopay/handle-webhook.js +61 -0
- package/lib/payment/cryptopay/handle-webhook.js.map +1 -0
- package/lib/payment/cryptopay/handler-express.d.ts.map +1 -1
- package/lib/payment/cryptopay/handler-express.js +3 -56
- package/lib/payment/cryptopay/handler-express.js.map +1 -1
- package/lib/payment/cryptopay/handler-fastify.d.ts.map +1 -1
- package/lib/payment/cryptopay/handler-fastify.js +3 -55
- package/lib/payment/cryptopay/handler-fastify.js.map +1 -1
- package/lib/payment/cryptopay/module.d.ts +26 -26
- package/lib/payment/cryptopay/module.d.ts.map +1 -1
- package/lib/payment/cryptopay/module.js +26 -24
- package/lib/payment/cryptopay/module.js.map +1 -1
- package/lib/payment/cryptopay/plugin.d.ts.map +1 -1
- package/lib/payment/cryptopay/plugin.js +33 -79
- package/lib/payment/cryptopay/plugin.js.map +1 -1
- package/lib/payment/datatrans-v2/api/types.d.ts +41 -41
- package/lib/payment/datatrans-v2/api/types.d.ts.map +1 -1
- package/lib/payment/datatrans-v2/getPaths.d.ts +2 -2
- package/lib/payment/datatrans-v2/getPaths.d.ts.map +1 -1
- package/lib/payment/datatrans-v2/index.js +16 -14
- package/lib/payment/datatrans-v2/index.js.map +1 -1
- package/lib/payment/datatrans-v2/roundedAmountFromOrder.d.ts +1 -1
- package/lib/payment/datatrans-v2/roundedAmountFromOrder.d.ts.map +1 -1
- package/lib/payment/datatrans-v2/roundedAmountFromOrder.js +3 -3
- package/lib/payment/datatrans-v2/roundedAmountFromOrder.js.map +1 -1
- package/lib/payment/paypal-checkout.js +1 -1
- package/lib/payment/paypal-checkout.js.map +1 -1
- package/lib/payment/payrexx/api/index.d.ts +2 -2
- package/lib/payment/payrexx/api/index.d.ts.map +1 -1
- package/lib/payment/payrexx/api/makeFetcher.d.ts.map +1 -1
- package/lib/payment/payrexx/api/makeFetcher.js.map +1 -1
- package/lib/payment/payrexx/index.js +4 -4
- package/lib/payment/payrexx/index.js.map +1 -1
- package/lib/payment/payrexx/payrexx.js +2 -2
- package/lib/payment/payrexx/payrexx.js.map +1 -1
- package/lib/payment/postfinance-checkout/index.js +3 -5
- package/lib/payment/postfinance-checkout/index.js.map +1 -1
- package/lib/payment/postfinance-checkout/types.d.ts +4 -4
- package/lib/payment/postfinance-checkout/types.d.ts.map +1 -1
- package/lib/payment/postfinance-checkout/utils.js +2 -2
- package/lib/payment/postfinance-checkout/utils.js.map +1 -1
- package/lib/payment/saferpay/adapter.d.ts.map +1 -1
- package/lib/payment/saferpay/adapter.js +4 -6
- package/lib/payment/saferpay/adapter.js.map +1 -1
- package/lib/payment/saferpay/api/models/Transaction.d.ts +2 -2
- package/lib/payment/saferpay/api/models/Transaction.d.ts.map +1 -1
- package/lib/payment/saferpay/module.d.ts +2 -2
- package/lib/payment/saferpay/module.d.ts.map +1 -1
- package/lib/payment/stripe/index.js +5 -5
- package/lib/payment/stripe/index.js.map +1 -1
- package/lib/payment/stripe/stripe.js +3 -3
- package/lib/payment/stripe/stripe.js.map +1 -1
- package/lib/presets/all.d.ts +12 -12
- package/lib/presets/all.d.ts.map +1 -1
- package/lib/pricing/delivery-swiss-tax.d.ts.map +1 -1
- package/lib/pricing/delivery-swiss-tax.js +2 -2
- package/lib/pricing/delivery-swiss-tax.js.map +1 -1
- package/lib/pricing/order-delivery.js +1 -1
- package/lib/pricing/order-delivery.js.map +1 -1
- package/lib/pricing/order-discount.js +3 -3
- package/lib/pricing/order-discount.js.map +1 -1
- package/lib/pricing/order-items-discount.js +1 -1
- package/lib/pricing/order-items-discount.js.map +1 -1
- package/lib/pricing/order-items.js +1 -1
- package/lib/pricing/order-items.js.map +1 -1
- package/lib/pricing/order-payment.js +1 -1
- package/lib/pricing/order-payment.js.map +1 -1
- package/lib/pricing/order-round.d.ts +1 -1
- package/lib/pricing/order-round.d.ts.map +1 -1
- package/lib/pricing/order-round.js +8 -8
- package/lib/pricing/order-round.js.map +1 -1
- package/lib/pricing/product-catalog-price.d.ts +0 -1
- package/lib/pricing/product-catalog-price.d.ts.map +1 -1
- package/lib/pricing/product-catalog-price.js +6 -18
- package/lib/pricing/product-catalog-price.js.map +1 -1
- package/lib/pricing/product-price-rateconversion.js +2 -2
- package/lib/pricing/product-price-rateconversion.js.map +1 -1
- package/lib/pricing/product-round.d.ts +1 -1
- package/lib/pricing/product-round.d.ts.map +1 -1
- package/lib/pricing/product-round.js +2 -2
- package/lib/pricing/product-round.js.map +1 -1
- package/lib/pricing/product-swiss-tax.d.ts +1 -1
- package/lib/pricing/product-swiss-tax.d.ts.map +1 -1
- package/lib/pricing/product-swiss-tax.js +2 -2
- package/lib/pricing/product-swiss-tax.js.map +1 -1
- package/lib/warehousing/eth-minter.js +2 -2
- package/lib/warehousing/eth-minter.js.map +1 -1
- package/lib/worker/bulk-import.js +1 -1
- package/lib/worker/bulk-import.js.map +1 -1
- package/lib/worker/enrollment-order-generator.js +1 -1
- package/lib/worker/enrollment-order-generator.js.map +1 -1
- package/lib/worker/error-notifications.d.ts +4 -4
- package/lib/worker/error-notifications.d.ts.map +1 -1
- package/lib/worker/message.d.ts +1 -1
- package/lib/worker/message.d.ts.map +1 -1
- package/lib/worker/sms.js +16 -16
- package/lib/worker/sms.js.map +1 -1
- package/lib/worker/update-coinbase-rates.js +1 -1
- package/lib/worker/update-coinbase-rates.js.map +1 -1
- package/lib/worker/update-ecb-rates.js.map +1 -1
- package/package.json +37 -53
- package/src/delivery/pick-mup.ts +0 -2
- package/src/files/gridfs/module.ts +2 -2
- package/src/filters/local-search.ts +11 -2
- package/src/payment/apple-iap/adapter.ts +6 -13
- package/src/payment/apple-iap/fix-periods.ts +4 -7
- package/src/payment/apple-iap/handler-express.ts +3 -3
- package/src/payment/apple-iap/handler-fastify.ts +3 -3
- package/src/payment/apple-iap/module.ts +2 -2
- package/src/payment/braintree.ts +3 -4
- package/src/payment/cryptopay/db/CryptopayTransactions.ts +1 -2
- package/src/payment/cryptopay/denote-amount.test.ts +28 -0
- package/src/payment/cryptopay/denote-amount.ts +29 -0
- package/src/payment/cryptopay/derive-btc-address.test.ts +22 -0
- package/src/payment/cryptopay/derive-btc-address.ts +48 -0
- package/src/payment/cryptopay/derive-eth-address.test.ts +22 -0
- package/src/payment/cryptopay/derive-eth-address.ts +38 -0
- package/src/payment/cryptopay/handle-webhook.ts +103 -0
- package/src/payment/cryptopay/handler-express.ts +3 -69
- package/src/payment/cryptopay/handler-fastify.ts +5 -70
- package/src/payment/cryptopay/module.ts +44 -40
- package/src/payment/cryptopay/plugin.ts +50 -87
- package/src/payment/cryptopay/readme.md +23 -1
- package/src/payment/datatrans-v2/api/types.ts +41 -41
- package/src/payment/datatrans-v2/getPaths.ts +2 -2
- package/src/payment/datatrans-v2/index.ts +17 -15
- package/src/payment/datatrans-v2/roundedAmountFromOrder.ts +4 -4
- package/src/payment/paypal-checkout.ts +1 -1
- package/src/payment/payrexx/api/index.ts +2 -2
- package/src/payment/payrexx/api/makeFetcher.ts +1 -1
- package/src/payment/payrexx/index.ts +4 -4
- package/src/payment/payrexx/payrexx.ts +2 -2
- package/src/payment/postfinance-checkout/index.ts +3 -5
- package/src/payment/postfinance-checkout/types.ts +6 -6
- package/src/payment/postfinance-checkout/utils.ts +2 -2
- package/src/payment/saferpay/adapter.ts +4 -6
- package/src/payment/saferpay/api/models/Transaction.ts +2 -2
- package/src/payment/saferpay/module.ts +2 -2
- package/src/payment/stripe/index.ts +5 -5
- package/src/payment/stripe/stripe.ts +3 -3
- package/src/pricing/delivery-swiss-tax.ts +6 -2
- package/src/pricing/order-delivery.ts +1 -1
- package/src/pricing/order-discount.ts +3 -3
- package/src/pricing/order-items-discount.ts +1 -1
- package/src/pricing/order-items.ts +1 -1
- package/src/pricing/order-payment.ts +1 -1
- package/src/pricing/order-round.ts +9 -9
- package/src/pricing/product-catalog-price.ts +6 -25
- package/src/pricing/product-price-rateconversion.ts +2 -2
- package/src/pricing/product-round.ts +3 -3
- package/src/pricing/product-swiss-tax.test.ts +6 -6
- package/src/pricing/product-swiss-tax.ts +2 -2
- package/src/warehousing/eth-minter.ts +2 -2
- package/src/worker/bulk-import.ts +1 -1
- package/src/worker/enrollment-order-generator.ts +3 -3
- package/src/worker/error-notifications.ts +4 -4
- package/src/worker/heartbeat.ts +2 -2
- package/src/worker/message.ts +1 -1
- package/src/worker/push-notification.ts +2 -2
- package/src/worker/sms.ts +19 -17
- package/src/worker/update-coinbase-rates.ts +3 -6
- package/src/worker/update-ecb-rates.ts +3 -3
- package/src/worker/BaseWorker.ts +0 -116
- package/src/worker/EventListenerWorker.ts +0 -61
- package/src/worker/FailedRescheduler.ts +0 -80
- package/src/worker/IntervalWorker.ts +0 -54
package/src/worker/message.ts
CHANGED
|
@@ -3,7 +3,7 @@ import webPush from 'web-push';
|
|
|
3
3
|
|
|
4
4
|
const { PUSH_NOTIFICATION_PUBLIC_KEY, PUSH_NOTIFICATION_PRIVATE_KEY } = process.env;
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
interface NotificationOptions {
|
|
7
7
|
vapidDetails: {
|
|
8
8
|
subject: string;
|
|
9
9
|
publicKey: string;
|
|
@@ -12,7 +12,7 @@ type NotificationOptions = {
|
|
|
12
12
|
TTL: number;
|
|
13
13
|
urgency?: 'very-low' | 'low' | 'normal' | 'high';
|
|
14
14
|
topic?: string;
|
|
15
|
-
}
|
|
15
|
+
}
|
|
16
16
|
|
|
17
17
|
const PushNotificationWorkerPlugin: IWorkerAdapter<
|
|
18
18
|
{
|
package/src/worker/sms.ts
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
import { IWorkerAdapter, WorkerAdapter, WorkerDirector } from '@unchainedshop/core';
|
|
2
|
-
import Twilio from 'twilio';
|
|
3
2
|
|
|
4
3
|
const { TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_SMS_FROM } = process.env;
|
|
5
4
|
|
|
6
|
-
/* Potential: no need for twilio npm
|
|
7
|
-
curl -X POST "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Messages.json" \
|
|
8
|
-
--data-urlencode "From=+15017122661" \
|
|
9
|
-
--data-urlencode "Body=Hi there" \
|
|
10
|
-
--data-urlencode "To=+15558675310" \
|
|
11
|
-
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
5
|
const SmsWorkerPlugin: IWorkerAdapter<
|
|
15
6
|
{
|
|
16
7
|
from?: string;
|
|
@@ -49,25 +40,36 @@ const SmsWorkerPlugin: IWorkerAdapter<
|
|
|
49
40
|
}
|
|
50
41
|
|
|
51
42
|
try {
|
|
52
|
-
const
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
43
|
+
const url = `https://api.twilio.com/2010-04-01/Accounts/${TWILIO_ACCOUNT_SID}/Messages.json`;
|
|
44
|
+
const response = await fetch(url, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: {
|
|
47
|
+
Authorization: `Basic ${Buffer.from(`${TWILIO_ACCOUNT_SID}:${TWILIO_AUTH_TOKEN}`).toString('base64')}`,
|
|
48
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
49
|
+
},
|
|
50
|
+
body: new URLSearchParams({
|
|
51
|
+
Body: text || '',
|
|
52
|
+
From: from || TWILIO_SMS_FROM,
|
|
53
|
+
To: to,
|
|
54
|
+
}),
|
|
57
55
|
});
|
|
58
|
-
|
|
56
|
+
|
|
57
|
+
const data = await response.json();
|
|
58
|
+
|
|
59
|
+
if (!response.ok) {
|
|
59
60
|
return {
|
|
60
61
|
success: false,
|
|
61
62
|
error: {
|
|
62
63
|
name: 'TWILIO_ERROR',
|
|
63
|
-
message:
|
|
64
|
+
message: data.message || 'Failed to send SMS',
|
|
64
65
|
},
|
|
65
66
|
};
|
|
66
67
|
}
|
|
68
|
+
|
|
67
69
|
return {
|
|
68
70
|
success: true,
|
|
69
71
|
result: {
|
|
70
|
-
sid,
|
|
72
|
+
sid: data.sid,
|
|
71
73
|
},
|
|
72
74
|
error: null,
|
|
73
75
|
};
|
|
@@ -3,7 +3,7 @@ import later from '@breejs/later';
|
|
|
3
3
|
import { ProductPriceRate } from '@unchainedshop/core-products';
|
|
4
4
|
import { resolveBestCurrency } from '@unchainedshop/utils';
|
|
5
5
|
|
|
6
|
-
const getExchangeRates = async (base) => {
|
|
6
|
+
const getExchangeRates = async (base): Promise<{ currency: string; rates: Record<string, string> }> => {
|
|
7
7
|
return fetch(`https://api.coinbase.com/v2/exchange-rates?currency=${base}`, {
|
|
8
8
|
method: 'GET',
|
|
9
9
|
})
|
|
@@ -28,16 +28,13 @@ const UpdateCoinbaseRates: IWorkerAdapter<any, any> = {
|
|
|
28
28
|
|
|
29
29
|
const currencyCodes = currencies.map((currency) => currency.isoCode);
|
|
30
30
|
|
|
31
|
-
const {
|
|
32
|
-
currency: baseCurrency,
|
|
33
|
-
rates: pairs,
|
|
34
|
-
}: { currency: string; rates: Record<string, string> } = await getExchangeRates(currencyCode);
|
|
31
|
+
const { currency: baseCurrency, rates: pairs } = await getExchangeRates(currencyCode);
|
|
35
32
|
const timestamp = new Date();
|
|
36
33
|
|
|
37
34
|
// five minutes
|
|
38
35
|
const expiresAt = new Date(new Date().getTime() + 5 * 60 * 1000);
|
|
39
36
|
|
|
40
|
-
const rates:
|
|
37
|
+
const rates: ProductPriceRate[] = Object.entries(pairs)
|
|
41
38
|
.map(([quoteCurrency, rate]) => {
|
|
42
39
|
return {
|
|
43
40
|
baseCurrency,
|
|
@@ -3,7 +3,7 @@ import later from '@breejs/later';
|
|
|
3
3
|
import { xml2json } from 'xml-js';
|
|
4
4
|
import { ProductPriceRate } from '@unchainedshop/core-products';
|
|
5
5
|
|
|
6
|
-
const getExchangeRates = async () => {
|
|
6
|
+
const getExchangeRates = async (): Promise<{ currency: string; rate: string }[]> => {
|
|
7
7
|
return fetch(`https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml`, {
|
|
8
8
|
method: 'GET',
|
|
9
9
|
})
|
|
@@ -34,7 +34,7 @@ const UpdateECBRates: IWorkerAdapter<any, any> = {
|
|
|
34
34
|
const { modules } = unchainedAPI;
|
|
35
35
|
|
|
36
36
|
try {
|
|
37
|
-
const data
|
|
37
|
+
const data = await getExchangeRates();
|
|
38
38
|
const timestamp = new Date();
|
|
39
39
|
const expiresAt = new Date(new Date().getTime() + 24 * 60 * 60 * 1000);
|
|
40
40
|
|
|
@@ -50,7 +50,7 @@ const UpdateECBRates: IWorkerAdapter<any, any> = {
|
|
|
50
50
|
},
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
-
const rates:
|
|
53
|
+
const rates: ProductPriceRate[] = data
|
|
54
54
|
.map((d) => {
|
|
55
55
|
return {
|
|
56
56
|
baseCurrency,
|
package/src/worker/BaseWorker.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import later from '@breejs/later';
|
|
2
|
-
import { Work, WorkData } from '@unchainedshop/core-worker';
|
|
3
|
-
import { WorkerDirector } from '@unchainedshop/core';
|
|
4
|
-
|
|
5
|
-
export type IWorker<P extends { workerId?: string }> = {
|
|
6
|
-
key: string;
|
|
7
|
-
label: string;
|
|
8
|
-
version: string;
|
|
9
|
-
type: string;
|
|
10
|
-
external: boolean;
|
|
11
|
-
|
|
12
|
-
getFloorDate: (date?: Date) => Date;
|
|
13
|
-
|
|
14
|
-
actions: (
|
|
15
|
-
params: P,
|
|
16
|
-
unchainedAPI,
|
|
17
|
-
) => {
|
|
18
|
-
autorescheduleTypes: (options: { referenceDate: Date }) => Promise<Array<Work | null>>;
|
|
19
|
-
process: (options: { maxWorkItemCount?: number; referenceDate?: Date }) => Promise<void>;
|
|
20
|
-
reset: () => Promise<void>;
|
|
21
|
-
start: () => void;
|
|
22
|
-
stop: () => void;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
interface WorkerParams {
|
|
27
|
-
workerId?: string;
|
|
28
|
-
worker: IWorker<any>;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export const BaseWorker: IWorker<WorkerParams> = {
|
|
32
|
-
key: 'shop.unchained.worker.base',
|
|
33
|
-
label: 'Base worker. Do not use this directly.',
|
|
34
|
-
version: '1.0.0',
|
|
35
|
-
type: 'BASE',
|
|
36
|
-
external: false,
|
|
37
|
-
|
|
38
|
-
getFloorDate: (date = new Date()) => {
|
|
39
|
-
const floored = new Date(Math.floor(date.getTime() / 1000) * 1000);
|
|
40
|
-
return floored;
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
actions: ({ workerId }: WorkerParams, unchainedAPI) => {
|
|
44
|
-
const workerActions = {
|
|
45
|
-
start() {
|
|
46
|
-
throw new Error(`Not implemented on ${this.constructor.key}`);
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
stop() {
|
|
50
|
-
throw new Error(`Not implemented on ${this.constructor.key}`);
|
|
51
|
-
},
|
|
52
|
-
|
|
53
|
-
reset: async (referenceDate = new Date()) => {
|
|
54
|
-
await unchainedAPI.modules.worker.markOldWorkAsFailed({
|
|
55
|
-
types: WorkerDirector.getActivePluginTypes({ external: false }),
|
|
56
|
-
worker: workerId,
|
|
57
|
-
referenceDate,
|
|
58
|
-
});
|
|
59
|
-
},
|
|
60
|
-
|
|
61
|
-
autorescheduleTypes: async ({ referenceDate }) => {
|
|
62
|
-
return Promise.all(
|
|
63
|
-
WorkerDirector.getAutoSchedules().map(async ([scheduleId, workConfig]) => {
|
|
64
|
-
if (!workConfig.schedule) {
|
|
65
|
-
await unchainedAPI.modules.worker.ensureNoWork({
|
|
66
|
-
type: workConfig.type,
|
|
67
|
-
priority: workConfig.priority || 0,
|
|
68
|
-
scheduleId,
|
|
69
|
-
});
|
|
70
|
-
return null;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const fixedSchedule = { ...workConfig.schedule };
|
|
74
|
-
fixedSchedule.schedules[0].s = [0]; // ignore seconds, always run on second 0
|
|
75
|
-
const nextDate = later.schedule(fixedSchedule).next(1, referenceDate) as Date;
|
|
76
|
-
nextDate.setMilliseconds(0);
|
|
77
|
-
const workData: WorkData = {
|
|
78
|
-
type: workConfig.type,
|
|
79
|
-
scheduleId,
|
|
80
|
-
scheduled: nextDate,
|
|
81
|
-
timeout: workConfig.timeout,
|
|
82
|
-
priority: workConfig.priority || 0,
|
|
83
|
-
retries: workConfig.retries || 0,
|
|
84
|
-
};
|
|
85
|
-
if (workConfig.input) {
|
|
86
|
-
workData.input = await workConfig.input(workData);
|
|
87
|
-
// A work input fn can skip auto scheduling a new record
|
|
88
|
-
// when it explicitly returns a falsish input instead of a dictionary
|
|
89
|
-
if (!workData.input) return null;
|
|
90
|
-
}
|
|
91
|
-
return unchainedAPI.modules.worker.ensureOneWork(workData);
|
|
92
|
-
}),
|
|
93
|
-
);
|
|
94
|
-
},
|
|
95
|
-
|
|
96
|
-
process: async ({ maxWorkItemCount, referenceDate }) => {
|
|
97
|
-
await workerActions.autorescheduleTypes({
|
|
98
|
-
referenceDate,
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
const processRecursively = async (recursionCounter = 0) => {
|
|
102
|
-
if (maxWorkItemCount && maxWorkItemCount < recursionCounter) return null;
|
|
103
|
-
const doneWork = await WorkerDirector.processNextWork(unchainedAPI, workerId);
|
|
104
|
-
if (doneWork) return processRecursively(recursionCounter + 1);
|
|
105
|
-
return null;
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
await processRecursively();
|
|
109
|
-
},
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
workerActions.reset();
|
|
113
|
-
|
|
114
|
-
return workerActions;
|
|
115
|
-
},
|
|
116
|
-
};
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { subscribe } from '@unchainedshop/events';
|
|
2
|
-
import { BaseWorker, IWorker } from './BaseWorker.js';
|
|
3
|
-
import { WorkerEventTypes } from '@unchainedshop/core-worker';
|
|
4
|
-
|
|
5
|
-
function debounce<T extends (...args: any) => any>(func: T, wait) {
|
|
6
|
-
let timeout;
|
|
7
|
-
return (...args) => {
|
|
8
|
-
clearTimeout(timeout);
|
|
9
|
-
timeout = setTimeout(() => {
|
|
10
|
-
timeout = null;
|
|
11
|
-
func(...args);
|
|
12
|
-
}, wait);
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface EventListenerWorkerParams {
|
|
17
|
-
workerId?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const EventListenerWorker: IWorker<EventListenerWorkerParams> = {
|
|
21
|
-
...BaseWorker,
|
|
22
|
-
|
|
23
|
-
key: 'shop.unchained.worker.event-listener',
|
|
24
|
-
label: 'Allocates work on events. This worker does not make sense on multiple containers.',
|
|
25
|
-
version: '1.0.0',
|
|
26
|
-
type: 'EVENT_LISTENER',
|
|
27
|
-
|
|
28
|
-
actions: ({ workerId }, unchainedAPI) => {
|
|
29
|
-
const baseWorkerActions = BaseWorker.actions(
|
|
30
|
-
{ workerId, worker: EventListenerWorker },
|
|
31
|
-
unchainedAPI,
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
// Debounce in the event of many work queue events conflicting with each other
|
|
35
|
-
const processWorkQueue = debounce<() => Promise<void>>(async () => {
|
|
36
|
-
await baseWorkerActions.process({
|
|
37
|
-
maxWorkItemCount: 1, // only one work item at a time, else we could end up in a loop
|
|
38
|
-
referenceDate: EventListenerWorker.getFloorDate(),
|
|
39
|
-
});
|
|
40
|
-
}, 300);
|
|
41
|
-
|
|
42
|
-
return {
|
|
43
|
-
...baseWorkerActions,
|
|
44
|
-
|
|
45
|
-
start() {
|
|
46
|
-
subscribe(WorkerEventTypes.ADDED, processWorkQueue);
|
|
47
|
-
subscribe(WorkerEventTypes.FINISHED, processWorkQueue);
|
|
48
|
-
|
|
49
|
-
setTimeout(async () => {
|
|
50
|
-
await baseWorkerActions.autorescheduleTypes({
|
|
51
|
-
referenceDate: EventListenerWorker.getFloorDate(),
|
|
52
|
-
});
|
|
53
|
-
}, 300);
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
stop() {
|
|
57
|
-
/* */
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
},
|
|
61
|
-
};
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { defaultLogger } from '@unchainedshop/logger';
|
|
2
|
-
import { subscribe } from '@unchainedshop/events';
|
|
3
|
-
import { Work, WorkData, WorkerEventTypes } from '@unchainedshop/core-worker';
|
|
4
|
-
|
|
5
|
-
export interface FailedReschedulerParams {
|
|
6
|
-
retryInput?: (
|
|
7
|
-
workData: WorkData,
|
|
8
|
-
priorInput: Record<string, any>,
|
|
9
|
-
) => Promise<Record<string, any> | null>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export type IScheduler<P> = {
|
|
13
|
-
key: string;
|
|
14
|
-
label: string;
|
|
15
|
-
version: string;
|
|
16
|
-
|
|
17
|
-
actions: (
|
|
18
|
-
params: P,
|
|
19
|
-
unchainedAPI,
|
|
20
|
-
) => {
|
|
21
|
-
start: () => void;
|
|
22
|
-
stop: () => void;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const FailedRescheduler: IScheduler<FailedReschedulerParams> = {
|
|
27
|
-
key: 'shop.unchained.scheduler.failed',
|
|
28
|
-
label: 'Reschedule failed works',
|
|
29
|
-
version: '1.0.0',
|
|
30
|
-
|
|
31
|
-
actions: ({ retryInput }, unchainedAPI) => {
|
|
32
|
-
const handleFinishedWork = async ({ payload: work }: { payload: Work }) => {
|
|
33
|
-
if (!work.success && work.retries > 0) {
|
|
34
|
-
const now = new Date();
|
|
35
|
-
const workDelayMs = work.scheduled.getTime() - work.created.getTime();
|
|
36
|
-
|
|
37
|
-
// In short: Double the delay of the old work or delay for 5 seconds
|
|
38
|
-
const scheduled =
|
|
39
|
-
workDelayMs > 1000
|
|
40
|
-
? new Date(now.getTime() + workDelayMs * 2)
|
|
41
|
-
: new Date(now.setSeconds(now.getSeconds() + 5));
|
|
42
|
-
|
|
43
|
-
defaultLogger.error(
|
|
44
|
-
`${FailedRescheduler.key} -> Reschedule failed work ${work._id} ${
|
|
45
|
-
work.type
|
|
46
|
-
} for ${scheduled.toISOString()} (in ${Math.round(workDelayMs / 1000)}). Remaining retries: ${
|
|
47
|
-
work.retries
|
|
48
|
-
}`,
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
const workData: WorkData = {
|
|
52
|
-
type: work.type,
|
|
53
|
-
priority: work.priority,
|
|
54
|
-
originalWorkId: work.originalWorkId || work._id,
|
|
55
|
-
retries: work.retries - 1,
|
|
56
|
-
timeout: work.timeout,
|
|
57
|
-
scheduled,
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
if (retryInput) {
|
|
61
|
-
workData.input = await retryInput(workData, work.input);
|
|
62
|
-
} else {
|
|
63
|
-
workData.input = work.input;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
unchainedAPI.modules.worker.addWork(workData);
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
start() {
|
|
72
|
-
subscribe<Work>(WorkerEventTypes.FINISHED, handleFinishedWork);
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
stop() {
|
|
76
|
-
/* */
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
},
|
|
80
|
-
};
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import later, { ScheduleData } from '@breejs/later';
|
|
2
|
-
import { BaseWorker, IWorker } from './BaseWorker.js';
|
|
3
|
-
|
|
4
|
-
const { NODE_ENV } = process.env;
|
|
5
|
-
|
|
6
|
-
export interface IntervalWorkerParams {
|
|
7
|
-
workerId?: string;
|
|
8
|
-
batchCount?: number;
|
|
9
|
-
schedule?: ScheduleData;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const defaultSchedule = later.parse.text(
|
|
13
|
-
NODE_ENV !== 'production' ? 'every 2 seconds' : 'every 30 seconds',
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
export const scheduleToInterval = (schedule: ScheduleData) => {
|
|
17
|
-
const referenceDate = new Date(1000);
|
|
18
|
-
const [one, two] = later.schedule(schedule).next(2, referenceDate) as Date[];
|
|
19
|
-
const diff = new Date(two).getTime() - new Date(one).getTime();
|
|
20
|
-
return Math.min(1000 * 60 * 60, diff); // at least once every hour!
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export const IntervalWorker: IWorker<IntervalWorkerParams> = {
|
|
24
|
-
...BaseWorker,
|
|
25
|
-
|
|
26
|
-
key: 'shop.unchained.worker.cron',
|
|
27
|
-
label: 'Allocates work on fixed intervals with native node setInterval',
|
|
28
|
-
version: '1.0.0',
|
|
29
|
-
type: 'CRON',
|
|
30
|
-
|
|
31
|
-
actions: ({ workerId, batchCount = 0, schedule = defaultSchedule }, unchainedAPI) => {
|
|
32
|
-
const baseWorkerActions = BaseWorker.actions({ workerId, worker: IntervalWorker }, unchainedAPI);
|
|
33
|
-
|
|
34
|
-
const intervalDelay = scheduleToInterval(schedule);
|
|
35
|
-
let intervalHandle: NodeJS.Timeout;
|
|
36
|
-
|
|
37
|
-
return {
|
|
38
|
-
...baseWorkerActions,
|
|
39
|
-
|
|
40
|
-
start() {
|
|
41
|
-
intervalHandle = setInterval(() => {
|
|
42
|
-
baseWorkerActions.process({
|
|
43
|
-
maxWorkItemCount: batchCount,
|
|
44
|
-
referenceDate: IntervalWorker.getFloorDate(),
|
|
45
|
-
});
|
|
46
|
-
}, intervalDelay);
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
stop() {
|
|
50
|
-
clearInterval(intervalHandle);
|
|
51
|
-
},
|
|
52
|
-
};
|
|
53
|
-
},
|
|
54
|
-
};
|