@memberjunction/core 2.72.0 → 2.74.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/dist/generic/applicationInfo.d.ts +92 -1
- package/dist/generic/applicationInfo.d.ts.map +1 -1
- package/dist/generic/applicationInfo.js +92 -1
- package/dist/generic/applicationInfo.js.map +1 -1
- package/dist/generic/baseInfo.d.ts +15 -0
- package/dist/generic/baseInfo.d.ts.map +1 -1
- package/dist/generic/baseInfo.js +15 -0
- package/dist/generic/baseInfo.js.map +1 -1
- package/dist/generic/entityInfo.d.ts +184 -3
- package/dist/generic/entityInfo.d.ts.map +1 -1
- package/dist/generic/entityInfo.js +184 -3
- package/dist/generic/entityInfo.js.map +1 -1
- package/dist/generic/interfaces.d.ts +119 -4
- package/dist/generic/interfaces.d.ts.map +1 -1
- package/dist/generic/interfaces.js +44 -3
- package/dist/generic/interfaces.js.map +1 -1
- package/dist/generic/providerBase.d.ts +248 -8
- package/dist/generic/providerBase.d.ts.map +1 -1
- package/dist/generic/providerBase.js +185 -2
- package/dist/generic/providerBase.js.map +1 -1
- package/dist/generic/queryInfo.d.ts +312 -1
- package/dist/generic/queryInfo.d.ts.map +1 -1
- package/dist/generic/queryInfo.js +371 -2
- package/dist/generic/queryInfo.js.map +1 -1
- package/dist/generic/querySQLFilters.d.ts +54 -0
- package/dist/generic/querySQLFilters.d.ts.map +1 -0
- package/dist/generic/querySQLFilters.js +84 -0
- package/dist/generic/querySQLFilters.js.map +1 -0
- package/dist/generic/runQuery.d.ts +42 -0
- package/dist/generic/runQuery.d.ts.map +1 -1
- package/dist/generic/runQuery.js +26 -0
- package/dist/generic/runQuery.js.map +1 -1
- package/dist/generic/runQuerySQLFilterImplementations.d.ts +51 -0
- package/dist/generic/runQuerySQLFilterImplementations.d.ts.map +1 -0
- package/dist/generic/runQuerySQLFilterImplementations.js +238 -0
- package/dist/generic/runQuerySQLFilterImplementations.js.map +1 -0
- package/dist/generic/securityInfo.d.ts +212 -13
- package/dist/generic/securityInfo.d.ts.map +1 -1
- package/dist/generic/securityInfo.js +200 -14
- package/dist/generic/securityInfo.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/readme.md +550 -1
|
@@ -20,9 +20,27 @@ export type RunQueryParams = {
|
|
|
20
20
|
* Optional, if provided, the query to be run will be selected to match the specified CategoryID
|
|
21
21
|
*/
|
|
22
22
|
CategoryID?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Optional parameters to pass to parameterized queries that use Nunjucks templates.
|
|
25
|
+
* Key-value pairs where keys match parameter names defined in QueryParameter metadata.
|
|
26
|
+
* Values will be validated and type-converted based on parameter definitions.
|
|
27
|
+
*/
|
|
28
|
+
Parameters?: Record<string, any>;
|
|
29
|
+
/**
|
|
30
|
+
* Optional maximum number of rows to return from the query.
|
|
31
|
+
* If not provided, all rows will be returned.
|
|
32
|
+
*/
|
|
33
|
+
MaxRows?: number;
|
|
34
|
+
/**
|
|
35
|
+
* Optional - if provided, this value will be used to offset the rows returned.
|
|
36
|
+
* Used for pagination in conjunction with MaxRows.
|
|
37
|
+
*/
|
|
38
|
+
StartRow?: number;
|
|
23
39
|
};
|
|
24
40
|
/**
|
|
25
41
|
* Class used to run a query and return the results.
|
|
42
|
+
* Provides an abstraction layer for executing saved queries with proper security checks.
|
|
43
|
+
* Supports both instance-based and static provider patterns.
|
|
26
44
|
*/
|
|
27
45
|
export declare class RunQuery {
|
|
28
46
|
private _provider;
|
|
@@ -30,10 +48,34 @@ export declare class RunQuery {
|
|
|
30
48
|
* Optionally, you can pass in a provider to use for running the query. If not provided, the static provider will be used.
|
|
31
49
|
*/
|
|
32
50
|
constructor(provider?: IRunQueryProvider | null);
|
|
51
|
+
/**
|
|
52
|
+
* Gets the query provider to use for execution.
|
|
53
|
+
* Returns the instance provider if set, otherwise falls back to the static provider.
|
|
54
|
+
* @returns The query provider instance
|
|
55
|
+
*/
|
|
33
56
|
get ProviderToUse(): IRunQueryProvider;
|
|
57
|
+
/**
|
|
58
|
+
* Executes a saved query and returns the results.
|
|
59
|
+
* The query must exist in the system and the user must have permission to execute it.
|
|
60
|
+
* @param params - Parameters including query ID or name
|
|
61
|
+
* @param contextUser - Optional user context for permissions (mainly used server-side)
|
|
62
|
+
* @returns Query results including data rows and execution metadata
|
|
63
|
+
*/
|
|
34
64
|
RunQuery(params: RunQueryParams, contextUser?: UserInfo): Promise<RunQueryResult>;
|
|
35
65
|
private static _globalProviderKey;
|
|
66
|
+
/**
|
|
67
|
+
* Gets the static query provider instance.
|
|
68
|
+
* Used when no instance-specific provider is configured.
|
|
69
|
+
* @returns The global query provider
|
|
70
|
+
* @throws Error if global object store is not available
|
|
71
|
+
*/
|
|
36
72
|
static get Provider(): IRunQueryProvider;
|
|
73
|
+
/**
|
|
74
|
+
* Sets the static query provider instance.
|
|
75
|
+
* This provider will be used by all RunQuery instances that don't have their own provider.
|
|
76
|
+
* @param value - The query provider to set globally
|
|
77
|
+
* @throws Error if global object store is not available
|
|
78
|
+
*/
|
|
37
79
|
static set Provider(value: IRunQueryProvider);
|
|
38
80
|
}
|
|
39
81
|
//# sourceMappingURL=runQuery.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runQuery.d.ts","sourceRoot":"","sources":["../../src/generic/runQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"runQuery.d.ts","sourceRoot":"","sources":["../../src/generic/runQuery.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IACzB;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAChC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED;;;;GAIG;AACH,qBAAa,QAAQ;IACjB,OAAO,CAAC,SAAS,CAA2B;IAC5C;;OAEG;gBACS,QAAQ,GAAE,iBAAiB,GAAG,IAAW;IAIrD;;;;OAIG;IACH,IAAW,aAAa,IAAI,iBAAiB,CAE5C;IACD;;;;;;OAMG;IACU,QAAQ,CAAC,MAAM,EAAE,cAAc,EAAE,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC;IAI9F,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAiC;IAClE;;;;;OAKG;IACH,WAAkB,QAAQ,IAAI,iBAAiB,CAM9C;IACD;;;;;OAKG;IACH,WAAkB,QAAQ,CAAC,KAAK,EAAE,iBAAiB,EAMlD;CAEJ"}
|
package/dist/generic/runQuery.js
CHANGED
|
@@ -4,6 +4,8 @@ exports.RunQuery = void 0;
|
|
|
4
4
|
const global_1 = require("@memberjunction/global");
|
|
5
5
|
/**
|
|
6
6
|
* Class used to run a query and return the results.
|
|
7
|
+
* Provides an abstraction layer for executing saved queries with proper security checks.
|
|
8
|
+
* Supports both instance-based and static provider patterns.
|
|
7
9
|
*/
|
|
8
10
|
class RunQuery {
|
|
9
11
|
/**
|
|
@@ -12,12 +14,30 @@ class RunQuery {
|
|
|
12
14
|
constructor(provider = null) {
|
|
13
15
|
this._provider = provider;
|
|
14
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Gets the query provider to use for execution.
|
|
19
|
+
* Returns the instance provider if set, otherwise falls back to the static provider.
|
|
20
|
+
* @returns The query provider instance
|
|
21
|
+
*/
|
|
15
22
|
get ProviderToUse() {
|
|
16
23
|
return this._provider || RunQuery.Provider;
|
|
17
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Executes a saved query and returns the results.
|
|
27
|
+
* The query must exist in the system and the user must have permission to execute it.
|
|
28
|
+
* @param params - Parameters including query ID or name
|
|
29
|
+
* @param contextUser - Optional user context for permissions (mainly used server-side)
|
|
30
|
+
* @returns Query results including data rows and execution metadata
|
|
31
|
+
*/
|
|
18
32
|
async RunQuery(params, contextUser) {
|
|
19
33
|
return this.ProviderToUse.RunQuery(params, contextUser);
|
|
20
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Gets the static query provider instance.
|
|
37
|
+
* Used when no instance-specific provider is configured.
|
|
38
|
+
* @returns The global query provider
|
|
39
|
+
* @throws Error if global object store is not available
|
|
40
|
+
*/
|
|
21
41
|
static get Provider() {
|
|
22
42
|
const g = global_1.MJGlobal.Instance.GetGlobalObjectStore();
|
|
23
43
|
if (g)
|
|
@@ -25,6 +45,12 @@ class RunQuery {
|
|
|
25
45
|
else
|
|
26
46
|
throw new Error('No global object store, so we cant get the static provider');
|
|
27
47
|
}
|
|
48
|
+
/**
|
|
49
|
+
* Sets the static query provider instance.
|
|
50
|
+
* This provider will be used by all RunQuery instances that don't have their own provider.
|
|
51
|
+
* @param value - The query provider to set globally
|
|
52
|
+
* @throws Error if global object store is not available
|
|
53
|
+
*/
|
|
28
54
|
static set Provider(value) {
|
|
29
55
|
const g = global_1.MJGlobal.Instance.GetGlobalObjectStore();
|
|
30
56
|
if (g)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runQuery.js","sourceRoot":"","sources":["../../src/generic/runQuery.ts"],"names":[],"mappings":";;;AAAA,mDAAkD;
|
|
1
|
+
{"version":3,"file":"runQuery.js","sourceRoot":"","sources":["../../src/generic/runQuery.ts"],"names":[],"mappings":";;;AAAA,mDAAkD;AA0ClD;;;;GAIG;AACH,MAAa,QAAQ;IAEjB;;OAEG;IACH,YAAY,WAAqC,IAAI;QACjD,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC9B,CAAC;IAED;;;;OAIG;IACH,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,SAAS,IAAI,QAAQ,CAAC,QAAQ,CAAC;IAC/C,CAAC;IACD;;;;;;OAMG;IACI,KAAK,CAAC,QAAQ,CAAC,MAAsB,EAAE,WAAsB;QAChE,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC5D,CAAC;IAGD;;;;;OAKG;IACI,MAAM,KAAK,QAAQ;QACtB,MAAM,CAAC,GAAG,iBAAQ,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;QACnD,IAAI,CAAC;YACD,OAAO,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;;YAEtC,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IACtF,CAAC;IACD;;;;;OAKG;IACI,MAAM,KAAK,QAAQ,CAAC,KAAwB;QAC/C,MAAM,CAAC,GAAG,iBAAQ,CAAC,QAAQ,CAAC,oBAAoB,EAAE,CAAC;QACnD,IAAI,CAAC;YACD,CAAC,CAAC,QAAQ,CAAC,kBAAkB,CAAC,GAAG,KAAK,CAAC;;YAEvC,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;IACtF,CAAC;;AAtDL,4BAwDC;AA5BkB,2BAAkB,GAAW,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SQL Filter Implementations for RunQuery
|
|
3
|
+
*
|
|
4
|
+
* This module provides the actual implementation functions for RunQuery SQL filters.
|
|
5
|
+
* This is separate from the filter definitions to keep AI prompts token-efficient.
|
|
6
|
+
*
|
|
7
|
+
* @module @memberjunction/core/runQuerySQLFilterImplementations
|
|
8
|
+
*/
|
|
9
|
+
import { RunQuerySQLFilter } from './querySQLFilters';
|
|
10
|
+
/**
|
|
11
|
+
* Complete SQL filters with implementations attached.
|
|
12
|
+
* This is the array that should be used by the QueryParameterProcessor.
|
|
13
|
+
*/
|
|
14
|
+
export declare const RUN_QUERY_SQL_FILTERS_WITH_IMPLEMENTATIONS: RunQuerySQLFilter[];
|
|
15
|
+
/**
|
|
16
|
+
* Singleton class for managing RunQuery SQL filters with implementations
|
|
17
|
+
*/
|
|
18
|
+
export declare class RunQuerySQLFilterManager {
|
|
19
|
+
private static _instance;
|
|
20
|
+
private _filters;
|
|
21
|
+
private constructor();
|
|
22
|
+
/**
|
|
23
|
+
* Gets the singleton instance
|
|
24
|
+
*/
|
|
25
|
+
static get Instance(): RunQuerySQLFilterManager;
|
|
26
|
+
/**
|
|
27
|
+
* Gets a filter by name
|
|
28
|
+
* @param name The filter name
|
|
29
|
+
* @returns The filter with implementation or undefined if not found
|
|
30
|
+
*/
|
|
31
|
+
getFilter(name: string): RunQuerySQLFilter | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Gets all available filter names
|
|
34
|
+
* @returns Array of filter names
|
|
35
|
+
*/
|
|
36
|
+
getFilterNames(): string[];
|
|
37
|
+
/**
|
|
38
|
+
* Gets all filters with implementations
|
|
39
|
+
* @returns Array of all filters
|
|
40
|
+
*/
|
|
41
|
+
getAllFilters(): RunQuerySQLFilter[];
|
|
42
|
+
/**
|
|
43
|
+
* Executes a filter function by name
|
|
44
|
+
* @param filterName The name of the filter to execute
|
|
45
|
+
* @param value The value to filter
|
|
46
|
+
* @returns The filtered result
|
|
47
|
+
* @throws Error if filter is not found or execution fails
|
|
48
|
+
*/
|
|
49
|
+
executeFilter(filterName: string, value: any): any;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=runQuerySQLFilterImplementations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runQuerySQLFilterImplementations.d.ts","sourceRoot":"","sources":["../../src/generic/runQuerySQLFilterImplementations.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAyB,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAgM7E;;;GAGG;AACH,eAAO,MAAM,0CAA0C,EAAE,iBAAiB,EAInE,CAAC;AAER;;GAEG;AACH,qBAAa,wBAAwB;IACjC,OAAO,CAAC,MAAM,CAAC,SAAS,CAA2B;IACnD,OAAO,CAAC,QAAQ,CAAiC;IAEjD,OAAO;IAUP;;OAEG;IACH,WAAkB,QAAQ,IAAI,wBAAwB,CAKrD;IAED;;;;OAIG;IACI,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS;IAI7D;;;OAGG;IACI,cAAc,IAAI,MAAM,EAAE;IAIjC;;;OAGG;IACI,aAAa,IAAI,iBAAiB,EAAE;IAI3C;;;;;;OAMG;IACI,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,GAAG;CAO5D"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview SQL Filter Implementations for RunQuery
|
|
4
|
+
*
|
|
5
|
+
* This module provides the actual implementation functions for RunQuery SQL filters.
|
|
6
|
+
* This is separate from the filter definitions to keep AI prompts token-efficient.
|
|
7
|
+
*
|
|
8
|
+
* @module @memberjunction/core/runQuerySQLFilterImplementations
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.RunQuerySQLFilterManager = exports.RUN_QUERY_SQL_FILTERS_WITH_IMPLEMENTATIONS = void 0;
|
|
12
|
+
const querySQLFilters_1 = require("./querySQLFilters");
|
|
13
|
+
/**
|
|
14
|
+
* Dangerous SQL keywords that should be blocked in expressions
|
|
15
|
+
*/
|
|
16
|
+
const DANGEROUS_SQL_KEYWORDS = [
|
|
17
|
+
// DDL (Data Definition Language) - Structure modification
|
|
18
|
+
'DROP', 'CREATE', 'ALTER', 'TRUNCATE', 'RENAME',
|
|
19
|
+
// DML (Data Manipulation Language) - Data modification
|
|
20
|
+
'INSERT', 'UPDATE', 'DELETE', 'MERGE', 'REPLACE',
|
|
21
|
+
// DCL (Data Control Language) - Permissions
|
|
22
|
+
'GRANT', 'REVOKE', 'DENY',
|
|
23
|
+
// Execution and procedures
|
|
24
|
+
'EXEC', 'EXECUTE', 'CALL', 'PROCEDURE', 'FUNCTION',
|
|
25
|
+
// Transaction control
|
|
26
|
+
'BEGIN', 'COMMIT', 'ROLLBACK', 'SAVEPOINT',
|
|
27
|
+
// Database/schema operations
|
|
28
|
+
'USE', 'DATABASE', 'SCHEMA',
|
|
29
|
+
// Conditional execution that could be dangerous
|
|
30
|
+
'IF', 'WHILE', 'LOOP', 'FOR', 'GOTO',
|
|
31
|
+
// System functions and variables
|
|
32
|
+
'SYSTEM', 'ADMIN', 'USER', 'SESSION', 'GLOBAL',
|
|
33
|
+
'SHOW', 'DESCRIBE', 'EXPLAIN',
|
|
34
|
+
// Union and set operations (can be used for injection)
|
|
35
|
+
'UNION', 'INTERSECT', 'EXCEPT',
|
|
36
|
+
// Subquery keywords (when used maliciously)
|
|
37
|
+
'EXISTS', 'ANY', 'ALL', 'SOME',
|
|
38
|
+
// Comment indicators (used in injection)
|
|
39
|
+
'--', '/*', '*/',
|
|
40
|
+
// String manipulation that could escape
|
|
41
|
+
'CHAR', 'ASCII', 'UNICODE',
|
|
42
|
+
// File operations
|
|
43
|
+
'BULK', 'OPENROWSET', 'OPENDATASOURCE', 'OPENQUERY',
|
|
44
|
+
// Dynamic SQL
|
|
45
|
+
'DYNAMIC', 'PREPARE', 'DEALLOCATE',
|
|
46
|
+
// Common injection patterns
|
|
47
|
+
'WAITFOR', 'DELAY', 'SLEEP'
|
|
48
|
+
];
|
|
49
|
+
/**
|
|
50
|
+
* Allowed keywords and functions for ORDER BY and similar expressions
|
|
51
|
+
*/
|
|
52
|
+
const ALLOWED_SQL_KEYWORDS = [
|
|
53
|
+
// Direction keywords
|
|
54
|
+
'ASC', 'ASCENDING', 'DESC', 'DESCENDING',
|
|
55
|
+
// Basic aggregate functions (read-only)
|
|
56
|
+
'COUNT', 'SUM', 'AVG', 'MIN', 'MAX',
|
|
57
|
+
// Math functions
|
|
58
|
+
'ABS', 'CEILING', 'FLOOR', 'ROUND', 'SQRT',
|
|
59
|
+
// String functions (read-only)
|
|
60
|
+
'LEN', 'LENGTH', 'UPPER', 'LOWER', 'LTRIM', 'RTRIM', 'TRIM',
|
|
61
|
+
// Date functions (read-only)
|
|
62
|
+
'YEAR', 'MONTH', 'DAY', 'DATEPART', 'DATEDIFF',
|
|
63
|
+
// Case expressions
|
|
64
|
+
'CASE', 'WHEN', 'THEN', 'ELSE', 'END',
|
|
65
|
+
// Basic logical
|
|
66
|
+
'AND', 'OR', 'NOT', 'IS', 'NULL', 'LIKE',
|
|
67
|
+
// Comparison operators (as words)
|
|
68
|
+
'BETWEEN', 'IN'
|
|
69
|
+
];
|
|
70
|
+
/**
|
|
71
|
+
* SQL Filter implementation functions
|
|
72
|
+
*/
|
|
73
|
+
const FILTER_IMPLEMENTATIONS = {
|
|
74
|
+
sqlString: (value) => {
|
|
75
|
+
if (value === null || value === undefined)
|
|
76
|
+
return 'NULL';
|
|
77
|
+
return `'${String(value).replace(/'/g, "''")}'`;
|
|
78
|
+
},
|
|
79
|
+
sqlNumber: (value) => {
|
|
80
|
+
const num = Number(value);
|
|
81
|
+
if (isNaN(num))
|
|
82
|
+
throw new Error(`Invalid number: ${value}`);
|
|
83
|
+
return num;
|
|
84
|
+
},
|
|
85
|
+
sqlDate: (value) => {
|
|
86
|
+
if (!value)
|
|
87
|
+
return 'NULL';
|
|
88
|
+
const date = value instanceof Date ? value : new Date(value);
|
|
89
|
+
if (isNaN(date.getTime()))
|
|
90
|
+
throw new Error(`Invalid date: ${value}`);
|
|
91
|
+
return `'${date.toISOString()}'`;
|
|
92
|
+
},
|
|
93
|
+
sqlBoolean: (value) => {
|
|
94
|
+
return value ? '1' : '0';
|
|
95
|
+
},
|
|
96
|
+
sqlIdentifier: (value) => {
|
|
97
|
+
if (!value)
|
|
98
|
+
throw new Error('Identifier cannot be empty');
|
|
99
|
+
const identifier = String(value);
|
|
100
|
+
// Basic SQL injection prevention for identifiers
|
|
101
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(identifier)) {
|
|
102
|
+
throw new Error(`Invalid SQL identifier: ${identifier}`);
|
|
103
|
+
}
|
|
104
|
+
return `[${identifier}]`;
|
|
105
|
+
},
|
|
106
|
+
sqlIn: (values) => {
|
|
107
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
108
|
+
return '(NULL)'; // This will match nothing
|
|
109
|
+
}
|
|
110
|
+
const escaped = values.map(v => {
|
|
111
|
+
if (typeof v === 'string') {
|
|
112
|
+
return `'${v.replace(/'/g, "''")}'`;
|
|
113
|
+
}
|
|
114
|
+
else if (typeof v === 'number') {
|
|
115
|
+
return v;
|
|
116
|
+
}
|
|
117
|
+
else if (v === null || v === undefined) {
|
|
118
|
+
return 'NULL';
|
|
119
|
+
}
|
|
120
|
+
return `'${String(v).replace(/'/g, "''")}'`;
|
|
121
|
+
});
|
|
122
|
+
return `(${escaped.join(', ')})`;
|
|
123
|
+
},
|
|
124
|
+
sqlNoKeywordsExpression: (value) => {
|
|
125
|
+
if (!value) {
|
|
126
|
+
throw new Error('SQL expression cannot be empty');
|
|
127
|
+
}
|
|
128
|
+
const expression = String(value).trim();
|
|
129
|
+
if (!expression) {
|
|
130
|
+
throw new Error('SQL expression cannot be empty');
|
|
131
|
+
}
|
|
132
|
+
// Convert to uppercase for keyword checking
|
|
133
|
+
const upperExpression = expression.toUpperCase();
|
|
134
|
+
// Check for dangerous keywords
|
|
135
|
+
for (const keyword of DANGEROUS_SQL_KEYWORDS) {
|
|
136
|
+
// Use word boundaries to avoid false positives (e.g., "Description" containing "DESC")
|
|
137
|
+
const regex = new RegExp(`\\b${keyword.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}\\b`, 'i');
|
|
138
|
+
if (regex.test(upperExpression)) {
|
|
139
|
+
throw new Error(`Dangerous SQL keyword detected: ${keyword}`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Extract all words/tokens from the expression
|
|
143
|
+
const tokens = expression.match(/\b[A-Za-z_][A-Za-z0-9_]*\b/g) || [];
|
|
144
|
+
// Check that any SQL keywords used are in the allowed list
|
|
145
|
+
for (const token of tokens) {
|
|
146
|
+
const upperToken = token.toUpperCase();
|
|
147
|
+
// If it's a SQL keyword (appears in either list), it must be in the allowed list
|
|
148
|
+
const isKnownKeyword = DANGEROUS_SQL_KEYWORDS.includes(upperToken) || ALLOWED_SQL_KEYWORDS.includes(upperToken);
|
|
149
|
+
const isAllowed = ALLOWED_SQL_KEYWORDS.includes(upperToken);
|
|
150
|
+
// If it's a known SQL keyword and not allowed, block it
|
|
151
|
+
if (isKnownKeyword && !isAllowed) {
|
|
152
|
+
throw new Error(`SQL keyword '${token}' is not allowed in expressions`);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Additional safety checks
|
|
156
|
+
if (upperExpression.includes('--') || upperExpression.includes('/*') || upperExpression.includes('*/')) {
|
|
157
|
+
throw new Error('Comments are not allowed in SQL expressions');
|
|
158
|
+
}
|
|
159
|
+
if (upperExpression.includes(';')) {
|
|
160
|
+
throw new Error('Semicolons are not allowed in SQL expressions');
|
|
161
|
+
}
|
|
162
|
+
// Check for suspicious patterns
|
|
163
|
+
if (upperExpression.includes('()') && !upperExpression.match(/\b(COUNT|SUM|AVG|MIN|MAX|ABS|CEILING|FLOOR|ROUND|SQRT|LEN|LENGTH|UPPER|LOWER|TRIM|YEAR|MONTH|DAY)\s*\(/i)) {
|
|
164
|
+
throw new Error('Function calls with empty parentheses are not allowed');
|
|
165
|
+
}
|
|
166
|
+
// Return the original expression (preserving case)
|
|
167
|
+
return expression;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
/**
|
|
171
|
+
* Complete SQL filters with implementations attached.
|
|
172
|
+
* This is the array that should be used by the QueryParameterProcessor.
|
|
173
|
+
*/
|
|
174
|
+
exports.RUN_QUERY_SQL_FILTERS_WITH_IMPLEMENTATIONS = querySQLFilters_1.RUN_QUERY_SQL_FILTERS.map(filter => ({
|
|
175
|
+
...filter,
|
|
176
|
+
implementation: FILTER_IMPLEMENTATIONS[filter.name]
|
|
177
|
+
}));
|
|
178
|
+
/**
|
|
179
|
+
* Singleton class for managing RunQuery SQL filters with implementations
|
|
180
|
+
*/
|
|
181
|
+
class RunQuerySQLFilterManager {
|
|
182
|
+
constructor() {
|
|
183
|
+
this._filters = new Map();
|
|
184
|
+
// Initialize with all filters that have implementations
|
|
185
|
+
exports.RUN_QUERY_SQL_FILTERS_WITH_IMPLEMENTATIONS.forEach(filter => {
|
|
186
|
+
if (filter.implementation) {
|
|
187
|
+
this._filters.set(filter.name, filter);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Gets the singleton instance
|
|
193
|
+
*/
|
|
194
|
+
static get Instance() {
|
|
195
|
+
if (!this._instance) {
|
|
196
|
+
this._instance = new RunQuerySQLFilterManager();
|
|
197
|
+
}
|
|
198
|
+
return this._instance;
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Gets a filter by name
|
|
202
|
+
* @param name The filter name
|
|
203
|
+
* @returns The filter with implementation or undefined if not found
|
|
204
|
+
*/
|
|
205
|
+
getFilter(name) {
|
|
206
|
+
return this._filters.get(name);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Gets all available filter names
|
|
210
|
+
* @returns Array of filter names
|
|
211
|
+
*/
|
|
212
|
+
getFilterNames() {
|
|
213
|
+
return Array.from(this._filters.keys());
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Gets all filters with implementations
|
|
217
|
+
* @returns Array of all filters
|
|
218
|
+
*/
|
|
219
|
+
getAllFilters() {
|
|
220
|
+
return Array.from(this._filters.values());
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Executes a filter function by name
|
|
224
|
+
* @param filterName The name of the filter to execute
|
|
225
|
+
* @param value The value to filter
|
|
226
|
+
* @returns The filtered result
|
|
227
|
+
* @throws Error if filter is not found or execution fails
|
|
228
|
+
*/
|
|
229
|
+
executeFilter(filterName, value) {
|
|
230
|
+
const filter = this._filters.get(filterName);
|
|
231
|
+
if (!filter || !filter.implementation) {
|
|
232
|
+
throw new Error(`Filter '${filterName}' not found or has no implementation`);
|
|
233
|
+
}
|
|
234
|
+
return filter.implementation(value);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
exports.RunQuerySQLFilterManager = RunQuerySQLFilterManager;
|
|
238
|
+
//# sourceMappingURL=runQuerySQLFilterImplementations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runQuerySQLFilterImplementations.js","sourceRoot":"","sources":["../../src/generic/runQuerySQLFilterImplementations.ts"],"names":[],"mappings":"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"}
|