@global-torque/invest-core 0.4.0 → 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 +95 -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,100 @@
|
|
|
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
|
+
|
|
15
|
+
## 0.4.12 candidate
|
|
16
|
+
|
|
17
|
+
- Reissued the cohort with a side-effect-free shared CSS contract root resolver;
|
|
18
|
+
release contract tests do not launch a browser.
|
|
19
|
+
|
|
20
|
+
## 0.4.11 abandoned candidate
|
|
21
|
+
|
|
22
|
+
- CI run `35574140527` and candidate run `35574298182` launched the browser
|
|
23
|
+
contract before Playwright/dependency installation; no hosted candidate
|
|
24
|
+
artifact, GitHub release, or npm package exists. The immutable tagged source
|
|
25
|
+
ledger paired dashboard.webdevelop.biz with torque-packages sourceRevision
|
|
26
|
+
`82fe93868d28682211ea21867badcdeb85879970`; no artifact or receipt escaped.
|
|
27
|
+
|
|
28
|
+
## 0.4.10 abandoned candidate
|
|
29
|
+
|
|
30
|
+
- Immutable candidate passed the absent-token npm path, but the corresponding
|
|
31
|
+
pnpm strict-layout path failed with `ENOENT` for an undeclared sibling
|
|
32
|
+
package; the 0.2.1 and 0.3.0 paths did not run; no registry package exists.
|
|
33
|
+
|
|
34
|
+
## 0.4.9 abandoned candidate
|
|
35
|
+
|
|
36
|
+
- Immutable candidate was superseded because the immutable release ledger
|
|
37
|
+
misstated public evidence as authenticated and conflated the observed
|
|
38
|
+
offer-card difference with the inferred `VHeaderBar` sibling; no registry
|
|
39
|
+
package exists.
|
|
40
|
+
|
|
41
|
+
## 0.4.8 abandoned candidate
|
|
42
|
+
|
|
43
|
+
- Immutable candidate was superseded before publication after the required
|
|
44
|
+
public Investor mobile offer parity gate on
|
|
45
|
+
`/tahoe-e2e-fund-766pk7` found 2 differing pixels / 4 channel-level deltas
|
|
46
|
+
in the offer-card shadow; source review found the same fallback defect in
|
|
47
|
+
`VHeaderBar`; no registry package exists.
|
|
48
|
+
|
|
49
|
+
## 0.4.8 candidate
|
|
50
|
+
|
|
51
|
+
- Reissued the seven-package cohort with the PWA login and footer compatibility
|
|
52
|
+
corrections.
|
|
53
|
+
|
|
54
|
+
## 0.4.7 abandoned candidate
|
|
55
|
+
|
|
56
|
+
- Superseded before publication after authenticated Platform desktop parity
|
|
57
|
+
exposed invisible footer disclosure and copyright text; no registry package
|
|
58
|
+
exists.
|
|
59
|
+
|
|
60
|
+
## 0.4.6 candidate
|
|
61
|
+
|
|
62
|
+
- Reissued the seven-package cohort with the Invest Shell geometry recovery and
|
|
63
|
+
complete token compatibility characterization.
|
|
64
|
+
|
|
65
|
+
## 0.4.5 abandoned candidate
|
|
66
|
+
|
|
67
|
+
- Superseded before publication by the 0.4.6 geometry recovery.
|
|
68
|
+
|
|
69
|
+
## 0.4.5 candidate
|
|
70
|
+
|
|
71
|
+
- Reissued the seven-package cohort with the inverse-footer compatibility fix;
|
|
72
|
+
core contracts and the final `price_update` removal are unchanged.
|
|
73
|
+
|
|
74
|
+
## 0.4.4 abandoned candidate
|
|
75
|
+
|
|
76
|
+
- Immutable candidate was superseded before publication; no registry package
|
|
77
|
+
exists.
|
|
78
|
+
|
|
79
|
+
## 0.4.4 candidate
|
|
80
|
+
|
|
81
|
+
- Reissued the seven-package cohort after the accepted Invest Shell CSS
|
|
82
|
+
contract recovery; core contracts are unchanged.
|
|
83
|
+
|
|
84
|
+
## 0.4.3 abandoned candidate
|
|
85
|
+
|
|
86
|
+
- Immutable candidate tag was retained after a successful candidate run but
|
|
87
|
+
was superseded before publication by the footer-role recovery.
|
|
88
|
+
|
|
89
|
+
## 0.4.2 abandoned candidate
|
|
90
|
+
|
|
91
|
+
- Reissued the cohort with the final `price_update` removal retained.
|
|
92
|
+
|
|
93
|
+
## 0.4.1 abandoned candidate
|
|
94
|
+
|
|
95
|
+
- Immutable candidate tag was retained but not published after its browser CI
|
|
96
|
+
gate lacked a Chromium installation step.
|
|
97
|
+
|
|
3
98
|
## 0.4.0 candidate
|
|
4
99
|
|
|
5
100
|
- Reissued the framework cohort for the breaking redemption domain contract;
|
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 {
|