@infrab4a/connect 5.3.0-beta.30 → 5.3.0-beta.32

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 (38) hide show
  1. package/index.cjs.js +333 -92
  2. package/index.esm.js +324 -74
  3. package/package.json +1 -1
  4. package/src/domain/shop-settings/models/shop-configs.d.ts +3 -12
  5. package/src/domain/shop-settings/models/types/antifraud-config.type.d.ts +21 -0
  6. package/src/domain/shop-settings/models/types/index.d.ts +1 -0
  7. package/src/domain/shop-settings/models/types/limit-orders.type.d.ts +3 -2
  8. package/src/domain/shopping/helpers/antifraud-enabled.helper.d.ts +8 -0
  9. package/src/domain/shopping/helpers/antifraud-volume-limits.helper.d.ts +6 -0
  10. package/src/domain/shopping/helpers/index.d.ts +2 -0
  11. package/src/domain/shopping/index.d.ts +1 -0
  12. package/src/domain/shopping/models/campaign-hashtag-posts.d.ts +23 -0
  13. package/src/domain/shopping/models/campaign-hashtag.d.ts +12 -10
  14. package/src/domain/shopping/models/checkout.d.ts +2 -0
  15. package/src/domain/shopping/models/coupons/coupon.d.ts +1 -0
  16. package/src/domain/shopping/models/index.d.ts +1 -0
  17. package/src/domain/shopping/models/line-item.d.ts +4 -0
  18. package/src/domain/shopping/models/order.d.ts +1 -0
  19. package/src/domain/shopping/models/shipping-method.d.ts +1 -0
  20. package/src/domain/shopping/models/types/line-item-recurrence.type.d.ts +1 -1
  21. package/src/domain/shopping/repositories/campaign-hashtag-posts.repository.d.ts +4 -0
  22. package/src/domain/shopping/repositories/index.d.ts +1 -0
  23. package/src/domain/shopping/services/antifraud-bankslip.service.d.ts +3 -1
  24. package/src/domain/shopping/services/antifraud-card.service.d.ts +6 -6
  25. package/src/domain/shopping/services/antifraud-glampoints.service.d.ts +4 -2
  26. package/src/domain/shopping/services/antifraud-pix.service.d.ts +4 -2
  27. package/src/domain/shopping/types/antifraud-card-validation.type.d.ts +40 -0
  28. package/src/domain/shopping/types/antifraud-volume-limits.type.d.ts +24 -0
  29. package/src/domain/shopping/types/create-recurrency-payload.type.d.ts +0 -2
  30. package/src/domain/shopping/types/index.d.ts +3 -0
  31. package/src/domain/shopping/types/shopping-recurrence-update-payloads.type.d.ts +35 -0
  32. package/src/infra/cache/index.d.ts +1 -0
  33. package/src/infra/cache/resolve-cache-config.d.ts +2 -0
  34. package/src/infra/cache/restcache.adapter.d.ts +3 -0
  35. package/src/infra/firebase/firestore/repositories/shopping/campaign-hashtag-posts-firestore.repository.d.ts +8 -0
  36. package/src/infra/firebase/firestore/repositories/shopping/index.d.ts +1 -0
  37. package/src/utils/index.d.ts +1 -0
  38. package/src/utils/to-cents.d.ts +5 -0
package/index.esm.js CHANGED
@@ -8,7 +8,7 @@ export { formatInTimeZone } from 'date-fns-tz';
8
8
  import { compact, get, isNil, isArray, first, last, flatten, isString, omit, each, unset, isObject, isEmpty, isDate, isBoolean, isInteger, isNumber, isNaN as isNaN$1, set, chunk, sortBy } from 'lodash';
9
9
  export { chunk, each, get, isBoolean, isDate, isEmpty, isInteger, isNaN, isNil, isNumber, isObject, isString, now, omit, pick, set, sortBy, unset } from 'lodash';
10
10
  import { debug } from 'debug';
11
- import * as serializeJavascript from 'serialize-javascript';
11
+ import serializeJavascript from 'serialize-javascript';
12
12
  import { CustomError } from 'ts-custom-error';
13
13
  import axios, { AxiosError } from 'axios';
14
14
  import { signInWithEmailAndPassword, signInWithPopup, GoogleAuthProvider, browserPopupRedirectResolver, signInAnonymously, sendPasswordResetEmail, createUserWithEmailAndPassword, sendEmailVerification } from 'firebase/auth';
@@ -151,6 +151,123 @@ class PaymentProviderFactory {
151
151
  }
152
152
  }
153
153
 
