@stilyng94/athena-query-client 1.0.1 → 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.
- package/README.md +8 -8
- package/dist/demo.js +31 -14
- package/dist/demo.js.map +1 -1
- package/dist/demo.processor.d.ts +88 -0
- package/dist/demo.processor.js +192 -0
- package/dist/demo.processor.js.map +1 -0
- package/dist/query-results-processor.js +3 -2
- package/dist/query-results-processor.js.map +1 -1
- package/dist/schema.d.ts +72 -0
- package/dist/schema.js +62 -0
- package/dist/schema.js.map +1 -0
- package/dist/utils.d.ts +21 -0
- package/dist/utils.js +98 -0
- package/dist/utils.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,9 +25,9 @@ import {
|
|
|
25
25
|
JsonFileAppender,
|
|
26
26
|
} from "@stilyng94/athena-query-client";
|
|
27
27
|
|
|
28
|
-
const
|
|
28
|
+
const athenaQuery = "SELECT * from api_logs";
|
|
29
29
|
|
|
30
|
-
const execute = async (query) => {
|
|
30
|
+
const execute = async (query: string) => {
|
|
31
31
|
const athena = new AthenaQueryClient({
|
|
32
32
|
Catalog: "catalog",
|
|
33
33
|
Database: "logs",
|
|
@@ -37,7 +37,7 @@ const execute = async (query) => {
|
|
|
37
37
|
s3Region: "us-west-2",
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
const queryExecutionId = await athena.query();
|
|
40
|
+
const queryExecutionId = await athena.query(query);
|
|
41
41
|
|
|
42
42
|
const jsonFileAppender = new JsonFileAppender({
|
|
43
43
|
directory: "",
|
|
@@ -60,7 +60,7 @@ const execute = async (query) => {
|
|
|
60
60
|
.catch((error) => console.error(error));
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
execute().catch(console.error);
|
|
63
|
+
execute(athenaQuery).catch(console.error);
|
|
64
64
|
```
|
|
65
65
|
|
|
66
66
|
## Get query results and map to Js object
|
|
@@ -71,9 +71,9 @@ import {
|
|
|
71
71
|
MappedQueryResultProcessor,
|
|
72
72
|
} from "@stilyng94/athena-query-client";
|
|
73
73
|
|
|
74
|
-
const
|
|
74
|
+
const athenaQuery = "SELECT * from api_logs";
|
|
75
75
|
|
|
76
|
-
const execute = async (query) => {
|
|
76
|
+
const execute = async (query: string) => {
|
|
77
77
|
const athena = new AthenaQueryClient({
|
|
78
78
|
Catalog: "catalog",
|
|
79
79
|
Database: "logs",
|
|
@@ -83,7 +83,7 @@ const execute = async (query) => {
|
|
|
83
83
|
s3Region: "us-west-2",
|
|
84
84
|
});
|
|
85
85
|
|
|
86
|
-
const queryExecutionId = await athena.query();
|
|
86
|
+
const queryExecutionId = await athena.query(query);
|
|
87
87
|
|
|
88
88
|
const mappedQueryResultProcessor = new MappedQueryResultProcessor({
|
|
89
89
|
athenaClient: athena,
|
|
@@ -93,5 +93,5 @@ const execute = async (query) => {
|
|
|
93
93
|
});
|
|
94
94
|
};
|
|
95
95
|
|
|
96
|
-
execute().catch(console.error);
|
|
96
|
+
execute(athenaQuery).catch(console.error);
|
|
97
97
|
```
|
package/dist/demo.js
CHANGED
|
@@ -1,15 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
1
|
+
import { DemoS3QueryResultProcessor } from "./demo.processor.js";
|
|
2
|
+
import { JsonFileAppender } from "./json-file-appender.js";
|
|
3
|
+
import { processToJson } from "./utils.js";
|
|
4
|
+
const execute = async () => {
|
|
5
|
+
const fileNamesSet = new Set();
|
|
6
|
+
const s3QueryResultProcessor = new DemoS3QueryResultProcessor({
|
|
7
|
+
s3OutputLocation: "s3://results/queries",
|
|
8
|
+
s3Region: "us-west-2",
|
|
9
|
+
batchSize: 999,
|
|
10
|
+
onData: async (rows) => {
|
|
11
|
+
const fileNames = await processToJson(rows, "conversions");
|
|
12
|
+
// biome-ignore lint/complexity/noForEach: <explanation>
|
|
13
|
+
fileNames.forEach((fileName) => {
|
|
14
|
+
fileNamesSet.add(fileName);
|
|
15
|
+
});
|
|
16
|
+
},
|
|
17
|
+
onComplete: async () => {
|
|
18
|
+
await Promise.all(Array.from(fileNamesSet).map((fileName) => {
|
|
19
|
+
const jsonFileAppender = new JsonFileAppender({
|
|
20
|
+
fileName,
|
|
21
|
+
directory: "conversions",
|
|
22
|
+
});
|
|
23
|
+
return jsonFileAppender.closeFileWithBracket();
|
|
24
|
+
}));
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
s3QueryResultProcessor
|
|
28
|
+
.processResults("094cedb4-8739-4957-81c1-ecf3e4d8c783")
|
|
29
|
+
.catch((error) => console.error(error));
|
|
30
|
+
};
|
|
31
|
+
execute().catch(console.error);
|
|
15
32
|
//# sourceMappingURL=demo.js.map
|
package/dist/demo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"demo.js","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"demo.js","sourceRoot":"","sources":["../src/demo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;IACzB,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAEvC,MAAM,sBAAsB,GAAG,IAAI,0BAA0B,CAAC;QAC5D,gBAAgB,EAAE,sBAAsB;QACxC,QAAQ,EAAE,WAAW;QACrB,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACrB,MAAM,SAAS,GAAG,MAAM,aAAa,CACnC,IASE,EACF,aAAa,CACd,CAAC;YACF,wDAAwD;YACxD,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;gBAC7B,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YAC7B,CAAC,CAAC,CAAC;QACL,CAAC;QACD,UAAU,EAAE,KAAK,IAAI,EAAE;YACrB,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;gBACxC,MAAM,gBAAgB,GAAG,IAAI,gBAAgB,CAAC;oBAC5C,QAAQ;oBACR,SAAS,EAAE,aAAa;iBACzB,CAAC,CAAC;gBACH,OAAO,gBAAgB,CAAC,oBAAoB,EAAE,CAAC;YACjD,CAAC,CAAC,CACH,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;IACH,sBAAsB;SACnB,cAAc,CAAC,sCAAsC,CAAC;SACtD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;AAC5C,CAAC,CAAC;AAEF,OAAO,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { Readable } from "node:stream";
|
|
2
|
+
import { type ResultSet, type Row } from "@aws-sdk/client-athena";
|
|
3
|
+
import { type MappedQueryResultProcessorParams, type QueryResultProcessor, type S3QueryResultProcessorParams } from "./types.js";
|
|
4
|
+
/**
|
|
5
|
+
* Processes Athena query results stored in S3
|
|
6
|
+
*/
|
|
7
|
+
export declare class DemoS3QueryResultProcessor implements QueryResultProcessor {
|
|
8
|
+
private readonly config;
|
|
9
|
+
readonly batchSize: number;
|
|
10
|
+
readonly s3OutputLocation: string;
|
|
11
|
+
/**
|
|
12
|
+
* Creates a new S3QueryResultProcessor
|
|
13
|
+
* @param {S3QueryResultProcessorParams} config - Configuration parameters
|
|
14
|
+
*/
|
|
15
|
+
constructor(config: S3QueryResultProcessorParams);
|
|
16
|
+
/**
|
|
17
|
+
* Processes query results from S3
|
|
18
|
+
* @param {string} queryExecutionId - The ID of the query execution
|
|
19
|
+
* @returns {Promise<void>} Promise that resolves when processing is complete
|
|
20
|
+
*/
|
|
21
|
+
processResults(queryExecutionId: string): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Processes streaming results from S3
|
|
24
|
+
* @param {Readable} stream - The readable stream of results
|
|
25
|
+
* @returns {Promise<void>} Promise that resolves when processing is complete
|
|
26
|
+
*/
|
|
27
|
+
processStreamingResults(stream: Readable): Promise<void>;
|
|
28
|
+
/**
|
|
29
|
+
* Processes a batch of records
|
|
30
|
+
* @param {unknown[]} batch - Array of records to process
|
|
31
|
+
* @returns {Promise<void>} Promise that resolves when batch is processed
|
|
32
|
+
*/
|
|
33
|
+
processBatch(batch: unknown[]): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Validates the batch size configuration
|
|
36
|
+
* @param {number} [batchSize] - The batch size to validate
|
|
37
|
+
* @returns {number} The validated batch size
|
|
38
|
+
* @throws {Error} If batch size exceeds maximum allowed
|
|
39
|
+
*/
|
|
40
|
+
validateBatchSize(batchSize?: number): number;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Processes Athena query results by mapping them to objects
|
|
44
|
+
*/
|
|
45
|
+
export declare class MappedQueryResultProcessor implements QueryResultProcessor {
|
|
46
|
+
private readonly config;
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new MappedQueryResultProcessor
|
|
49
|
+
* @param {MappedQueryResultProcessorParams} config - Configuration parameters
|
|
50
|
+
*/
|
|
51
|
+
constructor(config: MappedQueryResultProcessorParams);
|
|
52
|
+
/**
|
|
53
|
+
* Processes query results by mapping them to objects
|
|
54
|
+
* @param {string} queryExecutionId - The ID of the query execution
|
|
55
|
+
* @returns {Promise<Record<string, string>[]>} Promise resolving to array of mapped objects
|
|
56
|
+
*/
|
|
57
|
+
processResults(queryExecutionId: string): Promise<Record<string, string>[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Fetches query results from Athena
|
|
60
|
+
* @param {string} queryExecutionId - The ID of the query execution
|
|
61
|
+
* @returns {Promise<ResultSet>} Promise resolving to Athena ResultSet
|
|
62
|
+
* @throws {Error} If results are empty or undefined
|
|
63
|
+
*/
|
|
64
|
+
fetchQueryResults(queryExecutionId: string): Promise<ResultSet>;
|
|
65
|
+
/**
|
|
66
|
+
* Extracts column headers from result rows
|
|
67
|
+
* @param {Row[]} rows - Array of result rows
|
|
68
|
+
* @returns {string[]} Array of header names
|
|
69
|
+
* @throws {Error} If no headers are found
|
|
70
|
+
*/
|
|
71
|
+
extractHeaders(rows: Row[]): string[];
|
|
72
|
+
/**
|
|
73
|
+
* Maps a row to an object using column headers as keys
|
|
74
|
+
* @param {Row} row - The row to map
|
|
75
|
+
* @param {string[]} headers - Array of column headers
|
|
76
|
+
* @returns {Record<string, string>} Object with header-value pairs
|
|
77
|
+
*/
|
|
78
|
+
mapRowToObject(row: Row, headers: string[]): Record<string, string>;
|
|
79
|
+
/**
|
|
80
|
+
* Extracts Athena ResultSet data into an array of key-value objects
|
|
81
|
+
* Extracts Athena ResultSet data into an array of key-value objects
|
|
82
|
+
* @private
|
|
83
|
+
* @param {ResultSet} resultSet - The ResultSet object returned by Athena
|
|
84
|
+
* @returns {Record<string, string>[]} Array of objects representing query rows
|
|
85
|
+
* @throws {Error} If no headers are found
|
|
86
|
+
*/
|
|
87
|
+
extractRows(resultSet: ResultSet): Record<string, string>[];
|
|
88
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { createReadStream } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { cwd } from "node:process";
|
|
4
|
+
import { finished } from "node:stream/promises";
|
|
5
|
+
import { GetQueryResultsCommand, } from "@aws-sdk/client-athena";
|
|
6
|
+
import { parse } from "csv-parse";
|
|
7
|
+
import { MAX_BATCH_SIZE, } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Processes Athena query results stored in S3
|
|
10
|
+
*/
|
|
11
|
+
export class DemoS3QueryResultProcessor {
|
|
12
|
+
config;
|
|
13
|
+
batchSize = MAX_BATCH_SIZE;
|
|
14
|
+
s3OutputLocation;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new S3QueryResultProcessor
|
|
17
|
+
* @param {S3QueryResultProcessorParams} config - Configuration parameters
|
|
18
|
+
*/
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.batchSize = this.validateBatchSize(config.batchSize);
|
|
22
|
+
this.s3OutputLocation = config.s3OutputLocation;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Processes query results from S3
|
|
26
|
+
* @param {string} queryExecutionId - The ID of the query execution
|
|
27
|
+
* @returns {Promise<void>} Promise that resolves when processing is complete
|
|
28
|
+
*/
|
|
29
|
+
async processResults(queryExecutionId) {
|
|
30
|
+
console.log("Fetching query results from S3:", queryExecutionId);
|
|
31
|
+
const responseStream = createReadStream(path.join(cwd(), "athena.csv"));
|
|
32
|
+
return this.processStreamingResults(responseStream);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Processes streaming results from S3
|
|
36
|
+
* @param {Readable} stream - The readable stream of results
|
|
37
|
+
* @returns {Promise<void>} Promise that resolves when processing is complete
|
|
38
|
+
*/
|
|
39
|
+
async processStreamingResults(stream) {
|
|
40
|
+
const batch = [];
|
|
41
|
+
let totalProcessed = 0;
|
|
42
|
+
const parser = stream.pipe(parse({ ...(this.config.csvParseOptions ?? { columns: true }) }));
|
|
43
|
+
try {
|
|
44
|
+
parser.on("readable", async () => {
|
|
45
|
+
let record = parser.read();
|
|
46
|
+
while (record !== null) {
|
|
47
|
+
// Work with each record
|
|
48
|
+
batch.push(record);
|
|
49
|
+
if (batch.length >= this.batchSize) {
|
|
50
|
+
console.log(`Processing batch of ${batch.length} records...`);
|
|
51
|
+
await this.processBatch(batch);
|
|
52
|
+
totalProcessed += batch.length;
|
|
53
|
+
batch.length = 0; // Clear array efficiently
|
|
54
|
+
console.log(`Total records processed: ${totalProcessed}`);
|
|
55
|
+
}
|
|
56
|
+
record = parser.read();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
// Wait for parsing to complete
|
|
60
|
+
await finished(parser);
|
|
61
|
+
// Process remaining records
|
|
62
|
+
if (batch.length > 0) {
|
|
63
|
+
console.log(`Processing final batch of ${batch.length} records...`);
|
|
64
|
+
await this.processBatch(batch);
|
|
65
|
+
totalProcessed += batch.length;
|
|
66
|
+
console.log(`Final total records processed: ${totalProcessed}`);
|
|
67
|
+
}
|
|
68
|
+
await this.config?.onComplete?.();
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
throw new Error(`Error processing results: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Processes a batch of records
|
|
76
|
+
* @param {unknown[]} batch - Array of records to process
|
|
77
|
+
* @returns {Promise<void>} Promise that resolves when batch is processed
|
|
78
|
+
*/
|
|
79
|
+
async processBatch(batch) {
|
|
80
|
+
try {
|
|
81
|
+
await this.config.onData(batch);
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
throw new Error(`Error processing batch: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Validates the batch size configuration
|
|
89
|
+
* @param {number} [batchSize] - The batch size to validate
|
|
90
|
+
* @returns {number} The validated batch size
|
|
91
|
+
* @throws {Error} If batch size exceeds maximum allowed
|
|
92
|
+
*/
|
|
93
|
+
validateBatchSize(batchSize) {
|
|
94
|
+
if (!batchSize)
|
|
95
|
+
return MAX_BATCH_SIZE;
|
|
96
|
+
if (batchSize > MAX_BATCH_SIZE) {
|
|
97
|
+
throw new Error(`Batch size cannot be greater than ${MAX_BATCH_SIZE}`);
|
|
98
|
+
}
|
|
99
|
+
return batchSize;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Processes Athena query results by mapping them to objects
|
|
104
|
+
*/
|
|
105
|
+
export class MappedQueryResultProcessor {
|
|
106
|
+
config;
|
|
107
|
+
/**
|
|
108
|
+
* Creates a new MappedQueryResultProcessor
|
|
109
|
+
* @param {MappedQueryResultProcessorParams} config - Configuration parameters
|
|
110
|
+
*/
|
|
111
|
+
constructor(config) {
|
|
112
|
+
this.config = config;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Processes query results by mapping them to objects
|
|
116
|
+
* @param {string} queryExecutionId - The ID of the query execution
|
|
117
|
+
* @returns {Promise<Record<string, string>[]>} Promise resolving to array of mapped objects
|
|
118
|
+
*/
|
|
119
|
+
async processResults(queryExecutionId) {
|
|
120
|
+
console.log("Fetching results for QueryExecutionId:", queryExecutionId);
|
|
121
|
+
try {
|
|
122
|
+
const resultSet = await this.fetchQueryResults(queryExecutionId);
|
|
123
|
+
return this.extractRows(resultSet);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
throw new Error(`Error processing results: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Fetches query results from Athena
|
|
131
|
+
* @param {string} queryExecutionId - The ID of the query execution
|
|
132
|
+
* @returns {Promise<ResultSet>} Promise resolving to Athena ResultSet
|
|
133
|
+
* @throws {Error} If results are empty or undefined
|
|
134
|
+
*/
|
|
135
|
+
async fetchQueryResults(queryExecutionId) {
|
|
136
|
+
const response = await this.config.athenaClient.send(new GetQueryResultsCommand({ QueryExecutionId: queryExecutionId }));
|
|
137
|
+
if (!response.ResultSet) {
|
|
138
|
+
throw new Error("Query results are empty or undefined");
|
|
139
|
+
}
|
|
140
|
+
return response.ResultSet;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Extracts column headers from result rows
|
|
144
|
+
* @param {Row[]} rows - Array of result rows
|
|
145
|
+
* @returns {string[]} Array of header names
|
|
146
|
+
* @throws {Error} If no headers are found
|
|
147
|
+
*/
|
|
148
|
+
extractHeaders(rows) {
|
|
149
|
+
const headers = rows[0]?.Data?.map((column) => column.VarCharValue || "");
|
|
150
|
+
if (!headers || headers.length === 0) {
|
|
151
|
+
throw new Error("No headers found in the result set");
|
|
152
|
+
}
|
|
153
|
+
return headers;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Maps a row to an object using column headers as keys
|
|
157
|
+
* @param {Row} row - The row to map
|
|
158
|
+
* @param {string[]} headers - Array of column headers
|
|
159
|
+
* @returns {Record<string, string>} Object with header-value pairs
|
|
160
|
+
*/
|
|
161
|
+
mapRowToObject(row, headers) {
|
|
162
|
+
const mappedRow = {};
|
|
163
|
+
row.Data?.forEach((value, index) => {
|
|
164
|
+
const header = headers[index];
|
|
165
|
+
if (header) {
|
|
166
|
+
mappedRow[header] = value.VarCharValue || "";
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
return mappedRow;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Extracts Athena ResultSet data into an array of key-value objects
|
|
173
|
+
* Extracts Athena ResultSet data into an array of key-value objects
|
|
174
|
+
* @private
|
|
175
|
+
* @param {ResultSet} resultSet - The ResultSet object returned by Athena
|
|
176
|
+
* @returns {Record<string, string>[]} Array of objects representing query rows
|
|
177
|
+
* @throws {Error} If no headers are found
|
|
178
|
+
*/
|
|
179
|
+
extractRows(resultSet) {
|
|
180
|
+
const { Rows } = resultSet;
|
|
181
|
+
if (!Rows || Rows.length === 0) {
|
|
182
|
+
console.error("No rows found in result set");
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
const headers = this.extractHeaders(Rows);
|
|
186
|
+
if (!headers.length) {
|
|
187
|
+
throw new Error("No headers found in the result set");
|
|
188
|
+
}
|
|
189
|
+
return Rows.slice(1).map((row) => this.mapRowToObject(row, headers));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=demo.processor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"demo.processor.js","sourceRoot":"","sources":["../src/demo.processor.ts"],"names":[],"mappings":"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"}
|
|
@@ -42,10 +42,10 @@ export class S3QueryResultProcessor {
|
|
|
42
42
|
async #processStreamingResults(stream) {
|
|
43
43
|
const batch = [];
|
|
44
44
|
let totalProcessed = 0;
|
|
45
|
-
const parser = stream.pipe(parse({ ...(this.config.csvParseOptions ?? {}) }));
|
|
45
|
+
const parser = stream.pipe(parse({ columns: true, ...(this.config.csvParseOptions ?? {}) }));
|
|
46
46
|
try {
|
|
47
47
|
parser.on('readable', async () => {
|
|
48
|
-
|
|
48
|
+
let record = parser.read();
|
|
49
49
|
while (record !== null) {
|
|
50
50
|
// Work with each record
|
|
51
51
|
batch.push(record);
|
|
@@ -56,6 +56,7 @@ export class S3QueryResultProcessor {
|
|
|
56
56
|
batch.length = 0; // Clear array efficiently
|
|
57
57
|
console.log(`Total records processed: ${totalProcessed}`);
|
|
58
58
|
}
|
|
59
|
+
record = parser.read();
|
|
59
60
|
}
|
|
60
61
|
});
|
|
61
62
|
// Wait for parsing to complete
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-results-processor.js","sourceRoot":"","sources":["../src/query-results-processor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AAC/C,OAAO,EACL,sBAAsB,GAGvB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC/D,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAA;AACjC,OAAO,EACL,cAAc,GAIf,MAAM,YAAY,CAAA;AAEnB;;GAEG;AACH,MAAM,OAAO,sBAAsB;IASJ;IARpB,UAAU,GAAG,cAAc,CAAA;IAC3B,SAAS,CAAU;IACnB,iBAAiB,CAAQ;IAElC;;;OAGG;IACH,YAA6B,MAAoC;QAApC,WAAM,GAAN,MAAM,CAA8B;QAC/D,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC3D,IAAI,CAAC,iBAAiB,GAAG,MAAM,CAAC,gBAAgB,CAAA;QAChD,IAAI,CAAC,SAAS,GAAG,IAAI,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAA;IAC5D,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,cAAc,CAAC,gBAAwB;QAC3C,iCAAiC;QACjC,MAAM,UAAU,GAAG,GAAG,IAAI,CAAC,iBAAiB,IAAI,gBAAgB,MAAM,CAAA;QACtE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAA;QACpD,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,UAAU,CAAC,CAAA;QAE1D,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;QAC7D,OAAO,IAAI,CAAC,wBAAwB,CAAC,cAAc,CAAC,CAAA;IACtD,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,wBAAwB,CAAC,MAAgB;QAC7C,MAAM,KAAK,GAAc,EAAE,CAAA;QAC3B,IAAI,cAAc,GAAG,CAAC,CAAA;QAEtB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CACxB,KAAK,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,EAAE,CAAC,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"query-results-processor.js","sourceRoot":"","sources":["../src/query-results-processor.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const safeUrlDecode: (value: string) => string;
|
|
3
|
+
export declare const urlEncodedString: (schema: z.ZodString) => z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>;
|
|
4
|
+
export declare const datePreprocessor: z.ZodEffects<z.ZodString, string, unknown>;
|
|
5
|
+
export declare const CsiUriQuerySchema: z.ZodObject<{
|
|
6
|
+
type: z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>;
|
|
7
|
+
siteId: z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>;
|
|
8
|
+
currency: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>>;
|
|
9
|
+
idorder: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>>;
|
|
10
|
+
revenue: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
11
|
+
created_at: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodString, string, unknown>>>;
|
|
12
|
+
shipping: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>>;
|
|
13
|
+
discount: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
14
|
+
referrer: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>>;
|
|
15
|
+
_idv: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>>;
|
|
16
|
+
_id: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>>;
|
|
17
|
+
idsite: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
18
|
+
quicktransaction: z.ZodOptional<z.ZodEnum<["0", "1"]>>;
|
|
19
|
+
agent: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>>;
|
|
20
|
+
audit_key: z.ZodNullable<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>;
|
|
21
|
+
device_type: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>>;
|
|
22
|
+
parent_idv: z.ZodDefault<z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>>;
|
|
23
|
+
country: z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>;
|
|
24
|
+
items_count: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
25
|
+
url: z.ZodOptional<z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodString>>, string, unknown>>;
|
|
26
|
+
date: z.ZodOptional<z.ZodEffects<z.ZodString, string, unknown>>;
|
|
27
|
+
}, "strip", z.ZodTypeAny, {
|
|
28
|
+
currency: string;
|
|
29
|
+
idorder: string;
|
|
30
|
+
revenue: string;
|
|
31
|
+
created_at: string;
|
|
32
|
+
shipping: string;
|
|
33
|
+
discount: string;
|
|
34
|
+
referrer: string;
|
|
35
|
+
_idv: string;
|
|
36
|
+
_id: string;
|
|
37
|
+
idsite: string;
|
|
38
|
+
agent: string;
|
|
39
|
+
audit_key: string | null;
|
|
40
|
+
device_type: string;
|
|
41
|
+
parent_idv: string;
|
|
42
|
+
items_count: string;
|
|
43
|
+
type?: string | undefined;
|
|
44
|
+
siteId?: string | undefined;
|
|
45
|
+
quicktransaction?: "0" | "1" | undefined;
|
|
46
|
+
country?: string | undefined;
|
|
47
|
+
url?: string | undefined;
|
|
48
|
+
date?: string | undefined;
|
|
49
|
+
}, {
|
|
50
|
+
type?: unknown;
|
|
51
|
+
siteId?: unknown;
|
|
52
|
+
currency?: unknown;
|
|
53
|
+
idorder?: unknown;
|
|
54
|
+
revenue?: string | undefined;
|
|
55
|
+
created_at?: unknown;
|
|
56
|
+
shipping?: unknown;
|
|
57
|
+
discount?: string | undefined;
|
|
58
|
+
referrer?: unknown;
|
|
59
|
+
_idv?: unknown;
|
|
60
|
+
_id?: unknown;
|
|
61
|
+
idsite?: string | undefined;
|
|
62
|
+
quicktransaction?: "0" | "1" | undefined;
|
|
63
|
+
agent?: unknown;
|
|
64
|
+
audit_key?: unknown;
|
|
65
|
+
device_type?: unknown;
|
|
66
|
+
parent_idv?: unknown;
|
|
67
|
+
country?: unknown;
|
|
68
|
+
items_count?: string | undefined;
|
|
69
|
+
url?: unknown;
|
|
70
|
+
date?: unknown;
|
|
71
|
+
}>;
|
|
72
|
+
export type CsiUriQuery = z.infer<typeof CsiUriQuerySchema>;
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
// Helper function to decode URL components safely
|
|
3
|
+
export const safeUrlDecode = (value) => {
|
|
4
|
+
try {
|
|
5
|
+
// Handle different levels of URL encoding
|
|
6
|
+
return decodeURIComponent(decodeURIComponent(value.replace(/\+/g, " ")));
|
|
7
|
+
// biome-ignore lint/correctness/noUnusedVariables: <explanation>
|
|
8
|
+
}
|
|
9
|
+
catch (e) {
|
|
10
|
+
try {
|
|
11
|
+
// Try single decoding if double fails
|
|
12
|
+
return decodeURIComponent(value.replace(/\+/g, " "));
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Return original if both fail
|
|
16
|
+
return value;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
// Create a preprocessor for URL-encoded strings
|
|
21
|
+
export const urlEncodedString = (schema) => z.preprocess((val) => {
|
|
22
|
+
if (typeof val !== "string")
|
|
23
|
+
return val;
|
|
24
|
+
return safeUrlDecode(val);
|
|
25
|
+
}, schema.optional().default(""));
|
|
26
|
+
// Create a preprocessor for dates
|
|
27
|
+
export const datePreprocessor = z.preprocess((val) => {
|
|
28
|
+
if (typeof val !== "string")
|
|
29
|
+
return val;
|
|
30
|
+
const decoded = safeUrlDecode(val);
|
|
31
|
+
try {
|
|
32
|
+
return new Date(decoded).toISOString();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return val;
|
|
36
|
+
}
|
|
37
|
+
}, z.string());
|
|
38
|
+
// Zod schema with all fields optional
|
|
39
|
+
export const CsiUriQuerySchema = z.object({
|
|
40
|
+
type: urlEncodedString(z.string()).optional(),
|
|
41
|
+
siteId: urlEncodedString(z.string().regex(/^\d+$/, "Site ID must be numeric")).optional(),
|
|
42
|
+
currency: urlEncodedString(z.string()).optional().default(""),
|
|
43
|
+
idorder: urlEncodedString(z.string()).optional().default(""),
|
|
44
|
+
revenue: z.string().optional().default(""),
|
|
45
|
+
created_at: datePreprocessor.optional().default(""),
|
|
46
|
+
shipping: urlEncodedString(z.string()).optional().default(""),
|
|
47
|
+
discount: z.string().optional().default(""),
|
|
48
|
+
referrer: urlEncodedString(z.string()).optional().default(""),
|
|
49
|
+
_idv: urlEncodedString(z.string()).optional().default(""),
|
|
50
|
+
_id: urlEncodedString(z.string()).optional().default(""),
|
|
51
|
+
idsite: z.string().optional().default(""),
|
|
52
|
+
quicktransaction: z.enum(["0", "1"]).optional(),
|
|
53
|
+
agent: urlEncodedString(z.string()).optional().default(""),
|
|
54
|
+
audit_key: urlEncodedString(z.string()).nullable(),
|
|
55
|
+
device_type: urlEncodedString(z.string()).optional().default(""),
|
|
56
|
+
parent_idv: urlEncodedString(z.string()).optional().default(""),
|
|
57
|
+
country: urlEncodedString(z.string().length(2, "Country must be a 2-letter code")).optional(),
|
|
58
|
+
items_count: z.string().optional().default(""),
|
|
59
|
+
url: urlEncodedString(z.string().url()).optional(),
|
|
60
|
+
date: datePreprocessor.optional(),
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*@description Interface for mapped data row structure
|
|
3
|
+
*/
|
|
4
|
+
interface MappedDataRow {
|
|
5
|
+
partition_date: string;
|
|
6
|
+
hour: string;
|
|
7
|
+
idorder: string;
|
|
8
|
+
idsite: string;
|
|
9
|
+
siteid: string;
|
|
10
|
+
sid: string;
|
|
11
|
+
cs_uri_query: string;
|
|
12
|
+
cs_referer: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @description Processes mapped data and writes to JSON files grouped by date
|
|
16
|
+
* @param {MappedDataRow[]} mappedData - Data to be processed
|
|
17
|
+
* @param {string} directory - Output directory for files
|
|
18
|
+
* @returns {Promise<string[]>} Array of created filenames
|
|
19
|
+
*/
|
|
20
|
+
export declare function processToJson(mappedData: MappedDataRow[], directory: string): Promise<string[]>;
|
|
21
|
+
export {};
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { JsonFileAppender } from "./json-file-appender.js";
|
|
2
|
+
import { CsiUriQuerySchema } from "./schema.js";
|
|
3
|
+
/**
|
|
4
|
+
*@description Parses a CSI_URI query string into a structured object
|
|
5
|
+
* @param {string} queryString - The query string to parse
|
|
6
|
+
* @returns {CsiUriQuery} Parsed and validated query object
|
|
7
|
+
*/
|
|
8
|
+
const parseCsiUriQuery = (queryString) => {
|
|
9
|
+
const cleanQueryString = queryString
|
|
10
|
+
.replace(/^cs_uri_query:\s*['"]?/, "")
|
|
11
|
+
.replace(/['"]$/, "");
|
|
12
|
+
// Create params object
|
|
13
|
+
const params = {};
|
|
14
|
+
// Split and parse, handling both & and ; separators
|
|
15
|
+
// biome-ignore lint/complexity/noForEach: <explanation>
|
|
16
|
+
cleanQueryString.split(/[&;]/).forEach((param) => {
|
|
17
|
+
const [key, ...values] = param.split("=");
|
|
18
|
+
if (key) {
|
|
19
|
+
// Join values back together in case the value contained = signs
|
|
20
|
+
params[key.trim()] = values.join("=");
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
// Validate and return
|
|
24
|
+
const parsed = CsiUriQuerySchema.parse(params);
|
|
25
|
+
return parsed;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
*@description Converts pixel log data to conversion format
|
|
29
|
+
* @param {MappedDataRow} mappedRow - Raw mapped data
|
|
30
|
+
* @param {CsiUriQuery} csiUriQuery - Parsed URI query parameters
|
|
31
|
+
*/
|
|
32
|
+
const pixelLog = (mappedRow, csiUriQuery) => {
|
|
33
|
+
const conversion = {
|
|
34
|
+
created_at: `${new Date(mappedRow.partition_date).toISOString().split("T")[0]} ${mappedRow.hour}:00`,
|
|
35
|
+
date: new Date(mappedRow.partition_date).toISOString().split("T")[0] ?? "",
|
|
36
|
+
idorder: mappedRow.idorder,
|
|
37
|
+
revenue: csiUriQuery.revenue,
|
|
38
|
+
currency: csiUriQuery.currency,
|
|
39
|
+
parent_idv: csiUriQuery._idv,
|
|
40
|
+
_idv: csiUriQuery._idv,
|
|
41
|
+
nginxLogs: true,
|
|
42
|
+
};
|
|
43
|
+
return conversion;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* @description Processes mapped data and writes to JSON files grouped by date
|
|
47
|
+
* @param {MappedDataRow[]} mappedData - Data to be processed
|
|
48
|
+
* @param {string} directory - Output directory for files
|
|
49
|
+
* @returns {Promise<string[]>} Array of created filenames
|
|
50
|
+
*/
|
|
51
|
+
export async function processToJson(mappedData, directory) {
|
|
52
|
+
console.log(`Processing ${mappedData.length} rows to directory: ${directory}`);
|
|
53
|
+
const fileNames = [];
|
|
54
|
+
try {
|
|
55
|
+
// Group data by date
|
|
56
|
+
const dateGroup = mappedData.reduce((acc, row) => {
|
|
57
|
+
const csiUriQuery = parseCsiUriQuery(row.cs_uri_query);
|
|
58
|
+
const log = pixelLog(row, csiUriQuery);
|
|
59
|
+
// biome-ignore lint/style/noNonNullAssertion: <explanation>
|
|
60
|
+
const date = log.created_at.split(" ")[0];
|
|
61
|
+
// ignore log if idorder is empty or _idv is empty or idv value is undefined or revenue cannot be parsed as number
|
|
62
|
+
if (!log.idorder ||
|
|
63
|
+
log.idorder === "undefined" ||
|
|
64
|
+
!log._idv ||
|
|
65
|
+
log._idv === "undefined" ||
|
|
66
|
+
!log.revenue ||
|
|
67
|
+
Number.isNaN(Number(log.revenue))) {
|
|
68
|
+
return acc;
|
|
69
|
+
}
|
|
70
|
+
if (!acc[date]) {
|
|
71
|
+
acc[date] = [];
|
|
72
|
+
}
|
|
73
|
+
// biome-ignore lint/style/noNonNullAssertion: <explanation>
|
|
74
|
+
acc[date].push(log);
|
|
75
|
+
return acc;
|
|
76
|
+
}, {});
|
|
77
|
+
console.log(`Grouped data into ${Object.keys(dateGroup).length} dates`);
|
|
78
|
+
const jsonFileAppenderPromises = Object.entries(dateGroup).map(async ([date, data]) => {
|
|
79
|
+
const filename = `conversion_${date}.json`;
|
|
80
|
+
console.log(`Processing ${date}: ${data.length} records`);
|
|
81
|
+
fileNames.push(filename);
|
|
82
|
+
const jsonFileAppender = new JsonFileAppender({
|
|
83
|
+
fileName: filename,
|
|
84
|
+
directory: directory,
|
|
85
|
+
});
|
|
86
|
+
await jsonFileAppender.flush(data);
|
|
87
|
+
console.log(`Completed writing ${filename}`);
|
|
88
|
+
});
|
|
89
|
+
await Promise.all(jsonFileAppenderPromises);
|
|
90
|
+
console.log("All files processed successfully");
|
|
91
|
+
return fileNames;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
console.error("Error in processToJson:", error);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED