@gblikas/querykit 0.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.
Files changed (118) hide show
  1. package/.cursor/BUGBOT.md +21 -0
  2. package/.cursor/rules/01-project-structure.mdc +77 -0
  3. package/.cursor/rules/02-typescript-standards.mdc +105 -0
  4. package/.cursor/rules/03-testing-standards.mdc +78 -0
  5. package/.cursor/rules/04-query-language.mdc +79 -0
  6. package/.cursor/rules/05-solid-principles.mdc +118 -0
  7. package/.cursor/rules/liqe-readme-docs.mdc +438 -0
  8. package/.devcontainer/devcontainer.json +25 -0
  9. package/.eslintignore +1 -0
  10. package/.eslintrc.js +39 -0
  11. package/.github/dependabot.yml +12 -0
  12. package/.github/workflows/ci.yml +114 -0
  13. package/.github/workflows/publish.yml +61 -0
  14. package/.husky/pre-commit +30 -0
  15. package/.prettierrc +10 -0
  16. package/CONTRIBUTING.md +187 -0
  17. package/LICENSE +674 -0
  18. package/README.md +237 -0
  19. package/dist/adapters/drizzle/index.d.ts +122 -0
  20. package/dist/adapters/drizzle/index.js +166 -0
  21. package/dist/adapters/index.d.ts +7 -0
  22. package/dist/adapters/index.js +25 -0
  23. package/dist/adapters/types.d.ts +60 -0
  24. package/dist/adapters/types.js +8 -0
  25. package/dist/index.d.ts +75 -0
  26. package/dist/index.js +118 -0
  27. package/dist/parser/index.d.ts +2 -0
  28. package/dist/parser/index.js +18 -0
  29. package/dist/parser/parser.d.ts +51 -0
  30. package/dist/parser/parser.js +201 -0
  31. package/dist/parser/types.d.ts +68 -0
  32. package/dist/parser/types.js +5 -0
  33. package/dist/query/builder.d.ts +61 -0
  34. package/dist/query/builder.js +188 -0
  35. package/dist/query/index.d.ts +2 -0
  36. package/dist/query/index.js +18 -0
  37. package/dist/query/types.d.ts +79 -0
  38. package/dist/query/types.js +2 -0
  39. package/dist/security/index.d.ts +2 -0
  40. package/dist/security/index.js +18 -0
  41. package/dist/security/types.d.ts +181 -0
  42. package/dist/security/types.js +43 -0
  43. package/dist/security/validator.d.ts +191 -0
  44. package/dist/security/validator.js +344 -0
  45. package/dist/translators/drizzle/index.d.ts +73 -0
  46. package/dist/translators/drizzle/index.js +260 -0
  47. package/dist/translators/index.d.ts +8 -0
  48. package/dist/translators/index.js +27 -0
  49. package/dist/translators/sql/index.d.ts +108 -0
  50. package/dist/translators/sql/index.js +252 -0
  51. package/dist/translators/types.d.ts +39 -0
  52. package/dist/translators/types.js +8 -0
  53. package/examples/qk-next/README.md +35 -0
  54. package/examples/qk-next/app/favicon.ico +0 -0
  55. package/examples/qk-next/app/globals.css +122 -0
  56. package/examples/qk-next/app/layout.tsx +121 -0
  57. package/examples/qk-next/app/page.tsx +813 -0
  58. package/examples/qk-next/app/providers.tsx +80 -0
  59. package/examples/qk-next/components/aurora-background.tsx +12 -0
  60. package/examples/qk-next/components/github-stars.tsx +51 -0
  61. package/examples/qk-next/components/mode-toggle.tsx +27 -0
  62. package/examples/qk-next/components/reactbits/blocks/Backgrounds/Aurora/Aurora.tsx +217 -0
  63. package/examples/qk-next/components/reactbits/blocks/Backgrounds/LightRays/LightRays.tsx +474 -0
  64. package/examples/qk-next/components/theme-provider.tsx +11 -0
  65. package/examples/qk-next/components/ui/card.tsx +92 -0
  66. package/examples/qk-next/components/ui/command.tsx +184 -0
  67. package/examples/qk-next/components/ui/dialog.tsx +143 -0
  68. package/examples/qk-next/components/ui/drawer.tsx +135 -0
  69. package/examples/qk-next/components/ui/hover-card.tsx +44 -0
  70. package/examples/qk-next/components/ui/icons.tsx +148 -0
  71. package/examples/qk-next/components/ui/sonner.tsx +26 -0
  72. package/examples/qk-next/components/ui/table.tsx +117 -0
  73. package/examples/qk-next/components.json +21 -0
  74. package/examples/qk-next/eslint.config.mjs +21 -0
  75. package/examples/qk-next/jsrepo.json +13 -0
  76. package/examples/qk-next/lib/utils.ts +6 -0
  77. package/examples/qk-next/next.config.ts +8 -0
  78. package/examples/qk-next/package.json +48 -0
  79. package/examples/qk-next/pnpm-lock.yaml +5558 -0
  80. package/examples/qk-next/postcss.config.mjs +5 -0
  81. package/examples/qk-next/public/file.svg +1 -0
  82. package/examples/qk-next/public/globe.svg +1 -0
  83. package/examples/qk-next/public/next.svg +1 -0
  84. package/examples/qk-next/public/vercel.svg +1 -0
  85. package/examples/qk-next/public/window.svg +1 -0
  86. package/examples/qk-next/tsconfig.json +42 -0
  87. package/examples/qk-next/types/sonner.d.ts +3 -0
  88. package/jest.config.js +26 -0
  89. package/package.json +51 -0
  90. package/src/adapters/drizzle/drizzle-adapter.test.ts +115 -0
  91. package/src/adapters/drizzle/index.ts +299 -0
  92. package/src/adapters/index.ts +11 -0
  93. package/src/adapters/types.ts +72 -0
  94. package/src/index.ts +194 -0
  95. package/src/integration.test.ts +202 -0
  96. package/src/parser/index.ts +2 -0
  97. package/src/parser/parser.test.ts +1056 -0
  98. package/src/parser/parser.ts +268 -0
  99. package/src/parser/types.ts +97 -0
  100. package/src/query/builder.test.ts +272 -0
  101. package/src/query/builder.ts +274 -0
  102. package/src/query/index.ts +2 -0
  103. package/src/query/types.ts +107 -0
  104. package/src/security/index.ts +2 -0
  105. package/src/security/types.ts +210 -0
  106. package/src/security/validator.test.ts +459 -0
  107. package/src/security/validator.ts +395 -0
  108. package/src/security.test.ts +366 -0
  109. package/src/translators/drizzle/drizzle-translator.test.ts +128 -0
  110. package/src/translators/drizzle/index.test.ts +45 -0
  111. package/src/translators/drizzle/index.ts +346 -0
  112. package/src/translators/index.ts +14 -0
  113. package/src/translators/sql/index.test.ts +45 -0
  114. package/src/translators/sql/index.ts +331 -0
  115. package/src/translators/sql/sql-translator.test.ts +419 -0
  116. package/src/translators/types.ts +44 -0
  117. package/src/types/sonner.d.ts +3 -0
  118. package/tsconfig.json +34 -0
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QueryBuilder = void 0;
4
+ const parser_1 = require("../parser");
5
+ /**
6
+ * Implementation of the type-safe query builder
7
+ */
8
+ class QueryBuilder {
9
+ constructor(options = {}) {
10
+ this.expression = '';
11
+ this.orderByClause = '';
12
+ this.limitClause = '';
13
+ this.offsetClause = '';
14
+ this.parser = new parser_1.QueryParser({
15
+ caseInsensitiveFields: options.caseInsensitiveFields,
16
+ fieldMappings: options.fieldMappings
17
+ });
18
+ }
19
+ where(fieldOrQueryString, operator, value) {
20
+ if (operator === undefined || value === undefined) {
21
+ // Handle direct query string format
22
+ this.expression = fieldOrQueryString;
23
+ }
24
+ else {
25
+ // Handle field, operator, value format
26
+ this.expression = this.buildComparison(fieldOrQueryString, operator, value);
27
+ }
28
+ return this;
29
+ }
30
+ andWhere(fieldOrQueryString, operator, value) {
31
+ if (!this.expression) {
32
+ if (typeof fieldOrQueryString === 'string' && (operator === undefined || value === undefined)) {
33
+ // Handle direct query string
34
+ return this.where(fieldOrQueryString);
35
+ }
36
+ else {
37
+ // Handle field, operator, value format
38
+ return this.where(fieldOrQueryString, operator, value);
39
+ }
40
+ }
41
+ if (operator === undefined || value === undefined) {
42
+ // Handle direct query string format
43
+ this.expression = `(${this.expression}) AND ${fieldOrQueryString}`;
44
+ }
45
+ else {
46
+ // Handle field, operator, value format
47
+ this.expression = `(${this.expression}) AND ${this.buildComparison(fieldOrQueryString, operator, value)}`;
48
+ }
49
+ return this;
50
+ }
51
+ orWhere(fieldOrQueryString, operator, value) {
52
+ if (!this.expression) {
53
+ if (typeof fieldOrQueryString === 'string' && (operator === undefined || value === undefined)) {
54
+ // Handle direct query string
55
+ return this.where(fieldOrQueryString);
56
+ }
57
+ else {
58
+ // Handle field, operator, value format
59
+ return this.where(fieldOrQueryString, operator, value);
60
+ }
61
+ }
62
+ if (operator === undefined || value === undefined) {
63
+ // Handle direct query string format
64
+ this.expression = `(${this.expression}) OR ${fieldOrQueryString}`;
65
+ }
66
+ else {
67
+ // Handle field, operator, value format
68
+ this.expression = `(${this.expression}) OR ${this.buildComparison(fieldOrQueryString, operator, value)}`;
69
+ }
70
+ return this;
71
+ }
72
+ notWhere(fieldOrQueryString, operator, value) {
73
+ if (!this.expression) {
74
+ if (operator === undefined || value === undefined) {
75
+ // Handle direct query string format
76
+ this.expression = `NOT ${fieldOrQueryString}`;
77
+ }
78
+ else {
79
+ // Handle field, operator, value format
80
+ this.expression = `NOT ${this.buildComparison(fieldOrQueryString, operator, value)}`;
81
+ }
82
+ }
83
+ else {
84
+ if (operator === undefined || value === undefined) {
85
+ // Handle direct query string format
86
+ this.expression = `(${this.expression}) AND NOT ${fieldOrQueryString}`;
87
+ }
88
+ else {
89
+ // Handle field, operator, value format
90
+ this.expression = `(${this.expression}) AND NOT ${this.buildComparison(fieldOrQueryString, operator, value)}`;
91
+ }
92
+ }
93
+ return this;
94
+ }
95
+ /**
96
+ * Add an order by clause to the query
97
+ */
98
+ orderBy(field, direction = 'asc') {
99
+ this.orderByClause = `ORDER BY ${field} ${direction.toUpperCase()}`;
100
+ return this;
101
+ }
102
+ /**
103
+ * Add a limit to the query
104
+ */
105
+ limit(count) {
106
+ this.limitClause = `LIMIT ${count}`;
107
+ return this;
108
+ }
109
+ /**
110
+ * Add an offset to the query
111
+ */
112
+ offset(count) {
113
+ this.offsetClause = `OFFSET ${count}`;
114
+ return this;
115
+ }
116
+ /**
117
+ * Get the current query expression
118
+ */
119
+ getExpression() {
120
+ return this.parser.parse(this.expression);
121
+ }
122
+ /**
123
+ * Get the current query as a string
124
+ */
125
+ toString() {
126
+ const clauses = [
127
+ this.expression,
128
+ this.orderByClause,
129
+ this.limitClause,
130
+ this.offsetClause
131
+ ].filter(Boolean);
132
+ return clauses.join(' ');
133
+ }
134
+ /**
135
+ * Build a comparison expression
136
+ */
137
+ buildComparison(field, operator, value) {
138
+ // Map QueryKit operators to Liqe operators
139
+ const operatorMap = {
140
+ '==': ':',
141
+ '!=': '!=',
142
+ '>': '>',
143
+ '>=': '>=',
144
+ '<': '<',
145
+ '<=': '<=',
146
+ 'IN': 'in',
147
+ 'NOT IN': 'not in',
148
+ 'LIKE': ':'
149
+ };
150
+ const liqeOperator = operatorMap[operator];
151
+ const formattedValue = this.formatValue(value, operator);
152
+ // For equality and LIKE operators, use field:value format (simple colon)
153
+ if (operator === '==' || operator === 'LIKE') {
154
+ return `${field}${liqeOperator}${formattedValue}`;
155
+ }
156
+ // Based on Liqe docs, comparison operators are prefixed with colon
157
+ // e.g., 'height:>100', 'height:<100'
158
+ if (operator === '>' || operator === '>=' || operator === '<' || operator === '<=' || operator === '!=') {
159
+ return `${field}:${liqeOperator}${formattedValue}`;
160
+ }
161
+ // For array operators (IN, NOT IN), use the format field:operator[values]
162
+ if (operator === 'IN' || operator === 'NOT IN') {
163
+ return `${field}:${liqeOperator}${formattedValue}`;
164
+ }
165
+ // For other operators, use field:operator value format
166
+ return `${field}:${liqeOperator} ${formattedValue}`;
167
+ }
168
+ /**
169
+ * Format a value for use in a query
170
+ */
171
+ formatValue(value, operator) {
172
+ if (value === null) {
173
+ return 'null';
174
+ }
175
+ if (Array.isArray(value)) {
176
+ return `[${value.map(v => this.formatValue(v)).join(',')}]`;
177
+ }
178
+ if (typeof value === 'string') {
179
+ // For LIKE operator with wildcard patterns, don't add quotes to allow pattern matching
180
+ if (operator === 'LIKE' && (value.includes('*') || value.includes('?'))) {
181
+ return value;
182
+ }
183
+ return `"${value}"`;
184
+ }
185
+ return String(value);
186
+ }
187
+ }
188
+ exports.QueryBuilder = QueryBuilder;
@@ -0,0 +1,2 @@
1
+ export * from './types';
2
+ export * from './builder';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./builder"), exports);
@@ -0,0 +1,79 @@
1
+ import { QueryExpression } from '../parser/types';
2
+ /**
3
+ * Represents a field in a query
4
+ */
5
+ export type QueryField<T> = keyof T & string;
6
+ /**
7
+ * Represents a value that can be used in a query
8
+ */
9
+ export type QueryValue = string | number | boolean | null | Array<string | number | boolean | null>;
10
+ /**
11
+ * Represents a comparison operator in a query
12
+ */
13
+ export type ComparisonOperator = '==' | '!=' | '>' | '>=' | '<' | '<=' | 'IN' | 'NOT IN' | 'LIKE';
14
+ /**
15
+ * Represents a logical operator in a query
16
+ */
17
+ export type LogicalOperator = 'AND' | 'OR' | 'NOT';
18
+ /**
19
+ * Represents a sort direction
20
+ */
21
+ export type SortDirection = 'asc' | 'desc';
22
+ /**
23
+ * Configuration options for the query builder
24
+ */
25
+ export interface IQueryBuilderOptions<T> {
26
+ /**
27
+ * Whether to allow case-insensitive field names
28
+ */
29
+ caseInsensitiveFields?: boolean;
30
+ /**
31
+ * Custom field name mappings
32
+ */
33
+ fieldMappings?: Partial<Record<QueryField<T>, string>>;
34
+ }
35
+ /**
36
+ * Interface for a query builder
37
+ */
38
+ export interface IQueryBuilder<T> {
39
+ /**
40
+ * Add a where clause to the query
41
+ */
42
+ where(queryString: string): IQueryBuilder<T>;
43
+ where(field: QueryField<T>, operator: ComparisonOperator, value: QueryValue): IQueryBuilder<T>;
44
+ /**
45
+ * Add an AND where clause to the query
46
+ */
47
+ andWhere(queryString: string): IQueryBuilder<T>;
48
+ andWhere(field: QueryField<T>, operator: ComparisonOperator, value: QueryValue): IQueryBuilder<T>;
49
+ /**
50
+ * Add an OR where clause to the query
51
+ */
52
+ orWhere(queryString: string): IQueryBuilder<T>;
53
+ orWhere(field: QueryField<T>, operator: ComparisonOperator, value: QueryValue): IQueryBuilder<T>;
54
+ /**
55
+ * Add a NOT where clause to the query
56
+ */
57
+ notWhere(queryString: string): IQueryBuilder<T>;
58
+ notWhere(field: QueryField<T>, operator: ComparisonOperator, value: QueryValue): IQueryBuilder<T>;
59
+ /**
60
+ * Add an order by clause to the query
61
+ */
62
+ orderBy(field: QueryField<T>, direction?: SortDirection): IQueryBuilder<T>;
63
+ /**
64
+ * Add a limit to the query
65
+ */
66
+ limit(count: number): IQueryBuilder<T>;
67
+ /**
68
+ * Add an offset to the query
69
+ */
70
+ offset(count: number): IQueryBuilder<T>;
71
+ /**
72
+ * Get the current query expression
73
+ */
74
+ getExpression(): QueryExpression;
75
+ /**
76
+ * Get the current query as a string
77
+ */
78
+ toString(): string;
79
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export * from './types';
2
+ export * from './validator';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./validator"), exports);
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Security configuration types for QueryKit
3
+ *
4
+ * This module defines the security configuration interface and default values
5
+ * used throughout QueryKit to enforce security boundaries and prevent abuse.
6
+ */
7
+ /**
8
+ * @interface ISecurityOptions
9
+ * @description Comprehensive security configuration options for QueryKit
10
+ *
11
+ * These options help protect your application from potential security issues,
12
+ * resource exhaustion, and performance problems when exposing QueryKit to users.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import { createQueryKit, type ISecurityOptions } from 'querykit';
17
+ *
18
+ * // Configure security options
19
+ * const securityOptions: ISecurityOptions = {
20
+ * allowedFields: ['id', 'name', 'createdAt'],
21
+ * denyFields: ['password', 'secretKey'],
22
+ * maxQueryDepth: 5,
23
+ * maxClauseCount: 20
24
+ * };
25
+ *
26
+ * // Create QueryKit instance with security options
27
+ * const queryKit = createQueryKit({
28
+ * // ...other options
29
+ * security: securityOptions
30
+ * });
31
+ * ```
32
+ */
33
+ export interface ISecurityOptions {
34
+ /**
35
+ * List of fields that are allowed to be queried.
36
+ * If empty, all fields in the schema are allowed by default.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * // Only allow specific fields to be queried
41
+ * allowedFields: ['id', 'name', 'email', 'createdAt']
42
+ * ```
43
+ */
44
+ allowedFields?: string[];
45
+ /**
46
+ * List of fields that are explicitly denied from being queried.
47
+ * These fields will be blocked even if they appear in allowedFields.
48
+ * Use this to protect sensitive data fields.
49
+ *
50
+ * @example
51
+ * ```typescript
52
+ * // Prevent querying of sensitive fields
53
+ * denyFields: ['password', 'secretToken', 'ssn']
54
+ * ```
55
+ */
56
+ denyFields?: string[];
57
+ /**
58
+ * Maximum nesting depth of query expressions.
59
+ * Prevents deeply nested queries that could impact performance.
60
+ *
61
+ * @default 10
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * // Allow only simple queries with limited nesting
66
+ * maxQueryDepth: 3
67
+ *
68
+ * // This would allow queries like:
69
+ * // title:"Meeting notes" && (priority > 2 || completed == true)
70
+ * // But would reject more deeply nested expressions
71
+ * ```
72
+ */
73
+ maxQueryDepth?: number;
74
+ /**
75
+ * Maximum number of clauses (AND/OR operations) in a query.
76
+ * Prevents overly complex queries that could impact performance.
77
+ *
78
+ * @default 50
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * // Limit query complexity
83
+ * maxClauseCount: 20
84
+ *
85
+ * // This would allow queries with up to 20 conditions joined by AND/OR
86
+ * ```
87
+ */
88
+ maxClauseCount?: number;
89
+ /**
90
+ * Default limit for query results if none is specified by the client.
91
+ * Prevents unintentionally large result sets.
92
+ *
93
+ * @default 100
94
+ *
95
+ * @example
96
+ * ```typescript
97
+ * // Set conservative default limit
98
+ * defaultLimit: 50
99
+ * ```
100
+ */
101
+ defaultLimit?: number;
102
+ /**
103
+ * Maximum allowed limit for pagination.
104
+ * Prevents clients from requesting excessively large result sets.
105
+ *
106
+ * @default 1000
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * // Restrict maximum page size
111
+ * maxLimit: 500
112
+ *
113
+ * // Even if a client requests limit=10000, it will be capped at 500
114
+ * ```
115
+ */
116
+ maxLimit?: number;
117
+ /**
118
+ * Maximum string length for query values.
119
+ * Prevents memory exhaustion from extremely large string values.
120
+ *
121
+ * @default 1000
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * // Limit string length in query values
126
+ * maxValueLength: 500
127
+ *
128
+ * // Prevents attacks using extremely long strings in filters
129
+ * ```
130
+ */
131
+ maxValueLength?: number;
132
+ /**
133
+ * Whether to sanitize wildcard patterns in LIKE queries to prevent regex DoS.
134
+ * When enabled, excessive wildcard patterns are sanitized or rejected.
135
+ *
136
+ * @default true
137
+ *
138
+ * @example
139
+ * ```typescript
140
+ * // Enable wildcard sanitization
141
+ * sanitizeWildcards: true
142
+ *
143
+ * // Prevents regex DoS attacks like: name LIKE "%a%a%a%a%a%a%a%a%..."
144
+ * ```
145
+ */
146
+ sanitizeWildcards?: boolean;
147
+ /**
148
+ * Timeout in milliseconds for query execution.
149
+ * Prevents long-running queries from consuming excessive resources.
150
+ *
151
+ * @default 30000 (30 seconds)
152
+ *
153
+ * @example
154
+ * ```typescript
155
+ * // Set shorter timeout for API endpoints
156
+ * queryTimeout: 5000 // 5 seconds
157
+ *
158
+ * // Queries taking longer than 5 seconds will be terminated
159
+ * ```
160
+ */
161
+ queryTimeout?: number;
162
+ }
163
+ /**
164
+ * Default security configuration values
165
+ *
166
+ * These defaults provide a reasonable balance between functionality and security.
167
+ * It's recommended to review and adjust these settings based on your specific use case.
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * import { DEFAULT_SECURITY_OPTIONS } from 'querykit';
172
+ *
173
+ * // Use defaults but override specific options
174
+ * const securityOptions = {
175
+ * ...DEFAULT_SECURITY_OPTIONS,
176
+ * maxLimit: 500,
177
+ * queryTimeout: 10000
178
+ * };
179
+ * ```
180
+ */
181
+ export declare const DEFAULT_SECURITY_OPTIONS: Required<ISecurityOptions>;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ /**
3
+ * Security configuration types for QueryKit
4
+ *
5
+ * This module defines the security configuration interface and default values
6
+ * used throughout QueryKit to enforce security boundaries and prevent abuse.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.DEFAULT_SECURITY_OPTIONS = void 0;
10
+ /**
11
+ * Default security configuration values
12
+ *
13
+ * These defaults provide a reasonable balance between functionality and security.
14
+ * It's recommended to review and adjust these settings based on your specific use case.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { DEFAULT_SECURITY_OPTIONS } from 'querykit';
19
+ *
20
+ * // Use defaults but override specific options
21
+ * const securityOptions = {
22
+ * ...DEFAULT_SECURITY_OPTIONS,
23
+ * maxLimit: 500,
24
+ * queryTimeout: 10000
25
+ * };
26
+ * ```
27
+ */
28
+ exports.DEFAULT_SECURITY_OPTIONS = {
29
+ // Field restrictions - by default, all schema fields are allowed
30
+ allowedFields: [], // Empty means "use schema fields"
31
+ denyFields: [], // Empty means no denied fields
32
+ // Query complexity limits
33
+ maxQueryDepth: 10, // Maximum nesting level of expressions
34
+ maxClauseCount: 50, // Maximum number of clauses (AND/OR operations)
35
+ // Resource protection
36
+ defaultLimit: 100, // Default result limit if none specified
37
+ maxLimit: 1000, // Maximum allowed limit for pagination
38
+ // Value sanitization
39
+ maxValueLength: 1000, // Maximum string length for query values
40
+ sanitizeWildcards: true, // Prevent regex DoS with wildcards in LIKE queries
41
+ // Performance safeguards
42
+ queryTimeout: 30000 // 30 second timeout by default
43
+ };