@dialecte/core 0.4.15 → 0.4.17

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.
@@ -0,0 +1,24 @@
1
+ import { AssertValidXmlOptions, AssertValidXmlTestCasesParams, CreateXmlSchemaAssertionsParams } from './assert-valid-xml.types';
2
+ /**
3
+ * Create structural XML assertions bound to a dialecte's generated `definition`
4
+ * and declared `namespaces`. Instantiate once per dialecte (e.g. in scl test) and
5
+ * re-export alongside createTestProject, like createXmlAssertions.
6
+ *
7
+ * `assertValidXml` asserts, structurally: every element's namespace matches its
8
+ * parent context, every element is an allowed child of its parent, and every
9
+ * attribute is a known attribute of its element. Elements unknown to the schema are
10
+ * skipped (bespoke content under a transparent `Private`), and so is any element in
11
+ * a namespace the dialecte does not declare — even when its local name collides with
12
+ * a schema element. An element in NO namespace is not foreign — it is a schema
13
+ * element the snippet forgot to put in its namespace, and stays validated.
14
+ *
15
+ * `requireComplete` (default `true`) additionally requires every schema-required
16
+ * attribute to be present. NOT yet enforced (planned with the validation feature):
17
+ * attribute VALUE facets (uuid pattern, enums, datatypes) and cross-element
18
+ * constraints (unique keys, keyref resolution).
19
+ */
20
+ export declare function createXmlSchemaAssertions(params: CreateXmlSchemaAssertionsParams): {
21
+ assertValidXml: (xml: string, label?: string, options?: AssertValidXmlOptions) => void;
22
+ assertValidXmlTestCases: (params: AssertValidXmlTestCasesParams) => void;
23
+ };
24
+ //# sourceMappingURL=assert-valid-xml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-valid-xml.d.ts","sourceRoot":"","sources":["../../../src/test/assert-valid-xml/assert-valid-xml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACX,qBAAqB,EACrB,6BAA6B,EAG7B,+BAA+B,EAE/B,MAAM,0BAA0B,CAAA;AAGjC;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,+BAA+B;0BA4I1E,MAAM,4BAEF,qBAAqB,KAC5B,IAAI;sCAWkC,6BAA6B,KAAG,IAAI;EAqB7E"}
@@ -0,0 +1,41 @@
1
+ import { AnyDefinition, ElementDefinition, Namespace } from '../../types';
2
+ /** Options controlling how strict a single-document validation is. */
3
+ export type AssertValidXmlOptions = {
4
+ /**
5
+ * Also require every schema-required attribute to be present. Default `true`;
6
+ * minimal fixtures legitimately omit required attributes (a bare `<SCL>` without
7
+ * `version`/`revision`/`release`) and pass `false`.
8
+ */
9
+ requireComplete?: boolean;
10
+ };
11
+ export type CreateXmlSchemaAssertionsParams = {
12
+ /** The dialecte's generated element definitions, keyed by local name. */
13
+ definition: AnyDefinition;
14
+ /** The dialecte's declared namespaces; their URIs form the "known" set. */
15
+ namespaces: Record<string, Namespace>;
16
+ /** Names the schema in violation messages ("not valid SCL"). Default `'XML'`. */
17
+ schemaName?: string;
18
+ };
19
+ export type CollectElementViolationsParams = {
20
+ element: Element;
21
+ parentLocalName: string | undefined;
22
+ requireComplete: boolean;
23
+ };
24
+ export type CollectAttributeViolationsParams = {
25
+ element: Element;
26
+ elementDefinition: ElementDefinition;
27
+ requireComplete: boolean;
28
+ };
29
+ export type DescribeInvalidXmlParams = {
30
+ xml: string;
31
+ label: string;
32
+ requireComplete: boolean;
33
+ };
34
+ export type XmlSchemaTestCase = {
35
+ sourceXml: string;
36
+ targetXml?: string;
37
+ };
38
+ export type AssertValidXmlTestCasesParams = {
39
+ testCases: Record<string, XmlSchemaTestCase>;
40
+ };
41
+ //# sourceMappingURL=assert-valid-xml.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assert-valid-xml.types.d.ts","sourceRoot":"","sources":["../../../src/test/assert-valid-xml/assert-valid-xml.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAE1E,sEAAsE;AACtE,MAAM,MAAM,qBAAqB,GAAG;IACnC;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,+BAA+B,GAAG;IAC7C,yEAAyE;IACzE,UAAU,EAAE,aAAa,CAAA;IACzB,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACrC,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,8BAA8B,GAAG;IAC5C,OAAO,EAAE,OAAO,CAAA;IAChB,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,eAAe,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,gCAAgC,GAAG;IAC9C,OAAO,EAAE,OAAO,CAAA;IAChB,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,eAAe,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACtC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzE,MAAM,MAAM,6BAA6B,GAAG;IAC3C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAA;CAC5C,CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './assert-valid-xml';
2
+ export type * from './assert-valid-xml.types';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/test/assert-valid-xml/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,mBAAmB,0BAA0B,CAAA"}
@@ -1,7 +1,9 @@
1
+ export * from './assert-valid-xml';
1
2
  export * from './assert-xml';
2
3
  export * from './config';
3
4
  export * from './constant';
4
5
  export * from './create-test-dialecte';
6
+ export * from './normalize-uuids';
5
7
  export * from './run-test-cases';
6
8
  export type * from './run-test-cases.type';
7
9
  export * from './test-record';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,kBAAkB,CAAA;AAChC,mBAAmB,uBAAuB,CAAA;AAC1C,cAAc,eAAe,CAAA;AAC7B,mBAAmB,qBAAqB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/test/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,cAAc,CAAA;AAC5B,cAAc,UAAU,CAAA;AACxB,cAAc,YAAY,CAAA;AAC1B,cAAc,wBAAwB,CAAA;AACtC,cAAc,mBAAmB,CAAA;AACjC,cAAc,kBAAkB,CAAA;AAChC,mBAAmB,uBAAuB,CAAA;AAC1C,cAAc,eAAe,CAAA;AAC7B,mBAAmB,qBAAqB,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare function normalizeUuids(text: string): string;
2
+ //# sourceMappingURL=normalize-uuids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize-uuids.d.ts","sourceRoot":"","sources":["../../src/test/normalize-uuids.ts"],"names":[],"mappings":"AAYA,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASnD"}
package/dist/test.js CHANGED
@@ -1,15 +1,105 @@
1
- import { N as e, V as t, ft as n, ht as r, pt as i, t as a, u as o } from "./project-FFHlnZpz.js";
1
+ import { N as e, V as t, ft as n, ht as r, pt as i, t as a, u as o } from "./project-nvZv2ie8.js";
2
2
  import { DIALECTE_NAMESPACES as s, standardizeRecord as c, toTrackedRecord as l, toTreeRecord as u } from "./helpers.js";
3
3
  import { expect as d, it as f } from "vitest";
