glasswork 1.0.0 → 1.1.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 (198) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +34 -2
  3. package/dist/audit/audit-logger.d.ts +22 -0
  4. package/dist/audit/audit-logger.d.ts.map +1 -0
  5. package/dist/audit/audit-logger.js +44 -0
  6. package/dist/audit/audit-logger.js.map +1 -0
  7. package/dist/audit/context.d.ts +13 -0
  8. package/dist/audit/context.d.ts.map +1 -0
  9. package/dist/audit/context.js +66 -0
  10. package/dist/audit/context.js.map +1 -0
  11. package/dist/audit/index.d.ts +8 -0
  12. package/dist/audit/index.d.ts.map +1 -0
  13. package/dist/audit/index.js +7 -0
  14. package/dist/audit/index.js.map +1 -0
  15. package/dist/audit/types.d.ts +74 -0
  16. package/dist/audit/types.d.ts.map +1 -0
  17. package/dist/audit/types.js +2 -0
  18. package/dist/audit/types.js.map +1 -0
  19. package/dist/auth/abilities.d.ts +1 -1
  20. package/dist/auth/abilities.d.ts.map +1 -1
  21. package/dist/auth/abilities.js.map +1 -1
  22. package/dist/auth/better-auth-provider.d.ts +6 -3
  23. package/dist/auth/better-auth-provider.d.ts.map +1 -1
  24. package/dist/auth/better-auth-provider.js +1 -3
  25. package/dist/auth/better-auth-provider.js.map +1 -1
  26. package/dist/auth/index.d.ts +2 -2
  27. package/dist/auth/index.d.ts.map +1 -1
  28. package/dist/auth/index.js.map +1 -1
  29. package/dist/auth/middleware.d.ts +9 -7
  30. package/dist/auth/middleware.d.ts.map +1 -1
  31. package/dist/auth/middleware.js +9 -1
  32. package/dist/auth/middleware.js.map +1 -1
  33. package/dist/auth/types.d.ts +7 -0
  34. package/dist/auth/types.d.ts.map +1 -1
  35. package/dist/config/config-service.d.ts.map +1 -1
  36. package/dist/config/config-service.js.map +1 -1
  37. package/dist/config/providers.js.map +1 -1
  38. package/dist/core/bootstrap.js.map +1 -1
  39. package/dist/email/compiler/compiler.js +3 -3
  40. package/dist/email/compiler/compiler.js.map +1 -1
  41. package/dist/email/email-service.d.ts.map +1 -1
  42. package/dist/email/template-registry.d.ts.map +1 -1
  43. package/dist/email/templated-email-service.d.ts.map +1 -1
  44. package/dist/email/transports/mock-transport.d.ts.map +1 -1
  45. package/dist/email/transports/ses-transport.d.ts.map +1 -1
  46. package/dist/email/webhooks/handler-factory.js.map +1 -1
  47. package/dist/email/webhooks/signature-verification.js.map +1 -1
  48. package/dist/email/webhooks/subscription-handler.js.map +1 -1
  49. package/dist/hono-context.d.ts +1 -1
  50. package/dist/hono-context.d.ts.map +1 -1
  51. package/dist/http/error-handler.js.map +1 -1
  52. package/dist/http/errors.d.ts.map +1 -1
  53. package/dist/http/errors.js.map +1 -1
  54. package/dist/http/route-authorization.d.ts +1 -2
  55. package/dist/http/route-authorization.d.ts.map +1 -1
  56. package/dist/http/route-authorization.js.map +1 -1
  57. package/dist/http/route-context.d.ts +4 -2
  58. package/dist/http/route-context.d.ts.map +1 -1
  59. package/dist/http/route-context.js +7 -2
  60. package/dist/http/route-context.js.map +1 -1
  61. package/dist/http/route-helpers.d.ts +3 -3
  62. package/dist/http/route-helpers.d.ts.map +1 -1
  63. package/dist/http/route-helpers.js.map +1 -1
  64. package/dist/http/route-openapi.d.ts +1 -1
  65. package/dist/http/route-openapi.d.ts.map +1 -1
  66. package/dist/http/route-openapi.js.map +1 -1
  67. package/dist/http/route-types.d.ts +26 -23
  68. package/dist/http/route-types.d.ts.map +1 -1
  69. package/dist/jobs/drivers/eventbridge-scheduler-driver.d.ts.map +1 -1
  70. package/dist/jobs/drivers/eventbridge-scheduler-driver.js.map +1 -1
  71. package/dist/jobs/drivers/mock-driver.d.ts.map +1 -1
  72. package/dist/jobs/drivers/mock-driver.js.map +1 -1
  73. package/dist/jobs/drivers/sqs-driver.d.ts.map +1 -1
  74. package/dist/jobs/drivers/sqs-driver.js.map +1 -1
  75. package/dist/jobs/errors.d.ts.map +1 -1
  76. package/dist/jobs/job-registry.d.ts.map +1 -1
  77. package/dist/jobs/job-registry.js.map +1 -1
  78. package/dist/jobs/job-service.d.ts.map +1 -1
  79. package/dist/jobs/job-service.js.map +1 -1
  80. package/dist/jobs/observability/client.d.ts +26 -0
  81. package/dist/jobs/observability/client.d.ts.map +1 -0
  82. package/dist/jobs/observability/client.js +286 -0
  83. package/dist/jobs/observability/client.js.map +1 -0
  84. package/dist/jobs/observability/dashboard.d.ts +19 -0
  85. package/dist/jobs/observability/dashboard.d.ts.map +1 -0
  86. package/dist/jobs/observability/dashboard.js +144 -0
  87. package/dist/jobs/observability/dashboard.js.map +1 -0
  88. package/dist/jobs/observability/emf.d.ts +24 -0
  89. package/dist/jobs/observability/emf.d.ts.map +1 -0
  90. package/dist/jobs/observability/emf.js +100 -0
  91. package/dist/jobs/observability/emf.js.map +1 -0
  92. package/dist/jobs/observability/index.d.ts +5 -0
  93. package/dist/jobs/observability/index.d.ts.map +1 -0
  94. package/dist/jobs/observability/index.js +4 -0
  95. package/dist/jobs/observability/index.js.map +1 -0
  96. package/dist/jobs/observability/types.d.ts +234 -0
  97. package/dist/jobs/observability/types.d.ts.map +1 -0
  98. package/dist/jobs/observability/types.js +2 -0
  99. package/dist/jobs/observability/types.js.map +1 -0
  100. package/dist/jobs/worker.d.ts +1 -1
  101. package/dist/jobs/worker.d.ts.map +1 -1
  102. package/dist/list-query/builder.d.ts +11 -2
  103. package/dist/list-query/builder.d.ts.map +1 -1
  104. package/dist/list-query/builder.js +29 -5
  105. package/dist/list-query/builder.js.map +1 -1
  106. package/dist/list-query/filter-mapping.d.ts +89 -0
  107. package/dist/list-query/filter-mapping.d.ts.map +1 -0
  108. package/dist/list-query/filter-mapping.js +254 -0
  109. package/dist/list-query/filter-mapping.js.map +1 -0
  110. package/dist/list-query/filter-value-schemas.d.ts +16 -0
  111. package/dist/list-query/filter-value-schemas.d.ts.map +1 -0
  112. package/dist/list-query/filter-value-schemas.js +56 -0
  113. package/dist/list-query/filter-value-schemas.js.map +1 -0
  114. package/dist/list-query/index.d.ts +5 -2
  115. package/dist/list-query/index.d.ts.map +1 -1
  116. package/dist/list-query/index.js +5 -2
  117. package/dist/list-query/index.js.map +1 -1
  118. package/dist/list-query/parse-filter-values.d.ts +21 -0
  119. package/dist/list-query/parse-filter-values.d.ts.map +1 -0
  120. package/dist/list-query/parse-filter-values.js +177 -0
  121. package/dist/list-query/parse-filter-values.js.map +1 -0
  122. package/dist/list-query/parser.d.ts +3 -2
  123. package/dist/list-query/parser.d.ts.map +1 -1
  124. package/dist/list-query/parser.js.map +1 -1
  125. package/dist/list-query/prisma-builder.d.ts.map +1 -1
  126. package/dist/list-query/prisma-builder.js +3 -50
  127. package/dist/list-query/prisma-builder.js.map +1 -1
  128. package/dist/list-query/prisma-executor.d.ts +44 -29
  129. package/dist/list-query/prisma-executor.d.ts.map +1 -1
  130. package/dist/list-query/prisma-executor.js +48 -33
  131. package/dist/list-query/prisma-executor.js.map +1 -1
  132. package/dist/list-query/query-schema.d.ts +8 -13
  133. package/dist/list-query/query-schema.d.ts.map +1 -1
  134. package/dist/list-query/query-schema.js +11 -12
  135. package/dist/list-query/query-schema.js.map +1 -1
  136. package/dist/list-query/schema-helpers.d.ts +34 -31
  137. package/dist/list-query/schema-helpers.d.ts.map +1 -1
  138. package/dist/list-query/schema-helpers.js +47 -37
  139. package/dist/list-query/schema-helpers.js.map +1 -1
  140. package/dist/list-query/sort-mapping.d.ts +37 -0
  141. package/dist/list-query/sort-mapping.d.ts.map +1 -0
  142. package/dist/list-query/sort-mapping.js +88 -0
  143. package/dist/list-query/sort-mapping.js.map +1 -0
  144. package/dist/list-query/types.d.ts +3 -10
  145. package/dist/list-query/types.d.ts.map +1 -1
  146. package/dist/list-query/validator.d.ts.map +1 -1
  147. package/dist/list-query/validator.js +28 -10
  148. package/dist/list-query/validator.js.map +1 -1
  149. package/dist/observability/exception-tracking.d.ts.map +1 -1
  150. package/dist/observability/exception-tracking.js.map +1 -1
  151. package/dist/observability/index.d.ts +1 -1
  152. package/dist/observability/index.d.ts.map +1 -1
  153. package/dist/observability/index.js +1 -1
  154. package/dist/observability/index.js.map +1 -1
  155. package/dist/observability/pino-logger.d.ts +0 -28
  156. package/dist/observability/pino-logger.d.ts.map +1 -1
  157. package/dist/observability/pino-logger.js +21 -12
  158. package/dist/observability/pino-logger.js.map +1 -1
  159. package/dist/observability/request-context.d.ts +36 -1
  160. package/dist/observability/request-context.d.ts.map +1 -1
  161. package/dist/observability/request-context.js +43 -0
  162. package/dist/observability/request-context.js.map +1 -1
  163. package/dist/rls/configuration.d.ts +3 -0
  164. package/dist/rls/configuration.d.ts.map +1 -0
  165. package/dist/rls/configuration.js +13 -0
  166. package/dist/rls/configuration.js.map +1 -0
  167. package/dist/rls/context.d.ts +37 -0
  168. package/dist/rls/context.d.ts.map +1 -0
  169. package/dist/rls/context.js +56 -0
  170. package/dist/rls/context.js.map +1 -0
  171. package/dist/rls/extension.d.ts +7 -0
  172. package/dist/rls/extension.d.ts.map +1 -0
  173. package/dist/rls/extension.js +91 -0
  174. package/dist/rls/extension.js.map +1 -0
  175. package/dist/rls/generator.d.ts +17 -0
  176. package/dist/rls/generator.d.ts.map +1 -0
  177. package/dist/rls/generator.js +47 -0
  178. package/dist/rls/generator.js.map +1 -0
  179. package/dist/rls/index.d.ts +7 -0
  180. package/dist/rls/index.d.ts.map +1 -0
  181. package/dist/rls/index.js +7 -0
  182. package/dist/rls/index.js.map +1 -0
  183. package/dist/rls/middleware.d.ts +17 -0
  184. package/dist/rls/middleware.d.ts.map +1 -0
  185. package/dist/rls/middleware.js +51 -0
  186. package/dist/rls/middleware.js.map +1 -0
  187. package/dist/rls/testing.d.ts +24 -0
  188. package/dist/rls/testing.d.ts.map +1 -0
  189. package/dist/rls/testing.js +31 -0
  190. package/dist/rls/testing.js.map +1 -0
  191. package/dist/rls/types.d.ts +51 -0
  192. package/dist/rls/types.d.ts.map +1 -0
  193. package/dist/rls/types.js +16 -0
  194. package/dist/rls/types.js.map +1 -0
  195. package/dist/uploads/uploads.service.d.ts.map +1 -1
  196. package/dist/uploads/validators.d.ts.map +1 -1
  197. package/dist/utils/serialize-prisma-types.js.map +1 -1
  198. package/package.json +47 -34
