@ifc-lite/rules 0.2.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/LICENSE +373 -0
- package/README.md +45 -0
- package/dist/engine/rule-engine-chunk.d.ts +25 -0
- package/dist/engine/rule-engine-chunk.d.ts.map +1 -0
- package/dist/engine/rule-engine-chunk.js +43 -0
- package/dist/engine/rule-engine-chunk.js.map +1 -0
- package/dist/engine/rule-engine-compare.d.ts +17 -0
- package/dist/engine/rule-engine-compare.d.ts.map +1 -0
- package/dist/engine/rule-engine-compare.js +69 -0
- package/dist/engine/rule-engine-compare.js.map +1 -0
- package/dist/engine/rule-engine-requirements.d.ts +37 -0
- package/dist/engine/rule-engine-requirements.d.ts.map +1 -0
- package/dist/engine/rule-engine-requirements.js +293 -0
- package/dist/engine/rule-engine-requirements.js.map +1 -0
- package/dist/engine/rule-engine-sets.d.ts +46 -0
- package/dist/engine/rule-engine-sets.d.ts.map +1 -0
- package/dist/engine/rule-engine-sets.js +298 -0
- package/dist/engine/rule-engine-sets.js.map +1 -0
- package/dist/engine/rule-engine-unit.d.ts +23 -0
- package/dist/engine/rule-engine-unit.d.ts.map +1 -0
- package/dist/engine/rule-engine-unit.js +64 -0
- package/dist/engine/rule-engine-unit.js.map +1 -0
- package/dist/engine/rule-engine.d.ts +29 -0
- package/dist/engine/rule-engine.d.ts.map +1 -0
- package/dist/engine/rule-engine.js +244 -0
- package/dist/engine/rule-engine.js.map +1 -0
- package/dist/filter/effective-filter-fields.d.ts +13 -0
- package/dist/filter/effective-filter-fields.d.ts.map +1 -0
- package/dist/filter/effective-filter-fields.js +44 -0
- package/dist/filter/effective-filter-fields.js.map +1 -0
- package/dist/filter/entity-predefined-type.d.ts +24 -0
- package/dist/filter/entity-predefined-type.d.ts.map +1 -0
- package/dist/filter/entity-predefined-type.js +34 -0
- package/dist/filter/entity-predefined-type.js.map +1 -0
- package/dist/filter/filter-evaluate-groups.d.ts +36 -0
- package/dist/filter/filter-evaluate-groups.d.ts.map +1 -0
- package/dist/filter/filter-evaluate-groups.js +111 -0
- package/dist/filter/filter-evaluate-groups.js.map +1 -0
- package/dist/filter/filter-evaluate-model-tag.d.ts +22 -0
- package/dist/filter/filter-evaluate-model-tag.d.ts.map +1 -0
- package/dist/filter/filter-evaluate-model-tag.js +35 -0
- package/dist/filter/filter-evaluate-model-tag.js.map +1 -0
- package/dist/filter/filter-evaluate-mutations.d.ts +51 -0
- package/dist/filter/filter-evaluate-mutations.d.ts.map +1 -0
- package/dist/filter/filter-evaluate-mutations.js +111 -0
- package/dist/filter/filter-evaluate-mutations.js.map +1 -0
- package/dist/filter/filter-evaluate-yield.d.ts +9 -0
- package/dist/filter/filter-evaluate-yield.d.ts.map +1 -0
- package/dist/filter/filter-evaluate-yield.js +32 -0
- package/dist/filter/filter-evaluate-yield.js.map +1 -0
- package/dist/filter/filter-evaluate.d.ts +120 -0
- package/dist/filter/filter-evaluate.d.ts.map +1 -0
- package/dist/filter/filter-evaluate.js +408 -0
- package/dist/filter/filter-evaluate.js.map +1 -0
- package/dist/filter/filter-group-rule.d.ts +23 -0
- package/dist/filter/filter-group-rule.d.ts.map +1 -0
- package/dist/filter/filter-group-rule.js +69 -0
- package/dist/filter/filter-group-rule.js.map +1 -0
- package/dist/filter/filter-groups.d.ts +65 -0
- package/dist/filter/filter-groups.d.ts.map +1 -0
- package/dist/filter/filter-groups.js +136 -0
- package/dist/filter/filter-groups.js.map +1 -0
- package/dist/filter/filter-iteration-source.d.ts +26 -0
- package/dist/filter/filter-iteration-source.d.ts.map +1 -0
- package/dist/filter/filter-iteration-source.js +154 -0
- package/dist/filter/filter-iteration-source.js.map +1 -0
- package/dist/filter/filter-iteration.d.ts +5 -0
- package/dist/filter/filter-iteration.d.ts.map +1 -0
- package/dist/filter/filter-iteration.js +25 -0
- package/dist/filter/filter-iteration.js.map +1 -0
- package/dist/filter/filter-match.d.ts +114 -0
- package/dist/filter/filter-match.d.ts.map +1 -0
- package/dist/filter/filter-match.js +302 -0
- package/dist/filter/filter-match.js.map +1 -0
- package/dist/filter/filter-ops.d.ts +90 -0
- package/dist/filter/filter-ops.d.ts.map +1 -0
- package/dist/filter/filter-ops.js +202 -0
- package/dist/filter/filter-ops.js.map +1 -0
- package/dist/filter/filter-rule-guards.d.ts +4 -0
- package/dist/filter/filter-rule-guards.d.ts.map +1 -0
- package/dist/filter/filter-rule-guards.js +74 -0
- package/dist/filter/filter-rule-guards.js.map +1 -0
- package/dist/filter/filter-rules.d.ts +275 -0
- package/dist/filter/filter-rules.d.ts.map +1 -0
- package/dist/filter/filter-rules.js +68 -0
- package/dist/filter/filter-rules.js.map +1 -0
- package/dist/filter/lens-material-names.d.ts +13 -0
- package/dist/filter/lens-material-names.d.ts.map +1 -0
- package/dist/filter/lens-material-names.js +36 -0
- package/dist/filter/lens-material-names.js.map +1 -0
- package/dist/filter/measure-units.d.ts +29 -0
- package/dist/filter/measure-units.d.ts.map +1 -0
- package/dist/filter/measure-units.js +72 -0
- package/dist/filter/measure-units.js.map +1 -0
- package/dist/filter/model-tag.d.ts +65 -0
- package/dist/filter/model-tag.d.ts.map +1 -0
- package/dist/filter/model-tag.js +57 -0
- package/dist/filter/model-tag.js.map +1 -0
- package/dist/filter/read-measure-subject.d.ts +28 -0
- package/dist/filter/read-measure-subject.d.ts.map +1 -0
- package/dist/filter/read-measure-subject.js +116 -0
- package/dist/filter/read-measure-subject.js.map +1 -0
- package/dist/filter/read-subject.d.ts +72 -0
- package/dist/filter/read-subject.d.ts.map +1 -0
- package/dist/filter/read-subject.js +128 -0
- package/dist/filter/read-subject.js.map +1 -0
- package/dist/filter/subject-match.d.ts +27 -0
- package/dist/filter/subject-match.d.ts.map +1 -0
- package/dist/filter/subject-match.js +52 -0
- package/dist/filter/subject-match.js.map +1 -0
- package/dist/filter/subject-read-options.d.ts +33 -0
- package/dist/filter/subject-read-options.d.ts.map +1 -0
- package/dist/filter/subject-read-options.js +8 -0
- package/dist/filter/subject-read-options.js.map +1 -0
- package/dist/ids/ids-facet-to-rules.d.ts +20 -0
- package/dist/ids/ids-facet-to-rules.d.ts.map +1 -0
- package/dist/ids/ids-facet-to-rules.js +230 -0
- package/dist/ids/ids-facet-to-rules.js.map +1 -0
- package/dist/ids/ids-regex.d.ts +44 -0
- package/dist/ids/ids-regex.d.ts.map +1 -0
- package/dist/ids/ids-regex.js +334 -0
- package/dist/ids/ids-regex.js.map +1 -0
- package/dist/ids/ids-to-rule-set.d.ts +39 -0
- package/dist/ids/ids-to-rule-set.d.ts.map +1 -0
- package/dist/ids/ids-to-rule-set.js +103 -0
- package/dist/ids/ids-to-rule-set.js.map +1 -0
- package/dist/ids/ids-xml-writer.d.ts +11 -0
- package/dist/ids/ids-xml-writer.d.ts.map +1 -0
- package/dist/ids/ids-xml-writer.js +172 -0
- package/dist/ids/ids-xml-writer.js.map +1 -0
- package/dist/ids/rule-set-to-ids.d.ts +45 -0
- package/dist/ids/rule-set-to-ids.d.ts.map +1 -0
- package/dist/ids/rule-set-to-ids.js +140 -0
- package/dist/ids/rule-set-to-ids.js.map +1 -0
- package/dist/ids/rule-to-ids-facets.d.ts +52 -0
- package/dist/ids/rule-to-ids-facets.d.ts.map +1 -0
- package/dist/ids/rule-to-ids-facets.js +291 -0
- package/dist/ids/rule-to-ids-facets.js.map +1 -0
- package/dist/ids/stored-unit-scale.d.ts +15 -0
- package/dist/ids/stored-unit-scale.d.ts.map +1 -0
- package/dist/ids/stored-unit-scale.js +64 -0
- package/dist/ids/stored-unit-scale.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +46 -0
- package/dist/index.js.map +1 -0
- package/dist/rule-set/between-chip.d.ts +54 -0
- package/dist/rule-set/between-chip.d.ts.map +1 -0
- package/dist/rule-set/between-chip.js +95 -0
- package/dist/rule-set/between-chip.js.map +1 -0
- package/dist/rule-set/requirement-invariants.d.ts +25 -0
- package/dist/rule-set/requirement-invariants.d.ts.map +1 -0
- package/dist/rule-set/requirement-invariants.js +29 -0
- package/dist/rule-set/requirement-invariants.js.map +1 -0
- package/dist/rule-set/requirement-text.d.ts +20 -0
- package/dist/rule-set/requirement-text.d.ts.map +1 -0
- package/dist/rule-set/requirement-text.js +179 -0
- package/dist/rule-set/requirement-text.js.map +1 -0
- package/dist/rule-set/rule-set-io-requirement.d.ts +22 -0
- package/dist/rule-set/rule-set-io-requirement.d.ts.map +1 -0
- package/dist/rule-set/rule-set-io-requirement.js +140 -0
- package/dist/rule-set/rule-set-io-requirement.js.map +1 -0
- package/dist/rule-set/rule-set-io-shared.d.ts +24 -0
- package/dist/rule-set/rule-set-io-shared.d.ts.map +1 -0
- package/dist/rule-set/rule-set-io-shared.js +48 -0
- package/dist/rule-set/rule-set-io-shared.js.map +1 -0
- package/dist/rule-set/rule-set-io-subject.d.ts +10 -0
- package/dist/rule-set/rule-set-io-subject.d.ts.map +1 -0
- package/dist/rule-set/rule-set-io-subject.js +67 -0
- package/dist/rule-set/rule-set-io-subject.js.map +1 -0
- package/dist/rule-set/rule-set-io.d.ts +37 -0
- package/dist/rule-set/rule-set-io.d.ts.map +1 -0
- package/dist/rule-set/rule-set-io.js +142 -0
- package/dist/rule-set/rule-set-io.js.map +1 -0
- package/dist/rule-set/rule-set.d.ts +109 -0
- package/dist/rule-set/rule-set.d.ts.map +1 -0
- package/dist/rule-set/rule-set.js +5 -0
- package/dist/rule-set/rule-set.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,334 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Regex translation between a rule's `matches` operand (a JavaScript regex,
|
|
6
|
+
* searched UNANCHORED, see `filter-ops.ts`'s `regexOpMatches`) and an IDS
|
|
7
|
+
* `xs:pattern` (an XSD regex, matched against the WHOLE value) (#5225).
|
|
8
|
+
*
|
|
9
|
+
* The two dialects share most syntax, so each direction walks the pattern
|
|
10
|
+
* and either rewrites a construct into its exact counterpart or refuses the
|
|
11
|
+
* pattern with the construct named. It never approximates: a pattern that
|
|
12
|
+
* means something different in the other dialect is a refusal, not a
|
|
13
|
+
* best-effort translation.
|
|
14
|
+
*/
|
|
15
|
+
import { translateXsdRegex } from '@ifc-lite/ids';
|
|
16
|
+
/** Characters that must be escaped to stand for themselves in an XSD regex. */
|
|
17
|
+
const XSD_META = new Set(['\\', '|', '.', '?', '*', '+', '(', ')', '{', '}', '[', ']', '^', '$', '-']);
|
|
18
|
+
/** `text` as an XSD regex matching exactly that text. */
|
|
19
|
+
export function escapeXsdLiteral(text) {
|
|
20
|
+
let out = '';
|
|
21
|
+
for (const ch of text)
|
|
22
|
+
out += XSD_META.has(ch) ? `\\${ch}` : ch;
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The regex a `matches` operand stands for, following `regexOpMatches`:
|
|
27
|
+
* `valueKind: 'regex'` means the whole string is the source; no kind means
|
|
28
|
+
* a `/body/flags` literal is a pattern and anything else is a bare source.
|
|
29
|
+
*/
|
|
30
|
+
export function jsRegexOf(value, valueKind) {
|
|
31
|
+
if (valueKind === undefined) {
|
|
32
|
+
const literal = /^\/(.+)\/([a-z]*)$/.exec(value);
|
|
33
|
+
if (literal)
|
|
34
|
+
return { source: literal[1], flags: literal[2] };
|
|
35
|
+
}
|
|
36
|
+
return { source: value, flags: '' };
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Whether `regex` can read a character outside the Basic Multilingual Plane
|
|
40
|
+
* (an emoji, rare CJK) differently from its IDS pattern. Without the `u`
|
|
41
|
+
* flag JavaScript sees such a character as two UTF-16 code units, so `.`,
|
|
42
|
+
* a negated class `[^…]` or `\D` can match half of it, while an XSD pattern
|
|
43
|
+
* always works on whole characters. Every other construct the translation
|
|
44
|
+
* accepts means the same in both dialects.
|
|
45
|
+
*/
|
|
46
|
+
export function hasAstralCaveat(regex) {
|
|
47
|
+
if (regex.flags.includes('u'))
|
|
48
|
+
return false;
|
|
49
|
+
let inClass = false;
|
|
50
|
+
for (let i = 0; i < regex.source.length; i++) {
|
|
51
|
+
const ch = regex.source[i];
|
|
52
|
+
if (ch === '\\') {
|
|
53
|
+
if (regex.source[i + 1] === 'D')
|
|
54
|
+
return true;
|
|
55
|
+
i++;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (inClass) {
|
|
59
|
+
if (ch === ']')
|
|
60
|
+
inClass = false;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (ch === '[') {
|
|
64
|
+
inClass = true;
|
|
65
|
+
if (regex.source[i + 1] === '^')
|
|
66
|
+
return true;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (ch === '.')
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
/** Index of every `|` at nesting depth 0, outside character classes. */
|
|
75
|
+
function hasTopLevelAlternation(source) {
|
|
76
|
+
let depth = 0;
|
|
77
|
+
let inClass = false;
|
|
78
|
+
for (let i = 0; i < source.length; i++) {
|
|
79
|
+
const ch = source[i];
|
|
80
|
+
if (ch === '\\') {
|
|
81
|
+
i++;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (inClass) {
|
|
85
|
+
if (ch === ']')
|
|
86
|
+
inClass = false;
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
if (ch === '[')
|
|
90
|
+
inClass = true;
|
|
91
|
+
else if (ch === '(')
|
|
92
|
+
depth++;
|
|
93
|
+
else if (ch === ')')
|
|
94
|
+
depth--;
|
|
95
|
+
else if (ch === '|' && depth === 0)
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
/** `^(?:X)$` → `X`, when the group really spans the whole source. */
|
|
101
|
+
function unwrapAnchoredGroup(source) {
|
|
102
|
+
if (!source.startsWith('^(?:') || !source.endsWith(')$'))
|
|
103
|
+
return null;
|
|
104
|
+
const inner = source.slice(4, -2);
|
|
105
|
+
// The `)` before `$` must close the `(?:` opened at index 1.
|
|
106
|
+
let depth = 0;
|
|
107
|
+
let inClass = false;
|
|
108
|
+
for (let i = 0; i < inner.length; i++) {
|
|
109
|
+
const ch = inner[i];
|
|
110
|
+
if (ch === '\\') {
|
|
111
|
+
i++;
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (inClass) {
|
|
115
|
+
if (ch === ']')
|
|
116
|
+
inClass = false;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (ch === '[')
|
|
120
|
+
inClass = true;
|
|
121
|
+
else if (ch === '(')
|
|
122
|
+
depth++;
|
|
123
|
+
else if (ch === ')') {
|
|
124
|
+
depth--;
|
|
125
|
+
if (depth < 0)
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return depth === 0 ? inner : null;
|
|
130
|
+
}
|
|
131
|
+
const QUANTIFIER_END = new Set(['*', '+', '?', '}']);
|
|
132
|
+
/** Rewrite a JS regex body (no anchors) into XSD syntax, or say why not. */
|
|
133
|
+
function jsBodyToXsd(body, unicode) {
|
|
134
|
+
let out = '';
|
|
135
|
+
let inClass = false;
|
|
136
|
+
let classStart = false;
|
|
137
|
+
let afterQuantifier = false;
|
|
138
|
+
for (let i = 0; i < body.length; i++) {
|
|
139
|
+
const ch = body[i];
|
|
140
|
+
const wasAfterQuantifier = afterQuantifier;
|
|
141
|
+
afterQuantifier = false;
|
|
142
|
+
if (ch === '\\') {
|
|
143
|
+
const next = body[i + 1];
|
|
144
|
+
if (next === undefined)
|
|
145
|
+
return { ok: false, reason: 'the pattern ends in a lone backslash' };
|
|
146
|
+
i++;
|
|
147
|
+
classStart = false;
|
|
148
|
+
if (next === 'd') {
|
|
149
|
+
out += inClass ? '0-9' : '[0-9]';
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (next === 'D') {
|
|
153
|
+
if (inClass)
|
|
154
|
+
return { ok: false, reason: '\\D inside a character class has no XSD form' };
|
|
155
|
+
out += '[^0-9]';
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if ('wWsSbB'.includes(next)) {
|
|
159
|
+
return { ok: false, reason: `\\${next} means something different in an IDS (XSD) pattern` };
|
|
160
|
+
}
|
|
161
|
+
if ((next === 'p' || next === 'P') && unicode) {
|
|
162
|
+
const m = /^\{([A-Z][a-z]?)\}/.exec(body.slice(i + 1));
|
|
163
|
+
if (!m)
|
|
164
|
+
return { ok: false, reason: `the Unicode property escape at \\${next} has no XSD form` };
|
|
165
|
+
out += `\\${next}{${m[1]}}`;
|
|
166
|
+
i += m[0].length;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
if (next === 'n' || next === 'r' || next === 't') {
|
|
170
|
+
out += `\\${next}`;
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (/[0-9]/.test(next))
|
|
174
|
+
return { ok: false, reason: 'back-references are not supported by IDS (XSD) patterns' };
|
|
175
|
+
if (/[a-zA-Z]/.test(next)) {
|
|
176
|
+
if (unicode)
|
|
177
|
+
return { ok: false, reason: `the escape \\${next} has no XSD form` };
|
|
178
|
+
// Without the `u` flag an unknown letter escape is the letter itself.
|
|
179
|
+
if ('xucfvk'.includes(next))
|
|
180
|
+
return { ok: false, reason: `the escape \\${next} has no XSD form` };
|
|
181
|
+
out += next;
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
out += XSD_META.has(next) ? `\\${next}` : next;
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
if (inClass) {
|
|
188
|
+
if (ch === ']' && !classStart) {
|
|
189
|
+
inClass = false;
|
|
190
|
+
out += ch;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (ch === '[') {
|
|
194
|
+
out += '\\[';
|
|
195
|
+
classStart = false;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (ch === '^' && classStart) {
|
|
199
|
+
out += ch;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
classStart = false;
|
|
203
|
+
out += ch;
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (ch === '[') {
|
|
207
|
+
inClass = true;
|
|
208
|
+
classStart = true;
|
|
209
|
+
out += ch;
|
|
210
|
+
continue;
|
|
211
|
+
}
|
|
212
|
+
if (ch === '(' && body[i + 1] === '?') {
|
|
213
|
+
return { ok: false, reason: 'groups starting "(?" (lookaround, named or non-capturing) are not supported by IDS (XSD) patterns' };
|
|
214
|
+
}
|
|
215
|
+
if (ch === '^' || ch === '$') {
|
|
216
|
+
return { ok: false, reason: `"${ch}" is only supported at the very start or end of the pattern` };
|
|
217
|
+
}
|
|
218
|
+
if (ch === '?' && wasAfterQuantifier) {
|
|
219
|
+
return { ok: false, reason: 'lazy quantifiers are not supported by IDS (XSD) patterns' };
|
|
220
|
+
}
|
|
221
|
+
if (QUANTIFIER_END.has(ch))
|
|
222
|
+
afterQuantifier = true;
|
|
223
|
+
out += ch;
|
|
224
|
+
}
|
|
225
|
+
if (inClass)
|
|
226
|
+
return { ok: false, reason: 'the pattern has an unterminated character class' };
|
|
227
|
+
return { ok: true, pattern: out };
|
|
228
|
+
}
|
|
229
|
+
/** Whether `xsd` compiles, through the same translator the IDS checker uses. */
|
|
230
|
+
function xsdCompiles(xsd) {
|
|
231
|
+
const translated = translateXsdRegex(xsd);
|
|
232
|
+
if (!translated.supported)
|
|
233
|
+
return false;
|
|
234
|
+
try {
|
|
235
|
+
new RegExp(`^(?:${translated.pattern})$`, 'u');
|
|
236
|
+
return true;
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Translate the engine's unanchored JS regex into an IDS pattern that
|
|
244
|
+
* accepts exactly the same values. `^…$` anchors (or the `^(?:…)$` wrapper
|
|
245
|
+
* `idsPatternToJsRegex` produces) become the XSD pattern's implicit whole-
|
|
246
|
+
* value match; an unanchored side becomes `.*`.
|
|
247
|
+
*/
|
|
248
|
+
export function jsRegexToIdsPattern(regex) {
|
|
249
|
+
// `g` and `y` are dropped because the engine drops them: `@ifc-lite/lists`'
|
|
250
|
+
// `parseRegexLiteral` compiles every operand without them (a cached,
|
|
251
|
+
// shared matcher must not carry `lastIndex` state), so `/a/y` already
|
|
252
|
+
// searches like `/a/`. `d` only adds match indices.
|
|
253
|
+
const flags = regex.flags.replace(/[gyd]/g, '');
|
|
254
|
+
for (const flag of flags) {
|
|
255
|
+
if (flag === 'i')
|
|
256
|
+
return { ok: false, reason: 'the "i" flag makes the pattern case-insensitive, which IDS patterns cannot be' };
|
|
257
|
+
if (flag !== 'u')
|
|
258
|
+
return { ok: false, reason: `the "${flag}" regex flag has no IDS (XSD) equivalent` };
|
|
259
|
+
}
|
|
260
|
+
const unicode = flags.includes('u');
|
|
261
|
+
const wrapped = unwrapAnchoredGroup(regex.source);
|
|
262
|
+
let body = wrapped ?? regex.source;
|
|
263
|
+
let anchoredStart = wrapped !== null;
|
|
264
|
+
let anchoredEnd = wrapped !== null;
|
|
265
|
+
if (wrapped === null) {
|
|
266
|
+
anchoredStart = body.startsWith('^');
|
|
267
|
+
// A trailing `$` is an anchor unless it is escaped (`\$`).
|
|
268
|
+
anchoredEnd = body.endsWith('$') && !/(^|[^\\])(\\\\)*\\\$$/.test(body);
|
|
269
|
+
if ((anchoredStart || anchoredEnd) && hasTopLevelAlternation(body)) {
|
|
270
|
+
return { ok: false, reason: 'anchors combined with a top-level "|" have no single IDS pattern' };
|
|
271
|
+
}
|
|
272
|
+
if (anchoredStart)
|
|
273
|
+
body = body.slice(1);
|
|
274
|
+
if (anchoredEnd)
|
|
275
|
+
body = body.slice(0, -1);
|
|
276
|
+
}
|
|
277
|
+
if (body.length === 0)
|
|
278
|
+
return { ok: false, reason: 'the pattern is empty' };
|
|
279
|
+
const converted = jsBodyToXsd(body, unicode);
|
|
280
|
+
if (!converted.ok)
|
|
281
|
+
return converted;
|
|
282
|
+
const needsGroup = !(anchoredStart && anchoredEnd) && hasTopLevelAlternation(converted.pattern);
|
|
283
|
+
const core = needsGroup ? `(${converted.pattern})` : converted.pattern;
|
|
284
|
+
const pattern = `${anchoredStart ? '' : '.*'}${core}${anchoredEnd ? '' : '.*'}`;
|
|
285
|
+
if (!xsdCompiles(pattern))
|
|
286
|
+
return { ok: false, reason: 'the translated pattern is not a valid IDS (XSD) pattern' };
|
|
287
|
+
return { ok: true, pattern };
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Translate an IDS pattern into the rule operand that accepts the same
|
|
291
|
+
* values: a `/^(?:…)$/u` literal (the `u` flag because XSD's `\d`, `\i`,
|
|
292
|
+
* `\c` and `\w` translate to Unicode property escapes). XSD's `^` and `$`
|
|
293
|
+
* are ordinary characters, so they are escaped first.
|
|
294
|
+
*/
|
|
295
|
+
export function idsPatternToJsRegex(xsd) {
|
|
296
|
+
let literalAnchors = '';
|
|
297
|
+
let inClass = false;
|
|
298
|
+
let classStart = false;
|
|
299
|
+
for (let i = 0; i < xsd.length; i++) {
|
|
300
|
+
const ch = xsd[i];
|
|
301
|
+
if (ch === '\\') {
|
|
302
|
+
literalAnchors += ch + (xsd[i + 1] ?? '');
|
|
303
|
+
i++;
|
|
304
|
+
classStart = false;
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
if (inClass) {
|
|
308
|
+
if (ch === ']' && !classStart)
|
|
309
|
+
inClass = false;
|
|
310
|
+
classStart = false;
|
|
311
|
+
literalAnchors += ch;
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (ch === '[') {
|
|
315
|
+
inClass = true;
|
|
316
|
+
classStart = true;
|
|
317
|
+
literalAnchors += ch;
|
|
318
|
+
continue;
|
|
319
|
+
}
|
|
320
|
+
literalAnchors += ch === '^' || ch === '$' ? `\\${ch}` : ch;
|
|
321
|
+
}
|
|
322
|
+
const translated = translateXsdRegex(literalAnchors);
|
|
323
|
+
if (!translated.supported)
|
|
324
|
+
return { ok: false, reason: translated.reason };
|
|
325
|
+
const source = `^(?:${translated.pattern})$`;
|
|
326
|
+
try {
|
|
327
|
+
new RegExp(source, 'u');
|
|
328
|
+
}
|
|
329
|
+
catch (err) {
|
|
330
|
+
return { ok: false, reason: `the pattern does not compile: ${err.message}` };
|
|
331
|
+
}
|
|
332
|
+
return { ok: true, pattern: `/${source}/u` };
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=ids-regex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids-regex.js","sourceRoot":"","sources":["../../src/ids/ids-regex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Import the simple specifications of an IDS document as rules (#5225), so
|
|
3
|
+
* an incoming deliverable can be extended with checks IDS cannot express.
|
|
4
|
+
*
|
|
5
|
+
* A specification imports when every facet has an exact rule equivalent:
|
|
6
|
+
* entity, attribute and property facets (and classification presence,
|
|
7
|
+
* material) whose constraints are simple values, patterns, enumerations or
|
|
8
|
+
* numeric bounds. Anything else blocks THAT specification with a named
|
|
9
|
+
* reason rather than being approximated: partOf, optional and prohibited
|
|
10
|
+
* facets, a pattern on an entity or attribute NAME,
|
|
11
|
+
* length/digit restrictions. The per-facet mapping is in
|
|
12
|
+
* `ids-facet-to-rules.ts`.
|
|
13
|
+
*/
|
|
14
|
+
import type { IDSDocument } from '@ifc-lite/ids';
|
|
15
|
+
import type { RuleSetFile } from '../rule-set/rule-set.js';
|
|
16
|
+
export interface IdsToRuleSetOptions {
|
|
17
|
+
/** Id for a rule whose specification has no usable `identifier`. Default: `crypto.randomUUID()`. */
|
|
18
|
+
newId?: () => string;
|
|
19
|
+
}
|
|
20
|
+
export interface RefusedSpecification {
|
|
21
|
+
specificationName: string;
|
|
22
|
+
reasons: string[];
|
|
23
|
+
}
|
|
24
|
+
export interface IdsToRuleSetResult {
|
|
25
|
+
/** `null` when no specification could be imported. */
|
|
26
|
+
file: RuleSetFile | null;
|
|
27
|
+
refused: RefusedSpecification[];
|
|
28
|
+
/** Caveats that apply to the imported rules as a whole. */
|
|
29
|
+
notes: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Checks the IDS makes that the imported rules do not, one entry per
|
|
32
|
+
* dropped check as `"<rule name>: <what>"` (today: a property facet's
|
|
33
|
+
* `dataType`, which the rule vocabulary cannot check, #5225).
|
|
34
|
+
*/
|
|
35
|
+
droppedChecks: string[];
|
|
36
|
+
}
|
|
37
|
+
/** Convert the simple specifications of `doc` to a rule set. Never throws. */
|
|
38
|
+
export declare function idsToRuleSet(doc: IDSDocument, options?: IdsToRuleSetOptions): IdsToRuleSetResult;
|
|
39
|
+
//# sourceMappingURL=ids-to-rule-set.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids-to-rule-set.d.ts","sourceRoot":"","sources":["../../src/ids/ids-to-rule-set.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAoB,MAAM,eAAe,CAAC;AAEnE,OAAO,KAAK,EAAmB,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAI5E,MAAM,WAAW,mBAAmB;IAClC,oGAAoG;IACpG,KAAK,CAAC,EAAE,MAAM,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,2DAA2D;IAC3D,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;;OAIG;IACH,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAyED,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE,mBAAwB,GAAG,kBAAkB,CAgCpG"}
|
|
@@ -0,0 +1,103 @@
|
|
|
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 { RULE_SET_VERSION } from '../rule-set/rule-set.js';
|
|
5
|
+
import { facetToRules } from './ids-facet-to-rules.js';
|
|
6
|
+
const ALL_VERSIONS_NOTE = 'IDS specifications limited to some IFC versions were imported as rules that run on every model';
|
|
7
|
+
function cardinalityOf(spec, reasons) {
|
|
8
|
+
const min = spec.minOccurs ?? 0;
|
|
9
|
+
const max = spec.maxOccurs ?? 'unbounded';
|
|
10
|
+
if (max === 'unbounded')
|
|
11
|
+
return min > 0 ? { minApplicable: min } : undefined;
|
|
12
|
+
if (max < min) {
|
|
13
|
+
reasons.push(`maxOccurs ${max} is below minOccurs ${min}`);
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
return { ...(min > 0 ? { minApplicable: min } : {}), maxApplicable: max };
|
|
17
|
+
}
|
|
18
|
+
function specificationToRule(spec, id) {
|
|
19
|
+
const reasons = [];
|
|
20
|
+
const dropped = [];
|
|
21
|
+
const cardinality = cardinalityOf(spec, reasons);
|
|
22
|
+
const applicability = [];
|
|
23
|
+
for (const facet of spec.applicability.facets) {
|
|
24
|
+
const mapped = facetToRules(facet, 'applicability');
|
|
25
|
+
if (mapped.ok) {
|
|
26
|
+
applicability.push(...mapped.rules);
|
|
27
|
+
dropped.push(...(mapped.dropped ?? []));
|
|
28
|
+
}
|
|
29
|
+
else
|
|
30
|
+
reasons.push(`applicability: ${mapped.reason}`);
|
|
31
|
+
}
|
|
32
|
+
if (spec.applicability.facets.length === 0)
|
|
33
|
+
reasons.push('the applicability has no facets');
|
|
34
|
+
const requirement = [];
|
|
35
|
+
for (const req of spec.requirements) {
|
|
36
|
+
if (req.optionality !== 'required') {
|
|
37
|
+
reasons.push(req.optionality === 'optional'
|
|
38
|
+
? `requirements: an optional ${req.facet.type} facet ("if present, must match") has no rule equivalent`
|
|
39
|
+
: `requirements: a prohibited ${req.facet.type} facet has no rule equivalent`);
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
const mapped = facetToRules(req.facet, 'requirement');
|
|
43
|
+
if (mapped.ok) {
|
|
44
|
+
requirement.push(...mapped.rules);
|
|
45
|
+
dropped.push(...(mapped.dropped ?? []));
|
|
46
|
+
}
|
|
47
|
+
else
|
|
48
|
+
reasons.push(`requirements: ${mapped.reason}`);
|
|
49
|
+
}
|
|
50
|
+
if (spec.requirements.length === 0) {
|
|
51
|
+
reasons.push('a specification without requirements has no rule equivalent (a rule always checks something)');
|
|
52
|
+
}
|
|
53
|
+
if (reasons.length > 0)
|
|
54
|
+
return { ok: false, reasons };
|
|
55
|
+
const description = [spec.description, spec.instructions].filter((s) => !!s).join('\n\n');
|
|
56
|
+
return {
|
|
57
|
+
ok: true,
|
|
58
|
+
dropped,
|
|
59
|
+
rule: {
|
|
60
|
+
id,
|
|
61
|
+
name: spec.name || id,
|
|
62
|
+
...(description ? { description } : {}),
|
|
63
|
+
applicability: { groups: [{ rules: applicability, combinator: 'AND' }], authoredAs: 'chips' },
|
|
64
|
+
requirement: { kind: 'element', block: { groups: [{ rules: requirement, combinator: 'AND' }], authoredAs: 'chips' } },
|
|
65
|
+
...(cardinality ? { cardinality } : {}),
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const ALL_VERSIONS = new Set(['IFC2X3', 'IFC4', 'IFC4X3', 'IFC4X3_ADD2']);
|
|
70
|
+
/** Convert the simple specifications of `doc` to a rule set. Never throws. */
|
|
71
|
+
export function idsToRuleSet(doc, options = {}) {
|
|
72
|
+
const newId = options.newId ?? (() => globalThis.crypto.randomUUID());
|
|
73
|
+
const usedIds = new Set();
|
|
74
|
+
const rules = [];
|
|
75
|
+
const refused = [];
|
|
76
|
+
const notes = new Set();
|
|
77
|
+
const droppedChecks = [];
|
|
78
|
+
doc.specifications.forEach((spec, index) => {
|
|
79
|
+
const identifier = spec.identifier?.trim();
|
|
80
|
+
const id = identifier && !usedIds.has(identifier) ? identifier : newId();
|
|
81
|
+
const outcome = specificationToRule(spec, id);
|
|
82
|
+
if (!outcome.ok) {
|
|
83
|
+
refused.push({ specificationName: spec.name || `Specification ${index + 1}`, reasons: outcome.reasons });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
usedIds.add(id);
|
|
87
|
+
rules.push(outcome.rule);
|
|
88
|
+
for (const loss of outcome.dropped)
|
|
89
|
+
droppedChecks.push(`${outcome.rule.name}: ${loss}`);
|
|
90
|
+
const versions = new Set(spec.ifcVersions);
|
|
91
|
+
if (![...ALL_VERSIONS].every((v) => versions.has(v) || (v === 'IFC4X3' && versions.has('IFC4X3_ADD2')) || (v === 'IFC4X3_ADD2' && versions.has('IFC4X3')))) {
|
|
92
|
+
notes.add(ALL_VERSIONS_NOTE);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
const file = rules.length === 0 ? null : {
|
|
96
|
+
version: RULE_SET_VERSION,
|
|
97
|
+
name: doc.info.title || 'Imported IDS',
|
|
98
|
+
...(doc.info.description ? { description: doc.info.description } : {}),
|
|
99
|
+
rules,
|
|
100
|
+
};
|
|
101
|
+
return { file, refused, notes: [...notes], droppedChecks };
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=ids-to-rule-set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids-to-rule-set.js","sourceRoot":"","sources":["../../src/ids/ids-to-rule-set.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialise an `IDSDocument` as IDS 1.0 XML (#5225). Covers the subset of
|
|
3
|
+
* the model `ruleSetToIds` produces: entity, attribute, property,
|
|
4
|
+
* classification and material facets, with simple-value, pattern,
|
|
5
|
+
* enumeration and numeric-bound constraints. Element order follows
|
|
6
|
+
* `ids.xsd`, so `parseIDS` and `auditIDSDocument` read the result back.
|
|
7
|
+
*/
|
|
8
|
+
import type { IDSDocument } from '@ifc-lite/ids';
|
|
9
|
+
/** `doc` as an IDS 1.0 XML string. */
|
|
10
|
+
export declare function writeIdsXml(doc: IDSDocument): string;
|
|
11
|
+
//# sourceMappingURL=ids-xml-writer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids-xml-writer.d.ts","sourceRoot":"","sources":["../../src/ids/ids-xml-writer.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,KAAK,EAEV,WAAW,EAIZ,MAAM,eAAe,CAAC;AAuJvB,sCAAsC;AACtC,wBAAgB,WAAW,CAAC,GAAG,EAAE,WAAW,GAAG,MAAM,CAiBpD"}
|