@quatrain/worker 1.2.3 → 1.2.5

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.
@@ -1,9 +1,45 @@
1
1
  import { FileType } from '@quatrain/storage';
2
+ /**
3
+ * Utility class providing synchronous and asynchronous file system operations
4
+ * specifically tailored for the worker environment (e.g., managing temp folders, downloading remote files).
5
+ */
2
6
  export declare class FileSystem {
7
+ /**
8
+ * Prepares a clean processing directory, creating it along with required subdirectories (`images`, `vecto`).
9
+ * Any existing folder with the same name will be deleted first.
10
+ *
11
+ * @param folder - The base directory path to set up.
12
+ */
3
13
  static prepare(folder: string): void;
14
+ /**
15
+ * Synchronously creates a single directory.
16
+ *
17
+ * @param folder - The directory path.
18
+ */
4
19
  static makeFolder(folder: string): void;
20
+ /**
21
+ * Recursively and synchronously removes a folder and its entire contents.
22
+ *
23
+ * @param folder - The target directory to destroy.
24
+ * @param recursively - Whether to traverse and delete nested folders. Defaults to true.
25
+ * @throws {Error} If `recursively` is false but nested folders are encountered.
26
+ */
5
27
  static removeFolder(folder: string, recursively?: boolean): void;
28
+ /**
29
+ * Downloads a file from an external HTTP/HTTPS URL into the local filesystem.
30
+ *
31
+ * @param url - The remote resource URL.
32
+ * @param filepath - The local destination path.
33
+ * @returns A promise resolving when the download finishes.
34
+ * @throws {Error} If the HTTP request or stream fails.
35
+ */
6
36
  static downloadFile(url: string, filepath: string): Promise<unknown>;
37
+ /**
38
+ * Sanitizes a string to be used safely as a filename by replacing spaces with underscores.
39
+ *
40
+ * @param name - The original string.
41
+ * @returns The sanitized string.
42
+ */
7
43
  static safeString(name: string): string;
8
44
  /**
9
45
  * Upload file to public URL and return meta data
@@ -43,7 +43,17 @@ const axios_1 = __importDefault(require("axios"));
43
43
  const Worker_1 = require("./Worker");
44
44
  const node_fetch_native_1 = __importDefault(require("node-fetch-native"));
45
45
  const ffmpeg = __importStar(require("fluent-ffmpeg"));
46
+ /**
47
+ * Utility class providing synchronous and asynchronous file system operations
48
+ * specifically tailored for the worker environment (e.g., managing temp folders, downloading remote files).
49
+ */
46
50
  class FileSystem {
51
+ /**
52
+ * Prepares a clean processing directory, creating it along with required subdirectories (`images`, `vecto`).
53
+ * Any existing folder with the same name will be deleted first.
54
+ *
55
+ * @param folder - The base directory path to set up.
56
+ */
47
57
  static prepare(folder) {
48
58
  Worker_1.Worker.debug(`Setting up process folder ${folder}`);
49
59
  this.removeFolder(folder);
@@ -51,9 +61,21 @@ class FileSystem {
51
61
  node_fs_1.default.mkdirSync(folder + node_path_1.default.sep + 'images');
52
62
  node_fs_1.default.mkdirSync(folder + node_path_1.default.sep + 'vecto');
53
63
  }
64
+ /**
65
+ * Synchronously creates a single directory.
66
+ *
67
+ * @param folder - The directory path.
68
+ */
54
69
  static makeFolder(folder) {
55
70
  node_fs_1.default.mkdirSync(folder);
56
71
  }
72
+ /**
73
+ * Recursively and synchronously removes a folder and its entire contents.
74
+ *
75
+ * @param folder - The target directory to destroy.
76
+ * @param recursively - Whether to traverse and delete nested folders. Defaults to true.
77
+ * @throws {Error} If `recursively` is false but nested folders are encountered.
78
+ */
57
79
  static removeFolder(folder, recursively = true) {
58
80
  if (node_fs_1.default.existsSync(folder)) {
59
81
  node_fs_1.default.readdirSync(folder).forEach((element) => {
@@ -71,6 +93,14 @@ class FileSystem {
71
93
  node_fs_1.default.rmdirSync(folder);
72
94
  }
73
95
  }
96
+ /**
97
+ * Downloads a file from an external HTTP/HTTPS URL into the local filesystem.
98
+ *
99
+ * @param url - The remote resource URL.
100
+ * @param filepath - The local destination path.
101
+ * @returns A promise resolving when the download finishes.
102
+ * @throws {Error} If the HTTP request or stream fails.
103
+ */
74
104
  static async downloadFile(url, filepath) {
75
105
  try {
76
106
  Worker_1.Worker.debug(`Downloading file at ${url} to ${filepath}`);
@@ -89,6 +119,12 @@ class FileSystem {
89
119
  throw err;
90
120
  }
91
121
  }
122
+ /**
123
+ * Sanitizes a string to be used safely as a filename by replacing spaces with underscores.
124
+ *
125
+ * @param name - The original string.
126
+ * @returns The sanitized string.
127
+ */
92
128
  static safeString(name) {
93
129
  return name.replaceAll(/\s+/g, '_');
94
130
  }
package/dist/Helpers.d.ts CHANGED
@@ -1,5 +1,9 @@
1
+ /**
2
+ * General utility class providing common static helpers for workers.
3
+ */
1
4
  export declare class Helpers {
2
- static FFMPEG: string;
5
+ /** Default absolute path to the system's FFmpeg binary. */
6
+ static FFMPEG: Promise<string>;
3
7
  /**
4
8
  * Generate a thubnail from a video file at given frame position
5
9
  * @param videoPath path to video file
package/dist/Helpers.js CHANGED
@@ -2,8 +2,12 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Helpers = void 0;
4
4
  const Worker_1 = require("./Worker");
5
+ /**
6
+ * General utility class providing common static helpers for workers.
7
+ */
5
8
  class Helpers {
6
- static FFMPEG = '/usr/bin/ffmpeg';
9
+ /** Default absolute path to the system's FFmpeg binary. */
10
+ static FFMPEG = Worker_1.Worker.getSystemCommandPath('ffmpeg');
7
11
  /**
8
12
  * Generate a thubnail from a video file at given frame position
9
13
  * @param videoPath path to video file
@@ -28,7 +32,7 @@ class Helpers {
28
32
  '-y',
29
33
  ];
30
34
  Worker_1.Worker.info(`Generating Thumbnail : ${outputPath}`);
31
- return await Worker_1.Worker.execPromise(Helpers.FFMPEG, ffmpegParams);
35
+ return await Worker_1.Worker.execPromise(await Helpers.FFMPEG, ffmpegParams);
32
36
  };
33
37
  }
34
38
  exports.Helpers = Helpers;
package/dist/Worker.d.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  import { Core } from '@quatrain/core';
2
2
  import { HandlerParameters } from './types/HandlerParameters';
3
+ /**
4
+ * The core orchestration class for background task workers.
5
+ * Manages event reporting, child process execution, and queue listening.
6
+ */
3
7
  export declare class Worker extends Core {
8
+ /** The HTTP endpoint used to push worker status events. */
4
9
  static endpoint: string;
10
+ /** Dedicated logger instance for the worker subsystem. */
5
11
  static readonly logger: any;
6
12
  /**
7
13
  * Execute an external command in a promise
package/dist/Worker.js CHANGED
@@ -8,8 +8,14 @@ const core_1 = require("@quatrain/core");
8
8
  const node_os_1 = __importDefault(require("node:os"));
9
9
  const axios_1 = __importDefault(require("axios"));
10
10
  const node_child_process_1 = require("node:child_process");
11
+ /**
12
+ * The core orchestration class for background task workers.
13
+ * Manages event reporting, child process execution, and queue listening.
14
+ */
11
15
  class Worker extends core_1.Core {
16
+ /** The HTTP endpoint used to push worker status events. */
12
17
  static endpoint = '';
18
+ /** Dedicated logger instance for the worker subsystem. */
13
19
  static logger = this.addLogger('Worker');
14
20
  /**
15
21
  * Execute an external command in a promise
@@ -8,7 +8,7 @@ const axios_1 = __importDefault(require("axios"));
8
8
  const node_child_process_1 = require("node:child_process");
9
9
  // Mock dependencies
10
10
  jest.mock('axios');
11
- jest.mock('child_process');
11
+ jest.mock('node:child_process');
12
12
  const mockedAxios = axios_1.default;
13
13
  const mockedSpawn = node_child_process_1.spawn;
14
14
  describe('Worker', () => {
@@ -153,6 +153,7 @@ describe('Worker', () => {
153
153
  await expect(Worker_1.Worker.execPromise('ls', ['-la'], '/tmp')).resolves.toBeUndefined();
154
154
  expect(mockedSpawn).toHaveBeenCalledWith('ls', ['-la'], {
155
155
  cwd: '/tmp',
156
+ shell: false,
156
157
  });
157
158
  });
158
159
  it('should reject on command failure', async () => {
@@ -191,6 +192,7 @@ describe('Worker', () => {
191
192
  await Worker_1.Worker.execPromise('echo', ['test']);
192
193
  expect(mockedSpawn).toHaveBeenCalledWith('echo', ['test'], {
193
194
  cwd: process.cwd(),
195
+ shell: false,
194
196
  });
195
197
  });
196
198
  it('should pass arguments to command', async () => {
@@ -208,6 +210,7 @@ describe('Worker', () => {
208
210
  await Worker_1.Worker.execPromise('command', args, '/custom/path');
209
211
  expect(mockedSpawn).toHaveBeenCalledWith('command', args, {
210
212
  cwd: '/custom/path',
213
+ shell: false,
211
214
  });
212
215
  });
213
216
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quatrain/worker",
3
- "version": "1.2.3",
3
+ "version": "1.2.5",
4
4
  "description": "Container Worker helpers",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -34,9 +34,9 @@
34
34
  "typescript": "^5.1.5"
35
35
  },
36
36
  "dependencies": {
37
- "@quatrain/core": "^1.2.5",
38
- "@quatrain/queue": "^1.2.2",
39
- "@quatrain/storage": "^1.2.3",
37
+ "@quatrain/core": "^1.2.9",
38
+ "@quatrain/queue": "^1.2.3",
39
+ "@quatrain/storage": "^1.2.8",
40
40
  "axios": "^1.7.7",
41
41
  "fluent-ffmpeg": "^2.1.2",
42
42
  "fs-extra": "^11.2.0",
package/src/FileSystem.ts CHANGED
@@ -6,7 +6,17 @@ import fetch from 'node-fetch-native'
6
6
  import * as ffmpeg from 'fluent-ffmpeg'
7
7
  import { FileType } from '@quatrain/storage'
8
8
 
9
+ /**
10
+ * Utility class providing synchronous and asynchronous file system operations
11
+ * specifically tailored for the worker environment (e.g., managing temp folders, downloading remote files).
12
+ */
9
13
  export class FileSystem {
14
+ /**
15
+ * Prepares a clean processing directory, creating it along with required subdirectories (`images`, `vecto`).
16
+ * Any existing folder with the same name will be deleted first.
17
+ *
18
+ * @param folder - The base directory path to set up.
19
+ */
10
20
  static prepare(folder: string) {
11
21
  Worker.debug(`Setting up process folder ${folder}`)
12
22
  this.removeFolder(folder)
@@ -16,10 +26,22 @@ export class FileSystem {
16
26
  fs.mkdirSync(folder + path.sep + 'vecto')
17
27
  }
18
28
 
29
+ /**
30
+ * Synchronously creates a single directory.
31
+ *
32
+ * @param folder - The directory path.
33
+ */
19
34
  static makeFolder(folder: string) {
20
35
  fs.mkdirSync(folder)
21
36
  }
22
37
 
38
+ /**
39
+ * Recursively and synchronously removes a folder and its entire contents.
40
+ *
41
+ * @param folder - The target directory to destroy.
42
+ * @param recursively - Whether to traverse and delete nested folders. Defaults to true.
43
+ * @throws {Error} If `recursively` is false but nested folders are encountered.
44
+ */
23
45
  static removeFolder(folder: string, recursively = true) {
24
46
  if (fs.existsSync(folder)) {
25
47
  fs.readdirSync(folder).forEach((element) => {
@@ -38,6 +60,14 @@ export class FileSystem {
38
60
  }
39
61
  }
40
62
 
63
+ /**
64
+ * Downloads a file from an external HTTP/HTTPS URL into the local filesystem.
65
+ *
66
+ * @param url - The remote resource URL.
67
+ * @param filepath - The local destination path.
68
+ * @returns A promise resolving when the download finishes.
69
+ * @throws {Error} If the HTTP request or stream fails.
70
+ */
41
71
  static async downloadFile(url: string, filepath: string) {
42
72
  try {
43
73
  Worker.debug(`Downloading file at ${url} to ${filepath}`)
@@ -58,6 +88,12 @@ export class FileSystem {
58
88
  }
59
89
  }
60
90
 
91
+ /**
92
+ * Sanitizes a string to be used safely as a filename by replacing spaces with underscores.
93
+ *
94
+ * @param name - The original string.
95
+ * @returns The sanitized string.
96
+ */
61
97
  static safeString(name: string) {
62
98
  return name.replaceAll(/\s+/g, '_')
63
99
  }
package/src/Helpers.ts CHANGED
@@ -1,8 +1,12 @@
1
1
  import { Worker } from './Worker'
2
2
  import path from 'node:path'
3
3
 
4
+ /**
5
+ * General utility class providing common static helpers for workers.
6
+ */
4
7
  export class Helpers {
5
- static FFMPEG = '/usr/bin/ffmpeg'
8
+ /** Default absolute path to the system's FFmpeg binary. */
9
+ static FFMPEG = Worker.getSystemCommandPath('ffmpeg')
6
10
 
7
11
  /**
8
12
  * Generate a thubnail from a video file at given frame position
@@ -35,6 +39,6 @@ export class Helpers {
35
39
 
36
40
  Worker.info(`Generating Thumbnail : ${outputPath}`)
37
41
 
38
- return await Worker.execPromise(Helpers.FFMPEG, ffmpegParams)
42
+ return await Worker.execPromise(await Helpers.FFMPEG, ffmpegParams)
39
43
  }
40
44
  }
@@ -4,7 +4,7 @@ import { spawn } from 'node:child_process'
4
4
 
5
5
  // Mock dependencies
6
6
  jest.mock('axios')
7
- jest.mock('child_process')
7
+ jest.mock('node:child_process')
8
8
 
9
9
  const mockedAxios = axios as jest.Mocked<typeof axios>
10
10
  const mockedSpawn = spawn as jest.MockedFunction<typeof spawn>
@@ -209,6 +209,7 @@ describe('Worker', () => {
209
209
 
210
210
  expect(mockedSpawn).toHaveBeenCalledWith('ls', ['-la'], {
211
211
  cwd: '/tmp',
212
+ shell: false,
212
213
  })
213
214
  })
214
215
 
@@ -256,6 +257,7 @@ describe('Worker', () => {
256
257
 
257
258
  expect(mockedSpawn).toHaveBeenCalledWith('echo', ['test'], {
258
259
  cwd: process.cwd(),
260
+ shell: false,
259
261
  })
260
262
  })
261
263
 
@@ -277,6 +279,7 @@ describe('Worker', () => {
277
279
 
278
280
  expect(mockedSpawn).toHaveBeenCalledWith('command', args, {
279
281
  cwd: '/custom/path',
282
+ shell: false,
280
283
  })
281
284
  })
282
285
  })
package/src/Worker.ts CHANGED
@@ -4,8 +4,14 @@ import axios from 'axios'
4
4
  import { spawn } from 'node:child_process'
5
5
  import { HandlerParameters } from './types/HandlerParameters'
6
6
 
7
+ /**
8
+ * The core orchestration class for background task workers.
9
+ * Manages event reporting, child process execution, and queue listening.
10
+ */
7
11
  export class Worker extends Core {
12
+ /** The HTTP endpoint used to push worker status events. */
8
13
  static endpoint: string = ''
14
+ /** Dedicated logger instance for the worker subsystem. */
9
15
  static readonly logger = this.addLogger('Worker')
10
16
 
11
17
  /**