4
- //#region src/test/assert-xml/xpath-parser.ts
4
+ //#region src/test/assert-valid-xml/assert-valid-xml.ts
5
5
  function p(e) {
6
- let t = m(e);
6
+ let { definition: t, namespaces: n, schemaName: r = "XML" } = e, i = Object.values(n).map((e) => e.uri);
7
+ function a(e) {
8
+ return e.namespaceURI !== null && !i.includes(e.namespaceURI);
9
+ }
10
+ function o(e, n) {
11
+ return ((e ? t[e]?.children.details[n]?.namespace : void 0) ?? t[n]?.namespace)?.uri;
12
+ }
13
+ function s(e, t) {
14
+ let n = e.children;
15
+ return n.any === !0 || n.sequence.includes(t) ? !0 : t in n.details;
16
+ }
17
+ function c(e) {
18
+ return new Set([...e.attributes.sequence, ...Object.keys(e.attributes.details)]);
19
+ }
20
+ function l(e) {
21
+ let { element: t, elementDefinition: n, requireComplete: r } = e, i = c(n), a = Array.from(t.attributes).filter((e) => e.namespaceURI === null && !i.has(e.localName)).map((e) => `[attribute] <${t.localName}> has unknown attribute '${e.localName}'`);
22
+ if (!r) return a;
23
+ let o = Object.entries(n.attributes.details).filter(([e, n]) => n.required && !t.hasAttribute(e)).map(([e]) => `[required] <${t.localName}> is missing required attribute '${e}'`);
24
+ return [...a, ...o];
25
+ }
26
+ function u(e) {
27
+ let { element: n, parentLocalName: r, requireComplete: i } = e, c = Array.from(n.children);
28
+ if (a(n)) return c.flatMap((e) => u({
29
+ element: e,
30
+ parentLocalName: void 0,
31
+ requireComplete: i
32
+ }));
33
+ let d = n.localName, f = [], p = o(r, d), m = n.namespaceURI ?? "";
34
+ if (p !== void 0 && m !== p) {
35
+ let e = r ? ` under <${r}>` : "";
36
+ f.push(`[namespace] <${n.tagName}>${e}: is in ${n.namespaceURI ?? "(no namespace)"}, schema declares ${p || "(no namespace)"}`);
37
+ }
38
+ let h = r ? t[r] : void 0;
39
+ h && !s(h, d) && f.push(`[containment] <${d}> is not a valid child of <${r}>`);
40
+ let g = t[d], _ = g ? l({
41
+ element: n,
42
+ elementDefinition: g,
43
+ requireComplete: i
44
+ }) : [], v = c.flatMap((e) => u({
45
+ element: e,
46
+ parentLocalName: d,
47
+ requireComplete: i
48
+ }));
49
+ return [
50
+ ...f,
51
+ ..._,
52
+ ...v
53
+ ];
54
+ }
55
+ function d(e) {
56
+ let { xml: t, label: n, requireComplete: i } = e;
57
+ if (!t.startsWith("<?xml") && t.trimStart().startsWith("<?xml")) return `${n}: malformed XML — the XML declaration must be the very first characters of the string: remove the declaration (a snippet does not need one) or the whitespace before it`;
58
+ let a = new DOMParser().parseFromString(t, "application/xml"), o = a.querySelector("parsererror");
59
+ if (o) return `${n}: malformed XML — ${o.textContent?.trim()}`;
60
+ if (!a.documentElement) return;
61
+ let s = u({
62
+ element: a.documentElement,
63
+ parentLocalName: void 0,
64
+ requireComplete: i
65
+ });
66
+ return s.length > 0 ? `${n}: not valid ${r}:\n ${s.join("\n ")}` : void 0;
67
+ }
68
+ function f(e, t = "test XML", n = {}) {
69
+ let r = d({
70
+ xml: e,
71
+ label: t,
72
+ requireComplete: n.requireComplete ?? !0
73
+ });
74
+ if (r) throw Error(r);
75
+ }
76
+ function p(e) {
77
+ let { testCases: t } = e, n = Object.entries(t).flatMap(([e, t]) => [d({
78
+ xml: t.sourceXml,
79
+ label: `${e} › sourceXml`,
80
+ requireComplete: !1
81
+ }), t.targetXml ? d({
82
+ xml: t.targetXml,
83
+ label: `${e} › targetXml`,
84
+ requireComplete: !1
85
+ }) : void 0].filter((e) => e !== void 0));
86
+ if (n.length > 0) throw Error(n.join("\n"));
87
+ }
88
+ return {
89
+ assertValidXml: f,
90
+ assertValidXmlTestCases: p
91
+ };
92
+ }
93
+ //#endregion
94
+ //#region src/test/assert-xml/xpath-parser.ts
95
+ function m(e) {
96
+ let t = h(e);
7
97
  if (t.length === 0) return [e];
8
98
  let n = [];
9
99
  for (let r of t) n.push(e.slice(0, r));
10
100
  return n.push(e), n;
11
101
  }