154
+ const ANTIFRAUD_CONFIG_CACHE_TTL_SECONDS = 60;
155
+ /**
156
+ * Lê `shopConfigs.antifraude.enabled`.
157
+ * - `false` explícito → antifraude desligado
158
+ * - ausente / erro / inválido → `true` (mantém comportamento histórico)
159
+ */
160
+ async function isAntifraudEnabled(shopConfigsRepository) {
161
+ if (!shopConfigsRepository) {
162
+ return true;
163
+ }
164
+ try {
165
+ const result = await shopConfigsRepository.find({}, { cache: { enabled: true, ttl: ANTIFRAUD_CONFIG_CACHE_TTL_SECONDS } });
166
+ const enabled = result?.data?.at(0)?.antifraude?.enabled;
167
+ if (typeof enabled === 'boolean') {
168
+ return enabled;
169
+ }
170
+ return true;
171
+ }
172
+ catch (error) {
173
+ console.warn(JSON.stringify({
174
+ msg: 'antifraud_enabled_config_load_failed',
175
+ enabled: true,
176
+ error: error instanceof Error ? error.message : String(error),
177
+ }));
178
+ return true;
179
+ }
180
+ }
181
+
182
+ /** Defaults de runtime (week.zip = Infinity). Usados só como fallback no checkout. */
183
+ const DEFAULT_ANTIFRAUD_VOLUME_LIMITS = {
184
+ enabled: true,
185
+ source: 'fallback',
186
+ day: {
187
+ subscriber: { cpf: 4, email: 4, phone: 4, card: 4, zip: 4 },
188
+ nonSubscriber: { cpf: 2, email: 2, phone: 2, card: 2, zip: 2 },
189
+ },
190
+ week: {
191
+ subscriber: { cpf: 12, email: 12, phone: 12, card: 12, zip: Infinity },
192
+ nonSubscriber: { cpf: 7, email: 7, phone: 7, card: 7, zip: Infinity },
193
+ },
194
+ blockedAttemptsDay: {
195
+ subscriber: 7,
196
+ nonSubscriber: 5,
197
+ },
198
+ };
199
+ function isPositiveInteger(value) {
200
+ return typeof value === 'number' && Number.isFinite(value) && value >= 1 && Number.isInteger(value);
201
+ }
202
+ function normalizeLimitOrders(raw, allowInfiniteZip) {
203
+ if (!raw)
204
+ return null;
205
+ const zip = allowInfiniteZip && (raw.zip === null || raw.zip === undefined || raw.zip === Infinity) ? Infinity : raw.zip;
206
+ const normalized = {
207
+ cpf: raw.cpf,
208
+ email: raw.email,
209
+ phone: raw.phone,
210
+ zip: zip,
211
+ card: raw.card,
212
+ };
213
+ for (const key of ['cpf', 'email', 'phone', 'zip', 'card']) {
214
+ if (key === 'zip' && normalized.zip === Infinity)
215
+ continue;
216
+ if (!isPositiveInteger(normalized[key]))
217
+ return null;
218
+ }
219
+ return normalized;
220
+ }
221
+ function cloneFallbackLimits() {
222
+ return {
223
+ ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS,
224
+ day: {
225
+ subscriber: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.day.subscriber },
226
+ nonSubscriber: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.day.nonSubscriber },
227
+ },
228
+ week: {
229
+ subscriber: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.week.subscriber },
230
+ nonSubscriber: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.week.nonSubscriber },
231
+ },
232
+ blockedAttemptsDay: { ...DEFAULT_ANTIFRAUD_VOLUME_LIMITS.blockedAttemptsDay },
233
+ source: 'fallback',
234
+ };
235
+ }
236
+ /** Config inválida/ausente → fallback (comportamento histórico). */
237
+ function resolveAntifraudVolumeLimits(antifraude) {
238
+ if (!antifraude || typeof antifraude.enabled !== 'boolean') {
239
+ return cloneFallbackLimits();
240
+ }
241
+ const daySubscriber = normalizeLimitOrders(antifraude.day?.subscriber, false);
242
+ const dayNonSubscriber = normalizeLimitOrders(antifraude.day?.nonSubscriber, false);
243
+ const weekSubscriber = normalizeLimitOrders(antifraude.week?.subscriber, true);
244
+ const weekNonSubscriber = normalizeLimitOrders(antifraude.week?.nonSubscriber, true);
245
+ const blocked = antifraude.blockedAttemptsDay;
246
+ if (!daySubscriber ||
247
+ !dayNonSubscriber ||
248
+ !weekSubscriber ||
249
+ !weekNonSubscriber ||
250
+ !blocked ||
251
+ !isPositiveInteger(blocked.subscriber) ||
252
+ !isPositiveInteger(blocked.nonSubscriber)) {
253
+ // Kill-switch explícito prevalece mesmo com payload inválido.
254
+ if (antifraude.enabled === false) {
255
+ return { ...cloneFallbackLimits(), enabled: false, source: 'fallback' };
256
+ }
257
+ return cloneFallbackLimits();
258
+ }
259
+ return {
260
+ enabled: antifraude.enabled,
261
+ source: 'config',
262
+ day: { subscriber: daySubscriber, nonSubscriber: dayNonSubscriber },
263
+ week: { subscriber: weekSubscriber, nonSubscriber: weekNonSubscriber },
264
+ blockedAttemptsDay: {
265
+ subscriber: blocked.subscriber,
266
+ nonSubscriber: blocked.nonSubscriber,
267
+ },
268
+ };
269
+ }
270
+
154
271
  const registry = new Map();
