@global-torque/invest-core 0.4.12 → 0.4.14
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/CHANGELOG.md +12 -0
- package/README.md +4 -2
- package/package.json +4 -4
- package/src/analytics/__tests__/analyticsBody.test.ts +42 -0
- package/src/analytics/analyticsBody.ts +35 -0
- package/src/form-validation/general.ts +4 -4
- package/src/form-validation/investment.ts +2 -2
- package/src/helpers/formatters/formatToNumber.ts +1 -1
- package/src/helpers/general.ts +5 -5
- package/src/helpers/model.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.14 candidate
|
|
4
|
+
|
|
5
|
+
- Carries forward the ESM Lodash imports, generated Node exports, exact cohort
|
|
6
|
+
dependency, and regulated identity/payment analytics redaction from 0.4.13.
|
|
7
|
+
|
|
8
|
+
## 0.4.13 candidate
|
|
9
|
+
|
|
10
|
+
- Replace CommonJS Lodash deep imports with ESM `lodash-es` imports so published TypeScript sources load without CommonJS interop in native ESM consumers.
|
|
11
|
+
- Pin `@global-torque/domain-types` to cohort `0.4.13` so Git-subpath installs resolve without workspace links while preserving deliberate future cohort coupling.
|
|
12
|
+
- Track the three generated `dist/node` entrypoints owned by `pnpm run build:node` so Git-subpath Node/VitePress consumers resolve the existing public exports.
|
|
13
|
+
- Extend the shared analytics body normalization policy to redact regulated identity and payment fields in event and error telemetry.
|
|
14
|
+
|
|
3
15
|
## 0.4.12 candidate
|
|
4
16
|
|
|
5
17
|
- Reissued the cohort with a side-effect-free shared CSS contract root resolver;
|
package/README.md
CHANGED
|
@@ -8,8 +8,8 @@ This package owns deterministic helpers, mappers, formatters, calculations, and
|
|
|
8
8
|
|
|
9
9
|
## Allowed Dependencies
|
|
10
10
|
|
|
11
|
-
- `@global-torque/domain-types
|
|
12
|
-
- AJV, `ajv-errors`, `ajv-formats`, lodash
|
|
11
|
+
- `@global-torque/domain-types` at exact `0.4.14`; the fixed cohort version keeps Git-subpath installs portable without workspace links and couples this source branch to the matching domain contract until the next cohort.
|
|
12
|
+
- AJV, `ajv-errors`, `ajv-formats`, `lodash-es`, and markdown-it for the published
|
|
13
13
|
investment validation and formatting helpers.
|
|
14
14
|
- TypeScript and platform-standard value types.
|
|
15
15
|
|
|
@@ -27,6 +27,8 @@ TypeScript browser and type targets and additionally provide exact generated
|
|
|
27
27
|
candidate packer emits only these three Node files; all other exports remain
|
|
28
28
|
source based.
|
|
29
29
|
|
|
30
|
+
`pnpm run build:node` owns regeneration of exactly these three tracked Node files for Git-subpath consumers; the candidate packer emits the same inventory and all other exports remain source based.
|
|
31
|
+
|
|
30
32
|
- `analytics/analyticsBody`: analytics request body normalization with exact
|
|
31
33
|
credential-field redaction. User, business, numeric, URL, and diagnostic
|
|
32
34
|
values are retained unless assigned to a known credential field.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@global-torque/invest-core",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.14",
|
|
5
5
|
"description": "Pure investment policy, calculations, formatters, and schema helpers.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"engines": {
|
|
@@ -66,12 +66,12 @@
|
|
|
66
66
|
"./form-validation/investment": "./src/form-validation/investment.ts"
|
|
67
67
|
},
|
|
68
68
|
"dependencies": {
|
|
69
|
-
"@types/lodash": "^4.17.
|
|
70
|
-
"@global-torque/domain-types": "0.4.
|
|
69
|
+
"@types/lodash-es": "^4.17.12",
|
|
70
|
+
"@global-torque/domain-types": "0.4.14",
|
|
71
71
|
"ajv": "^8.20.0",
|
|
72
72
|
"ajv-errors": "^3.0.0",
|
|
73
73
|
"ajv-formats": "^3.0.1",
|
|
74
|
-
"lodash": "^4.18.1",
|
|
74
|
+
"lodash-es": "^4.18.1",
|
|
75
75
|
"markdown-it": "^15.0.2"
|
|
76
76
|
},
|
|
77
77
|
"devDependencies": {
|
|
@@ -49,6 +49,48 @@ describe('analyticsBody', () => {
|
|
|
49
49
|
expect(input.nested.jwtToken).toBe('jwt-secret');
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
+
it('redacts exact regulated payment and identity fields without broad near-name matching', () => {
|
|
53
|
+
const input = {
|
|
54
|
+
ssn: '111-22-3333',
|
|
55
|
+
socialSecurityNumber: '222-33-4444',
|
|
56
|
+
taxId: 'tax-secret',
|
|
57
|
+
taxpayerIdentificationNumber: 'tin-secret',
|
|
58
|
+
bankAccountNumber: 'bank-secret',
|
|
59
|
+
routingNumber: 'routing-secret',
|
|
60
|
+
cardNumber: '4111111111111111',
|
|
61
|
+
creditCardNumber: '4222222222222222',
|
|
62
|
+
cvv: '123',
|
|
63
|
+
cvc: '456',
|
|
64
|
+
iban: 'DE89370400440532013000',
|
|
65
|
+
paymentToken: 'payment-token-secret',
|
|
66
|
+
account: 'business-account',
|
|
67
|
+
accountType: 'checking',
|
|
68
|
+
token_symbol: 'USDC',
|
|
69
|
+
tokenNote: 'business token note',
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
expect(normalizeAnalyticsBody(input)).toEqual({
|
|
73
|
+
ssn: '[redacted]',
|
|
74
|
+
socialSecurityNumber: '[redacted]',
|
|
75
|
+
taxId: '[redacted]',
|
|
76
|
+
taxpayerIdentificationNumber: '[redacted]',
|
|
77
|
+
bankAccountNumber: '[redacted]',
|
|
78
|
+
routingNumber: '[redacted]',
|
|
79
|
+
cardNumber: '[redacted]',
|
|
80
|
+
creditCardNumber: '[redacted]',
|
|
81
|
+
cvv: '[redacted]',
|
|
82
|
+
cvc: '[redacted]',
|
|
83
|
+
iban: '[redacted]',
|
|
84
|
+
paymentToken: '[redacted]',
|
|
85
|
+
account: 'business-account',
|
|
86
|
+
accountType: 'checking',
|
|
87
|
+
token_symbol: 'USDC',
|
|
88
|
+
tokenNote: 'business token note',
|
|
89
|
+
});
|
|
90
|
+
expect(input.ssn).toBe('111-22-3333');
|
|
91
|
+
expect(input.paymentToken).toBe('payment-token-secret');
|
|
92
|
+
});
|
|
93
|
+
|
|
52
94
|
it('normalizes JSON strings and retains GET bodies', () => {
|
|
53
95
|
expect(normalizeAnalyticsBody('{"email":"user@example.com","token":"secret","keep":1}')).toEqual({
|
|
54
96
|
email: 'user@example.com',
|
|
@@ -48,6 +48,41 @@ const CREDENTIAL_KEYS = new Set([
|
|
|
48
48
|
'link_token',
|
|
49
49
|
'challenge_signature',
|
|
50
50
|
'owner_signature',
|
|
51
|
+
// Regulated identity, bank, card, and payment fields. Keep these exact
|
|
52
|
+
// after normalization so near-name business fields remain observable.
|
|
53
|
+
'ssn',
|
|
54
|
+
'social_security_number',
|
|
55
|
+
'social_security',
|
|
56
|
+
'tax_id',
|
|
57
|
+
'tax_number',
|
|
58
|
+
'taxpayer_id',
|
|
59
|
+
'taxpayer_identification_number',
|
|
60
|
+
'tax_identification_number',
|
|
61
|
+
'tin',
|
|
62
|
+
'ein',
|
|
63
|
+
'bank_account',
|
|
64
|
+
'bank_account_number',
|
|
65
|
+
'account_number',
|
|
66
|
+
'routing_number',
|
|
67
|
+
'bank_routing_number',
|
|
68
|
+
'routing_num',
|
|
69
|
+
'card_number',
|
|
70
|
+
'credit_card_number',
|
|
71
|
+
'debit_card_number',
|
|
72
|
+
'card_expiry',
|
|
73
|
+
'card_expiration',
|
|
74
|
+
'card_expiry_month',
|
|
75
|
+
'card_expiry_year',
|
|
76
|
+
'cvv',
|
|
77
|
+
'cvc',
|
|
78
|
+
'cid',
|
|
79
|
+
'security_code',
|
|
80
|
+
'iban',
|
|
81
|
+
'payment_token',
|
|
82
|
+
'payment_method_token',
|
|
83
|
+
'payment_card_token',
|
|
84
|
+
'payment_intent',
|
|
85
|
+
'payment_intent_id',
|
|
51
86
|
]);
|
|
52
87
|
const COMPACT_CREDENTIAL_KEYS = new Set(
|
|
53
88
|
[...CREDENTIAL_KEYS].map((key) => key.replaceAll('_', '')),
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { JSONSchemaType } from 'ajv/dist/types/json-schema';
|
|
2
|
-
import cloneDeep from 'lodash/cloneDeep.js';
|
|
3
|
-
import get from 'lodash/get.js';
|
|
4
|
-
import pick from 'lodash/pick.js';
|
|
5
|
-
import set from 'lodash/set.js';
|
|
2
|
+
import cloneDeep from 'lodash-es/cloneDeep.js';
|
|
3
|
+
import get from 'lodash-es/get.js';
|
|
4
|
+
import pick from 'lodash-es/pick.js';
|
|
5
|
+
import set from 'lodash-es/set.js';
|
|
6
6
|
|
|
7
7
|
interface FilteredObjectElement {
|
|
8
8
|
$ref?: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { JSONSchemaType } from 'ajv/dist/types/json-schema';
|
|
2
|
-
import cloneDeep from 'lodash/cloneDeep.js';
|
|
3
|
-
import merge from 'lodash/merge.js';
|
|
2
|
+
import cloneDeep from 'lodash-es/cloneDeep.js';
|
|
3
|
+
import merge from 'lodash-es/merge.js';
|
|
4
4
|
import { undefinedEmptyProp } from './general.ts';
|
|
5
5
|
|
|
6
6
|
export type InvestmentSchema<T extends object = object> = JSONSchemaType<T> & Record<string, unknown>;
|
package/src/helpers/general.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import lodashIsEmpty from 'lodash/isEmpty.js';
|
|
2
|
-
import startCase from 'lodash/startCase.js';
|
|
3
|
-
import toLower from 'lodash/toLower.js';
|
|
4
|
-
import unionBy from 'lodash/unionBy.js';
|
|
5
|
-
import kebabCase from 'lodash/kebabCase.js';
|
|
1
|
+
import lodashIsEmpty from 'lodash-es/isEmpty.js';
|
|
2
|
+
import startCase from 'lodash-es/startCase.js';
|
|
3
|
+
import toLower from 'lodash-es/toLower.js';
|
|
4
|
+
import unionBy from 'lodash-es/unionBy.js';
|
|
5
|
+
import kebabCase from 'lodash-es/kebabCase.js';
|
|
6
6
|
|
|
7
7
|
export function isEmpty(obj: object) {
|
|
8
8
|
return lodashIsEmpty(obj);
|
package/src/helpers/model.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { JSONSchemaType } from 'ajv/dist/types/json-schema';
|
|
2
|
-
import cloneDeep from 'lodash/cloneDeep.js';
|
|
3
|
-
import defaults from 'lodash/defaults.js';
|
|
4
|
-
import pick from 'lodash/pick.js';
|
|
2
|
+
import cloneDeep from 'lodash-es/cloneDeep.js';
|
|
3
|
+
import defaults from 'lodash-es/defaults.js';
|
|
4
|
+
import pick from 'lodash-es/pick.js';
|
|
5
5
|
import { capitalizeFirstLetter } from './text';
|
|
6
6
|
|
|
7
7
|
export function populateModel<T extends object>(source: Partial<T>, defaultsObj: T): T {
|