sof-mssql 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/dist/fhirpath/jsonSafeEmptiness.test.d.ts +19 -0
- package/dist/fhirpath/jsonSafeEmptiness.test.d.ts.map +1 -0
- package/dist/fhirpath/jsonSafeEmptiness.test.js +80 -0
- package/dist/fhirpath/jsonSafeEmptiness.test.js.map +1 -0
- package/dist/fhirpath/visitor.d.ts +78 -0
- package/dist/fhirpath/visitor.d.ts.map +1 -1
- package/dist/fhirpath/visitor.js +228 -23
- package/dist/fhirpath/visitor.js.map +1 -1
- package/dist/load.d.ts +9 -0
- package/dist/load.d.ts.map +1 -1
- package/dist/load.js +4 -0
- package/dist/load.js.map +1 -1
- package/dist/loader/feedback.integration.test.d.ts +14 -0
- package/dist/loader/feedback.integration.test.d.ts.map +1 -0
- package/dist/loader/feedback.integration.test.js +76 -0
- package/dist/loader/feedback.integration.test.js.map +1 -0
- package/dist/loader/index.d.ts.map +1 -1
- package/dist/loader/index.js +19 -6
- package/dist/loader/index.js.map +1 -1
- package/dist/loader/jsonColumn.integration.test.d.ts +13 -0
- package/dist/loader/jsonColumn.integration.test.d.ts.map +1 -0
- package/dist/loader/jsonColumn.integration.test.js +86 -0
- package/dist/loader/jsonColumn.integration.test.js.map +1 -0
- package/dist/loader/tables.d.ts +96 -3
- package/dist/loader/tables.d.ts.map +1 -1
- package/dist/loader/tables.js +182 -16
- package/dist/loader/tables.js.map +1 -1
- package/dist/loader/tables.test.d.ts +12 -0
- package/dist/loader/tables.test.d.ts.map +1 -0
- package/dist/loader/tables.test.js +130 -0
- package/dist/loader/tables.test.js.map +1 -0
- package/dist/loader/types.d.ts +9 -0
- package/dist/loader/types.d.ts.map +1 -1
- package/dist/parser.d.ts +1 -1
- package/dist/parser.js +1 -1
- package/dist/queryGenerator/treeWalker/compile.js +0 -1
- package/dist/queryGenerator/treeWalker/compile.js.map +1 -1
- package/dist/queryGenerator/treeWalker/cteTemplates.d.ts +9 -1
- package/dist/queryGenerator/treeWalker/cteTemplates.d.ts.map +1 -1
- package/dist/queryGenerator/treeWalker/cteTemplates.js +39 -3
- package/dist/queryGenerator/treeWalker/cteTemplates.js.map +1 -1
- package/dist/queryGenerator/treeWalker/operators/forEach.d.ts +4 -2
- package/dist/queryGenerator/treeWalker/operators/forEach.d.ts.map +1 -1
- package/dist/queryGenerator/treeWalker/operators/forEach.js +11 -5
- package/dist/queryGenerator/treeWalker/operators/forEach.js.map +1 -1
- package/dist/queryGenerator/treeWalker/operators/repeat.d.ts +2 -0
- package/dist/queryGenerator/treeWalker/operators/repeat.d.ts.map +1 -1
- package/dist/queryGenerator/treeWalker/operators/repeat.js +12 -0
- package/dist/queryGenerator/treeWalker/operators/repeat.js.map +1 -1
- package/dist/queryGenerator/treeWalker/types.d.ts +0 -2
- package/dist/queryGenerator/treeWalker/types.d.ts.map +1 -1
- package/dist/tests/load.test.d.ts +11 -0
- package/dist/tests/load.test.d.ts.map +1 -0
- package/dist/tests/load.test.js +37 -0
- package/dist/tests/load.test.js.map +1 -0
- package/dist/tests/utils/database.d.ts +2 -0
- package/dist/tests/utils/database.d.ts.map +1 -1
- package/dist/tests/utils/database.js +61 -4
- package/dist/tests/utils/database.js.map +1 -1
- package/dist/tests/utils/generator.d.ts +2 -0
- package/dist/tests/utils/generator.d.ts.map +1 -1
- package/dist/tests/utils/generator.js +24 -0
- package/dist/tests/utils/generator.js.map +1 -1
- package/dist/tests/utils/loaderIntegration.d.ts +59 -0
- package/dist/tests/utils/loaderIntegration.d.ts.map +1 -0
- package/dist/tests/utils/loaderIntegration.js +137 -0
- package/dist/tests/utils/loaderIntegration.js.map +1 -0
- package/dist/tests/utils/reporter.d.ts +1 -1
- package/dist/tests/utils/reporter.d.ts.map +1 -1
- package/dist/tests/utils/reporter.js +5 -4
- package/dist/tests/utils/reporter.js.map +1 -1
- package/dist/tests/utils/serverCapabilities.d.ts +23 -0
- package/dist/tests/utils/serverCapabilities.d.ts.map +1 -0
- package/dist/tests/utils/serverCapabilities.js +35 -0
- package/dist/tests/utils/serverCapabilities.js.map +1 -0
- package/dist/tests/utils/types.d.ts +1 -1
- package/dist/tests/utils/types.js +1 -1
- package/dist/tests/validation.test.d.ts +13 -0
- package/dist/tests/validation.test.d.ts.map +1 -0
- package/dist/tests/validation.test.js +81 -0
- package/dist/tests/validation.test.js.map +1 -0
- package/dist/types.d.ts +1 -1
- package/dist/validation.d.ts +40 -0
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +56 -0
- package/dist/validation.js.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forEach.d.ts","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/forEach.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"forEach.d.ts","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/forEach.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EAGd,MAAM,aAAa,CAAC;AAErB,UAAU,WAAW;IACnB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,OAAO,KAAK,QAAQ,EACvD,IAAI,EAAE,WAAW,GAChB,QAAQ,CA2BV"}
|
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
*
|
|
10
10
|
* Path-handling parity is delegated to PathParser (`.where()`, `.first()`,
|
|
11
11
|
* array indexing, multi-segment array flattening).
|
|
12
|
+
*
|
|
13
|
+
* @author John Grimes
|
|
12
14
|
*/
|
|
13
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
16
|
exports.walkForEach = walkForEach;
|
|
@@ -31,8 +33,8 @@ const types_js_1 = require("../types.js");
|
|
|
31
33
|
* @param node - The ForEach or ForEachOrNull select node. `node.forEach` or
|
|
32
34
|
* `node.forEachOrNull` supplies the FHIRPath expression to iterate.
|
|
33
35
|
* @param ctx - The current walker context; the inner context is derived from
|
|
34
|
-
* it by updating `source`, `partitionKeys`, `ancestorApplies`,
|
|
35
|
-
*
|
|
36
|
+
* it by updating `source`, `partitionKeys`, `ancestorApplies`, and
|
|
37
|
+
* `transpilerCtx`.
|
|
36
38
|
* @param walk - The recursive walk function used to visit the inner sub-tree.
|
|
37
39
|
* @param deps - Dependencies containing the `PathParser` used to parse and
|
|
38
40
|
* decompose the FHIRPath expression.
|
|
@@ -45,7 +47,7 @@ function walkForEach(node, ctx, walk, deps) {
|
|
|
45
47
|
const applyType = isOrNull ? "OUTER APPLY" : "CROSS APPLY";
|
|
46
48
|
const alias = (0, aliasGenerator_js_1.freshAlias)(ctx, "forEach");
|
|
47
49
|
const applyClause = buildForEachApply(rawPath, ctx.source, alias, applyType, ctx.transpilerCtx, deps.pathParser);
|
|
48
|
-
const innerCtx = buildInnerCtx(ctx, alias, rawPath, applyClause
|
|
50
|
+
const innerCtx = buildInnerCtx(ctx, alias, rawPath, applyClause);
|
|
49
51
|
const innerNode = {
|
|
50
52
|
column: node.column,
|
|
51
53
|
select: node.select,
|
|
@@ -57,13 +59,18 @@ function walkForEach(node, ctx, walk, deps) {
|
|
|
57
59
|
fromExtensions: applyClause + inner.fromExtensions,
|
|
58
60
|
};
|
|
59
61
|
}
|
|
60
|
-
function buildInnerCtx(ctx, alias, rawPath, applyClause
|
|
62
|
+
function buildInnerCtx(ctx, alias, rawPath, applyClause) {
|
|
61
63
|
const innerTranspilerCtx = {
|
|
62
64
|
...ctx.transpilerCtx,
|
|
63
65
|
iterationContext: `${alias}.value`,
|
|
64
66
|
currentForEachAlias: alias,
|
|
65
67
|
forEachSource: ctx.source,
|
|
66
68
|
forEachPath: `$.${rawPath}`,
|
|
69
|
+
// `%rowIndex` resolves to the iterated element's 0-based position, which is
|
|
70
|
+
// the OPENJSON `[key]` column. For forEachOrNull over an empty collection
|
|
71
|
+
// the OUTER APPLY yields a single null-padded row whose `[key]` is NULL;
|
|
72
|
+
// the spec requires `%rowIndex` to be 0 for that row, hence the COALESCE.
|
|
73
|
+
rowIndexExpr: `COALESCE(CAST(${alias}.[key] AS INT), 0)`,
|
|
67
74
|
};
|
|
68
75
|
const innerKey = {
|
|
69
76
|
name: `${alias}_key`,
|
|
@@ -75,7 +82,6 @@ function buildInnerCtx(ctx, alias, rawPath, applyClause, isOrNull) {
|
|
|
75
82
|
source: `${alias}.value`,
|
|
76
83
|
partitionKeys: [...ctx.partitionKeys, innerKey],
|
|
77
84
|
ancestorApplies: ctx.ancestorApplies + applyClause,
|
|
78
|
-
nullable: ctx.nullable || isOrNull,
|
|
79
85
|
transpilerCtx: innerTranspilerCtx,
|
|
80
86
|
};
|
|
81
87
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"forEach.js","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/forEach.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"forEach.js","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/forEach.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* plus a content-derived `__path` for stable identity across re-evaluations.
|
|
6
6
|
* The Fragment's `fromExtensions` is an INNER JOIN to the CTE on the partition key
|
|
7
7
|
* `[id]`; sibling-level composite-key joins are added by `mergeSiblings`.
|
|
8
|
+
*
|
|
9
|
+
* @author John Grimes
|
|
8
10
|
*/
|
|
9
11
|
import type { ViewDefinitionSelect } from "../../../types.js";
|
|
10
12
|
import { type Context, type Fragment } from "../types.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repeat.d.ts","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/repeat.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"repeat.d.ts","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/repeat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAG9D,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,QAAQ,EAGd,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,UAAU,CACxB,IAAI,EAAE,oBAAoB,EAC1B,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,CAAC,CAAC,EAAE,oBAAoB,EAAE,CAAC,EAAE,OAAO,KAAK,QAAQ,EACvD,IAAI,EAAE,UAAU,GACf,QAAQ,CAmCV"}
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
* plus a content-derived `__path` for stable identity across re-evaluations.
|
|
7
7
|
* The Fragment's `fromExtensions` is an INNER JOIN to the CTE on the partition key
|
|
8
8
|
* `[id]`; sibling-level composite-key joins are added by `mergeSiblings`.
|
|
9
|
+
*
|
|
10
|
+
* @author John Grimes
|
|
9
11
|
*/
|
|
10
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
13
|
exports.walkRepeat = walkRepeat;
|
|
@@ -90,12 +92,22 @@ function buildRepeatInnerCtx(ctx, cteAlias, paths, joinClause) {
|
|
|
90
92
|
sqlExpr: `${cteAlias}.__path`,
|
|
91
93
|
sqlType: types_js_1.SQL_NVARCHAR_MAX,
|
|
92
94
|
};
|
|
95
|
+
// `%rowIndex` inside a repeat is the 0-based position within the flattened
|
|
96
|
+
// depth-first traversal. The CTE exposes a padded `__order` accumulator whose
|
|
97
|
+
// lexical order matches pre-order; ROW_NUMBER over it (less one) yields the
|
|
98
|
+
// index. Partitioning on the ancestor keys captured before the repeat key is
|
|
99
|
+
// appended (the resource, and any enclosing forEach element) restarts the
|
|
100
|
+
// sequence per partition. The window lives in the outer SELECT, which already
|
|
101
|
+
// INNER JOINs the CTE, so the reference is in scope.
|
|
102
|
+
const partitionCols = (0, cteTemplates_js_1.qualifiedKeyCols)(cteAlias, ctx.partitionKeys);
|
|
103
|
+
const partitionClause = partitionCols ? `PARTITION BY ${partitionCols} ` : "";
|
|
93
104
|
const innerTranspilerCtx = {
|
|
94
105
|
...ctx.transpilerCtx,
|
|
95
106
|
iterationContext: `${cteAlias}.item_json`,
|
|
96
107
|
currentForEachAlias: cteAlias,
|
|
97
108
|
forEachSource: ctx.source,
|
|
98
109
|
forEachPath: paths.map((p) => `$.${p}`).join(", "),
|
|
110
|
+
rowIndexExpr: `(ROW_NUMBER() OVER (${partitionClause}ORDER BY ${cteAlias}.__order) - 1)`,
|
|
99
111
|
};
|
|
100
112
|
// Propagate the join into ancestorApplies so any *nested* Repeat builds
|
|
101
113
|
// its CTE anchor with this CTE in scope.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repeat.js","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/repeat.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"repeat.js","sourceRoot":"","sources":["../../../../src/queryGenerator/treeWalker/operators/repeat.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,8 +40,6 @@ export interface Context {
|
|
|
40
40
|
* with "\n".
|
|
41
41
|
*/
|
|
42
42
|
ancestorApplies: string;
|
|
43
|
-
/** True if any forEachOrNull ancestor is in scope. */
|
|
44
|
-
nullable: boolean;
|
|
45
43
|
/** Shared mutable counter for unique CTE/alias names across the whole compile. */
|
|
46
44
|
cteCounter: {
|
|
47
45
|
value: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,eAAO,MAAM,OAAO,QAAQ,CAAC;AAC7B,eAAO,MAAM,iBAAiB,mBAAmB,CAAC;AAClD,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,OAAO,GACP,SAAS,GACT,eAAe,GACf,QAAQ,GACR,UAAU,CAAC;AAEf,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEtE,eAAO,MAAM,OAAO,QAAQ,CAAC;AAC7B,eAAO,MAAM,iBAAiB,mBAAmB,CAAC;AAClD,eAAO,MAAM,gBAAgB,kBAAkB,CAAC;AAEhD,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,OAAO,GACP,SAAS,GACT,eAAe,GACf,QAAQ,GACR,UAAU,CAAC;AAEf,MAAM,WAAW,YAAY;IAC3B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,OAAO;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,kFAAkF;IAClF,UAAU,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9B,wDAAwD;IACxD,aAAa,EAAE,iBAAiB,CAAC;CAClC;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB;;;;;;OAMG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,8DAA8D;IAC9D,aAAa,EAAE,YAAY,EAAE,CAAC;CAC/B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unit tests for the `load` command option mapping.
|
|
3
|
+
*
|
|
4
|
+
* Verifies that the `--resource-json-data-type` CLI flag is mapped onto
|
|
5
|
+
* `LoaderOptions.resourceJsonDataType` and passed through untouched, leaving
|
|
6
|
+
* validation and normalisation to the loader (FR-007, cli-load contract).
|
|
7
|
+
*
|
|
8
|
+
* @author John Grimes
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=load.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.test.d.ts","sourceRoot":"","sources":["../../src/tests/load.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Unit tests for the `load` command option mapping.
|
|
4
|
+
*
|
|
5
|
+
* Verifies that the `--resource-json-data-type` CLI flag is mapped onto
|
|
6
|
+
* `LoaderOptions.resourceJsonDataType` and passed through untouched, leaving
|
|
7
|
+
* validation and normalisation to the loader (FR-007, cli-load contract).
|
|
8
|
+
*
|
|
9
|
+
* @author John Grimes
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const vitest_1 = require("vitest");
|
|
13
|
+
const load_1 = require("../load");
|
|
14
|
+
(0, vitest_1.describe)("buildLoaderOptions", () => {
|
|
15
|
+
(0, vitest_1.it)("maps --resource-json-data-type onto resourceJsonDataType", () => {
|
|
16
|
+
// Dry-run avoids any need for database environment variables.
|
|
17
|
+
const options = (0, load_1.buildLoaderOptions)("./data", {
|
|
18
|
+
dryRun: true,
|
|
19
|
+
resourceJsonDataType: "JSON",
|
|
20
|
+
});
|
|
21
|
+
(0, vitest_1.expect)(options.resourceJsonDataType).toBe("JSON");
|
|
22
|
+
});
|
|
23
|
+
(0, vitest_1.it)("leaves resourceJsonDataType undefined when the flag is absent", () => {
|
|
24
|
+
const options = (0, load_1.buildLoaderOptions)("./data", { dryRun: true });
|
|
25
|
+
(0, vitest_1.expect)(options.resourceJsonDataType).toBeUndefined();
|
|
26
|
+
});
|
|
27
|
+
(0, vitest_1.it)("passes the raw value through without normalising", () => {
|
|
28
|
+
// Normalisation is the loader's responsibility; the CLI layer must not
|
|
29
|
+
// pre-empt it, so a lower-case value is forwarded verbatim.
|
|
30
|
+
const options = (0, load_1.buildLoaderOptions)("./data", {
|
|
31
|
+
dryRun: true,
|
|
32
|
+
resourceJsonDataType: "json",
|
|
33
|
+
});
|
|
34
|
+
(0, vitest_1.expect)(options.resourceJsonDataType).toBe("json");
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=load.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.test.js","sourceRoot":"","sources":["../../src/tests/load.test.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAEH,mCAA8C;AAC9C,kCAA6C;AAE7C,IAAA,iBAAQ,EAAC,oBAAoB,EAAE,GAAG,EAAE;IAClC,IAAA,WAAE,EAAC,0DAA0D,EAAE,GAAG,EAAE;QAClE,8DAA8D;QAC9D,MAAM,OAAO,GAAG,IAAA,yBAAkB,EAAC,QAAQ,EAAE;YAC3C,MAAM,EAAE,IAAI;YACZ,oBAAoB,EAAE,MAAM;SAC7B,CAAC,CAAC;QACH,IAAA,eAAM,EAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,OAAO,GAAG,IAAA,yBAAkB,EAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,IAAA,eAAM,EAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,aAAa,EAAE,CAAC;IACvD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,uEAAuE;QACvE,4DAA4D;QAC5D,MAAM,OAAO,GAAG,IAAA,yBAAkB,EAAC,QAAQ,EAAE;YAC3C,MAAM,EAAE,IAAI;YACZ,oBAAoB,EAAE,MAAM;SAC7B,CAAC,CAAC;QACH,IAAA,eAAM,EAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/tests/utils/database.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/tests/utils/database.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,cAAc,EAAkC,MAAM,OAAO,CAAC;AA4DvE;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBnD;AAED;;;GAGG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAWrD;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,GAAG,EAAE,EAChB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAoDf;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCnE;AAsID;;;GAGG;AACH,wBAAgB,eAAe,IAAI,cAAc,CAKhD"}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Provides functions to manage database connections, table creation,
|
|
6
6
|
* and test data lifecycle during Vitest test execution.
|
|
7
|
+
*
|
|
8
|
+
* @author John Grimes
|
|
7
9
|
*/
|
|
8
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
11
|
exports.setupDatabase = setupDatabase;
|
|
@@ -11,7 +13,9 @@ exports.cleanupDatabase = cleanupDatabase;
|
|
|
11
13
|
exports.setupTestData = setupTestData;
|
|
12
14
|
exports.cleanupTestData = cleanupTestData;
|
|
13
15
|
exports.getDatabasePool = getDatabasePool;
|
|
16
|
+
const lossless_json_1 = require("lossless-json");
|
|
14
17
|
const mssql_1 = require("mssql");
|
|
18
|
+
const validation_1 = require("../../validation");
|
|
15
19
|
// Global connection pool
|
|
16
20
|
let globalPool = null;
|
|
17
21
|
let isConnected = false;
|
|
@@ -41,12 +45,20 @@ const getDatabaseConfig = () => {
|
|
|
41
45
|
/**
|
|
42
46
|
* Get table configuration from environment variables.
|
|
43
47
|
* Uses a test-specific table name to avoid conflicts with production data.
|
|
48
|
+
*
|
|
49
|
+
* The `json` column's storage type is governed by MSSQL_RESOURCE_JSON_DATA_TYPE
|
|
50
|
+
* (default `NVARCHAR(MAX)`); setting it to `JSON` exercises the native JSON type
|
|
51
|
+
* and requires a SQL Server 2025 instance. This lets the full conformance suite
|
|
52
|
+
* run against both column types (FR-011).
|
|
44
53
|
*/
|
|
45
54
|
const getTableConfig = () => ({
|
|
46
55
|
tableName: process.env.MSSQL_TEST_TABLE ?? "fhir_resources_test",
|
|
47
56
|
schemaName: process.env.MSSQL_SCHEMA ?? "dbo",
|
|
48
57
|
resourceIdColumn: "id",
|
|
49
58
|
resourceJsonColumn: "json",
|
|
59
|
+
resourceJsonDataType: process.env.MSSQL_RESOURCE_JSON_DATA_TYPE
|
|
60
|
+
? (0, validation_1.normaliseResourceJsonDataType)(process.env.MSSQL_RESOURCE_JSON_DATA_TYPE)
|
|
61
|
+
: "NVARCHAR(MAX)",
|
|
50
62
|
});
|
|
51
63
|
/**
|
|
52
64
|
* Setup database connection and create the FHIR resources table.
|
|
@@ -115,7 +127,13 @@ async function setupTestData(resources, testId) {
|
|
|
115
127
|
`;
|
|
116
128
|
const insertRequest = new mssql_1.Request(globalPool);
|
|
117
129
|
insertRequest.input("resource_type", resource.resourceType);
|
|
118
|
-
|
|
130
|
+
// Serialise with lossless-json so decimal lexemes (including trailing
|
|
131
|
+
// zeros, e.g. 1.0) are preserved in the stored JSON. This relies on the
|
|
132
|
+
// resource having been parsed losslessly upstream (see the dynamic test
|
|
133
|
+
// generator); plain JSON.stringify would collapse 1.0 to 1 and strip the
|
|
134
|
+
// precision the boundary functions depend on (FR-011). Non-numeric values
|
|
135
|
+
// are unaffected.
|
|
136
|
+
insertRequest.input("json", (0, lossless_json_1.stringify)(resource) ?? "null");
|
|
119
137
|
insertRequest.input("test_id", testId);
|
|
120
138
|
const result = await insertRequest.query(insertSql);
|
|
121
139
|
const insertedId = result.recordset[0]?.[tableConfig.resourceIdColumn];
|
|
@@ -206,6 +224,34 @@ async function clearTestTable() {
|
|
|
206
224
|
throw new Error(`Failed to clear test table: ${error instanceof Error ? error.message : String(error)}`);
|
|
207
225
|
}
|
|
208
226
|
}
|
|
227
|
+
/**
|
|
228
|
+
* Determine the existing test table's json column type.
|
|
229
|
+
*
|
|
230
|
+
* Maps the INFORMATION_SCHEMA representation to a canonical type: `json` for the
|
|
231
|
+
* native type, otherwise `NVARCHAR(MAX)` (the test table only ever uses these
|
|
232
|
+
* two). Used to decide whether the persisted table needs recreating when the
|
|
233
|
+
* configured type changes.
|
|
234
|
+
*
|
|
235
|
+
* @param tableConfig - The resolved test table configuration.
|
|
236
|
+
* @returns The canonical existing json column type.
|
|
237
|
+
*/
|
|
238
|
+
async function getExistingTestTableJsonType(tableConfig) {
|
|
239
|
+
if (!globalPool) {
|
|
240
|
+
throw new Error("Database not connected");
|
|
241
|
+
}
|
|
242
|
+
const request = new mssql_1.Request(globalPool);
|
|
243
|
+
request.input("schemaName", tableConfig.schemaName);
|
|
244
|
+
request.input("tableName", tableConfig.tableName);
|
|
245
|
+
request.input("columnName", tableConfig.resourceJsonColumn);
|
|
246
|
+
const result = await request.query(`
|
|
247
|
+
SELECT DATA_TYPE
|
|
248
|
+
FROM INFORMATION_SCHEMA.COLUMNS
|
|
249
|
+
WHERE TABLE_SCHEMA = @schemaName
|
|
250
|
+
AND TABLE_NAME = @tableName
|
|
251
|
+
AND COLUMN_NAME = @columnName
|
|
252
|
+
`);
|
|
253
|
+
return result.recordset[0]?.DATA_TYPE === "json" ? "JSON" : "NVARCHAR(MAX)";
|
|
254
|
+
}
|
|
209
255
|
/**
|
|
210
256
|
* Create the FHIR resources table if it doesn't exist.
|
|
211
257
|
*/
|
|
@@ -227,14 +273,25 @@ async function createTableIfNotExists() {
|
|
|
227
273
|
const checkResult = await checkRequest.query(checkTableSql);
|
|
228
274
|
const tableExists = checkResult.recordset[0]?.table_count > 0;
|
|
229
275
|
if (tableExists) {
|
|
230
|
-
|
|
276
|
+
// The shared test table persists between runs. If its json column type no
|
|
277
|
+
// longer matches the configured type (e.g. switching
|
|
278
|
+
// MSSQL_RESOURCE_JSON_DATA_TYPE between NVARCHAR(MAX) and JSON), drop it so
|
|
279
|
+
// it is recreated with the right type; otherwise leave it as is.
|
|
280
|
+
const existingType = await getExistingTestTableJsonType(tableConfig);
|
|
281
|
+
if (existingType === tableConfig.resourceJsonDataType) {
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
284
|
+
await new mssql_1.Request(globalPool).query(`DROP TABLE ${tableName}`);
|
|
231
285
|
}
|
|
232
|
-
// Create test table with test_id column for concurrent test isolation
|
|
286
|
+
// Create test table with test_id column for concurrent test isolation. The
|
|
287
|
+
// json column type is configurable so the same suite can prove conformance
|
|
288
|
+
// over both NVARCHAR(MAX) and the native JSON type. The type is a canonical,
|
|
289
|
+
// allowlisted value (see getTableConfig), so it carries no injection risk.
|
|
233
290
|
const createTableSql = `
|
|
234
291
|
CREATE TABLE ${tableName} (
|
|
235
292
|
[${tableConfig.resourceIdColumn}] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
|
|
236
293
|
[resource_type] NVARCHAR(64) NOT NULL,
|
|
237
|
-
[${tableConfig.resourceJsonColumn}]
|
|
294
|
+
[${tableConfig.resourceJsonColumn}] ${tableConfig.resourceJsonDataType} NOT NULL,
|
|
238
295
|
[test_id] NVARCHAR(255) NOT NULL
|
|
239
296
|
)
|
|
240
297
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/tests/utils/database.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/tests/utils/database.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Creates Vitest test suites dynamically at runtime without generating physical files.
|
|
5
5
|
* Each SQL-on-FHIR JSON test file becomes a describe block with individual it blocks
|
|
6
6
|
* for each test case. Results are collected for report generation.
|
|
7
|
+
*
|
|
8
|
+
* @author John Grimes
|
|
7
9
|
*/
|
|
8
10
|
import type { TestReport } from "./types";
|
|
9
11
|
declare global {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/tests/utils/generator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../../src/tests/utils/generator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAcH,OAAO,KAAK,EAAE,UAAU,EAAmB,MAAM,SAAS,CAAC;AAM3D,OAAO,CAAC,MAAM,CAAC;IAEb,IAAI,WAAW,EAAE,UAAU,GAAG,SAAS,CAAC;CACzC;AAiBD;;GAEG;AACH,qBAAa,sBAAsB;IACjC;;OAEG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAoB7C;;OAEG;IACH,0BAA0B,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI;IAWvD;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IA+BzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAexB;;OAEG;IACH,OAAO,CAAC,aAAa;IAQrB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA+BzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA+C3B;;OAEG;IACH,gBAAgB,IAAI,IAAI;CAKzB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,sBAAsB,CAoB3E"}
|
|
@@ -5,17 +5,34 @@
|
|
|
5
5
|
* Creates Vitest test suites dynamically at runtime without generating physical files.
|
|
6
6
|
* Each SQL-on-FHIR JSON test file becomes a describe block with individual it blocks
|
|
7
7
|
* for each test case. Results are collected for report generation.
|
|
8
|
+
*
|
|
9
|
+
* @author John Grimes
|
|
8
10
|
*/
|
|
9
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
12
|
exports.DynamicVitestGenerator = void 0;
|
|
11
13
|
exports.createDynamicTests = createDynamicTests;
|
|
12
14
|
const fs_1 = require("fs");
|
|
15
|
+
const lossless_json_1 = require("lossless-json");
|
|
13
16
|
const path_1 = require("path");
|
|
14
17
|
const vitest_1 = require("vitest");
|
|
15
18
|
const parser_1 = require("../../parser");
|
|
16
19
|
const database_js_1 = require("./database.js");
|
|
17
20
|
const sqlOnFhir_1 = require("./sqlOnFhir");
|
|
18
21
|
const testContext_js_1 = require("./testContext.js");
|
|
22
|
+
/**
|
|
23
|
+
* Parse the `resources` array of a test suite from its raw JSON, preserving
|
|
24
|
+
* numeric lexemes (e.g. decimal trailing zeros such as 1.0) as lossless values
|
|
25
|
+
* so they survive insertion into the database (FR-011). Only the resources are
|
|
26
|
+
* parsed this way; the surrounding suite (including expected results) is parsed
|
|
27
|
+
* normally elsewhere so result comparison keeps plain numbers.
|
|
28
|
+
*
|
|
29
|
+
* @param testSuiteJson - The raw test suite JSON text.
|
|
30
|
+
* @returns The resources array with numeric lexemes preserved.
|
|
31
|
+
*/
|
|
32
|
+
function losslessParseResources(testSuiteJson) {
|
|
33
|
+
const parsed = (0, lossless_json_1.parse)(testSuiteJson);
|
|
34
|
+
return Array.isArray(parsed.resources) ? parsed.resources : [];
|
|
35
|
+
}
|
|
19
36
|
/**
|
|
20
37
|
* Dynamic test generator that creates Vitest tests at runtime.
|
|
21
38
|
*/
|
|
@@ -26,6 +43,13 @@ class DynamicVitestGenerator {
|
|
|
26
43
|
generateTestsFromFile(filePath) {
|
|
27
44
|
const testSuiteJson = (0, fs_1.readFileSync)(filePath, "utf8");
|
|
28
45
|
const testSuite = parser_1.ViewDefinitionParser.parseTestSuite(testSuiteJson);
|
|
46
|
+
// Re-parse the resources losslessly so decimal lexemes (e.g. 1.0) survive
|
|
47
|
+
// for insertion (FR-011). The standard parse used above collapses 1.0 to 1
|
|
48
|
+
// before the value ever reaches the database, which the decimal boundary
|
|
49
|
+
// functions cannot recover from. Only the resources need this treatment;
|
|
50
|
+
// the test expectations keep plain numbers so result comparison is
|
|
51
|
+
// unaffected. The lossless objects are serialised by setupTestData.
|
|
52
|
+
testSuite.resources = losslessParseResources(testSuiteJson);
|
|
29
53
|
const suiteName = testSuite.title;
|
|
30
54
|
// Extract filename for report (e.g., "basic.json" from "/path/to/basic.json")
|
|
31
55
|
const fileName = filePath.split("/").pop() ?? filePath;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../src/tests/utils/generator.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../../src/tests/utils/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared harness for database-backed loader integration tests.
|
|
3
|
+
*
|
|
4
|
+
* Encapsulates the connection pool lifecycle, native-JSON capability probe,
|
|
5
|
+
* sample NDJSON generation, and per-test table/temp-directory cleanup so the
|
|
6
|
+
* individual integration test files stay focused on assertions. The native
|
|
7
|
+
* JSON type is only available on SQL Server 2025+, so callers gate JSON-specific
|
|
8
|
+
* cases on isNativeJsonSupported().
|
|
9
|
+
*
|
|
10
|
+
* @author John Grimes
|
|
11
|
+
*/
|
|
12
|
+
/** A small, representative set of FHIR resources used by the integration tests. */
|
|
13
|
+
export declare const SAMPLE_PATIENTS: ({
|
|
14
|
+
resourceType: string;
|
|
15
|
+
id: string;
|
|
16
|
+
active: boolean;
|
|
17
|
+
gender?: undefined;
|
|
18
|
+
} | {
|
|
19
|
+
resourceType: string;
|
|
20
|
+
id: string;
|
|
21
|
+
gender: string;
|
|
22
|
+
active?: undefined;
|
|
23
|
+
})[];
|
|
24
|
+
/** The effective type of a json column read from INFORMATION_SCHEMA. */
|
|
25
|
+
export interface JsonColumnType {
|
|
26
|
+
/** The INFORMATION_SCHEMA DATA_TYPE (e.g. `nvarchar` or `json`). */
|
|
27
|
+
dataType: string;
|
|
28
|
+
/** The CHARACTER_MAXIMUM_LENGTH (-1 for MAX, null for the native type). */
|
|
29
|
+
maxLength: number | null;
|
|
30
|
+
}
|
|
31
|
+
/** Helpers bound to a single connection pool for one integration test file. */
|
|
32
|
+
export interface LoaderIntegrationHarness {
|
|
33
|
+
/** Open the pool and probe native-JSON support. Call from beforeAll. */
|
|
34
|
+
connect(): Promise<void>;
|
|
35
|
+
/** Drop created tables, remove temp dirs and close the pool. Call from afterAll. */
|
|
36
|
+
cleanup(): Promise<void>;
|
|
37
|
+
/** Whether the connected server supports the native JSON column type. */
|
|
38
|
+
isNativeJsonSupported(): boolean;
|
|
39
|
+
/** Generate and register a unique, valid table name. */
|
|
40
|
+
makeTableName(): string;
|
|
41
|
+
/**
|
|
42
|
+
* Create a loader-shaped table whose `json` column uses the given SQL type,
|
|
43
|
+
* for exercising the existing-column mismatch safeguard.
|
|
44
|
+
*/
|
|
45
|
+
createTableWithJsonColumnType(tableName: string, jsonColumnType: string): Promise<void>;
|
|
46
|
+
/** Load the sample NDJSON into a table, returning the rows loaded. */
|
|
47
|
+
loadSample(tableName: string, resourceJsonDataType?: string): Promise<number>;
|
|
48
|
+
/** Read the effective type of a table's json column. */
|
|
49
|
+
getJsonColumnType(tableName: string): Promise<JsonColumnType>;
|
|
50
|
+
/** Count the rows in a table. */
|
|
51
|
+
getRowCount(tableName: string): Promise<number>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Create a loader integration harness.
|
|
55
|
+
*
|
|
56
|
+
* @returns A harness whose lifecycle is driven by connect()/cleanup().
|
|
57
|
+
*/
|
|
58
|
+
export declare function createLoaderIntegrationHarness(): LoaderIntegrationHarness;
|
|
59
|
+
//# sourceMappingURL=loaderIntegration.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loaderIntegration.d.ts","sourceRoot":"","sources":["../../../src/tests/utils/loaderIntegration.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAgBH,mFAAmF;AACnF,eAAO,MAAM,eAAe;;;;;;;;;;IAI3B,CAAC;AAEF,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,+EAA+E;AAC/E,MAAM,WAAW,wBAAwB;IACvC,wEAAwE;IACxE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,oFAAoF;IACpF,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,yEAAyE;IACzE,qBAAqB,IAAI,OAAO,CAAC;IACjC,wDAAwD;IACxD,aAAa,IAAI,MAAM,CAAC;IACxB;;;OAGG;IACH,6BAA6B,CAC3B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,sEAAsE;IACtE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9E,wDAAwD;IACxD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC9D,iCAAiC;IACjC,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACjD;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,IAAI,wBAAwB,CA0HzE"}
|