@ifc-lite/ids 2.0.0 → 3.0.3
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/audit/coherence/index.js +3 -3
- package/dist/audit/coherence/regex.d.ts +2 -1
- package/dist/audit/coherence/regex.d.ts.map +1 -1
- package/dist/audit/coherence/regex.js +2 -1
- package/dist/audit/coherence/regex.js.map +1 -1
- package/dist/bridge/classifications.d.ts +24 -1
- package/dist/bridge/classifications.d.ts.map +1 -1
- package/dist/bridge/classifications.js +95 -22
- package/dist/bridge/classifications.js.map +1 -1
- package/dist/bridge/data-accessor.d.ts +14 -1
- package/dist/bridge/data-accessor.d.ts.map +1 -1
- package/dist/bridge/data-accessor.js +34 -9
- package/dist/bridge/data-accessor.js.map +1 -1
- package/dist/bridge/entity-visibility.d.ts +68 -0
- package/dist/bridge/entity-visibility.d.ts.map +1 -0
- package/dist/bridge/entity-visibility.js +161 -0
- package/dist/bridge/entity-visibility.js.map +1 -0
- package/dist/bridge/index.d.ts +1 -1
- package/dist/bridge/index.d.ts.map +1 -1
- package/dist/bridge/index.js.map +1 -1
- package/dist/bridge/materials.d.ts.map +1 -1
- package/dist/bridge/materials.js +10 -0
- package/dist/bridge/materials.js.map +1 -1
- package/dist/bridge/properties.d.ts.map +1 -1
- package/dist/bridge/properties.js +21 -12
- package/dist/bridge/properties.js.map +1 -1
- package/dist/bridge/property-overlay-resolver.d.ts.map +1 -1
- package/dist/bridge/property-overlay-resolver.js +10 -2
- package/dist/bridge/property-overlay-resolver.js.map +1 -1
- package/dist/constraints/describe.d.ts.map +1 -1
- package/dist/constraints/describe.js +2 -4
- package/dist/constraints/describe.js.map +1 -1
- package/dist/constraints/digit-facets.d.ts +19 -21
- package/dist/constraints/digit-facets.d.ts.map +1 -1
- package/dist/constraints/digit-facets.js +42 -55
- package/dist/constraints/digit-facets.js.map +1 -1
- package/dist/constraints/match-family.js +16 -7
- package/dist/constraints/match-family.js.map +1 -1
- package/dist/constraints/xsd-regex.d.ts +11 -1
- package/dist/constraints/xsd-regex.d.ts.map +1 -1
- package/dist/constraints/xsd-regex.js +65 -4
- package/dist/constraints/xsd-regex.js.map +1 -1
- package/dist/facets/material-facet.d.ts.map +1 -1
- package/dist/facets/material-facet.js +39 -4
- package/dist/facets/material-facet.js.map +1 -1
- package/dist/facets/property-datatype.d.ts +21 -0
- package/dist/facets/property-datatype.d.ts.map +1 -0
- package/dist/facets/property-datatype.js +33 -0
- package/dist/facets/property-datatype.js.map +1 -0
- package/dist/facets/property-facet.d.ts.map +1 -1
- package/dist/facets/property-facet.js +6 -26
- package/dist/facets/property-facet.js.map +1 -1
- package/dist/facets/test-helpers.d.ts +3 -0
- package/dist/facets/test-helpers.d.ts.map +1 -1
- package/dist/facets/test-helpers.js +3 -2
- package/dist/facets/test-helpers.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/translation/locales/de.d.ts +2 -0
- package/dist/translation/locales/de.d.ts.map +1 -1
- package/dist/translation/locales/de.js +2 -0
- package/dist/translation/locales/de.js.map +1 -1
- package/dist/translation/locales/en.d.ts +2 -0
- package/dist/translation/locales/en.d.ts.map +1 -1
- package/dist/translation/locales/en.js +2 -0
- package/dist/translation/locales/en.js.map +1 -1
- package/dist/translation/locales/fr.d.ts +2 -0
- package/dist/translation/locales/fr.d.ts.map +1 -1
- package/dist/translation/locales/fr.js +2 -0
- package/dist/translation/locales/fr.js.map +1 -1
- package/dist/translation/service.d.ts.map +1 -1
- package/dist/translation/service.js +4 -0
- package/dist/translation/service.js.map +1 -1
- package/dist/types.d.ts +10 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/validation/format-failure-reason.d.ts.map +1 -1
- package/dist/validation/format-failure-reason.js +4 -0
- package/dist/validation/format-failure-reason.js.map +1 -1
- package/dist/validation/validator.d.ts.map +1 -1
- package/dist/validation/validator.js +33 -4
- package/dist/validation/validator.js.map +1 -1
- package/package.json +4 -4
|
@@ -3,61 +3,50 @@
|
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
import { isStrictNumericLiteral } from './comparators.js';
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* `
|
|
6
|
+
* Count decimal digits per XSD §4.3.11/§4.3.12 facet semantics, over any
|
|
7
|
+
* strict numeric literal (`isStrictNumericLiteral`), exponent included.
|
|
8
|
+
* Write the value as `0.D × 10^p`, where `D` has no leading or trailing
|
|
9
|
+
* zeros and `L` digits:
|
|
10
|
+
*
|
|
11
|
+
* - `fractionDigits` is `n` in value = i × 10⁻ⁿ: the digits after the
|
|
12
|
+
* decimal point, `max(0, L - p)`. Leading fraction zeros count
|
|
13
|
+
* (`0.0025` → 4); trailing zeros do not (`1.4500` → 2).
|
|
14
|
+
* - `totalDigits` is the digit count of `i`. Leading zeros are absorbed
|
|
15
|
+
* into the scale and never count (`0.0025 = 25 × 10⁻⁴` → 2), trailing
|
|
16
|
+
* fraction zeros are dropped, and trailing INTEGER zeros stay
|
|
17
|
+
* significant (`1000` → 4): `max(L, p)`.
|
|
18
|
+
*
|
|
19
|
+
* The exponent is applied arithmetically on the lexical digits (#5186), so
|
|
20
|
+
* `"1.5e3"` counts as 1500 (4, 0) without going through a double or
|
|
21
|
+
* materialising the expanded string. The count is exact for any number of
|
|
22
|
+
* significant digits and any exponent (BigInt), and a literal like
|
|
23
|
+
* `"1e999999"` costs nothing. A `number` is counted from
|
|
24
|
+
* `String(num)`, which may itself be exponential (`1e-7`).
|
|
10
25
|
*/
|
|
11
|
-
export function
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const neg = mantissa.startsWith('-');
|
|
18
|
-
const m = neg ? mantissa.slice(1) : mantissa;
|
|
19
|
-
const [intPart, fracPart = ''] = m.split('.');
|
|
26
|
+
export function countDecimalDigits(literal) {
|
|
27
|
+
const [mantissaRaw, expRaw] = literal.split(/[eE]/);
|
|
28
|
+
const mantissa = mantissaRaw.replace(/^[+-]/, '');
|
|
29
|
+
// BigInt: an exponent past 2^53 would otherwise round (review on #5280).
|
|
30
|
+
const exp = expRaw === undefined ? 0n : BigInt(expRaw);
|
|
31
|
+
const [intPart, fracPart = ''] = mantissa.split('.');
|
|
20
32
|
const digits = intPart + fracPart;
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
return neg ? `-${out}` : out;
|
|
33
|
+
const lead = digits.length - digits.replace(/^0+/, '').length;
|
|
34
|
+
const significant = digits.slice(lead).replace(/0+$/, '');
|
|
35
|
+
// Zero in any spelling (`0`, `0.000`, `0e5`): one digit, no fraction.
|
|
36
|
+
if (significant.length === 0)
|
|
37
|
+
return { total: 1, fraction: 0 };
|
|
38
|
+
const L = BigInt(significant.length);
|
|
39
|
+
const p = BigInt(intPart.length - lead) + exp;
|
|
40
|
+
return {
|
|
41
|
+
total: toCount(L > p ? L : p),
|
|
42
|
+
fraction: toCount(L - p > 0n ? L - p : 0n),
|
|
43
|
+
};
|
|
33
44
|
}
|
|
34
|
-
/**
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
* after the decimal point, full stop. Leading zeros in the fraction
|
|
40
|
-
* DO count (`0.0025` → 4) since they fix the magnitude (`10⁻ⁿ`);
|
|
41
|
-
* only trailing zeros are insignificant (`1.4500` → 2).
|
|
42
|
-
* - `totalDigits` is the digit count of `i` in that same value = i ×
|
|
43
|
-
* 10⁻ⁿ. Leading zeros — in the integer part AND in the fraction
|
|
44
|
-
* before the first non-zero digit — are absorbed into the `10⁻ⁿ`
|
|
45
|
-
* scale factor and do NOT count (`0.0025 = 25 × 10⁻⁴` → 2, not 4).
|
|
46
|
-
* Trailing zeros in the fraction are still dropped (`0.250` → `25`
|
|
47
|
-
* → 2). Trailing zeros in the INTEGER part stay significant per the
|
|
48
|
-
* digit-count reading (`1000` → 4): only leading zeros are stripped.
|
|
49
|
-
*/
|
|
50
|
-
export function countDecimalDigits(decimalStr) {
|
|
51
|
-
const unsigned = decimalStr.replace(/^[+-]/, '');
|
|
52
|
-
const [intPartRaw, fracPartRaw = ''] = unsigned.split('.');
|
|
53
|
-
const fracTrimmed = fracPartRaw.replace(/0+$/, '');
|
|
54
|
-
const fraction = fracTrimmed.length;
|
|
55
|
-
// totalDigits: strip every leading zero — integer-part zeros AND any
|
|
56
|
-
// fraction zeros before the first significant digit — then count
|
|
57
|
-
// what's left of the (trailing-trimmed) digit string.
|
|
58
|
-
const totalTrimmed = (intPartRaw + fracTrimmed).replace(/^0+/, '');
|
|
59
|
-
const total = totalTrimmed.length === 0 ? 1 : totalTrimmed.length;
|
|
60
|
-
return { total, fraction };
|
|
45
|
+
/** A count past `Number.MAX_SAFE_INTEGER` cannot be compared exactly with a
|
|
46
|
+
* facet value (itself a JS number), and exceeds any facet a document can
|
|
47
|
+
* state exactly, so it reads as `Infinity`: over every bound. */
|
|
48
|
+
function toCount(n) {
|
|
49
|
+
return n > BigInt(Number.MAX_SAFE_INTEGER) ? Infinity : Number(n);
|
|
61
50
|
}
|
|
62
51
|
/**
|
|
63
52
|
* Whether `actualValue` satisfies a bounds constraint's
|
|
@@ -70,9 +59,7 @@ export function matchDigitFacets(constraint, actualValue) {
|
|
|
70
59
|
if (constraint.totalDigits === undefined && constraint.fractionDigits === undefined) {
|
|
71
60
|
return undefined;
|
|
72
61
|
}
|
|
73
|
-
const decimalStr =
|
|
74
|
-
? toFixedDecimalString(actualValue)
|
|
75
|
-
: String(actualValue);
|
|
62
|
+
const decimalStr = String(actualValue);
|
|
76
63
|
// The digit facets are only meaningful against a decimal lexical
|
|
77
64
|
// form; a non-numeric string actual can never satisfy them.
|
|
78
65
|
if (!isStrictNumericLiteral(decimalStr))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"digit-facets.js","sourceRoot":"","sources":["../../src/constraints/digit-facets.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAU/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D
|
|
1
|
+
{"version":3,"file":"digit-facets.js","sourceRoot":"","sources":["../../src/constraints/digit-facets.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAU/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAIhD,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAClD,yEAAyE;IACzE,MAAM,GAAG,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvD,MAAM,CAAC,OAAO,EAAE,QAAQ,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IAElC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC;IAC9D,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC1D,sEAAsE;IACtE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC;IAE/D,MAAM,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IACrC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;IAC9C,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,QAAQ,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED;;kEAEkE;AAClE,SAAS,OAAO,CAAC,CAAS;IACxB,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAC9B,UAAuE,EACvE,WAAsC;IAEtC,IAAI,UAAU,CAAC,WAAW,KAAK,SAAS,IAAI,UAAU,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;QACpF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,iEAAiE;IACjE,4DAA4D;IAC5D,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC;QAAE,OAAO,KAAK,CAAC;IACtD,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAC3D,IAAI,UAAU,CAAC,WAAW,KAAK,SAAS,IAAI,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QAC3E,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,UAAU,CAAC,cAAc,KAAK,SAAS,IAAI,QAAQ,GAAG,UAAU,CAAC,cAAc,EAAE,CAAC;QACpF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
import { compareBoolean, compareNumeric, compareString, isStrictNumericLiteral, isBooleanLiteral, } from './comparators.js';
|
|
5
5
|
import { isNumericXsdBase, isBooleanXsdBase } from './xsd-cast.js';
|
|
6
|
-
import { translateXsdRegex } from './xsd-regex.js';
|
|
6
|
+
import { translateXsdRegex, SUBTRACTION_UNSUPPORTED_REASON } from './xsd-regex.js';
|
|
7
7
|
import { matchDigitFacets } from './digit-facets.js';
|
|
8
|
-
import { assertGuardedRegexPattern } from '@ifc-lite/regex-guard';
|
|
8
|
+
import { assertGuardedRegexPattern, UnsafeRegexPatternError } from '@ifc-lite/regex-guard';
|
|
9
9
|
/** Tolerance for the bounds matcher's exclusive comparators. */
|
|
10
10
|
export const NUMERIC_TOLERANCE = 1e-6;
|
|
11
11
|
/**
|
|
@@ -136,14 +136,23 @@ function buildPatternRegex(xsdPattern, caseInsensitive) {
|
|
|
136
136
|
// `validateSpecification`, which turns the thrown error into a
|
|
137
137
|
// failed specification result.
|
|
138
138
|
assertGuardedRegexPattern(xsdPattern);
|
|
139
|
-
// XSD char-class subtraction `[a-z-[aeiou]]` has no JS equivalent;
|
|
140
|
-
// approximate as the positive class (drop the exclusion) so the rest
|
|
141
|
-
// of the pattern still evaluates, matching long-standing behaviour.
|
|
142
|
-
const desubtracted = xsdPattern.replace(/\[([^\]]+)-\[[^\]]+\]\]/g, '[$1]');
|
|
143
139
|
// Shared XSD → JS translation: `\i`/`\c`/`\d`/`\w` (and their
|
|
144
140
|
// negations) map to Unicode property escapes, and verbatim `\p{…}`
|
|
145
141
|
// classes pass through — both require the `u` flag for full fidelity.
|
|
146
|
-
|
|
142
|
+
// XSD character-class subtraction (`[a-z-[aeiou]]`) is translated
|
|
143
|
+
// exactly (a negative lookahead, see `translateSubtraction`). One that
|
|
144
|
+
// cannot be delimited is refused rather than approximated: dropping the
|
|
145
|
+
// exclusion would make the pattern accept exactly the values it was
|
|
146
|
+
// written to exclude (#5183). `UnsafeRegexPatternError` becomes a failed
|
|
147
|
+
// specification result in `validateSpecification`, never a silent pass.
|
|
148
|
+
// Other unsupported constructs (an unrepresentable `\p{…}` block escape,
|
|
149
|
+
// a negated class escape inside `[ … ]`) keep their permissive
|
|
150
|
+
// any-character placeholder: they over-match rather than invert intent,
|
|
151
|
+
// and the coherence auditor flags them.
|
|
152
|
+
const { pattern, supported, reason } = translateXsdRegex(xsdPattern);
|
|
153
|
+
if (!supported && reason === SUBTRACTION_UNSUPPORTED_REASON) {
|
|
154
|
+
throw new UnsafeRegexPatternError(xsdPattern, reason);
|
|
155
|
+
}
|
|
147
156
|
// IDS patterns must match the entire lexical value. Wrapping in a
|
|
148
157
|
// non-capturing group anchors top-level alternation correctly
|
|
149
158
|
// (`a|b` → `^(?:a|b)$`, not `^a|b$`). Case-insensitive matching is
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"match-family.js","sourceRoot":"","sources":["../../src/constraints/match-family.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAmB/D,OAAO,EACL,cAAc,EACd,cAAc,EACd,aAAa,EACb,sBAAsB,EACtB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"match-family.js","sourceRoot":"","sources":["../../src/constraints/match-family.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
* - `\D`, `\C`, `\I`, `\W` — negations
|
|
17
17
|
* - `\p{IsBasicLatin}`-style Unicode *block* escapes — .NET supports
|
|
18
18
|
* these but JS does not, so they are approximated.
|
|
19
|
-
* - char-class subtraction `[a-z-[aeiou]]` — no JS
|
|
19
|
+
* - char-class subtraction `[a-z-[aeiou]]` — no JS class syntax under
|
|
20
|
+
* `u`, translated exactly to a negative lookahead (`translateSubtraction`).
|
|
20
21
|
*
|
|
21
22
|
* The translation maps to JS Unicode property escapes, so the compiled
|
|
22
23
|
* `RegExp` MUST use the `u` flag. Verbatim `\p{…}` / `\P{…}` *category*
|
|
@@ -42,6 +43,15 @@ export interface TranslateResult {
|
|
|
42
43
|
*/
|
|
43
44
|
reason: string;
|
|
44
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* `TranslateResult.reason` when the pattern uses XSD character-class
|
|
48
|
+
* subtraction (`[a-z-[aeiou]]`). Exported so a caller that needs to
|
|
49
|
+
* distinguish this specific construct — rather than "some construct is
|
|
50
|
+
* unsupported" in general — doesn't have to duplicate the message
|
|
51
|
+
* string (see `matchPattern`'s fail-closed check, which refuses only
|
|
52
|
+
* a subtraction pattern rather than every approximated construct).
|
|
53
|
+
*/
|
|
54
|
+
export declare const SUBTRACTION_UNSUPPORTED_REASON = "XSD character-class subtraction is not supported in JS regex";
|
|
45
55
|
/**
|
|
46
56
|
* Translate the XSD pattern. Returns the JS-compatible pattern plus a
|
|
47
57
|
* `supported` flag — when `false`, callers should warn / treat the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xsd-regex.d.ts","sourceRoot":"","sources":["../../src/constraints/xsd-regex.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"xsd-regex.d.ts","sourceRoot":"","sources":["../../src/constraints/xsd-regex.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,MAAM,WAAW,eAAe;IAC9B,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAMD;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,iEACqB,CAAC;AAEjE;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAmFlE"}
|
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
/** Any single character — placeholder for untranslatable constructs. */
|
|
5
5
|
const ANY_OUTSIDE_CLASS = '[\\s\\S]';
|
|
6
6
|
const ANY_INSIDE_CLASS = '\\s\\S';
|
|
7
|
+
/**
|
|
8
|
+
* `TranslateResult.reason` when the pattern uses XSD character-class
|
|
9
|
+
* subtraction (`[a-z-[aeiou]]`). Exported so a caller that needs to
|
|
10
|
+
* distinguish this specific construct — rather than "some construct is
|
|
11
|
+
* unsupported" in general — doesn't have to duplicate the message
|
|
12
|
+
* string (see `matchPattern`'s fail-closed check, which refuses only
|
|
13
|
+
* a subtraction pattern rather than every approximated construct).
|
|
14
|
+
*/
|
|
15
|
+
export const SUBTRACTION_UNSUPPORTED_REASON = 'XSD character-class subtraction is not supported in JS regex';
|
|
7
16
|
/**
|
|
8
17
|
* Translate the XSD pattern. Returns the JS-compatible pattern plus a
|
|
9
18
|
* `supported` flag — when `false`, callers should warn / treat the
|
|
@@ -14,8 +23,11 @@ export function translateXsdRegex(pattern) {
|
|
|
14
23
|
let i = 0;
|
|
15
24
|
let inClass = false;
|
|
16
25
|
let reason = '';
|
|
26
|
+
// The first reason wins, except that an undelimitable subtraction always
|
|
27
|
+
// does: callers fail closed on exactly that reason, so an earlier
|
|
28
|
+
// approximated construct must not hide it (review on #5286).
|
|
17
29
|
const flag = (r) => {
|
|
18
|
-
if (!reason)
|
|
30
|
+
if (!reason || r === SUBTRACTION_UNSUPPORTED_REASON)
|
|
19
31
|
reason = r;
|
|
20
32
|
};
|
|
21
33
|
while (i < pattern.length) {
|
|
@@ -57,9 +69,20 @@ export function translateXsdRegex(pattern) {
|
|
|
57
69
|
continue;
|
|
58
70
|
}
|
|
59
71
|
if (ch === '[' && !inClass) {
|
|
60
|
-
|
|
61
|
-
if (
|
|
62
|
-
|
|
72
|
+
const span = scanClass(pattern, i);
|
|
73
|
+
if (span?.subtract) {
|
|
74
|
+
// XSD char-class subtraction `[base-[excluded]]` (#5183).
|
|
75
|
+
const sub = translateSubtraction(pattern, span);
|
|
76
|
+
if (sub.reason)
|
|
77
|
+
flag(sub.reason);
|
|
78
|
+
out += sub.pattern;
|
|
79
|
+
i = span.end;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (span === undefined && /^\[[^\]]*-\[/.test(pattern.slice(i))) {
|
|
83
|
+
// A subtraction we cannot delimit (unterminated): refuse it rather
|
|
84
|
+
// than guess which characters it excludes.
|
|
85
|
+
flag(SUBTRACTION_UNSUPPORTED_REASON);
|
|
63
86
|
}
|
|
64
87
|
inClass = true;
|
|
65
88
|
out += ch;
|
|
@@ -77,6 +100,44 @@ export function translateXsdRegex(pattern) {
|
|
|
77
100
|
}
|
|
78
101
|
return { pattern: out, supported: reason === '', reason };
|
|
79
102
|
}
|
|
103
|
+
function scanClass(pattern, start) {
|
|
104
|
+
let j = start + 1;
|
|
105
|
+
while (j < pattern.length) {
|
|
106
|
+
const c = pattern.charAt(j);
|
|
107
|
+
if (c === '\\') {
|
|
108
|
+
const prop = /^\\[pP]\{[^}]*\}/.exec(pattern.slice(j));
|
|
109
|
+
j += prop ? prop[0].length : 2;
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (c === '-' && pattern.charAt(j + 1) === '[') {
|
|
113
|
+
const subtract = scanClass(pattern, j + 1);
|
|
114
|
+
if (!subtract || pattern.charAt(subtract.end) !== ']')
|
|
115
|
+
return undefined;
|
|
116
|
+
return { start, baseEnd: j, subtract, end: subtract.end + 1 };
|
|
117
|
+
}
|
|
118
|
+
if (c === ']')
|
|
119
|
+
return { start, baseEnd: j, end: j + 1 };
|
|
120
|
+
j++;
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* `[base-[excluded]]` matches one character that is in `base` and not in
|
|
126
|
+
* `excluded`. JS under the `u` flag has no class subtraction, but the same
|
|
127
|
+
* single-character set is `(?:(?!excluded)base)`: the negative lookahead
|
|
128
|
+
* refuses an excluded character and the base class then consumes one. This
|
|
129
|
+
* is exact, not an approximation, and it nests for `[a-z-[b-y-[c]]]`.
|
|
130
|
+
*/
|
|
131
|
+
function translateSubtraction(pattern, span) {
|
|
132
|
+
const base = translateXsdRegex(`${pattern.slice(span.start, span.baseEnd)}]`);
|
|
133
|
+
const excluded = span.subtract.subtract
|
|
134
|
+
? translateSubtraction(pattern, span.subtract)
|
|
135
|
+
: translateXsdRegex(pattern.slice(span.subtract.start, span.subtract.end));
|
|
136
|
+
return {
|
|
137
|
+
pattern: `(?:(?!${excluded.pattern})${base.pattern})`,
|
|
138
|
+
reason: base.reason || excluded.reason,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
80
141
|
/** Sentinel: escape has no faithful form inside a `[ … ]` character class. */
|
|
81
142
|
const UNSUPPORTED_IN_CLASS = '\0unsupported-in-class';
|
|
82
143
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xsd-regex.js","sourceRoot":"","sources":["../../src/constraints/xsd-regex.ts"],"names":[],"mappings":"AAAA;;+DAE+D;
|
|
1
|
+
{"version":3,"file":"xsd-regex.js","sourceRoot":"","sources":["../../src/constraints/xsd-regex.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material-facet.d.ts","sourceRoot":"","sources":["../../src/facets/material-facet.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GACxB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"material-facet.d.ts","sourceRoot":"","sources":["../../src/facets/material-facet.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GACxB,gBAAgB,CAmFlB"}
|
|
@@ -8,6 +8,13 @@ import { matchConstraint, formatConstraint } from '../constraints/index.js';
|
|
|
8
8
|
export function checkMaterialFacet(facet, expressId, accessor) {
|
|
9
9
|
// Get materials for the entity
|
|
10
10
|
const materials = accessor.getMaterials(expressId);
|
|
11
|
+
// An `unresolved` entry (#5227) is a real IfcRelAssociatesMaterial edge
|
|
12
|
+
// whose material this store cannot read (server-parsed, no source
|
|
13
|
+
// bytes). It PROVES the entity has a material, so it satisfies a
|
|
14
|
+
// presence-only facet, but it can neither match nor fail a value. This is
|
|
15
|
+
// the same contract as the classification facet's `unresolved` (#3948).
|
|
16
|
+
const resolvedMaterials = materials.filter((m) => !m.unresolved);
|
|
17
|
+
const hasUnresolved = resolvedMaterials.length < materials.length;
|
|
11
18
|
// If no value constraint, just check if any material exists
|
|
12
19
|
if (!facet.value) {
|
|
13
20
|
if (materials.length === 0) {
|
|
@@ -23,12 +30,12 @@ export function checkMaterialFacet(facet, expressId, accessor) {
|
|
|
23
30
|
}
|
|
24
31
|
return {
|
|
25
32
|
passed: true,
|
|
26
|
-
actualValue: materials.map((m) => m.name).join(', '),
|
|
33
|
+
actualValue: materials.map((m) => (m.unresolved ? '(unresolved)' : m.name)).join(', '),
|
|
27
34
|
expectedValue: 'any material',
|
|
28
35
|
};
|
|
29
36
|
}
|
|
30
|
-
// Check if any material matches the value constraint
|
|
31
|
-
const matchingMaterials =
|
|
37
|
+
// Check if any readable material matches the value constraint
|
|
38
|
+
const matchingMaterials = resolvedMaterials.filter((m) => matchConstraint(facet.value, m.name) ||
|
|
32
39
|
(m.category && matchConstraint(facet.value, m.category)));
|
|
33
40
|
if (matchingMaterials.length === 0) {
|
|
34
41
|
if (materials.length === 0) {
|
|
@@ -42,7 +49,13 @@ export function checkMaterialFacet(facet, expressId, accessor) {
|
|
|
42
49
|
},
|
|
43
50
|
};
|
|
44
51
|
}
|
|
45
|
-
|
|
52
|
+
// An unreadable material might be the one that matches: we cannot say
|
|
53
|
+
// it doesn't, so this is not a MISMATCH. The validator fails it even
|
|
54
|
+
// under a prohibition, so "cannot verify" is never a pass.
|
|
55
|
+
if (hasUnresolved) {
|
|
56
|
+
return unresolvedResult(facet);
|
|
57
|
+
}
|
|
58
|
+
const availableMaterials = resolvedMaterials.map((m) => m.name).join(', ');
|
|
46
59
|
return {
|
|
47
60
|
passed: false,
|
|
48
61
|
actualValue: availableMaterials,
|
|
@@ -64,4 +77,26 @@ export function checkMaterialFacet(facet, expressId, accessor) {
|
|
|
64
77
|
expectedValue: formatConstraint(facet.value),
|
|
65
78
|
};
|
|
66
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Result for a value-constrained facet when the entity has a material this
|
|
82
|
+
* data source cannot read, and no readable material matched. `passed:
|
|
83
|
+
* false` is the closest the boolean result gets to "could not determine";
|
|
84
|
+
* `failure.type` `MATERIAL_UNRESOLVED` (never `_MISSING`/`_MISMATCH`) is
|
|
85
|
+
* what tells a report "cannot verify" apart from a genuine violation.
|
|
86
|
+
*/
|
|
87
|
+
function unresolvedResult(facet) {
|
|
88
|
+
const expected = formatConstraint(facet.value);
|
|
89
|
+
return {
|
|
90
|
+
passed: false,
|
|
91
|
+
actualValue: '(unresolved)',
|
|
92
|
+
expectedValue: expected,
|
|
93
|
+
failure: {
|
|
94
|
+
type: 'MATERIAL_UNRESOLVED',
|
|
95
|
+
expected,
|
|
96
|
+
context: {
|
|
97
|
+
reason: 'Entity has a material association, but the material attributes are unavailable on this data source (server-parsed model without source bytes).',
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
}
|
|
67
102
|
//# sourceMappingURL=material-facet.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"material-facet.js","sourceRoot":"","sources":["../../src/facets/material-facet.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAQ/D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE5E;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAAuB,EACvB,SAAiB,EACjB,QAAyB;IAEzB,+BAA+B;IAC/B,MAAM,SAAS,GAAG,QAAQ,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IAEnD,4DAA4D;IAC5D,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACjB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO;gBACL,MAAM,EAAE,KAAK;gBACb,WAAW,EAAE,QAAQ;gBACrB,aAAa,EAAE,cAAc;gBAC7B,OAAO,EAAE;oBACP,IAAI,EAAE,kBAAkB;oBACxB,QAAQ,EAAE,cAAc;iBACzB;aACF,CAAC;QACJ,CAAC;QAED,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"material-facet.js","sourceRoot":"","sources":["../../src/facets/material-facet.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The property facet's `dataType` gate, shared by `checkPropertyFacet` and
|
|
3
|
+
* its diagnostics-free twin `propertyFacetPasses` so that the two cannot
|
|
4
|
+
* drift (#5224: they used to carry the same skip-on-absence condition).
|
|
5
|
+
*
|
|
6
|
+
* A property whose dataType is not known FAILS a dataType-constrained facet.
|
|
7
|
+
* If the type cannot be established, the requirement cannot be asserted as
|
|
8
|
+
* met. The one exemption is explicit: an `IfcPropertyTableValue` carries
|
|
9
|
+
* `dataTypeMixed`, because its columns differ in type by design. It defers
|
|
10
|
+
* to the value match against its candidates, as upstream ifctester does.
|
|
11
|
+
*/
|
|
12
|
+
import type { IDSConstraint, PropertySetInfo } from '../types.js';
|
|
13
|
+
import type { FacetCheckResult } from './index.js';
|
|
14
|
+
type Prop = PropertySetInfo['properties'][number];
|
|
15
|
+
/** Whether `prop` satisfies the facet's `dataType` constraint. */
|
|
16
|
+
export declare function dataTypePasses(expected: IDSConstraint, prop: Prop): boolean;
|
|
17
|
+
/** The failure `checkSingleProperty` reports when {@link dataTypePasses} is
|
|
18
|
+
* false: MISMATCH when the type is known, UNKNOWN when it is not. */
|
|
19
|
+
export declare function dataTypeFailure(expected: IDSConstraint, psetName: string, prop: Prop): FacetCheckResult;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=property-datatype.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"property-datatype.d.ts","sourceRoot":"","sources":["../../src/facets/property-datatype.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAMnD,KAAK,IAAI,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAElD,kEAAkE;AAClE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI,GAAG,OAAO,CAG3E;AAED;sEACsE;AACtE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,GAAG,gBAAgB,CAiBvG"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { matchConstraint, formatConstraint } from '../constraints/index.js';
|
|
5
|
+
/** IFC data type names (IFCLABEL, IFCREAL, etc.) are case-insensitive */
|
|
6
|
+
const DATATYPE_OPTS = { caseInsensitive: true };
|
|
7
|
+
/** Whether `prop` satisfies the facet's `dataType` constraint. */
|
|
8
|
+
export function dataTypePasses(expected, prop) {
|
|
9
|
+
if (prop.dataTypeMixed)
|
|
10
|
+
return true;
|
|
11
|
+
return !!prop.dataType && matchConstraint(expected, prop.dataType, DATATYPE_OPTS);
|
|
12
|
+
}
|
|
13
|
+
/** The failure `checkSingleProperty` reports when {@link dataTypePasses} is
|
|
14
|
+
* false: MISMATCH when the type is known, UNKNOWN when it is not. */
|
|
15
|
+
export function dataTypeFailure(expected, psetName, prop) {
|
|
16
|
+
const field = `${psetName}.${prop.name}`;
|
|
17
|
+
const expectedText = formatConstraint(expected);
|
|
18
|
+
if (!prop.dataType) {
|
|
19
|
+
return {
|
|
20
|
+
passed: false,
|
|
21
|
+
actualValue: `${field} (dataType unknown)`,
|
|
22
|
+
expectedValue: `dataType ${expectedText}`,
|
|
23
|
+
failure: { type: 'PROPERTY_DATATYPE_UNKNOWN', field, expected: expectedText },
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
passed: false,
|
|
28
|
+
actualValue: `${field} (${prop.dataType})`,
|
|
29
|
+
expectedValue: `dataType ${expectedText}`,
|
|
30
|
+
failure: { type: 'PROPERTY_DATATYPE_MISMATCH', field, actual: prop.dataType, expected: expectedText },
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=property-datatype.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"property-datatype.js","sourceRoot":"","sources":["../../src/facets/property-datatype.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAgB/D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAqB,MAAM,yBAAyB,CAAC;AAE/F,yEAAyE;AACzE,MAAM,aAAa,GAAiB,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;AAI9D,kEAAkE;AAClE,MAAM,UAAU,cAAc,CAAC,QAAuB,EAAE,IAAU;IAChE,IAAI,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IACpC,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;AACpF,CAAC;AAED;sEACsE;AACtE,MAAM,UAAU,eAAe,CAAC,QAAuB,EAAE,QAAgB,EAAE,IAAU;IACnF,MAAM,KAAK,GAAG,GAAG,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,YAAY,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAChD,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACnB,OAAO;YACL,MAAM,EAAE,KAAK;YACb,WAAW,EAAE,GAAG,KAAK,qBAAqB;YAC1C,aAAa,EAAE,YAAY,YAAY,EAAE;YACzC,OAAO,EAAE,EAAE,IAAI,EAAE,2BAA2B,EAAE,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE;SAC9E,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM,EAAE,KAAK;QACb,WAAW,EAAE,GAAG,KAAK,KAAK,IAAI,CAAC,QAAQ,GAAG;QAC1C,aAAa,EAAE,YAAY,YAAY,EAAE;QACzC,OAAO,EAAE,EAAE,IAAI,EAAE,4BAA4B,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,EAAE;KACtG,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"property-facet.d.ts","sourceRoot":"","sources":["../../src/facets/property-facet.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAEhB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"property-facet.d.ts","sourceRoot":"","sources":["../../src/facets/property-facet.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EAEhB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAmGnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GACxB,OAAO,CAqBT;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,gBAAgB,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,eAAe,GACxB,gBAAgB,CAmGlB"}
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
4
|
import { matchConstraint, formatConstraint } from '../constraints/index.js';
|
|
5
5
|
import { ifcMeasureToXsdTypes, literalCastsUnderAnyType } from '../constraints/xsd-cast.js';
|
|
6
|
-
|
|
7
|
-
const DATATYPE_OPTS = { caseInsensitive: true };
|
|
6
|
+
import { dataTypeFailure, dataTypePasses } from './property-datatype.js';
|
|
8
7
|
/**
|
|
9
8
|
* Failure-detail string caches. During applicability filtering every
|
|
10
9
|
* non-matching entity takes a failure path, and these name lists were
|
|
@@ -70,11 +69,8 @@ function singlePropertyPasses(facet, prop, schemaVersion) {
|
|
|
70
69
|
if (prop.value === null || prop.value === undefined || prop.value === '') {
|
|
71
70
|
return false;
|
|
72
71
|
}
|
|
73
|
-
if (facet.dataType &&
|
|
74
|
-
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
72
|
+
if (facet.dataType && !dataTypePasses(facet.dataType, prop))
|
|
73
|
+
return false;
|
|
78
74
|
if (facet.value) {
|
|
79
75
|
if (facet.value.type === 'simpleValue') {
|
|
80
76
|
if (!passesCastGate(facet.value, prop.dataType, schemaVersion))
|
|
@@ -288,25 +284,9 @@ function checkSingleProperty(facet, pset, prop, schemaVersion) {
|
|
|
288
284
|
},
|
|
289
285
|
};
|
|
290
286
|
}
|
|
291
|
-
// Check data type if specified
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
// omit a single representative type so the value match against the
|
|
295
|
-
// expanded `values[]` array can still satisfy the requirement.
|
|
296
|
-
if (facet.dataType && prop.dataType) {
|
|
297
|
-
if (!matchConstraint(facet.dataType, prop.dataType, DATATYPE_OPTS)) {
|
|
298
|
-
return {
|
|
299
|
-
passed: false,
|
|
300
|
-
actualValue: `${pset.name}.${prop.name} (${prop.dataType})`,
|
|
301
|
-
expectedValue: `dataType ${formatConstraint(facet.dataType)}`,
|
|
302
|
-
failure: {
|
|
303
|
-
type: 'PROPERTY_DATATYPE_MISMATCH',
|
|
304
|
-
field: `${pset.name}.${prop.name}`,
|
|
305
|
-
actual: prop.dataType,
|
|
306
|
-
expected: formatConstraint(facet.dataType),
|
|
307
|
-
},
|
|
308
|
-
};
|
|
309
|
-
}
|
|
287
|
+
// Check data type if specified; an unknown type fails (#5224).
|
|
288
|
+
if (facet.dataType && !dataTypePasses(facet.dataType, prop)) {
|
|
289
|
+
return dataTypeFailure(facet.dataType, pset.name, prop);
|
|
310
290
|
}
|
|
311
291
|
// Check value if specified
|
|
312
292
|
if (facet.value) {
|