@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 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, and markdown-it for the published
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.0",
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.24",
70
- "@global-torque/domain-types": "0.4.0",
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>;
@@ -1,4 +1,4 @@
1
- import trimEnd from 'lodash/trimEnd.js';
1
+ import trimEnd from 'lodash-es/trimEnd.js';
2
2
 
3
3
  /**
4
4
  * when round === Infinity -> 1000.0000123 convert to 1,000.000123
@@ -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);
@@ -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 {