sof-mssql 2.3.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 (57) 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.map +1 -1
  7. package/dist/fhirpath/visitor.js +20 -12
  8. package/dist/fhirpath/visitor.js.map +1 -1
  9. package/dist/load.d.ts +9 -0
  10. package/dist/load.d.ts.map +1 -1
  11. package/dist/load.js +4 -0
  12. package/dist/load.js.map +1 -1
  13. package/dist/loader/feedback.integration.test.d.ts +14 -0
  14. package/dist/loader/feedback.integration.test.d.ts.map +1 -0
  15. package/dist/loader/feedback.integration.test.js +76 -0
  16. package/dist/loader/feedback.integration.test.js.map +1 -0
  17. package/dist/loader/index.d.ts.map +1 -1
  18. package/dist/loader/index.js +19 -6
  19. package/dist/loader/index.js.map +1 -1
  20. package/dist/loader/jsonColumn.integration.test.d.ts +13 -0
  21. package/dist/loader/jsonColumn.integration.test.d.ts.map +1 -0
  22. package/dist/loader/jsonColumn.integration.test.js +86 -0
  23. package/dist/loader/jsonColumn.integration.test.js.map +1 -0
  24. package/dist/loader/tables.d.ts +96 -3
  25. package/dist/loader/tables.d.ts.map +1 -1
  26. package/dist/loader/tables.js +182 -16
  27. package/dist/loader/tables.js.map +1 -1
  28. package/dist/loader/tables.test.d.ts +12 -0
  29. package/dist/loader/tables.test.d.ts.map +1 -0
  30. package/dist/loader/tables.test.js +130 -0
  31. package/dist/loader/tables.test.js.map +1 -0
  32. package/dist/loader/types.d.ts +9 -0
  33. package/dist/loader/types.d.ts.map +1 -1
  34. package/dist/tests/load.test.d.ts +11 -0
  35. package/dist/tests/load.test.d.ts.map +1 -0
  36. package/dist/tests/load.test.js +37 -0
  37. package/dist/tests/load.test.js.map +1 -0
  38. package/dist/tests/utils/database.d.ts.map +1 -1
  39. package/dist/tests/utils/database.js +51 -3
  40. package/dist/tests/utils/database.js.map +1 -1
  41. package/dist/tests/utils/loaderIntegration.d.ts +59 -0
  42. package/dist/tests/utils/loaderIntegration.d.ts.map +1 -0
  43. package/dist/tests/utils/loaderIntegration.js +137 -0
  44. package/dist/tests/utils/loaderIntegration.js.map +1 -0
  45. package/dist/tests/utils/serverCapabilities.d.ts +23 -0
  46. package/dist/tests/utils/serverCapabilities.d.ts.map +1 -0
  47. package/dist/tests/utils/serverCapabilities.js +35 -0
  48. package/dist/tests/utils/serverCapabilities.js.map +1 -0
  49. package/dist/tests/validation.test.d.ts +13 -0
  50. package/dist/tests/validation.test.d.ts.map +1 -0
  51. package/dist/tests/validation.test.js +81 -0
  52. package/dist/tests/validation.test.js.map +1 -0
  53. package/dist/validation.d.ts +40 -0
  54. package/dist/validation.d.ts.map +1 -1
  55. package/dist/validation.js +56 -0
  56. package/dist/validation.js.map +1 -1
  57. package/package.json +1 -1
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ /**
3
+ * Integration tests for misconfiguration feedback (US4).
4
+ *
5
+ * Covers: invalid values rejected before any connection is opened (FR-003,
6
+ * runs without a database); an existing-table type mismatch emitting a warning
7
+ * and leaving the table unaltered (FR-008, runs on any server); and the SQL
8
+ * Server "unsupported type" error being surfaced rather than swallowed when
9
+ * JSON is requested on a server that does not support it (FR-009, runs only on
10
+ * pre-2025 servers).
11
+ *
12
+ * @author John Grimes
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const vitest_1 = require("vitest");
16
+ const index_1 = require("./index");
17
+ const loaderIntegration_1 = require("../tests/utils/loaderIntegration");
18
+ const harness = (0, loaderIntegration_1.createLoaderIntegrationHarness)();
19
+ (0, vitest_1.beforeAll)(() => harness.connect());
20
+ (0, vitest_1.afterAll)(() => harness.cleanup());
21
+ (0, vitest_1.describe)("invalid resourceJsonDataType (US4, no database required)", () => {
22
+ (0, vitest_1.it)("throws before opening a connection", async () => {
23
+ // The database host is unroutable. If validation did not run first, the
24
+ // call would fail with a connection error; instead it must fail with the
25
+ // validation error, proving no connection was attempted (FR-003).
26
+ await (0, vitest_1.expect)((0, index_1.loadNdjsonFiles)({
27
+ directory: "/nonexistent-directory",
28
+ database: {
29
+ host: "203.0.113.1",
30
+ user: "unused",
31
+ password: "unused",
32
+ database: "unused",
33
+ },
34
+ resourceJsonDataType: "TEXT",
35
+ })).rejects.toThrow(/Invalid resource JSON data type.*TEXT/s);
36
+ });
37
+ });
38
+ (0, vitest_1.describe)("existing-table type mismatch (US4)", () => {
39
+ (0, vitest_1.it)("warns naming both types and does not alter the existing table", async () => {
40
+ // First load creates the table as the default NVARCHAR(MAX).
41
+ const tableName = harness.makeTableName();
42
+ await harness.loadSample(tableName);
43
+ // Second load requests JSON against the now-existing NVARCHAR(MAX) table.
44
+ const warnSpy = vitest_1.vi.spyOn(console, "warn").mockImplementation(() => { });
45
+ let warnings = [];
46
+ try {
47
+ await harness.loadSample(tableName, "JSON");
48
+ warnings = warnSpy.mock.calls.map((call) => call.join(" "));
49
+ }
50
+ finally {
51
+ warnSpy.mockRestore();
52
+ }
53
+ // A warning naming both the existing and requested types must be emitted.
54
+ const mismatchWarning = warnings.find((w) => w.includes("NVARCHAR(MAX)") &&
55
+ w.includes("JSON") &&
56
+ w.includes(tableName));
57
+ (0, vitest_1.expect)(mismatchWarning).toBeDefined();
58
+ // The table must be left unaltered (still NVARCHAR(MAX)).
59
+ const columnType = await harness.getJsonColumnType(tableName);
60
+ (0, vitest_1.expect)(columnType.dataType).toBe("nvarchar");
61
+ (0, vitest_1.expect)(columnType.maxLength).toBe(-1);
62
+ });
63
+ });
64
+ (0, vitest_1.describe)("JSON requested on an unsupporting server (US4)", () => {
65
+ (0, vitest_1.it)("surfaces the SQL Server error rather than swallowing it", async (ctx) => {
66
+ // Only meaningful on servers without the native JSON type; on SQL Server
67
+ // 2025+ the request succeeds, so this is skipped there. CI exercises it on
68
+ // the 2017/2019/2022 matrix dimensions (FR-009).
69
+ if (harness.isNativeJsonSupported()) {
70
+ ctx.skip();
71
+ }
72
+ const tableName = harness.makeTableName();
73
+ await (0, vitest_1.expect)(harness.loadSample(tableName, "JSON")).rejects.toThrow();
74
+ });
75
+ });
76
+ //# sourceMappingURL=feedback.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.integration.test.js","sourceRoot":"","sources":["../../src/loader/feedback.integration.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/loader/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAEV,aAAa,EAEb,aAAa,EACd,MAAM,YAAY,CAAC;AAiNpB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,aAAa,CAAC,CA6BxB;AAED;;GAEG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/loader/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAEV,aAAa,EAEb,aAAa,EACd,MAAM,YAAY,CAAC;AAkOpB;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,aAAa,CAAC,CAqCxB;AAED;;GAEG;AACH,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC"}
@@ -21,6 +21,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
21
  };
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
23
  exports.loadNdjsonFiles = loadNdjsonFiles;
24
+ const validation_js_1 = require("../validation.js");
24
25
  const connection_js_1 = require("./connection.js");
25
26
  const discovery_js_1 = require("./discovery.js");
26
27
  const tables_js_1 = require("./tables.js");
@@ -74,14 +75,20 @@ function chunkFiles(files, chunkSize) {
74
75
  * @param options - Loader options.
75
76
  * @returns Table schema and name.
76
77
  */
