@finsys/core 2.6.0 → 3.1.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/README.md +14 -2
- package/dist/data/adapter-categories.json +142 -2
- package/dist/index.cjs +282 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +207 -23
- package/dist/index.d.ts +207 -23
- package/dist/index.js +279 -32
- package/dist/index.js.map +1 -1
- package/dist/schema/adapter-manifest.schema.json +13 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ function getPastYearLabel(yearsAgo) {
|
|
|
9
9
|
const date = /* @__PURE__ */ new Date();
|
|
10
10
|
return (date.getFullYear() - yearsAgo).toString();
|
|
11
11
|
}
|
|
12
|
-
function evaluateExpression(expression,
|
|
12
|
+
function evaluateExpression(expression, data) {
|
|
13
13
|
if (!expression) return true;
|
|
14
14
|
try {
|
|
15
15
|
let jsExpression = expression.replace(/\{([^}]+)\}/g, (_, key) => {
|
|
@@ -33,7 +33,7 @@ function evaluateExpression(expression, data2) {
|
|
|
33
33
|
(_, ref, val) => `!(${ref} || []).includes('${val}')`
|
|
34
34
|
);
|
|
35
35
|
const func = new Function(`return ${jsExpression};`);
|
|
36
|
-
return !!func.call(
|
|
36
|
+
return !!func.call(data || {});
|
|
37
37
|
} catch (e) {
|
|
38
38
|
return false;
|
|
39
39
|
}
|
|
@@ -179,16 +179,16 @@ function groupFieldsByCategory(fields, categories) {
|
|
|
179
179
|
// src/rhf-generator.ts
|
|
180
180
|
import { z } from "zod";
|
|
181
181
|
function applyVisibilityValidation(baseObject, fields) {
|
|
182
|
-
return baseObject.superRefine((
|
|
182
|
+
return baseObject.superRefine((data, ctx) => {
|
|
183
183
|
fields.forEach((field) => {
|
|
184
184
|
const isRequired = field.isRequired !== false && field.required !== false && field.type !== "html";
|
|
185
185
|
if (!isRequired) return;
|
|
186
186
|
let isVisible = field.visible !== false;
|
|
187
187
|
if (isVisible && field.visibleIf) {
|
|
188
|
-
isVisible = evaluateExpression(field.visibleIf,
|
|
188
|
+
isVisible = evaluateExpression(field.visibleIf, data);
|
|
189
189
|
}
|
|
190
190
|
if (isVisible) {
|
|
191
|
-
const value =
|
|
191
|
+
const value = data[field.name];
|
|
192
192
|
const isEmpty = value === void 0 || value === null || value === "" || Array.isArray(value) && value.length === 0;
|
|
193
193
|
if (isEmpty) {
|
|
194
194
|
ctx.addIssue({
|
|
@@ -649,22 +649,22 @@ var ajv = new Ajv({ allErrors: true, strict: false });
|
|
|
649
649
|
var addFormatsFn = addFormats.default || addFormats;
|
|
650
650
|
addFormatsFn(ajv);
|
|
651
651
|
ajv.addSchema(unified_form_schema_default, "unified-form.schema.json");
|
|
652
|
-
function validateFormConfig(
|
|
652
|
+
function validateFormConfig(data) {
|
|
653
653
|
const validate = ajv.getSchema("unified-form.schema.json");
|
|
654
654
|
if (!validate) {
|
|
655
655
|
return { valid: false, message: "Could not load unified form schema" };
|
|
656
656
|
}
|
|
657
|
-
const valid = validate(
|
|
657
|
+
const valid = validate(data);
|
|
658
658
|
return {
|
|
659
659
|
valid: !!valid,
|
|
660
660
|
errors: validate.errors || void 0
|
|
661
661
|
};
|
|
662
662
|
}
|
|
663
|
-
function validateFormSpec(
|
|
664
|
-
return validateFormConfig(
|
|
663
|
+
function validateFormSpec(data) {
|
|
664
|
+
return validateFormConfig(data);
|
|
665
665
|
}
|
|
666
|
-
function validatePagesConfig(
|
|
667
|
-
return validateFormConfig(
|
|
666
|
+
function validatePagesConfig(data) {
|
|
667
|
+
return validateFormConfig(data);
|
|
668
668
|
}
|
|
669
669
|
|
|
670
670
|
// src/form-field-category.ts
|
|
@@ -1121,10 +1121,10 @@ var _FormSpec = class _FormSpec {
|
|
|
1121
1121
|
if (Array.isArray(jsonData.fields)) {
|
|
1122
1122
|
fieldObjects = jsonData.fields;
|
|
1123
1123
|
} else if (typeof jsonData.fields === "object" && jsonData.fields !== null) {
|
|
1124
|
-
fieldObjects = Object.entries(jsonData.fields).map(([name,
|
|
1124
|
+
fieldObjects = Object.entries(jsonData.fields).map(([name, data]) => {
|
|
1125
1125
|
return {
|
|
1126
1126
|
name,
|
|
1127
|
-
...
|
|
1127
|
+
...data
|
|
1128
1128
|
};
|
|
1129
1129
|
});
|
|
1130
1130
|
}
|
|
@@ -9382,18 +9382,18 @@ function buildTableForGroup(groupName, fields, ihsData) {
|
|
|
9382
9382
|
const items = [];
|
|
9383
9383
|
for (const [baseName, periodMap] of Object.entries(columnGroups)) {
|
|
9384
9384
|
const numeric = isNumericField(baseName);
|
|
9385
|
-
const
|
|
9385
|
+
const data = {};
|
|
9386
9386
|
const formattedData = {};
|
|
9387
9387
|
for (const period of periods) {
|
|
9388
9388
|
const colName = periodMap[period];
|
|
9389
9389
|
const value = colName ? ihsData[colName] ?? null : null;
|
|
9390
|
-
|
|
9390
|
+
data[period] = value;
|
|
9391
9391
|
formattedData[period] = formatValue(value, numeric);
|
|
9392
9392
|
}
|
|
9393
9393
|
items.push({
|
|
9394
9394
|
displayName: getDisplayName(baseName),
|
|
9395
9395
|
timePeriods: periods,
|
|
9396
|
-
data
|
|
9396
|
+
data,
|
|
9397
9397
|
formattedData,
|
|
9398
9398
|
type: tableType,
|
|
9399
9399
|
isNumeric: numeric
|
|
@@ -9814,7 +9814,7 @@ var adapter_categories_default = {
|
|
|
9814
9814
|
{
|
|
9815
9815
|
id: "telco-carrier",
|
|
9816
9816
|
displayName: "Telco Carrier",
|
|
9817
|
-
description: "Mobile carrier bill-payment + account-history signals. Any
|
|
9817
|
+
description: "Mobile carrier bill-payment + account-history signals. Any mobile carrier implementing this category produces the same canonical field set.",
|
|
9818
9818
|
canonicalTable: "ihs_alt_data_telco",
|
|
9819
9819
|
fields: [
|
|
9820
9820
|
{
|
|
@@ -9867,7 +9867,7 @@ var adapter_categories_default = {
|
|
|
9867
9867
|
{
|
|
9868
9868
|
id: "payment-network",
|
|
9869
9869
|
displayName: "Payment Network",
|
|
9870
|
-
description: "Merchant-side payment-flow signals from POS / gateway networks
|
|
9870
|
+
description: "Merchant-side payment-flow signals from POS / payment-gateway networks. Captures actual transaction velocity rather than self-reported revenue.",
|
|
9871
9871
|
canonicalTable: "ihs_alt_data_payments",
|
|
9872
9872
|
fields: [
|
|
9873
9873
|
{
|
|
@@ -9961,17 +9961,259 @@ var adapter_categories_default = {
|
|
|
9961
9961
|
description: "Bounced / returned transactions in the period. Distress signal at counts > 0."
|
|
9962
9962
|
}
|
|
9963
9963
|
]
|
|
9964
|
+
},
|
|
9965
|
+
{
|
|
9966
|
+
id: "social-media",
|
|
9967
|
+
displayName: "Social Media Presence",
|
|
9968
|
+
description: "Public business-presence signals from social / commerce platforms \u2014 establishment, reach, engagement authenticity, customer reputation, and account standing. Vendor-agnostic: any platform exposing a public business profile maps its data to this canonical field set. Useful as thin-file corroboration of a borrower's operating reality where formal financials are sparse.",
|
|
9969
|
+
canonicalTable: "ihs_alt_data_social_media",
|
|
9970
|
+
fields: [
|
|
9971
|
+
{
|
|
9972
|
+
name: "socialAccountTenureMonths",
|
|
9973
|
+
type: "number",
|
|
9974
|
+
unit: "months",
|
|
9975
|
+
range: [0, 600],
|
|
9976
|
+
description: "Age of the oldest verified public business presence across linked profiles. Establishment / continuity proxy, parallel to telco + payment-network tenure."
|
|
9977
|
+
},
|
|
9978
|
+
{
|
|
9979
|
+
name: "socialFollowerCount",
|
|
9980
|
+
type: "number",
|
|
9981
|
+
unit: "count",
|
|
9982
|
+
range: [0, 1e8],
|
|
9983
|
+
description: "Aggregate audience size across linked public profiles. Coarse reach / scale proxy \u2014 gameable on its own, so read alongside socialEngagementRate90d."
|
|
9984
|
+
},
|
|
9985
|
+
{
|
|
9986
|
+
name: "socialEngagementRate90d",
|
|
9987
|
+
type: "number",
|
|
9988
|
+
unit: "ratio",
|
|
9989
|
+
range: [0, 1],
|
|
9990
|
+
description: "Mean interactions per impression over the trailing 90 days. Authenticity signal: a large follower count with near-zero engagement indicates a bought or dormant audience."
|
|
9991
|
+
},
|
|
9992
|
+
{
|
|
9993
|
+
name: "socialPostingConsistency12m",
|
|
9994
|
+
type: "number",
|
|
9995
|
+
unit: "ratio",
|
|
9996
|
+
range: [0, 1],
|
|
9997
|
+
description: "Fraction of weeks in the trailing 12 months with at least one public post. Ongoing-operation signal \u2014 distinguishes an active business from a stale listing."
|
|
9998
|
+
},
|
|
9999
|
+
{
|
|
10000
|
+
name: "socialVerifiedBusinessAccount",
|
|
10001
|
+
type: "boolean",
|
|
10002
|
+
description: "Has at least one platform-verified business / commerce profile. Legitimacy signal \u2014 the platform has performed its own business-identity check."
|
|
10003
|
+
},
|
|
10004
|
+
{
|
|
10005
|
+
name: "socialCustomerRatingAvg",
|
|
10006
|
+
type: "number",
|
|
10007
|
+
unit: "rating",
|
|
10008
|
+
range: [0, 5],
|
|
10009
|
+
description: "Mean public customer rating (normalised to a 0\u20135 scale) across review-bearing profiles. Reputation signal; especially predictive for consumer-facing SMEs."
|
|
10010
|
+
},
|
|
10011
|
+
{
|
|
10012
|
+
name: "socialNegativeSentimentRatio90d",
|
|
10013
|
+
type: "number",
|
|
10014
|
+
unit: "ratio",
|
|
10015
|
+
range: [0, 1],
|
|
10016
|
+
description: "Fraction of public mentions / reviews classified as negative over the trailing 90 days. Reputation-risk / distress signal independent of overall rating volume."
|
|
10017
|
+
},
|
|
10018
|
+
{
|
|
10019
|
+
name: "socialAccountFlags24m",
|
|
10020
|
+
type: "number",
|
|
10021
|
+
unit: "count",
|
|
10022
|
+
range: [0, 100],
|
|
10023
|
+
description: "Policy strikes, suspensions, or content takedowns across linked profiles in the last 24 months. Distress signal, parallel to telcoSuspensionsCount24m."
|
|
10024
|
+
}
|
|
10025
|
+
]
|
|
10026
|
+
},
|
|
10027
|
+
{
|
|
10028
|
+
id: "trade-credit",
|
|
10029
|
+
displayName: "Trade Credit (Accounting)",
|
|
10030
|
+
description: "Accounts-receivable / accounts-payable aging and ledger-derived working-capital signals sourced from a business's accounting / ERP system. Captures how promptly the business collects from its debtors and pays its creditors, the aging profile and concentration of its receivables, and P&L / cash-conversion efficiency. Vendor-agnostic: any accounting or ERP system that exposes an AR/AP aging report plus a P&L summary maps its data to this canonical field set. A direct, high-signal view of trade-obligation behaviour \u2014 closer to formal credit history than most alternative data \u2014 and the anchor for cross-referencing self-reported accounting figures against bank-statement reality.",
|
|
10031
|
+
canonicalTable: "ihs_alt_data_trade_credit",
|
|
10032
|
+
fields: [
|
|
10033
|
+
{
|
|
10034
|
+
name: "arDaysSalesOutstanding",
|
|
10035
|
+
type: "number",
|
|
10036
|
+
unit: "days",
|
|
10037
|
+
range: [0, 400],
|
|
10038
|
+
description: "Days Sales Outstanding \u2014 average days to collect a receivable. The headline collection-efficiency metric; lower is healthier, and a rising DSO is an early liquidity-stress signal."
|
|
10039
|
+
},
|
|
10040
|
+
{
|
|
10041
|
+
name: "apDaysPayableOutstanding",
|
|
10042
|
+
type: "number",
|
|
10043
|
+
unit: "days",
|
|
10044
|
+
range: [0, 400],
|
|
10045
|
+
description: "Days Payable Outstanding \u2014 average days the business takes to pay its suppliers. Context for DSO; a very high DPO can indicate the business is stretching its creditors to fund operations."
|
|
10046
|
+
},
|
|
10047
|
+
{
|
|
10048
|
+
name: "arTotalOutstandingMyr",
|
|
10049
|
+
type: "number",
|
|
10050
|
+
unit: "MYR",
|
|
10051
|
+
range: [0, 1e9],
|
|
10052
|
+
description: "Total accounts-receivable balance outstanding (RM). The size of the debtor book the business is carrying."
|
|
10053
|
+
},
|
|
10054
|
+
{
|
|
10055
|
+
name: "arCurrentRatio",
|
|
10056
|
+
type: "number",
|
|
10057
|
+
unit: "ratio",
|
|
10058
|
+
range: [0, 1],
|
|
10059
|
+
description: "Fraction of the receivables book that is current (within payment terms, not yet overdue). Higher is healthier; the complement is the overdue share across all aging buckets."
|
|
10060
|
+
},
|
|
10061
|
+
{
|
|
10062
|
+
name: "arOverdue90PlusRatio",
|
|
10063
|
+
type: "number",
|
|
10064
|
+
unit: "ratio",
|
|
10065
|
+
range: [0, 1],
|
|
10066
|
+
description: "Fraction of the receivables book aged more than 90 days past terms. The key impairment / bad-debt risk signal from the AR aging report; elevated values indicate collection difficulty."
|
|
10067
|
+
},
|
|
10068
|
+
{
|
|
10069
|
+
name: "debtorConcentrationTop5Ratio",
|
|
10070
|
+
type: "number",
|
|
10071
|
+
unit: "ratio",
|
|
10072
|
+
range: [0, 1],
|
|
10073
|
+
description: "Share of total receivables owed by the top-5 debtors. Above ~0.6 is single-customer concentration risk \u2014 one debtor default would materially impair cash flow."
|
|
10074
|
+
},
|
|
10075
|
+
{
|
|
10076
|
+
name: "tradeReferenceDefaults12m",
|
|
10077
|
+
type: "number",
|
|
10078
|
+
unit: "count",
|
|
10079
|
+
range: [0, 1e3],
|
|
10080
|
+
description: "Count of supplier-reported defaults or dishonoured / returned payments against the business in the trailing 12 months. Direct distress signal, parallel to a bureau default record."
|
|
10081
|
+
},
|
|
10082
|
+
{
|
|
10083
|
+
name: "accountingRevenue12mMyr",
|
|
10084
|
+
type: "number",
|
|
10085
|
+
unit: "MYR",
|
|
10086
|
+
range: [0, 1e9],
|
|
10087
|
+
description: "Trailing-12-month turnover per the general ledger (RM). The cross-reference anchor: comparing this self-reported accounting revenue against payment-network volume and bank-statement inflows surfaces book-vs-reality inconsistencies."
|
|
10088
|
+
},
|
|
10089
|
+
{
|
|
10090
|
+
name: "grossMarginPct",
|
|
10091
|
+
type: "number",
|
|
10092
|
+
unit: "ratio",
|
|
10093
|
+
range: [0, 1],
|
|
10094
|
+
description: "Gross margin from the P&L (gross profit / revenue). Profitability-quality signal; a thin or declining margin constrains debt-service capacity even at healthy revenue."
|
|
10095
|
+
},
|
|
10096
|
+
{
|
|
10097
|
+
name: "cashConversionCycleDays",
|
|
10098
|
+
type: "number",
|
|
10099
|
+
unit: "days",
|
|
10100
|
+
range: [-200, 600],
|
|
10101
|
+
description: "Cash Conversion Cycle (DSO + days-inventory-outstanding \u2212 DPO). Working-capital efficiency; negative values (collect before paying suppliers) are strongest, very high values indicate cash tied up in operations."
|
|
10102
|
+
}
|
|
10103
|
+
]
|
|
9964
10104
|
}
|
|
9965
10105
|
]
|
|
9966
10106
|
};
|
|
9967
10107
|
|
|
9968
10108
|
// src/adapter-categories.ts
|
|
9969
|
-
var
|
|
10109
|
+
var VALID_FIELD_TYPES = [
|
|
10110
|
+
"number",
|
|
10111
|
+
"boolean",
|
|
10112
|
+
"string"
|
|
10113
|
+
];
|
|
10114
|
+
function buildCategoryRegistry(raw) {
|
|
10115
|
+
if (!raw || typeof raw !== "object") {
|
|
10116
|
+
throw new Error("adapter category data: expected an object");
|
|
10117
|
+
}
|
|
10118
|
+
if (typeof raw.schemaVersion !== "string" || raw.schemaVersion.length === 0) {
|
|
10119
|
+
throw new Error("adapter category data: missing schemaVersion");
|
|
10120
|
+
}
|
|
10121
|
+
if (!Array.isArray(raw.categories) || raw.categories.length === 0) {
|
|
10122
|
+
throw new Error("adapter category data: categories must be a non-empty array");
|
|
10123
|
+
}
|
|
10124
|
+
const byId = /* @__PURE__ */ new Map();
|
|
10125
|
+
const fieldToCategory = /* @__PURE__ */ new Map();
|
|
10126
|
+
const tables = /* @__PURE__ */ new Set();
|
|
10127
|
+
const all = [];
|
|
10128
|
+
for (const cat of raw.categories) {
|
|
10129
|
+
const where = `category "${cat?.id ?? "<unknown>"}"`;
|
|
10130
|
+
if (typeof cat.id !== "string" || cat.id.length === 0) {
|
|
10131
|
+
throw new Error("adapter category data: every category needs a non-empty id");
|
|
10132
|
+
}
|
|
10133
|
+
if (byId.has(cat.id)) {
|
|
10134
|
+
throw new Error(`adapter category data: duplicate category id "${cat.id}"`);
|
|
10135
|
+
}
|
|
10136
|
+
if (typeof cat.displayName !== "string" || cat.displayName.length === 0) {
|
|
10137
|
+
throw new Error(`adapter category data: ${where} needs a non-empty displayName`);
|
|
10138
|
+
}
|
|
10139
|
+
if (typeof cat.description !== "string" || cat.description.length === 0) {
|
|
10140
|
+
throw new Error(`adapter category data: ${where} needs a non-empty description`);
|
|
10141
|
+
}
|
|
10142
|
+
if (typeof cat.canonicalTable !== "string" || !/^ihs_alt_data_/.test(cat.canonicalTable)) {
|
|
10143
|
+
throw new Error(
|
|
10144
|
+
`adapter category data: ${where} canonicalTable must start with "ihs_alt_data_" (got "${cat.canonicalTable}")`
|
|
10145
|
+
);
|
|
10146
|
+
}
|
|
10147
|
+
if (tables.has(cat.canonicalTable)) {
|
|
10148
|
+
throw new Error(
|
|
10149
|
+
`adapter category data: duplicate canonicalTable "${cat.canonicalTable}" (${where})`
|
|
10150
|
+
);
|
|
10151
|
+
}
|
|
10152
|
+
if (!Array.isArray(cat.fields) || cat.fields.length === 0) {
|
|
10153
|
+
throw new Error(`adapter category data: ${where} must declare at least one field`);
|
|
10154
|
+
}
|
|
10155
|
+
const fields = [];
|
|
10156
|
+
for (const f of cat.fields) {
|
|
10157
|
+
if (typeof f.name !== "string" || f.name.length === 0) {
|
|
10158
|
+
throw new Error(`adapter category data: ${where} has a field with no name`);
|
|
10159
|
+
}
|
|
10160
|
+
if (fieldToCategory.has(f.name)) {
|
|
10161
|
+
throw new Error(
|
|
10162
|
+
`adapter category data: canonical field "${f.name}" declared by more than one category (${fieldToCategory.get(f.name)} + ${cat.id}) \u2014 field names must be globally unique`
|
|
10163
|
+
);
|
|
10164
|
+
}
|
|
10165
|
+
if (!VALID_FIELD_TYPES.includes(f.type)) {
|
|
10166
|
+
throw new Error(
|
|
10167
|
+
`adapter category data: field "${f.name}" (${where}) has invalid type "${f.type}"`
|
|
10168
|
+
);
|
|
10169
|
+
}
|
|
10170
|
+
if (typeof f.description !== "string" || f.description.length === 0) {
|
|
10171
|
+
throw new Error(
|
|
10172
|
+
`adapter category data: field "${f.name}" (${where}) needs a non-empty description`
|
|
10173
|
+
);
|
|
10174
|
+
}
|
|
10175
|
+
if (f.range !== void 0) {
|
|
10176
|
+
if (!Array.isArray(f.range) || f.range.length !== 2 || !Number.isFinite(f.range[0]) || !Number.isFinite(f.range[1]) || f.range[0] > f.range[1]) {
|
|
10177
|
+
throw new Error(
|
|
10178
|
+
`adapter category data: field "${f.name}" (${where}) has an invalid range \u2014 expected [lo, hi] with finite lo <= hi`
|
|
10179
|
+
);
|
|
10180
|
+
}
|
|
10181
|
+
}
|
|
10182
|
+
const spec = Object.freeze({
|
|
10183
|
+
name: f.name,
|
|
10184
|
+
type: f.type,
|
|
10185
|
+
...f.unit !== void 0 ? { unit: f.unit } : {},
|
|
10186
|
+
...f.range !== void 0 ? { range: Object.freeze([f.range[0], f.range[1]]) } : {},
|
|
10187
|
+
description: f.description
|
|
10188
|
+
});
|
|
10189
|
+
fields.push(spec);
|
|
10190
|
+
fieldToCategory.set(f.name, cat.id);
|
|
10191
|
+
}
|
|
10192
|
+
const schema = Object.freeze({
|
|
10193
|
+
id: cat.id,
|
|
10194
|
+
displayName: cat.displayName,
|
|
10195
|
+
description: cat.description,
|
|
10196
|
+
canonicalTable: cat.canonicalTable,
|
|
10197
|
+
fields: Object.freeze(fields)
|
|
10198
|
+
});
|
|
10199
|
+
byId.set(cat.id, schema);
|
|
10200
|
+
tables.add(cat.canonicalTable);
|
|
10201
|
+
all.push(schema);
|
|
10202
|
+
}
|
|
10203
|
+
return Object.freeze({
|
|
10204
|
+
all: Object.freeze(all),
|
|
10205
|
+
ids: Object.freeze(all.map((c) => c.id)),
|
|
10206
|
+
byId,
|
|
10207
|
+
fieldToCategory
|
|
10208
|
+
});
|
|
10209
|
+
}
|
|
10210
|
+
var registry = buildCategoryRegistry(adapter_categories_default);
|
|
10211
|
+
var ADAPTER_CATEGORY_IDS = registry.ids;
|
|
9970
10212
|
function categorySchemaOf(id) {
|
|
9971
|
-
const found =
|
|
10213
|
+
const found = registry.byId.get(id);
|
|
9972
10214
|
if (!found) {
|
|
9973
10215
|
throw new Error(
|
|
9974
|
-
`Unknown adapter category: ${id}. Available: ${
|
|
10216
|
+
`Unknown adapter category: ${id}. Available: ${registry.ids.join(", ")}`
|
|
9975
10217
|
);
|
|
9976
10218
|
}
|
|
9977
10219
|
return found;
|
|
@@ -9980,21 +10222,24 @@ function categoryFieldsOf(id) {
|
|
|
9980
10222
|
return categorySchemaOf(id).fields.map((f) => f.name);
|
|
9981
10223
|
}
|
|
9982
10224
|
function allCategories() {
|
|
9983
|
-
return
|
|
10225
|
+
return registry.all;
|
|
9984
10226
|
}
|
|
9985
|
-
var fieldToCategory = (() => {
|
|
9986
|
-
const m = /* @__PURE__ */ new Map();
|
|
9987
|
-
for (const cat of data.categories) {
|
|
9988
|
-
for (const f of cat.fields) {
|
|
9989
|
-
m.set(f.name, cat.id);
|
|
9990
|
-
}
|
|
9991
|
-
}
|
|
9992
|
-
return m;
|
|
9993
|
-
})();
|
|
9994
10227
|
function categoryForField(field) {
|
|
9995
|
-
return fieldToCategory.get(field) ?? null;
|
|
10228
|
+
return registry.fieldToCategory.get(field) ?? null;
|
|
10229
|
+
}
|
|
10230
|
+
function isAdapterCategory(id) {
|
|
10231
|
+
return registry.byId.has(id);
|
|
10232
|
+
}
|
|
10233
|
+
function assertAdapterCategory(id) {
|
|
10234
|
+
if (!registry.byId.has(id)) {
|
|
10235
|
+
throw new Error(
|
|
10236
|
+
`Unknown adapter category: ${id}. Available: ${registry.ids.join(", ")}`
|
|
10237
|
+
);
|
|
10238
|
+
}
|
|
10239
|
+
return id;
|
|
9996
10240
|
}
|
|
9997
10241
|
export {
|
|
10242
|
+
ADAPTER_CATEGORY_IDS,
|
|
9998
10243
|
ALL_AGGREGATION_OPS,
|
|
9999
10244
|
AdapterError,
|
|
10000
10245
|
BASE_FIELD_SPECS,
|
|
@@ -10020,6 +10265,7 @@ export {
|
|
|
10020
10265
|
allCategories,
|
|
10021
10266
|
applyAggregation,
|
|
10022
10267
|
applyDynamicTitles,
|
|
10268
|
+
assertAdapterCategory,
|
|
10023
10269
|
buildFileFieldTables,
|
|
10024
10270
|
categoryFieldsOf,
|
|
10025
10271
|
categoryForField,
|
|
@@ -10044,6 +10290,7 @@ export {
|
|
|
10044
10290
|
groupDetailsByCategory,
|
|
10045
10291
|
groupFieldsByCategory,
|
|
10046
10292
|
groupFieldsByPattern,
|
|
10293
|
+
isAdapterCategory,
|
|
10047
10294
|
isFailureIhsStatus,
|
|
10048
10295
|
isTerminalIhsStatus,
|
|
10049
10296
|
isValidIhsStatus,
|