uss-xsd-engine 0.1.0-beta.5 → 0.1.0-rc.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.
package/README.md CHANGED
@@ -5,6 +5,9 @@ Browser-first XSD engine for schema diagnostics, tree extraction, sample XML gen
5
5
  ---
6
6
 
7
7
  ![npm](https://img.shields.io/npm/v/uss-xsd-engine)
8
+ ![dw](https://img.shields.io/npm/dw/uss-xsd-engine)
9
+ ![dm](https://img.shields.io/npm/dm/uss-xsd-engine)
10
+ ![dy](https://img.shields.io/npm/dy/uss-xsd-engine)
8
11
  [![Jsdelivr](https://data.jsdelivr.com/v1/package/npm/uss-xsd-engine/badge)](https://www.jsdelivr.com/package/npm/uss-xsd-engine)
9
12
 
10
13
  ---
@@ -102,11 +105,11 @@ console.log(result.issues);
102
105
  ### CDN/Browser
103
106
 
104
107
  ```HTML
105
- <script src="https://unpkg.com/uss-xsd-engine@0.1.0-beta.5/dist/uss-xsd-engine.standalone.js"></script>
108
+ <script src="https://unpkg.com/uss-xsd-engine@latest/dist/uss-xsd-engine.standalone.js"></script>
106
109
 
107
110
  or
108
111
 
109
- <script src="https://cdn.jsdelivr.net/npm/uss-xsd-engine@0.1.0-beta.5/dist/uss-xsd-engine.esm.min.js"></script>
112
+ <script src="https://cdn.jsdelivr.net/npm/uss-xsd-engine@latest/dist/uss-xsd-engine.esm.min.js"></script>
110
113
 
111
114
  <script>
112
115
  const result = UssXsdEngine.getSchemaDiagnostics({ xsdText });
@@ -299,38 +302,64 @@ Use **uss-xsd-engine** if you need:
299
302
  ---
300
303
 
301
304
  ## ⚠️ Supported vs Not Fully Supported
302
- ### ✅ Supported (v0.1.x)
303
- - Most common XSD structures
304
- - Namespace-aware resolution
305
+ ### ✅ Supported (v0.1.x / RC)
306
+ - XSD parsing into an internal schema model
307
+ - Namespace-aware resolution (elements, types, attributes, groups)
305
308
  - Extensions (`xs:extension`)
306
- - Restrictions (subset + occurrence checks)
307
- - Facet validation (including pattern)
308
- - Default / fixed semantics
309
- - Include/import (manual provision with recursive resolution)
310
- - Sample XML generation (namespace-aware, multi-schema support)
311
- - XML validation (structure, facets, and source-mapped diagnostics)
309
+ - Restrictions (subset enforcement, occurrence narrowing, attribute constraints)
310
+ - Facet validation:
311
+ - length, numeric, pattern, enumeration, digits
312
+ - Default / fixed semantics (schema + XML validation)
313
+ - Include/import:
314
+ - manual provision via `externalDocuments`
315
+ - recursive resolution
316
+ - strict namespace enforcement
317
+ - Chameleon includes (namespace adoption for no-targetNamespace schemas)
318
+ - Namespace-aware sample XML generation:
319
+ - minimal + representative modes
320
+ - pattern-aware generation (e.g., UETR, BIC)
321
+ - XML validation:
322
+ - structural validation (sequence, choice, all, groups)
323
+ - simpleContent + complexContent enforcement
324
+ - mixed content handling
325
+ - restriction validation (pass 2)
326
+ - Root and nested `simpleContent` validation alignment
312
327
  - XML parse diagnostics with line/column support
313
- - Semantic validation diagnostics with line/column support
314
- - Attribute and value-level source mapping
328
+ - Semantic XML diagnostics with line/column support
329
+ - Attribute, value, and text source mapping
315
330
  - Namespace-aware schema tree extraction
331
+ - Imported schema isolation with namespace-safe lookup
332
+ - QName resolution:
333
+ - prefixed + default namespace handling
334
+ - no cross-namespace leakage
316
335
 
317
336
  ---
318
337
 
319
338
  ## ⚠️ Partially Supported / In Progress
320
- - Deep sample XML expansion (choice branching, recursion depth)
321
- - Full restriction theorem validation (advanced edge cases)
322
- - Advanced Namespace handling (prefix customizatioon, default namespace strategies)
323
- - Advanced wildcard (`xs:any`, `xs:anyAttribute`)
324
- - Attribute namespace qualification
339
+ - Deep sample XML expansion:
340
+ - complex choice branching
341
+ - recursion depth control
342
+ - Full restriction theorem validation:
343
+ - advanced edge cases (beyond practical subset checks)
344
+ - Advanced wildcard handling:
345
+ - `xs:any`
346
+ - `xs:anyAttribute`
347
+ - Attribute namespace qualification edge cases
325
348
 
326
349
  ---
327
350
 
328
351
  ## ❌ Not Supported Yet
329
- - Identity constraints (`xs:key`, `xs:keyref`, `xs:unique`)
352
+ - Identity constraints:
353
+ - `xs:key`
354
+ - `xs:keyref`
355
+ - `xs:unique`
356
+ - `xs:redefine`
330
357
  - Automatic network fetching of schemas
331
- - Full W3C spec conformance (edge-case completeness)
332
- - Streaming validation for very large XML
333
- - Chameleon includes (namespace adaptation)
358
+ - (engine is intentionally browser-first and caller-driven)
359
+ - Full W3C spec completeness
360
+ - (focus is practical + real-world coverage)
361
+ - Streaming / incremental validation for very large XML
362
+
334
363
 
335
364
  ---
336
365
 
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * uss-xsd-engine v0.1.0-beta.5
2
+ * uss-xsd-engine v0.1.0-rc.2
3
3
  * (c) 2026 Bernard Mumble
4
4
  * MIT License
5
5
  */
@@ -60,6 +60,7 @@ var ISSUE_CODES = {
60
60
  XML_INVALID_TEXT_FOR_COMPLEX_TYPE: "XML_INVALID_TEXT_FOR_COMPLEX_TYPE",
61
61
  XML_VALUE_INVALID: "XML_VALUE_INVALID",
62
62
  XML_ENUMERATION_MISMATCH: "XML_ENUMERATION_MISMATCH",
63
+ XML_VALUE_REQUIRED: "XML_VALUE_REQUIRED",
63
64
  XML_PATTERN_MISMATCH: "XML_PATTERN_MISMATCH",
64
65
  XML_LENGTH_MISMATCH: "XML_LENGTH_MISMATCH",
65
66
  XML_MIN_LENGTH_VIOLATION: "XML_MIN_LENGTH_VIOLATION",
@@ -1523,7 +1524,7 @@ function parseAttributeGroup(node, xsdText, lineStarts, parentPath, schema, issu
1523
1524
  });
1524
1525
  }
1525
1526
  function getEffectiveTargetNamespace(schemaRoot, options = {}) {
1526
- if (Object.prototype.hasOwnProperty.call(options, "_overrideTargetNamespace")) {
1527
+ if (Object.prototype.hasOwnProperty.call(options, "_overrideTargetNamespace") && options._overrideTargetNamespace !== void 0) {
1527
1528
  return options._overrideTargetNamespace;
1528
1529
  }
1529
1530
  return schemaRoot.getAttribute("targetNamespace");
@@ -1534,12 +1535,12 @@ function isIncludeNamespaceCompatible(hostSchema, includedSchema) {
1534
1535
  return hostNs === includedNs;
1535
1536
  }
1536
1537
  function isImportNamespaceCompatible(ref, importedSchema) {
1537
- const declaredNs = ref?.namespace || null;
1538
- const importedNs = importedSchema?.targetNamespace || null;
1538
+ const declaredNs = ref && Object.prototype.hasOwnProperty.call(ref, "namespace") ? ref.namespace : null;
1539
+ const importedNs = importedSchema && Object.prototype.hasOwnProperty.call(importedSchema, "targetNamespace") ? importedSchema.targetNamespace : null;
1539
1540
  if (!declaredNs) {
1540
1541
  return true;
1541
1542
  }
1542
- return declaredNs === importedNs;
1543
+ return (declaredNs || null) === (importedNs || null);
1543
1544
  }
1544
1545
  function buildSchemaModel(doc, options = {}) {
1545
1546
  const issues = [];
@@ -1774,16 +1775,21 @@ function buildSchemaModel(doc, options = {}) {
1774
1775
  continue;
1775
1776
  }
1776
1777
  const externalRoot = getSchemaRoot(externalDoc);
1777
- const externalDeclaredTargetNamespace = externalRoot?.getAttribute("targetNamespace") || null;
1778
- const shouldApplyChameleonInclude = ref.kind === "include" && (schema.targetNamespace || null) !== null && externalDeclaredTargetNamespace === null;
1778
+ const externalDeclaredTargetNamespace = externalRoot?.hasAttribute(
1779
+ "targetNamespace"
1780
+ ) ? externalRoot.getAttribute("targetNamespace") : null;
1781
+ const shouldApplyChameleonInclude = ref.kind === "include" && externalDeclaredTargetNamespace === null;
1779
1782
  const externalBuild = buildSchemaModel(externalDoc, {
1780
1783
  ...options,
1781
1784
  xsdText: externalXsdText,
1782
1785
  externalDocuments,
1783
1786
  _visitedExternalSchemas: visited,
1784
- _overrideTargetNamespace: shouldApplyChameleonInclude ? schema.targetNamespace : void 0
1787
+ ...shouldApplyChameleonInclude ? { _overrideTargetNamespace: schema.targetNamespace } : {}
1785
1788
  });
1786
1789
  if (externalBuild.schema) {
1790
+ if (ref.kind === "import") {
1791
+ schema.importedSchemas.push(externalBuild.schema);
1792
+ }
1787
1793
  if (ref.kind === "include") {
1788
1794
  if (!isIncludeNamespaceCompatible(schema, externalBuild.schema)) {
1789
1795
  issues.push(
@@ -2400,6 +2406,9 @@ function runSchemaDiagnostics(schema, options = {}) {
2400
2406
  };
2401
2407
  }
2402
2408
 
2409
+ // src/version.js
2410
+ var ENGINE_VERSION = "v0.1.0-rc.2";
2411
+
2403
2412
  // src/utils/result.js
2404
2413
  function summarizeIssues(issues = []) {
2405
2414
  return issues.reduce(
@@ -2420,7 +2429,8 @@ function makeResult({ data = null, issues = [] } = {}) {
2420
2429
  ok: !hasErrors(issues),
2421
2430
  data,
2422
2431
  issues,
2423
- summary: summarizeIssues(issues)
2432
+ summary: summarizeIssues(issues),
2433
+ version: ENGINE_VERSION
2424
2434
  };
2425
2435
  }
2426
2436
 
@@ -4805,6 +4815,27 @@ function validateXmlAgainstSchema(schema, xmlText, options = {}, helpers = {}) {
4805
4815
  const isSimpleContent = resolvedRootType?.contentModel === "simple" && resolvedRootType?.derivation?.baseTypeName;
4806
4816
  if (isSimpleContent) {
4807
4817
  const textValue = (xmlRoot.textContent || "").trim();
4818
+ const children2 = elementChildren3(xmlRoot);
4819
+ if (children2.length > 0) {
4820
+ for (const childNode of children2) {
4821
+ const childName = localName2(childNode);
4822
+ issues.push(
4823
+ createIssue({
4824
+ code: ISSUE_CODES.XML_UNEXPECTED_ELEMENT,
4825
+ severity: "error",
4826
+ message: `Unexpected element '${childName}'.`,
4827
+ ...toLocationFields(locator.getNodeLocation(childNode)),
4828
+ path: `/${xmlRootName}/${childName}`,
4829
+ source: "xml",
4830
+ nodeKind: "element",
4831
+ name: childName,
4832
+ details: {
4833
+ namespaceUri: namespaceUri2(childNode)
4834
+ }
4835
+ })
4836
+ );
4837
+ }
4838
+ }
4808
4839
  if (!textValue) {
4809
4840
  issues.push(
4810
4841
  createIssue({
@@ -4822,10 +4853,6 @@ function validateXmlAgainstSchema(schema, xmlText, options = {}, helpers = {}) {
4822
4853
  })
4823
4854
  );
4824
4855
  } else {
4825
- const baseType = resolveType(
4826
- schema,
4827
- resolvedRootType.derivation.baseTypeName
4828
- );
4829
4856
  const valueResult = validateElementValue(
4830
4857
  schema,
4831
4858
  { ...schemaRoot, typeName: resolvedRootType.derivation.baseTypeName },
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * uss-xsd-engine v0.1.0-beta.5
2
+ * uss-xsd-engine v0.1.0-rc.2
3
3
  * (c) 2026 Bernard Mumble
4
4
  * MIT License
5
5
  */
@@ -87,6 +87,7 @@ var UssXsdEngine = (() => {
87
87
  XML_INVALID_TEXT_FOR_COMPLEX_TYPE: "XML_INVALID_TEXT_FOR_COMPLEX_TYPE",
88
88
  XML_VALUE_INVALID: "XML_VALUE_INVALID",
89
89
  XML_ENUMERATION_MISMATCH: "XML_ENUMERATION_MISMATCH",
90
+ XML_VALUE_REQUIRED: "XML_VALUE_REQUIRED",
90
91
  XML_PATTERN_MISMATCH: "XML_PATTERN_MISMATCH",
91
92
  XML_LENGTH_MISMATCH: "XML_LENGTH_MISMATCH",
92
93
  XML_MIN_LENGTH_VIOLATION: "XML_MIN_LENGTH_VIOLATION",
@@ -1550,7 +1551,7 @@ var UssXsdEngine = (() => {
1550
1551
  });
1551
1552
  }
1552
1553
  function getEffectiveTargetNamespace(schemaRoot, options = {}) {
1553
- if (Object.prototype.hasOwnProperty.call(options, "_overrideTargetNamespace")) {
1554
+ if (Object.prototype.hasOwnProperty.call(options, "_overrideTargetNamespace") && options._overrideTargetNamespace !== void 0) {
1554
1555
  return options._overrideTargetNamespace;
1555
1556
  }
1556
1557
  return schemaRoot.getAttribute("targetNamespace");
@@ -1561,12 +1562,12 @@ var UssXsdEngine = (() => {
1561
1562
  return hostNs === includedNs;
1562
1563
  }
1563
1564
  function isImportNamespaceCompatible(ref, importedSchema) {
1564
- const declaredNs = ref?.namespace || null;
1565
- const importedNs = importedSchema?.targetNamespace || null;
1565
+ const declaredNs = ref && Object.prototype.hasOwnProperty.call(ref, "namespace") ? ref.namespace : null;
1566
+ const importedNs = importedSchema && Object.prototype.hasOwnProperty.call(importedSchema, "targetNamespace") ? importedSchema.targetNamespace : null;
1566
1567
  if (!declaredNs) {
1567
1568
  return true;
1568
1569
  }
1569
- return declaredNs === importedNs;
1570
+ return (declaredNs || null) === (importedNs || null);
1570
1571
  }
1571
1572
  function buildSchemaModel(doc, options = {}) {
1572
1573
  const issues = [];
@@ -1801,16 +1802,21 @@ var UssXsdEngine = (() => {
1801
1802
  continue;
1802
1803
  }
1803
1804
  const externalRoot = getSchemaRoot(externalDoc);
1804
- const externalDeclaredTargetNamespace = externalRoot?.getAttribute("targetNamespace") || null;
1805
- const shouldApplyChameleonInclude = ref.kind === "include" && (schema.targetNamespace || null) !== null && externalDeclaredTargetNamespace === null;
1805
+ const externalDeclaredTargetNamespace = externalRoot?.hasAttribute(
1806
+ "targetNamespace"
1807
+ ) ? externalRoot.getAttribute("targetNamespace") : null;
1808
+ const shouldApplyChameleonInclude = ref.kind === "include" && externalDeclaredTargetNamespace === null;
1806
1809
  const externalBuild = buildSchemaModel(externalDoc, {
1807
1810
  ...options,
1808
1811
  xsdText: externalXsdText,
1809
1812
  externalDocuments,
1810
1813
  _visitedExternalSchemas: visited,
1811
- _overrideTargetNamespace: shouldApplyChameleonInclude ? schema.targetNamespace : void 0
1814
+ ...shouldApplyChameleonInclude ? { _overrideTargetNamespace: schema.targetNamespace } : {}
1812
1815
  });
1813
1816
  if (externalBuild.schema) {
1817
+ if (ref.kind === "import") {
1818
+ schema.importedSchemas.push(externalBuild.schema);
1819
+ }
1814
1820
  if (ref.kind === "include") {
1815
1821
  if (!isIncludeNamespaceCompatible(schema, externalBuild.schema)) {
1816
1822
  issues.push(
@@ -2427,6 +2433,9 @@ var UssXsdEngine = (() => {
2427
2433
  };
2428
2434
  }
2429
2435
 
2436
+ // src/version.js
2437
+ var ENGINE_VERSION = "v0.1.0-rc.2";
2438
+
2430
2439
  // src/utils/result.js
2431
2440
  function summarizeIssues(issues = []) {
2432
2441
  return issues.reduce(
@@ -2447,7 +2456,8 @@ var UssXsdEngine = (() => {
2447
2456
  ok: !hasErrors(issues),
2448
2457
  data,
2449
2458
  issues,
2450
- summary: summarizeIssues(issues)
2459
+ summary: summarizeIssues(issues),
2460
+ version: ENGINE_VERSION
2451
2461
  };
2452
2462
  }
2453
2463
 
@@ -4832,6 +4842,27 @@ ${writeNode(rootNode, 0)}`;
4832
4842
  const isSimpleContent = resolvedRootType?.contentModel === "simple" && resolvedRootType?.derivation?.baseTypeName;
4833
4843
  if (isSimpleContent) {
4834
4844
  const textValue = (xmlRoot.textContent || "").trim();
4845
+ const children2 = elementChildren3(xmlRoot);
4846
+ if (children2.length > 0) {
4847
+ for (const childNode of children2) {
4848
+ const childName = localName2(childNode);
4849
+ issues.push(
4850
+ createIssue({
4851
+ code: ISSUE_CODES.XML_UNEXPECTED_ELEMENT,
4852
+ severity: "error",
4853
+ message: `Unexpected element '${childName}'.`,
4854
+ ...toLocationFields(locator.getNodeLocation(childNode)),
4855
+ path: `/${xmlRootName}/${childName}`,
4856
+ source: "xml",
4857
+ nodeKind: "element",
4858
+ name: childName,
4859
+ details: {
4860
+ namespaceUri: namespaceUri2(childNode)
4861
+ }
4862
+ })
4863
+ );
4864
+ }
4865
+ }
4835
4866
  if (!textValue) {
4836
4867
  issues.push(
4837
4868
  createIssue({
@@ -4849,10 +4880,6 @@ ${writeNode(rootNode, 0)}`;
4849
4880
  })
4850
4881
  );
4851
4882
  } else {
4852
- const baseType = resolveType(
4853
- schema,
4854
- resolvedRootType.derivation.baseTypeName
4855
- );
4856
4883
  const valueResult = validateElementValue(
4857
4884
  schema,
4858
4885
  { ...schemaRoot, typeName: resolvedRootType.derivation.baseTypeName },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uss-xsd-engine",
3
- "version": "0.1.0-beta.5",
3
+ "version": "0.1.0-rc.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",
@@ -30,6 +30,7 @@
30
30
  "url": "https://github.com/mumblebaj/uss-xsd-engine/issues"
31
31
  },
32
32
  "scripts": {
33
+ "write": "node scripts/write-version.js",
33
34
  "build": "node scripts/build.mjs",
34
35
  "clean": "rm -rf dist",
35
36
  "check:git": "git diff --quiet && git diff --cached --quiet",