@cobre-npm/library-portal-core 0.64.0 → 0.66.0

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 (33) hide show
  1. package/README.md +22 -8
  2. package/dist/cjs/canonicalTransactions/nature/catalog.d.ts +6 -0
  3. package/dist/cjs/canonicalTransactions/nature/catalog.js +2 -0
  4. package/dist/cjs/canonicalTransactions/nature/locales/en.json +3 -1
  5. package/dist/cjs/canonicalTransactions/nature/locales/es-mex.json +3 -1
  6. package/dist/cjs/currencies/catalog.d.ts +4 -0
  7. package/dist/cjs/currencies/catalog.js +3 -3
  8. package/dist/cjs/financialInstitutions/utils/financial-institution.utils.d.ts +9 -2
  9. package/dist/cjs/financialInstitutions/utils/financial-institution.utils.js +8 -7
  10. package/dist/cjs/movements/index.d.ts +1 -1
  11. package/dist/cjs/movements/types/catalog.d.ts +18 -1
  12. package/dist/cjs/movements/types/catalog.js +2 -0
  13. package/dist/cjs/movements/types/locales/en.json +3 -1
  14. package/dist/cjs/movements/types/locales/es-mex.json +3 -1
  15. package/dist/cjs/movements/types/utils/movement-type.utils.d.ts +10 -3
  16. package/dist/cjs/movements/types/utils/movement-type.utils.js +9 -2
  17. package/dist/cjs/transactions/types/catalog.d.ts +24 -0
  18. package/dist/cjs/transactions/types/catalog.js +24 -0
  19. package/dist/cjs/transactions/types/locales/en.json +4 -1
  20. package/dist/cjs/transactions/types/locales/es-mex.json +4 -1
  21. package/dist/esm/canonicalTransactions/nature/catalog.js +2 -0
  22. package/dist/esm/canonicalTransactions/nature/locales/en.json +3 -1
  23. package/dist/esm/canonicalTransactions/nature/locales/es-mex.json +3 -1
  24. package/dist/esm/currencies/catalog.js +3 -3
  25. package/dist/esm/financialInstitutions/utils/financial-institution.utils.js +8 -7
  26. package/dist/esm/movements/types/catalog.js +2 -0
  27. package/dist/esm/movements/types/locales/en.json +3 -1
  28. package/dist/esm/movements/types/locales/es-mex.json +3 -1
  29. package/dist/esm/movements/types/utils/movement-type.utils.js +9 -2
  30. package/dist/esm/transactions/types/catalog.js +24 -0
  31. package/dist/esm/transactions/types/locales/en.json +4 -1
  32. package/dist/esm/transactions/types/locales/es-mex.json +4 -1
  33. package/package.json +1 -1
package/README.md CHANGED
@@ -286,9 +286,12 @@ queryMovementStatuses({ lang: "en", type: "error" }) // error, failed, rejected
286
286
  `section: FilterClassificationSection` (`cop | mxn | usd_global | eur | corridors | stablecoin | …`), the heading it
287
287
  is listed under in grouped filters. `getMovementTypes()` returns each rail's own `label` unchanged.
288
288
  - **types query** (i18n `queryX()`): `queryMovementTypes({ lang, ...filters })` — same rules as
289
- `queryTransactionTypes`/`queryDocumentTypes`, no default field. `code`, `line`, `category` and `section` are
290
- filterable (equality only; a list matches any of its values). A present key always filters, so an optional UI
291
- filter has to be spread in conditionally:
289
+ `queryTransactionTypes`/`queryDocumentTypes`. `code`, `line`, `category` and `section` are
290
+ filterable (equality only; a list matches any of its values). `scope` is the one field with a default: `mint` and
291
+ `redeem` carry `scope: "internal_ops"` (internal operations of a single client), so they never come back from
292
+ `queryMovementTypes({ lang })` and no filter offers them. To read their label use `getMovementTypes(lang).mint`, or
293
+ ask for them with `{ scope: "internal_ops" }`; `{ code: "mint" }` alone returns `[]`. A present key always filters,
294
+ so an optional UI filter has to be spread in conditionally:
292
295
 
293
296
  ```ts
294
297
  queryMovementTypes({ lang, ...(section.value ? { section: section.value } : {}) })
@@ -410,6 +413,9 @@ queryCurrencies({ type: "fiat" }) // [ cop, mxn, usd ] → the list a pic
410
413
 
411
414
  No `lang`: the `label` is fixed (a display code, the same in any language).
412
415
 
416
+ `symbol` is the token's display ticker (`usdt` → `USDT`, `usdc` → `USDC`, `copco` → `COPco`) and exists only on
417
+ tokens: `label` can't serve as one (the label of `usdc` is `USD (USDC)`). Fall back to `code.toUpperCase()` when absent.
418
+
413
419
  **Which one to use.** `getCurrencies()` is the catalog keyed by code — use it to look a single currency
414
420
  up (`getCurrencies()[code]`) or when you genuinely want all of them. `queryCurrencies()` returns a
415
421
  **list**, narrowed by the query, and is what a dropdown, table filter or picker should call.
@@ -498,7 +504,7 @@ queryTransactionTypes({ lang: "en", category: "top_up" }) // col_top_up_credit
498
504
 
499
505
  ```ts
