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.
Files changed (88) hide show
  1. package/README.md +88 -0
  2. package/dist/fhirpath/jsonSafeEmptiness.test.d.ts +19 -0
  3. package/dist/fhirpath/jsonSafeEmptiness.test.d.ts.map +1 -0
  4. package/dist/fhirpath/jsonSafeEmptiness.test.js +80 -0
  5. package/dist/fhirpath/jsonSafeEmptiness.test.js.map +1 -0
  6. package/dist/fhirpath/visitor.d.ts +78 -0
  7. package/dist/fhirpath/visitor.d.ts.map +1 -1
  8. package/dist/fhirpath/visitor.js +228 -23
  9. package/dist/fhirpath/visitor.js.map +1 -1
  10. package/dist/load.d.ts +9 -0
  11. package/dist/load.d.ts.map +1 -1
  12. package/dist/load.js +4 -0
  13. package/dist/load.js.map +1 -1
  14. package/dist/loader/feedback.integration.test.d.ts +14 -0
  15. package/dist/loader/feedback.integration.test.d.ts.map +1 -0
  16. package/dist/loader/feedback.integration.test.js +76 -0
  17. package/dist/loader/feedback.integration.test.js.map +1 -0
  18. package/dist/loader/index.d.ts.map +1 -1
  19. package/dist/loader/index.js +19 -6
  20. package/dist/loader/index.js.map +1 -1
  21. package/dist/loader/jsonColumn.integration.test.d.ts +13 -0
  22. package/dist/loader/jsonColumn.integration.test.d.ts.map +1 -0
  23. package/dist/loader/jsonColumn.integration.test.js +86 -0
  24. package/dist/loader/jsonColumn.integration.test.js.map +1 -0
  25. package/dist/loader/tables.d.ts +96 -3
  26. package/dist/loader/tables.d.ts.map +1 -1
  27. package/dist/loader/tables.js +182 -16
  28. package/dist/loader/tables.js.map +1 -1
  29. package/dist/loader/tables.test.d.ts +12 -0
  30. package/dist/loader/tables.test.d.ts.map +1 -0
  31. package/dist/loader/tables.test.js +130 -0
  32. package/dist/loader/tables.test.js.map +1 -0
  33. package/dist/loader/types.d.ts +9 -0
  34. package/dist/loader/types.d.ts.map +1 -1
  35. package/dist/parser.d.ts +1 -1
  36. package/dist/parser.js +1 -1
  37. package/dist/queryGenerator/treeWalker/compile.js +0 -1
  38. package/dist/queryGenerator/treeWalker/compile.js.map +1 -1
  39. package/dist/queryGenerator/treeWalker/cteTemplates.d.ts +9 -1
  40. package/dist/queryGenerator/treeWalker/cteTemplates.d.ts.map +1 -1
  41. package/dist/queryGenerator/treeWalker/cteTemplates.js +39 -3
  42. package/dist/queryGenerator/treeWalker/cteTemplates.js.map +1 -1
  43. package/dist/queryGenerator/treeWalker/operators/forEach.d.ts +4 -2
  44. package/dist/queryGenerator/treeWalker/operators/forEach.d.ts.map +1 -1
  45. package/dist/queryGenerator/treeWalker/operators/forEach.js +11 -5
  46. package/dist/queryGenerator/treeWalker/operators/forEach.js.map +1 -1
  47. package/dist/queryGenerator/treeWalker/operators/repeat.d.ts +2 -0
  48. package/dist/queryGenerator/treeWalker/operators/repeat.d.ts.map +1 -1
  49. package/dist/queryGenerator/treeWalker/operators/repeat.js +12 -0
  50. package/dist/queryGenerator/treeWalker/operators/repeat.js.map +1 -1
  51. package/dist/queryGenerator/treeWalker/types.d.ts +0 -2
  52. package/dist/queryGenerator/treeWalker/types.d.ts.map +1 -1
  53. package/dist/tests/load.test.d.ts +11 -0
  54. package/dist/tests/load.test.d.ts.map +1 -0
  55. package/dist/tests/load.test.js +37 -0
  56. package/dist/tests/load.test.js.map +1 -0
  57. package/dist/tests/utils/database.d.ts +2 -0
  58. package/dist/tests/utils/database.d.ts.map +1 -1
  59. package/dist/tests/utils/database.js +61 -4
  60. package/dist/tests/utils/database.js.map +1 -1
  61. package/dist/tests/utils/generator.d.ts +2 -0
  62. package/dist/tests/utils/generator.d.ts.map +1 -1
  63. package/dist/tests/utils/generator.js +24 -0
  64. package/dist/tests/utils/generator.js.map +1 -1
  65. package/dist/tests/utils/loaderIntegration.d.ts +59 -0
  66. package/dist/tests/utils/loaderIntegration.d.ts.map +1 -0
  67. package/dist/tests/utils/loaderIntegration.js +137 -0
  68. package/dist/tests/utils/loaderIntegration.js.map +1 -0
  69. package/dist/tests/utils/reporter.d.ts +1 -1
  70. package/dist/tests/utils/reporter.d.ts.map +1 -1
  71. package/dist/tests/utils/reporter.js +5 -4
  72. package/dist/tests/utils/reporter.js.map +1 -1
  73. package/dist/tests/utils/serverCapabilities.d.ts +23 -0
  74. package/dist/tests/utils/serverCapabilities.d.ts.map +1 -0
  75. package/dist/tests/utils/serverCapabilities.js +35 -0
  76. package/dist/tests/utils/serverCapabilities.js.map +1 -0
  77. package/dist/tests/utils/types.d.ts +1 -1
  78. package/dist/tests/utils/types.js +1 -1
  79. package/dist/tests/validation.test.d.ts +13 -0
  80. package/dist/tests/validation.test.d.ts.map +1 -0
  81. package/dist/tests/validation.test.js +81 -0
  82. package/dist/tests/validation.test.js.map +1 -0
  83. package/dist/types.d.ts +1 -1
  84. package/dist/validation.d.ts +40 -0
  85. package/dist/validation.d.ts.map +1 -1
  86. package/dist/validation.js +56 -0
  87. package/dist/validation.js.map +1 -1
  88. package/package.json +2 -1
