@grepr/cli 1.1.4 → 1.3.0-94fe60c

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 (108) hide show
  1. package/build/dist/commands/base-command.d.ts +3 -3
  2. package/build/dist/commands/base-command.d.ts.map +1 -1
  3. package/build/dist/commands/base-command.js +1 -7
  4. package/build/dist/commands/base-command.js.map +1 -1
  5. package/build/dist/commands/config-command.d.ts +5 -9
  6. package/build/dist/commands/config-command.d.ts.map +1 -1
  7. package/build/dist/commands/config-command.js +32 -4
  8. package/build/dist/commands/config-command.js.map +1 -1
  9. package/build/dist/commands/crud-command.d.ts +11 -18
  10. package/build/dist/commands/crud-command.d.ts.map +1 -1
  11. package/build/dist/commands/crud-command.js +27 -11
  12. package/build/dist/commands/crud-command.js.map +1 -1
  13. package/build/dist/commands/dataset-command.d.ts +8 -13
  14. package/build/dist/commands/dataset-command.d.ts.map +1 -1
  15. package/build/dist/commands/dataset-command.js.map +1 -1
  16. package/build/dist/commands/docs-command.d.ts +87 -0
  17. package/build/dist/commands/docs-command.d.ts.map +1 -0
  18. package/build/dist/commands/docs-command.js +164 -0
  19. package/build/dist/commands/docs-command.js.map +1 -0
  20. package/build/dist/commands/docs-get-command.d.ts +53 -0
  21. package/build/dist/commands/docs-get-command.d.ts.map +1 -0
  22. package/build/dist/commands/docs-get-command.js +75 -0
  23. package/build/dist/commands/docs-get-command.js.map +1 -0
  24. package/build/dist/commands/grok-command.d.ts +71 -0
  25. package/build/dist/commands/grok-command.d.ts.map +1 -0
  26. package/build/dist/commands/grok-command.js +258 -0
  27. package/build/dist/commands/grok-command.js.map +1 -0
  28. package/build/dist/commands/integration-command.d.ts +5 -7
  29. package/build/dist/commands/integration-command.d.ts.map +1 -1
  30. package/build/dist/commands/integration-command.js +4 -4
  31. package/build/dist/commands/integration-command.js.map +1 -1
  32. package/build/dist/commands/job-command.d.ts +7 -43
  33. package/build/dist/commands/job-command.d.ts.map +1 -1
  34. package/build/dist/commands/job-command.js +5 -3
  35. package/build/dist/commands/job-command.js.map +1 -1
  36. package/build/dist/commands/job-to-test-command.d.ts +74 -0
  37. package/build/dist/commands/job-to-test-command.d.ts.map +1 -0
  38. package/build/dist/commands/job-to-test-command.js +159 -0
  39. package/build/dist/commands/job-to-test-command.js.map +1 -0
  40. package/build/dist/commands/list-command.d.ts +5 -7
  41. package/build/dist/commands/list-command.d.ts.map +1 -1
  42. package/build/dist/commands/list-command.js +20 -4
  43. package/build/dist/commands/list-command.js.map +1 -1
  44. package/build/dist/commands/query-command.d.ts +3 -8
  45. package/build/dist/commands/query-command.d.ts.map +1 -1
  46. package/build/dist/commands/query-command.js +34 -14
  47. package/build/dist/commands/query-command.js.map +1 -1
  48. package/build/dist/docs-index/catalog.json +1 -0
  49. package/build/dist/docs-index/index.json +1 -0
  50. package/build/dist/grepr.js +43 -7
  51. package/build/dist/grepr.js.map +1 -1
  52. package/build/dist/lib/api-client-factory.d.ts +2 -2
  53. package/build/dist/lib/api-client-factory.d.ts.map +1 -1
  54. package/build/dist/lib/api-client-factory.js +1 -1
  55. package/build/dist/lib/api-client-factory.js.map +1 -1
  56. package/build/dist/lib/auth.d.ts +17 -9
  57. package/build/dist/lib/auth.d.ts.map +1 -1
  58. package/build/dist/lib/auth.js +53 -14
  59. package/build/dist/lib/auth.js.map +1 -1
  60. package/build/dist/lib/command-registry.d.ts +3 -2
  61. package/build/dist/lib/command-registry.d.ts.map +1 -1
  62. package/build/dist/lib/command-registry.js.map +1 -1
  63. package/build/dist/lib/config.d.ts +15 -0
  64. package/build/dist/lib/config.d.ts.map +1 -1
  65. package/build/dist/lib/config.js +45 -11
  66. package/build/dist/lib/config.js.map +1 -1
  67. package/build/dist/lib/docs-search.d.ts +154 -0
  68. package/build/dist/lib/docs-search.d.ts.map +1 -0
  69. package/build/dist/lib/docs-search.js +208 -0
  70. package/build/dist/lib/docs-search.js.map +1 -0
  71. package/build/dist/lib/grepr-api-client.d.ts +33 -193
  72. package/build/dist/lib/grepr-api-client.d.ts.map +1 -1
  73. package/build/dist/lib/grepr-api-client.js +58 -38
  74. package/build/dist/lib/grepr-api-client.js.map +1 -1
  75. package/build/dist/lib/job-graph-transformer.d.ts +89 -0
  76. package/build/dist/lib/job-graph-transformer.d.ts.map +1 -0
  77. package/build/dist/lib/job-graph-transformer.js +497 -0
  78. package/build/dist/lib/job-graph-transformer.js.map +1 -0
  79. package/build/dist/lib/job-graph-utils.d.ts +50 -0
  80. package/build/dist/lib/job-graph-utils.d.ts.map +1 -0
  81. package/build/dist/lib/job-graph-utils.js +84 -0
  82. package/build/dist/lib/job-graph-utils.js.map +1 -0
  83. package/build/dist/lib/json-formatter.d.ts +1 -0
  84. package/build/dist/lib/json-formatter.d.ts.map +1 -1
  85. package/build/dist/lib/json-formatter.js +28 -16
  86. package/build/dist/lib/json-formatter.js.map +1 -1
  87. package/build/dist/lib/parser.d.ts.map +1 -1
  88. package/build/dist/lib/parser.js +3 -6
  89. package/build/dist/lib/parser.js.map +1 -1
  90. package/build/dist/lib/streaming-job-executor.d.ts +3 -3
  91. package/build/dist/lib/streaming-job-executor.d.ts.map +1 -1
  92. package/build/dist/lib/streaming-job-executor.js +54 -21
  93. package/build/dist/lib/streaming-job-executor.js.map +1 -1
  94. package/build/dist/lib/time-utils.js +1 -1
  95. package/build/dist/lib/time-utils.js.map +1 -1
  96. package/build/dist/lib/transformers-embeddings.d.ts +76 -0
  97. package/build/dist/lib/transformers-embeddings.d.ts.map +1 -0
  98. package/build/dist/lib/transformers-embeddings.js +109 -0
  99. package/build/dist/lib/transformers-embeddings.js.map +1 -0
  100. package/build/dist/openapi/openApiTypes.d.ts +3967 -2240
  101. package/build/dist/openapi/openApiTypes.d.ts.map +1 -1
  102. package/build/dist/openapi/openApiTypes.js +341 -85
  103. package/build/dist/openapi/openApiTypes.js.map +1 -1
  104. package/build/dist/types.d.ts +48 -78
  105. package/build/dist/types.d.ts.map +1 -1
  106. package/build/dist/types.js +73 -0
  107. package/build/dist/types.js.map +1 -1
  108. package/package.json +41 -11
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Job graph transformation utilities for converting production jobs to test configurations.
3
+ *
4
+ * This module provides functions to transform a production job definition into a test job
5
+ * by replacing sources, sinks, and adding test-specific tagging. The transformations are
6
+ * purely functional - they do not make any API calls or create resources.
7
+ *
8
+ * Key transformations:
9
+ * - Source replacement: Replace vendor sources with dataset queries or keep originals with limits
10
+ * - Sink replacement: Replace vendor sinks with synchronous test sinks or test dataset sinks
11
+ * - Test tagging: Add test run ID and sink name tags to track test data
12
+ *
13
+ * The transformed job can then be executed using the standard job:create command.
14
+ */
15
+ import { JobExecution, JobProcessing } from '../types.js';
16
+ import { SchemaCreateJob } from '../openapi/openApiTypes.js';
17
+ /**
18
+ * Options for transforming a job to a test configuration.
19
+ */
20
+ export interface JobToTestOptions {
21
+ /** Target execution type (default: keep original) */
22
+ execution?: JobExecution;
23
+ /** Target processing type (default: keep original) */
24
+ processing?: JobProcessing;
25
+ /** Path to sample data file (not yet implemented) */
26
+ sampleDataFile?: string;
27
+ /** Dataset ID to use as data source (requires start and end) */
28
+ datasetId?: string;
29
+ /** Query to filter dataset source data (optional, requires datasetId) */
30
+ query?: string;
31
+ /** Start time for dataset query (ISO 8601 format) */
32
+ start?: string;
33
+ /** End time for dataset query (ISO 8601 format) */
34
+ end?: string;
35
+ /** Record limit for batch sources (default: 1000) */
36
+ limitRecords?: number;
37
+ /** Dataset ID for async test output (enables tagging) */
38
+ testDataset?: string;
39
+ /** Custom test run identifier (default: auto-generated) */
40
+ testTag?: string;
41
+ /** Custom test job name (default: {original}_test) */
42
+ testName?: string;
43
+ }
44
+ /**
45
+ * Transforms a production job configuration into a test job configuration.
46
+ *
47
+ * This is the main entry point for job transformation. It applies the following changes:
48
+ * 1. Renames the job (appends "_test" or uses custom name)
49
+ * 2. Updates execution and processing types if specified
50
+ * 3. Adds test run ID tag to job tags
51
+ * 4. Transforms sources (replace with dataset query, sample data, or add limits)
52
+ * 5. Transforms sinks (replace with sync sink or test dataset sinks)
53
+ * 6. Adds test tagging operations before sinks
54
+ *
55
+ * The transformation is purely functional and does not make any API calls.
56
+ *
57
+ * @param originalJob - The production job to transform
58
+ * @param options - Transformation options
59
+ * @returns A new job configuration suitable for testing
60
+ * @throws Error if job graph is missing or invalid
61
+ *
62
+ * @example
63
+ * const testJob = transformJobToTest(prodJob, {
64
+ * execution: 'SYNCHRONOUS',
65
+ * processing: 'BATCH',
66
+ * datasetId: 'my_dataset',
67
+ * start: '2025-01-01T00:00:00Z',
68
+ * end: '2025-01-01T01:00:00Z',
69
+ * limitRecords: 100
70
+ * });
71
+ */
72
+ export declare function transformJobToTest(originalJob: SchemaCreateJob, options: JobToTestOptions): SchemaCreateJob;
73
+ /**
74
+ * Displays a summary of the transformations applied to a job.
75
+ *
76
+ * This shows a before/after comparison including:
77
+ * - Job name changes
78
+ * - Execution type changes
79
+ * - Processing type changes
80
+ * - operation and edge changes
81
+ * - Test run ID
82
+ *
83
+ * The output is formatted for console display.
84
+ *
85
+ * @param originalJob - The original production job
86
+ * @param transformedJob - The transformed test job
87
+ */
88
+ export declare function showDiff(originalJob: SchemaCreateJob, transformedJob: SchemaCreateJob): void;
89
+ //# sourceMappingURL=job-graph-transformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-graph-transformer.d.ts","sourceRoot":"","sources":["../../../src/main/typescript/lib/job-graph-transformer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAiC,YAAY,EAAE,aAAa,EAAyB,MAAM,aAAa,CAAC;AAChH,OAAO,EAGL,eAAe,EAWhB,MAAM,wBAAwB,CAAC;AAQhC;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,qDAAqD;IACrD,SAAS,CAAC,EAAE,YAAY,CAAC;IAEzB,sDAAsD;IACtD,UAAU,CAAC,EAAE,aAAa,CAAC;IAE3B,qDAAqD;IACrD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,sDAAsD;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,eAAe,EAC5B,OAAO,EAAE,gBAAgB,GACxB,eAAe,CAwDjB;AA+YD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CACtB,WAAW,EAAE,eAAe,EAC5B,cAAc,EAAE,eAAe,GAC9B,IAAI,CA4EN"}
@@ -0,0 +1,497 @@
1
+ /**
2
+ * Job graph transformation utilities for converting production jobs to test configurations.
3
+ *
4
+ * This module provides functions to transform a production job definition into a test job
5
+ * by replacing sources, sinks, and adding test-specific tagging. The transformations are
6
+ * purely functional - they do not make any API calls or create resources.
7
+ *
8
+ * Key transformations:
9
+ * - Source replacement: Replace vendor sources with dataset queries or keep originals with limits
10
+ * - Sink replacement: Replace vendor sinks with synchronous test sinks or test dataset sinks
11
+ * - Test tagging: Add test run ID and sink name tags to track test data
12
+ *
13
+ * The transformed job can then be executed using the standard job:create command.
14
+ */
15
+ import { DEFAULT_INPUT, DEFAULT_OUTPUT, JobExecution, JobProcessing, Vertex, DEFAULT_LIMIT } from '../types.js';
16
+ import { LogsIcebergTableSourceType, LogsSynchronousSinkType, LogsIcebergTableSinkType, LogTransformActionType, DatadogQueryPredicateType, TagActionModification, TagActionType, LogsValuesSourceType } from '../openapi/openApiTypes.js';
17
+ import { canLimit, parseEdge, generateUUID } from './job-graph-utils.js';
18
+ import * as fs from 'fs-extra';
19
+ /**
20
+ * Transforms a production job configuration into a test job configuration.
21
+ *
22
+ * This is the main entry point for job transformation. It applies the following changes:
23
+ * 1. Renames the job (appends "_test" or uses custom name)
24
+ * 2. Updates execution and processing types if specified
25
+ * 3. Adds test run ID tag to job tags
26
+ * 4. Transforms sources (replace with dataset query, sample data, or add limits)
27
+ * 5. Transforms sinks (replace with sync sink or test dataset sinks)
28
+ * 6. Adds test tagging operations before sinks
29
+ *
30
+ * The transformation is purely functional and does not make any API calls.
31
+ *
32
+ * @param originalJob - The production job to transform
33
+ * @param options - Transformation options
34
+ * @returns A new job configuration suitable for testing
35
+ * @throws Error if job graph is missing or invalid
36
+ *
37
+ * @example
38
+ * const testJob = transformJobToTest(prodJob, {
39
+ * execution: 'SYNCHRONOUS',
40
+ * processing: 'BATCH',
41
+ * datasetId: 'my_dataset',
42
+ * start: '2025-01-01T00:00:00Z',
43
+ * end: '2025-01-01T01:00:00Z',
44
+ * limitRecords: 100
45
+ * });
46
+ */
47
+ export function transformJobToTest(originalJob, options) {
48
+ const job = { ...originalJob };
49
+ // Determine target execution and processing types (use options or keep original)
50
+ const targetExecution = options.execution || job.execution;
51
+ const targetProcessing = options.processing || job.processing;
52
+ // Create base transformed job with updated metadata
53
+ const transformedJob = {
54
+ ...job,
55
+ name: options.testName || `${job.name}_test`,
56
+ execution: targetExecution,
57
+ processing: targetProcessing,
58
+ tags: {
59
+ ...(job.tags || {}),
60
+ 'grepr.test_run_id': options.testTag || generateUUID()
61
+ }
62
+ };
63
+ if (!transformedJob.jobGraph) {
64
+ throw new Error('Job graph is required');
65
+ }
66
+ const parsedGraph = parseGraph(transformedJob.jobGraph);
67
+ // Step 1: Add test tagging operations on all edges BEFORE transforming sources/sinks
68
+ // This captures the original source/sink names in the edge tags
69
+ addTestTagging(parsedGraph, transformedJob.tags?.['grepr.test_run_id'] || generateUUID());
70
+ // Step 2: Transform sources (replace with dataset, sample data, or add limits)
71
+ transformSources(parsedGraph, targetProcessing, options);
72
+ // Step 3: Transform sinks (replace with sync sink or test dataset sinks)
73
+ transformSinks(parsedGraph, targetExecution, options);
74
+ // Convert the parsed/modified graph back to SchemaGreprJobGraph format
75
+ const transformedVertices = [];
76
+ const transformedEdges = [];
77
+ for (const vertex of parsedGraph.values()) {
78
+ transformedVertices.push(vertex.operation);
79
+ for (const [outputPort, nextIos] of vertex.next) {
80
+ for (const nextIo of nextIos) {
81
+ const edgeStr = `${vertex.name}:${outputPort} -> ${nextIo.vertex.name}:${nextIo.name}`;
82
+ transformedEdges.push(edgeStr);
83
+ }
84
+ }
85
+ }
86
+ transformedJob.jobGraph = {
87
+ vertices: transformedVertices,
88
+ edges: transformedEdges
89
+ };
90
+ return transformedJob;
91
+ }
92
+ /**
93
+ * Parses the job graph into a vertex-based representation, returning all vertices.
94
+ */
95
+ function parseGraph(jobGraph) {
96
+ const verticesMap = new Map();
97
+ // Create Vertex objects for each operation
98
+ for (const operation of jobGraph.vertices) {
99
+ verticesMap.set(operation.name, new Vertex(operation));
100
+ }
101
+ // Link vertices based on edges
102
+ for (const edge of jobGraph.edges) {
103
+ const { sourceVertex: sourceVertexName, targetVertex: targetVertexName, sourcePort, targetPort } = parseEdge(edge);
104
+ const sourceVertex = verticesMap.get(sourceVertexName);
105
+ const targetVertex = verticesMap.get(targetVertexName);
106
+ if (sourceVertex && targetVertex) {
107
+ sourceVertex.addNext(sourcePort, { name: targetPort, vertex: targetVertex });
108
+ }
109
+ }
110
+ return verticesMap;
111
+ }
112
+ /**
113
+ * Transforms job graph sources based on the specified options.
114
+ *
115
+ * Three transformation strategies are supported:
116
+ * 1. Sample data file: Replace all sources with a LogsValuesSource (not yet implemented)
117
+ * 2. Dataset query: Replace all sources with a single IcebergTableSource
118
+ * 3. In-place: Keep original sources but add record limits for batch processing
119
+ *
120
+ * @param jobGraph - The job graph to transform
121
+ * @param processing - Target processing type
122
+ * @param options - Source transformation options
123
+ * @returns Transformed job graph with updated sources
124
+ */
125
+ function transformSources(jobGraph, processing, options) {
126
+ if (options.sampleDataFile) {
127
+ transformSourcesToSampleData(jobGraph, options.sampleDataFile);
128
+ }
129
+ else if (options.datasetId) {
130
+ transformSourcesToDatasetQuery(jobGraph, options.datasetId, options.query, options.start, options.end, processing, options.limitRecords);
131
+ }
132
+ else {
133
+ transformSourcesInPlace(jobGraph, processing, options.limitRecords);
134
+ }
135
+ }
136
+ /**
137
+ * Transforms sources to use sample data from a file.
138
+ *
139
+ * This replaces all existing sources with a single LogsValuesSource that
140
+ * emits the log events from the sample data file. The file should contain
141
+ * a JSON array of log events matching the LogEvent schema.
142
+ *
143
+ * All edges from the old sources are rewired to connect from the new source
144
+ * to the first downstream operation in the pipeline.
145
+ *
146
+ * @param jobGraph - The job graph to transform
147
+ * @param sampleDataFile - Path to sample data file (JSON array of log events)
148
+ * @throws Error if the file cannot be read or parsed
149
+ */
150
+ function transformSourcesToSampleData(jobGraph, sampleDataFile) {
151
+ // Read and parse the sample data file
152
+ if (!fs.existsSync(sampleDataFile)) {
153
+ throw new Error(`Sample data file not found: ${sampleDataFile}`);
154
+ }
155
+ let sampleLogs;
156
+ try {
157
+ const fileContent = fs.readFileSync(sampleDataFile, 'utf-8');
158
+ sampleLogs = JSON.parse(fileContent);
159
+ if (!Array.isArray(sampleLogs)) {
160
+ throw new Error('Sample data must be a JSON array of log events');
161
+ }
162
+ }
163
+ catch (error) {
164
+ if (error.message.includes('Sample data')) {
165
+ throw error;
166
+ }
167
+ throw new Error(`Failed to parse sample data file: ${error.message}`);
168
+ }
169
+ // Create a new LogsValuesSource with the sample data
170
+ const newSource = {
171
+ type: LogsValuesSourceType.logs_values_source,
172
+ name: 'test_sample_source',
173
+ values: sampleLogs,
174
+ indefinite: false
175
+ };
176
+ const newSourceVertex = new Vertex(newSource);
177
+ // Remove all old sources and connect them to the new source
178
+ for (const vertex of Array.from(jobGraph.values())) {
179
+ if (isSource(vertex)) {
180
+ // Rewire edges from old source's next vertices to new source
181
+ for (const [port, nextIos] of vertex.next) {
182
+ for (const nextIo of nextIos) {
183
+ vertex.removeNext(port, nextIo);
184
+ newSourceVertex.addNext(DEFAULT_OUTPUT, nextIo);
185
+ }
186
+ }
187
+ jobGraph.delete(vertex.name);
188
+ }
189
+ }
190
+ // Add the new source vertex to the graph
191
+ jobGraph.set(newSourceVertex.name, newSourceVertex);
192
+ }
193
+ /**
194
+ * Transforms sources to use an Iceberg dataset as the data source.
195
+ *
196
+ * This replaces all existing sources with a single IcebergTableSource that:
197
+ * - Reads from the specified dataset
198
+ * - Optionally filters data using a query
199
+ * - Reads data within the specified time range
200
+ * - Limits records for batch processing if specified
201
+ *
202
+ * All edges from the old sources are rewired to connect from the new source
203
+ * to the first downstream operation in the pipeline.
204
+ *
205
+ * @param jobGraph - The job graph to transform
206
+ * @param datasetId - ID of the dataset to read from
207
+ * @param query - Optional query to filter dataset data
208
+ * @param start - Start time for data query
209
+ * @param end - End time for data query
210
+ * @param processing - Processing type (BATCH or STREAMING)
211
+ * @param limitRecords - Optional record limit for batch processing
212
+ * @returns Transformed job graph with dataset source
213
+ */
214
+ function transformSourcesToDatasetQuery(jobGraph, datasetId, query, start, end, processing, limitRecords) {
215
+ // Create a new Iceberg table source with the specified configuration
216
+ const newSource = {
217
+ type: LogsIcebergTableSourceType.logs_iceberg_table_source,
218
+ name: 'test_dataset_source',
219
+ datasetId,
220
+ query: {
221
+ type: DatadogQueryPredicateType.datadog_query,
222
+ query: query || ''
223
+ },
224
+ start: start || '',
225
+ end: end || '',
226
+ limit: limitRecords ?? DEFAULT_LIMIT
227
+ };
228
+ const newSourceVertex = new Vertex(newSource);
229
+ // Remove all old sources and connect them to the new source
230
+ for (const vertex of Array.from(jobGraph.values())) {
231
+ if (isSource(vertex)) {
232
+ // This is a source vertex since it has no inputs.
233
+ // Rewire edges from old source's next vertices to new source
234
+ for (const [port, nextIos] of vertex.next) {
235
+ for (const nextIo of nextIos) {
236
+ vertex.removeNext(port, nextIo);
237
+ newSourceVertex.addNext(DEFAULT_OUTPUT, nextIo);
238
+ }
239
+ }
240
+ jobGraph.delete(vertex.name);
241
+ }
242
+ }
243
+ // Add the new source vertex to the graph
244
+ jobGraph.set(newSourceVertex.name, newSourceVertex);
245
+ }
246
+ /**
247
+ * Transforms sources in place by adding record limits for batch processing.
248
+ *
249
+ * This keeps the original sources but adds a 'limit' parameter to sources
250
+ * that support it (e.g., IcebergTableSource). This is useful when you want
251
+ * to test with the same data sources but limit the amount of data processed.
252
+ *
253
+ * @param jobGraph - The job graph to transform
254
+ * @param processing - Processing type
255
+ * @param limitRecords - Optional record limit to apply
256
+ * @returns Transformed job graph with limited sources
257
+ */
258
+ function transformSourcesInPlace(jobGraph, processing, limitRecords) {
259
+ for (const vertex of jobGraph.values()) {
260
+ if (!isSource(vertex)) {
261
+ // Not a source vertex
262
+ continue;
263
+ }
264
+ if (processing === JobProcessing.BATCH && limitRecords && canLimit(vertex.operation)) {
265
+ vertex.operation = {
266
+ ...vertex.operation,
267
+ limit: limitRecords
268
+ };
269
+ }
270
+ }
271
+ }
272
+ /**
273
+ * Transforms job graph sinks based on the target execution type.
274
+ *
275
+ * Two transformation strategies:
276
+ * 1. SYNCHRONOUS: Replace all sinks with a single synchronous sink that returns results
277
+ * 2. ASYNCHRONOUS: Replace vendor sinks with test dataset sinks (if testDataset provided)
278
+ *
279
+ * @param jobGraph - The job graph to transform
280
+ * @param execution - Target execution type
281
+ * @param options - Sink transformation options
282
+ * @returns Transformed job graph with updated sinks
283
+ */
284
+ function transformSinks(jobGraph, execution, options) {
285
+ if (execution === JobExecution.SYNCHRONOUS) {
286
+ return transformSinksToSynchronous(jobGraph);
287
+ }
288
+ else {
289
+ if (!options.testDataset) {
290
+ throw new Error('Test dataset ID is required for ASYNCHRONOUS test job');
291
+ }
292
+ return transformSinksToAsynchronous(jobGraph, options.testDataset);
293
+ }
294
+ }
295
+ /**
296
+ * Transforms all sinks to a single synchronous sink.
297
+ *
298
+ * For synchronous testing, we replace all sink operations with a single
299
+ * LogsSyncSink that returns the processed data in the API response.
300
+ * This allows immediate verification of results.
301
+ *
302
+ * All operations that were feeding into the original sinks are rewired
303
+ * to feed into the new synchronous sink.
304
+ *
305
+ * @param jobGraph - The job graph to transform
306
+ */
307
+ function transformSinksToSynchronous(jobGraph) {
308
+ // Create a single synchronous sink to replace them all
309
+ const syncSink = {
310
+ type: LogsSynchronousSinkType.logs_sync_sink,
311
+ name: 'test_synchronous_sink'
312
+ };
313
+ const sinkVertex = new Vertex(syncSink);
314
+ wireNewSink(jobGraph, sinkVertex);
315
+ }
316
+ /**
317
+ * Transforms sinks for asynchronous testing with a test dataset.
318
+ *
319
+ * If a test dataset ID is provided, this replaces vendor sinks, raw data sinks,
320
+ * and event dedup sinks with Iceberg table sinks that write to the test dataset.
321
+ *
322
+ * The original sink names are preserved to maintain the graph structure.
323
+ * Test tagging (added separately) allows distinguishing which sink the data came from.
324
+ *
325
+ * @param jobGraph - The job graph to transform
326
+ * @param testDatasetId - Optional test dataset ID for output
327
+ */
328
+ function transformSinksToAsynchronous(jobGraph, testDatasetId) {
329
+ // For each sink (no outputs), replace with test dataset sink.
330
+ const sinkOp = {
331
+ type: LogsIcebergTableSinkType.logs_iceberg_table_sink,
332
+ name: 'test_async_sink',
333
+ datasetId: testDatasetId
334
+ };
335
+ const sinkVertex = new Vertex(sinkOp);
336
+ wireNewSink(jobGraph, sinkVertex);
337
+ }
338
+ function wireNewSink(jobGraph, sinkVertex) {
339
+ // Find all vertices that feed into sinks and rewire them to the new sync sink
340
+ for (const vertex of Array.from(jobGraph.values())) {
341
+ if (isSink(vertex)) {
342
+ // This is a sink vertex since it has no outputs.
343
+ // Rewire edges from old sink's prev vertices to new sync sink
344
+ for (const [port, prevIos] of vertex.prev) {
345
+ for (const prevIo of prevIos) {
346
+ vertex.removePrev(port, prevIo);
347
+ prevIo.vertex.addNext(prevIo.name, { name: DEFAULT_INPUT, vertex: sinkVertex });
348
+ }
349
+ }
350
+ jobGraph.delete(vertex.name);
351
+ }
352
+ }
353
+ // Add the new sink vertex to the graph
354
+ jobGraph.set(sinkVertex.name, sinkVertex);
355
+ }
356
+ /**
357
+ * Adds test tagging operations on all edges, with the id of the
358
+ * original edge and the test run ID.
359
+ *
360
+ * @param jobGraph - The job graph to transform
361
+ * @param testRunId - Unique test run identifier
362
+ */
363
+ function addTestTagging(jobGraph, testRunId) {
364
+ for (const vertex of Array.from(jobGraph.values())) {
365
+ for (const [output, nextIos] of Array.from(vertex.next)) {
366
+ for (const nextIo of nextIos) {
367
+ // insert a tagging operation before this io
368
+ const edge = `${vertex.name}_${output}_${nextIo.vertex.name}_${nextIo.name}`;
369
+ const tagOpName = `${edge}_test_tag`;
370
+ const tagOp = createTestTagOperation(tagOpName, testRunId, edge);
371
+ const tagVertex = new Vertex(tagOp);
372
+ // Rewire edges: vertex -> tagOp -> nextIo.vertex
373
+ vertex.removeNext(output, nextIo);
374
+ vertex.addNext(output, { name: DEFAULT_INPUT, vertex: tagVertex });
375
+ tagVertex.addNext(DEFAULT_OUTPUT, nextIo);
376
+ // Add the new tagging vertex to the graph
377
+ jobGraph.set(tagVertex.name, tagVertex);
378
+ }
379
+ }
380
+ }
381
+ }
382
+ /**
383
+ * Creates a log transform operation that adds test tags.
384
+ *
385
+ * The operation adds two tags:
386
+ * - grepr.test_run_id: Identifies which test run this data belongs to
387
+ * - grepr.edge: Identifies edge this data was going through
388
+ *
389
+ * These tags are added using the ADD modification, which appends to existing tag arrays.
390
+ *
391
+ * @param name - Name for the tagging operation
392
+ * @param testRunId - Unique test run identifier
393
+ * @param edge - Name of the edge
394
+ * @returns A LogTransformAction operation that adds the tags
395
+ */
396
+ function createTestTagOperation(name, testRunId, edge) {
397
+ return {
398
+ type: LogTransformActionType.log_transform,
399
+ name,
400
+ transforms: [
401
+ {
402
+ order: 0,
403
+ type: TagActionType.tag_action,
404
+ modification: TagActionModification.ADD,
405
+ tagKey: 'grepr.test_run_id',
406
+ values: [testRunId]
407
+ },
408
+ {
409
+ order: 1,
410
+ type: TagActionType.tag_action,
411
+ modification: TagActionModification.ADD,
412
+ tagKey: 'grepr.edge',
413
+ values: [edge]
414
+ }
415
+ ]
416
+ };
417
+ }
418
+ const isSource = (vertex) => vertex.prev.size === 0;
419
+ const isSink = (vertex) => vertex.next.size === 0;
420
+ /**
421
+ * Displays a summary of the transformations applied to a job.
422
+ *
423
+ * This shows a before/after comparison including:
424
+ * - Job name changes
425
+ * - Execution type changes
426
+ * - Processing type changes
427
+ * - operation and edge changes
428
+ * - Test run ID
429
+ *
430
+ * The output is formatted for console display.
431
+ *
432
+ * @param originalJob - The original production job
433
+ * @param transformedJob - The transformed test job
434
+ */
435
+ export function showDiff(originalJob, transformedJob) {
436
+ console.log('\n=== TRANSFORMATION SUMMARY ===\n');
437
+ console.log(`Name: ${originalJob.name} → ${transformedJob.name}`);
438
+ console.log(`Execution: ${originalJob.execution} → ${transformedJob.execution}`);
439
+ console.log(`Processing: ${originalJob.processing} → ${transformedJob.processing}`);
440
+ if (originalJob.jobGraph && transformedJob.jobGraph) {
441
+ // Show added/removed operations and added/removed edges
442
+ // For each operation in original, check if in transformed, and if changed
443
+ const originalOps = new Set(originalJob.jobGraph.vertices.map(v => v.name));
444
+ const transformedOps = new Set(transformedJob.jobGraph.vertices.map(v => v.name));
445
+ const originalOpsMap = new Map(originalJob.jobGraph.vertices.map(v => [v.name, v]));
446
+ const transformedOpsMap = new Map(transformedJob.jobGraph.vertices.map(v => [v.name, v]));
447
+ const addedOps = Array.from(transformedOps).filter(op => !originalOps.has(op));
448
+ const removedOps = Array.from(originalOps).filter(op => !transformedOps.has(op));
449
+ const changedOps = Array.from(originalOps).filter(op => transformedOps.has(op) &&
450
+ JSON.stringify(originalOpsMap.get(op)) !== JSON.stringify(transformedOpsMap.get(op)));
451
+ if (addedOps.length > 0) {
452
+ console.log(`Added Operations:`);
453
+ for (const opName of addedOps) {
454
+ const op = transformedOpsMap.get(opName);
455
+ console.log(`${JSON.stringify(op, null, 2)}`);
456
+ }
457
+ }
458
+ if (removedOps.length > 0) {
459
+ console.log(`Removed Operations:`);
460
+ for (const opName of removedOps) {
461
+ const op = originalOpsMap.get(opName);
462
+ console.log(`${JSON.stringify(op, null, 2)}`);
463
+ }
464
+ }
465
+ if (changedOps.length > 0) {
466
+ console.log(` Changed Operations:`);
467
+ for (const opName of changedOps) {
468
+ const originalOp = originalOpsMap.get(opName);
469
+ const transformedOp = transformedOpsMap.get(opName);
470
+ console.log(`- Original: ${JSON.stringify(originalOp, null, 2)}`);
471
+ console.log(`+ Transformed: ${JSON.stringify(transformedOp, null, 2)}`);
472
+ }
473
+ }
474
+ // Show edge changes
475
+ const originalEdges = new Set(originalJob.jobGraph.edges);
476
+ const transformedEdges = new Set(transformedJob.jobGraph.edges);
477
+ const addedEdges = Array.from(transformedEdges).filter(edge => !originalEdges.has(edge));
478
+ const removedEdges = Array.from(originalEdges).filter(edge => !transformedEdges.has(edge));
479
+ if (addedEdges.length > 0) {
480
+ console.log(`\n Added Edges:`);
481
+ for (const edge of addedEdges) {
482
+ console.log(`+ ${edge}`);
483
+ }
484
+ }
485
+ if (removedEdges.length > 0) {
486
+ console.log(`\n Removed Edges:`);
487
+ for (const edge of removedEdges) {
488
+ console.log(`- ${edge}`);
489
+ }
490
+ }
491
+ console.log('\nOperations:');
492
+ }
493
+ console.log('\nTest Tag:');
494
+ console.log(` ${transformedJob.tags?.['grepr.test_run_id']}`);
495
+ console.log('\n=== TRANSFORMED JOB JSON ===\n');
496
+ }
497
+ //# sourceMappingURL=job-graph-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-graph-transformer.js","sourceRoot":"","sources":["../../../src/main/typescript/lib/job-graph-transformer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Utility functions for working with Grepr job graphs.
3
+ *
4
+ * This module provides helper functions for:
5
+ * - Identifying different types of operations (sources, sinks, etc.)
6
+ * - Parsing and manipulating job graph edges
7
+ * - Traversing the job graph to find related vertices
8
+ * - Generating test identifiers
9
+ *
10
+ * All functions work with the OpenAPI-generated types to ensure type safety.
11
+ */
12
+ import { SchemaOperation } from '../openapi/openApiTypes.js';
13
+ /**
14
+ * Checks if a source vertex supports record limiting.
15
+ *
16
+ * Some source operations (like Iceberg table sources and Grepr internal sources)
17
+ * support a 'limit' parameter to restrict the number of records read, which is
18
+ * useful for batch testing.
19
+ *
20
+ * @param vertex - The operation to check
21
+ * @returns true if the vertex supports limiting
22
+ */
23
+ export declare function canLimit(vertex: SchemaOperation): boolean;
24
+ /**
25
+ * Parses a job graph edge string into source and target vertex names.
26
+ *
27
+ * Edges are represented as strings in the format "source -> target".
28
+ * Or "source:out -> target:in".
29
+ * This function splits the edge and validates the format.
30
+ *
31
+ * @param edge - The edge string to parse (e.g., "source -> target")
32
+ * @returns A tuple of [source, target] vertex/port names
33
+ * @throws Error if the edge format is invalid
34
+ */
35
+ export declare function parseEdge(edge: string): {
36
+ sourceVertex: string;
37
+ sourcePort: string;
38
+ targetVertex: string;
39
+ targetPort: string;
40
+ };
41
+ /**
42
+ * Generates a unique test identifier.
43
+ *
44
+ * Creates a unique ID for test runs using a combination of timestamp and random string.
45
+ * Format: test_{timestamp}_{random}
46
+ *
47
+ * @returns A unique test identifier string
48
+ */
49
+ export declare function generateUUID(): string;
50
+ //# sourceMappingURL=job-graph-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"job-graph-utils.d.ts","sourceRoot":"","sources":["../../../src/main/typescript/lib/job-graph-utils.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,eAAe,EAGhB,MAAM,wBAAwB,CAAC;AAGhC;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAazD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IACvC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAA;CACnB,CA6BA;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC"}