@tmlmobilidade/go-utils-exec 20260905.126.6 → 20260905.1222.34
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.
|
@@ -16,46 +16,55 @@ import { getDirectoryFiles } from './get-directory-files.js';
|
|
|
16
16
|
export async function getZipFileHash(filePath) {
|
|
17
17
|
//
|
|
18
18
|
//
|
|
19
|
-
// Initialize a new temporary directory
|
|
19
|
+
// Initialize a new temporary directory
|
|
20
20
|
const temporaryDirectory = fs.mkdtempDisposableSync('get-zip-file-hash-');
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
21
|
+
try {
|
|
22
|
+
//
|
|
23
|
+
//
|
|
24
|
+
// Extract the ZIP file into the temporary directory.
|
|
25
|
+
await fs
|
|
26
|
+
.createReadStream(filePath)
|
|
27
|
+
.pipe(unzipper.Extract({ path: temporaryDirectory.path }))
|
|
28
|
+
.promise();
|
|
29
|
+
//
|
|
30
|
+
// Find all extracted files.
|
|
31
|
+
const sortedExtractedFilePaths = await getDirectoryFiles(temporaryDirectory.path);
|
|
32
|
+
//
|
|
33
|
+
// Initialize the list of files to hash.
|
|
34
|
+
const foundFiles = [];
|
|
35
|
+
for (const absolutePath of sortedExtractedFilePaths) {
|
|
36
|
+
// Create a new hash for the file
|
|
37
|
+
const hash = createHash('sha256');
|
|
38
|
+
// Open a read stream for the file.
|
|
39
|
+
const stream = fs.createReadStream(absolutePath);
|
|
40
|
+
// Stream the file contents and calculate the SHA-256 hash.
|
|
41
|
+
for await (const chunk of stream) {
|
|
42
|
+
hash.update(chunk);
|
|
43
|
+
}
|
|
44
|
+
// Add the file to the list of files to hash.
|
|
45
|
+
const relativeFilePath = path.relative(temporaryDirectory.path, absolutePath);
|
|
46
|
+
foundFiles.push({ hash: hash.digest('hex'), path: relativeFilePath });
|
|
47
|
+
}
|
|
48
|
+
//
|
|
49
|
+
// Make the result independent of the order of entries in the zip file.
|
|
50
|
+
foundFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
51
|
+
//
|
|
52
|
+
// Clean up the temporary directory.
|
|
53
|
+
temporaryDirectory.remove();
|
|
54
|
+
//
|
|
55
|
+
// Calculate the final hash by concatenating the sorted list
|
|
56
|
+
// of filenames and individual file hashes.
|
|
57
|
+
const finalHash = createHash('sha256');
|
|
58
|
+
for (const file of foundFiles) {
|
|
59
|
+
finalHash.update(file.path);
|
|
60
|
+
finalHash.update('\0');
|
|
61
|
+
finalHash.update(file.hash);
|
|
62
|
+
finalHash.update('\0');
|
|
39
63
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
foundFiles.push({ hash: hash.digest('hex'), path: relativeFilePath });
|
|
64
|
+
return finalHash.digest('hex');
|
|
65
|
+
//
|
|
43
66
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
foundFiles.sort((a, b) => a.path.localeCompare(b.path));
|
|
47
|
-
//
|
|
48
|
-
// Clean up the temporary directory.
|
|
49
|
-
temporaryDirectory.remove();
|
|
50
|
-
//
|
|
51
|
-
// Calculate the final hash by concatenating the sorted list
|
|
52
|
-
// of filenames and individual file hashes.
|
|
53
|
-
const finalHash = createHash('sha256');
|
|
54
|
-
for (const file of foundFiles) {
|
|
55
|
-
finalHash.update(file.path);
|
|
56
|
-
finalHash.update('\0');
|
|
57
|
-
finalHash.update(file.hash);
|
|
58
|
-
finalHash.update('\0');
|
|
67
|
+
finally {
|
|
68
|
+
temporaryDirectory.remove();
|
|
59
69
|
}
|
|
60
|
-
return finalHash.digest('hex');
|
|
61
70
|
}
|
|
@@ -8,6 +8,13 @@ import fs from 'fs';
|
|
|
8
8
|
* @returns A promise that resolves when the stream is closed.
|
|
9
9
|
*/
|
|
10
10
|
export async function streamCsvFile(filePath, rowParser) {
|
|
11
|
+
//
|
|
12
|
+
//
|
|
13
|
+
// Check if the file exists,
|
|
14
|
+
// throw an error if it doesn't.
|
|
15
|
+
await fs.promises.access(filePath);
|
|
16
|
+
//
|
|
17
|
+
// Initialize the CSV parser.
|
|
11
18
|
const parser = csvParser({
|
|
12
19
|
bom: true,
|
|
13
20
|
cast: value => value === '' ? undefined : value,
|
|
@@ -17,6 +24,9 @@ export async function streamCsvFile(filePath, rowParser) {
|
|
|
17
24
|
skipRecordsWithEmptyValues: true,
|
|
18
25
|
trim: true,
|
|
19
26
|
});
|
|
27
|
+
//
|
|
28
|
+
// Open the file stream and pipe it to the parser,
|
|
29
|
+
// calling the row parser for each row.
|
|
20
30
|
const fileStream = fs.createReadStream(filePath);
|
|
21
31
|
const stream = fileStream.pipe(parser);
|
|
22
32
|
for await (const rowData of stream) {
|
package/dist/lifecycle/index.js
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface StartHeartbeatParams {
|
|
2
|
+
intervalMs: number;
|
|
3
|
+
runFn: () => Promise<void>;
|
|
4
|
+
}
|
|
5
|
+
interface StartHeartbeatReturnType {
|
|
6
|
+
stop: () => void;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Starts a heartbeat to indicate that an operation is still being processed.
|
|
10
|
+
* @param operationId The ID of the operation to heartbeat.
|
|
11
|
+
* @returns An object with a `stop` method to stop the heartbeat.
|
|
12
|
+
*/
|
|
13
|
+
export declare function startHeartbeat({ intervalMs, runFn }: StartHeartbeatParams): StartHeartbeatReturnType;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/* * */
|
|
2
|
+
/**
|
|
3
|
+
* Starts a heartbeat to indicate that an operation is still being processed.
|
|
4
|
+
* @param operationId The ID of the operation to heartbeat.
|
|
5
|
+
* @returns An object with a `stop` method to stop the heartbeat.
|
|
6
|
+
*/
|
|
7
|
+
export function startHeartbeat({ intervalMs, runFn }) {
|
|
8
|
+
//
|
|
9
|
+
let isStopped = false;
|
|
10
|
+
let timer;
|
|
11
|
+
const tick = async () => {
|
|
12
|
+
// Skip if the heartbeat is stopped
|
|
13
|
+
if (isStopped)
|
|
14
|
+
return;
|
|
15
|
+
// Run the function
|
|
16
|
+
await runFn();
|
|
17
|
+
// Schedule the next heartbeat
|
|
18
|
+
if (!isStopped)
|
|
19
|
+
timer = setTimeout(tick, intervalMs);
|
|
20
|
+
};
|
|
21
|
+
//
|
|
22
|
+
// Start the heartbeat
|
|
23
|
+
void tick();
|
|
24
|
+
//
|
|
25
|
+
// Return the stop function
|
|
26
|
+
return {
|
|
27
|
+
stop: () => {
|
|
28
|
+
isStopped = true;
|
|
29
|
+
if (timer)
|
|
30
|
+
clearTimeout(timer);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|