@ifc-lite/ids 1.0.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.
Files changed (75) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +76 -0
  3. package/dist/constraints/index.d.ts +17 -0
  4. package/dist/constraints/index.d.ts.map +1 -0
  5. package/dist/constraints/index.js +226 -0
  6. package/dist/constraints/index.js.map +1 -0
  7. package/dist/facets/attribute-facet.d.ts +10 -0
  8. package/dist/facets/attribute-facet.d.ts.map +1 -0
  9. package/dist/facets/attribute-facet.js +107 -0
  10. package/dist/facets/attribute-facet.js.map +1 -0
  11. package/dist/facets/classification-facet.d.ts +10 -0
  12. package/dist/facets/classification-facet.d.ts.map +1 -0
  13. package/dist/facets/classification-facet.js +98 -0
  14. package/dist/facets/classification-facet.js.map +1 -0
  15. package/dist/facets/entity-facet.d.ts +18 -0
  16. package/dist/facets/entity-facet.d.ts.map +1 -0
  17. package/dist/facets/entity-facet.js +116 -0
  18. package/dist/facets/entity-facet.js.map +1 -0
  19. package/dist/facets/index.d.ts +31 -0
  20. package/dist/facets/index.d.ts.map +1 -0
  21. package/dist/facets/index.js +57 -0
  22. package/dist/facets/index.js.map +1 -0
  23. package/dist/facets/material-facet.d.ts +10 -0
  24. package/dist/facets/material-facet.d.ts.map +1 -0
  25. package/dist/facets/material-facet.js +67 -0
  26. package/dist/facets/material-facet.js.map +1 -0
  27. package/dist/facets/partof-facet.d.ts +10 -0
  28. package/dist/facets/partof-facet.d.ts.map +1 -0
  29. package/dist/facets/partof-facet.js +112 -0
  30. package/dist/facets/partof-facet.js.map +1 -0
  31. package/dist/facets/property-facet.d.ts +10 -0
  32. package/dist/facets/property-facet.d.ts.map +1 -0
  33. package/dist/facets/property-facet.js +156 -0
  34. package/dist/facets/property-facet.js.map +1 -0
  35. package/dist/index.d.ts +18 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +26 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/parser/xml-parser.d.ts +15 -0
  40. package/dist/parser/xml-parser.d.ts.map +1 -0
  41. package/dist/parser/xml-parser.js +486 -0
  42. package/dist/parser/xml-parser.js.map +1 -0
  43. package/dist/translation/index.d.ts +3 -0
  44. package/dist/translation/index.d.ts.map +1 -0
  45. package/dist/translation/index.js +6 -0
  46. package/dist/translation/index.js.map +1 -0
  47. package/dist/translation/locales/de.d.ts +189 -0
  48. package/dist/translation/locales/de.d.ts.map +1 -0
  49. package/dist/translation/locales/de.js +226 -0
  50. package/dist/translation/locales/de.js.map +1 -0
  51. package/dist/translation/locales/en.d.ts +190 -0
  52. package/dist/translation/locales/en.d.ts.map +1 -0
  53. package/dist/translation/locales/en.js +226 -0
  54. package/dist/translation/locales/en.js.map +1 -0
  55. package/dist/translation/locales/fr.d.ts +189 -0
  56. package/dist/translation/locales/fr.d.ts.map +1 -0
  57. package/dist/translation/locales/fr.js +226 -0
  58. package/dist/translation/locales/fr.js.map +1 -0
  59. package/dist/translation/locales/index.d.ts +4 -0
  60. package/dist/translation/locales/index.d.ts.map +1 -0
  61. package/dist/translation/locales/index.js +7 -0
  62. package/dist/translation/locales/index.js.map +1 -0
  63. package/dist/translation/service.d.ts +62 -0
  64. package/dist/translation/service.d.ts.map +1 -0
  65. package/dist/translation/service.js +569 -0
  66. package/dist/translation/service.js.map +1 -0
  67. package/dist/types.d.ts +407 -0
  68. package/dist/types.d.ts.map +1 -0
  69. package/dist/types.js +5 -0
  70. package/dist/types.js.map +1 -0
  71. package/dist/validation/validator.d.ts +9 -0
  72. package/dist/validation/validator.d.ts.map +1 -0
  73. package/dist/validation/validator.js +431 -0
  74. package/dist/validation/validator.js.map +1 -0
  75. package/package.json +51 -0