@@ -0,0 +1,19 @@
1
+ import type { CloudWatchDashboardDefinition, GenerateJobsDashboardOptions, GetJobsInsightsQueriesOptions, JobsInsightsQueries } from './types.js';
2
+ /**
3
+ * Generate a production-ready AWS CloudWatch Dashboard JSON definition for background jobs.
4
+ *
5
+ * Can be deployed via AWS CLI (`aws cloudwatch put-dashboard`), AWS CDK (`CfnDashboard`),
6
+ * or Terraform (`aws_cloudwatch_dashboard`).
7
+ *
8
+ * @param options - Dashboard configuration options (names, widgets, region).
9
+ * @returns An object with dashboardName and serialized dashboardBody JSON.
10
+ */
11
+ export declare function generateJobsDashboard(options: GenerateJobsDashboardOptions): CloudWatchDashboardDefinition;
12
+ /**
13
+ * Returns a set of pre-canned CloudWatch Logs Insights queries for monitoring and troubleshooting jobs.
14
+ *
15
+ * @param options - Optional configuration for logGroupName and namespace filter.
16
+ * @returns Queries for recent failures, slowest jobs, retries, and job tracing.
17
+ */
18
+ export declare function getJobsInsightsQueries(options?: GetJobsInsightsQueriesOptions): JobsInsightsQueries;
19
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../../src/jobs/observability/dashboard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,6BAA6B,EAC7B,4BAA4B,EAC5B,6BAA6B,EAC7B,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,4BAA4B,GACpC,6BAA6B,CAqI/B;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,6BAAkC,GAC1C,mBAAmB,CAerB"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Generate a production-ready AWS CloudWatch Dashboard JSON definition for background jobs.
3
+ *
4
+ * Can be deployed via AWS CLI (`aws cloudwatch put-dashboard`), AWS CDK (`CfnDashboard`),
5
+ * or Terraform (`aws_cloudwatch_dashboard`).
6
+ *
7
+ * @param options - Dashboard configuration options (names, widgets, region).
8
+ * @returns An object with dashboardName and serialized dashboardBody JSON.
9
+ */
10
+ export function generateJobsDashboard(options) {
11
+ const { dashboardName, namespace = 'Glasswork/Jobs', jobNames = [], periodSeconds = 300, region = 'eu-west-1', logGroupName, } = options;
12
+ // Widget 1: Throughput (JobCount)
13
+ const throughputMetrics = jobNames.length > 0
14
+ ? jobNames.map((name) => [namespace, 'JobCount', 'JobName', name, { stat: 'Sum' }])
15
+ : [[namespace, 'JobCount', { stat: 'Sum' }]];
16
+ // Widget 2: Errors (JobErrorCount)
17
+ const errorMetrics = jobNames.length > 0
18
+ ? jobNames.map((name) => [
19
+ namespace,
20
+ 'JobErrorCount',
21
+ 'JobName',
22
+ name,
23
+ { stat: 'Sum', color: '#d62728' },
24
+ ])
25
+ : [[namespace, 'JobErrorCount', { stat: 'Sum', color: '#d62728' }]];
26
+ // Widget 3: Duration Percentiles
27
+ const durationMetrics = [
28
+ [namespace, 'JobDuration', { stat: 'p50', label: 'Duration p50' }],
29
+ [namespace, 'JobDuration', { stat: 'p90', label: 'Duration p90' }],
30
+ [namespace, 'JobDuration', { stat: 'p99', label: 'Duration p99' }],
31
+ ];
32
+ // Widget 4: Queue Wait Time
33
+ const queueWaitMetrics = [
34
+ [namespace, 'QueueWaitTime', { stat: 'Average', label: 'Avg Queue Wait' }],
35
+ [namespace, 'QueueWaitTime', { stat: 'Maximum', label: 'Max Queue Wait' }],
36
+ ];
37
+ // biome-ignore lint/suspicious/noExplicitAny: CloudWatch Dashboard JSON specification uses dynamic property arrays
38
+ const widgets = [
39
+ {
40
+ type: 'metric',
41
+ x: 0,
42
+ y: 0,
43
+ width: 12,
44
+ height: 6,
45
+ properties: {
46
+ metrics: throughputMetrics,
47
+ view: 'timeSeries',
48
+ stacked: true,
49
+ region,
50
+ title: 'Background Jobs - Throughput (JobCount)',
51
+ period: periodSeconds,
52
+ },
53
+ },
54
+ {
55
+ type: 'metric',
56
+ x: 12,
57
+ y: 0,
58
+ width: 12,
59
+ height: 6,
60
+ properties: {
61
+ metrics: errorMetrics,
62
+ view: 'timeSeries',
63
+ stacked: true,
64
+ region,
65
+ title: 'Background Jobs - Errors & Failures',
66
+ period: periodSeconds,
67
+ },
68
+ },
69
+ {
70
+ type: 'metric',
71
+ x: 0,
72
+ y: 6,
73
+ width: 12,
74
+ height: 6,
75
+ properties: {
76
+ metrics: durationMetrics,
77
+ view: 'timeSeries',
78
+ region,
79
+ title: 'Execution Duration (p50 / p90 / p99)',
80
+ period: periodSeconds,
81
+ yAxis: {
82
+ left: {
83
+ label: 'Milliseconds',
84
+ },
85
+ },
86
+ },
87
+ },
88
+ {
89
+ type: 'metric',
90
+ x: 12,
91
+ y: 6,
92
+ width: 12,
93
+ height: 6,
94
+ properties: {
95
+ metrics: queueWaitMetrics,
96
+ view: 'timeSeries',
97
+ region,
98
+ title: 'Queue Wait Time (Enqueued to Execution)',
99
+ period: periodSeconds,
100
+ yAxis: {
101
+ left: {
102
+ label: 'Milliseconds',
103
+ },
104
+ },
105
+ },
106
+ },
107
+ ];
108
+ if (logGroupName) {
109
+ widgets.push({
110
+ type: 'log',
111
+ x: 0,
112
+ y: 12,
113
+ width: 24,
114
+ height: 6,
115
+ properties: {
116
+ query: `SOURCE '${logGroupName}' | fields @timestamp, JobName, JobId, AttemptNumber, ErrorName, ErrorMessage\n| filter Status in ["failed", "dead_letter"]\n| sort @timestamp desc\n| limit 25`,
117
+ region,
118
+ title: 'Recent Job Failures & Dead Letters',
119
+ view: 'table',
120
+ },
121
+ });
122
+ }
123
+ return {
124
+ dashboardName,
125
+ dashboardBody: JSON.stringify({ widgets }),
126
+ };
127
+ }
128
+ /**
129
+ * Returns a set of pre-canned CloudWatch Logs Insights queries for monitoring and troubleshooting jobs.
130
+ *
131
+ * @param options - Optional configuration for logGroupName and namespace filter.
132
+ * @returns Queries for recent failures, slowest jobs, retries, and job tracing.
133
+ */
134
+ export function getJobsInsightsQueries(options = {}) {
135
+ const sourcePrefix = options.logGroupName ? `SOURCE '${options.logGroupName}' | ` : '';
136
+ return {
137
+ recentFailures: `${sourcePrefix}fields @timestamp, JobName, JobId, AttemptNumber, ErrorName, ErrorMessage\n| filter Status in ["failed", "dead_letter"]\n| sort @timestamp desc\n| limit 50`,
138
+ slowestJobs: `${sourcePrefix}fields @timestamp, JobName, JobId, JobDuration, QueueWaitTime\n| filter Status = "success"\n| sort JobDuration desc\n| limit 25`,
139
+ retriedJobs: `${sourcePrefix}fields @timestamp, JobName, JobId, AttemptNumber, Status, ErrorMessage\n| filter AttemptNumber > 1\n| sort @timestamp desc\n| limit 50`,
140
+ throughputHourly: `${sourcePrefix}filter ispresent(JobName)\n| stats count(*) as Total, sum(JobErrorCount) as Errors, avg(JobDuration) as AvgDurationMs by bin(1h), JobName`,
141
+ traceJob: (jobId) => `${sourcePrefix}fields @timestamp, JobName, Status, AttemptNumber, @message\n| filter JobId = "${jobId}"\n| sort @timestamp asc`,
142
+ };
143
+ }
144
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../../src/jobs/observability/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { EMFJobMetricRecord, JobExecutionMetricData, JobMetricsConfig } from './types.js';
2
+ /**
3
+ * Build a structured AWS CloudWatch Embedded Metric Format (EMF) record for a background job.
4
+ *
5
+ * Conforms to the AWS CloudWatch EMF specification:
6
+ * https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html
7
+ *
8
+ * @param data - Execution metrics for the completed or failed job.
9
+ * @param config - Optional configuration for namespace, dimensions, etc.
10
+ * @returns An object adhering to the EMF JSON schema.
11
+ */
12
+ export declare function createEMFJobMetric(data: JobExecutionMetricData, config?: JobMetricsConfig): EMFJobMetricRecord;
13
+ /**
14
+ * Emit an EMF metric to stdout or a configured sink.
15
+ *
16
+ * When emitted to stdout within an AWS Lambda environment, AWS CloudWatch Logs automatically
17
+ * extracts these metrics into CloudWatch Metrics with zero API overhead and zero latency.
18
+ *
19
+ * @param data - Execution metrics for the job.
20
+ * @param config - Optional configuration for namespace, dimensions, or custom sink.
21
+ * @returns The generated record or null if metrics are disabled.
22
+ */
23
+ export declare function emitJobMetric(data: JobExecutionMetricData, config?: JobMetricsConfig): EMFJobMetricRecord | null;
24
+ //# sourceMappingURL=emf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emf.d.ts","sourceRoot":"","sources":["../../../src/jobs/observability/emf.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE/F;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,sBAAsB,EAC5B,MAAM,CAAC,EAAE,gBAAgB,GACxB,kBAAkB,CAyEpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,sBAAsB,EAC5B,MAAM,CAAC,EAAE,gBAAgB,GACxB,kBAAkB,GAAG,IAAI,CAgB3B"}
@@ -0,0 +1,100 @@
1
+ import { isTest } from '../../utils/environment.js';
2
+ /**
3
+ * Build a structured AWS CloudWatch Embedded Metric Format (EMF) record for a background job.
4
+ *
5
+ * Conforms to the AWS CloudWatch EMF specification:
6
+ * https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Specification.html
7
+ *
8
+ * @param data - Execution metrics for the completed or failed job.
9
+ * @param config - Optional configuration for namespace, dimensions, etc.
10
+ * @returns An object adhering to the EMF JSON schema.
11
+ */
12
+ export function createEMFJobMetric(data, config) {
13
+ const namespace = config?.namespace ?? 'Glasswork/Jobs';
14
+ const customDimensions = {
15
+ ...(config?.dimensions ?? {}),
16
+ ...(data.customDimensions ?? {}),
17
+ };
18
+ const customDimensionKeys = Object.keys(customDimensions);
19
+ // Standard dimension sets:
20
+ // 1. [JobName]
21
+ // 2. [JobName, Status]
22
+ // 3. [Status]
23
+ // If custom dimensions exist, they are appended to each dimension set for granular filtering.
24
+ const baseDimensionSets = [['JobName'], ['JobName', 'Status'], ['Status']];
25
+ const dimensionSets = customDimensionKeys.length > 0
26
+ ? baseDimensionSets.map((set) => [...set, ...customDimensionKeys])
27
+ : baseDimensionSets;
28
+ const queueWaitTime = data.enqueuedAt
29
+ ? Math.max(0, data.startedAt.getTime() - data.enqueuedAt.getTime())
30
+ : undefined;
31
+ const retryCount = Math.max(0, data.attemptNumber - 1);
32
+ const isError = data.status !== 'success';
33
+ const metrics = [
34
+ { Name: 'JobCount', Unit: 'Count' },
35
+ { Name: 'JobDuration', Unit: 'Milliseconds' },
36
+ { Name: 'JobErrorCount', Unit: 'Count' },
37
+ { Name: 'RetryCount', Unit: 'Count' },
38
+ ];
39
+ if (queueWaitTime !== undefined) {
40
+ metrics.push({ Name: 'QueueWaitTime', Unit: 'Milliseconds' });
41
+ }
42
+ const record = {
43
+ _aws: {
44
+ Timestamp: Date.now(),
45
+ CloudWatchMetrics: [
46
+ {
47
+ Namespace: namespace,
48
+ Dimensions: dimensionSets,
49
+ Metrics: metrics,
50
+ },
51
+ ],
52
+ },
53
+ JobName: data.jobName,
54
+ Status: data.status,
55
+ JobId: data.jobId,
56
+ AttemptNumber: data.attemptNumber,
57
+ JobCount: 1,
58
+ JobDuration: data.durationMs,
59
+ JobErrorCount: isError ? 1 : 0,
60
+ RetryCount: retryCount,
61
+ ...customDimensions,
62
+ };
63
+ if (queueWaitTime !== undefined) {
64
+ record.QueueWaitTime = queueWaitTime;
65
+ }
66
+ if (data.error) {
67
+ record.ErrorName = data.error.name || 'Error';
68
+ record.ErrorMessage = data.error.message;
69
+ if (data.error.stack) {
70
+ record.ErrorStack = data.error.stack;
71
+ }
72
+ }
73
+ return record;
74
+ }
75
+ /**
76
+ * Emit an EMF metric to stdout or a configured sink.
77
+ *
78
+ * When emitted to stdout within an AWS Lambda environment, AWS CloudWatch Logs automatically
79
+ * extracts these metrics into CloudWatch Metrics with zero API overhead and zero latency.
80
+ *
81
+ * @param data - Execution metrics for the job.
82
+ * @param config - Optional configuration for namespace, dimensions, or custom sink.
83
+ * @returns The generated record or null if metrics are disabled.
84
+ */
85
+ export function emitJobMetric(data, config) {
86
+ const isEnabled = config?.enabled ?? (config?.sink !== undefined || !isTest());
87
+ if (!isEnabled) {
88
+ return null;
89
+ }
90
+ const record = createEMFJobMetric(data, config);
91
+ const json = JSON.stringify(record);
92
+ if (config?.sink) {
93
+ config.sink(json);
94
+ }
95
+ else {
96
+ console.log(json);
97
+ }
98
+ return record;
99
+ }
100
+ //# sourceMappingURL=emf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emf.js","sourceRoot":"","sources":["../../../src/jobs/observability/emf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { createJobsObservabilityClient, type JobsObservabilityClient, } from './client.js';
2
+ export { generateJobsDashboard, getJobsInsightsQueries, } from './dashboard.js';
3
+ export { createEMFJobMetric, emitJobMetric, } from './emf.js';
4
+ export type { CloudWatchDashboardDefinition, EMFJobMetricRecord, EMFMetadata, EMFMetricUnit, FailedJobDTO, GenerateJobsDashboardOptions, GetFailedJobsOptions, GetJobSummaryOptions, GetJobsInsightsQueriesOptions, JobExecutionMetricData, JobExecutionStatus, JobMetricsConfig, JobStatsSummaryDTO, JobsInsightsQueries, JobsObservabilityClientOptions, JobTypeStatsDTO, } from './types.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/jobs/observability/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,6BAA6B,EAC7B,kBAAkB,EAClB,WAAW,EACX,aAAa,EACb,YAAY,EACZ,4BAA4B,EAC5B,oBAAoB,EACpB,oBAAoB,EACpB,6BAA6B,EAC7B,sBAAsB,EACtB,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,8BAA8B,EAC9B,eAAe,GAChB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { createJobsObservabilityClient, } from './client.js';
2
+ export { generateJobsDashboard, getJobsInsightsQueries, } from './dashboard.js';
3
+ export { createEMFJobMetric, emitJobMetric, } from './emf.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/jobs/observability/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,GAE9B,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,kBAAkB,EAClB,aAAa,GACd,MAAM,UAAU,CAAC"}
@@ -0,0 +1,234 @@
1
+ /**
2
+ * Lifecycle status of a background job execution for observability metrics.
3
+ */
4
+ export type JobExecutionStatus = 'success' | 'failed' | 'retry' | 'dead_letter';
5
+ /**
6
+ * Metric units supported by AWS CloudWatch EMF.
7
+ */
8
+ export type EMFMetricUnit = 'Count' | 'Milliseconds' | 'Bytes' | 'Seconds' | 'None';
9
+ /**
10
+ * AWS CloudWatch Embedded Metric Format (EMF) metadata definition.
11
+ */
12
+ export interface EMFMetadata {
13
+ Timestamp: number;
14
+ CloudWatchMetrics: Array<{
15
+ Namespace: string;
16
+ Dimensions: string[][];
17
+ Metrics: Array<{
18
+ Name: string;
19
+ Unit: EMFMetricUnit;
20
+ }>;
21
+ }>;
22
+ }
23
+ /**
24
+ * Complete EMF JSON record structure emitted to stdout.
25
+ */
26
+ export interface EMFJobMetricRecord {
27
+ _aws: EMFMetadata;
28
+ JobName: string;
29
+ Status: JobExecutionStatus;
30
+ JobId: string;
31
+ AttemptNumber: number;
32
+ JobCount: number;
33
+ JobDuration: number;
34
+ JobErrorCount: number;
35
+ QueueWaitTime?: number;
36
+ RetryCount: number;
37
+ ErrorName?: string;
38
+ ErrorMessage?: string;
39
+ ErrorStack?: string;
40
+ [key: string]: unknown;
41
+ }
42
+ /**
43
+ * Input data provided to create an EMF metric record.
44
+ */
45
+ export interface JobExecutionMetricData {
46
+ jobName: string;
47
+ jobId: string;
48
+ status: JobExecutionStatus;
49
+ attemptNumber: number;
50
+ durationMs: number;
51
+ enqueuedAt?: Date;
52
+ startedAt: Date;
53
+ error?: Error;
54
+ customDimensions?: Record<string, string>;
55
+ }
56
+ /**
57
+ * Configuration for worker EMF metric emission.
58
+ */
59
+ export interface JobMetricsConfig {
60
+ /**
61
+ * Whether EMF metric logging is enabled.
62
+ * Defaults to true if not in test environment.
63
+ */
64
+ enabled?: boolean;
65
+ /**
66
+ * CloudWatch metrics namespace.
67
+ * @default 'Glasswork/Jobs'
68
+ */
69
+ namespace?: string;
70
+ /**
71
+ * Additional global dimensions to attach to all job metrics (e.g. environment: 'production').
72
+ */
73
+ dimensions?: Record<string, string>;
74
+ /**
75
+ * Custom output sink for EMF formatted JSON strings.
76
+ * Defaults to process.stdout.write / console.log.
77
+ */
78
+ sink?: (logLine: string) => void;
79
+ }
80
+ /**
81
+ * Performance and throughput statistics for a specific job type.
82
+ */
83
+ export interface JobTypeStatsDTO {
84
+ jobName: string;
85
+ count: number;
86
+ succeededCount: number;
87
+ failedCount: number;
88
+ retryCount: number;
89
+ avgDurationMs: number;
90
+ p95DurationMs: number;
91
+ }
92
+ /**
93
+ * Aggregated summary DTO of background jobs across a given time window.
94
+ */
95
+ export interface JobStatsSummaryDTO {
96
+ totalExecuted: number;
97
+ totalSucceeded: number;
98
+ totalFailed: number;
99
+ totalRetried: number;
100
+ /** Success percentage between 0 and 100, rounded to 2 decimals */
101
+ successRate: number;
102
+ avgDurationMs: number;
103
+ p95DurationMs: number;
104
+ byJob: Record<string, JobTypeStatsDTO>;
105
+ }
106
+ /**
107
+ * Details of a failed background job execution.
108
+ */
109
+ export interface FailedJobDTO {
110
+ jobId: string;
111
+ jobName: string;
112
+ attemptNumber: number;
113
+ errorMessage: string;
114
+ errorName?: string;
115
+ errorStack?: string;
116
+ failedAt: Date;
117
+ durationMs?: number;
118
+ queueWaitTimeMs?: number;
119
+ }
120
+ /**
121
+ * Options for generating a CloudWatch Dashboard.
122
+ */
123
+ export interface GenerateJobsDashboardOptions {
124
+ /**
125
+ * Dashboard name in AWS CloudWatch.
126
+ */
127
+ dashboardName: string;
128
+ /**
129
+ * Metric namespace.
130
+ * @default 'Glasswork/Jobs'
131
+ */
132
+ namespace?: string;
133
+ /**
134
+ * Known job names to generate dedicated graphs and widgets for.
135
+ */
136
+ jobNames?: string[];
137
+ /**
138
+ * Aggregation period in seconds for CloudWatch widgets.
139
+ * @default 300 (5 minutes)
140
+ */
141
+ periodSeconds?: number;
142
+ /**
143
+ * AWS Region for CloudWatch widgets.
144
+ * @default 'eu-west-1'
145
+ */
146
+ region?: string;
147
+ /**
148
+ * CloudWatch Log Group name where worker logs are stored.
149
+ * If provided, an embedded CloudWatch Logs Insights widget will be added.
150
+ */
151
+ logGroupName?: string;
152
+ }
153
+ /**
154
+ * CloudWatch Dashboard JSON definition compatible with AWS API / CLI / CDK / Terraform.
155
+ */
156
+ export interface CloudWatchDashboardDefinition {
157
+ dashboardName: string;
158
+ dashboardBody: string;
159
+ }
160
+ /**
161
+ * Options for generating CloudWatch Logs Insights queries.
162
+ */
163
+ export interface GetJobsInsightsQueriesOptions {
164
+ /**
165
+ * Target log group name.
166
+ */
167
+ logGroupName?: string;
168
+ /**
169
+ * Custom namespace if filtered in logs.
170
+ * @default 'Glasswork/Jobs'
171
+ */
172
+ namespace?: string;
173
+ }
174
+ /**
175
+ * Collection of pre-canned CloudWatch Logs Insights queries.
176
+ */
177
+ export interface JobsInsightsQueries {
178
+ /** Query returning recent failed and dead-letter jobs with error messages */
179
+ recentFailures: string;
180
+ /** Query finding the slowest job executions */
181
+ slowestJobs: string;
182
+ /** Query finding jobs that required retries */
183
+ retriedJobs: string;
184
+ /** Hourly job volume and error aggregation */
185
+ throughputHourly: string;
186
+ /** Function returning a query to trace a single jobId */
187
+ traceJob: (jobId: string) => string;
188
+ }
189
+ /**
190
+ * Options for initializing the JobsObservabilityClient.
191
+ */
192
+ export interface JobsObservabilityClientOptions {
193
+ /**
194
+ * CloudWatch metric namespace.
195
+ * @default 'Glasswork/Jobs'
196
+ */
197
+ namespace?: string;
198
+ /**
199
+ * CloudWatch Log Group name for worker execution logs.
200
+ */
201
+ logGroupName?: string;
202
+ /**
203
+ * AWS Region.
204
+ */
205
+ region?: string;
206
+ /**
207
+ * Pre-configured CloudWatch client (avoids loading AWS SDK if injected).
208
+ */
209
+ cloudWatchClient?: unknown;
210
+ /**
211
+ * Pre-configured CloudWatch Logs client (avoids loading AWS SDK if injected).
212
+ */
213
+ cloudWatchLogsClient?: unknown;
214
+ }
215
+ /**
216
+ * Query options for job summaries.
217
+ */
218
+ export interface GetJobSummaryOptions {
219
+ startTime?: Date;
220
+ endTime?: Date;
221
+ jobNames?: string[];
222
+ /** Relative hours if startTime/endTime are omitted */
223
+ hours?: number;
224
+ }
225
+ /**
226
+ * Query options for fetching failed jobs.
227
+ */
228
+ export interface GetFailedJobsOptions {
229
+ startTime?: Date;
230
+ endTime?: Date;
231
+ limit?: number;
232
+ jobName?: string;
233
+ }
234
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/jobs/observability/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/jobs/observability/types.ts"],"names":[],"mappings":""}
@@ -28,8 +28,8 @@ export declare function bootstrapWorker(config: WorkerConfig): (event: SQSEvent
28
28
  batchItemFailures: import("aws-lambda").SQSBatchItemFailure[];
29
29
  success?: undefined;
30
30
  } | {
31
- success: boolean;
32
31
  batchItemFailures?: undefined;
32
+ success: boolean;
33
33
  }>;
