@memberjunction/sqlserver-dataprovider 5.4.1 → 5.5.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.
@@ -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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"}