uss-xsd-engine 0.2.1 → 0.2.2

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.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * uss-xsd-engine v0.2.1
2
+ * uss-xsd-engine v0.2.2
3
3
  * (c) 2026 Bernard Mumble
4
4
  * MIT License
5
5
  */
@@ -103,7 +103,9 @@ var ISSUE_CODES = {
103
103
  XSD_INCLUDE_NOT_PROVIDED: "XSD_INCLUDE_NOT_PROVIDED",
104
104
  XSD_IMPORT_NOT_PROVIDED: "XSD_IMPORT_NOT_PROVIDED",
105
105
  XSD_INCLUDE_NAMESPACE_MISMATCH: "XSD_INCLUDE_NAMESPACE_MISMATCH",
106
- XSD_IMPORT_NAMESPACE_MISMATCH: "XSD_IMPORT_NAMESPACE_MISMATCH"
106
+ XSD_IMPORT_NAMESPACE_MISMATCH: "XSD_IMPORT_NAMESPACE_MISMATCH",
107
+ XSD_REDEFINE_NAMESPACE_MISMATCH: "XSD_REDEFINE_NAMESPACE_MISMATCH",
108
+ REDEFINE_INVALID_OVERRIDE: "REDEFINE_INVALID_OVERRIDE"
107
109
  };
108
110
 
109
111
  // src/parser/parseXsd.js