34
34
  export {};
35
35
  //# sourceMappingURL=worker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/jobs/worker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAoB,QAAQ,EAAa,MAAM,YAAY,CAAC;AAQnG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAQ/D,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAmB1D,UAAU,WAAW;IACnB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9E,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACjF,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7F,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAClG;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,IAAI,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AASD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,IAKhD,OAAO,QAAQ,GAAG,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7E,MAAM,OAAO;;;;;;GA8ChB"}
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../../src/jobs/worker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,gBAAgB,EAAoB,QAAQ,EAAa,MAAM,YAAY,CAAC;AAQnG,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAQ/D,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAmB1D,UAAU,WAAW;IACnB,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC9E,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACjF,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC7F,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAClG;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,IAAI,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AASD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,WAKzC,QAAQ,GAAG,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,QACvE,OAAO;;;;;;GA8ChB"}
@@ -1,6 +1,9 @@
1
1
  import type { Context } from 'hono';
2
2
  import type { BaseIssue, BaseSchema, InferOutput } from 'valibot';
3
- import type { AggregationConfig, AggregationResult, RawQueryParams, SearchFieldInput } from './types.js';
3
+ import { type FilterMappings } from './filter-mapping.js';
4
+ import type { ListQueryParams } from './query-schema.js';
5
+ import { type SortMappings } from './sort-mapping.js';
6
+ import type { AggregationConfig, AggregationResult, SearchFieldInput } from './types.js';
4
7
  import { permissiveOrderByEntrySchema, unrestrictedWhereSchema } from './unrestricted-schemas.js';