77
- async function prepareTable(pool, options) {
78
+ async function prepareTable(pool, options, jsonType) {
78
79
  const schemaName = options.schemaName ?? "dbo";
79
80
  const tableName = options.tableName ?? "fhir_resources";
80
81
  if (options.createTable !== false) {
81
82
  if (options.verbose) {
82
- console.log(`Ensuring table [${schemaName}].[${tableName}] exists${options.truncate ? " (will truncate)" : ""}...`);
83
+ console.log(`Ensuring table [${schemaName}].[${tableName}] exists as [json] ${jsonType}${options.truncate ? " (will truncate)" : ""}...`);
83
84
  }
84
- await (0, tables_js_1.ensureTable)(pool, schemaName, tableName, options.truncate ?? false);
85
+ await (0, tables_js_1.ensureTable)(pool, schemaName, tableName, options.truncate ?? false, jsonType);
86
+ }
87
+ else {
88
+ // Table creation is disabled, so the requested type cannot be applied.
89
+ // Still surface a mismatch against an existing table so misconfiguration
90
+ // remains visible (FR-008 edge case).
91
+ await (0, tables_js_1.warnIfJsonTypeMismatch)(pool, schemaName, tableName, jsonType);
85
92
  }
86
93
  return { schemaName, tableName };
87
94
  }
@@ -129,7 +136,7 @@ async function loadFilesInChunks(pool, files, options, schemaName, tableName, pr
129
136
  * @param startTime - Start timestamp.
130
137
  * @returns Loader summary.
131
138
  */
132
- async function performLoad(pool, files, options, startTime) {
139
+ async function performLoad(pool, files, options, startTime, jsonType) {
133
140
  const connected = await (0, connection_js_1.testConnection)(pool);
134
141
  if (!connected) {
135
142
  throw new Error("Failed to connect to database");
@@ -138,7 +145,7 @@ async function performLoad(pool, files, options, startTime) {
138
145
  console.log("Connected successfully\n");
139
146
  }
140
147
  const progress = (0, progress_js_1.createProgressTracker)(files);
141
- const { schemaName, tableName } = await prepareTable(pool, options);
148
+ const { schemaName, tableName } = await prepareTable(pool, options, jsonType);
142
149
  if (!options.quiet) {
143
150
  console.log("Loading files...\n");
144
151
  }
@@ -160,6 +167,12 @@ async function performLoad(pool, files, options, startTime) {
160
167
  */
161
168
  async function loadNdjsonFiles(options) {
162
169
  const startTime = Date.now();
170
+ // Resolve and validate the json column storage type before any file
171
+ // discovery, connection or DDL. An invalid value throws synchronously here,
172
+ // so misconfiguration is reported before a connection is opened (FR-003).
173
+ const jsonType = options.resourceJsonDataType === undefined
174
+ ? "NVARCHAR(MAX)"
175
+ : (0, validation_js_1.normaliseResourceJsonDataType)(options.resourceJsonDataType);
163
176
  const files = discoverAndLogFiles(options);
164
177
  if (files.length === 0) {
165
178
  return (0, progress_js_1.createSummary)((0, progress_js_1.createProgressTracker)([]), Date.now() - startTime);
@@ -175,7 +188,7 @@ async function loadNdjsonFiles(options) {
175
188
  }
176
189
  const pool = await (0, connection_js_1.createConnectionPool)(options.database);
177
190
  try {
178
- return await performLoad(pool, files, options, startTime);
191
+ return await performLoad(pool, files, options, startTime, jsonType);
179
192
  }
180
193
  finally {
181
194
  await (0, connection_js_1.closeConnectionPool)(pool);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/loader/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;AA8NH,0CA+BC;AApPD,mDAIyB;AACzB,iDAAyE;AACzE,2CAA0C;AAC1C,2CAAuC;AACvC,+CASuB;AAEvB;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,OAAsB;IACjD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,+BAA+B,OAAO,CAAC,SAAS,KAAK,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,KAAK,GAAG,IAAA,4BAAa,EAAC,OAAO,CAAC,CAAC;IAErC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC7D,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,mBAAmB,GAAG,IAAA,uCAAwB,EAAC,KAAK,CAAC,CAAC;QAC5D,OAAO,CAAC,GAAG,CACT,SAAS,KAAK,CAAC,MAAM,gBAAgB,mBAAmB,CAAC,IAAI,sBAAsB,CACpF,CAAC;QACF,KAAK,MAAM,CAAC,YAAY,EAAE,aAAa,CAAC,IAAI,mBAAmB,EAAE,CAAC;YAChE,OAAO,CAAC,GAAG,CAAC,KAAK,YAAY,KAAK,aAAa,CAAC,MAAM,UAAU,CAAC,CAAC;QACpE,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;GAMG;AACH,SAAS,UAAU,CACjB,KAAuB,EACvB,SAAiB;IAEjB,MAAM,MAAM,GAAuB,EAAE,CAAC;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;QACjD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAC7C,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;GAMG;AACH,KAAK,UAAU,YAAY,CACzB,IAAoB,EACpB,OAAsB;IAEtB,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;IAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,gBAAgB,CAAC;IAExD,IAAI,OAAO,CAAC,WAAW,KAAK,KAAK,EAAE,CAAC;QAClC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;YACpB,OAAO,CAAC,GAAG,CACT,mBAAmB,UAAU,MAAM,SAAS,WAAW,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,KAAK,CACvG,CAAC;QACJ,CAAC;QACD,MAAM,IAAA,uBAAW,EAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC;IAC5E,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC;AACnC,CAAC;AAED;;;;;;;;;GASG;AACH,KAAK,UAAU,iBAAiB,CAC9B,IAAoB,EACpB,KAAuB,EACvB,OAAsB,EACtB,UAAkB,EAClB,SAAiB,EACjB,QAAwB;IAExB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC;IACvC,MAAM,eAAe,GAAG,OAAO,CAAC,eAAe,IAAI,KAAK,CAAC;IACzD,MAAM,UAAU,GAAG,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAE/C,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;QAC/B,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YAC5C,IAAA,oCAAsB,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAEvC,MAAM,MAAM,GAAG,MAAM,IAAA,oBAAQ,EAC3B,IAAI,EACJ,IAAI,EACJ,UAAU,EACV,SAAS,EACT,OAAO,CAAC,SAAS,IAAI,IAAI,EACzB,CAAC,UAAU,EAAE,EAAE;gBACb,IAAA,gCAAkB,EAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACpD,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;oBACzC,IAAA,iCAAmB,EAAC,QAAQ,CAAC,CAAC;gBAChC,CAAC;YACH,CAAC,CACF,CAAC;YAEF,IAAA,kCAAoB,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAEvC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACpB,IAAA,kCAAoB,EAAC,QAAQ,CAAC,CAAC;YACjC,CAAC;YAED,IAAI,MAAM,CAAC,KAAK,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrC,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;YAClE,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,KAAK,UAAU,WAAW,CACxB,IAAoB,EACpB,KAAuB,EACvB,OAAsB,EACtB,SAAiB;IAEjB,MAAM,SAAS,GAAG,MAAM,IAAA,8BAAc,EAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IAC1C,CAAC;IAED,MAAM,QAAQ,GAAG,IAAA,mCAAqB,EAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAEpE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACpC,CAAC;IAED,MAAM,iBAAiB,CACrB,IAAI,EACJ,KAAK,EACL,OAAO,EACP,UAAU,EACV,SAAS,EACT,QAAQ,CACT,CAAC;IAEF,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC3D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,2BAAa,EAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;IAEhE,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,IAAA,0BAAY,EAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,eAAe,CACnC,OAAsB;IAEtB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAE3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,IAAA,2BAAa,EAAC,IAAA,mCAAqB,EAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,IAAA,2BAAa,EAAC,IAAA,mCAAqB,EAAC,KAAK,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;IAC7E,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CACT,+BAA+B,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,IAAI,IAAI,KAAK,CAC3F,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,IAAA,oCAAoB,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE1D,IAAI,CAAC;QACH,OAAO,MAAM,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC5D,CAAC;YAAS,CAAC;QACT,MAAM,IAAA,mCAAmB,EAAC,IAAI,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,6CAA2B;AAC3B,kDAAgC;AAChC,iDAA+B;AAC/B,8CAA4B;AAC5B,8CAA4B;AAC5B,gDAA8B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/loader/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Database-backed integration tests for the configurable `json` column type.
3
+ *
4
+ * Exercises the loader end to end against a real SQL Server: the default
5
+ * `NVARCHAR(MAX)` column (US1, every supported version) and the native `JSON`
6
+ * column (US1/US2, SQL Server 2025+ only). The native-JSON cases skip
7
+ * automatically on servers that do not support the type, so the same file is
8
+ * safe to run across the whole CI matrix.
9
+ *
10
+ * @author John Grimes
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=jsonColumn.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonColumn.integration.test.d.ts","sourceRoot":"","sources":["../../src/loader/jsonColumn.integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ /**
3
+ * Database-backed integration tests for the configurable `json` column type.
4
+ *
5
+ * Exercises the loader end to end against a real SQL Server: the default
6
+ * `NVARCHAR(MAX)` column (US1, every supported version) and the native `JSON`
7
+ * column (US1/US2, SQL Server 2025+ only). The native-JSON cases skip
8
+ * automatically on servers that do not support the type, so the same file is
9
+ * safe to run across the whole CI matrix.
10
+ *
11
+ * @author John Grimes
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ const vitest_1 = require("vitest");
15
+ const loaderIntegration_1 = require("../tests/utils/loaderIntegration");
16
+ const harness = (0, loaderIntegration_1.createLoaderIntegrationHarness)();
17
+ (0, vitest_1.beforeAll)(() => harness.connect());
18
+ (0, vitest_1.afterAll)(() => harness.cleanup());
19
+ (0, vitest_1.describe)("loadNdjsonFiles json column type (US1)", () => {
20
+ (0, vitest_1.it)("creates an NVARCHAR(MAX) column and loads every row when the type is omitted", async () => {
21
+ // The default path must be unchanged from earlier releases (SC-001).
22
+ const tableName = harness.makeTableName();
23
+ const rowsLoaded = await harness.loadSample(tableName);
24
+ (0, vitest_1.expect)(rowsLoaded).toBe(loaderIntegration_1.SAMPLE_PATIENTS.length);
25
+ const columnType = await harness.getJsonColumnType(tableName);
26
+ (0, vitest_1.expect)(columnType.dataType).toBe("nvarchar");
27
+ (0, vitest_1.expect)(columnType.maxLength).toBe(-1);
28
+ (0, vitest_1.expect)(await harness.getRowCount(tableName)).toBe(loaderIntegration_1.SAMPLE_PATIENTS.length);
29
+ });
30
+ (0, vitest_1.it)("creates a native JSON column and loads every row when JSON is requested", async (ctx) => {
31
+ if (!harness.isNativeJsonSupported()) {
32
+ ctx.skip();
33
+ }
34
+ const tableName = harness.makeTableName();
35
+ const rowsLoaded = await harness.loadSample(tableName, "JSON");
36
+ (0, vitest_1.expect)(rowsLoaded).toBe(loaderIntegration_1.SAMPLE_PATIENTS.length);
37
+ const columnType = await harness.getJsonColumnType(tableName);
38
+ (0, vitest_1.expect)(columnType.dataType).toBe("json");
39
+ (0, vitest_1.expect)(await harness.getRowCount(tableName)).toBe(loaderIntegration_1.SAMPLE_PATIENTS.length);
40
+ });
41
+ (0, vitest_1.it)("accepts a lower-case json value and still creates the native type", async (ctx) => {
42
+ if (!harness.isNativeJsonSupported()) {
43
+ ctx.skip();
44
+ }
45
+ const tableName = harness.makeTableName();
46
+ await harness.loadSample(tableName, "json");
47
+ const columnType = await harness.getJsonColumnType(tableName);
48
+ (0, vitest_1.expect)(columnType.dataType).toBe("json");
49
+ });
50
+ });
51
+ (0, vitest_1.describe)("loadNdjsonFiles json column type (US2 - programmatic, no CLI)", () => {
52
+ // loadSample calls loadNdjsonFiles with LoaderOptions directly, demonstrating
53
+ // that the capability is fully available through the programmatic API with no
54
+ // CLI or commander layer involved.
55
+ (0, vitest_1.it)("honours LoaderOptions.resourceJsonDataType = JSON via the programmatic API", async (ctx) => {
56
+ if (!harness.isNativeJsonSupported()) {
57
+ ctx.skip();
58
+ }
59
+ const tableName = harness.makeTableName();
60
+ const rowsLoaded = await harness.loadSample(tableName, "JSON");
61
+ (0, vitest_1.expect)(rowsLoaded).toBe(loaderIntegration_1.SAMPLE_PATIENTS.length);
62
+ const columnType = await harness.getJsonColumnType(tableName);
63
+ (0, vitest_1.expect)(columnType.dataType).toBe("json");
64
+ });
65
+ (0, vitest_1.it)("defaults to NVARCHAR(MAX) programmatically when the option is omitted", async () => {
66
+ const tableName = harness.makeTableName();
67
+ const rowsLoaded = await harness.loadSample(tableName);
68
+ (0, vitest_1.expect)(rowsLoaded).toBe(loaderIntegration_1.SAMPLE_PATIENTS.length);
69
+ const columnType = await harness.getJsonColumnType(tableName);
70
+ (0, vitest_1.expect)(columnType.dataType).toBe("nvarchar");
71
+ (0, vitest_1.expect)(columnType.maxLength).toBe(-1);
72
+ });
73
+ });
74
+ (0, vitest_1.describe)("loadNdjsonFiles existing json column safeguard (FR-008)", () => {
75
+ (0, vitest_1.it)("fails fast when an existing json column cannot hold a FHIR resource", async () => {
76
+ // A pre-existing table whose json column is a bounded VARCHAR cannot hold a
77
+ // serialised FHIR resource. The loader must reject it before writing any
78
+ // rows, rather than coercing it to NVARCHAR(MAX) and corrupting data.
79
+ const tableName = harness.makeTableName();
80
+ await harness.createTableWithJsonColumnType(tableName, "VARCHAR(100)");
81
+ await (0, vitest_1.expect)(harness.loadSample(tableName)).rejects.toThrow(/VARCHAR\(100\)/);
82
+ // No rows must have been written into the unsafe column.
83
+ (0, vitest_1.expect)(await harness.getRowCount(tableName)).toBe(0);
84
+ });
85
+ });
86
+ //# sourceMappingURL=jsonColumn.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jsonColumn.integration.test.js","sourceRoot":"","sources":["../../src/loader/jsonColumn.integration.test.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,63 @@
5
5
  * @author John Grimes
6
6
  */
7
7
  import { type ConnectionPool } from "mssql";
8
+ import { type ResourceJsonDataType } from "../validation.js";
9
+ /**
10
+ * The DDL statements needed to create the resources table and its index.
11
+ */
12
+ export interface CreateTableStatements {
13
+ /** The `CREATE TABLE` statement. */
14
+ createTable: string;
15
+ /** The `CREATE INDEX` statement for the `resource_type` column. */
16
+ createIndex: string;
17
+ }
18
+ /**
19
+ * Build the DDL statements for the resources table and its index.
20
+ *
21
+ * This is a pure function so the generated SQL can be unit-tested without a
22
+ * database. The `json` column is typed with the resolved {@link
23
+ * ResourceJsonDataType}; with the default `NVARCHAR(MAX)` the output is
24
+ * byte-for-byte identical to earlier releases (SC-001). Identifiers are assumed
25
+ * to have been validated by the caller (see {@link createTable}).
26
+ *
27
+ * @param schemaName - Schema name (already validated).
28
+ * @param tableName - Table name (already validated).
29
+ * @param jsonType - Resolved canonical storage type for the `json` column.
30
+ * @returns The `CREATE TABLE` and `CREATE INDEX` statements.
31
+ */
32
+ export declare function buildCreateTableStatements(schemaName: string, tableName: string, jsonType: ResourceJsonDataType): CreateTableStatements;
33
+ /**
34
+ * Resolve an INFORMATION_SCHEMA column description to a canonical json type.
35
+ *
36
+ * Only two column shapes can faithfully hold a serialised FHIR resource: the
37
+ * native type (`data_type = 'json'`) and `NVARCHAR(MAX)` (`data_type =
38
+ * 'nvarchar'` with `character_maximum_length = -1`). Any other shape - a bounded
39
+ * `NVARCHAR(64)`, a non-Unicode `VARCHAR`, `TEXT`, and so on - is rejected here
40
+ * rather than silently coerced to `NVARCHAR(MAX)`. Coercion would let the
41
+ * mismatch check pass and the loader write into a column that cannot hold the
42
+ * data, surfacing later as a `String or binary data would be truncated` error
43
+ * or, under non-Unicode `VARCHAR`, silent character corruption. Failing fast
44
+ * turns that late, data-dependent failure into an early, actionable
45
+ * configuration error (Constitution Principle IV).
46
+ *
47
+ * @param dataType - The INFORMATION_SCHEMA DATA_TYPE.
48
+ * @param characterMaximumLength - The INFORMATION_SCHEMA CHARACTER_MAXIMUM_LENGTH.
49
+ * @returns The canonical resource json data type (`JSON` or `NVARCHAR(MAX)`).
50
+ * @throws Error if the column is neither native `JSON` nor `NVARCHAR(MAX)`. The
51
+ * message names the offending type and the two acceptable types.
52
+ */
53
+ export declare function resolveColumnJsonDataType(dataType: string, characterMaximumLength: number | null): ResourceJsonDataType;
54
+ /**
55
+ * Build a warning for an existing table whose json column type differs from the
56
+ * requested type.
57
+ *
58
+ * @param schemaName - Schema name.
59
+ * @param tableName - Table name.
60
+ * @param existingType - The table's current json column type.
61
+ * @param requestedType - The requested json column type.
62
+ * @returns A warning message naming both types, or null when they match.
63
+ */
64
+ export declare function buildJsonTypeMismatchWarning(schemaName: string, tableName: string, existingType: ResourceJsonDataType, requestedType: ResourceJsonDataType): string | null;
8
65
  /**
9
66
  * Check if a table exists in the database.
10
67
  *
@@ -14,15 +71,46 @@ import { type ConnectionPool } from "mssql";
14
71
  * @returns Promise that resolves to true if the table exists.
15
72
  */
16
73
  export declare function tableExists(pool: ConnectionPool, schemaName: string, tableName: string): Promise<boolean>;
74
+ /**
75
+ * Read the effective json column type for an existing table.
76
+ *
77
+ * @param pool - Database connection pool.
78
+ * @param schemaName - Schema name.
79
+ * @param tableName - Name of the table.
80
+ * @returns The canonical json column type, or null if the table or its `json`
81
+ * column does not exist.
82
+ * @throws Error if the column exists but is neither native `JSON` nor
83
+ * `NVARCHAR(MAX)` (see {@link resolveColumnJsonDataType}).
84
+ */
85
+ export declare function getExistingJsonColumnType(pool: ConnectionPool, schemaName: string, tableName: string): Promise<ResourceJsonDataType | null>;
86
+ /**
87
+ * Emit a warning if an existing table's json column type differs from the
88
+ * requested type. The table is never altered; this only surfaces the mismatch
89
+ * so it is visible rather than silently ignored (FR-008, SC-005).
90
+ *
91
+ * An existing column that is neither native `JSON` nor `NVARCHAR(MAX)` cannot
92
+ * hold a serialised FHIR resource, so it is rejected outright rather than
93
+ * warned about: the error is raised here before any rows are loaded.
94
+ *
95
+ * @param pool - Database connection pool.
96
+ * @param schemaName - Schema name.
97
+ * @param tableName - Name of the table.
98
+ * @param requestedType - The requested json column type.
99
+ * @throws Error if the existing `json` column is neither native `JSON` nor
100
+ * `NVARCHAR(MAX)` (see {@link resolveColumnJsonDataType}).
101
+ */
102
+ export declare function warnIfJsonTypeMismatch(pool: ConnectionPool, schemaName: string, tableName: string, requestedType: ResourceJsonDataType): Promise<void>;
17
103
  /**
18
104
  * Create the fhir_resources table with an index on resource_type.
19
- * Table schema: id (INT IDENTITY PRIMARY KEY), resource_type (NVARCHAR(64)), json (NVARCHAR(MAX))
105
+ * Table schema: id (INT IDENTITY PRIMARY KEY), resource_type (NVARCHAR(64)),
106
+ * json (the configured storage type, NVARCHAR(MAX) by default).
20
107
  *
21
108
  * @param pool - Database connection pool.
22
109
  * @param schemaName - Schema name.
23
110
  * @param tableName - Name of the table to create.
111
+ * @param jsonType - Storage type for the `json` column (default `NVARCHAR(MAX)`).
24
112
  */
25
- export declare function createTable(pool: ConnectionPool, schemaName: string, tableName: string): Promise<void>;
113
+ export declare function createTable(pool: ConnectionPool, schemaName: string, tableName: string, jsonType?: ResourceJsonDataType): Promise<void>;
26
114
  /**
27
115
  * Truncate a table (remove all rows).
28
116
  *
@@ -34,10 +122,15 @@ export declare function truncateTable(pool: ConnectionPool, schemaName: string,
34
122
  /**
35
123
  * Ensure the fhir_resources table exists, creating it if necessary.
36
124
  *
125
+ * When the table already exists it is never altered; the requested `json`
126
+ * column type only governs creation of a new table.
127
+ *
37
128
  * @param pool - Database connection pool.
38
129
  * @param schemaName - Schema name.
39
130
  * @param tableName - Name of the table.
40
131
  * @param truncate - Whether to truncate the table if it exists.
132
+ * @param jsonType - Storage type for the `json` column when creating the table
133
+ * (default `NVARCHAR(MAX)`).
41
134
  */
42
- export declare function ensureTable(pool: ConnectionPool, schemaName: string, tableName: string, truncate?: boolean): Promise<void>;
135
+ export declare function ensureTable(pool: ConnectionPool, schemaName: string, tableName: string, truncate?: boolean, jsonType?: ResourceJsonDataType): Promise<void>;
43
136
  //# sourceMappingURL=tables.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../src/loader/tables.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAY,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAGjD;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAmBf;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,OAAe,GACxB,OAAO,CAAC,IAAI,CAAC,CAUf"}
1
+ {"version":3,"file":"tables.d.ts","sourceRoot":"","sources":["../../src/loader/tables.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAY,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AACjD,OAAO,EACL,KAAK,oBAAoB,EAE1B,MAAM,kBAAkB,CAAC;AAE1B;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,oBAAoB,GAC7B,qBAAqB,CAiBvB;AA0BD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,sBAAsB,EAAE,MAAM,GAAG,IAAI,GACpC,oBAAoB,CAgBtB;AAED;;;;;;;;;GASG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,oBAAoB,EAClC,aAAa,EAAE,oBAAoB,GAClC,MAAM,GAAG,IAAI,CASf;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAiBtC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,oBAAoB,GAClC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;;;;;;;GASG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,oBAAsC,GAC/C,OAAO,CAAC,IAAI,CAAC,CAcf;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,OAAe,EACzB,QAAQ,GAAE,oBAAsC,GAC/C,OAAO,CAAC,IAAI,CAAC,CAaf"}