@memberjunction/sqlserver-dataprovider 5.4.1 → 5.6.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 +13 -6
- package/dist/SQLServerDataProvider.d.ts +57 -478
- package/dist/SQLServerDataProvider.d.ts.map +1 -1
- package/dist/SQLServerDataProvider.js +269 -3312
- package/dist/SQLServerDataProvider.js.map +1 -1
- package/dist/SQLServerTransactionGroup.d.ts.map +1 -1
- package/dist/SQLServerTransactionGroup.js +5 -6
- package/dist/SQLServerTransactionGroup.js.map +1 -1
- package/dist/UserCache.js +2 -2
- package/dist/UserCache.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +0 -81
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +14 -15
- package/dist/SqlLogger.d.ts +0 -70
- package/dist/SqlLogger.d.ts.map +0 -1
- package/dist/SqlLogger.js +0 -311
- package/dist/SqlLogger.js.map +0 -1
- package/dist/queryParameterProcessor.d.ts +0 -59
- package/dist/queryParameterProcessor.d.ts.map +0 -1
- package/dist/queryParameterProcessor.js +0 -208
- package/dist/queryParameterProcessor.js.map +0 -1
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { QueryInfo, QueryParameterInfo } from '@memberjunction/core';
|
|
2
|
-
/**
|
|
3
|
-
* Result of parameter validation
|
|
4
|
-
*/
|
|
5
|
-
export interface ParameterValidationResult {
|
|
6
|
-
/**
|
|
7
|
-
* Whether all parameters passed validation
|
|
8
|
-
*/
|
|
9
|
-
success: boolean;
|
|
10
|
-
/**
|
|
11
|
-
* Error messages for any validation failures
|
|
12
|
-
*/
|
|
13
|
-
errors: string[];
|
|
14
|
-
/**
|
|
15
|
-
* The validated and type-converted parameters
|
|
16
|
-
*/
|
|
17
|
-
validatedParameters: Record<string, any>;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Result of processing a query template
|
|
21
|
-
*/
|
|
22
|
-
export interface QueryProcessingResult {
|
|
23
|
-
/**
|
|
24
|
-
* Whether template processing was successful
|
|
25
|
-
*/
|
|
26
|
-
success: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* The processed SQL query with parameters substituted
|
|
29
|
-
*/
|
|
30
|
-
processedSQL: string;
|
|
31
|
-
/**
|
|
32
|
-
* Error message if processing failed
|
|
33
|
-
*/
|
|
34
|
-
error?: string;
|
|
35
|
-
/**
|
|
36
|
-
* The final parameters that were applied, including defaults
|
|
37
|
-
*/
|
|
38
|
-
appliedParameters: Record<string, any>;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Handles parameter validation and query template processing for parameterized queries.
|
|
42
|
-
* Provides type conversion, validation, and secure template processing using Nunjucks.
|
|
43
|
-
*/
|
|
44
|
-
export declare class QueryParameterProcessor {
|
|
45
|
-
private static _nunjucksEnv;
|
|
46
|
-
/**
|
|
47
|
-
* Gets or creates the Nunjucks environment with custom SQL-safe filters
|
|
48
|
-
*/
|
|
49
|
-
private static get nunjucksEnv();
|
|
50
|
-
/**
|
|
51
|
-
* Validates parameters against their definitions
|
|
52
|
-
*/
|
|
53
|
-
static validateParameters(parameters: Record<string, any> | undefined, parameterDefinitions: QueryParameterInfo[]): ParameterValidationResult;
|
|
54
|
-
/**
|
|
55
|
-
* Processes a query template with the provided parameters
|
|
56
|
-
*/
|
|
57
|
-
static processQueryTemplate(query: QueryInfo, parameters: Record<string, any> | undefined): QueryProcessingResult;
|
|
58
|
-
}
|
|
59
|
-
//# sourceMappingURL=queryParameterProcessor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queryParameterProcessor.d.ts","sourceRoot":"","sources":["../src/queryParameterProcessor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAA4B,MAAM,sBAAsB,CAAC;AAG/F;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACtC;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;OAEG;IACH,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC1C;AAED;;;GAGG;AACH,qBAAa,uBAAuB;IAChC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAuB;IAElD;;OAEG;IACH,OAAO,CAAC,MAAM,KAAK,WAAW,GAoB7B;IAED;;OAEG;WACW,kBAAkB,CAC5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,EAC3C,oBAAoB,EAAE,kBAAkB,EAAE,GAC3C,yBAAyB;IA8H5B;;OAEG;WACW,oBAAoB,CAC9B,KAAK,EAAE,SAAS,EAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAC5C,qBAAqB;CAmD3B"}
|
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
import { RunQuerySQLFilterManager } from '@memberjunction/core';
|
|
2
|
-
import nunjucks from 'nunjucks';
|
|
3
|
-
/**
|
|
4
|
-
* Handles parameter validation and query template processing for parameterized queries.
|
|
5
|
-
* Provides type conversion, validation, and secure template processing using Nunjucks.
|
|
6
|
-
*/
|
|
7
|
-
export class QueryParameterProcessor {
|
|
8
|
-
/**
|
|
9
|
-
* Gets or creates the Nunjucks environment with custom SQL-safe filters
|
|
10
|
-
*/
|
|
11
|
-
static get nunjucksEnv() {
|
|
12
|
-
if (!this._nunjucksEnv) {
|
|
13
|
-
this._nunjucksEnv = new nunjucks.Environment(null, {
|
|
14
|
-
autoescape: false,
|
|
15
|
-
throwOnUndefined: true,
|
|
16
|
-
trimBlocks: true,
|
|
17
|
-
lstripBlocks: true
|
|
18
|
-
});
|
|
19
|
-
// Add custom SQL-safe filters from the RunQuerySQLFilterManager
|
|
20
|
-
const filterManager = RunQuerySQLFilterManager.Instance;
|
|
21
|
-
const filters = filterManager.getAllFilters();
|
|
22
|
-
for (const filter of filters) {
|
|
23
|
-
if (filter.implementation) {
|
|
24
|
-
this._nunjucksEnv.addFilter(filter.name, filter.implementation);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
return this._nunjucksEnv;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Validates parameters against their definitions
|
|
32
|
-
*/
|
|
33
|
-
static validateParameters(parameters, parameterDefinitions) {
|
|
34
|
-
const errors = [];
|
|
35
|
-
const validatedParams = {};
|
|
36
|
-
// Process each defined parameter
|
|
37
|
-
for (const paramDef of parameterDefinitions) {
|
|
38
|
-
const value = parameters?.[paramDef.Name];
|
|
39
|
-
// Check required parameters
|
|
40
|
-
if (paramDef.IsRequired && (value === undefined || value === null || value === '')) {
|
|
41
|
-
errors.push(`Required parameter '${paramDef.Name}' is missing`);
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
// Use default value if not provided
|
|
45
|
-
let finalValue = value;
|
|
46
|
-
if ((finalValue === undefined || finalValue === null) && paramDef.DefaultValue !== null) {
|
|
47
|
-
try {
|
|
48
|
-
// Parse default value based on type
|
|
49
|
-
switch (paramDef.Type) {
|
|
50
|
-
case 'number':
|
|
51
|
-
finalValue = Number(paramDef.DefaultValue);
|
|
52
|
-
break;
|
|
53
|
-
case 'boolean':
|
|
54
|
-
finalValue = paramDef.DefaultValue.toLowerCase() === 'true';
|
|
55
|
-
break;
|
|
56
|
-
case 'date':
|
|
57
|
-
finalValue = new Date(paramDef.DefaultValue);
|
|
58
|
-
break;
|
|
59
|
-
case 'array':
|
|
60
|
-
finalValue = JSON.parse(paramDef.DefaultValue);
|
|
61
|
-
break;
|
|
62
|
-
default:
|
|
63
|
-
finalValue = paramDef.DefaultValue;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
catch (e) {
|
|
67
|
-
errors.push(`Failed to parse default value for parameter '${paramDef.Name}': ${e.message}`);
|
|
68
|
-
continue;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Type conversion and validation
|
|
72
|
-
if (finalValue !== undefined && finalValue !== null) {
|
|
73
|
-
try {
|
|
74
|
-
switch (paramDef.Type) {
|
|
75
|
-
case 'string':
|
|
76
|
-
validatedParams[paramDef.Name] = String(finalValue);
|
|
77
|
-
break;
|
|
78
|
-
case 'number':
|
|
79
|
-
const num = Number(finalValue);
|
|
80
|
-
if (isNaN(num)) {
|
|
81
|
-
errors.push(`Parameter '${paramDef.Name}' must be a number`);
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
validatedParams[paramDef.Name] = num;
|
|
85
|
-
break;
|
|
86
|
-
case 'date':
|
|
87
|
-
const date = finalValue instanceof Date ? finalValue : new Date(finalValue);
|
|
88
|
-
if (isNaN(date.getTime())) {
|
|
89
|
-
errors.push(`Parameter '${paramDef.Name}' must be a valid date`);
|
|
90
|
-
continue;
|
|
91
|
-
}
|
|
92
|
-
// Store as ISO string for SQL compatibility - Date.toString() produces
|
|
93
|
-
// format like "Mon Jan 26 2026..." which SQL Server cannot parse
|
|
94
|
-
validatedParams[paramDef.Name] = date.toISOString();
|
|
95
|
-
break;
|
|
96
|
-
case 'boolean':
|
|
97
|
-
// Convert to 0/1 for SQL Server bit fields
|
|
98
|
-
// This ensures proper SQL syntax: WHERE BitColumn = 1 (not WHERE BitColumn = true)
|
|
99
|
-
if (typeof finalValue === 'boolean') {
|
|
100
|
-
validatedParams[paramDef.Name] = finalValue ? 1 : 0;
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
validatedParams[paramDef.Name] = String(finalValue).toLowerCase() === 'true' ? 1 : 0;
|
|
104
|
-
}
|
|
105
|
-
break;
|
|
106
|
-
case 'array':
|
|
107
|
-
if (Array.isArray(finalValue)) {
|
|
108
|
-
validatedParams[paramDef.Name] = finalValue;
|
|
109
|
-
}
|
|
110
|
-
else if (typeof finalValue === 'string') {
|
|
111
|
-
try {
|
|
112
|
-
validatedParams[paramDef.Name] = JSON.parse(finalValue);
|
|
113
|
-
}
|
|
114
|
-
catch {
|
|
115
|
-
errors.push(`Parameter '${paramDef.Name}' must be a valid JSON array`);
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
errors.push(`Parameter '${paramDef.Name}' must be an array`);
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
break;
|
|
124
|
-
default:
|
|
125
|
-
validatedParams[paramDef.Name] = finalValue;
|
|
126
|
-
}
|
|
127
|
-
// Apply validation filters if any
|
|
128
|
-
if (paramDef.ValidationFilters) {
|
|
129
|
-
const filters = paramDef.ParsedFilters;
|
|
130
|
-
for (const filter of filters) {
|
|
131
|
-
// This is where custom validation logic would go
|
|
132
|
-
// For now, we'll just log that we would apply filters
|
|
133
|
-
// In a real implementation, you'd apply the filter rules
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
catch (e) {
|
|
138
|
-
errors.push(`Error processing parameter '${paramDef.Name}': ${e.message}`);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
// Check for unknown parameters
|
|
143
|
-
if (parameters) {
|
|
144
|
-
const definedParamNames = new Set(parameterDefinitions.map(p => p.Name));
|
|
145
|
-
for (const key of Object.keys(parameters)) {
|
|
146
|
-
if (!definedParamNames.has(key)) {
|
|
147
|
-
errors.push(`Unknown parameter: '${key}'`);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return {
|
|
152
|
-
success: errors.length === 0,
|
|
153
|
-
errors,
|
|
154
|
-
validatedParameters: validatedParams
|
|
155
|
-
};
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Processes a query template with the provided parameters
|
|
159
|
-
*/
|
|
160
|
-
static processQueryTemplate(query, parameters) {
|
|
161
|
-
try {
|
|
162
|
-
// If query doesn't use templates, return the SQL as-is
|
|
163
|
-
if (!query.UsesTemplate) {
|
|
164
|
-
return {
|
|
165
|
-
success: true,
|
|
166
|
-
processedSQL: query.SQL,
|
|
167
|
-
appliedParameters: {}
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
// Validate parameters
|
|
171
|
-
const validation = this.validateParameters(parameters, query.Parameters);
|
|
172
|
-
if (!validation.success) {
|
|
173
|
-
return {
|
|
174
|
-
success: false,
|
|
175
|
-
processedSQL: '',
|
|
176
|
-
error: `Parameter validation failed: ${validation.errors.join('; ')}`,
|
|
177
|
-
appliedParameters: {}
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
// Process the template
|
|
181
|
-
try {
|
|
182
|
-
const processedSQL = this.nunjucksEnv.renderString(query.SQL, validation.validatedParameters);
|
|
183
|
-
return {
|
|
184
|
-
success: true,
|
|
185
|
-
processedSQL,
|
|
186
|
-
appliedParameters: validation.validatedParameters
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
catch (e) {
|
|
190
|
-
return {
|
|
191
|
-
success: false,
|
|
192
|
-
processedSQL: '',
|
|
193
|
-
error: `Template processing failed: ${e.message}`,
|
|
194
|
-
appliedParameters: validation.validatedParameters
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
catch (e) {
|
|
199
|
-
return {
|
|
200
|
-
success: false,
|
|
201
|
-
processedSQL: '',
|
|
202
|
-
error: `Unexpected error during query processing: ${e.message}`,
|
|
203
|
-
appliedParameters: {}
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
//# sourceMappingURL=queryParameterProcessor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queryParameterProcessor.js","sourceRoot":"","sources":["../src/queryParameterProcessor.ts"],"names":[],"mappings":"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"}
|