12
- function m(e) {
102
+ function h(e) {
13
103
  let t = [], n = 0, r = 0, i = null;
14
104
  for (let a = 0; a < e.length; a++) {
15
105
  let o = e[a];
@@ -50,60 +140,60 @@ function m(e) {
50
140
  }
51
141
  //#endregion
52
142
  //#region src/test/assert-xml/assert-xml.ts
53
- var h = /* @__PURE__ */ r(t(), 1);
54
- function g(e) {
55
- let { namespaces: t } = e, n = v(t);
143
+ var g = /* @__PURE__ */ r(t(), 1);
144
+ function _(e) {
145
+ let { namespaces: t } = e, n = y(t);
56
146
  return {
57
147
  assertExpectedElementQueries(e) {
58
- _({
148
+ v({
59
149
  ...e,
60
150
  nsResolver: n
61
151
  });
62
152
  },
63
153
  assertUnexpectedElementQueries(e) {
64
- y({
154
+ b({
65
155
  ...e,
66
156
  nsResolver: n
67
157
  });
68
158
  }
69
159
  };
70
160
  }
71
- function _(e) {
161
+ function v(e) {
72
162
  let { xmlDocument: t, queries: n, nsResolver: r } = e;
73
- for (let e of n) b({
163
+ for (let e of n) x({
74
164
  xmlDocument: t,
75
165
  xpath: e,
76
166
  nsResolver: r
77
167
  });
78
168
  }
79
- function v(e) {
169
+ function y(e) {
80
170
  return (t) => t ? e[t]?.uri ?? null : null;
81
171
  }
82
- function y(e) {
172
+ function b(e) {
83
173
  let { xmlDocument: t, queries: n, nsResolver: r } = e;
84
- for (let e of n) S({
174
+ for (let e of n) C({
85
175
  xmlDocument: t,
86
176
  xpath: e,
87
177
  nsResolver: r
88
178
  });
89
179
  }
90
- function b(e) {
91
- let { xmlDocument: t, xpath: n, nsResolver: r } = e, i = p(n), a = null, o = 0;
180
+ function x(e) {
181
+ let { xmlDocument: t, xpath: n, nsResolver: r } = e, i = m(n), a = null, o = 0;
92
182
  for (let e = 0; e < i.length; e++) {
93
183
  let s = i[e], c = t.evaluate(s, t, r ?? null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
94
184
  if (c) {
95
185
  a = c, o = e + 1;
96
186
  continue;
97
187
  }
98
- let l = e === 0 ? i[0] : n.slice(i[e - 1].length), u = o === 0 ? `[No parent matched — failed from document root]\n Document:\n${x({ xml: new XMLSerializer().serializeToString(t) })}` : `[Last match at step ${o}/${i.length}]:\n${a ? x({ xml: a.outerHTML }) : "(none)"}`;
188
+ let l = e === 0 ? i[0] : n.slice(i[e - 1].length), u = o === 0 ? `[No parent matched — failed from document root]\n Document:\n${S({ xml: new XMLSerializer().serializeToString(t) })}` : `[Last match at step ${o}/${i.length}]:\n${a ? S({ xml: a.outerHTML }) : "(none)"}`;
99
189
  d(c, `Element not found in XML.\n Failed at step ${e + 1}/${i.length}: ${l.trim()}\n Full XPath: ${n}\n ${u}`).toBeTruthy();
100
190
  return;
101
191
  }
102
192
  }
103
- function x(e) {
193
+ function S(e) {
104
194
  let { xml: t } = e;
105
195
  try {
106
- return (0, h.default)(t, {
196
+ return (0, g.default)(t, {
107
197
  indentation: " ",
108
198
  collapseContent: !0
109
199
  });
@@ -111,23 +201,23 @@ function x(e) {
111
201
  return t;
112
202
  }
113
203
  }
114
- function S(e) {
115
- let { xmlDocument: t, xpath: n, nsResolver: r } = e, i = p(n);
204
+ function C(e) {
205
+ let { xmlDocument: t, xpath: n, nsResolver: r } = e, i = m(n);
116
206
  if (i.length > 1) {
117
207
  let e = null;
118
208
  for (let a = 0; a < i.length - 1; a++) {
119
- let o = i[a], s = t.evaluate(o, t, r ?? null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue, c = a === 0 ? i[0] : n.slice(i[a - 1].length), l = a === 0 ? "[Document root — no parent context]" : `[Parent element found at step ${a}]:\n${e ? x({ xml: e.outerHTML }) : "(none)"}`;
209
+ let o = i[a], s = t.evaluate(o, t, r ?? null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue, c = a === 0 ? i[0] : n.slice(i[a - 1].length), l = a === 0 ? "[Document root — no parent context]" : `[Parent element found at step ${a}]:\n${e ? S({ xml: e.outerHTML }) : "(none)"}`;
120
210
  d(s, `Absent assertion is unreliable: ancestor step does not exist.
121
211
  The query passes but for the wrong reason — an ancestor is missing, not the target element.
122
212
  Missing at step ${a + 1}/${i.length}: ${c.trim()}\n Full XPath: ${n}\n ${l}`).toBeTruthy(), e = s;
123
213
  }
124
214
  }
125
215
  let a = t.evaluate(n, t, r ?? null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
126
- d(a, `Element should NOT exist in XML but was found.\n XPath: ${n}\n Found:\n${a ? x({ xml: a.outerHTML }) : "(none)"}`).toBeFalsy();
216
+ d(a, `Element should NOT exist in XML but was found.\n XPath: ${n}\n Found:\n${a ? S({ xml: a.outerHTML }) : "(none)"}`).toBeFalsy();
127
217
  }
128
218
  //#endregion
129
219
  //#region src/test/constant.ts
130
- var C = {
220
+ var w = {
131
221
  ...s,
132
222
  default: {
133
223
  uri: "http://dialecte.dev/XML/DEFAULT",
@@ -137,7 +227,7 @@ var C = {
137
227
  uri: "http://dialecte.dev/XML/DEV-EXT",
138
228
  prefix: "ext"
139
229
  }
140
- }, w = `xmlns="${C.default.uri}"`, T = `xmlns:${C.dev.prefix}="${C.dev.uri}"`, E = `xmlns:${C.ext.prefix}="${C.ext.uri}"`, D = /* @__PURE__ */ "A.AAAA_1.AAAA_2.AAAA_3.AAA_1.AAA_2.AAA_3.AA_1.AA_2.AA_3.B.BBBB_1.BBBB_2.BBBB_3.BBB_1.BBB_2.BBB_3.BB_1.BB_2.BB_3.C.CCCC_1.CCCC_2.CCCC_3.CCC_1.CCC_2.CCC_3.CC_1.CC_2.CC_3.Root".split("."), O = {
230
+ }, T = `xmlns="${w.default.uri}"`, E = `xmlns:${w.dev.prefix}="${w.dev.uri}"`, D = `xmlns:${w.ext.prefix}="${w.ext.uri}"`, O = /* @__PURE__ */ "A.AAAA_1.AAAA_2.AAAA_3.AAA_1.AAA_2.AAA_3.AA_1.AA_2.AA_3.B.BBBB_1.BBBB_2.BBBB_3.BBB_1.BBB_2.BBB_3.BB_1.BB_2.BB_3.C.CCCC_1.CCCC_2.CCCC_3.CCC_1.CCC_2.CCC_3.CC_1.CC_2.CC_3.Root".split("."), k = {
141
231
  A: [
142
232
  "AA_1",
143
233
  "AA_2",
@@ -257,7 +347,7 @@ var C = {
257
347
  "B",
258
348
  "C"
259
349
  ]
260
- }, k = {
350
+ }, A = {
261
351
  A: ["Root"],
262
352
  AAAA_1: [
263
353
  "AAA_1",
@@ -361,7 +451,7 @@ var C = {
361
451
  CC_2: ["C"],
362
452
  CC_3: ["C"],
363
453
  Root: []
364
- }, A = {
454
+ }, j = {
365
455
  A: [
366
456
  "AAAA_1",
367
457
  "AAAA_2",
@@ -522,7 +612,7 @@ var C = {
522
612
  "CCC_3"
523
613
  ],
524
614
  Root: /* @__PURE__ */ "A.AAAA_1.AAAA_2.AAAA_3.AAA_1.AAA_2.AAA_3.AA_1.AA_2.AA_3.B.BBBB_1.BBBB_2.BBBB_3.BBB_1.BBB_2.BBB_3.BB_1.BB_2.BB_3.C.CCCC_1.CCCC_2.CCCC_3.CCC_1.CCC_2.CCC_3.CC_1.CC_2.CC_3".split(".")
525
- }, j = {
615
+ }, M = {
526
616
  A: ["Root"],
527
617
  AAAA_1: [
528
618
  "A",
@@ -689,7 +779,7 @@ var C = {
689
779
  CC_2: ["C", "Root"],
690
780
  CC_3: ["C", "Root"],
691
781
  Root: []
692
- }, M = "Root", N = [
782
+ }, N = "Root", P = [
693
783
  "A",
694
784
  "AA_1",
695
785
  "B",
@@ -698,7 +788,7 @@ var C = {
698
788
  "CC_1",
699
789
  "CC_2",
700
790
  "Root"
701
- ], P = {
791
+ ], F = {
702
792
  A: {
703
793
  aA: "",
704
794
  bA: "",
@@ -853,7 +943,7 @@ var C = {
853
943
  "ext:root": "",
854
944
  root: ""
855
945
  }
856
- }, F = {
946
+ }, I = {
857
947
  A: {
858
948
  tag: "A",
859
949
  namespace: {
@@ -2694,7 +2784,7 @@ var C = {
2694
2784
  } }]
2695
2785
  }]
2696
2786
  }
2697
- }, I = { supportedFileExtensions: [".xml"] }, L = {
2787
+ }, L = { supportedFileExtensions: [".xml"] }, R = {
2698
2788
  recordSchema: {
2699
2789
  primaryKey: "id",
2700
2790
  indexes: [
@@ -2709,24 +2799,24 @@ var C = {
2709
2799
  name: "xmlElements",
2710
2800
  schema: "id, tagName, [id+tagName], parent.id, parent.tagName, *children.id, *children.tagName"
2711
2801
  } }
2712
- }, R = {
2713
- rootElementName: M,
2714
- singletonElements: N,
2715
- elements: D,
2716
- namespaces: C,
2717
- attributes: P,
2718
- children: O,
2719
- parents: k,
2720
- descendants: A,
2721
- ancestors: j,
2722
- database: L,
2723
- io: I,
2724
- definition: F
2802
+ }, z = {
2803
+ rootElementName: N,
2804
+ singletonElements: P,
2805
+ elements: O,
2806
+ namespaces: w,
2807
+ attributes: F,
2808
+ children: k,
2809
+ parents: A,
2810
+ descendants: j,
2811
+ ancestors: M,
2812
+ database: R,
2813
+ io: L,
2814
+ definition: I
2725
2815
  };
2726
2816
  //#endregion
2727
2817
  //#region src/test/create-test-dialecte.ts
2728
- async function z(e) {
2729
- let { sourceXml: t, targetXml: n, dialecteConfig: r = R, extensions: i, hooks: o, dev: s } = e, c = `test-${crypto.randomUUID()}`, l = await new a({
2818
+ async function B(e) {
2819
+ let { sourceXml: t, targetXml: n, dialecteConfig: r = z, extensions: i, hooks: o, dev: s } = e, c = `test-${crypto.randomUUID()}`, l = await new a({
2730
2820
  configs: { default: r },
2731
2821
  defaultConfigKey: "default",
2732
2822
  storage: { type: "local" },
@@ -2750,7 +2840,7 @@ async function z(e) {
2750
2840
  target: f
2751
2841
  };
2752
2842
  }
2753
- async function B(t) {
2843
+ async function V(t) {
2754
2844
  let { databaseName: r, dialecteConfig: a, documentId: s } = t, c = new o(r, { recordSchema: a.database.recordSchema });
2755
2845
  return await c.open(), {
2756
2846
  dialecteConfig: a,
@@ -2769,19 +2859,31 @@ async function B(t) {
2769
2859
  };
2770
2860
  }
2771
2861
  //#endregion
2862
+ //#region src/test/normalize-uuids.ts
2863
+ var H = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
2864
+ function U(e) {
2865
+ let t = /* @__PURE__ */ new Map();
2866
+ return e.replace(H, (e) => {
2867
+ let n = t.get(e);
2868
+ if (n) return n;
2869
+ let r = `uuid-${t.size + 1}`;
2870
+ return t.set(e, r), r;
2871
+ });
2872
+ }
2873
+ //#endregion
2772
2874
  //#region src/test/run-test-cases.ts
2773
- var V = crypto.randomUUID.bind(crypto);
2774
- function H() {
2875
+ var W = crypto.randomUUID.bind(crypto);
2876
+ function G() {
2775
2877
  let e = 0;
2776
2878
  return function() {
2777
2879
  return `${e++}`;
2778
2880
  };
2779
2881
  }
2780
- function U(e) {
2781
- let { testCases: t, act: n, extensions: r, hooks: i, dialecteConfig: a = R } = e, { assertExpectedElementQueries: o, assertUnexpectedElementQueries: s } = g({ namespaces: a.namespaces });
2882
+ function K(e) {
2883
+ let { testCases: t, act: n, extensions: r, hooks: i, dialecteConfig: a = z } = e, { assertExpectedElementQueries: o, assertUnexpectedElementQueries: s } = _({ namespaces: a.namespaces });
2782
2884
  for (let [e, c] of Object.entries(t)) (c.only ? f.only : f)(e, async () => {
2783
- crypto.randomUUID = V;
2784
- let { project: e, source: t, target: l } = await z({
2885
+ crypto.randomUUID = W;
2886
+ let { project: e, source: t, target: l } = await B({
2785
2887
  sourceXml: c.sourceXml,
2786
2888
  targetXml: c.targetXml,
2787
2889
  dialecteConfig: a,
@@ -2789,7 +2891,7 @@ function U(e) {
2789
2891
  hooks: i
2790
2892
  });
2791
2893
  try {
2792
- crypto.randomUUID = H();
2894
+ crypto.randomUUID = G();
2793
2895
  let r = await n({
2794
2896
  testCase: c,
2795
2897
  project: e,
@@ -2810,15 +2912,15 @@ function U(e) {
2810
2912
  queries: c.unexpectedQueries
2811
2913
  });
2812
2914
  } finally {
2813
- crypto.randomUUID = V, await e.destroy();
2915
+ crypto.randomUUID = W, await e.destroy();
2814
2916
  }
2815
2917
  });
2816
2918
  }
2817
- function W(e) {
2818
- let { testCases: t, act: n, extensions: r, hooks: i, dialecteConfig: a = R } = e;
2919
+ function q(e) {
2920
+ let { testCases: t, act: n, extensions: r, hooks: i, dialecteConfig: a = z } = e;
2819
2921
  for (let [e, o] of Object.entries(t)) (o.only ? f.only : f)(e, async () => {
2820
- crypto.randomUUID = V;
2821
- let { project: e, source: t, target: s } = await z({
2922
+ crypto.randomUUID = W;
2923
+ let { project: e, source: t, target: s } = await B({
2822
2924
  sourceXml: o.sourceXml,
2823
2925
  targetXml: o.targetXml,
2824
2926
  dialecteConfig: a,
@@ -2826,42 +2928,42 @@ function W(e) {
2826
2928
  hooks: i
2827
2929
  });
2828
2930
  try {
2829
- crypto.randomUUID = H(), await n({
2931
+ crypto.randomUUID = G(), await n({
2830
2932
  testCase: o,
2831
2933
  project: e,
2832
2934
  source: t.document,
2833
2935
  target: s?.document
2834
2936
  });
2835
2937
  } finally {
2836
- crypto.randomUUID = V, await e.destroy();
2938
+ crypto.randomUUID = W, await e.destroy();
2837
2939
  }
2838
2940
  });
2839
2941
  }
2840
- function G(e, t) {
2942
+ function J(e, t) {
2841
2943
  for (let [n, r] of Object.entries(e)) (r.only ? f.only : f)(n, () => t(r));
2842
2944
  }
2843
- var K = q({ dialecteConfig: R });
2844
- function q(e) {
2945
+ var Y = X({ dialecteConfig: z });
2946
+ function X(e) {
2845
2947
  let { dialecteConfig: t, hooks: n, extensions: r } = e;
2846
2948
  return {
2847
- withExport: (e) => U({
2949
+ withExport: (e) => K({
2848
2950
  dialecteConfig: t,
2849
2951
  extensions: r,
2850
2952
  hooks: n,
2851
2953
  ...e
2852
2954
  }),
2853
- withoutExport: (e) => W({
2955
+ withoutExport: (e) => q({
2854
2956
  dialecteConfig: t,
2855
2957
  extensions: r,
2856
2958
  hooks: n,
2857
2959
  ...e
2858
2960
  }),
2859
- generic: G
2961
+ generic: J
2860
2962
  };
2861
2963
  }
2862
2964
  //#endregion
2863
2965
  //#region src/test/test-record.ts
2864
- function J(e) {
2966
+ function Z(e) {
2865
2967
  function t(t) {
2866
2968
  let { record: n, type: r = "raw" } = t, i = c({
2867
2969
  record: n,
@@ -2876,6 +2978,6 @@ function J(e) {
2876
2978
  }
2877
2979
  return t;
2878
2980
  }
2879
- var Y = J(R);
2981
+ var Q = Z(z);
2880
2982
  //#endregion
2881
- export { L as DATABASE_CONFIG, C as DIALECTE_TEST_NAMESPACES, I as IO_CONFIG, R as TEST_DIALECTE_CONFIG, w as XMLNS_DEFAULT_NAMESPACE, T as XMLNS_DEV_NAMESPACE, E as XMLNS_EXT_NAMESPACE, _ as assertExpectedElementQueries, y as assertUnexpectedElementQueries, H as createMockRandomUUID, B as createTestContext, z as createTestProject, Y as createTestRecord, J as createTestRecordFactory, q as createTestRunner, g as createXmlAssertions, K as runTestCases, p as splitXpathIntoSteps };
2983
+ export { R as DATABASE_CONFIG, w as DIALECTE_TEST_NAMESPACES, L as IO_CONFIG, z as TEST_DIALECTE_CONFIG, T as XMLNS_DEFAULT_NAMESPACE, E as XMLNS_DEV_NAMESPACE, D as XMLNS_EXT_NAMESPACE, v as assertExpectedElementQueries, b as assertUnexpectedElementQueries, G as createMockRandomUUID, V as createTestContext, B as createTestProject, Q as createTestRecord, Z as createTestRecordFactory, X as createTestRunner, _ as createXmlAssertions, p as createXmlSchemaAssertions, U as normalizeUuids, Y as runTestCases, m as splitXpathIntoSteps };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Format an XML string to a canonical, readable shape: one structural tag per line, indented by depth,
3
+ * with pure-text leaves kept inline (`<Name ...>text</Name>`).
4
+ *
5
+ * NON-VALIDATING and tolerant of `${...}` template interpolations (treated as opaque characters), so it
6
+ * works on XML embedded in JS/TS template literals — where a `${templateUuid}` interpolation can stand
7
+ * for a whole attribute, which a real XML parser silently mis-parses. It only rewrites the insignificant
8
+ * whitespace *between* elements: attribute text and leaf text are preserved verbatim, and an element with
9
+ * mixed text + element content is emitted with its original inner content untouched, so no significant
10
+ * value is ever altered. Idempotent.
11
+ */
12
+ export declare function formatXml(source: string, options?: {
13
+ indent?: string;
14
+ baseIndent?: string;
15
+ }): string;
16
+ /**
17
+ * Reformat every XML snippet embedded in a JS/TS source string — a template literal preceded by a
18
+ * `/* xml *\/` marker comment — with {@link formatXml}, re-indented under the marker's own line with the
19
+ * closing backtick aligned to the statement. Leaves the rest of the source untouched. The reusable core
20
+ * of an `xmlfmt`-style step for test fixtures (see the `dialecte-xmlfmt` bin).
21
+ */
22
+ export declare function formatEmbeddedXml(sourceCode: string, options?: {
23
+ indent?: string;
24
+ }): string;
25
+ //# sourceMappingURL=format-xml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format-xml.d.ts","sourceRoot":"","sources":["../../src/utils/format-xml.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CACxB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACpD,MAAM,CAOR;AAyJD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,MAAM,CAW/F"}
@@ -1,4 +1,5 @@
1
1
  export * from './attribute-rules';
2
+ export * from './format-xml';
2
3
  export * from './invariant';
3
4
  export * from './order-children';
4
5
  export * from './save-to-disk';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAA;AACjC,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,gBAAgB,CAAA"}