@@ -0,0 +1,4 @@
1
+ export { en } from './en.js';
2
+ export { de } from './de.js';
3
+ export { fr } from './fr.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/translation/locales/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,7 @@
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
+ export { en } from './en.js';
5
+ export { de } from './de.js';
6
+ export { fr } from './fr.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/translation/locales/index.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAE/D,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Translation service for IDS validation reports
3
+ */
4
+ import type { IDSFacet, IDSConstraint, IDSRequirement, IDSRequirementResult, SupportedLocale, TranslationService, PartOfRelation, RequirementOptionality } from '../types.js';
5
+ /**
6
+ * Create a translation service for the specified locale
7
+ */
8
+ export declare function createTranslationService(locale?: SupportedLocale): TranslationService;
9
+ declare class IDSTranslationServiceImpl implements TranslationService {
10
+ readonly locale: SupportedLocale;
11
+ private translations;
12
+ constructor(locale: SupportedLocale);
13
+ /**
14
+ * Translate a key with parameter interpolation
15
+ */
16
+ t(key: string, params?: Record<string, string | number>): string;
17
+ /**
18
+ * Interpolate parameters into a string
19
+ */
20
+ private interpolate;
21
+ /**
22
+ * Describe a facet in human-readable form
23
+ */
24
+ describeFacet(facet: IDSFacet, context: 'applicability' | 'requirement'): string;
25
+ private describeEntityFacet;
26
+ private describeAttributeFacet;
27
+ private describePropertyFacet;
28
+ private describeClassificationFacet;
29
+ private describeMaterialFacet;
30
+ private describePartOfFacet;
31
+ /**
32
+ * Describe a constraint value in human-readable form
33
+ */
34
+ describeConstraint(constraint: IDSConstraint): string;
35
+ private describeBounds;
36
+ /**
37
+ * Describe a failure in human-readable form
38
+ */
39
+ describeFailure(result: IDSRequirementResult): string;
40
+ private extractPsetFromField;
41
+ private extractPropertyFromField;
42
+ /**
43
+ * Describe a requirement in human-readable form
44
+ */
45
+ describeRequirement(requirement: IDSRequirement): string;
46
+ private applyProhibited;
47
+ private applyOptional;
48
+ /**
49
+ * Get status text
50
+ */
51
+ getStatusText(status: 'pass' | 'fail' | 'not_applicable'): string;
52
+ /**
53
+ * Get optionality text
54
+ */
55
+ getOptionalityText(optionality: RequirementOptionality): string;
56
+ /**
57
+ * Get human-readable relationship description
58
+ */
59
+ getRelationDescription(relation: PartOfRelation): string;
60
+ }
61
+ export { IDSTranslationServiceImpl };
62
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/translation/service.ts"],"names":[],"mappings":"AAIA;;GAEG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACvB,MAAM,aAAa,CAAC;AAcrB;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,GAAE,eAAsB,GAC7B,kBAAkB,CAEpB;AAED,cAAM,yBAA0B,YAAW,kBAAkB;IAC3D,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,OAAO,CAAC,YAAY,CAAe;gBAEvB,MAAM,EAAE,eAAe;IAKnC;;OAEG;IACH,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM;IA0BhE;;OAEG;IACH,OAAO,CAAC,WAAW;IAYnB;;OAEG;IACH,aAAa,CACX,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,eAAe,GAAG,aAAa,GACvC,MAAM;IAqBT,OAAO,CAAC,mBAAmB;IA0B3B,OAAO,CAAC,sBAAsB;IAsC9B,OAAO,CAAC,qBAAqB;IA+D7B,OAAO,CAAC,2BAA2B;IAgDnC,OAAO,CAAC,qBAAqB;IAiC7B,OAAO,CAAC,mBAAmB;IAiC3B;;OAEG;IACH,kBAAkB,CAAC,UAAU,EAAE,aAAa,GAAG,MAAM;IAgCrD,OAAO,CAAC,cAAc;IAgCtB;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM;IAqLrD,OAAO,CAAC,oBAAoB;IAM5B,OAAO,CAAC,wBAAwB;IAMhC;;OAEG;IACH,mBAAmB,CAAC,WAAW,EAAE,cAAc,GAAG,MAAM;IAaxD,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,aAAa;IAQrB;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,gBAAgB,GAAG,MAAM;IAIjE;;OAEG;IACH,kBAAkB,CAAC,WAAW,EAAE,sBAAsB,GAAG,MAAM;IAI/D;;OAEG;IACH,sBAAsB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM;CAMzD;AAED,OAAO,EAAE,yBAAyB,EAAE,CAAC"}
@@ -0,0 +1,569 @@
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 { en } from './locales/en.js';
5
+ import { de } from './locales/de.js';
6
+ import { fr } from './locales/fr.js';
7
+ const LOCALES = {
8
+ en,
9
+ de,
10
+ fr,
11
+ };
12
+ /**
13
+ * Create a translation service for the specified locale
14
+ */
15
+ export function createTranslationService(locale = 'en') {
16
+ return new IDSTranslationServiceImpl(locale);
17
+ }
18
+ class IDSTranslationServiceImpl {
19
+ locale;
20
+ translations;
21
+ constructor(locale) {
22
+ this.locale = locale;
23
+ this.translations = LOCALES[locale] || LOCALES.en;
24
+ }
25
+ /**
26
+ * Translate a key with parameter interpolation
27
+ */
28
+ t(key, params) {
29
+ // Navigate to the translation value
30
+ const parts = key.split('.');
31
+ let value = this.translations;
32
+ for (const part of parts) {
33
+ if (value && typeof value === 'object' && part in value) {
34
+ value = value[part];
35
+ }
36
+ else {
37
+ // Key not found, return the key itself
38
+ return key;
39
+ }
40
+ }
41
+ if (typeof value !== 'string') {
42
+ return key;
43
+ }
44
+ // Interpolate parameters
45
+ if (params) {
46
+ return this.interpolate(value, params);
47
+ }
48
+ return value;
49
+ }
50
+ /**
51
+ * Interpolate parameters into a string
52
+ */
53
+ interpolate(template, params) {
54
+ return template.replace(/\{(\w+)\}/g, (match, key) => {
55
+ if (key in params) {
56
+ return String(params[key]);
57
+ }
58
+ return match;
59
+ });
60
+ }
61
+ /**
62
+ * Describe a facet in human-readable form
63
+ */
64
+ describeFacet(facet, context) {
65
+ const t = this.translations;
66
+ switch (facet.type) {
67
+ case 'entity':
68
+ return this.describeEntityFacet(facet, context);
69
+ case 'attribute':
70
+ return this.describeAttributeFacet(facet, context);
71
+ case 'property':
72
+ return this.describePropertyFacet(facet, context);
73
+ case 'classification':
74
+ return this.describeClassificationFacet(facet, context);
75
+ case 'material':
76
+ return this.describeMaterialFacet(facet, context);
77
+ case 'partOf':
78
+ return this.describePartOfFacet(facet, context);
79
+ default:
80
+ return 'Unknown facet';
81
+ }
82
+ }
83
+ describeEntityFacet(facet, context) {
84
+ const t = this.translations;
85
+ const entityType = this.describeConstraint(facet.name);
86
+ if (context === 'applicability') {
87
+ if (facet.predefinedType) {
88
+ return this.interpolate(t.applicability.entity.withPredefined, {
89
+ entityType,
90
+ predefinedType: this.describeConstraint(facet.predefinedType),
91
+ });
92
+ }
93
+ return this.interpolate(t.applicability.entity.simple, { entityType });
94
+ }
95
+ else {
96
+ if (facet.predefinedType) {
97
+ return this.interpolate(t.requirements.entity.mustBeWithPredefined, {
98
+ entityType,
99
+ predefinedType: this.describeConstraint(facet.predefinedType),
100
+ });
101
+ }
102
+ return this.interpolate(t.requirements.entity.mustBe, { entityType });
103
+ }
104
+ }
105
+ describeAttributeFacet(facet, context) {
106
+ const t = this.translations;
107
+ const name = this.describeConstraint(facet.name);
108
+ if (context === 'applicability') {
109
+ if (facet.value) {
110
+ if (facet.value.type === 'pattern') {
111
+ return this.interpolate(t.applicability.attribute.pattern, {
112
+ name,
113
+ pattern: this.describeConstraint(facet.value),
114
+ });
115
+ }
116
+ return this.interpolate(t.applicability.attribute.equals, {
117
+ name,
118
+ value: this.describeConstraint(facet.value),
119
+ });
120
+ }
121
+ return this.interpolate(t.applicability.attribute.exists, { name });
122
+ }
123
+ else {
124
+ if (facet.value) {
125
+ if (facet.value.type === 'pattern') {
126
+ return this.interpolate(t.requirements.attribute.mustMatch, {
127
+ name,
128
+ pattern: this.describeConstraint(facet.value),
129
+ });
130
+ }
131
+ return this.interpolate(t.requirements.attribute.mustEqual, {
132
+ name,
133
+ value: this.describeConstraint(facet.value),
134
+ });
135
+ }
136
+ return this.interpolate(t.requirements.attribute.mustExist, { name });
137
+ }
138
+ }
139
+ describePropertyFacet(facet, context) {
140
+ const t = this.translations;
141
+ const pset = this.describeConstraint(facet.propertySet);
142
+ const property = this.describeConstraint(facet.baseName);
143
+ if (context === 'applicability') {
144
+ if (facet.value) {
145
+ if (facet.value.type === 'pattern') {
146
+ return this.interpolate(t.applicability.property.pattern, {
147
+ pset,
148
+ property,
149
+ pattern: this.describeConstraint(facet.value),
150
+ });
151
+ }
152
+ if (facet.value.type === 'bounds') {
153
+ return this.interpolate(t.applicability.property.bounded, {
154
+ pset,
155
+ property,
156
+ bounds: this.describeConstraint(facet.value),
157
+ });
158
+ }
159
+ return this.interpolate(t.applicability.property.equals, {
160
+ pset,
161
+ property,
162
+ value: this.describeConstraint(facet.value),
163
+ });
164
+ }
165
+ return this.interpolate(t.applicability.property.exists, {
166
+ pset,
167
+ property,
168
+ });
169
+ }
170
+ else {
171
+ if (facet.value) {
172
+ if (facet.value.type === 'pattern') {
173
+ return this.interpolate(t.requirements.property.mustMatch, {
174
+ pset,
175
+ property,
176
+ pattern: this.describeConstraint(facet.value),
177
+ });
178
+ }
179
+ if (facet.value.type === 'bounds') {
180
+ return this.interpolate(t.requirements.property.mustBeBounded, {
181
+ pset,
182
+ property,
183
+ bounds: this.describeConstraint(facet.value),
184
+ });
185
+ }
186
+ return this.interpolate(t.requirements.property.mustEqual, {
187
+ pset,
188
+ property,
189
+ value: this.describeConstraint(facet.value),
190
+ });
191
+ }
192
+ return this.interpolate(t.requirements.property.mustExist, {
193
+ pset,
194
+ property,
195
+ });
196
+ }
197
+ }
198
+ describeClassificationFacet(facet, context) {
199
+ const t = this.translations;
200
+ if (context === 'applicability') {
201
+ if (facet.system && facet.value) {
202
+ return this.interpolate(t.applicability.classification.systemAndValue, {
203
+ system: this.describeConstraint(facet.system),
204
+ value: this.describeConstraint(facet.value),
205
+ });
206
+ }
207
+ if (facet.system) {
208
+ return this.interpolate(t.applicability.classification.system, {
209
+ system: this.describeConstraint(facet.system),
210
+ });
211
+ }
212
+ if (facet.value) {
213
+ return this.interpolate(t.applicability.classification.value, {
214
+ value: this.describeConstraint(facet.value),
215
+ });
216
+ }
217
+ return t.applicability.classification.any;
218
+ }
219
+ else {
220
+ if (facet.system && facet.value) {
221
+ return this.interpolate(t.requirements.classification.mustBeInSystemWithValue, {
222
+ system: this.describeConstraint(facet.system),
223
+ value: this.describeConstraint(facet.value),
224
+ });
225
+ }
226
+ if (facet.system) {
227
+ return this.interpolate(t.requirements.classification.mustBeInSystem, {
228
+ system: this.describeConstraint(facet.system),
229
+ });
230
+ }
231
+ if (facet.value) {
232
+ return this.interpolate(t.requirements.classification.mustHaveValue, {
233
+ value: this.describeConstraint(facet.value),
234
+ });
235
+ }
236
+ return t.requirements.classification.mustHave;
237
+ }
238
+ }
239
+ describeMaterialFacet(facet, context) {
240
+ const t = this.translations;
241
+ if (context === 'applicability') {
242
+ if (facet.value) {
243
+ if (facet.value.type === 'pattern') {
244
+ return this.interpolate(t.applicability.material.pattern, {
245
+ pattern: this.describeConstraint(facet.value),
246
+ });
247
+ }
248
+ return this.interpolate(t.applicability.material.value, {
249
+ value: this.describeConstraint(facet.value),
250
+ });
251
+ }
252
+ return t.applicability.material.any;
253
+ }
254
+ else {
255
+ if (facet.value) {
256
+ if (facet.value.type === 'pattern') {
257
+ return this.interpolate(t.requirements.material.mustMatch, {
258
+ pattern: this.describeConstraint(facet.value),
259
+ });
260
+ }
261
+ return this.interpolate(t.requirements.material.mustBe, {
262
+ value: this.describeConstraint(facet.value),
263
+ });
264
+ }
265
+ return t.requirements.material.mustHave;
266
+ }
267
+ }
268
+ describePartOfFacet(facet, context) {
269
+ const t = this.translations;
270
+ const relation = this.getRelationDescription(facet.relation);
271
+ if (context === 'applicability') {
272
+ if (facet.entity) {
273
+ if (facet.entity.predefinedType) {
274
+ return this.interpolate(t.applicability.partOf.withEntityAndType, {
275
+ relation,
276
+ entity: this.describeConstraint(facet.entity.name),
277
+ predefinedType: this.describeConstraint(facet.entity.predefinedType),
278
+ });
279
+ }
280
+ return this.interpolate(t.applicability.partOf.withEntity, {
281
+ relation,
282
+ entity: this.describeConstraint(facet.entity.name),
283
+ });
284
+ }
285
+ return this.interpolate(t.applicability.partOf.simple, { relation });
286
+ }
287
+ else {
288
+ if (facet.entity) {
289
+ return this.interpolate(t.requirements.partOf.mustBe, {
290
+ relation,
291
+ entity: this.describeConstraint(facet.entity.name),
292
+ });
293
+ }
294
+ return this.interpolate(t.requirements.partOf.mustBeSimple, { relation });
295
+ }
296
+ }
297
+ /**
298
+ * Describe a constraint value in human-readable form
299
+ */
300
+ describeConstraint(constraint) {
301
+ const t = this.translations;
302
+ switch (constraint.type) {
303
+ case 'simpleValue':
304
+ return this.interpolate(t.constraints.simpleValue, {
305
+ value: constraint.value,
306
+ });
307
+ case 'pattern':
308
+ return this.interpolate(t.constraints.pattern, {
309
+ pattern: constraint.pattern,
310
+ });
311
+ case 'enumeration':
312
+ if (constraint.values.length === 1) {
313
+ return this.interpolate(t.constraints.enumeration.single, {
314
+ value: constraint.values[0],
315
+ });
316
+ }
317
+ return this.interpolate(t.constraints.enumeration.multiple, {
318
+ values: constraint.values.map((v) => `"${v}"`).join(', '),
319
+ });
320
+ case 'bounds':
321
+ return this.describeBounds(constraint);
322
+ default:
323
+ return 'unknown constraint';
324
+ }
325
+ }
326
+ describeBounds(constraint) {
327
+ const t = this.translations.constraints.bounds;
328
+ if (constraint.minInclusive !== undefined &&
329
+ constraint.maxInclusive !== undefined) {
330
+ return this.interpolate(t.between, {
331
+ min: constraint.minInclusive,
332
+ max: constraint.maxInclusive,
333
+ });
334
+ }
335
+ if (constraint.minInclusive !== undefined) {
336
+ return this.interpolate(t.atLeast, { min: constraint.minInclusive });
337
+ }
338
+ if (constraint.maxInclusive !== undefined) {
339
+ return this.interpolate(t.atMost, { max: constraint.maxInclusive });
340
+ }
341
+ if (constraint.minExclusive !== undefined) {
342
+ return this.interpolate(t.greaterThan, { min: constraint.minExclusive });
343
+ }
344
+ if (constraint.maxExclusive !== undefined) {
345
+ return this.interpolate(t.lessThan, { max: constraint.maxExclusive });
346
+ }
347
+ return 'any value';
348
+ }
349
+ /**
350
+ * Describe a failure in human-readable form
351
+ */
352
+ describeFailure(result) {
353
+ const t = this.translations.failures;
354
+ if (!result.failure) {
355
+ if (result.actualValue && result.expectedValue) {
356
+ return `${result.actualValue} ≠ ${result.expectedValue}`;
357
+ }
358
+ return t.unknown.replace('{reason}', 'no details');
359
+ }
360
+ const { type, field, actual, expected, context } = result.failure;
361
+ switch (type) {
362
+ // Entity failures
363
+ case 'ENTITY_TYPE_MISMATCH':
364
+ return this.interpolate(t.entityTypeMismatch, {
365
+ actual: actual || '?',
366
+ expected: expected || '?',
367
+ });
368
+ case 'PREDEFINED_TYPE_MISMATCH':
369
+ return this.interpolate(t.predefinedTypeMismatch, {
370
+ actual: actual || '?',
371
+ expected: expected || '?',
372
+ });
373
+ case 'PREDEFINED_TYPE_MISSING':
374
+ return this.interpolate(t.predefinedTypeMissing, {
375
+ expected: expected || '?',
376
+ });
377
+ // Attribute failures
378
+ case 'ATTRIBUTE_MISSING':
379
+ return this.interpolate(t.attributeMissing, {
380
+ name: field || '?',
381
+ });
382
+ case 'ATTRIBUTE_VALUE_MISMATCH':
383
+ return this.interpolate(t.attributeValueMismatch, {
384
+ name: field || '?',
385
+ actual: actual || '?',
386
+ expected: expected || '?',
387
+ });
388
+ case 'ATTRIBUTE_PATTERN_MISMATCH':
389
+ return this.interpolate(t.attributePatternMismatch, {
390
+ name: field || '?',
391
+ actual: actual || '?',
392
+ expected: expected || '?',
393
+ });
394
+ // Property failures
395
+ case 'PSET_MISSING':
396
+ if (context?.availablePsets) {
397
+ return this.interpolate(t.psetMissingAvailable, {
398
+ pset: field || expected || '?',
399
+ available: context.availablePsets,
400
+ });
401
+ }
402
+ return this.interpolate(t.psetMissing, {
403
+ pset: field || expected || '?',
404
+ });
405
+ case 'PROPERTY_MISSING':
406
+ if (context?.availableProperties) {
407
+ return this.interpolate(t.propertyMissingAvailable, {
408
+ property: field || '?',
409
+ pset: context.propertySet || '?',
410
+ available: context.availableProperties,
411
+ });
412
+ }
413
+ return this.interpolate(t.propertyMissing, {
414
+ property: field || '?',
415
+ pset: context?.propertySet || '?',
416
+ });
417
+ case 'PROPERTY_VALUE_MISMATCH':
418
+ return this.interpolate(t.propertyValueMismatch, {
419
+ pset: this.extractPsetFromField(field),
420
+ property: this.extractPropertyFromField(field),
421
+ actual: actual || '?',
422
+ expected: expected || '?',
423
+ });
424
+ case 'PROPERTY_DATATYPE_MISMATCH':
425
+ return this.interpolate(t.propertyDatatypeMismatch, {
426
+ pset: this.extractPsetFromField(field),
427
+ property: this.extractPropertyFromField(field),
428
+ actual: actual || '?',
429
+ expected: expected || '?',
430
+ });
431
+ case 'PROPERTY_OUT_OF_BOUNDS':
432
+ return this.interpolate(t.propertyOutOfBounds, {
433
+ pset: this.extractPsetFromField(field),
434
+ property: this.extractPropertyFromField(field),
435
+ actual: actual || '?',
436
+ expected: expected || '?',
437
+ });
438
+ // Classification failures
439
+ case 'CLASSIFICATION_MISSING':
440
+ return t.classificationMissing;
441
+ case 'CLASSIFICATION_SYSTEM_MISMATCH':
442
+ if (context?.availableSystems) {
443
+ return this.interpolate(t.classificationSystemMissingAvailable, {
444
+ expected: expected || '?',
445
+ available: context.availableSystems,
446
+ });
447
+ }
448
+ return this.interpolate(t.classificationSystemMismatch, {
449
+ actual: actual || '?',
450
+ expected: expected || '?',
451
+ });
452
+ case 'CLASSIFICATION_VALUE_MISMATCH':
453
+ if (context?.availableValues) {
454
+ return this.interpolate(t.classificationValueMissingAvailable, {
455
+ expected: expected || '?',
456
+ available: context.availableValues,
457
+ });
458
+ }
459
+ return this.interpolate(t.classificationValueMismatch, {
460
+ actual: actual || '?',
461
+ expected: expected || '?',
462
+ });
463
+ // Material failures
464
+ case 'MATERIAL_MISSING':
465
+ return t.materialMissing;
466
+ case 'MATERIAL_VALUE_MISMATCH':
467
+ if (context?.availableMaterials) {
468
+ return this.interpolate(t.materialValueMissingAvailable, {
469
+ expected: expected || '?',
470
+ available: context.availableMaterials,
471
+ });
472
+ }
473
+ return this.interpolate(t.materialValueMismatch, {
474
+ actual: actual || '?',
475
+ expected: expected || '?',
476
+ });
477
+ // PartOf failures
478
+ case 'PARTOF_RELATION_MISSING':
479
+ if (context?.entity) {
480
+ return this.interpolate(t.partOfMissing, {
481
+ relation: this.getRelationDescription(field || 'IfcRelContainedInSpatialStructure'),
482
+ entity: context.entity,
483
+ });
484
+ }
485
+ return this.interpolate(t.partOfMissingSimple, {
486
+ relation: this.getRelationDescription(field || 'IfcRelContainedInSpatialStructure'),
487
+ });
488
+ case 'PARTOF_ENTITY_MISMATCH':
489
+ return this.interpolate(t.partOfEntityMismatch, {
490
+ actual: actual || '?',
491
+ expected: expected || '?',
492
+ });
493
+ // Prohibited failures
494
+ case 'PROHIBITED_ATTRIBUTE_EXISTS':
495
+ case 'PROHIBITED_PROPERTY_EXISTS':
496
+ case 'PROHIBITED_CLASSIFICATION_EXISTS':
497
+ case 'PROHIBITED_MATERIAL_EXISTS':
498
+ return this.interpolate(t.prohibited, {
499
+ field: field || 'value',
500
+ actual: actual || '?',
501
+ });
502
+ default:
503
+ return this.interpolate(t.unknown, { reason: type });
504
+ }
505
+ }
506
+ extractPsetFromField(field) {
507
+ if (!field)
508
+ return '?';
509
+ const parts = field.split('.');
510
+ return parts.length > 1 ? parts[0] : '?';
511
+ }
512
+ extractPropertyFromField(field) {
513
+ if (!field)
514
+ return '?';
515
+ const parts = field.split('.');
516
+ return parts.length > 1 ? parts.slice(1).join('.') : field;
517
+ }
518
+ /**
519
+ * Describe a requirement in human-readable form
520
+ */
521
+ describeRequirement(requirement) {
522
+ let description = this.describeFacet(requirement.facet, 'requirement');
523
+ // Apply optionality modifiers
524
+ if (requirement.optionality === 'prohibited') {
525
+ description = this.applyProhibited(description);
526
+ }
527
+ else if (requirement.optionality === 'optional') {
528
+ description = this.applyOptional(description);
529
+ }
530
+ return description;
531
+ }
532
+ applyProhibited(description) {
533
+ // Replace "Must" with "Must NOT" etc.
534
+ return description
535
+ .replace(/^Must be/i, 'Must NOT be')
536
+ .replace(/^Must have/i, 'Must NOT have')
537
+ .replace(/^Muss/i, 'Darf nicht')
538
+ .replace(/^Doit être/i, 'Ne doit pas être')
539
+ .replace(/^Doit avoir/i, 'Ne doit pas avoir');
540
+ }
541
+ applyOptional(description) {
542
+ // Replace "Must" with "Should" etc.
543
+ return description
544
+ .replace(/^Must/i, 'Should')
545
+ .replace(/^Muss/i, 'Sollte')
546
+ .replace(/^Doit/i, 'Devrait');
547
+ }
548
+ /**
549
+ * Get status text
550
+ */
551
+ getStatusText(status) {
552
+ return this.translations.status[status];
553
+ }
554
+ /**
555
+ * Get optionality text
556
+ */
557
+ getOptionalityText(optionality) {
558
+ return this.translations.optionality[optionality];
559
+ }
560
+ /**
561
+ * Get human-readable relationship description
562
+ */
563
+ getRelationDescription(relation) {
564
+ return (this.translations.relations[relation] ||
565
+ relation.replace('IfcRel', '').toLowerCase());
566
+ }
567
+ }
568
+ export { IDSTranslationServiceImpl };
569
+ //# sourceMappingURL=service.js.map