155
272
  function registerClass(name, classConstructor) {
156
273
  registry.set(name, classConstructor);
@@ -639,6 +756,19 @@ const serialize = (data) => {
639
756
  return serializeJavascript(data);
640
757
  };
641
758
 
759
+ /**
760
+ * Converts a BRL major-unit amount (e.g. 10.5) to integer cents (1050).
761
+ * Uses fixed 2-decimal normalization to avoid IEEE-754 artifacts like 19.99 * 100.
762
+ */
763
+ function toCents(amount) {
764
+ if (!Number.isFinite(amount)) {
765
+ throw new Error(`Invalid amount: ${amount}`);
766
+ }
767
+ const sign = amount < 0 ? -1 : 1;
768
+ const [whole, fraction = '0'] = Math.abs(amount).toFixed(2).split('.');
769
+ return sign * (Number(whole) * 100 + Number(fraction));
770
+ }
771
+
642
772
  class BaseModel {
643
773
  get identifier() {
644
774
  const fields = this.constructor.identifiersFields.filter((field) => field !== 'identifier');
@@ -1019,6 +1149,12 @@ class CampaignHashtag extends BaseModel {
1019
1149
  }
1020
1150
  }
1021
1151
 
1152
+ class CampaignHashtagPosts extends BaseModel {
1153
+ static get identifiersFields() {
1154
+ return ['id'];
1155
+ }
1156
+ }
1157
+
1022
1158
  class BeautyProfile extends BaseModel {
1023
1159
  toPlain() {
1024
1160
  const plain = super.toPlain();
@@ -1887,12 +2023,23 @@ class StockOutError extends BusinessError {
1887
2023
  }
1888
2024
  }
1889
2025
 
2026
+ /* eslint-disable no-console */
1890
2027
  class AntifraudBankSlipService {
1891
- constructor(orderBlockedRepository) {
2028
+ constructor(orderBlockedRepository, shopConfigsRepository) {
1892
2029
  this.orderBlockedRepository = orderBlockedRepository;
2030
+ this.shopConfigsRepository = shopConfigsRepository;
1893
2031
  this.MAX_ORDER_VALUE = 5000;
1894
2032
  }
1895
2033
  async validate(checkout) {
2034
+ const enabled = await isAntifraudEnabled(this.shopConfigsRepository);
2035
+ if (!enabled) {
2036
+ console.info(JSON.stringify({
2037
+ msg: 'antifraud_bankslip_skipped',
2038
+ enabled: false,
2039
+ checkoutId: checkout.id,
2040
+ }));
2041
+ return true;
2042
+ }
1896
2043
  if (checkout.totalPrice && checkout.totalPrice > this.MAX_ORDER_VALUE && !checkout.user?.isSubscriber) {
1897
2044
  await this.orderBlockedRepository.createBlockedOrderOrPayment({
1898
2045
  checkout,
@@ -1914,62 +2061,67 @@ class AntifraudBankSlipService {
1914
2061
  }
1915
2062
  }
1916
2063
 
2064
+ /* eslint-disable max-params */
1917
2065
  class AntifraudCardService {
1918
- constructor(orderRepository, orderBlockedRepository) {
2066
+ constructor(orderRepository, orderBlockedRepository, shopConfigsRepository) {
1919
2067
  this.orderRepository = orderRepository;
1920
2068
  this.orderBlockedRepository = orderBlockedRepository;
1921
- this.LIMIT_ORDERS_DAY = null;
1922
- this.LIMIT_ORDERS_WEEK = null;
2069
+ this.shopConfigsRepository = shopConfigsRepository;
1923
2070
  }
1924
2071
  async validate(checkout, card) {
1925
- this.setLimitsByUserType(checkout.user.isSubscriber);
1926
- await this.validateBlockedOrderAttempts(checkout, card);
1927
- await this.validateDayAndWeekOrderLimits(checkout, card);
2072
+ // Limites locais por request — evita race em provider Nest singleton entre awaits.
2073
+ const resolved = await this.loadResolvedLimits();
2074
+ const isSubscriber = !!checkout.user?.isSubscriber;
2075
+ const dayLimits = isSubscriber ? resolved.day.subscriber : resolved.day.nonSubscriber;
2076
+ const weekLimits = isSubscriber ? resolved.week.subscriber : resolved.week.nonSubscriber;
2077
+ const blockedAttemptsDay = isSubscriber
2078
+ ? resolved.blockedAttemptsDay.subscriber
2079
+ : resolved.blockedAttemptsDay.nonSubscriber;
2080
+ if (!resolved.enabled) {
2081
+ console.info(JSON.stringify({
2082
+ msg: 'antifraud_card_volume_skipped',
2083
+ source: resolved.source,
2084
+ enabled: false,
2085
+ checkoutId: checkout.id,
2086
+ isSubscriber,
2087
+ }));
2088
+ return true;
2089
+ }
2090
+ console.info(JSON.stringify({
2091
+ msg: 'antifraud_card_volume_limits',
2092
+ source: resolved.source,
2093
+ enabled: true,
2094
+ checkoutId: checkout.id,
2095
+ isSubscriber,
2096
+ blockedAttemptsDay,
2097
+ day: dayLimits,
2098
+ week: weekLimits,
2099
+ }));
2100
+ await this.validateBlockedOrderAttempts(checkout, card, blockedAttemptsDay);
2101
+ await this.validateDayAndWeekOrderLimits(checkout, card, dayLimits, weekLimits);
1928
2102
  return true;
1929
2103
  }
1930
- setLimitsByUserType(isSubscriber) {
1931
- this.LIMIT_ORDERS_DAY = {
1932
- subscriber: {
1933
- cpf: 4,
1934
- email: 4,
1935
- phone: 4,
1936
- card: 4,
1937
- zip: 4,
1938
- },
1939
- nonSubscriber: {
1940
- cpf: 2,
1941
- email: 2,
1942
- phone: 2,
1943
- card: 2,
1944
- zip: 2,
1945
- },
1946
- };
1947
- this.LIMIT_ORDERS_WEEK = {
1948
- subscriber: {
1949
- cpf: 12,
1950
- email: 12,
1951
- phone: 12,
1952
- card: 12,
1953
- zip: Infinity,
1954
- },
1955
- nonSubscriber: {
1956
- cpf: 7,
1957
- email: 7,
1958
- phone: 7,
1959
- card: 7,
1960
- zip: Infinity,
1961
- },
1962
- };
1963
- this.LIMIT_BLOCKED_ORDERS_DAY = isSubscriber ? 7 : 5;
1964
- }
1965
- getLimitsByUserType(type, isSubscriber) {
1966
- const limits = type === 'day' ? this.LIMIT_ORDERS_DAY : this.LIMIT_ORDERS_WEEK;
1967
- return isSubscriber ? limits['subscriber'] : limits['nonSubscriber'];
2104
+ async loadResolvedLimits() {
2105
+ if (!this.shopConfigsRepository) {
2106
+ return resolveAntifraudVolumeLimits(null);
2107
+ }
2108
+ try {
2109
+ const result = await this.shopConfigsRepository.find({}, { cache: { enabled: true, ttl: ANTIFRAUD_CONFIG_CACHE_TTL_SECONDS } });
2110
+ return resolveAntifraudVolumeLimits(result?.data?.at(0)?.antifraude);
2111
+ }
2112
+ catch (error) {
2113
+ console.warn(JSON.stringify({
2114
+ msg: 'antifraud_card_volume_config_load_failed',
2115
+ source: 'fallback',
2116
+ error: error instanceof Error ? error.message : String(error),
2117
+ }));
2118
+ return resolveAntifraudVolumeLimits(null);
2119
+ }
1968
2120
  }
1969
- async validateBlockedOrderAttempts(checkout, card) {
1970
- const isValid = await this.verifyBlockedOrderAttempts(checkout, card);
2121
+ async validateBlockedOrderAttempts(checkout, card, blockedAttemptsDay) {
2122
+ const isValid = await this.verifyBlockedOrderAttempts(checkout, card, blockedAttemptsDay);
1971
2123
  if (!isValid) {
1972
- throw new FraudValidationError(`Cliente com mais de ${this.LIMIT_BLOCKED_ORDERS_DAY} compras negadas/bloqueadas no dia`, ErrorsCode.fraudPreventionInternal, {
2124
+ throw new FraudValidationError(`Cliente com mais de ${blockedAttemptsDay} compras negadas/bloqueadas no dia`, ErrorsCode.fraudPreventionInternal, {
1973
2125
  checkoutId: checkout.id,
1974
2126
  userEmail: checkout.user.email,
1975
2127
  info: {
@@ -1980,8 +2132,8 @@ class AntifraudCardService {
1980
2132
  });
1981
2133
  }
1982
2134
  }
1983
- async validateDayAndWeekOrderLimits(checkout, card) {
1984
- const isValid = await this.verifyDayAndWeekOrders(checkout, card);
2135
+ async validateDayAndWeekOrderLimits(checkout, card, dayLimits, weekLimits) {
2136
+ const isValid = await this.verifyDayAndWeekOrders(checkout, card, dayLimits, weekLimits);
1985
2137
  if (!isValid) {
1986
2138
  throw new FraudValidationError('Cliente tentando comprar mais do que o permitido no dia/semana', ErrorsCode.fraudPreventionInternal, {
1987
2139
  checkoutId: checkout.id,
@@ -1994,15 +2146,15 @@ class AntifraudCardService {
1994
2146
  });
1995
2147
  }
1996
2148
  }
1997
- async verifyBlockedOrderAttempts(checkout, card) {
2149
+ async verifyBlockedOrderAttempts(checkout, card, blockedAttemptsDay) {
1998
2150
  const dateRange = this.getTodayDateRange();
1999
2151
  const blockedOrders = await this.getBlockedOrdersByMultipleCriteria(checkout, dateRange);
2000
2152
  const totalBlockedAttempts = this.calculateUniqueBlockedAttempts(blockedOrders, checkout);
2001
- if (totalBlockedAttempts >= this.LIMIT_BLOCKED_ORDERS_DAY) {
2153
+ if (totalBlockedAttempts >= blockedAttemptsDay) {
2002
2154
  await this.createBlockedOrderRecord({
2003
2155
  checkout,
2004
2156
  card,
2005
- reason: `More than ${this.LIMIT_BLOCKED_ORDERS_DAY} attempts have failed`,
2157
+ reason: `More than ${blockedAttemptsDay} attempts have failed`,
2006
2158
  key: 'Failed attempts',
2007
2159
  period: 'day',
2008
2160
  });
@@ -2104,12 +2256,12 @@ class AntifraudCardService {
2104
2256
  card,
2105
2257
  });
2106
2258
  }
2107
- async verifyDayAndWeekOrders(checkout, card) {
2259
+ async verifyDayAndWeekOrders(checkout, card, dayLimits, weekLimits) {
2108
2260
  const validationParams = this.buildValidationParams(checkout, card);
2109
- const isDayLimitValid = await this.validateDayOrderLimits(checkout, validationParams);
2261
+ const isDayLimitValid = await this.validateDayOrderLimits(checkout, validationParams, dayLimits);
2110
2262
  if (!isDayLimitValid)
2111
2263
  return false;
2112
- const isWeekLimitValid = await this.validateWeekOrderLimits(checkout, validationParams);
2264
+ const isWeekLimitValid = await this.validateWeekOrderLimits(checkout, validationParams, weekLimits);
2113
2265
  return isWeekLimitValid;
2114
2266
  }
2115
2267
  buildValidationParams(checkout, card) {
@@ -2121,9 +2273,8 @@ class AntifraudCardService {
2121
2273
  card,
2122
2274
  };
2123
2275
  }
2124
- async validateDayOrderLimits(checkout, params) {
2276
+ async validateDayOrderLimits(checkout, params, limits) {
2125
2277
  const ordersPerDay = await this.validateOrdersByRange(params, this.getDateRange('day'));
2126
- const limits = this.getLimitsByUserType('day', checkout.user.isSubscriber);
2127
2278
  return this.checkOrderLimitsAndBlock({
2128
2279
  checkout,
2129
2280
  orderCounts: ordersPerDay,
@@ -2131,9 +2282,8 @@ class AntifraudCardService {
2131
2282
  period: 'day',
2132
2283
  });
2133
2284
  }
2134
- async validateWeekOrderLimits(checkout, params) {
2285
+ async validateWeekOrderLimits(checkout, params, limits) {
2135
2286
  const ordersPerWeek = await this.validateOrdersByRange(params, this.getDateRange('week'));
2136
- const limits = this.getLimitsByUserType('week', checkout.user.isSubscriber);
2137
2287
  return this.checkOrderLimitsAndBlock({
2138
2288
  checkout,
2139
2289
  orderCounts: ordersPerWeek,
@@ -2210,15 +2360,35 @@ class AntifraudCardService {
2210
2360
  }
2211
2361
 
2212
2362
  class AntifraudGlampointsService {
2213
- constructor() { }
2214
- async validate(_checkout) {
2363
+ constructor(shopConfigsRepository) {
2364
+ this.shopConfigsRepository = shopConfigsRepository;
2365
+ }
2366
+ async validate(checkout) {
2367
+ const enabled = await isAntifraudEnabled(this.shopConfigsRepository);
2368
+ if (!enabled) {
2369
+ console.info(JSON.stringify({
2370
+ msg: 'antifraud_glampoints_skipped',
2371
+ enabled: false,
2372
+ checkoutId: checkout.id,
2373
+ }));
2374
+ }
2215
2375
  return true;
2216
2376
  }
2217
2377
  }
2218
2378
 
2219
2379
  class AntifraudPixService {
2220
- constructor() { }
2221
- async validate(_checkout) {
2380
+ constructor(shopConfigsRepository) {
2381
+ this.shopConfigsRepository = shopConfigsRepository;
2382
+ }
2383
+ async validate(checkout) {
2384
+ const enabled = await isAntifraudEnabled(this.shopConfigsRepository);
2385
+ if (!enabled) {
2386
+ console.info(JSON.stringify({
2387
+ msg: 'antifraud_pix_skipped',
2388
+ enabled: false,
2389
+ checkoutId: checkout.id,
2390
+ }));
2391
+ }
2222
2392
  return true;
2223
2393
  }
2224
2394
  }
@@ -2572,6 +2742,26 @@ class ShopSettings extends BaseModel {
2572
2742
  }
2573
2743
  }
2574
2744
 
2745
+ /**
2746
+ * Defaults iguais ao hardcode histórico do checkout.
2747
+ * `week.*.zip = null` → Infinity no runtime do volume de cartão.
2748
+ */
2749
+ const DEFAULT_SHOP_ANTIFRAUD_CONFIG = {
2750
+ enabled: true,
2751
+ day: {
2752
+ subscriber: { cpf: 4, email: 4, phone: 4, card: 4, zip: 4 },
2753
+ nonSubscriber: { cpf: 2, email: 2, phone: 2, card: 2, zip: 2 },
2754
+ },
2755
+ week: {
2756
+ subscriber: { cpf: 12, email: 12, phone: 12, card: 12, zip: null },
2757
+ nonSubscriber: { cpf: 7, email: 7, phone: 7, card: 7, zip: null },
2758
+ },
2759
+ blockedAttemptsDay: {
2760
+ subscriber: 7,
2761
+ nonSubscriber: 5,
2762
+ },
2763
+ };
2764
+
2575
2765
  class AdyenBlockedOrderHelper {
2576
2766
  static async handleUnauthorizedPayment(params) {
2577
2767
  await params.orderBlockedRepository.createBlockedOrderOrPayment({
@@ -2696,11 +2886,39 @@ class AdyenCardAxiosAdapter {
2696
2886
  }
2697
2887
  }
2698
2888
 
2889
+ function resolveCacheConfig(cache) {
2890
+ if (isNil(cache) || typeof cache !== 'object')
2891
+ return undefined;
2892
+ const candidate = cache;
2893
+ const cacheAdapter = candidate.cacheAdapter;
2894
+ if (!cacheAdapter)
2895
+ return undefined;
2896
+ if (!isCacheAdapter(cacheAdapter))
2897
+ return undefined;
2898
+ if (typeof cacheAdapter.isConfigured === 'function' && !cacheAdapter.isConfigured()) {
2899
+ return undefined;
2900
+ }
2901
+ return {
2902
+ cacheAdapter,
2903
+ ttlDefault: candidate.ttlDefault,
2904
+ };
2905
+ }
2906
+ function isCacheAdapter(adapter) {
2907
+ return (typeof adapter.get === 'function' &&
2908
+ typeof adapter.set === 'function' &&
2909
+ typeof adapter.remove === 'function' &&
2910
+ typeof adapter.clear === 'function');
2911
+ }
2912
+
2699
2913
  class RestCacheAdapter {
2700
2914
  constructor(config) {
2915
+ this.client = null;
2701
2916
  this.logger = new DebugHelper('RestCacheAdapter');
2917
+ this.configured = this.isValidBaseURL(config.baseURL);
2918
+ if (!this.configured)
2919
+ return;
2702
2920
  this.client = axios.create({
2703
- baseURL: config.baseURL,
2921
+ baseURL: config.baseURL.trim(),
2704
2922
  headers: {
2705
2923
  'Content-Type': 'application/json',
2706
2924
  ...(isNil(config.authToken) ? {} : { Authorization: `Bearer ${config.authToken}` }),
@@ -2708,7 +2926,12 @@ class RestCacheAdapter {
2708
2926
  },
2709
2927
  });
2710
2928
  }
2929
+ isConfigured() {
2930
+ return this.configured;
2931
+ }
2711
2932
  async set(options) {
2933
+ if (!this.client)
2934
+ return false;
2712
2935
  try {
2713
2936
  const response = await this.client.post('/redis/set', {
2714
2937
  key: options.key,
@@ -2724,6 +2947,8 @@ class RestCacheAdapter {
2724
2947
  }
2725
2948
  }
2726
2949
  async get(key) {
2950
+ if (!this.client)
2951
+ return null;
2727
2952
  try {
2728
2953
  const response = await this.client.post('/redis/get', {
2729
2954
  key,
@@ -2740,6 +2965,8 @@ class RestCacheAdapter {
2740
2965
  }
2741
2966
  }
2742
2967
  async remove(key) {
2968
+ if (!this.client)
2969
+ return false;
2743
2970
  try {
2744
2971
  const response = await this.client.post('/redis/del', {
2745
2972
  key,
@@ -2753,6 +2980,8 @@ class RestCacheAdapter {
2753
2980
  }
2754
2981
  }
2755
2982
  async clear() {
2983
+ if (!this.client)
2984
+ return false;
2756
2985
  try {
2757
2986
  const response = await this.client.post('/redis/flushdb', {});
2758
2987
  return response.data.success;
@@ -2763,6 +2992,9 @@ class RestCacheAdapter {
2763
2992
  return false;
2764
2993
  }
2765
2994
  }
2995
+ isValidBaseURL(baseURL) {
2996
+ return isString(baseURL) && baseURL.trim().length > 0;
2997
+ }
2766
2998
  }
2767
2999
 
2768
3000
  class AxiosAdapter {
@@ -5413,7 +5645,7 @@ class CampaignHashtagFirestoreRepository extends withCrudFirestore(withHelpers(w
5413
5645
  constructor({ firestore, interceptors, cache, }) {
5414
5646
  super({
5415
5647
  firestore,
5416
- collectionName: 'hashtagCampaignsAuto',
5648
+ collectionName: 'CampaignsHashtags',
5417
5649
  model: CampaignHashtag,
5418
5650
  interceptors,
5419
5651
  cache,
@@ -5421,6 +5653,18 @@ class CampaignHashtagFirestoreRepository extends withCrudFirestore(withHelpers(w
5421
5653
  }
5422
5654
  }
5423
5655
 
5656
+ class CampaignHashtagPostsFirestoreRepository extends withCrudFirestore(withHelpers(withFirestore(Base))) {
5657
+ constructor({ firestore, interceptors, cache, }) {
5658
+ super({
5659
+ firestore,
5660
+ collectionName: 'CampaignsHashtagsPosts',
5661
+ model: CampaignHashtagPosts,
5662
+ interceptors,
5663
+ cache,
5664
+ });
5665
+ }
5666
+ }
5667
+
5424
5668
  class CheckoutFirestoreRepository extends withCrudFirestore(withHelpers(withFirestore(Base))) {
5425
5669
  constructor({ firestore, interceptors, cache, }) {
5426
5670
  super({
@@ -6109,7 +6353,7 @@ function createHasuraGraphQLClass(MixinBase) {
6109
6353
  this.model = options.model;
6110
6354
  this.fields = options.fields || this.model.identifiersFields;
6111
6355
  this.logger = DebugHelper.from(this);
6112
- this.cache = options.cache;
6356
+ this.cache = resolveCacheConfig(options.cache);
6113
6357
  }
6114
6358
  get headers() {
6115
6359
  return HasuraAuthHelper.buildHeaders(this.authOptions);
@@ -11106,9 +11350,9 @@ class PagarmeV5BaseAxiosAdapter {
11106
11350
  }
11107
11351
  async refund(order, amount) {
11108
11352
  try {
11109
- console.warn('[PAGARME REFUND] Starting refund process for order', order.id, order.payment, 'with amount', amount);
11110
- const amountToSend = +amount.toFixed(2) * 100;
11111
- console.warn('[PAGARME REFUND] Amount to send in cents', amountToSend);
11353
+ console.warn('[PAGARME REFUND] Starting refund process for order', order.id, order.payment.payment_method, order.payment.amount, 'to refund with amount', amount);
11354
+ const amountInCents = toCents(amount);
11355
+ console.warn('[PAGARME REFUND] Amount to send in cents', amountInCents);
11112
11356
  const { data } = await axios({
11113
11357
  method: 'DELETE',
11114
11358
  url: `${this.credentials.URL}/charges/${order.payment.charger_id}`,
@@ -11117,7 +11361,7 @@ class PagarmeV5BaseAxiosAdapter {
11117
11361
  'Content-Type': 'application/json',
11118
11362
  },
11119
11363
  data: {
11120
- amount: amountToSend,
11364
+ amount: amountInCents,
11121
11365
  },
11122
11366
  });
11123
11367
  console.warn('[RESPONSE PAGARME REFUND]', JSON.stringify(data));
@@ -11133,7 +11377,13 @@ class PagarmeV5BaseAxiosAdapter {
11133
11377
  });
11134
11378
  return {
11135
11379
  status: this.getRefundStatus(data.status),
11136
- success: [PagarMeV5OrderStatus.Pago, PagarMeV5OrderStatus.Cancelado].includes(data.status) ? true : false,
11380
+ success: [
11381
+ PagarMeV5OrderStatus.Pago,
11382
+ PagarMeV5OrderStatus.Cancelado,
11383
+ PagarMeV5PaymentStatus['Em processamento'],
11384
+ ].includes(data.status)
11385
+ ? true
11386
+ : false,
11137
11387
  };
11138
11388
  }
11139
11389
  catch (error) {
@@ -11520,4 +11770,4 @@ class ProductsVertexSearch {
11520
11770
  }
11521
11771
  }
11522
11772
 
11523
- export { AccessoryImportances, Address, AdyenCardAxiosAdapter, AdyenPaymentMethodFactory, AntifraudBankSlipService, AntifraudCardService, AntifraudGlampointsService, AntifraudPixService, AntifraudProviderFactory, AntifraudProviders, Area, Authentication, AuthenticationFirebaseAuthService, AxiosAdapter, Base, BaseModel, BeardProblems, BeardSizes, BeautyProductImportances, BeautyProfile, BeautyQuestionsHelper, BillingStatus, BodyProblems, BodyShapes, BodyTattoos, BrandCategory, BrandCategoryFirestoreRepository, BrandEquityOptions, BusinessError, BusinessUnitEnum, Buy2Win, Buy2WinFirestoreRepository, Campaign, CampaignBanner, CampaignDashboard, CampaignDashboardFirestoreRepository, CampaignHashtag, CampaignHashtagFirestoreRepository, Category, CategoryCollectionChildren, CategoryCollectionChildrenHasuraGraphQLRepository, CategoryFilter, CategoryFilterHasuraGraphQLRepository, CategoryFirestoreRepository, CategoryHasuraGraphQL, CategoryHasuraGraphQLRepository, CategoryProduct, CategoryProductHasuraGraphQLRepository, Checkout, CheckoutFirestoreRepository, CheckoutSubscription, CheckoutSubscriptionFirestoreRepository, CheckoutTypes, ClassNameHelper, ConnectBaseDocumentSnapshot, ConnectCollectionService, ConnectDocumentService, ConnectFirestoreService, Coupon, CouponCategories, CouponCategory, CouponChannels, CouponFirestoreRepository, CouponOldCategories, CouponSubtypes, CouponTypes, Debug, DebugDecoratorHelper, DebugHelper, DebugNamespaces, DuplicatedResultsError, Edition, EditionStatus, ErrorsCode, Exclusivities, FaceSkinOilinesses, FaceSkinProblems, FaceSkinTones, FamilyIncomes, Filter, FilterHasuraGraphQLRepository, FilterOption, FilterOptionHasuraGraphQLRepository, FilterType, FirebaseFileUploaderService, FragranceImportances, FraudValidationError, GenderDestination, GlampointsPaymentMethodFactory, GlampointsPaymentService, Group, GroupFirestoreRepository, HairColors, HairProblems, HairStrands, HairTypes, Home, HomeFirestoreRepository, InvalidArgumentError, InvalidCheckoutError, KitProduct, KitProductHasuraGraphQL, Lead, LeadFirestoreRepository, LegacyOrderFirestoreRepository, LineItem, Log, LogDocument, LogFirestoreRepository, Logger, MercadoPagoBankSlipAxiosAdapter, MercadoPagoCardAxiosAdapter, MercadoPagoErrorHelper, MercadoPagoPaymentMethodFactory, MercadoPagoPixAxiosAdapter, MercadoPagoRequestHelper, MercadoPagoResponseHelper, MercadoPagoStatusDetailEnum, MercadoPagoStatusEnum, NotFoundError, ObsEmitter, OfficePosition, Order, OrderBlocked, OrderBlockedFirestoreRepository, OrderBlockedType, OrderFirestoreRepository, OrderPaymentStatus, OrderStatus, PagarMeV5OrderStatus, PagarMeV5PaymentStatus, PagarmeBankSlipAxiosAdapter, PagarmeCardAxiosAdapter, PagarmePaymentMethodFactory, PagarmePaymentStatus, PagarmePixAxiosAdapter, PagarmeV5BankSlipAxiosAdapter, PagarmeV5BaseAxiosAdapter, PagarmeV5CardAxiosAdapter, PagarmeV5PixAxiosAdapter, Payment, PaymentError, PaymentFirestoreRepository, PaymentMethods, PaymentProviderFactory, PaymentProviders, PaymentTransaction, PaymentType, PersonTypes, Plans, Product, ProductCatalogHasuraGraphQL, ProductCatalogHasuraGraphQLRepository, ProductErrors, ProductErrorsHasuraGraphQL, ProductErrorsHasuraGraphQLRepository, ProductFirestoreRepository, ProductGroup, ProductGroupHasuraGraphQLRepository, ProductHasuraGraphQL, ProductHasuraGraphQLRepository, ProductLabelEnum, ProductPriceLog, ProductPriceLogHasuraGraphQLRepository, ProductReview, ProductReviewHasuraGraphQLRepository, ProductSpents, ProductStockEntry, ProductStockEntryHasuraGraphQL, ProductStockEntryHasuraGraphQLRepository, ProductStockNotification, ProductStockNotificationHasuraGraphQLRepository, ProductVariantFirestoreRepository, ProductsIndex, ProductsVertexSearch, QuestionsFilters, RecoveryPassword, ReflectHelper, Register, RegisterFirebaseAuthService, RequiredArgumentError, RestCacheAdapter, RoundProductPricesHelper, Sequence, SequenceFirestoreRepository, ShippingMethod, ShopConfigs, ShopConfigsFirestoreRepository, ShopMenu, ShopMenuFirestoreRepository, ShopPageName, ShopSettings, ShopSettingsFirestoreRepository, ShoppingRecurrence, ShoppingRecurrenceCycle, ShoppingRecurrenceEdition, ShoppingRecurrenceEditionFirestoreRepository, ShoppingRecurrenceEditionStatus, ShoppingRecurrenceErrorLog, ShoppingRecurrenceErrorLogFirestoreRepository, ShoppingRecurrenceFirestoreRepository, ShoppingRecurrenceStatus, Shops, SignInMethods, SignOut, Status, StockLimitError, StockOutError, Subscription, SubscriptionEditionFirestoreRepository, SubscriptionFirestoreRepository, SubscriptionMaterialization, SubscriptionMaterializationFirestoreRepository, SubscriptionPayment, SubscriptionPaymentFirestoreRepository, SubscriptionPlan, SubscriptionPlanFirestoreRepository, SubscriptionProductFirestoreRepository, SubscriptionSummary, SubscriptionSummaryFirestoreRepository, Trace, TransactionPaymentMethods, UnauthorizedError, UpdateOptionActions, UpdateUserImage, User, UserAddress, UserAddressFirestoreRepository, UserAlreadyRegisteredError, UserBeautyProfileFirestoreRepository, UserFirestoreRepository, UserPaymentMethod, UserPaymentMethodFirestoreRepository, UserType, Variant, VariantHasuraGraphQL, VariantHasuraGraphQLRepository, VertexAxiosAdapter, WeakPasswordError, Where, Wishlist, WishlistHasuraGraphQLRepository, WishlistLogType, deserialize, getClass, is, isDebuggable, isUUID, parseDateTime, registerClass, resolveClass, serialize, withCreateFirestore, withCreateHasuraGraphQL, withCrudFirestore, withCrudHasuraGraphQL, withDeleteFirestore, withDeleteHasuraGraphQL, withFindFirestore, withFindHasuraGraphQL, withFirestore, withGetFirestore, withGetHasuraGraphQL, withHasuraGraphQL, withHelpers, withSubCollection, withUpdateFirestore, withUpdateHasuraGraphQL };
11773
+ export { ANTIFRAUD_CONFIG_CACHE_TTL_SECONDS, AccessoryImportances, Address, AdyenCardAxiosAdapter, AdyenPaymentMethodFactory, AntifraudBankSlipService, AntifraudCardService, AntifraudGlampointsService, AntifraudPixService, AntifraudProviderFactory, AntifraudProviders, Area, Authentication, AuthenticationFirebaseAuthService, AxiosAdapter, Base, BaseModel, BeardProblems, BeardSizes, BeautyProductImportances, BeautyProfile, BeautyQuestionsHelper, BillingStatus, BodyProblems, BodyShapes, BodyTattoos, BrandCategory, BrandCategoryFirestoreRepository, BrandEquityOptions, BusinessError, BusinessUnitEnum, Buy2Win, Buy2WinFirestoreRepository, Campaign, CampaignBanner, CampaignDashboard, CampaignDashboardFirestoreRepository, CampaignHashtag, CampaignHashtagFirestoreRepository, CampaignHashtagPosts, CampaignHashtagPostsFirestoreRepository, Category, CategoryCollectionChildren, CategoryCollectionChildrenHasuraGraphQLRepository, CategoryFilter, CategoryFilterHasuraGraphQLRepository, CategoryFirestoreRepository, CategoryHasuraGraphQL, CategoryHasuraGraphQLRepository, CategoryProduct, CategoryProductHasuraGraphQLRepository, Checkout, CheckoutFirestoreRepository, CheckoutSubscription, CheckoutSubscriptionFirestoreRepository, CheckoutTypes, ClassNameHelper, ConnectBaseDocumentSnapshot, ConnectCollectionService, ConnectDocumentService, ConnectFirestoreService, Coupon, CouponCategories, CouponCategory, CouponChannels, CouponFirestoreRepository, CouponOldCategories, CouponSubtypes, CouponTypes, DEFAULT_ANTIFRAUD_VOLUME_LIMITS, DEFAULT_SHOP_ANTIFRAUD_CONFIG, Debug, DebugDecoratorHelper, DebugHelper, DebugNamespaces, DuplicatedResultsError, Edition, EditionStatus, ErrorsCode, Exclusivities, FaceSkinOilinesses, FaceSkinProblems, FaceSkinTones, FamilyIncomes, Filter, FilterHasuraGraphQLRepository, FilterOption, FilterOptionHasuraGraphQLRepository, FilterType, FirebaseFileUploaderService, FragranceImportances, FraudValidationError, GenderDestination, GlampointsPaymentMethodFactory, GlampointsPaymentService, Group, GroupFirestoreRepository, HairColors, HairProblems, HairStrands, HairTypes, Home, HomeFirestoreRepository, InvalidArgumentError, InvalidCheckoutError, KitProduct, KitProductHasuraGraphQL, Lead, LeadFirestoreRepository, LegacyOrderFirestoreRepository, LineItem, Log, LogDocument, LogFirestoreRepository, Logger, MercadoPagoBankSlipAxiosAdapter, MercadoPagoCardAxiosAdapter, MercadoPagoErrorHelper, MercadoPagoPaymentMethodFactory, MercadoPagoPixAxiosAdapter, MercadoPagoRequestHelper, MercadoPagoResponseHelper, MercadoPagoStatusDetailEnum, MercadoPagoStatusEnum, NotFoundError, ObsEmitter, OfficePosition, Order, OrderBlocked, OrderBlockedFirestoreRepository, OrderBlockedType, OrderFirestoreRepository, OrderPaymentStatus, OrderStatus, PagarMeV5OrderStatus, PagarMeV5PaymentStatus, PagarmeBankSlipAxiosAdapter, PagarmeCardAxiosAdapter, PagarmePaymentMethodFactory, PagarmePaymentStatus, PagarmePixAxiosAdapter, PagarmeV5BankSlipAxiosAdapter, PagarmeV5BaseAxiosAdapter, PagarmeV5CardAxiosAdapter, PagarmeV5PixAxiosAdapter, Payment, PaymentError, PaymentFirestoreRepository, PaymentMethods, PaymentProviderFactory, PaymentProviders, PaymentTransaction, PaymentType, PersonTypes, Plans, Product, ProductCatalogHasuraGraphQL, ProductCatalogHasuraGraphQLRepository, ProductErrors, ProductErrorsHasuraGraphQL, ProductErrorsHasuraGraphQLRepository, ProductFirestoreRepository, ProductGroup, ProductGroupHasuraGraphQLRepository, ProductHasuraGraphQL, ProductHasuraGraphQLRepository, ProductLabelEnum, ProductPriceLog, ProductPriceLogHasuraGraphQLRepository, ProductReview, ProductReviewHasuraGraphQLRepository, ProductSpents, ProductStockEntry, ProductStockEntryHasuraGraphQL, ProductStockEntryHasuraGraphQLRepository, ProductStockNotification, ProductStockNotificationHasuraGraphQLRepository, ProductVariantFirestoreRepository, ProductsIndex, ProductsVertexSearch, QuestionsFilters, RecoveryPassword, ReflectHelper, Register, RegisterFirebaseAuthService, RequiredArgumentError, RestCacheAdapter, RoundProductPricesHelper, Sequence, SequenceFirestoreRepository, ShippingMethod, ShopConfigs, ShopConfigsFirestoreRepository, ShopMenu, ShopMenuFirestoreRepository, ShopPageName, ShopSettings, ShopSettingsFirestoreRepository, ShoppingRecurrence, ShoppingRecurrenceCycle, ShoppingRecurrenceEdition, ShoppingRecurrenceEditionFirestoreRepository, ShoppingRecurrenceEditionStatus, ShoppingRecurrenceErrorLog, ShoppingRecurrenceErrorLogFirestoreRepository, ShoppingRecurrenceFirestoreRepository, ShoppingRecurrenceStatus, Shops, SignInMethods, SignOut, Status, StockLimitError, StockOutError, Subscription, SubscriptionEditionFirestoreRepository, SubscriptionFirestoreRepository, SubscriptionMaterialization, SubscriptionMaterializationFirestoreRepository, SubscriptionPayment, SubscriptionPaymentFirestoreRepository, SubscriptionPlan, SubscriptionPlanFirestoreRepository, SubscriptionProductFirestoreRepository, SubscriptionSummary, SubscriptionSummaryFirestoreRepository, Trace, TransactionPaymentMethods, UnauthorizedError, UpdateOptionActions, UpdateUserImage, User, UserAddress, UserAddressFirestoreRepository, UserAlreadyRegisteredError, UserBeautyProfileFirestoreRepository, UserFirestoreRepository, UserPaymentMethod, UserPaymentMethodFirestoreRepository, UserType, Variant, VariantHasuraGraphQL, VariantHasuraGraphQLRepository, VertexAxiosAdapter, WeakPasswordError, Where, Wishlist, WishlistHasuraGraphQLRepository, WishlistLogType, deserialize, getClass, is, isAntifraudEnabled, isDebuggable, isUUID, parseDateTime, registerClass, resolveAntifraudVolumeLimits, resolveCacheConfig, resolveClass, serialize, toCents, withCreateFirestore, withCreateHasuraGraphQL, withCrudFirestore, withCrudHasuraGraphQL, withDeleteFirestore, withDeleteHasuraGraphQL, withFindFirestore, withFindHasuraGraphQL, withFirestore, withGetFirestore, withGetHasuraGraphQL, withHasuraGraphQL, withHelpers, withSubCollection, withUpdateFirestore, withUpdateHasuraGraphQL };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@infrab4a/connect",
3
- "version": "5.3.0-beta.30",
3
+ "version": "5.3.0-beta.32",
4
4
  "publishConfig": {
5
5
  "registry": "https://registry.npmjs.org"
6
6
  },
@@ -1,18 +1,9 @@
1
1
  import { BaseModel, GenericIdentifier } from '../../generic/model';
2
- import { LimitOrders, ShopErrorMessages, ShopSameDayNotAvailable } from './types';
2
+ import { ShopAntifraudConfig, ShopErrorMessages, ShopSameDayNotAvailable } from './types';
3
3
  export declare class ShopConfigs extends BaseModel<ShopConfigs> {
4
+ id: string;
4
5
  errors?: ShopErrorMessages[];
5
- antifraude?: {
6
- enabled: boolean;
7
- week: {
8
- subscriber: LimitOrders;
9
- nonSubscriber: LimitOrders;
10
- };
11
- day: {
12
- subscriber: LimitOrders;
13
- nonSubscriber: LimitOrders;
14
- };
15
- };
6
+ antifraude?: ShopAntifraudConfig;
16
7
  sameDayNotAvaliable?: ShopSameDayNotAvailable;
17
8
  static get identifiersFields(): GenericIdentifier[];
18
9
  }
@@ -0,0 +1,21 @@
1
+ import { LimitOrders } from './limit-orders.type';
2
+ export type AntifraudBlockedAttemptsDay = {
3
+ subscriber: number;
4
+ nonSubscriber: number;
5
+ };
6
+ export type AntifraudPeriodLimits = {
7
+ subscriber: LimitOrders;
8
+ nonSubscriber: LimitOrders;
9
+ };
10
+ /** Shape persistido em Firestore `shopConfigs.antifraude`. */
11
+ export type ShopAntifraudConfig = {
12
+ enabled: boolean;
13
+ day: AntifraudPeriodLimits;
14
+ week: AntifraudPeriodLimits;
15
+ blockedAttemptsDay: AntifraudBlockedAttemptsDay;
16
+ };
17
+ /**
18
+ * Defaults iguais ao hardcode histórico do checkout.
19
+ * `week.*.zip = null` → Infinity no runtime do volume de cartão.
20
+ */
21
+ export declare const DEFAULT_SHOP_ANTIFRAUD_CONFIG: ShopAntifraudConfig;