sof-mssql 1.0.1 → 2.0.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 +175 -35
- package/dist/fhirpath/transpiler.d.ts +40 -2
- package/dist/fhirpath/transpiler.d.ts.map +1 -1
- package/dist/fhirpath/transpiler.js +85 -15
- package/dist/fhirpath/transpiler.js.map +1 -1
- package/dist/loader/tables.d.ts.map +1 -1
- package/dist/loader/tables.js +7 -0
- package/dist/loader/tables.js.map +1 -1
- package/dist/parser.d.ts +12 -0
- package/dist/parser.d.ts.map +1 -1
- package/dist/parser.js +66 -9
- package/dist/parser.js.map +1 -1
- package/dist/queryGenerator/WhereClauseBuilder.d.ts +1 -0
- package/dist/queryGenerator/WhereClauseBuilder.d.ts.map +1 -1
- package/dist/queryGenerator/WhereClauseBuilder.js +6 -2
- package/dist/queryGenerator/WhereClauseBuilder.js.map +1 -1
- package/dist/queryGenerator.d.ts.map +1 -1
- package/dist/queryGenerator.js +13 -8
- package/dist/queryGenerator.js.map +1 -1
- package/dist/tests/utils/generator.js +11 -11
- package/dist/tests/utils/generator.js.map +1 -1
- package/dist/tests/utils/sqlOnFhir.d.ts.map +1 -1
- package/dist/tests/utils/sqlOnFhir.js +39 -4
- package/dist/tests/utils/sqlOnFhir.js.map +1 -1
- package/dist/tests/utils/testContext.d.ts +3 -6
- package/dist/tests/utils/testContext.d.ts.map +1 -1
- package/dist/tests/utils/testContext.js +5 -9
- package/dist/tests/utils/testContext.js.map +1 -1
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/validation.d.ts +66 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +449 -0
- package/dist/validation.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SQL Server identifier and FHIR resource type validation utilities.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.validateSqlServerIdentifier = validateSqlServerIdentifier;
|
|
7
|
+
exports.validateResourceType = validateResourceType;
|
|
8
|
+
exports.validateTestId = validateTestId;
|
|
9
|
+
exports.validateMsSqlType = validateMsSqlType;
|
|
10
|
+
exports.validateAnsiSqlType = validateAnsiSqlType;
|
|
11
|
+
/**
|
|
12
|
+
* FHIR R4 resource types.
|
|
13
|
+
* Complete list of all resource types defined in FHIR R4 specification.
|
|
14
|
+
*/
|
|
15
|
+
const FHIR_R4_RESOURCE_TYPES = new Set([
|
|
16
|
+
"Account",
|
|
17
|
+
"ActivityDefinition",
|
|
18
|
+
"AdverseEvent",
|
|
19
|
+
"AllergyIntolerance",
|
|
20
|
+
"Appointment",
|
|
21
|
+
"AppointmentResponse",
|
|
22
|
+
"AuditEvent",
|
|
23
|
+
"Basic",
|
|
24
|
+
"Binary",
|
|
25
|
+
"BiologicallyDerivedProduct",
|
|
26
|
+
"BodyStructure",
|
|
27
|
+
"Bundle",
|
|
28
|
+
"CapabilityStatement",
|
|
29
|
+
"CarePlan",
|
|
30
|
+
"CareTeam",
|
|
31
|
+
"CatalogEntry",
|
|
32
|
+
"ChargeItem",
|
|
33
|
+
"ChargeItemDefinition",
|
|
34
|
+
"Claim",
|
|
35
|
+
"ClaimResponse",
|
|
36
|
+
"ClinicalImpression",
|
|
37
|
+
"CodeSystem",
|
|
38
|
+
"Communication",
|
|
39
|
+
"CommunicationRequest",
|
|
40
|
+
"CompartmentDefinition",
|
|
41
|
+
"Composition",
|
|
42
|
+
"ConceptMap",
|
|
43
|
+
"Condition",
|
|
44
|
+
"Consent",
|
|
45
|
+
"Contract",
|
|
46
|
+
"Coverage",
|
|
47
|
+
"CoverageEligibilityRequest",
|
|
48
|
+
"CoverageEligibilityResponse",
|
|
49
|
+
"DetectedIssue",
|
|
50
|
+
"Device",
|
|
51
|
+
"DeviceDefinition",
|
|
52
|
+
"DeviceMetric",
|
|
53
|
+
"DeviceRequest",
|
|
54
|
+
"DeviceUseStatement",
|
|
55
|
+
"DiagnosticReport",
|
|
56
|
+
"DocumentManifest",
|
|
57
|
+
"DocumentReference",
|
|
58
|
+
"DomainResource",
|
|
59
|
+
"EffectEvidenceSynthesis",
|
|
60
|
+
"Encounter",
|
|
61
|
+
"Endpoint",
|
|
62
|
+
"EnrollmentRequest",
|
|
63
|
+
"EnrollmentResponse",
|
|
64
|
+
"EpisodeOfCare",
|
|
65
|
+
"EventDefinition",
|
|
66
|
+
"Evidence",
|
|
67
|
+
"EvidenceVariable",
|
|
68
|
+
"ExampleScenario",
|
|
69
|
+
"ExplanationOfBenefit",
|
|
70
|
+
"FamilyMemberHistory",
|
|
71
|
+
"Flag",
|
|
72
|
+
"Goal",
|
|
73
|
+
"GraphDefinition",
|
|
74
|
+
"Group",
|
|
75
|
+
"GuidanceResponse",
|
|
76
|
+
"HealthcareService",
|
|
77
|
+
"ImagingStudy",
|
|
78
|
+
"Immunization",
|
|
79
|
+
"ImmunizationEvaluation",
|
|
80
|
+
"ImmunizationRecommendation",
|
|
81
|
+
"ImplementationGuide",
|
|
82
|
+
"InsurancePlan",
|
|
83
|
+
"Invoice",
|
|
84
|
+
"Library",
|
|
85
|
+
"Linkage",
|
|
86
|
+
"List",
|
|
87
|
+
"Location",
|
|
88
|
+
"Measure",
|
|
89
|
+
"MeasureReport",
|
|
90
|
+
"Media",
|
|
91
|
+
"Medication",
|
|
92
|
+
"MedicationAdministration",
|
|
93
|
+
"MedicationDispense",
|
|
94
|
+
"MedicationKnowledge",
|
|
95
|
+
"MedicationRequest",
|
|
96
|
+
"MedicationStatement",
|
|
97
|
+
"MedicinalProduct",
|
|
98
|
+
"MedicinalProductAuthorization",
|
|
99
|
+
"MedicinalProductContraindication",
|
|
100
|
+
"MedicinalProductIndication",
|
|
101
|
+
"MedicinalProductIngredient",
|
|
102
|
+
"MedicinalProductInteraction",
|
|
103
|
+
"MedicinalProductManufactured",
|
|
104
|
+
"MedicinalProductPackaged",
|
|
105
|
+
"MedicinalProductPharmaceutical",
|
|
106
|
+
"MedicinalProductUndesirableEffect",
|
|
107
|
+
"MessageDefinition",
|
|
108
|
+
"MessageHeader",
|
|
109
|
+
"MolecularSequence",
|
|
110
|
+
"NamingSystem",
|
|
111
|
+
"NutritionOrder",
|
|
112
|
+
"Observation",
|
|
113
|
+
"ObservationDefinition",
|
|
114
|
+
"OperationDefinition",
|
|
115
|
+
"OperationOutcome",
|
|
116
|
+
"Organization",
|
|
117
|
+
"OrganizationAffiliation",
|
|
118
|
+
"Parameters",
|
|
119
|
+
"Patient",
|
|
120
|
+
"PaymentNotice",
|
|
121
|
+
"PaymentReconciliation",
|
|
122
|
+
"Person",
|
|
123
|
+
"PlanDefinition",
|
|
124
|
+
"Practitioner",
|
|
125
|
+
"PractitionerRole",
|
|
126
|
+
"Procedure",
|
|
127
|
+
"Provenance",
|
|
128
|
+
"Questionnaire",
|
|
129
|
+
"QuestionnaireResponse",
|
|
130
|
+
"RelatedPerson",
|
|
131
|
+
"RequestGroup",
|
|
132
|
+
"ResearchDefinition",
|
|
133
|
+
"ResearchElementDefinition",
|
|
134
|
+
"ResearchStudy",
|
|
135
|
+
"ResearchSubject",
|
|
136
|
+
"Resource",
|
|
137
|
+
"RiskAssessment",
|
|
138
|
+
"RiskEvidenceSynthesis",
|
|
139
|
+
"Schedule",
|
|
140
|
+
"SearchParameter",
|
|
141
|
+
"ServiceRequest",
|
|
142
|
+
"Slot",
|
|
143
|
+
"Specimen",
|
|
144
|
+
"SpecimenDefinition",
|
|
145
|
+
"StructureDefinition",
|
|
146
|
+
"StructureMap",
|
|
147
|
+
"Subscription",
|
|
148
|
+
"Substance",
|
|
149
|
+
"SubstanceNucleicAcid",
|
|
150
|
+
"SubstancePolymer",
|
|
151
|
+
"SubstanceProtein",
|
|
152
|
+
"SubstanceReferenceInformation",
|
|
153
|
+
"SubstanceSourceMaterial",
|
|
154
|
+
"SubstanceSpecification",
|
|
155
|
+
"SupplyDelivery",
|
|
156
|
+
"SupplyRequest",
|
|
157
|
+
"Task",
|
|
158
|
+
"TerminologyCapabilities",
|
|
159
|
+
"TestReport",
|
|
160
|
+
"TestScript",
|
|
161
|
+
"ValueSet",
|
|
162
|
+
"VerificationResult",
|
|
163
|
+
"VisionPrescription",
|
|
164
|
+
]);
|
|
165
|
+
/**
|
|
166
|
+
* SQL Server reserved words that cannot be used as identifiers without quoting.
|
|
167
|
+
* This is a subset of commonly used reserved words.
|
|
168
|
+
*/
|
|
169
|
+
const SQL_SERVER_RESERVED_WORDS = new Set([
|
|
170
|
+
"SELECT",
|
|
171
|
+
"FROM",
|
|
172
|
+
"WHERE",
|
|
173
|
+
"INSERT",
|
|
174
|
+
"UPDATE",
|
|
175
|
+
"DELETE",
|
|
176
|
+
"DROP",
|
|
177
|
+
"CREATE",
|
|
178
|
+
"ALTER",
|
|
179
|
+
"TABLE",
|
|
180
|
+
"INDEX",
|
|
181
|
+
"VIEW",
|
|
182
|
+
"PROCEDURE",
|
|
183
|
+
"FUNCTION",
|
|
184
|
+
"TRIGGER",
|
|
185
|
+
"DATABASE",
|
|
186
|
+
"SCHEMA",
|
|
187
|
+
"USER",
|
|
188
|
+
"ROLE",
|
|
189
|
+
"GRANT",
|
|
190
|
+
"REVOKE",
|
|
191
|
+
"JOIN",
|
|
192
|
+
"UNION",
|
|
193
|
+
"ORDER",
|
|
194
|
+
"GROUP",
|
|
195
|
+
"HAVING",
|
|
196
|
+
"AS",
|
|
197
|
+
"ON",
|
|
198
|
+
"IN",
|
|
199
|
+
"EXISTS",
|
|
200
|
+
"BETWEEN",
|
|
201
|
+
"LIKE",
|
|
202
|
+
"AND",
|
|
203
|
+
"OR",
|
|
204
|
+
"NOT",
|
|
205
|
+
"NULL",
|
|
206
|
+
"IS",
|
|
207
|
+
]);
|
|
208
|
+
/**
|
|
209
|
+
* Validate a SQL Server identifier (table name, schema name, etc.).
|
|
210
|
+
*
|
|
211
|
+
* SQL Server identifier rules:
|
|
212
|
+
* - Can start with: letter (A-Z, a-z), underscore (_), @, or #
|
|
213
|
+
* - Followed by: letters, digits (0-9), underscore, @, #, or $
|
|
214
|
+
* - Maximum length: 128 characters
|
|
215
|
+
* - Must not be a reserved word
|
|
216
|
+
*
|
|
217
|
+
* @param identifier - The identifier to validate
|
|
218
|
+
* @param type - The type of identifier (for error messages)
|
|
219
|
+
* @throws Error if the identifier is invalid
|
|
220
|
+
*/
|
|
221
|
+
function validateSqlServerIdentifier(identifier, type) {
|
|
222
|
+
// Check for empty identifier
|
|
223
|
+
if (!identifier || identifier.trim().length === 0) {
|
|
224
|
+
throw new Error(`${type} cannot be empty.`);
|
|
225
|
+
}
|
|
226
|
+
// Check length
|
|
227
|
+
if (identifier.length > 128) {
|
|
228
|
+
throw new Error(`${type} '${identifier}' exceeds maximum length of 128 characters.`);
|
|
229
|
+
}
|
|
230
|
+
// Check pattern: must start with letter, underscore, @, or #
|
|
231
|
+
// Followed by letters, digits, underscore, @, #, or $
|
|
232
|
+
if (!/^[a-zA-Z_@#][a-zA-Z0-9_@#$]*$/.test(identifier)) {
|
|
233
|
+
throw new Error(`${type} '${identifier}' contains invalid characters. Must start with a letter, underscore, @, or #, followed by letters, digits, underscore, @, #, or $.`);
|
|
234
|
+
}
|
|
235
|
+
// Check for reserved words (case-insensitive)
|
|
236
|
+
if (SQL_SERVER_RESERVED_WORDS.has(identifier.toUpperCase())) {
|
|
237
|
+
throw new Error(`${type} '${identifier}' is a SQL Server reserved word and cannot be used as an identifier.`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Validate a FHIR resource type against the R4 specification.
|
|
242
|
+
*
|
|
243
|
+
* @param resourceType - The resource type to validate
|
|
244
|
+
* @throws Error if the resource type is not valid
|
|
245
|
+
*/
|
|
246
|
+
function validateResourceType(resourceType) {
|
|
247
|
+
if (!resourceType || resourceType.trim().length === 0) {
|
|
248
|
+
throw new Error("Resource type cannot be empty.");
|
|
249
|
+
}
|
|
250
|
+
if (!FHIR_R4_RESOURCE_TYPES.has(resourceType)) {
|
|
251
|
+
throw new Error(`Invalid FHIR resource type: '${resourceType}'. Must be a valid FHIR R4 resource type.`);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Validate a test ID format.
|
|
256
|
+
* Test IDs must be valid UUIDs (version 4).
|
|
257
|
+
*
|
|
258
|
+
* @param testId - The test ID to validate
|
|
259
|
+
* @throws Error if the test ID format is invalid
|
|
260
|
+
*/
|
|
261
|
+
function validateTestId(testId) {
|
|
262
|
+
if (!testId || testId.trim().length === 0) {
|
|
263
|
+
throw new Error("Test ID cannot be empty.");
|
|
264
|
+
}
|
|
265
|
+
// UUID v4 format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
|
|
266
|
+
// where x is any hexadecimal digit and y is one of 8, 9, a, or b
|
|
267
|
+
const uuidV4Pattern = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
268
|
+
if (!uuidV4Pattern.test(testId)) {
|
|
269
|
+
throw new Error(`Invalid test ID format: '${testId}'. Must be a valid UUID v4.`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Valid MS SQL Server base type names.
|
|
274
|
+
*/
|
|
275
|
+
const VALID_SQL_SERVER_TYPES = new Set([
|
|
276
|
+
"BIT",
|
|
277
|
+
"TINYINT",
|
|
278
|
+
"SMALLINT",
|
|
279
|
+
"INT",
|
|
280
|
+
"BIGINT",
|
|
281
|
+
"DECIMAL",
|
|
282
|
+
"NUMERIC",
|
|
283
|
+
"MONEY",
|
|
284
|
+
"SMALLMONEY",
|
|
285
|
+
"FLOAT",
|
|
286
|
+
"REAL",
|
|
287
|
+
"DATE",
|
|
288
|
+
"TIME",
|
|
289
|
+
"DATETIME",
|
|
290
|
+
"DATETIME2",
|
|
291
|
+
"DATETIMEOFFSET",
|
|
292
|
+
"SMALLDATETIME",
|
|
293
|
+
"CHAR",
|
|
294
|
+
"VARCHAR",
|
|
295
|
+
"TEXT",
|
|
296
|
+
"NCHAR",
|
|
297
|
+
"NVARCHAR",
|
|
298
|
+
"NTEXT",
|
|
299
|
+
"BINARY",
|
|
300
|
+
"VARBINARY",
|
|
301
|
+
"IMAGE",
|
|
302
|
+
"UNIQUEIDENTIFIER",
|
|
303
|
+
"XML",
|
|
304
|
+
"SQL_VARIANT",
|
|
305
|
+
]);
|
|
306
|
+
/**
|
|
307
|
+
* Validate MS SQL Server type specification.
|
|
308
|
+
*
|
|
309
|
+
* Ensures the type is a valid SQL Server data type with correct syntax.
|
|
310
|
+
* Supports all common SQL Server types including:
|
|
311
|
+
* - Integer types: BIT, TINYINT, SMALLINT, INT, BIGINT
|
|
312
|
+
* - Decimal types: DECIMAL, NUMERIC, MONEY, SMALLMONEY, FLOAT, REAL
|
|
313
|
+
* - Date/time types: DATE, TIME, DATETIME, DATETIME2, DATETIMEOFFSET, SMALLDATETIME
|
|
314
|
+
* - String types: CHAR, VARCHAR, TEXT, NCHAR, NVARCHAR, NTEXT (with MAX or size)
|
|
315
|
+
* - Binary types: BINARY, VARBINARY, IMAGE (with MAX or size)
|
|
316
|
+
* - Other: UNIQUEIDENTIFIER, XML, SQL_VARIANT
|
|
317
|
+
*
|
|
318
|
+
* @param sqlType - SQL Server type string (e.g., 'NVARCHAR(MAX)', 'INT', 'DECIMAL(38,18)')
|
|
319
|
+
* @throws Error if type is invalid
|
|
320
|
+
*/
|
|
321
|
+
function validateMsSqlType(sqlType) {
|
|
322
|
+
if (!sqlType || sqlType.trim().length === 0) {
|
|
323
|
+
throw new Error("SQL Server type cannot be empty.");
|
|
324
|
+
}
|
|
325
|
+
const trimmedType = sqlType.trim();
|
|
326
|
+
// Extract base type and parameters by finding the opening parenthesis
|
|
327
|
+
const openParenIndex = trimmedType.indexOf("(");
|
|
328
|
+
const baseTypePart = openParenIndex === -1
|
|
329
|
+
? trimmedType
|
|
330
|
+
: trimmedType.substring(0, openParenIndex).trim();
|
|
331
|
+
const paramsPart = openParenIndex === -1 ? "" : trimmedType.substring(openParenIndex);
|
|
332
|
+
// Validate base type name: letters, digits, underscore
|
|
333
|
+
if (!/^[A-Z_][A-Z0-9_]*$/i.test(baseTypePart)) {
|
|
334
|
+
throw new Error(`Invalid MS SQL Server type format: '${sqlType}'. Must be a valid SQL Server data type such as INT, NVARCHAR(MAX), DECIMAL(38,18), DATETIME2(7), or DATETIMEOFFSET(3).`);
|
|
335
|
+
}
|
|
336
|
+
// Validate parameters if present: (size) or (precision,scale) where size can be MAX
|
|
337
|
+
if (paramsPart && !/^\(\s*(\d+|MAX)(\s*,\s*\d+)?\s*\)$/i.test(paramsPart)) {
|
|
338
|
+
throw new Error(`Invalid MS SQL Server type format: '${sqlType}'. Must be a valid SQL Server data type such as INT, NVARCHAR(MAX), DECIMAL(38,18), DATETIME2(7), or DATETIMEOFFSET(3).`);
|
|
339
|
+
}
|
|
340
|
+
// Check if base type is valid
|
|
341
|
+
const baseType = baseTypePart.toUpperCase();
|
|
342
|
+
if (!VALID_SQL_SERVER_TYPES.has(baseType)) {
|
|
343
|
+
throw new Error(`Unknown MS SQL Server type: '${baseType}'. Must be a valid SQL Server data type such as INT, NVARCHAR, DECIMAL, DATETIME2, or DATETIMEOFFSET.`);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Mapping of ANSI/ISO SQL standard types to MS SQL Server equivalents.
|
|
348
|
+
* Based on ISO/IEC 9075 SQL standard and SQL Server data type synonyms.
|
|
349
|
+
*/
|
|
350
|
+
const ANSI_TO_MSSQL_TYPE_MAP = new Map([
|
|
351
|
+
// Character types (SQL-92 and later)
|
|
352
|
+
["CHARACTER", "CHAR"],
|
|
353
|
+
["CHAR", "CHAR"],
|
|
354
|
+
["CHARACTER VARYING", "VARCHAR"],
|
|
355
|
+
["CHAR VARYING", "VARCHAR"],
|
|
356
|
+
["NATIONAL CHARACTER", "NCHAR"],
|
|
357
|
+
["NATIONAL CHAR", "NCHAR"],
|
|
358
|
+
["NATIONAL CHARACTER VARYING", "NVARCHAR"],
|
|
359
|
+
["NATIONAL CHAR VARYING", "NVARCHAR"],
|
|
360
|
+
// Numeric types - exact (SQL-92)
|
|
361
|
+
["INTEGER", "INT"],
|
|
362
|
+
["INT", "INT"],
|
|
363
|
+
["SMALLINT", "SMALLINT"],
|
|
364
|
+
["BIGINT", "BIGINT"],
|
|
365
|
+
["DECIMAL", "DECIMAL"],
|
|
366
|
+
["DEC", "DECIMAL"],
|
|
367
|
+
["NUMERIC", "NUMERIC"],
|
|
368
|
+
// Numeric types - approximate (SQL-92)
|
|
369
|
+
["FLOAT", "FLOAT"],
|
|
370
|
+
["REAL", "REAL"],
|
|
371
|
+
["DOUBLE PRECISION", "FLOAT"],
|
|
372
|
+
// Date/time types (SQL-92 and later)
|
|
373
|
+
["DATE", "DATE"],
|
|
374
|
+
["TIME", "TIME"],
|
|
375
|
+
// Note: ANSI TIMESTAMP maps to DATETIME2, not SQL Server's TIMESTAMP (which is for row versioning)
|
|
376
|
+
["TIMESTAMP", "DATETIME2"],
|
|
377
|
+
// Boolean (SQL:1999)
|
|
378
|
+
// Note: SQL Server doesn't have native BOOLEAN, BIT is the closest equivalent
|
|
379
|
+
["BOOLEAN", "BIT"],
|
|
380
|
+
// Binary types
|
|
381
|
+
["BINARY VARYING", "VARBINARY"],
|
|
382
|
+
]);
|
|
383
|
+
/**
|
|
384
|
+
* Parse an ANSI/ISO SQL type into base type and parameters.
|
|
385
|
+
*
|
|
386
|
+
* @param typeString - The type string to parse
|
|
387
|
+
* @returns Object with baseType and parameters
|
|
388
|
+
*/
|
|
389
|
+
function parseAnsiSqlType(typeString) {
|
|
390
|
+
const openParenIndex = typeString.indexOf("(");
|
|
391
|
+
const baseTypePart = openParenIndex === -1
|
|
392
|
+
? typeString
|
|
393
|
+
: typeString.substring(0, openParenIndex).trim();
|
|
394
|
+
const paramsPart = openParenIndex === -1 ? "" : typeString.substring(openParenIndex);
|
|
395
|
+
return {
|
|
396
|
+
baseType: baseTypePart.trim().toUpperCase(),
|
|
397
|
+
parameters: paramsPart,
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Validate and convert ANSI/ISO SQL type specification to MS SQL Server type.
|
|
402
|
+
*
|
|
403
|
+
* Supports ANSI/ISO SQL standard types from SQL-92, SQL:1999, and later versions.
|
|
404
|
+
* Converts standard types to their MS SQL Server equivalents and validates the result.
|
|
405
|
+
*
|
|
406
|
+
* Examples:
|
|
407
|
+
* - 'INTEGER' → 'INT'
|
|
408
|
+
* - 'CHARACTER(50)' → 'CHAR(50)'
|
|
409
|
+
* - 'BOOLEAN' → 'BIT'
|
|
410
|
+
* - 'TIMESTAMP' → 'DATETIME2'
|
|
411
|
+
*
|
|
412
|
+
* @param ansiType - ANSI/ISO SQL type string (e.g., 'INTEGER', 'CHARACTER(20)', 'DECIMAL(10,2)')
|
|
413
|
+
* @returns MS SQL Server equivalent type
|
|
414
|
+
* @throws Error if type is invalid or unsupported
|
|
415
|
+
*/
|
|
416
|
+
function validateAnsiSqlType(ansiType) {
|
|
417
|
+
if (!ansiType || ansiType.trim().length === 0) {
|
|
418
|
+
throw new Error("ANSI SQL type cannot be empty.");
|
|
419
|
+
}
|
|
420
|
+
const trimmedType = ansiType.trim();
|
|
421
|
+
const { baseType, parameters } = parseAnsiSqlType(trimmedType);
|
|
422
|
+
// Validate base type: must start with letter, followed by letters and spaces
|
|
423
|
+
if (!/^[A-Z][A-Z\s]*$/i.test(baseType)) {
|
|
424
|
+
throw new Error(`Invalid ANSI SQL type format: '${ansiType}'. Must be a valid ANSI/ISO SQL type such as INTEGER, CHARACTER(50), or DECIMAL(10,2).`);
|
|
425
|
+
}
|
|
426
|
+
// Validate parameters if present: (size) or (precision,scale) where size can be MAX
|
|
427
|
+
if (parameters && !/^\(\s*(\d+|MAX)(\s*,\s*\d+)?\s*\)$/i.test(parameters)) {
|
|
428
|
+
throw new Error(`Invalid ANSI SQL type format: '${ansiType}'. Must be a valid ANSI/ISO SQL type such as INTEGER, CHARACTER(50), or DECIMAL(10,2).`);
|
|
429
|
+
}
|
|
430
|
+
// Look up MS SQL Server equivalent
|
|
431
|
+
const mssqlBaseType = ANSI_TO_MSSQL_TYPE_MAP.get(baseType);
|
|
432
|
+
if (!mssqlBaseType) {
|
|
433
|
+
// Check if it's already a valid SQL Server type (pass-through)
|
|
434
|
+
const mssqlType = baseType + parameters;
|
|
435
|
+
try {
|
|
436
|
+
validateMsSqlType(mssqlType);
|
|
437
|
+
return mssqlType;
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
throw new Error(`Unsupported ANSI SQL type: '${baseType}'. Must be a valid ANSI/ISO SQL standard type such as INTEGER, CHARACTER, DECIMAL, TIMESTAMP, or BOOLEAN.`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
// Construct MS SQL Server type with parameters
|
|
444
|
+
const mssqlType = mssqlBaseType + parameters;
|
|
445
|
+
// Validate the resulting MS SQL Server type
|
|
446
|
+
validateMsSqlType(mssqlType);
|
|
447
|
+
return mssqlType;
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sof-mssql",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "A SQL on FHIR view runner that transpiles view definitions into T-SQL queries for MS SQL Server",
|
|
5
5
|
"author": "Australian e-Health Research Centre, CSIRO",
|
|
6
6
|
"contributors": [
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"cli:load": "tsx src/cli.ts load",
|
|
23
23
|
"cli:transpile": "tsx src/cli.ts transpile",
|
|
24
24
|
"test": "vitest run",
|
|
25
|
-
"test:
|
|
25
|
+
"test:coverage": "vitest run --coverage",
|
|
26
26
|
"test:watch": "vitest",
|
|
27
27
|
"test:ui": "vitest --ui",
|
|
28
28
|
"coverage": "vitest run --coverage",
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
"@types/node": "^22.5.5",
|
|
63
63
|
"@typescript-eslint/eslint-plugin": "^8.8.0",
|
|
64
64
|
"@typescript-eslint/parser": "^8.8.0",
|
|
65
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
65
66
|
"@vitest/ui": "^3.2.4",
|
|
66
67
|
"antlr4ts-cli": "^0.5.0-alpha.4",
|
|
67
68
|
"eslint": "^9.11.1",
|