5
8
  import type { SchemaValidationConfig, ValidatedListParams } from './validator.js';
6
9
  export interface PaginatedResult<T> {
@@ -15,6 +18,10 @@ export interface ListQueryConfig<TWhereSchema extends BaseSchema<unknown, unknow
15
18
  readonly aggregations?: Record<string, AggregationConfig>;
16
19
  /** Applied when the request has no `sorts` query parameter. */
17
20
  readonly defaultOrderBy?: readonly InferOutput<TOrderBySchema>[];
21
+ /** Virtual filter mappers to transform custom filters to database conditions. */
22
+ readonly mapFilters?: FilterMappings;
23
+ /** Sorter mappings to transform public sort fields to database/relation paths. */
24
+ readonly mapSorts?: SortMappings;
18
25
  }
19
26
  export declare class ListQueryBuilder<TWhereSchema extends BaseSchema<unknown, unknown, BaseIssue<unknown>>, TOrderBySchema extends BaseSchema<unknown, unknown, BaseIssue<unknown>>, TParams extends ValidatedListParams<TWhereSchema, TOrderBySchema> = ValidatedListParams<TWhereSchema, TOrderBySchema>> {
20
27
  private config;
@@ -26,7 +33,7 @@ export declare class ListQueryBuilder<TWhereSchema extends BaseSchema<unknown, u
26
33
  private whereConditions;
27
34
  private transformFn?;
28
35
  constructor(config: ListQueryConfig<TWhereSchema, TOrderBySchema>, validationConfig?: SchemaValidationConfig<TWhereSchema, TOrderBySchema> | undefined);
29
- parse(query: RawQueryParams, context?: Context): this;
36
+ parse(query: ListQueryParams, context?: Context): this;
30
37
  scope(conditions: InferOutput<TWhereSchema> | Record<string, unknown>): this;
31
38
  paginate(): this;
32
39
  /**
@@ -36,6 +43,7 @@ export declare class ListQueryBuilder<TWhereSchema extends BaseSchema<unknown, u
36
43
  disablePagination(): this;
37
44
  transform<TNext extends ValidatedListParams<TWhereSchema, TOrderBySchema>>(fn: (params: ValidatedListParams<TWhereSchema, TOrderBySchema>) => TNext): ListQueryBuilder<TWhereSchema, TOrderBySchema, TNext>;
38
45
  build(): TParams;
46
+ private resolveProcessedOrderBy;
39
47
  private buildAggregationParams;
40
48
  private removeFieldFromWhere;
41
49
  private processLogicalArray;
@@ -62,6 +70,7 @@ export declare function createListQuery<const TConfig extends {
62
70
  readonly search?: readonly SearchFieldInput[];
63
71
  readonly aggregations?: Record<string, AggregationConfig>;
64
72
  readonly defaultOrderBy?: readonly unknown[];
73
+ readonly mapFilters?: FilterMappings;
65
74
  } & ({
66
75
  readonly filter: AnySchema;
67
76
  } | {