500
506
  collapseTransactionTypes({ lang: "en", category: "conversions" }).map(option => option.code)
501
- // 7 conversion types → 4 options: ["on_ramp", "off_ramp", "stable_payout", "offramp_treasury_credit"]
507
+ // 10 conversion types → 7 options: ["on_ramp", "off_ramp", "stable_payout", "offramp_treasury_credit", "stable_credit", "stable_debit", "stable_refund"]
502
508
  collapseTransactionTypes({ lang: "en", creditDebitType: "debit" }) // no group survives: plain legs only
503
509
  const groups = collapseTransactionTypes({ lang: "en" }).filter(isGroupOption)
504
510
  expandGroupSelection(["cbmm", "spei_debit"], groups) // ["cbmm_debit", "cbmm_credit", "spei_debit"]
@@ -631,16 +637,17 @@ import type {
631
637
  - `ICanonicalAllowedActions.can_report_problem` is optional until `core-portal-bff` emits it (BLCK-32190); make it
632
638
  required then. `ICanonicalParticipant.subclient` is present only when the movement was made on a subclient's behalf.
633
639
  - **productType / nature** (i18n): `getProductTypes(lang)` / `getNatures(lang)` cover the 5 `product_type` and 6
634
- `nature` values of the BFF's `rail-mapper.interface.ts` (the source of truth), and `CanonicalProductType` /
640
+ `nature` values of the BFF's `rail-mapper.interface.ts` (the source of truth), plus the `mint` and `redeem` natures,
641
+ which the BFF adds in BLCK-33095, and `CanonicalProductType` /
635
642
  `CanonicalNature` are derived from them — `conversion`, `on_ramp` and `off_ramp` used to be missing. `en` labels
636
643
  are the humanized code in Title Case (`on_ramp` → "On Ramp"); `es-mex` labels are Design's copy (`payout` →
637
644
  "Transferencia", `payin` → "Depósito", `cross_border` → "Internacional", `payment` → "Pago", `collection` →
638
645
  "Recaudo", `return` → "Reversión", `on_ramp` → "Conversión a stablecoin", `off_ramp` → "Conversión a moneda
639
- local"). Only `getX()` for now (no `queryX()`).
646
+ local", `mint` → "Emisión", `redeem` → "Canje"). Only `getX()` for now (no `queryX()`).
640
647
  They are not duplicates of `businessLines` or `movements/types`: `product_type` is the BFF's per-transaction class
641
648
  and flips with the ledger direction (`payin` ↔ `payout`), whereas a `BusinessLine` is fixed per movement type;
642
649
  the value sets differ (`internal_transfer`, `conversion` vs `cbmm`, `stable`, `unclassified`) and
643
- `movements/types` has 26 rail codes, not 5 classes. The only shared label is `cross_border`.
650
+ `movements/types` has 28 rail codes (26 regular plus `mint`/`redeem`), not 5 classes. The only shared label is `cross_border`.
644
651
 
645
652
  ### `exports`
646
653
 
@@ -706,12 +713,14 @@ import {
706
713
  import {
707
714
  getFinancialInstitutions, queryFinancialInstitutions,
708
715
  type FinancialInstitution, type FinancialInstitutionGeo,
709
- type FinancialInstitutionOption, type FinancialInstitutionQuery, type FinancialInstitutionScope,
716
+ type FinancialInstitutionCatalog, type FinancialInstitutionOption, type FinancialInstitutionQuery,
717
+ type FinancialInstitutionScope,
710
718
  } from "@cobre-npm/library-portal-core/financialInstitutions"
711
719
 
712
720
  getFinancialInstitutions("en").pr_col_1007 // { code: "pr_col_1007", rawCode: "1007", geo: "col", label: "Bancolombia" }
713
721
  queryFinancialInstitutions({ lang: "en", geo: "col" }) // FinancialInstitutionOption[] → every COL institution
714
722
  queryFinancialInstitutions({ lang: "en", geo: "col", scope: "checkout" }) // → only the COL ones the checkout offers
723
+ getFinancialInstitutions("en")[`pr_col_${bankCode}`]?.label ?? bankCode // bankCode: string from an API payload, no cast
715
724
  ```
716
725
 
717
726
  - **institutions** (i18n): `getFinancialInstitutions(lang)`; each record carries `code`, `rawCode`, `geo`
@@ -728,6 +737,11 @@ queryFinancialInstitutions({ lang: "en", geo: "col", scope: "checkout" }) // →
728
737
  - `scope` (`"checkout"`, optional on the record) marks the subset of institutions the checkout offers for PSE.
729
738
  Unlike `scope` in `currencies` it has **no default**: leaving it out returns the whole catalog, and
730
739
  `scope: "checkout"` narrows it. An institution without `scope` is not offered in the checkout.
740
+ - `getFinancialInstitutions(lang)` is also indexable by a plain `string`, for codes that arrive from a payload
741
+ (`pr_<geo>_<rawCode>` built from a bare bank code): a known code stays non-optional, any other
742
+ string reads as `FinancialInstitutionOption | undefined`, so an unknown code is handled with `?.` and no cast.
743
+ The catch is `Object.values(getFinancialInstitutions(lang))`, which is then typed
744
+ `(FinancialInstitutionOption | undefined)[]`: for a list use `queryFinancialInstitutions`.
731
745
  - Bank names have no real translation between `en` and `es-mex`: `es-mex` keeps the name as published by
732
746
  the source (accented characters included, e.g. `"Banco de Bogotá"`), `en` is the same string with
733
747
  special Spanish characters stripped (`"Banco de Bogota"`) rather than left untranslated with accents.
@@ -17,6 +17,12 @@ export declare const NATURES: {
17
17
  readonly off_ramp: {
18
18
  readonly code: "off_ramp";
19
19
  };
20
+ readonly mint: {
21
+ readonly code: "mint";
22
+ };
23
+ readonly redeem: {
24
+ readonly code: "redeem";
25
+ };
20
26
  };
21
27
  export type Nature = keyof typeof NATURES;
22
28
  export type NatureRecord = (typeof NATURES)[Nature];
@@ -8,4 +8,6 @@ exports.NATURES = {
8
8
  fx_conversion: { code: "fx_conversion" },
9
9
  on_ramp: { code: "on_ramp" },
10
10
  off_ramp: { code: "off_ramp" },
11
+ mint: { code: "mint" },
12
+ redeem: { code: "redeem" },
11
13
  };
@@ -5,6 +5,8 @@
5
5
  "return": "Return",
6
6
  "fx_conversion": "FX Conversion",
7
7
  "on_ramp": "On Ramp",
8
- "off_ramp": "Off Ramp"
8
+ "off_ramp": "Off Ramp",
9
+ "mint": "Mint",
10
+ "redeem": "Redemption"
9
11
  }
10
12
  }
@@ -5,6 +5,8 @@
5
5
  "return": "Reversión",
6
6
  "fx_conversion": "Conversión FX",
7
7
  "on_ramp": "Conversión a stablecoin",
8
- "off_ramp": "Conversión a moneda local"
8
+ "off_ramp": "Conversión a moneda local",
9
+ "mint": "Emisión",
10
+ "redeem": "Canje"
9
11
  }
10
12
  }
@@ -44,6 +44,7 @@ export declare const CURRENCIES: {
44
44
  readonly flagAsset: "usdt";
45
45
  readonly minAmount: 1;
46
46
  readonly type: "stablecoin";
47
+ readonly symbol: "USDT";
47
48
  };
48
49
  readonly usdc: {
49
50
  readonly code: "usdc";
@@ -53,6 +54,7 @@ export declare const CURRENCIES: {
53
54
  readonly flagAsset: "usdc";
54
55
  readonly minAmount: 1;
55
56
  readonly type: "stablecoin";
57
+ readonly symbol: "USDC";
56
58
  };
57
59
  readonly copco: {
58
60
  readonly code: "copco";
@@ -62,6 +64,7 @@ export declare const CURRENCIES: {
62
64
  readonly flagAsset: "cop_stable";
63
65
  readonly minAmount: 1;
64
66
  readonly type: "stable";
67
+ readonly symbol: "COPco";
65
68
  };
66
69
  readonly cny: {
67
70
  readonly code: "cny";
@@ -88,4 +91,5 @@ export type Currency = keyof typeof CURRENCIES;
88
91
  export type CurrencyType = (typeof CURRENCIES)[Currency]["type"];
89
92
  export type CurrencyRecord = (typeof CURRENCIES)[Currency] & {
90
93
  readonly scope?: CurrencyScope;
94
+ readonly symbol?: string;
91
95
  };
@@ -6,9 +6,9 @@ exports.CURRENCIES = {
6
6
  mxn: { code: "mxn", label: "MXN", isoCode: "MXN", geo: "mex", flagAsset: "mex", minAmount: 0.01, type: "fiat" },
7
7
  usd: { code: "usd", label: "USD", isoCode: "USD", geo: "usa", flagAsset: "eu", minAmount: 100, type: "fiat" },
8
8
  usd_stable: { code: "usd_stable", label: "USD Stable", isoCode: "USD", geo: "global", flagAsset: "usd_stable", minAmount: 1, type: "stable" },
9
- usdt: { code: "usdt", label: "USD (USDT)", isoCode: "USD", geo: "usa", flagAsset: "usdt", minAmount: 1, type: "stablecoin" },
10
- usdc: { code: "usdc", label: "USD (USDC)", isoCode: "USD", geo: "usa", flagAsset: "usdc", minAmount: 1, type: "stablecoin" },
11
- copco: { code: "copco", label: "COPco", isoCode: "COP", geo: "col", flagAsset: "cop_stable", minAmount: 1, type: "stable" },
9
+ usdt: { code: "usdt", label: "USD (USDT)", isoCode: "USD", geo: "usa", flagAsset: "usdt", minAmount: 1, type: "stablecoin", symbol: "USDT" },
10
+ usdc: { code: "usdc", label: "USD (USDC)", isoCode: "USD", geo: "usa", flagAsset: "usdc", minAmount: 1, type: "stablecoin", symbol: "USDC" },
11
+ copco: { code: "copco", label: "COPco", isoCode: "COP", geo: "col", flagAsset: "cop_stable", minAmount: 1, type: "stable", symbol: "COPco" },
12
12
  cny: { code: "cny", label: "RMB", isoCode: "CNY", geo: "chn", flagAsset: "chn", minAmount: 100, type: "fiat", scope: "counterparties" },
13
13
  eur: { code: "eur", label: "EUR", isoCode: "EUR", geo: "eur", flagAsset: "eur", minAmount: 100, type: "fiat", scope: "counterparties" },
14
14
  };
@@ -4,11 +4,18 @@ import type { CatalogQuery } from "../../utils/catalog-query.utils";
4
4
  export type FinancialInstitutionOption = FinancialInstitutionRecord & {
5
5
  label: string;
6
6
  };
7
+ /**
8
+ * The catalog by code. Indexed by a plain string (e.g. a code from an API payload) instead of a known code,
9
+ * the lookup is `FinancialInstitutionOption | undefined`, so an unknown code needs no cast to be handled.
10
+ */
11
+ export interface FinancialInstitutionCatalog extends Record<FinancialInstitution, FinancialInstitutionOption> {
12
+ [code: string]: FinancialInstitutionOption | undefined;
13
+ }
7
14
  /**
8
15
  * The catalog indexed by code (same shape as FINANCIAL_INSTITUTIONS), each record enriched
9
- * with its label for the given language. Access by code directly, or Object.values for a list.
16
+ * with its label for the given language. Access by code directly; for a list use `queryFinancialInstitutions`.
10
17
  */
11
- export declare const getFinancialInstitutions: (lang: Locale) => Record<FinancialInstitution, FinancialInstitutionOption>;
18
+ export declare const getFinancialInstitutions: (lang: Locale) => FinancialInstitutionCatalog;
12
19
  /** `lang` is required (i18n domain, no default) and travels inside the query object, never positional. */
13
20
  export type FinancialInstitutionQuery = CatalogQuery<FinancialInstitutionRecord> & {
14
21
  lang: Locale;
@@ -9,11 +9,8 @@ const en_json_1 = __importDefault(require("../locales/en.json"));
9
9
  const es_mex_json_1 = __importDefault(require("../locales/es-mex.json"));
10
10
  const catalog_query_utils_1 = require("../../utils/catalog-query.utils");
11
11
  const locales = { en: en_json_1.default, "es-mex": es_mex_json_1.default };
12
- /**
13
- * The catalog indexed by code (same shape as FINANCIAL_INSTITUTIONS), each record enriched
14
- * with its label for the given language. Access by code directly, or Object.values for a list.
15
- */
16
- const getFinancialInstitutions = (lang) => {
12
+ // Built with the strict type so `queryFinancialInstitutions` lists it without the string index signature.
13
+ const buildFinancialInstitutions = (lang) => {
17
14
  const locale = locales[lang];
18
15
  const result = {};
19
16
  for (const record of Object.values(catalog_1.FINANCIAL_INSTITUTIONS)) {
@@ -21,11 +18,15 @@ const getFinancialInstitutions = (lang) => {
21
18
  }
22
19
  return result;
23
20
  };
21
+ /**
22
+ * The catalog indexed by code (same shape as FINANCIAL_INSTITUTIONS), each record enriched
23
+ * with its label for the given language. Access by code directly; for a list use `queryFinancialInstitutions`.
24
+ */
25
+ const getFinancialInstitutions = (lang) => buildFinancialInstitutions(lang);
24
26
  exports.getFinancialInstitutions = getFinancialInstitutions;
25
27
  /** The catalog as a list, narrowed by the query — see `matchesQuery` for the matching rules. */
26
28
  const queryFinancialInstitutions = (query) => {
27
29
  const { lang, ...criteria } = query;
28
- const institutions = (0, exports.getFinancialInstitutions)(lang);
29
- return Object.values(institutions).filter(institution => (0, catalog_query_utils_1.matchesQuery)(institution, criteria));
30
+ return Object.values(buildFinancialInstitutions(lang)).filter(institution => (0, catalog_query_utils_1.matchesQuery)(institution, criteria));
30
31
  };
31
32
  exports.queryFinancialInstitutions = queryFinancialInstitutions;
@@ -1,4 +1,4 @@
1
- export type { MovementType } from "./types/catalog";
1
+ export type { MovementType, MovementTypeScope } from "./types/catalog";
2
2
  export * from "./types/utils/movement-type.utils";
3
3
  export type { MovementStatus, MovementStatusType } from "./status/catalog";
4
4
  export * from "./status/utils/movement-status.utils";
@@ -1,3 +1,4 @@
1
+ export type MovementTypeScope = "internal_ops";
1
2
  export declare const MOVEMENT_TYPES: {
2
3
  readonly ach: {
3
4
  readonly code: "ach";
@@ -155,6 +156,22 @@ export declare const MOVEMENT_TYPES: {
155
156
  readonly category: "payments";
156
157
  readonly section: "eur";
157
158
  };
159
+ readonly mint: {
160
+ readonly code: "mint";
161
+ readonly line: "stable";
162
+ readonly category: "conversions";
163
+ readonly section: "stablecoin";
164
+ readonly scope: "internal_ops";
165
+ };
166
+ readonly redeem: {
167
+ readonly code: "redeem";
168
+ readonly line: "stable";
169
+ readonly category: "conversions";
170
+ readonly section: "stablecoin";
171
+ readonly scope: "internal_ops";
172
+ };
158
173
  };
159
174
  export type MovementType = keyof typeof MOVEMENT_TYPES;
160
- export type MovementTypeRecord = (typeof MOVEMENT_TYPES)[MovementType];
175
+ export type MovementTypeRecord = (typeof MOVEMENT_TYPES)[MovementType] & {
176
+ readonly scope?: MovementTypeScope;
177
+ };
@@ -28,4 +28,6 @@ exports.MOVEMENT_TYPES = {
28
28
  global_pay_to_generic: { code: "global_pay_to_generic", line: "payout", category: "payments", section: "usd_global" },
29
29
  swift: { code: "swift", line: "payout", category: "payments", section: "usd_global" },
30
30
  sepa: { code: "sepa", line: "payout", category: "payments", section: "eur" },
31
+ mint: { code: "mint", line: "stable", category: "conversions", section: "stablecoin", scope: "internal_ops" },
32
+ redeem: { code: "redeem", line: "stable", category: "conversions", section: "stablecoin", scope: "internal_ops" },
31
33
  };
@@ -25,6 +25,8 @@
25
25
  "breb": "Instant payment · Bre-B",
26
26
  "global_pay_to_generic": "International payment",
27
27
  "swift": "International transfer · Swift",
28
- "sepa": "International transfer · SEPA"
28
+ "sepa": "International transfer · SEPA",
29
+ "mint": "Stablecoin mint",
30
+ "redeem": "Stablecoin redemption"
29
31
  }
30
32
  }
@@ -25,6 +25,8 @@
25
25
  "breb": "Pago instantáneo · Bre-B",
26
26
  "global_pay_to_generic": "Pago internacional",
27
27
  "swift": "Transferencia internacional · Swift",
28
- "sepa": "Transferencia internacional · SEPA"
28
+ "sepa": "Transferencia internacional · SEPA",
29
+ "mint": "Emisión de stablecoin",
30
+ "redeem": "Canje de stablecoin"
29
31
  }
30
32
  }
@@ -1,4 +1,4 @@
1
- import type { MovementType, MovementTypeRecord } from "../catalog";
1
+ import type { MovementType, MovementTypeRecord, MovementTypeScope } from "../catalog";
2
2
  import type { Locale } from "../../../lang";
3
3
  import type { CatalogQuery } from "../../../utils/catalog-query.utils";
4
4
  export type MovementTypeOption = MovementTypeRecord & {
@@ -6,8 +6,15 @@ export type MovementTypeOption = MovementTypeRecord & {
6
6
  };
7
7
  export declare const getMovementTypes: (lang: Locale) => Record<MovementType, MovementTypeOption>;
8
8
  /** i18n domain: `lang` is required, inside the query object — see matchesQuery for the matching rules. */
9
- export type MovementTypeQuery = CatalogQuery<MovementTypeRecord> & {
9
+ export type MovementTypeQuery = CatalogQuery<Omit<MovementTypeRecord, "scope">> & {
10
10
  lang: Locale;
11
+ scope?: MovementTypeScope | readonly MovementTypeScope[];
11
12
  };
12
- /** The catalog as a list narrowed by the query, each record enriched with its label for `query.lang`. */
13
+ /**
14
+ * The catalog as a list narrowed by the query, each record enriched with its label for `query.lang`.
15
+ *
16
+ * `scope` is the one field with a default: leave the key out and only regular movement types come back, so a
17
+ * filter never inherits the internal ones by accident. That is also why `{ code: "mint" }` returns nothing —
18
+ * looking a movement type up by code is `getMovementTypes(lang)[code]`.
19
+ */
13
20
  export declare const queryMovementTypes: (query: MovementTypeQuery) => MovementTypeOption[];
@@ -18,11 +18,18 @@ const getMovementTypes = (lang) => {
18
18
  return result;
19
19
  };
20
20
  exports.getMovementTypes = getMovementTypes;
21
- /** The catalog as a list narrowed by the query, each record enriched with its label for `query.lang`. */
21
+ /**
22
+ * The catalog as a list narrowed by the query, each record enriched with its label for `query.lang`.
23
+ *
24
+ * `scope` is the one field with a default: leave the key out and only regular movement types come back, so a
25
+ * filter never inherits the internal ones by accident. That is also why `{ code: "mint" }` returns nothing —
26
+ * looking a movement type up by code is `getMovementTypes(lang)[code]`.
27
+ */
22
28
  const queryMovementTypes = (query) => {
23
29
  const { lang, ...filters } = query;
30
+ const withScopeDefault = "scope" in filters ? filters : { ...filters, scope: undefined };
24
31
  return Object.values(catalog_1.MOVEMENT_TYPES)
25
- .filter(record => (0, catalog_query_utils_1.matchesQuery)(record, filters))
32
+ .filter(record => (0, catalog_query_utils_1.matchesQuery)(record, withScopeDefault))
26
33
  .map(record => ({ ...record, label: locales[lang].movementTypes[record.code] }));
27
34
  };
28
35
  exports.queryMovementTypes = queryMovementTypes;
@@ -388,6 +388,30 @@ export declare const TRANSACTION_TYPES: {
388
388
  readonly section: "usd_global";
389
389
  readonly group: "off_ramp";
390
390
  };
391
+ readonly stable_credit: {
392
+ readonly creditDebitType: "credit";
393
+ readonly code: "stable_credit";
394
+ readonly line: "stable";
395
+ readonly category: "conversions";
396
+ readonly section: "usd_global";
397
+ readonly group: null;
398
+ };
399
+ readonly stable_debit: {
400
+ readonly creditDebitType: "debit";
401
+ readonly code: "stable_debit";
402
+ readonly line: "stable";
403
+ readonly category: "conversions";
404
+ readonly section: "usd_global";
405
+ readonly group: null;
406
+ };
407
+ readonly stable_refund: {
408
+ readonly creditDebitType: "credit";
409
+ readonly code: "stable_refund";
410
+ readonly line: "stable";
411
+ readonly category: "conversions";
412
+ readonly section: "usd_global";
413
+ readonly group: null;
414
+ };
391
415
  };
392
416
  /** `when_present`: shown in the grouped type filter only when the data contains it. */
393
417
  export type TransactionTypeFilterDisplay = "when_present";
@@ -391,4 +391,28 @@ exports.TRANSACTION_TYPES = {
391
391
  section: "usd_global",
392
392
  group: "off_ramp",
393
393
  },
394
+ stable_credit: {
395
+ creditDebitType: "credit",
396
+ code: "stable_credit",
397
+ line: "stable",
398
+ category: "conversions",
399
+ section: "usd_global",
400
+ group: null,
401
+ },
402
+ stable_debit: {
403
+ creditDebitType: "debit",
404
+ code: "stable_debit",
405
+ line: "stable",
406
+ category: "conversions",
407
+ section: "usd_global",
408
+ group: null,
409
+ },
410
+ stable_refund: {
411
+ creditDebitType: "credit",
412
+ code: "stable_refund",
413
+ line: "stable",
414
+ category: "conversions",
415
+ section: "usd_global",
416
+ group: null,
417
+ },
394
418
  };
@@ -47,7 +47,10 @@
47
47
  "global_rejected": "Rejection · Global",
48
48
  "offramp_treasury_credit": "Treasury conversion · Off-Ramp",
49
49
  "onramp_debit": "Conversion to stablecoin · On-Ramp · debit",
50
- "offramp_credit": "Conversion to local currency · Off-Ramp · credit"
50
+ "offramp_credit": "Conversion to local currency · Off-Ramp · credit",
51
+ "stable_credit": "Stablecoin payment received",
52
+ "stable_debit": "Stablecoin payment",
53
+ "stable_refund": "Stablecoin payment refund"
51
54
  },
52
55
  "transactionTypeGroups": {
53
56
  "cbmm": "Cross-border movement · Debit and credit",
@@ -47,7 +47,10 @@
47
47
  "global_rejected": "Rechazo · Global",
48
48
  "offramp_treasury_credit": "Conversión de tesorería · Off-Ramp",
49
49
  "onramp_debit": "Conversión a stablecoin · On-Ramp · débito",
50
- "offramp_credit": "Conversión a moneda local · Off-Ramp · crédito"
50
+ "offramp_credit": "Conversión a moneda local · Off-Ramp · crédito",
51
+ "stable_credit": "Pago en stablecoin recibido",
52
+ "stable_debit": "Pago en stablecoin",
53
+ "stable_refund": "Reembolso de pago en stablecoin"
51
54
  },
52
55
  "transactionTypeGroups": {
53
56
  "cbmm": "Movimiento cross-border · Débito y crédito",
@@ -5,4 +5,6 @@ export const NATURES = {
5
5
  fx_conversion: { code: "fx_conversion" },
6
6
  on_ramp: { code: "on_ramp" },
7
7
  off_ramp: { code: "off_ramp" },
8
+ mint: { code: "mint" },
9
+ redeem: { code: "redeem" },
8
10
  };
@@ -5,6 +5,8 @@
5
5
  "return": "Return",
6
6
  "fx_conversion": "FX Conversion",
7
7
  "on_ramp": "On Ramp",
8
- "off_ramp": "Off Ramp"
8
+ "off_ramp": "Off Ramp",
9
+ "mint": "Mint",
10
+ "redeem": "Redemption"
9
11
  }
10
12
  }
@@ -5,6 +5,8 @@
5
5
  "return": "Reversión",
6
6
  "fx_conversion": "Conversión FX",
7
7
  "on_ramp": "Conversión a stablecoin",
8
- "off_ramp": "Conversión a moneda local"
8
+ "off_ramp": "Conversión a moneda local",
9
+ "mint": "Emisión",
10
+ "redeem": "Canje"
9
11
  }
10
12
  }
@@ -3,9 +3,9 @@ export const CURRENCIES = {
3
3
  mxn: { code: "mxn", label: "MXN", isoCode: "MXN", geo: "mex", flagAsset: "mex", minAmount: 0.01, type: "fiat" },
4
4
  usd: { code: "usd", label: "USD", isoCode: "USD", geo: "usa", flagAsset: "eu", minAmount: 100, type: "fiat" },
5
5
  usd_stable: { code: "usd_stable", label: "USD Stable", isoCode: "USD", geo: "global", flagAsset: "usd_stable", minAmount: 1, type: "stable" },
6
- usdt: { code: "usdt", label: "USD (USDT)", isoCode: "USD", geo: "usa", flagAsset: "usdt", minAmount: 1, type: "stablecoin" },
7
- usdc: { code: "usdc", label: "USD (USDC)", isoCode: "USD", geo: "usa", flagAsset: "usdc", minAmount: 1, type: "stablecoin" },
8
- copco: { code: "copco", label: "COPco", isoCode: "COP", geo: "col", flagAsset: "cop_stable", minAmount: 1, type: "stable" },
6
+ usdt: { code: "usdt", label: "USD (USDT)", isoCode: "USD", geo: "usa", flagAsset: "usdt", minAmount: 1, type: "stablecoin", symbol: "USDT" },
7
+ usdc: { code: "usdc", label: "USD (USDC)", isoCode: "USD", geo: "usa", flagAsset: "usdc", minAmount: 1, type: "stablecoin", symbol: "USDC" },
8
+ copco: { code: "copco", label: "COPco", isoCode: "COP", geo: "col", flagAsset: "cop_stable", minAmount: 1, type: "stable", symbol: "COPco" },
9
9
  cny: { code: "cny", label: "RMB", isoCode: "CNY", geo: "chn", flagAsset: "chn", minAmount: 100, type: "fiat", scope: "counterparties" },
10
10
  eur: { code: "eur", label: "EUR", isoCode: "EUR", geo: "eur", flagAsset: "eur", minAmount: 100, type: "fiat", scope: "counterparties" },
11
11
  };
@@ -3,11 +3,8 @@ import enLocale from "../locales/en.json";
3
3
  import esMexLocale from "../locales/es-mex.json";
4
4
  import { matchesQuery } from "../../utils/catalog-query.utils";
5
5
  const locales = { en: enLocale, "es-mex": esMexLocale };
6
- /**
7
- * The catalog indexed by code (same shape as FINANCIAL_INSTITUTIONS), each record enriched
8
- * with its label for the given language. Access by code directly, or Object.values for a list.
9
- */
10
- export const getFinancialInstitutions = (lang) => {
6
+ // Built with the strict type so `queryFinancialInstitutions` lists it without the string index signature.
7
+ const buildFinancialInstitutions = (lang) => {
11
8
  const locale = locales[lang];
12
9
  const result = {};
13
10
  for (const record of Object.values(FINANCIAL_INSTITUTIONS)) {
@@ -15,9 +12,13 @@ export const getFinancialInstitutions = (lang) => {
15
12
  }
16
13
  return result;
17
14
  };
15
+ /**
16
+ * The catalog indexed by code (same shape as FINANCIAL_INSTITUTIONS), each record enriched
17
+ * with its label for the given language. Access by code directly; for a list use `queryFinancialInstitutions`.
18
+ */
19
+ export const getFinancialInstitutions = (lang) => buildFinancialInstitutions(lang);
18
20
  /** The catalog as a list, narrowed by the query — see `matchesQuery` for the matching rules. */
19
21
  export const queryFinancialInstitutions = (query) => {
20
22
  const { lang, ...criteria } = query;
21
- const institutions = getFinancialInstitutions(lang);
22
- return Object.values(institutions).filter(institution => matchesQuery(institution, criteria));
23
+ return Object.values(buildFinancialInstitutions(lang)).filter(institution => matchesQuery(institution, criteria));
23
24
  };
@@ -25,4 +25,6 @@ export const MOVEMENT_TYPES = {
25
25
  global_pay_to_generic: { code: "global_pay_to_generic", line: "payout", category: "payments", section: "usd_global" },
26
26
  swift: { code: "swift", line: "payout", category: "payments", section: "usd_global" },
27
27
  sepa: { code: "sepa", line: "payout", category: "payments", section: "eur" },
28
+ mint: { code: "mint", line: "stable", category: "conversions", section: "stablecoin", scope: "internal_ops" },
29
+ redeem: { code: "redeem", line: "stable", category: "conversions", section: "stablecoin", scope: "internal_ops" },
28
30
  };
@@ -25,6 +25,8 @@
25
25
  "breb": "Instant payment · Bre-B",
26
26
  "global_pay_to_generic": "International payment",
27
27
  "swift": "International transfer · Swift",
28
- "sepa": "International transfer · SEPA"
28
+ "sepa": "International transfer · SEPA",
29
+ "mint": "Stablecoin mint",
30
+ "redeem": "Stablecoin redemption"
29
31
  }
30
32
  }
@@ -25,6 +25,8 @@
25
25
  "breb": "Pago instantáneo · Bre-B",
26
26
  "global_pay_to_generic": "Pago internacional",
27
27
  "swift": "Transferencia internacional · Swift",
28
- "sepa": "Transferencia internacional · SEPA"
28
+ "sepa": "Transferencia internacional · SEPA",
29
+ "mint": "Emisión de stablecoin",
30
+ "redeem": "Canje de stablecoin"
29
31
  }
30
32
  }
@@ -11,10 +11,17 @@ export const getMovementTypes = (lang) => {
11
11
  }
12
12
  return result;
13
13
  };
14
- /** The catalog as a list narrowed by the query, each record enriched with its label for `query.lang`. */
14
+ /**
15
+ * The catalog as a list narrowed by the query, each record enriched with its label for `query.lang`.
16
+ *
17
+ * `scope` is the one field with a default: leave the key out and only regular movement types come back, so a
18
+ * filter never inherits the internal ones by accident. That is also why `{ code: "mint" }` returns nothing —
19
+ * looking a movement type up by code is `getMovementTypes(lang)[code]`.
20
+ */
15
21
  export const queryMovementTypes = (query) => {
16
22
  const { lang, ...filters } = query;
23
+ const withScopeDefault = "scope" in filters ? filters : { ...filters, scope: undefined };
17
24
  return Object.values(MOVEMENT_TYPES)
18
- .filter(record => matchesQuery(record, filters))
25
+ .filter(record => matchesQuery(record, withScopeDefault))
19
26
  .map(record => ({ ...record, label: locales[lang].movementTypes[record.code] }));
20
27
  };
@@ -388,4 +388,28 @@ export const TRANSACTION_TYPES = {
388
388
  section: "usd_global",
389
389
  group: "off_ramp",
390
390
  },
391
+ stable_credit: {
392
+ creditDebitType: "credit",
393
+ code: "stable_credit",
394
+ line: "stable",
395
+ category: "conversions",
396
+ section: "usd_global",
397
+ group: null,
398
+ },
399
+ stable_debit: {
400
+ creditDebitType: "debit",
401
+ code: "stable_debit",
402
+ line: "stable",
403
+ category: "conversions",
404
+ section: "usd_global",
405
+ group: null,
406
+ },
407
+ stable_refund: {
408
+ creditDebitType: "credit",
409
+ code: "stable_refund",
410
+ line: "stable",
411
+ category: "conversions",
412
+ section: "usd_global",
413
+ group: null,
414
+ },
391
415
  };
@@ -47,7 +47,10 @@
47
47
  "global_rejected": "Rejection · Global",
48
48
  "offramp_treasury_credit": "Treasury conversion · Off-Ramp",
49
49
  "onramp_debit": "Conversion to stablecoin · On-Ramp · debit",
50
- "offramp_credit": "Conversion to local currency · Off-Ramp · credit"
50
+ "offramp_credit": "Conversion to local currency · Off-Ramp · credit",
51
+ "stable_credit": "Stablecoin payment received",
52
+ "stable_debit": "Stablecoin payment",
53
+ "stable_refund": "Stablecoin payment refund"
51
54
  },
52
55
  "transactionTypeGroups": {
53
56
  "cbmm": "Cross-border movement · Debit and credit",
@@ -47,7 +47,10 @@
47
47
  "global_rejected": "Rechazo · Global",
48
48
  "offramp_treasury_credit": "Conversión de tesorería · Off-Ramp",
49
49
  "onramp_debit": "Conversión a stablecoin · On-Ramp · débito",
50
- "offramp_credit": "Conversión a moneda local · Off-Ramp · crédito"
50
+ "offramp_credit": "Conversión a moneda local · Off-Ramp · crédito",
51
+ "stable_credit": "Pago en stablecoin recibido",
52
+ "stable_debit": "Pago en stablecoin",
53
+ "stable_refund": "Reembolso de pago en stablecoin"
51
54
  },
52
55
  "transactionTypeGroups": {
53
56
  "cbmm": "Movimiento cross-border · Débito y crédito",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cobre-npm/library-portal-core",
3
- "version": "0.64.0",
3
+ "version": "0.66.0",
4
4
  "description": "Shared configurations and resources for Portal MFEs",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",