@@ -156,6 +158,7 @@ function createEmptySchemaModel() {
156
158
  targetNamespace: null,
157
159
  elementFormDefault: null,
158
160
  attributeFormDefault: null,
161
+ schemaVersion: null,
159
162
  namespaces: {
160
163
  default: null,
161
164
  prefixes: /* @__PURE__ */ Object.create(null)
@@ -171,7 +174,8 @@ function createEmptySchemaModel() {
171
174
  documents: [],
172
175
  externalRefs: {
173
176
  includes: [],
174
- imports: []
177
+ imports: [],
178
+ redefines: []
175
179
  },
176
180
  importedSchemas: [],
177
181
  roots: [],
@@ -204,6 +208,16 @@ function normalizeUse(value) {
204
208
  }
205
209
  return null;
206
210
  }
211
+ function createAnnotation({
212
+ documentation = null,
213
+ appinfo = null
214
+ } = {}) {
215
+ return {
216
+ kind: "annotation",
217
+ documentation,
218
+ appinfo
219
+ };
220
+ }
207
221
  function createElementDecl({
208
222
  name = null,
209
223
  qName = null,
@@ -217,6 +231,7 @@ function createElementDecl({
217
231
  fixedValue = null,
218
232
  nillable = false,
219
233
  identityConstraints = [],
234
+ annotation = null,
220
235
  line = null,
221
236
  column = null,
222
237
  path = null
@@ -235,6 +250,7 @@ function createElementDecl({
235
250
  fixedValue,
236
251
  nillable,
237
252
  identityConstraints,
253
+ annotation,
238
254
  line,
239
255
  column,
240
256
  path
@@ -250,6 +266,7 @@ function createAttributeDecl({
250
266
  use = null,
251
267
  defaultValue = null,
252
268
  fixedValue = null,
269
+ annotation = null,
253
270
  line = null,
254
271
  column = null,
255
272
  path = null
@@ -265,6 +282,7 @@ function createAttributeDecl({
265
282
  use,
266
283
  defaultValue,
267
284
  fixedValue,
285
+ annotation,
268
286
  line,
269
287
  column,
270
288
  path
@@ -281,6 +299,7 @@ function createComplexTypeDecl({
281
299
  mixed = false,
282
300
  abstract = false,
283
301
  identityConstraints = [],
302
+ annotation = null,
284
303
  line = null,
285
304
  column = null,
286
305
  path = null
@@ -297,6 +316,7 @@ function createComplexTypeDecl({
297
316
  mixed,
298
317
  abstract,
299
318
  identityConstraints,
319
+ annotation,
300
320
  line,
301
321
  column,
302
322
  path
@@ -309,6 +329,7 @@ function createSimpleTypeDecl({
309
329
  baseTypeName = null,
310
330
  facets = {},
311
331
  enumerations = [],
332
+ annotation = null,
312
333
  line = null,
313
334
  column = null,
314
335
  path = null
@@ -321,6 +342,7 @@ function createSimpleTypeDecl({
321
342
  baseTypeName,
322
343
  facets,
323
344
  enumerations,
345
+ annotation,
324
346
  line,
325
347
  column,
326
348
  path
@@ -368,6 +390,7 @@ function createAttributeGroupDecl({
368
390
  }
369
391
  function createAttributeGroupRef({
370
392
  refName,
393
+ use = null,
371
394
  line = null,
372
395
  column = null,
373
396
  path = null
@@ -375,6 +398,7 @@ function createAttributeGroupRef({
375
398
  return {
376
399
  kind: "attributeGroupRef",
377
400
  refName,
401
+ use,
378
402
  line,
379
403
  column,
380
404
  path
@@ -846,7 +870,6 @@ function getEffectiveContent(schema, complexTypeDecl) {
846
870
 
847
871
  // src/parser/buildSchemaModel.js
848
872
  var UNSUPPORTED_NODE_FEATURES = /* @__PURE__ */ new Set([
849
- "redefine",
850
873
  "notation"
851
874
  ]);
852
875
  function elementChildren(node) {
@@ -867,6 +890,8 @@ function recordExternalRef(schema, kind, node, path, loc) {
867
890
  schema.externalRefs.includes.push(entry);
868
891
  } else if (kind === "import") {
869
892
  schema.externalRefs.imports.push(entry);
893
+ } else if (kind === "redefine") {
894
+ schema.externalRefs.redefines.push(entry);
870
895
  }
871
896
  }
872
897
  function mergeGlobalsIntoSchema(targetSchema, sourceSchema, issues, createDuplicateIssue) {
@@ -907,6 +932,9 @@ function mergeGlobalsIntoSchema(targetSchema, sourceSchema, issues, createDuplic
907
932
  targetSchema.externalRefs.imports.push(
908
933
  ...sourceSchema.externalRefs.imports || []
909
934
  );
935
+ targetSchema.externalRefs.redefines.push(
936
+ ...sourceSchema.externalRefs.redefines || []
937
+ );
910
938
  targetSchema.importedSchemas.push(...sourceSchema.importedSchemas || []);
911
939
  targetSchema.identityConstraints.push(
912
940
  ...sourceSchema.identityConstraints || []
@@ -1180,6 +1208,42 @@ function parseFacets(node) {
1180
1208
  }
1181
1209
  return { facets, enumerations };
1182
1210
  }
1211
+ function parseAnnotation(node) {
1212
+ if (!node || node.localName !== "annotation") {
1213
+ return null;
1214
+ }
1215
+ const children = Array.from(node.children || []).filter(
1216
+ (child) => child.nodeType === 1
1217
+ );
1218
+ let documentation = null;
1219
+ let appinfo = null;
1220
+ for (const child of children) {
1221
+ if (child.localName === "documentation") {
1222
+ const lang = child.getAttribute("xml:lang") || null;
1223
+ const source = child.getAttribute("source") || null;
1224
+ const text = (child.textContent || "").trim();
1225
+ documentation = {
1226
+ text,
1227
+ lang,
1228
+ source
1229
+ };
1230
+ } else if (child.localName === "appinfo") {
1231
+ const source = child.getAttribute("source") || null;
1232
+ const text = (child.textContent || "").trim();
1233
+ appinfo = {
1234
+ text,
1235
+ source
1236
+ };
1237
+ }
1238
+ }
1239
+ if (!documentation && !appinfo) {
1240
+ return null;
1241
+ }
1242
+ return createAnnotation({
1243
+ documentation,
1244
+ appinfo
1245
+ });
1246
+ }
1183
1247
  function parseSimpleType(node, xsdText, lineStarts, parentPath, schema, issues) {
1184
1248
  const path = buildPath(parentPath, node);
1185
1249
  const loc = locateNodeInSource(xsdText, lineStarts, node);
@@ -1187,7 +1251,12 @@ function parseSimpleType(node, xsdText, lineStarts, parentPath, schema, issues)
1187
1251
  let baseTypeName = null;
1188
1252
  let facets = {};
1189
1253
  let enumerations = [];
1190
- const restriction = elementChildren(node).find(
1254
+ const children = elementChildren(node);
1255
+ const annotationNode = children.find(
1256
+ (child) => child.localName === "annotation"
1257
+ );
1258
+ const annotation = parseAnnotation(annotationNode);
1259
+ const restriction = children.find(
1191
1260
  (child) => child.localName === "restriction"
1192
1261
  );
1193
1262
  if (restriction) {
@@ -1214,6 +1283,7 @@ function parseSimpleType(node, xsdText, lineStarts, parentPath, schema, issues)
1214
1283
  baseTypeName,
1215
1284
  facets,
1216
1285
  enumerations,
1286
+ annotation,
1217
1287
  line: loc.line,
1218
1288
  column: loc.column,
1219
1289
  path
@@ -1223,7 +1293,12 @@ function parseAttribute(node, xsdText, lineStarts, parentPath, schema, issues) {
1223
1293
  const path = buildPath(parentPath, node);
1224
1294
  const loc = locateNodeInSource(xsdText, lineStarts, node);
1225
1295
  collectNodeDiagnostics(schema, issues, node, path, loc);
1226
- const inlineSimpleTypeNode = elementChildren(node).find(
1296
+ const children = elementChildren(node);
1297
+ const annotationNode = children.find(
1298
+ (child) => child.localName === "annotation"
1299
+ );
1300
+ const annotation = parseAnnotation(annotationNode);
1301
+ const inlineSimpleTypeNode = children.find(
1227
1302
  (child) => child.localName === "simpleType"
1228
1303
  );
1229
1304
  const inlineType = inlineSimpleTypeNode ? parseSimpleType(
@@ -1246,6 +1321,7 @@ function parseAttribute(node, xsdText, lineStarts, parentPath, schema, issues) {
1246
1321
  use: normalizeUse(node.getAttribute("use")),
1247
1322
  defaultValue: node.getAttribute("default"),
1248
1323
  fixedValue: node.getAttribute("fixed"),
1324
+ annotation,
1249
1325
  line: loc.line,
1250
1326
  column: loc.column,
1251
1327
  path
@@ -1257,6 +1333,7 @@ function parseAttributeGroupRef(node, xsdText, lineStarts, parentPath, schema, i
1257
1333
  collectNodeDiagnostics(schema, issues, node, path, loc);
1258
1334
  return createAttributeGroupRef({
1259
1335
  refName: node.getAttribute("ref"),
1336
+ use: normalizeUse(node.getAttribute("use")),
1260
1337
  line: loc.line,
1261
1338
  column: loc.column,
1262
1339
  path
@@ -1294,6 +1371,10 @@ function parseElement(node, xsdText, lineStarts, parentPath, schema, issues) {
1294
1371
  collectNodeDiagnostics(schema, issues, node, path, loc);
1295
1372
  let inlineType = null;
1296
1373
  const children = elementChildren(node);
1374
+ const annotationNode = children.find(
1375
+ (child) => child.localName === "annotation"
1376
+ );
1377
+ const annotation = parseAnnotation(annotationNode);
1297
1378
  const inlineComplexTypeNode = children.find(
1298
1379
  (child) => child.localName === "complexType"
1299
1380
  );
@@ -1349,6 +1430,7 @@ function parseElement(node, xsdText, lineStarts, parentPath, schema, issues) {
1349
1430
  fixedValue: node.getAttribute("fixed"),
1350
1431
  nillable: node.getAttribute("nillable") === "true",
1351
1432
  identityConstraints,
1433
+ annotation,
1352
1434
  line: loc.line,
1353
1435
  column: loc.column,
1354
1436
  path
@@ -1609,6 +1691,10 @@ function parseComplexType(node, xsdText, lineStarts, parentPath, schema, issues)
1609
1691
  let contentModel = "complex";
1610
1692
  const children = elementChildren(node);
1611
1693
  const namespaceUri4 = schema.targetNamespace || null;
1694
+ const annotationNode = children.find(
1695
+ (child) => child.localName === "annotation"
1696
+ );
1697
+ const annotation = parseAnnotation(annotationNode);
1612
1698
  const identityConstraints = children.filter(
1613
1699
  (child) => ["key", "keyref", "unique"].includes(child.localName)
1614
1700
  ).map(
@@ -1694,6 +1780,7 @@ function parseComplexType(node, xsdText, lineStarts, parentPath, schema, issues)
1694
1780
  mixed: node.getAttribute("mixed") === "true",
1695
1781
  abstract: node.getAttribute("abstract") === "true",
1696
1782
  identityConstraints,
1783
+ annotation,
1697
1784
  line: loc.line,
1698
1785
  column: loc.column,
1699
1786
  path
@@ -1763,6 +1850,63 @@ function isImportNamespaceCompatible(ref, importedSchema) {
1763
1850
  }
1764
1851
  return (declaredNs || null) === (importedNs || null);
1765
1852
  }
1853
+ function isRedefineNamespaceCompatible(hostSchema, redefinedSchema) {
1854
+ const hostNs = hostSchema?.targetNamespace || null;
1855
+ const redefinedNs = redefinedSchema?.targetNamespace || null;
1856
+ return hostNs === redefinedNs;
1857
+ }
1858
+ function mergeRedefinesIntoSchema(targetSchema, sourceSchema, issues, createDuplicateIssue) {
1859
+ const buckets = [
1860
+ ["complexTypes", "DUPLICATE_GLOBAL_COMPLEX_TYPE"],
1861
+ ["simpleTypes", "DUPLICATE_GLOBAL_SIMPLE_TYPE"],
1862
+ ["groups", "DUPLICATE_GLOBAL_GROUP"],
1863
+ ["attributeGroups", "DUPLICATE_GLOBAL_ATTRIBUTE_GROUP"]
1864
+ ];
1865
+ for (const [bucketName, _duplicateCode] of buckets) {
1866
+ for (const [key, decl] of Object.entries(
1867
+ sourceSchema.globals[bucketName] || {}
1868
+ )) {
1869
+ if (targetSchema.globals[bucketName][key]) {
1870
+ targetSchema.globals[bucketName][key] = {
1871
+ ...decl,
1872
+ redefined: true,
1873
+ originalDefinition: targetSchema.globals[bucketName][key]
1874
+ };
1875
+ } else {
1876
+ issues.push(
1877
+ createIssue({
1878
+ code: ISSUE_CODES.REDEFINE_INVALID_OVERRIDE,
1879
+ severity: "error",
1880
+ message: `xs:redefine attempts to override ${bucketName.slice(0, -1)} '${decl.name}' which does not exist in the base schema.`,
1881
+ line: decl.line,
1882
+ column: decl.column,
1883
+ path: decl.path,
1884
+ source: "xsd",
1885
+ nodeKind: decl.kind,
1886
+ name: decl.name,
1887
+ details: { declarationName: decl.name }
1888
+ })
1889
+ );
1890
+ }
1891
+ }
1892
+ }
1893
+ targetSchema.references.types.push(...sourceSchema.references.types || []);
1894
+ targetSchema.references.baseTypes.push(
1895
+ ...sourceSchema.references.baseTypes || []
1896
+ );
1897
+ targetSchema.references.groupRefs.push(
1898
+ ...sourceSchema.references.groupRefs || []
1899
+ );
1900
+ targetSchema.references.attributeGroupRefs.push(
1901
+ ...sourceSchema.references.attributeGroupRefs || []
1902
+ );
1903
+ for (const feature of sourceSchema.usedFeatures || []) {
1904
+ targetSchema.usedFeatures.add(feature);
1905
+ }
1906
+ targetSchema.unsupportedFeatures.push(
1907
+ ...sourceSchema.unsupportedFeatures || []
1908
+ );
1909
+ }
1766
1910
  function normalizeSchemaPath(value) {
1767
1911
  if (!value || typeof value !== "string") return null;
1768
1912
  const trimmed = value.trim();
@@ -1888,6 +2032,7 @@ function buildSchemaModel(doc, options = {}) {
1888
2032
  schema.targetNamespace = getEffectiveTargetNamespace(schemaRoot, options);
1889
2033
  schema.elementFormDefault = schemaRoot.getAttribute("elementFormDefault");
1890
2034
  schema.attributeFormDefault = schemaRoot.getAttribute("attributeFormDefault");
2035
+ schema.schemaVersion = schemaRoot.getAttribute("version");
1891
2036
  extractNamespaces(schemaRoot, schema);
1892
2037
  const rootPath = "/schema";
1893
2038
  const rootLoc = locateNodeInSource(xsdText, lineStarts, schemaRoot);
@@ -2040,6 +2185,13 @@ function buildSchemaModel(doc, options = {}) {
2040
2185
  recordExternalRef(schema, "import", child, path, loc);
2041
2186
  break;
2042
2187
  }
2188
+ case "redefine": {
2189
+ const path = buildPath(rootPath, child);
2190
+ const loc = locateNodeInSource(xsdText, lineStarts, child);
2191
+ collectNodeDiagnostics(schema, issues, child, path, loc);
2192
+ recordExternalRef(schema, "redefine", child, path, loc);
2193
+ break;
2194
+ }
2043
2195
  default: {
2044
2196
  const path = buildPath(rootPath, child);
2045
2197
  const loc = locateNodeInSource(xsdText, lineStarts, child);
@@ -2064,7 +2216,8 @@ function buildSchemaModel(doc, options = {}) {
2064
2216
  const visited = options._visitedExternalSchemas || /* @__PURE__ */ new Set();
2065
2217
  const includes = schema.externalRefs.includes || [];
2066
2218
  const imports = schema.externalRefs.imports || [];
2067
- for (const ref of [...includes, ...imports]) {
2219
+ const redefines = schema.externalRefs.redefines || [];
2220
+ for (const ref of [...includes, ...imports, ...redefines]) {
2068
2221
  if (!ref.schemaLocation) continue;
2069
2222
  const resolution = resolveExternalDocument(ref, externalDocuments);
2070
2223
  if (resolution.kind === "ambiguous-namespace") {
@@ -2191,6 +2344,34 @@ function buildSchemaModel(doc, options = {}) {
2191
2344
  } else {
2192
2345
  schema.importedSchemas.push(externalBuild.schema);
2193
2346
  }
2347
+ } else if (ref.kind === "redefine") {
2348
+ if (!isRedefineNamespaceCompatible(schema, externalBuild.schema)) {
2349
+ issues.push(
2350
+ createIssue({
2351
+ code: ISSUE_CODES.XSD_REDEFINE_NAMESPACE_MISMATCH,
2352
+ severity: "error",
2353
+ message: `xs:redefine namespace mismatch. Host targetNamespace is '${schema.targetNamespace || ""}', redefined schema targetNamespace is '${externalBuild.schema.targetNamespace || ""}'.`,
2354
+ line: ref.line,
2355
+ column: ref.column,
2356
+ path: ref.path,
2357
+ source: "xsd",
2358
+ nodeKind: "redefine",
2359
+ details: {
2360
+ schemaLocation: ref.schemaLocation,
2361
+ resolvedSchemaKey,
2362
+ hostTargetNamespace: schema.targetNamespace || null,
2363
+ redefinedTargetNamespace: externalBuild.schema.targetNamespace || null
2364
+ }
2365
+ })
2366
+ );
2367
+ } else {
2368
+ mergeRedefinesIntoSchema(
2369
+ schema,
2370
+ externalBuild.schema,
2371
+ issues,
2372
+ createDuplicateIssue
2373
+ );
2374
+ }
2194
2375
  }
2195
2376
  }
2196
2377
  issues.push(...externalBuild.issues || []);
@@ -3245,7 +3426,7 @@ function runSchemaDiagnostics(schema, options = {}) {
3245
3426
  }
3246
3427
 
3247
3428
  // src/version.js
3248
- var ENGINE_VERSION = "v0.2.1";
3429
+ var ENGINE_VERSION = "v0.2.2";
3249
3430
 
3250
3431
  // src/utils/result.js
3251
3432
  function summarizeIssues(issues = []) {
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * uss-xsd-engine v0.2.1
2
+ * uss-xsd-engine v0.2.2
3
3
  * (c) 2026 Bernard Mumble
4
4
  * MIT License
5
5
  */
@@ -130,7 +130,9 @@ var UssXsdEngine = (() => {
130
130
  XSD_INCLUDE_NOT_PROVIDED: "XSD_INCLUDE_NOT_PROVIDED",
131
131
  XSD_IMPORT_NOT_PROVIDED: "XSD_IMPORT_NOT_PROVIDED",
132
132
  XSD_INCLUDE_NAMESPACE_MISMATCH: "XSD_INCLUDE_NAMESPACE_MISMATCH",
133
- XSD_IMPORT_NAMESPACE_MISMATCH: "XSD_IMPORT_NAMESPACE_MISMATCH"
133
+ XSD_IMPORT_NAMESPACE_MISMATCH: "XSD_IMPORT_NAMESPACE_MISMATCH",
134
+ XSD_REDEFINE_NAMESPACE_MISMATCH: "XSD_REDEFINE_NAMESPACE_MISMATCH",
135
+ REDEFINE_INVALID_OVERRIDE: "REDEFINE_INVALID_OVERRIDE"
134
136
  };
135
137
 
136
138
  // src/parser/parseXsd.js
@@ -183,6 +185,7 @@ var UssXsdEngine = (() => {
183
185
  targetNamespace: null,
184
186
  elementFormDefault: null,
185
187
  attributeFormDefault: null,
188
+ schemaVersion: null,
186
189
  namespaces: {
187
190
  default: null,
188
191
  prefixes: /* @__PURE__ */ Object.create(null)
@@ -198,7 +201,8 @@ var UssXsdEngine = (() => {
198
201
  documents: [],
199
202
  externalRefs: {
200
203
  includes: [],
201
- imports: []
204
+ imports: [],
205
+ redefines: []
202
206
  },
203
207
  importedSchemas: [],
204
208
  roots: [],
@@ -231,6 +235,16 @@ var UssXsdEngine = (() => {
231
235
  }
232
236
  return null;
233
237
  }
238
+ function createAnnotation({
239
+ documentation = null,
240
+ appinfo = null
241
+ } = {}) {
242
+ return {
243
+ kind: "annotation",
244
+ documentation,
245
+ appinfo
246
+ };
247
+ }
234
248
  function createElementDecl({
235
249
  name = null,
236
250
  qName = null,
@@ -244,6 +258,7 @@ var UssXsdEngine = (() => {
244
258
  fixedValue = null,
245
259
  nillable = false,
246
260
  identityConstraints = [],
261
+ annotation = null,
247
262
  line = null,
248
263
  column = null,
249
264
  path = null
@@ -262,6 +277,7 @@ var UssXsdEngine = (() => {
262
277
  fixedValue,
263
278
  nillable,
264
279
  identityConstraints,
280
+ annotation,
265
281
  line,
266
282
  column,
267
283
  path
@@ -277,6 +293,7 @@ var UssXsdEngine = (() => {
277
293
  use = null,
278
294
  defaultValue = null,
279
295
  fixedValue = null,
296
+ annotation = null,
280
297
  line = null,
281
298
  column = null,
282
299
  path = null
@@ -292,6 +309,7 @@ var UssXsdEngine = (() => {
292
309
  use,
293
310
  defaultValue,
294
311
  fixedValue,
312
+ annotation,
295
313
  line,
296
314
  column,
297
315
  path
@@ -308,6 +326,7 @@ var UssXsdEngine = (() => {
308
326
  mixed = false,
309
327
  abstract = false,
310
328
  identityConstraints = [],
329
+ annotation = null,
311
330
  line = null,
312
331
  column = null,
313
332
  path = null
@@ -324,6 +343,7 @@ var UssXsdEngine = (() => {
324
343
  mixed,
325
344
  abstract,
326
345
  identityConstraints,
346
+ annotation,
327
347
  line,
328
348
  column,
329
349
  path
@@ -336,6 +356,7 @@ var UssXsdEngine = (() => {
336
356
  baseTypeName = null,
337
357
  facets = {},
338
358
  enumerations = [],
359
+ annotation = null,
339
360
  line = null,
340
361
  column = null,
341
362
  path = null
@@ -348,6 +369,7 @@ var UssXsdEngine = (() => {
348
369
  baseTypeName,
349
370
  facets,
350
371
  enumerations,
372
+ annotation,
351
373
  line,
352
374
  column,
353
375
  path
@@ -395,6 +417,7 @@ var UssXsdEngine = (() => {
395
417
  }
396
418
  function createAttributeGroupRef({
397
419
  refName,
420
+ use = null,
398
421
  line = null,
399
422
  column = null,
400
423
  path = null
@@ -402,6 +425,7 @@ var UssXsdEngine = (() => {
402
425
  return {
403
426
  kind: "attributeGroupRef",
404
427
  refName,
428
+ use,
405
429
  line,
406
430
  column,
407
431
  path
@@ -873,7 +897,6 @@ var UssXsdEngine = (() => {
873
897
 
874
898
  // src/parser/buildSchemaModel.js
875
899
  var UNSUPPORTED_NODE_FEATURES = /* @__PURE__ */ new Set([
876
- "redefine",
877
900
  "notation"
878
901
  ]);
879
902
  function elementChildren(node) {
@@ -894,6 +917,8 @@ var UssXsdEngine = (() => {
894
917
  schema.externalRefs.includes.push(entry);
895
918
  } else if (kind === "import") {
896
919
  schema.externalRefs.imports.push(entry);
920
+ } else if (kind === "redefine") {
921
+ schema.externalRefs.redefines.push(entry);
897
922
  }
898
923
  }
899
924
  function mergeGlobalsIntoSchema(targetSchema, sourceSchema, issues, createDuplicateIssue) {
@@ -934,6 +959,9 @@ var UssXsdEngine = (() => {
934
959
  targetSchema.externalRefs.imports.push(
935
960
  ...sourceSchema.externalRefs.imports || []
936
961
  );
962
+ targetSchema.externalRefs.redefines.push(
963
+ ...sourceSchema.externalRefs.redefines || []
964
+ );
937
965
  targetSchema.importedSchemas.push(...sourceSchema.importedSchemas || []);
938
966
  targetSchema.identityConstraints.push(
939
967
  ...sourceSchema.identityConstraints || []
@@ -1207,6 +1235,42 @@ var UssXsdEngine = (() => {
1207
1235
  }
1208
1236
  return { facets, enumerations };
1209
1237
  }
1238
+ function parseAnnotation(node) {
1239
+ if (!node || node.localName !== "annotation") {
1240
+ return null;
1241
+ }
1242
+ const children = Array.from(node.children || []).filter(
1243
+ (child) => child.nodeType === 1
1244
+ );
1245
+ let documentation = null;
1246
+ let appinfo = null;
1247
+ for (const child of children) {
1248
+ if (child.localName === "documentation") {
1249
+ const lang = child.getAttribute("xml:lang") || null;
1250
+ const source = child.getAttribute("source") || null;
1251
+ const text = (child.textContent || "").trim();
1252
+ documentation = {
1253
+ text,
1254
+ lang,
1255
+ source
1256
+ };
1257
+ } else if (child.localName === "appinfo") {
1258
+ const source = child.getAttribute("source") || null;
1259
+ const text = (child.textContent || "").trim();
1260
+ appinfo = {
1261
+ text,
1262
+ source
1263
+ };
1264
+ }
1265
+ }
1266
+ if (!documentation && !appinfo) {
1267
+ return null;
1268
+ }
1269
+ return createAnnotation({
1270
+ documentation,
1271
+ appinfo
1272
+ });
1273
+ }
1210
1274
  function parseSimpleType(node, xsdText, lineStarts, parentPath, schema, issues) {
1211
1275
  const path = buildPath(parentPath, node);
1212
1276
  const loc = locateNodeInSource(xsdText, lineStarts, node);
@@ -1214,7 +1278,12 @@ var UssXsdEngine = (() => {
1214
1278
  let baseTypeName = null;
1215
1279
  let facets = {};
1216
1280
  let enumerations = [];
1217
- const restriction = elementChildren(node).find(
1281
+ const children = elementChildren(node);
1282
+ const annotationNode = children.find(
1283
+ (child) => child.localName === "annotation"
1284
+ );
1285
+ const annotation = parseAnnotation(annotationNode);
1286
+ const restriction = children.find(
1218
1287
  (child) => child.localName === "restriction"
1219
1288
  );
1220
1289
  if (restriction) {
@@ -1241,6 +1310,7 @@ var UssXsdEngine = (() => {
1241
1310
  baseTypeName,
1242
1311
  facets,
1243
1312
  enumerations,
1313
+ annotation,
1244
1314
  line: loc.line,
1245
1315
  column: loc.column,
1246
1316
  path
@@ -1250,7 +1320,12 @@ var UssXsdEngine = (() => {
1250
1320
  const path = buildPath(parentPath, node);
1251
1321
  const loc = locateNodeInSource(xsdText, lineStarts, node);
1252
1322
  collectNodeDiagnostics(schema, issues, node, path, loc);
1253
- const inlineSimpleTypeNode = elementChildren(node).find(
1323
+ const children = elementChildren(node);
1324
+ const annotationNode = children.find(
1325
+ (child) => child.localName === "annotation"
1326
+ );
1327
+ const annotation = parseAnnotation(annotationNode);
1328
+ const inlineSimpleTypeNode = children.find(
1254
1329
  (child) => child.localName === "simpleType"
1255
1330
  );
1256
1331
  const inlineType = inlineSimpleTypeNode ? parseSimpleType(
@@ -1273,6 +1348,7 @@ var UssXsdEngine = (() => {
1273
1348
  use: normalizeUse(node.getAttribute("use")),
1274
1349
  defaultValue: node.getAttribute("default"),
1275
1350
  fixedValue: node.getAttribute("fixed"),
1351
+ annotation,
1276
1352
  line: loc.line,
1277
1353
  column: loc.column,
1278
1354
  path
@@ -1284,6 +1360,7 @@ var UssXsdEngine = (() => {
1284
1360
  collectNodeDiagnostics(schema, issues, node, path, loc);
1285
1361
  return createAttributeGroupRef({
1286
1362
  refName: node.getAttribute("ref"),
1363
+ use: normalizeUse(node.getAttribute("use")),
1287
1364
  line: loc.line,
1288
1365
  column: loc.column,
1289
1366
  path
@@ -1321,6 +1398,10 @@ var UssXsdEngine = (() => {
1321
1398
  collectNodeDiagnostics(schema, issues, node, path, loc);
1322
1399
  let inlineType = null;
1323
1400
  const children = elementChildren(node);
1401
+ const annotationNode = children.find(
1402
+ (child) => child.localName === "annotation"
1403
+ );
1404
+ const annotation = parseAnnotation(annotationNode);
1324
1405
  const inlineComplexTypeNode = children.find(
1325
1406
  (child) => child.localName === "complexType"
1326
1407
  );
@@ -1376,6 +1457,7 @@ var UssXsdEngine = (() => {
1376
1457
  fixedValue: node.getAttribute("fixed"),
1377
1458
  nillable: node.getAttribute("nillable") === "true",
1378
1459
  identityConstraints,
1460
+ annotation,
1379
1461
  line: loc.line,
1380
1462
  column: loc.column,
1381
1463
  path
@@ -1636,6 +1718,10 @@ var UssXsdEngine = (() => {
1636
1718
  let contentModel = "complex";
1637
1719
  const children = elementChildren(node);
1638
1720
  const namespaceUri4 = schema.targetNamespace || null;
1721
+ const annotationNode = children.find(
1722
+ (child) => child.localName === "annotation"
1723
+ );
1724
+ const annotation = parseAnnotation(annotationNode);
1639
1725
  const identityConstraints = children.filter(
1640
1726
  (child) => ["key", "keyref", "unique"].includes(child.localName)
1641
1727
  ).map(
@@ -1721,6 +1807,7 @@ var UssXsdEngine = (() => {
1721
1807
  mixed: node.getAttribute("mixed") === "true",
1722
1808
  abstract: node.getAttribute("abstract") === "true",
1723
1809
  identityConstraints,
1810
+ annotation,
1724
1811
  line: loc.line,
1725
1812
  column: loc.column,
1726
1813
  path
@@ -1790,6 +1877,63 @@ var UssXsdEngine = (() => {
1790
1877
  }
1791
1878
  return (declaredNs || null) === (importedNs || null);
1792
1879
  }
1880
+ function isRedefineNamespaceCompatible(hostSchema, redefinedSchema) {
1881
+ const hostNs = hostSchema?.targetNamespace || null;
1882
+ const redefinedNs = redefinedSchema?.targetNamespace || null;
1883
+ return hostNs === redefinedNs;
1884
+ }
1885
+ function mergeRedefinesIntoSchema(targetSchema, sourceSchema, issues, createDuplicateIssue) {
1886
+ const buckets = [
1887
+ ["complexTypes", "DUPLICATE_GLOBAL_COMPLEX_TYPE"],
1888
+ ["simpleTypes", "DUPLICATE_GLOBAL_SIMPLE_TYPE"],
1889
+ ["groups", "DUPLICATE_GLOBAL_GROUP"],
1890
+ ["attributeGroups", "DUPLICATE_GLOBAL_ATTRIBUTE_GROUP"]
1891
+ ];
1892
+ for (const [bucketName, _duplicateCode] of buckets) {
1893
+ for (const [key, decl] of Object.entries(
1894
+ sourceSchema.globals[bucketName] || {}
1895
+ )) {
1896
+ if (targetSchema.globals[bucketName][key]) {
1897
+ targetSchema.globals[bucketName][key] = {
1898
+ ...decl,
1899
+ redefined: true,
1900
+ originalDefinition: targetSchema.globals[bucketName][key]
1901
+ };
1902
+ } else {
1903
+ issues.push(
1904
+ createIssue({
1905
+ code: ISSUE_CODES.REDEFINE_INVALID_OVERRIDE,
1906
+ severity: "error",
1907
+ message: `xs:redefine attempts to override ${bucketName.slice(0, -1)} '${decl.name}' which does not exist in the base schema.`,
1908
+ line: decl.line,
1909
+ column: decl.column,
1910
+ path: decl.path,
1911
+ source: "xsd",
1912
+ nodeKind: decl.kind,
1913
+ name: decl.name,
1914
+ details: { declarationName: decl.name }
1915
+ })
1916
+ );
1917
+ }
1918
+ }
1919
+ }
1920
+ targetSchema.references.types.push(...sourceSchema.references.types || []);
1921
+ targetSchema.references.baseTypes.push(
1922
+ ...sourceSchema.references.baseTypes || []
1923
+ );
1924
+ targetSchema.references.groupRefs.push(
1925
+ ...sourceSchema.references.groupRefs || []
1926
+ );
1927
+ targetSchema.references.attributeGroupRefs.push(
1928
+ ...sourceSchema.references.attributeGroupRefs || []
1929
+ );
1930
+ for (const feature of sourceSchema.usedFeatures || []) {
1931
+ targetSchema.usedFeatures.add(feature);
1932
+ }
1933
+ targetSchema.unsupportedFeatures.push(
1934
+ ...sourceSchema.unsupportedFeatures || []
1935
+ );
1936
+ }
1793
1937
  function normalizeSchemaPath(value) {
1794
1938
  if (!value || typeof value !== "string") return null;
1795
1939
  const trimmed = value.trim();
@@ -1915,6 +2059,7 @@ var UssXsdEngine = (() => {
1915
2059
  schema.targetNamespace = getEffectiveTargetNamespace(schemaRoot, options);
1916
2060
  schema.elementFormDefault = schemaRoot.getAttribute("elementFormDefault");
1917
2061
  schema.attributeFormDefault = schemaRoot.getAttribute("attributeFormDefault");
2062
+ schema.schemaVersion = schemaRoot.getAttribute("version");
1918
2063
  extractNamespaces(schemaRoot, schema);
1919
2064
  const rootPath = "/schema";
1920
2065
  const rootLoc = locateNodeInSource(xsdText, lineStarts, schemaRoot);
@@ -2067,6 +2212,13 @@ var UssXsdEngine = (() => {
2067
2212
  recordExternalRef(schema, "import", child, path, loc);
2068
2213
  break;
2069
2214
  }
2215
+ case "redefine": {
2216
+ const path = buildPath(rootPath, child);
2217
+ const loc = locateNodeInSource(xsdText, lineStarts, child);
2218
+ collectNodeDiagnostics(schema, issues, child, path, loc);
2219
+ recordExternalRef(schema, "redefine", child, path, loc);
2220
+ break;
2221
+ }
2070
2222
  default: {
2071
2223
  const path = buildPath(rootPath, child);
2072
2224
  const loc = locateNodeInSource(xsdText, lineStarts, child);
@@ -2091,7 +2243,8 @@ var UssXsdEngine = (() => {
2091
2243
  const visited = options._visitedExternalSchemas || /* @__PURE__ */ new Set();
2092
2244
  const includes = schema.externalRefs.includes || [];
2093
2245
  const imports = schema.externalRefs.imports || [];
2094
- for (const ref of [...includes, ...imports]) {
2246
+ const redefines = schema.externalRefs.redefines || [];
2247
+ for (const ref of [...includes, ...imports, ...redefines]) {
2095
2248
  if (!ref.schemaLocation) continue;
2096
2249
  const resolution = resolveExternalDocument(ref, externalDocuments);
2097
2250
  if (resolution.kind === "ambiguous-namespace") {
@@ -2218,6 +2371,34 @@ var UssXsdEngine = (() => {
2218
2371
  } else {
2219
2372
  schema.importedSchemas.push(externalBuild.schema);
2220
2373
  }
2374
+ } else if (ref.kind === "redefine") {
2375
+ if (!isRedefineNamespaceCompatible(schema, externalBuild.schema)) {
2376
+ issues.push(
2377
+ createIssue({
2378
+ code: ISSUE_CODES.XSD_REDEFINE_NAMESPACE_MISMATCH,
2379
+ severity: "error",
2380
+ message: `xs:redefine namespace mismatch. Host targetNamespace is '${schema.targetNamespace || ""}', redefined schema targetNamespace is '${externalBuild.schema.targetNamespace || ""}'.`,
2381
+ line: ref.line,
2382
+ column: ref.column,
2383
+ path: ref.path,
2384
+ source: "xsd",
2385
+ nodeKind: "redefine",
2386
+ details: {
2387
+ schemaLocation: ref.schemaLocation,
2388
+ resolvedSchemaKey,
2389
+ hostTargetNamespace: schema.targetNamespace || null,
2390
+ redefinedTargetNamespace: externalBuild.schema.targetNamespace || null
2391
+ }
2392
+ })
2393
+ );
2394
+ } else {
2395
+ mergeRedefinesIntoSchema(
2396
+ schema,
2397
+ externalBuild.schema,
2398
+ issues,
2399
+ createDuplicateIssue
2400
+ );
2401
+ }
2221
2402
  }
2222
2403
  }
2223
2404
  issues.push(...externalBuild.issues || []);
@@ -3272,7 +3453,7 @@ var UssXsdEngine = (() => {
3272
3453
  }
3273
3454
 
3274
3455
  // src/version.js
3275
- var ENGINE_VERSION = "v0.2.1";
3456
+ var ENGINE_VERSION = "v0.2.2";
3276
3457
 
3277
3458
  // src/utils/result.js
3278
3459
  function summarizeIssues(issues = []) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uss-xsd-engine",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
4
4
  "description": "Browser-first XSD engine for schema diagnostics, tree extraction, sample XML generation, and XML validation.",
5
5
  "type": "module",
6
6
  "main": "dist/uss-xsd-engine.esm.js",