@@ -9,12 +9,119 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
9
9
  return (mod && mod.__esModule) ? mod : { "default": mod };
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.buildCreateTableStatements = buildCreateTableStatements;
13
+ exports.resolveColumnJsonDataType = resolveColumnJsonDataType;
14
+ exports.buildJsonTypeMismatchWarning = buildJsonTypeMismatchWarning;
12
15
  exports.tableExists = tableExists;
16
+ exports.getExistingJsonColumnType = getExistingJsonColumnType;
17
+ exports.warnIfJsonTypeMismatch = warnIfJsonTypeMismatch;
13
18
  exports.createTable = createTable;
14
19
  exports.truncateTable = truncateTable;
15
20
  exports.ensureTable = ensureTable;
16
21
  const mssql_1 = __importDefault(require("mssql"));
17
22
  const validation_js_1 = require("../validation.js");
23
+ /**
24
+ * Build the DDL statements for the resources table and its index.
25
+ *
26
+ * This is a pure function so the generated SQL can be unit-tested without a
27
+ * database. The `json` column is typed with the resolved {@link
28
+ * ResourceJsonDataType}; with the default `NVARCHAR(MAX)` the output is
29
+ * byte-for-byte identical to earlier releases (SC-001). Identifiers are assumed
30
+ * to have been validated by the caller (see {@link createTable}).
31
+ *
32
+ * @param schemaName - Schema name (already validated).
33
+ * @param tableName - Table name (already validated).
34
+ * @param jsonType - Resolved canonical storage type for the `json` column.
35
+ * @returns The `CREATE TABLE` and `CREATE INDEX` statements.
36
+ */
37
+ function buildCreateTableStatements(schemaName, tableName, jsonType) {
38
+ // Only the json column's type varies; every other part of the DDL is held
39
+ // constant so the default path is unchanged from earlier releases.
40
+ const createTable = `
41
+ CREATE TABLE [${schemaName}].[${tableName}] (
42
+ [id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
43
+ [resource_type] NVARCHAR(64) NOT NULL,
44
+ [json] ${jsonType} NOT NULL
45
+ )
46
+ `;
47
+ const createIndex = `
48
+ CREATE INDEX [IX_${tableName}_resource_type]
49
+ ON [${schemaName}].[${tableName}] ([resource_type])
50
+ `;
51
+ return { createTable, createIndex };
52
+ }
53
+ /**
54
+ * Render an INFORMATION_SCHEMA column type for a diagnostic message.
55
+ *
56
+ * Length-bearing types are shown with their declared length, with the `-1`
57
+ * sentinel rendered as `MAX`; types reported without a length (such as the
58
+ * native `JSON` type) are shown as the bare type name.
59
+ *
60
+ * @param dataType - The INFORMATION_SCHEMA DATA_TYPE.
61
+ * @param characterMaximumLength - The INFORMATION_SCHEMA CHARACTER_MAXIMUM_LENGTH.
62
+ * @returns A readable type such as `VARCHAR(100)`, `NVARCHAR(MAX)` or `JSON`.
63
+ */
64
+ function formatColumnType(dataType, characterMaximumLength) {
65
+ const baseType = dataType.trim().toUpperCase();
66
+ if (characterMaximumLength === null) {
67
+ return baseType;
68
+ }
69
+ const length = characterMaximumLength === -1 ? "MAX" : String(characterMaximumLength);
70
+ return `${baseType}(${length})`;
71
+ }
72
+ /**
73
+ * Resolve an INFORMATION_SCHEMA column description to a canonical json type.
74
+ *
75
+ * Only two column shapes can faithfully hold a serialised FHIR resource: the
76
+ * native type (`data_type = 'json'`) and `NVARCHAR(MAX)` (`data_type =
77
+ * 'nvarchar'` with `character_maximum_length = -1`). Any other shape - a bounded
78
+ * `NVARCHAR(64)`, a non-Unicode `VARCHAR`, `TEXT`, and so on - is rejected here
79
+ * rather than silently coerced to `NVARCHAR(MAX)`. Coercion would let the
80
+ * mismatch check pass and the loader write into a column that cannot hold the
81
+ * data, surfacing later as a `String or binary data would be truncated` error
82
+ * or, under non-Unicode `VARCHAR`, silent character corruption. Failing fast
83
+ * turns that late, data-dependent failure into an early, actionable
84
+ * configuration error (Constitution Principle IV).
85
+ *
86
+ * @param dataType - The INFORMATION_SCHEMA DATA_TYPE.
87
+ * @param characterMaximumLength - The INFORMATION_SCHEMA CHARACTER_MAXIMUM_LENGTH.
88
+ * @returns The canonical resource json data type (`JSON` or `NVARCHAR(MAX)`).
89
+ * @throws Error if the column is neither native `JSON` nor `NVARCHAR(MAX)`. The
90
+ * message names the offending type and the two acceptable types.
91
+ */
92
+ function resolveColumnJsonDataType(dataType, characterMaximumLength) {
93
+ const normalised = dataType.trim().toLowerCase();
94
+ if (normalised === "json") {
95
+ return "JSON";
96
+ }
97
+ // NVARCHAR(MAX) is the only nvarchar form that can hold an arbitrarily long
98
+ // resource; bounded lengths would truncate, so the length is required here.
99
+ if (normalised === "nvarchar" && characterMaximumLength === -1) {
100
+ return "NVARCHAR(MAX)";
101
+ }
102
+ throw new Error(`Existing [json] column is ` +
103
+ `${formatColumnType(dataType, characterMaximumLength)}, which cannot ` +
104
+ `safely hold serialised FHIR resources. Expected NVARCHAR(MAX) or JSON. ` +
105
+ `Alter or drop the column before loading.`);
106
+ }
107
+ /**
108
+ * Build a warning for an existing table whose json column type differs from the
109
+ * requested type.
110
+ *
111
+ * @param schemaName - Schema name.
112
+ * @param tableName - Table name.
113
+ * @param existingType - The table's current json column type.
114
+ * @param requestedType - The requested json column type.
115
+ * @returns A warning message naming both types, or null when they match.
116
+ */
117
+ function buildJsonTypeMismatchWarning(schemaName, tableName, existingType, requestedType) {
118
+ if (existingType === requestedType) {
119
+ return null;
120
+ }
121
+ return (`Warning: table [${schemaName}].[${tableName}] already exists with a json ` +
122
+ `column of type ${existingType}, but ${requestedType} was requested. The ` +
123
+ `existing table is left unaltered and loading continues into it.`);
124
+ }
18
125
  /**
19
126
  * Check if a table exists in the database.
20
127
  *
@@ -34,31 +141,82 @@ async function tableExists(pool, schemaName, tableName) {
34
141
  `);
35
142
  return result.recordset[0].count > 0;
36
143
  }
144
+ /**
145
+ * Read the effective json column type for an existing table.
146
+ *
147
+ * @param pool - Database connection pool.
148
+ * @param schemaName - Schema name.
149
+ * @param tableName - Name of the table.
150
+ * @returns The canonical json column type, or null if the table or its `json`
151
+ * column does not exist.
152
+ * @throws Error if the column exists but is neither native `JSON` nor
153
+ * `NVARCHAR(MAX)` (see {@link resolveColumnJsonDataType}).
154
+ */
155
+ async function getExistingJsonColumnType(pool, schemaName, tableName) {
156
+ const result = await pool
157
+ .request()
158
+ .input("schemaName", mssql_1.default.NVarChar, schemaName)
159
+ .input("tableName", mssql_1.default.NVarChar, tableName).query(`
160
+ SELECT DATA_TYPE, CHARACTER_MAXIMUM_LENGTH
161
+ FROM INFORMATION_SCHEMA.COLUMNS
162
+ WHERE TABLE_SCHEMA = @schemaName
163
+ AND TABLE_NAME = @tableName
164
+ AND COLUMN_NAME = 'json'
165
+ `);
166
+ const row = result.recordset[0];
167
+ if (!row) {
168
+ return null;
169
+ }
170
+ return resolveColumnJsonDataType(row.DATA_TYPE, row.CHARACTER_MAXIMUM_LENGTH);
171
+ }
172
+ /**
173
+ * Emit a warning if an existing table's json column type differs from the
174
+ * requested type. The table is never altered; this only surfaces the mismatch
175
+ * so it is visible rather than silently ignored (FR-008, SC-005).
176
+ *
177
+ * An existing column that is neither native `JSON` nor `NVARCHAR(MAX)` cannot
178
+ * hold a serialised FHIR resource, so it is rejected outright rather than
179
+ * warned about: the error is raised here before any rows are loaded.
180
+ *
181
+ * @param pool - Database connection pool.
182
+ * @param schemaName - Schema name.
183
+ * @param tableName - Name of the table.
184
+ * @param requestedType - The requested json column type.
185
+ * @throws Error if the existing `json` column is neither native `JSON` nor
186
+ * `NVARCHAR(MAX)` (see {@link resolveColumnJsonDataType}).
187
+ */
188
+ async function warnIfJsonTypeMismatch(pool, schemaName, tableName, requestedType) {
189
+ const existingType = await getExistingJsonColumnType(pool, schemaName, tableName);
190
+ if (existingType === null) {
191
+ return;
192
+ }
193
+ const warning = buildJsonTypeMismatchWarning(schemaName, tableName, existingType, requestedType);
194
+ if (warning !== null) {
195
+ // The warning is emitted regardless of quiet mode so the misconfiguration
196
+ // is always visible (SC-005).
197
+ console.warn(warning);
198
+ }
199
+ }
37
200
  /**
38
201
  * Create the fhir_resources table with an index on resource_type.
39
- * Table schema: id (INT IDENTITY PRIMARY KEY), resource_type (NVARCHAR(64)), json (NVARCHAR(MAX))
202
+ * Table schema: id (INT IDENTITY PRIMARY KEY), resource_type (NVARCHAR(64)),
203
+ * json (the configured storage type, NVARCHAR(MAX) by default).
40
204
  *
41
205
  * @param pool - Database connection pool.
42
206
  * @param schemaName - Schema name.
43
207
  * @param tableName - Name of the table to create.
208
+ * @param jsonType - Storage type for the `json` column (default `NVARCHAR(MAX)`).
44
209
  */
45
- async function createTable(pool, schemaName, tableName) {
46
- // Validate identifiers to prevent SQL injection
210
+ async function createTable(pool, schemaName, tableName, jsonType = "NVARCHAR(MAX)") {
211
+ // Validate identifiers to prevent SQL injection. The json type is already a
212
+ // canonical, allowlisted value, so it carries no injection risk.
47
213
  (0, validation_js_1.validateSqlServerIdentifier)(schemaName, "Schema name");
48
214
  (0, validation_js_1.validateSqlServerIdentifier)(tableName, "Table name");
215
+ const { createTable: createTableSql, createIndex: createIndexSql } = buildCreateTableStatements(schemaName, tableName, jsonType);
49
216
  // Create the table.
50
- await pool.request().query(`
51
- CREATE TABLE [${schemaName}].[${tableName}] (
52
- [id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
53
- [resource_type] NVARCHAR(64) NOT NULL,
54
- [json] NVARCHAR(MAX) NOT NULL
55
- )
56
- `);
217
+ await pool.request().query(createTableSql);
57
218
  // Create an index on resource_type for efficient filtering by resource type.
58
- await pool.request().query(`
59
- CREATE INDEX [IX_${tableName}_resource_type]
60
- ON [${schemaName}].[${tableName}] ([resource_type])
61
- `);
219
+ await pool.request().query(createIndexSql);
62
220
  }
63
221
  /**
64
222
  * Truncate a table (remove all rows).
@@ -76,20 +234,28 @@ async function truncateTable(pool, schemaName, tableName) {
76
234
  /**
77
235
  * Ensure the fhir_resources table exists, creating it if necessary.
78
236
  *
237
+ * When the table already exists it is never altered; the requested `json`
238
+ * column type only governs creation of a new table.
239
+ *
79
240
  * @param pool - Database connection pool.
80
241
  * @param schemaName - Schema name.
81
242
  * @param tableName - Name of the table.
82
243
  * @param truncate - Whether to truncate the table if it exists.
244
+ * @param jsonType - Storage type for the `json` column when creating the table
245
+ * (default `NVARCHAR(MAX)`).
83
246
  */
84
- async function ensureTable(pool, schemaName, tableName, truncate = false) {
247
+ async function ensureTable(pool, schemaName, tableName, truncate = false, jsonType = "NVARCHAR(MAX)") {
85
248
  const exists = await tableExists(pool, schemaName, tableName);
86
249
  if (exists) {
250
+ // The table already exists, so the requested type cannot take effect. Warn
251
+ // if it differs from the existing column type, then leave the table as is.
252
+ await warnIfJsonTypeMismatch(pool, schemaName, tableName, jsonType);
87
253
  if (truncate) {
88
254
  await truncateTable(pool, schemaName, tableName);
89
255
  }
90
256
  }
91
257
  else {
92
- await createTable(pool, schemaName, tableName);
258
+ await createTable(pool, schemaName, tableName, jsonType);
93
259
  }
94
260
  }
95
261
  //# sourceMappingURL=tables.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tables.js","sourceRoot":"","sources":["../../src/loader/tables.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;AAaH,kCAeC;AAUD,kCAuBC;AASD,sCAUC;AAUD,kCAeC;AAvGD,kDAAiD;AACjD,oDAA+D;AAE/D;;;;;;;GAOG;AACI,KAAK,UAAU,WAAW,CAC/B,IAAoB,EACpB,UAAkB,EAClB,SAAiB;IAEjB,MAAM,MAAM,GAAG,MAAM,IAAI;SACtB,OAAO,EAAE;SACT,KAAK,CAAC,YAAY,EAAE,eAAG,CAAC,QAAQ,EAAE,UAAU,CAAC;SAC7C,KAAK,CAAC,WAAW,EAAE,eAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC;;;;KAIlD,CAAC,CAAC;IAEL,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,WAAW,CAC/B,IAAoB,EACpB,UAAkB,EAClB,SAAiB;IAEjB,gDAAgD;IAChD,IAAA,2CAA2B,EAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACvD,IAAA,2CAA2B,EAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAErD,oBAAoB;IACpB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC;oBACT,UAAU,MAAM,SAAS;;;;;GAK1C,CAAC,CAAC;IAEH,6EAA6E;IAC7E,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC;uBACN,SAAS;UACtB,UAAU,MAAM,SAAS;GAChC,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,aAAa,CACjC,IAAoB,EACpB,UAAkB,EAClB,SAAiB;IAEjB,gDAAgD;IAChD,IAAA,2CAA2B,EAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACvD,IAAA,2CAA2B,EAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAErD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,mBAAmB,UAAU,MAAM,SAAS,GAAG,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,WAAW,CAC/B,IAAoB,EACpB,UAAkB,EAClB,SAAiB,EACjB,WAAoB,KAAK;IAEzB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAE9D,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACjD,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"tables.js","sourceRoot":"","sources":["../../src/loader/tables.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;AAgCH,gEAqBC;AA8CD,8DAmBC;AAYD,oEAcC;AAUD,kCAeC;AAaD,8DAqBC;AAkBD,wDAyBC;AAYD,kCAmBC;AASD,sCAUC;AAeD,kCAmBC;AAxUD,kDAAiD;AACjD,oDAG0B;AAY1B;;;;;;;;;;;;;GAaG;AACH,SAAgB,0BAA0B,CACxC,UAAkB,EAClB,SAAiB,EACjB,QAA8B;IAE9B,0EAA0E;IAC1E,mEAAmE;IACnE,MAAM,WAAW,GAAG;oBACF,UAAU,MAAM,SAAS;;;eAG9B,QAAQ;;GAEpB,CAAC;IAEF,MAAM,WAAW,GAAG;uBACC,SAAS;UACtB,UAAU,MAAM,SAAS;GAChC,CAAC;IAEF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AACtC,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,gBAAgB,CACvB,QAAgB,EAChB,sBAAqC;IAErC,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,IAAI,sBAAsB,KAAK,IAAI,EAAE,CAAC;QACpC,OAAO,QAAQ,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GACV,sBAAsB,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IACzE,OAAO,GAAG,QAAQ,IAAI,MAAM,GAAG,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,SAAgB,yBAAyB,CACvC,QAAgB,EAChB,sBAAqC;IAErC,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACjD,IAAI,UAAU,KAAK,MAAM,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,4EAA4E;IAC5E,4EAA4E;IAC5E,IAAI,UAAU,KAAK,UAAU,IAAI,sBAAsB,KAAK,CAAC,CAAC,EAAE,CAAC;QAC/D,OAAO,eAAe,CAAC;IACzB,CAAC;IACD,MAAM,IAAI,KAAK,CACb,4BAA4B;QAC1B,GAAG,gBAAgB,CAAC,QAAQ,EAAE,sBAAsB,CAAC,iBAAiB;QACtE,yEAAyE;QACzE,0CAA0C,CAC7C,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,SAAgB,4BAA4B,CAC1C,UAAkB,EAClB,SAAiB,EACjB,YAAkC,EAClC,aAAmC;IAEnC,IAAI,YAAY,KAAK,aAAa,EAAE,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,CACL,mBAAmB,UAAU,MAAM,SAAS,+BAA+B;QAC3E,kBAAkB,YAAY,SAAS,aAAa,sBAAsB;QAC1E,iEAAiE,CAClE,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACI,KAAK,UAAU,WAAW,CAC/B,IAAoB,EACpB,UAAkB,EAClB,SAAiB;IAEjB,MAAM,MAAM,GAAG,MAAM,IAAI;SACtB,OAAO,EAAE;SACT,KAAK,CAAC,YAAY,EAAE,eAAG,CAAC,QAAQ,EAAE,UAAU,CAAC;SAC7C,KAAK,CAAC,WAAW,EAAE,eAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC;;;;KAIlD,CAAC,CAAC;IAEL,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;AACvC,CAAC;AAED;;;;;;;;;;GAUG;AACI,KAAK,UAAU,yBAAyB,CAC7C,IAAoB,EACpB,UAAkB,EAClB,SAAiB;IAEjB,MAAM,MAAM,GAAG,MAAM,IAAI;SACtB,OAAO,EAAE;SACT,KAAK,CAAC,YAAY,EAAE,eAAG,CAAC,QAAQ,EAAE,UAAU,CAAC;SAC7C,KAAK,CAAC,WAAW,EAAE,eAAG,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,KAAK,CAAC;;;;;;KAMlD,CAAC,CAAC;IAEL,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAChC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,yBAAyB,CAAC,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,wBAAwB,CAAC,CAAC;AAChF,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACI,KAAK,UAAU,sBAAsB,CAC1C,IAAoB,EACpB,UAAkB,EAClB,SAAiB,EACjB,aAAmC;IAEnC,MAAM,YAAY,GAAG,MAAM,yBAAyB,CAClD,IAAI,EACJ,UAAU,EACV,SAAS,CACV,CAAC;IACF,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,MAAM,OAAO,GAAG,4BAA4B,CAC1C,UAAU,EACV,SAAS,EACT,YAAY,EACZ,aAAa,CACd,CAAC;IACF,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACrB,0EAA0E;QAC1E,8BAA8B;QAC9B,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACI,KAAK,UAAU,WAAW,CAC/B,IAAoB,EACpB,UAAkB,EAClB,SAAiB,EACjB,WAAiC,eAAe;IAEhD,4EAA4E;IAC5E,iEAAiE;IACjE,IAAA,2CAA2B,EAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACvD,IAAA,2CAA2B,EAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAErD,MAAM,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,GAChE,0BAA0B,CAAC,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAE9D,oBAAoB;IACpB,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAE3C,6EAA6E;IAC7E,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,aAAa,CACjC,IAAoB,EACpB,UAAkB,EAClB,SAAiB;IAEjB,gDAAgD;IAChD,IAAA,2CAA2B,EAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACvD,IAAA,2CAA2B,EAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAErD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,mBAAmB,UAAU,MAAM,SAAS,GAAG,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;;;;GAYG;AACI,KAAK,UAAU,WAAW,CAC/B,IAAoB,EACpB,UAAkB,EAClB,SAAiB,EACjB,WAAoB,KAAK,EACzB,WAAiC,eAAe;IAEhD,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IAE9D,IAAI,MAAM,EAAE,CAAC;QACX,2EAA2E;QAC3E,2EAA2E;QAC3E,MAAM,sBAAsB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACpE,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,WAAW,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Unit tests for pure table DDL generation and existing-column-type resolution.
3
+ *
4
+ * These exercise the string-building and comparison logic without a database,
5
+ * so the byte-for-byte DDL contract (SC-001), the native JSON column type
6
+ * (FR-005) and the type-mismatch decision (FR-008) can be verified in
7
+ * isolation.
8
+ *
9
+ * @author John Grimes
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=tables.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tables.test.d.ts","sourceRoot":"","sources":["../../src/loader/tables.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,130 @@
1
+ "use strict";
2
+ /**
3
+ * Unit tests for pure table DDL generation and existing-column-type resolution.
4
+ *
5
+ * These exercise the string-building and comparison logic without a database,
6
+ * so the byte-for-byte DDL contract (SC-001), the native JSON column type
7
+ * (FR-005) and the type-mismatch decision (FR-008) can be verified in
8
+ * isolation.
9
+ *
10
+ * @author John Grimes
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ const vitest_1 = require("vitest");
14
+ const tables_1 = require("./tables");
15
+ (0, vitest_1.describe)("buildCreateTableStatements", () => {
16
+ (0, vitest_1.describe)("default NVARCHAR(MAX) json column", () => {
17
+ const statements = (0, tables_1.buildCreateTableStatements)("dbo", "fhir_resources", "NVARCHAR(MAX)");
18
+ (0, vitest_1.it)("types the json column as NVARCHAR(MAX) NOT NULL", () => {
19
+ (0, vitest_1.expect)(statements.createTable).toContain("[json] NVARCHAR(MAX) NOT NULL");
20
+ });
21
+ (0, vitest_1.it)("keeps the id column unchanged", () => {
22
+ (0, vitest_1.expect)(statements.createTable).toContain("[id] INT IDENTITY(1,1) NOT NULL PRIMARY KEY");
23
+ });
24
+ (0, vitest_1.it)("keeps the resource_type column unchanged", () => {
25
+ (0, vitest_1.expect)(statements.createTable).toContain("[resource_type] NVARCHAR(64) NOT NULL");
26
+ });
27
+ (0, vitest_1.it)("brackets the schema and table identifiers", () => {
28
+ (0, vitest_1.expect)(statements.createTable).toContain("[dbo].[fhir_resources]");
29
+ });
30
+ (0, vitest_1.it)("builds the resource_type index", () => {
31
+ (0, vitest_1.expect)(statements.createIndex).toContain("[IX_fhir_resources_resource_type]");
32
+ (0, vitest_1.expect)(statements.createIndex).toContain("[dbo].[fhir_resources] ([resource_type])");
33
+ });
34
+ });
35
+ (0, vitest_1.describe)("native JSON json column", () => {
36
+ const statements = (0, tables_1.buildCreateTableStatements)("dbo", "fhir_resources", "JSON");
37
+ (0, vitest_1.it)("types the json column as JSON NOT NULL", () => {
38
+ (0, vitest_1.expect)(statements.createTable).toContain("[json] JSON NOT NULL");
39
+ });
40
+ (0, vitest_1.it)("does not emit NVARCHAR(MAX) for the json column", () => {
41
+ (0, vitest_1.expect)(statements.createTable).not.toContain("[json] NVARCHAR(MAX)");
42
+ });
43
+ (0, vitest_1.it)("keeps the resource_type column unchanged", () => {
44
+ (0, vitest_1.expect)(statements.createTable).toContain("[resource_type] NVARCHAR(64) NOT NULL");
45
+ });
46
+ (0, vitest_1.it)("leaves the index statement identical to the default", () => {
47
+ const defaultStatements = (0, tables_1.buildCreateTableStatements)("dbo", "fhir_resources", "NVARCHAR(MAX)");
48
+ (0, vitest_1.expect)(statements.createIndex).toBe(defaultStatements.createIndex);
49
+ });
50
+ });
51
+ (0, vitest_1.describe)("identifier bracketing", () => {
52
+ (0, vitest_1.it)("brackets custom schema and table names", () => {
53
+ const statements = (0, tables_1.buildCreateTableStatements)("analytics", "resources", "JSON");
54
+ (0, vitest_1.expect)(statements.createTable).toContain("[analytics].[resources]");
55
+ (0, vitest_1.expect)(statements.createIndex).toContain("[IX_resources_resource_type]");
56
+ (0, vitest_1.expect)(statements.createIndex).toContain("[analytics].[resources] ([resource_type])");
57
+ });
58
+ });
59
+ });
60
+ (0, vitest_1.describe)("resolveColumnJsonDataType", () => {
61
+ (0, vitest_1.it)("resolves nvarchar with MAX length to NVARCHAR(MAX)", () => {
62
+ // NVARCHAR(MAX) appears in INFORMATION_SCHEMA as data_type 'nvarchar' with a
63
+ // character_maximum_length of -1.
64
+ (0, vitest_1.expect)((0, tables_1.resolveColumnJsonDataType)("nvarchar", -1)).toBe("NVARCHAR(MAX)");
65
+ });
66
+ (0, vitest_1.it)("resolves json to JSON", () => {
67
+ // The native type appears as data_type 'json' with a null maximum length.
68
+ (0, vitest_1.expect)((0, tables_1.resolveColumnJsonDataType)("json", null)).toBe("JSON");
69
+ });
70
+ (0, vitest_1.it)("is case-insensitive on the data type name", () => {
71
+ (0, vitest_1.expect)((0, tables_1.resolveColumnJsonDataType)("JSON", null)).toBe("JSON");
72
+ (0, vitest_1.expect)((0, tables_1.resolveColumnJsonDataType)("NVARCHAR", -1)).toBe("NVARCHAR(MAX)");
73
+ });
74
+ (0, vitest_1.it)("tolerates surrounding whitespace on the data type name", () => {
75
+ (0, vitest_1.expect)((0, tables_1.resolveColumnJsonDataType)(" json ", null)).toBe("JSON");
76
+ (0, vitest_1.expect)((0, tables_1.resolveColumnJsonDataType)(" nvarchar ", -1)).toBe("NVARCHAR(MAX)");
77
+ });
78
+ // An existing column that is neither native JSON nor NVARCHAR(MAX) cannot
79
+ // faithfully hold a serialised FHIR resource. Such a column must be rejected
80
+ // at the boundary, naming the offending type, rather than silently coerced to
81
+ // NVARCHAR(MAX) - coercion would let the loader write into it and lose data
82
+ // through truncation or, under non-Unicode VARCHAR, character corruption
83
+ // (Constitution Principle IV).
84
+ (0, vitest_1.describe)("rejects column types that cannot hold a FHIR resource", () => {
85
+ (0, vitest_1.it)("throws for a bounded nvarchar, naming the offending type", () => {
86
+ (0, vitest_1.expect)(() => (0, tables_1.resolveColumnJsonDataType)("nvarchar", 64)).toThrow(/NVARCHAR\(64\)/);
87
+ });
88
+ (0, vitest_1.it)("throws for varchar, naming the offending type", () => {
89
+ (0, vitest_1.expect)(() => (0, tables_1.resolveColumnJsonDataType)("varchar", 100)).toThrow(/VARCHAR\(100\)/);
90
+ });
91
+ (0, vitest_1.it)("throws for a max-length varchar, which is still not Unicode-safe", () => {
92
+ // VARCHAR(MAX) reports a length of -1 but is non-Unicode, so it can
93
+ // silently corrupt multi-byte characters and must still be rejected.
94
+ (0, vitest_1.expect)(() => (0, tables_1.resolveColumnJsonDataType)("varchar", -1)).toThrow(/VARCHAR\(MAX\)/);
95
+ });
96
+ (0, vitest_1.it)("throws for text, naming the offending type", () => {
97
+ (0, vitest_1.expect)(() => (0, tables_1.resolveColumnJsonDataType)("text", 2147483647)).toThrow(/TEXT/);
98
+ });
99
+ (0, vitest_1.it)("names both acceptable types in the error message", () => {
100
+ let message = "";
101
+ try {
102
+ (0, tables_1.resolveColumnJsonDataType)("varchar", 100);
103
+ }
104
+ catch (error) {
105
+ message = error.message;
106
+ }
107
+ (0, vitest_1.expect)(message).toContain("NVARCHAR(MAX)");
108
+ (0, vitest_1.expect)(message).toContain("JSON");
109
+ });
110
+ });
111
+ });
112
+ (0, vitest_1.describe)("buildJsonTypeMismatchWarning", () => {
113
+ (0, vitest_1.it)("returns null when the existing and requested types are equal", () => {
114
+ (0, vitest_1.expect)((0, tables_1.buildJsonTypeMismatchWarning)("dbo", "t", "NVARCHAR(MAX)", "NVARCHAR(MAX)")).toBeNull();
115
+ (0, vitest_1.expect)((0, tables_1.buildJsonTypeMismatchWarning)("dbo", "t", "JSON", "JSON")).toBeNull();
116
+ });
117
+ (0, vitest_1.it)("returns a warning naming both types and the table when they differ", () => {
118
+ const warning = (0, tables_1.buildJsonTypeMismatchWarning)("dbo", "fhir_resources", "NVARCHAR(MAX)", "JSON");
119
+ (0, vitest_1.expect)(warning).not.toBeNull();
120
+ (0, vitest_1.expect)(warning).toContain("NVARCHAR(MAX)");
121
+ (0, vitest_1.expect)(warning).toContain("JSON");
122
+ (0, vitest_1.expect)(warning).toContain("fhir_resources");
123
+ });
124
+ (0, vitest_1.it)("names both the existing and the requested type in either direction", () => {
125
+ const warning = (0, tables_1.buildJsonTypeMismatchWarning)("dbo", "t", "JSON", "NVARCHAR(MAX)");
126
+ (0, vitest_1.expect)(warning).toMatch(/JSON/);
127
+ (0, vitest_1.expect)(warning).toMatch(/NVARCHAR\(MAX\)/);
128
+ });
129
+ });
130
+ //# sourceMappingURL=tables.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tables.test.js","sourceRoot":"","sources":["../../src/loader/tables.test.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,15 @@ export interface LoaderOptions {
49
49
  tableName?: string;
50
50
  /** Schema name (default: dbo). */
51
51
  schemaName?: string;
52
+ /**
53
+ * Storage type for the resources table `json` column. One of `NVARCHAR(MAX)`
54
+ * (default) or `JSON`. Matching is case-insensitive and tolerant of
55
+ * surrounding whitespace. `JSON` selects SQL Server 2025's native JSON type
56
+ * and requires SQL Server 2025 or later; when omitted the column is created as
57
+ * `NVARCHAR(MAX)`, exactly as in earlier releases. The value is validated
58
+ * against the allowlist before any database connection is opened.
59
+ */
60
+ resourceJsonDataType?: string;
52
61
  /** Create table if it doesn't exist. */
53
62
  createTable?: boolean;
54
63
  /** Truncate table before loading. */
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/loader/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,qBAAqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,yDAAyD;IACzD,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,kDAAkD;IAClD,YAAY,EAAE,MAAM,CAAC;IACrB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,QAAQ,EAAE,cAAc,CAAC;IACzB,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kEAAkE;IAClE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qCAAqC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iDAAiD;IACjD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,sBAAsB;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4BAA4B;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,SAAS,EAAE,OAAO,CAAC;IACnB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,iCAAiC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,0CAA0C;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,0CAA0C;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,8BAA8B;IAC9B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,WAAW,EAAE,MAAM,CAAC;IACpB,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,yCAAyC;IACzC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/loader/types.ts"],"names":[],"mappings":"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"}
package/dist/parser.d.ts CHANGED
@@ -8,7 +8,7 @@ export declare class ViewDefinitionParser {
8
8
  */
9
9
  static parseViewDefinition(json: string | object): ViewDefinition;
10
10
  /**
11
- * Parse a test suite from the sql-on-fhir-v2 format.
11
+ * Parse a test suite from the SQL on FHIR test format.
12
12
  */
13
13
  static parseTestSuite(json: string | object): TestSuite;
14
14
  /**
package/dist/parser.js CHANGED
@@ -16,7 +16,7 @@ class ViewDefinitionParser {
16
16
  throw new Error("Invalid ViewDefinition structure.");
17
17
  }
18
18
  /**
19
- * Parse a test suite from the sql-on-fhir-v2 format.
19
+ * Parse a test suite from the SQL on FHIR test format.
20
20
  */
21
21
  static parseTestSuite(json) {
22
22
  const data = typeof json === "string" ? JSON.parse(json) : json;
@@ -65,7 +65,6 @@ function buildRootContext(resourceAlias, transpilerCtx) {
65
65
  source: `${resourceAlias}.json`,
66
66
  partitionKeys: [idKey],
67
67
  ancestorApplies: "",
68
- nullable: false,
69
68
  cteCounter: { value: 0 },
70
69
  transpilerCtx,
71
70
  };
@@ -1 +1 @@
1
- {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/compile.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compile.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/compile.ts"],"names":[],"mappings":"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"}
@@ -9,8 +9,10 @@
9
9
  * If a JSON object key contains a literal `.`, two distinct nodes could
10
10
  * theoretically produce equal `__path` strings. FHIR JSON keys do not
11
11
  * contain dots in practice; not a blocker.
12
+ *
13
+ * @author John Grimes
12
14
  */
13
- import type { CteDefinition, PartitionKey } from "./types.js";
15
+ import { type CteDefinition, type PartitionKey } from "./types.js";
14
16
  export interface BuildRepeatCteArgs {
15
17
  cteAlias: string;
16
18
  /** FHIRPath strings — first is the anchor path; all are recursive paths. */
@@ -47,4 +49,10 @@ export interface BuildRepeatCteArgs {
47
49
  * `alias AS (...)` wrapper, which `renderRoot` adds).
48
50
  */
49
51
  export declare function buildRepeatCte(args: BuildRepeatCteArgs): CteDefinition;
52
+ /**
53
+ * Renders the partition keys as a comma-separated list of bracket-quoted
54
+ * columns qualified by `alias` (e.g. `cte.[id], cte.[fe_0_key]`). Shared by the
55
+ * recursive-member projection and the repeat `%rowIndex` window's PARTITION BY.
56
+ */
57
+ export declare function qualifiedKeyCols(alias: string, keys: PartitionKey[]): string;
50
58
  //# sourceMappingURL=cteTemplates.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cteTemplates.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/cteTemplates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAO9D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,eAAe,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,oEAAoE;IACpE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,aAAa,CAOtE"}
1
+ {"version":3,"file":"cteTemplates.d.ts","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/cteTemplates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,YAAY,EAGlB,MAAM,YAAY,CAAC;AAOpB,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,UAAU,EAAE,MAAM,CAAC;IACnB,gFAAgF;IAChF,eAAe,EAAE,MAAM,CAAC;IACxB,sEAAsE;IACtE,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,oEAAoE;IACpE,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,aAAa,CAOtE;AAqED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,GAAG,MAAM,CAE5E"}
@@ -10,9 +10,13 @@
10
10
  * If a JSON object key contains a literal `.`, two distinct nodes could
11
11
  * theoretically produce equal `__path` strings. FHIR JSON keys do not
12
12
  * contain dots in practice; not a blocker.
13
+ *
14
+ * @author John Grimes
13
15
  */
14
16
  Object.defineProperty(exports, "__esModule", { value: true });
15
17
  exports.buildRepeatCte = buildRepeatCte;
18
+ exports.qualifiedKeyCols = qualifiedKeyCols;
19
+ const types_js_1 = require("./types.js");
16
20
  /**
17
21
  * Builds the SQL body of the recursive CTE used by the Repeat operator.
18
22
  *
@@ -50,7 +54,8 @@ function buildAnchorMember(args) {
50
54
  const wherePart = resourcePredicate ? `\n ${resourcePredicate}` : "";
51
55
  return ` SELECT
52
56
  ${projLines},
53
- CAST(${chain.lastAlias}.[key] AS NVARCHAR(MAX)) AS __path,
57
+ CAST(${chain.lastAlias}.[key] AS ${types_js_1.SQL_NVARCHAR_MAX}) AS __path,
58
+ CAST(${orderSegment(chain.lastAlias)} AS ${types_js_1.SQL_NVARCHAR_MAX}) AS __order,
54
59
  ${chain.lastAlias}.value AS item_json,
55
60
  0 AS depth
56
61
  ${fromClause}${ancestorApplies}
@@ -58,16 +63,47 @@ function buildAnchorMember(args) {
58
63
  }
59
64
  function buildRecursiveMember(args, path, index) {
60
65
  const { cteAlias, partitionKeys } = args;
61
- const head = partitionKeys.map((k) => `cte.[${k.name}]`).join(", ");
66
+ const head = qualifiedKeyCols("cte", partitionKeys);
62
67
  const chain = buildOpenJsonChain("cte.item_json", path, `child_${index}`);
63
68
  return ` SELECT
64
69
  ${head},
65
- cte.__path + '.' + CAST(${chain.lastAlias}.[key] AS NVARCHAR(4000)) AS __path,
70
+ cte.__path + '.' + CAST(${chain.lastAlias}.[key] AS ${types_js_1.SQL_NVARCHAR_4000}) AS __path,
71
+ cte.__order + '.' + ${orderSegment(chain.lastAlias)} AS __order,
66
72
  ${chain.lastAlias}.value AS item_json,
67
73
  cte.depth + 1
68
74
  FROM ${cteAlias} AS cte
69
75
  ${chain.applyClauses}`;
70
76
  }
77
+ /**
78
+ * Width, in characters, that each `__order` segment is zero-padded to. A level
79
+ * with up to 10^ORDER_SEGMENT_WIDTH elements still sorts correctly; ten digits
80
+ * assume no single level exceeds 10^10 elements.
81
+ */
82
+ const ORDER_SEGMENT_WIDTH = 10;
83
+ /**
84
+ * Builds one segment of the `__order` accumulator: the element's `[key]`
85
+ * zero-padded to a fixed width so that lexical ordering of the `.`-joined
86
+ * order string is equivalent to numeric depth-first (pre-order) traversal.
87
+ * Without padding, lexical order would break once a level has ten or more
88
+ * elements (e.g. `"10" < "2"`). This is what `%rowIndex` orders by inside a
89
+ * `repeat`.
90
+ *
91
+ * `__order` is emitted by every repeat CTE unconditionally: the walker builds
92
+ * the CTE before descending into the inner subtree, so whether `%rowIndex` is
93
+ * actually referenced is not yet known when the column list is generated.
94
+ */
95
+ function orderSegment(alias) {
96
+ const pad = "0".repeat(ORDER_SEGMENT_WIDTH);
97
+ return `RIGHT('${pad}' + CAST(${alias}.[key] AS NVARCHAR(${ORDER_SEGMENT_WIDTH})), ${ORDER_SEGMENT_WIDTH})`;
98
+ }
99
+ /**
100
+ * Renders the partition keys as a comma-separated list of bracket-quoted
101
+ * columns qualified by `alias` (e.g. `cte.[id], cte.[fe_0_key]`). Shared by the
102
+ * recursive-member projection and the repeat `%rowIndex` window's PARTITION BY.
103
+ */
104
+ function qualifiedKeyCols(alias, keys) {
105
+ return keys.map((k) => `${alias}.[${k.name}]`).join(", ");
106
+ }
71
107
  /**
72
108
  * Builds the CROSS APPLY OPENJSON chain for a (possibly multi-segment) path.
73
109
  * For "a.b.c" produces three chained APPLYs; the last alias is `finalAlias`.
@@ -1 +1 @@
1
- {"version":3,"file":"cteTemplates.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/cteTemplates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cteTemplates.js","sourceRoot":"","sources":["../../../src/queryGenerator/treeWalker/cteTemplates.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,8 @@
8
8
  *
9
9
  * Path-handling parity is delegated to PathParser (`.where()`, `.first()`,
10
10
  * array indexing, multi-segment array flattening).
11
+ *
12
+ * @author John Grimes
11
13
  */
12
14
  import type { ViewDefinitionSelect } from "../../../types.js";
13
15
  import type { PathParser } from "../../PathParser.js";
@@ -32,8 +34,8 @@ interface ForEachDeps {
32
34
  * @param node - The ForEach or ForEachOrNull select node. `node.forEach` or
33
35
  * `node.forEachOrNull` supplies the FHIRPath expression to iterate.
34
36
  * @param ctx - The current walker context; the inner context is derived from
35
- * it by updating `source`, `partitionKeys`, `ancestorApplies`, `nullable`,
36
- * and `transpilerCtx`.
37
+ * it by updating `source`, `partitionKeys`, `ancestorApplies`, and
38
+ * `transpilerCtx`.
37
39
  * @param walk - The recursive walk function used to visit the inner sub-tree.
38
40
  * @param deps - Dependencies containing the `PathParser` used to parse and
39
41
  * decompose the FHIRPath expression.