@finsys/core 4.6.0 → 4.8.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.
- package/dist/data/adapter-categories.json +142 -2
- package/dist/index.cjs +231 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +80 -4
- package/dist/index.d.ts +80 -4
- package/dist/index.js +229 -7
- package/dist/index.js.map +1 -1
- package/dist/schema/adapter-manifest.schema.json +15 -0
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"schemaVersion": "1.
|
|
2
|
+
"schemaVersion": "1.2.0",
|
|
3
3
|
"categories": [
|
|
4
4
|
{
|
|
5
5
|
"id": "telco-carrier",
|
|
@@ -51,6 +51,30 @@
|
|
|
51
51
|
"unit": "MYR",
|
|
52
52
|
"range": [0, 10000],
|
|
53
53
|
"description": "Average Revenue Per User (monthly) in Malaysian Ringgit. Coarse spending-capacity proxy."
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"name": "telcoPaymentReliabilityTier",
|
|
57
|
+
"type": "string",
|
|
58
|
+
"kind": "enum",
|
|
59
|
+
"description": "Coarse bill-payment reliability bucket, for partners that return a tier label instead of a continuous ratio. Parallel signal to telcoOnTimePaymentRatio24m. Labels are vendor-declared (see the adapter manifest's enumValues); ordering and scoring live in the consumer's per-value mapping."
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"name": "telcoTenureTier",
|
|
63
|
+
"type": "string",
|
|
64
|
+
"kind": "enum",
|
|
65
|
+
"description": "Coarse account-age bucket, for partners that return a tenure tier label instead of a continuous month count. Parallel signal to telcoTenureMonths. Labels are vendor-declared (see the adapter manifest's enumValues)."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"name": "telcoDistressTier",
|
|
69
|
+
"type": "string",
|
|
70
|
+
"kind": "enum",
|
|
71
|
+
"description": "Coarse account-distress bucket, for partners that return a distress tier label instead of discrete counts. Parallel signal to telcoSuspensionsCount24m / telcoLateDays24m. Labels are vendor-declared (see the adapter manifest's enumValues)."
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"name": "telcoHandsetRiskTier",
|
|
75
|
+
"type": "string",
|
|
76
|
+
"kind": "enum",
|
|
77
|
+
"description": "Coarse handset-financing risk bucket, for partners that return a tier label instead of the discrete handset flags. Parallel signal to telcoHandsetFinancingActive / telcoHandsetFinancingDelinquent. Labels are vendor-declared (see the adapter manifest's enumValues)."
|
|
54
78
|
}
|
|
55
79
|
]
|
|
56
80
|
},
|
|
@@ -653,7 +677,8 @@
|
|
|
653
677
|
{
|
|
654
678
|
"name": "companyName",
|
|
655
679
|
"type": "string",
|
|
656
|
-
"
|
|
680
|
+
"fact": "companyName",
|
|
681
|
+
"description": "Company name as stated on the document. Attestation of the shared companyName fact — the SSM Form 9 extraction category attests the same fact from its own document."
|
|
657
682
|
},
|
|
658
683
|
{
|
|
659
684
|
"name": "financialYearEnd",
|
|
@@ -1372,6 +1397,121 @@
|
|
|
1372
1397
|
"description": "Cash-flow statement: cash and cash equivalents at the end of the financial year."
|
|
1373
1398
|
}
|
|
1374
1399
|
]
|
|
1400
|
+
},
|
|
1401
|
+
{
|
|
1402
|
+
"id": "finxtract-form9",
|
|
1403
|
+
"displayName": "SSM Form 9 (Document Extraction)",
|
|
1404
|
+
"description": "Fields extracted from an uploaded SSM Form 9 (Certificate of Incorporation of Private Company) document by the host's extraction pipeline. One instance per uploaded document. The company name and incorporation date are attestations of shared facts — the company-profile and financial-statement extraction categories attest the same real-world facts from their own documents.",
|
|
1405
|
+
"canonicalTable": "ihs_alt_data_form9",
|
|
1406
|
+
"fields": [
|
|
1407
|
+
{
|
|
1408
|
+
"name": "companyName",
|
|
1409
|
+
"type": "string",
|
|
1410
|
+
"fact": "companyName",
|
|
1411
|
+
"description": "Company name as printed on the certificate. Attestation of the shared companyName fact."
|
|
1412
|
+
},
|
|
1413
|
+
{
|
|
1414
|
+
"name": "companyRegNo",
|
|
1415
|
+
"type": "string",
|
|
1416
|
+
"description": "Company registration number as printed on the certificate."
|
|
1417
|
+
},
|
|
1418
|
+
{
|
|
1419
|
+
"name": "companyIncorporationDate",
|
|
1420
|
+
"type": "string",
|
|
1421
|
+
"fact": "companyIncorporationDate",
|
|
1422
|
+
"description": "Date of incorporation as printed on the certificate, normalized to ISO YYYY-MM-DD. Attestation of the shared companyIncorporationDate fact — a company has exactly one incorporation date regardless of which document it was extracted from."
|
|
1423
|
+
}
|
|
1424
|
+
]
|
|
1425
|
+
},
|
|
1426
|
+
{
|
|
1427
|
+
"id": "finxtract-ssm",
|
|
1428
|
+
"displayName": "SSM Company Profile (Document Extraction)",
|
|
1429
|
+
"description": "Fields extracted from an uploaded SSM company-profile document (company or business registration extract) by the host's extraction pipeline. One instance per uploaded document. Covers registration identity, status, key dates, registered address, capital, and the officer/shareholder registers. The incorporation date is an attestation of a shared fact — the Form 9 extraction category attests the same real-world fact from its own document.",
|
|
1430
|
+
"canonicalTable": "ihs_alt_data_ssm",
|
|
1431
|
+
"fields": [
|
|
1432
|
+
{
|
|
1433
|
+
"name": "ssmCompanyEntityType",
|
|
1434
|
+
"type": "string",
|
|
1435
|
+
"description": "Entity type stated on the profile (e.g. private limited company, enterprise)."
|
|
1436
|
+
},
|
|
1437
|
+
{
|
|
1438
|
+
"name": "ssmCompanyName",
|
|
1439
|
+
"type": "string",
|
|
1440
|
+
"description": "Business or company name as stated on the profile."
|
|
1441
|
+
},
|
|
1442
|
+
{
|
|
1443
|
+
"name": "ssmCompanyRegNo",
|
|
1444
|
+
"type": "string",
|
|
1445
|
+
"description": "Business or company registration number as stated on the profile."
|
|
1446
|
+
},
|
|
1447
|
+
{
|
|
1448
|
+
"name": "companyStatus",
|
|
1449
|
+
"type": "string",
|
|
1450
|
+
"description": "Registration status as stated on the profile (e.g. existing, dissolved)."
|
|
1451
|
+
},
|
|
1452
|
+
{
|
|
1453
|
+
"name": "businessOrigin",
|
|
1454
|
+
"type": "string",
|
|
1455
|
+
"description": "Business origin as stated on the profile."
|
|
1456
|
+
},
|
|
1457
|
+
{
|
|
1458
|
+
"name": "companyIncorporationDate",
|
|
1459
|
+
"type": "string",
|
|
1460
|
+
"fact": "companyIncorporationDate",
|
|
1461
|
+
"description": "Incorporation (or registration) date as stated on the profile, normalized to ISO YYYY-MM-DD. Attestation of the shared companyIncorporationDate fact — a company has exactly one incorporation date regardless of which document it was extracted from."
|
|
1462
|
+
},
|
|
1463
|
+
{
|
|
1464
|
+
"name": "businessCommencementDate",
|
|
1465
|
+
"type": "string",
|
|
1466
|
+
"description": "Business commencement (or start) date as stated on the profile, normalized to ISO YYYY-MM-DD."
|
|
1467
|
+
},
|
|
1468
|
+
{
|
|
1469
|
+
"name": "businessNature",
|
|
1470
|
+
"type": "string",
|
|
1471
|
+
"description": "Nature of business as stated on the profile."
|
|
1472
|
+
},
|
|
1473
|
+
{
|
|
1474
|
+
"name": "registeredAddress",
|
|
1475
|
+
"type": "string",
|
|
1476
|
+
"description": "Registered business address as stated on the profile."
|
|
1477
|
+
},
|
|
1478
|
+
{
|
|
1479
|
+
"name": "totalShareIssued",
|
|
1480
|
+
"type": "number",
|
|
1481
|
+
"description": "Total shares issued as stated on the profile."
|
|
1482
|
+
},
|
|
1483
|
+
{
|
|
1484
|
+
"name": "ssmPaidUpCapital",
|
|
1485
|
+
"type": "number",
|
|
1486
|
+
"unit": "MYR",
|
|
1487
|
+
"description": "Paid-up capital as stated on the profile (falls back to total shares issued when the profile omits an explicit paid-up figure)."
|
|
1488
|
+
},
|
|
1489
|
+
{
|
|
1490
|
+
"name": "directors",
|
|
1491
|
+
"type": "string",
|
|
1492
|
+
"description": "JSON-encoded list of current directors/officers (for enterprises, the business owner normalized into the same shape)."
|
|
1493
|
+
},
|
|
1494
|
+
{
|
|
1495
|
+
"name": "shareholders",
|
|
1496
|
+
"type": "string",
|
|
1497
|
+
"description": "JSON-encoded list of shareholders (for enterprises, the business owner normalized into the same shape)."
|
|
1498
|
+
},
|
|
1499
|
+
{
|
|
1500
|
+
"name": "previousDirectors",
|
|
1501
|
+
"type": "string",
|
|
1502
|
+
"description": "JSON-encoded list of previous directors/officers."
|
|
1503
|
+
},
|
|
1504
|
+
{
|
|
1505
|
+
"name": "companyLastOldName",
|
|
1506
|
+
"type": "string",
|
|
1507
|
+
"description": "The company's most recent former name, when the profile records a name change."
|
|
1508
|
+
},
|
|
1509
|
+
{
|
|
1510
|
+
"name": "companyNameDateOfChange",
|
|
1511
|
+
"type": "string",
|
|
1512
|
+
"description": "Date of the most recent name change, normalized to ISO YYYY-MM-DD."
|
|
1513
|
+
}
|
|
1514
|
+
]
|
|
1375
1515
|
}
|
|
1376
1516
|
]
|
|
1377
1517
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -61,11 +61,13 @@ __export(index_exports, {
|
|
|
61
61
|
buildDocumentRows: () => buildDocumentRows,
|
|
62
62
|
buildFileFieldTables: () => buildFileFieldTables,
|
|
63
63
|
buildFileFieldTablesFromInstances: () => buildFileFieldTablesFromInstances,
|
|
64
|
+
categoriesAttestingFact: () => categoriesAttestingFact,
|
|
64
65
|
categoryFieldsOf: () => categoryFieldsOf,
|
|
65
66
|
categoryForField: () => categoryForField,
|
|
66
67
|
categorySchemaOf: () => categorySchemaOf,
|
|
67
68
|
evaluateExpression: () => evaluateExpression,
|
|
68
69
|
extractTimePeriods: () => extractTimePeriods,
|
|
70
|
+
factOf: () => factOf,
|
|
69
71
|
formatDocumentSize: () => formatDocumentSize,
|
|
70
72
|
formatDocumentType: () => formatDocumentType,
|
|
71
73
|
formatDocumentUploaded: () => formatDocumentUploaded,
|
|
@@ -10321,7 +10323,7 @@ function applyAggregation(op, instances) {
|
|
|
10321
10323
|
|
|
10322
10324
|
// src/data/adapter-categories.json
|
|
10323
10325
|
var adapter_categories_default = {
|
|
10324
|
-
schemaVersion: "1.
|
|
10326
|
+
schemaVersion: "1.2.0",
|
|
10325
10327
|
categories: [
|
|
10326
10328
|
{
|
|
10327
10329
|
id: "telco-carrier",
|
|
@@ -10373,6 +10375,30 @@ var adapter_categories_default = {
|
|
|
10373
10375
|
unit: "MYR",
|
|
10374
10376
|
range: [0, 1e4],
|
|
10375
10377
|
description: "Average Revenue Per User (monthly) in Malaysian Ringgit. Coarse spending-capacity proxy."
|
|
10378
|
+
},
|
|
10379
|
+
{
|
|
10380
|
+
name: "telcoPaymentReliabilityTier",
|
|
10381
|
+
type: "string",
|
|
10382
|
+
kind: "enum",
|
|
10383
|
+
description: "Coarse bill-payment reliability bucket, for partners that return a tier label instead of a continuous ratio. Parallel signal to telcoOnTimePaymentRatio24m. Labels are vendor-declared (see the adapter manifest's enumValues); ordering and scoring live in the consumer's per-value mapping."
|
|
10384
|
+
},
|
|
10385
|
+
{
|
|
10386
|
+
name: "telcoTenureTier",
|
|
10387
|
+
type: "string",
|
|
10388
|
+
kind: "enum",
|
|
10389
|
+
description: "Coarse account-age bucket, for partners that return a tenure tier label instead of a continuous month count. Parallel signal to telcoTenureMonths. Labels are vendor-declared (see the adapter manifest's enumValues)."
|
|
10390
|
+
},
|
|
10391
|
+
{
|
|
10392
|
+
name: "telcoDistressTier",
|
|
10393
|
+
type: "string",
|
|
10394
|
+
kind: "enum",
|
|
10395
|
+
description: "Coarse account-distress bucket, for partners that return a distress tier label instead of discrete counts. Parallel signal to telcoSuspensionsCount24m / telcoLateDays24m. Labels are vendor-declared (see the adapter manifest's enumValues)."
|
|
10396
|
+
},
|
|
10397
|
+
{
|
|
10398
|
+
name: "telcoHandsetRiskTier",
|
|
10399
|
+
type: "string",
|
|
10400
|
+
kind: "enum",
|
|
10401
|
+
description: "Coarse handset-financing risk bucket, for partners that return a tier label instead of the discrete handset flags. Parallel signal to telcoHandsetFinancingActive / telcoHandsetFinancingDelinquent. Labels are vendor-declared (see the adapter manifest's enumValues)."
|
|
10376
10402
|
}
|
|
10377
10403
|
]
|
|
10378
10404
|
},
|
|
@@ -10975,7 +11001,8 @@ var adapter_categories_default = {
|
|
|
10975
11001
|
{
|
|
10976
11002
|
name: "companyName",
|
|
10977
11003
|
type: "string",
|
|
10978
|
-
|
|
11004
|
+
fact: "companyName",
|
|
11005
|
+
description: "Company name as stated on the document. Attestation of the shared companyName fact \u2014 the SSM Form 9 extraction category attests the same fact from its own document."
|
|
10979
11006
|
},
|
|
10980
11007
|
{
|
|
10981
11008
|
name: "financialYearEnd",
|
|
@@ -11694,6 +11721,121 @@ var adapter_categories_default = {
|
|
|
11694
11721
|
description: "Cash-flow statement: cash and cash equivalents at the end of the financial year."
|
|
11695
11722
|
}
|
|
11696
11723
|
]
|
|
11724
|
+
},
|
|
11725
|
+
{
|
|
11726
|
+
id: "finxtract-form9",
|
|
11727
|
+
displayName: "SSM Form 9 (Document Extraction)",
|
|
11728
|
+
description: "Fields extracted from an uploaded SSM Form 9 (Certificate of Incorporation of Private Company) document by the host's extraction pipeline. One instance per uploaded document. The company name and incorporation date are attestations of shared facts \u2014 the company-profile and financial-statement extraction categories attest the same real-world facts from their own documents.",
|
|
11729
|
+
canonicalTable: "ihs_alt_data_form9",
|
|
11730
|
+
fields: [
|
|
11731
|
+
{
|
|
11732
|
+
name: "companyName",
|
|
11733
|
+
type: "string",
|
|
11734
|
+
fact: "companyName",
|
|
11735
|
+
description: "Company name as printed on the certificate. Attestation of the shared companyName fact."
|
|
11736
|
+
},
|
|
11737
|
+
{
|
|
11738
|
+
name: "companyRegNo",
|
|
11739
|
+
type: "string",
|
|
11740
|
+
description: "Company registration number as printed on the certificate."
|
|
11741
|
+
},
|
|
11742
|
+
{
|
|
11743
|
+
name: "companyIncorporationDate",
|
|
11744
|
+
type: "string",
|
|
11745
|
+
fact: "companyIncorporationDate",
|
|
11746
|
+
description: "Date of incorporation as printed on the certificate, normalized to ISO YYYY-MM-DD. Attestation of the shared companyIncorporationDate fact \u2014 a company has exactly one incorporation date regardless of which document it was extracted from."
|
|
11747
|
+
}
|
|
11748
|
+
]
|
|
11749
|
+
},
|
|
11750
|
+
{
|
|
11751
|
+
id: "finxtract-ssm",
|
|
11752
|
+
displayName: "SSM Company Profile (Document Extraction)",
|
|
11753
|
+
description: "Fields extracted from an uploaded SSM company-profile document (company or business registration extract) by the host's extraction pipeline. One instance per uploaded document. Covers registration identity, status, key dates, registered address, capital, and the officer/shareholder registers. The incorporation date is an attestation of a shared fact \u2014 the Form 9 extraction category attests the same real-world fact from its own document.",
|
|
11754
|
+
canonicalTable: "ihs_alt_data_ssm",
|
|
11755
|
+
fields: [
|
|
11756
|
+
{
|
|
11757
|
+
name: "ssmCompanyEntityType",
|
|
11758
|
+
type: "string",
|
|
11759
|
+
description: "Entity type stated on the profile (e.g. private limited company, enterprise)."
|
|
11760
|
+
},
|
|
11761
|
+
{
|
|
11762
|
+
name: "ssmCompanyName",
|
|
11763
|
+
type: "string",
|
|
11764
|
+
description: "Business or company name as stated on the profile."
|
|
11765
|
+
},
|
|
11766
|
+
{
|
|
11767
|
+
name: "ssmCompanyRegNo",
|
|
11768
|
+
type: "string",
|
|
11769
|
+
description: "Business or company registration number as stated on the profile."
|
|
11770
|
+
},
|
|
11771
|
+
{
|
|
11772
|
+
name: "companyStatus",
|
|
11773
|
+
type: "string",
|
|
11774
|
+
description: "Registration status as stated on the profile (e.g. existing, dissolved)."
|
|
11775
|
+
},
|
|
11776
|
+
{
|
|
11777
|
+
name: "businessOrigin",
|
|
11778
|
+
type: "string",
|
|
11779
|
+
description: "Business origin as stated on the profile."
|
|
11780
|
+
},
|
|
11781
|
+
{
|
|
11782
|
+
name: "companyIncorporationDate",
|
|
11783
|
+
type: "string",
|
|
11784
|
+
fact: "companyIncorporationDate",
|
|
11785
|
+
description: "Incorporation (or registration) date as stated on the profile, normalized to ISO YYYY-MM-DD. Attestation of the shared companyIncorporationDate fact \u2014 a company has exactly one incorporation date regardless of which document it was extracted from."
|
|
11786
|
+
},
|
|
11787
|
+
{
|
|
11788
|
+
name: "businessCommencementDate",
|
|
11789
|
+
type: "string",
|
|
11790
|
+
description: "Business commencement (or start) date as stated on the profile, normalized to ISO YYYY-MM-DD."
|
|
11791
|
+
},
|
|
11792
|
+
{
|
|
11793
|
+
name: "businessNature",
|
|
11794
|
+
type: "string",
|
|
11795
|
+
description: "Nature of business as stated on the profile."
|
|
11796
|
+
},
|
|
11797
|
+
{
|
|
11798
|
+
name: "registeredAddress",
|
|
11799
|
+
type: "string",
|
|
11800
|
+
description: "Registered business address as stated on the profile."
|
|
11801
|
+
},
|
|
11802
|
+
{
|
|
11803
|
+
name: "totalShareIssued",
|
|
11804
|
+
type: "number",
|
|
11805
|
+
description: "Total shares issued as stated on the profile."
|
|
11806
|
+
},
|
|
11807
|
+
{
|
|
11808
|
+
name: "ssmPaidUpCapital",
|
|
11809
|
+
type: "number",
|
|
11810
|
+
unit: "MYR",
|
|
11811
|
+
description: "Paid-up capital as stated on the profile (falls back to total shares issued when the profile omits an explicit paid-up figure)."
|
|
11812
|
+
},
|
|
11813
|
+
{
|
|
11814
|
+
name: "directors",
|
|
11815
|
+
type: "string",
|
|
11816
|
+
description: "JSON-encoded list of current directors/officers (for enterprises, the business owner normalized into the same shape)."
|
|
11817
|
+
},
|
|
11818
|
+
{
|
|
11819
|
+
name: "shareholders",
|
|
11820
|
+
type: "string",
|
|
11821
|
+
description: "JSON-encoded list of shareholders (for enterprises, the business owner normalized into the same shape)."
|
|
11822
|
+
},
|
|
11823
|
+
{
|
|
11824
|
+
name: "previousDirectors",
|
|
11825
|
+
type: "string",
|
|
11826
|
+
description: "JSON-encoded list of previous directors/officers."
|
|
11827
|
+
},
|
|
11828
|
+
{
|
|
11829
|
+
name: "companyLastOldName",
|
|
11830
|
+
type: "string",
|
|
11831
|
+
description: "The company's most recent former name, when the profile records a name change."
|
|
11832
|
+
},
|
|
11833
|
+
{
|
|
11834
|
+
name: "companyNameDateOfChange",
|
|
11835
|
+
type: "string",
|
|
11836
|
+
description: "Date of the most recent name change, normalized to ISO YYYY-MM-DD."
|
|
11837
|
+
}
|
|
11838
|
+
]
|
|
11697
11839
|
}
|
|
11698
11840
|
]
|
|
11699
11841
|
};
|
|
@@ -11704,6 +11846,7 @@ var VALID_FIELD_TYPES = [
|
|
|
11704
11846
|
"boolean",
|
|
11705
11847
|
"string"
|
|
11706
11848
|
];
|
|
11849
|
+
var VALID_FIELD_KINDS = ["enum"];
|
|
11707
11850
|
function buildCategoryRegistry(raw) {
|
|
11708
11851
|
if (!raw || typeof raw !== "object") {
|
|
11709
11852
|
throw new Error("adapter category data: expected an object");
|
|
@@ -11716,6 +11859,9 @@ function buildCategoryRegistry(raw) {
|
|
|
11716
11859
|
}
|
|
11717
11860
|
const byId = /* @__PURE__ */ new Map();
|
|
11718
11861
|
const fieldToCategory = /* @__PURE__ */ new Map();
|
|
11862
|
+
const fieldToFact = /* @__PURE__ */ new Map();
|
|
11863
|
+
const factToCategories = /* @__PURE__ */ new Map();
|
|
11864
|
+
const declarations = /* @__PURE__ */ new Map();
|
|
11719
11865
|
const tables = /* @__PURE__ */ new Set();
|
|
11720
11866
|
const all = [];
|
|
11721
11867
|
for (const cat of raw.categories) {
|
|
@@ -11750,16 +11896,62 @@ function buildCategoryRegistry(raw) {
|
|
|
11750
11896
|
if (typeof f.name !== "string" || f.name.length === 0) {
|
|
11751
11897
|
throw new Error(`adapter category data: ${where} has a field with no name`);
|
|
11752
11898
|
}
|
|
11753
|
-
if (
|
|
11899
|
+
if (f.fact !== void 0 && (typeof f.fact !== "string" || f.fact.length === 0)) {
|
|
11754
11900
|
throw new Error(
|
|
11755
|
-
`adapter category data:
|
|
11901
|
+
`adapter category data: field "${f.name}" (${where}) has an invalid fact \u2014 expected a non-empty string`
|
|
11756
11902
|
);
|
|
11757
11903
|
}
|
|
11904
|
+
const prior = declarations.get(f.name);
|
|
11905
|
+
if (prior) {
|
|
11906
|
+
if (prior.categories.includes(cat.id)) {
|
|
11907
|
+
throw new Error(
|
|
11908
|
+
`adapter category data: ${where} declares field "${f.name}" more than once`
|
|
11909
|
+
);
|
|
11910
|
+
}
|
|
11911
|
+
if (prior.fact === void 0 || f.fact === void 0 || prior.fact !== f.fact) {
|
|
11912
|
+
const describeFact = (fact) => fact === void 0 ? "no fact" : `fact "${fact}"`;
|
|
11913
|
+
throw new Error(
|
|
11914
|
+
`adapter category data: canonical field "${f.name}" declared by more than one category (${prior.categories.join(" + ")} with ${describeFact(prior.fact)} + ${cat.id} with ${describeFact(f.fact)}) \u2014 field names must be globally unique unless every declaring category attests the same fact`
|
|
11915
|
+
);
|
|
11916
|
+
}
|
|
11917
|
+
if (prior.kind !== f.kind) {
|
|
11918
|
+
const describeKind = (kind) => kind === void 0 ? "no kind" : `kind "${kind}"`;
|
|
11919
|
+
throw new Error(
|
|
11920
|
+
`adapter category data: canonical field "${f.name}" declared with ${describeKind(prior.kind)} by ${prior.categories.join(" + ")} but ${describeKind(f.kind)} by ${cat.id} \u2014 shared-fact attestations must agree on kind`
|
|
11921
|
+
);
|
|
11922
|
+
}
|
|
11923
|
+
}
|
|
11924
|
+
if (f.fact !== void 0) {
|
|
11925
|
+
for (const [otherName, otherFact] of fieldToFact) {
|
|
11926
|
+
if (otherFact === f.fact && otherName !== f.name) {
|
|
11927
|
+
throw new Error(
|
|
11928
|
+
`adapter category data: fact "${f.fact}" is carried by two different field names ("${otherName}" + "${f.name}") \u2014 a fact id must map to exactly one canonical field name`
|
|
11929
|
+
);
|
|
11930
|
+
}
|
|
11931
|
+
}
|
|
11932
|
+
}
|
|
11758
11933
|
if (!VALID_FIELD_TYPES.includes(f.type)) {
|
|
11759
11934
|
throw new Error(
|
|
11760
11935
|
`adapter category data: field "${f.name}" (${where}) has invalid type "${f.type}"`
|
|
11761
11936
|
);
|
|
11762
11937
|
}
|
|
11938
|
+
if (f.kind !== void 0) {
|
|
11939
|
+
if (!VALID_FIELD_KINDS.includes(f.kind)) {
|
|
11940
|
+
throw new Error(
|
|
11941
|
+
`adapter category data: field "${f.name}" (${where}) has invalid kind "${String(f.kind)}"`
|
|
11942
|
+
);
|
|
11943
|
+
}
|
|
11944
|
+
if (f.type !== "string") {
|
|
11945
|
+
throw new Error(
|
|
11946
|
+
`adapter category data: field "${f.name}" (${where}) is kind "enum" but type "${f.type}" \u2014 enum labels are string-normalized, so an enum field must be type "string"`
|
|
11947
|
+
);
|
|
11948
|
+
}
|
|
11949
|
+
if (f.range !== void 0) {
|
|
11950
|
+
throw new Error(
|
|
11951
|
+
`adapter category data: field "${f.name}" (${where}) is kind "enum" but declares a range \u2014 enum labels are unordered; ordering belongs to the consumer, never the data contract`
|
|
11952
|
+
);
|
|
11953
|
+
}
|
|
11954
|
+
}
|
|
11763
11955
|
if (typeof f.description !== "string" || f.description.length === 0) {
|
|
11764
11956
|
throw new Error(
|
|
11765
11957
|
`adapter category data: field "${f.name}" (${where}) needs a non-empty description`
|
|
@@ -11777,10 +11969,27 @@ function buildCategoryRegistry(raw) {
|
|
|
11777
11969
|
type: f.type,
|
|
11778
11970
|
...f.unit !== void 0 ? { unit: f.unit } : {},
|
|
11779
11971
|
...f.range !== void 0 ? { range: Object.freeze([f.range[0], f.range[1]]) } : {},
|
|
11780
|
-
description: f.description
|
|
11972
|
+
description: f.description,
|
|
11973
|
+
...f.fact !== void 0 ? { fact: f.fact } : {},
|
|
11974
|
+
...f.kind !== void 0 ? { kind: f.kind } : {}
|
|
11781
11975
|
});
|
|
11782
11976
|
fields.push(spec);
|
|
11783
|
-
|
|
11977
|
+
if (prior) {
|
|
11978
|
+
prior.categories.push(cat.id);
|
|
11979
|
+
fieldToCategory.delete(f.name);
|
|
11980
|
+
} else {
|
|
11981
|
+
declarations.set(f.name, { fact: f.fact, kind: f.kind, categories: [cat.id] });
|
|
11982
|
+
fieldToCategory.set(f.name, cat.id);
|
|
11983
|
+
}
|
|
11984
|
+
if (f.fact !== void 0) {
|
|
11985
|
+
fieldToFact.set(f.name, f.fact);
|
|
11986
|
+
const attesters = factToCategories.get(f.fact);
|
|
11987
|
+
if (attesters) {
|
|
11988
|
+
attesters.push(cat.id);
|
|
11989
|
+
} else {
|
|
11990
|
+
factToCategories.set(f.fact, [cat.id]);
|
|
11991
|
+
}
|
|
11992
|
+
}
|
|
11784
11993
|
}
|
|
11785
11994
|
const schema = Object.freeze({
|
|
11786
11995
|
id: cat.id,
|
|
@@ -11797,7 +12006,14 @@ function buildCategoryRegistry(raw) {
|
|
|
11797
12006
|
all: Object.freeze(all),
|
|
11798
12007
|
ids: Object.freeze(all.map((c) => c.id)),
|
|
11799
12008
|
byId,
|
|
11800
|
-
fieldToCategory
|
|
12009
|
+
fieldToCategory,
|
|
12010
|
+
fieldToFact,
|
|
12011
|
+
factToCategories: new Map(
|
|
12012
|
+
[...factToCategories].map(([fact, cats]) => [
|
|
12013
|
+
fact,
|
|
12014
|
+
Object.freeze(cats)
|
|
12015
|
+
])
|
|
12016
|
+
)
|
|
11801
12017
|
});
|
|
11802
12018
|
}
|
|
11803
12019
|
var registry = buildCategoryRegistry(adapter_categories_default);
|
|
@@ -11820,6 +12036,12 @@ function allCategories() {
|
|
|
11820
12036
|
function categoryForField(field) {
|
|
11821
12037
|
return registry.fieldToCategory.get(field) ?? null;
|
|
11822
12038
|
}
|
|
12039
|
+
function factOf(field) {
|
|
12040
|
+
return registry.fieldToFact.get(field) ?? null;
|
|
12041
|
+
}
|
|
12042
|
+
function categoriesAttestingFact(factId) {
|
|
12043
|
+
return registry.factToCategories.get(factId) ?? [];
|
|
12044
|
+
}
|
|
11823
12045
|
function isAdapterCategory(id) {
|
|
11824
12046
|
return registry.byId.has(id);
|
|
11825
12047
|
}
|
|
@@ -11864,11 +12086,13 @@ function assertAdapterCategory(id) {
|
|
|
11864
12086
|
buildDocumentRows,
|
|
11865
12087
|
buildFileFieldTables,
|
|
11866
12088
|
buildFileFieldTablesFromInstances,
|
|
12089
|
+
categoriesAttestingFact,
|
|
11867
12090
|
categoryFieldsOf,
|
|
11868
12091
|
categoryForField,
|
|
11869
12092
|
categorySchemaOf,
|
|
11870
12093
|
evaluateExpression,
|
|
11871
12094
|
extractTimePeriods,
|
|
12095
|
+
factOf,
|
|
11872
12096
|
formatDocumentSize,
|
|
11873
12097
|
formatDocumentType,
|
|
11874
12098
|
formatDocumentUploaded,
|