@social-mail/social-mail-web-server 1.7.6 → 1.7.7

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 (55) hide show
  1. package/dist/common/spawnPromise.js +3 -3
  2. package/dist/common/spawnPromise.js.map +1 -1
  3. package/dist/isolated/FileInfo.d.ts +9 -0
  4. package/dist/isolated/FileInfo.d.ts.map +1 -0
  5. package/dist/isolated/FileInfo.js +11 -0
  6. package/dist/isolated/FileInfo.js.map +1 -0
  7. package/dist/isolated/IsolatedProcess.d.ts +11 -0
  8. package/dist/isolated/IsolatedProcess.d.ts.map +1 -0
  9. package/dist/isolated/IsolatedProcess.js +26 -0
  10. package/dist/isolated/IsolatedProcess.js.map +1 -0
  11. package/dist/isolated/extract/IExtract.d.ts +9 -0
  12. package/dist/isolated/extract/IExtract.d.ts.map +1 -0
  13. package/dist/isolated/extract/IExtract.js +2 -0
  14. package/dist/isolated/extract/IExtract.js.map +1 -0
  15. package/dist/isolated/extract/index.d.ts +7 -0
  16. package/dist/isolated/extract/index.d.ts.map +1 -0
  17. package/dist/isolated/extract/index.js +51 -0
  18. package/dist/isolated/extract/index.js.map +1 -0
  19. package/dist/isolated/image-converter/IImageConverter.d.ts +11 -0
  20. package/dist/isolated/image-converter/IImageConverter.d.ts.map +1 -0
  21. package/dist/isolated/image-converter/IImageConverter.js +2 -0
  22. package/dist/isolated/image-converter/IImageConverter.js.map +1 -0
  23. package/dist/isolated/image-converter/formats/size.d.ts +5 -0
  24. package/dist/isolated/image-converter/formats/size.d.ts.map +1 -0
  25. package/dist/{server/services → isolated}/image-converter/formats/size.js +1 -0
  26. package/dist/isolated/image-converter/formats/size.js.map +1 -0
  27. package/dist/isolated/image-converter/index.d.ts +2 -0
  28. package/dist/isolated/image-converter/index.d.ts.map +1 -0
  29. package/dist/isolated/image-converter/index.js +59 -0
  30. package/dist/isolated/image-converter/index.js.map +1 -0
  31. package/dist/server/services/convert/FileConversionService.d.ts.map +1 -1
  32. package/dist/server/services/convert/FileConversionService.js +1 -1
  33. package/dist/server/services/convert/FileConversionService.js.map +1 -1
  34. package/dist/server/services/extract/Extract.d.ts.map +1 -1
  35. package/dist/server/services/extract/Extract.js +3 -53
  36. package/dist/server/services/extract/Extract.js.map +1 -1
  37. package/dist/server/services/image-converter/ImageConverterService.d.ts.map +1 -1
  38. package/dist/server/services/image-converter/ImageConverterService.js +7 -22
  39. package/dist/server/services/image-converter/ImageConverterService.js.map +1 -1
  40. package/dist/tsconfig.tsbuildinfo +1 -1
  41. package/package.json +1 -1
  42. package/src/common/spawnPromise.ts +3 -3
  43. package/src/isolated/FileInfo.ts +13 -0
  44. package/src/isolated/IsolatedProcess.ts +33 -0
  45. package/src/isolated/extract/IExtract.ts +4 -0
  46. package/src/isolated/extract/index.ts +59 -0
  47. package/src/isolated/image-converter/IImageConverter.ts +6 -0
  48. package/src/{server/services → isolated}/image-converter/formats/size.ts +1 -2
  49. package/src/isolated/image-converter/index.ts +73 -0
  50. package/src/server/services/convert/FileConversionService.ts +1 -1
  51. package/src/server/services/extract/Extract.ts +3 -48
  52. package/src/server/services/image-converter/ImageConverterService.ts +10 -25
  53. package/dist/server/services/image-converter/formats/size.d.ts +0 -4
  54. package/dist/server/services/image-converter/formats/size.d.ts.map +0 -1
  55. package/dist/server/services/image-converter/formats/size.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@social-mail/social-mail-web-server",
3
- "version": "1.7.6",
3
+ "version": "1.7.7",
4
4
  "description": "## Phase 1",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -31,10 +31,10 @@ export const spawnPromise = (path, args?: string[], options?: SpawnOptionsWithou
31
31
  });
32
32
  cd.on("close", (status) => {
33
33
  if (status>0) {
34
+ if (logError) {
35
+ console.error(all);
36
+ }
34
37
  if (throwOnFail) {
35
- if (logError) {
36
- console.error(all);
37
- }
38
38
  reject(new Error(all.join("\n")));
39
39
  return;
40
40
  }
@@ -0,0 +1,13 @@
1
+ import { LocalFile } from "@entity-access/server-pages/dist/core/LocalFile.js";
2
+
3
+ export default class FileInfo {
4
+
5
+
6
+ public static from(file: LocalFile) {
7
+ return new FileInfo(file.path, file.contentType, file.fileName);
8
+ }
9
+
10
+ constructor(public readonly path: string, public readonly contentType: string, public readonly fileName: string) {
11
+
12
+ }
13
+ }
@@ -0,0 +1,33 @@
1
+ import { fileURLToPath } from "url";
2
+ import { spawnPromise } from "../common/spawnPromise.js";
3
+ import FileInfo from "./FileInfo.js";
4
+ import IImageConverter from "./image-converter/IImageConverter.js";
5
+ import IExtract from "./extract/IExtract.js";
6
+
7
+ export default class IsolatedProcess {
8
+
9
+ static async convertImage(p: IImageConverter) {
10
+ return spawnPromise(process.execPath, [
11
+ "--enable-source-maps",
12
+ fileURLToPath(import.meta.resolve("./image-converter/index.js")),
13
+ JSON.stringify(p),
14
+ ], {
15
+ logCommand: false,
16
+ logError: true
17
+ });
18
+ }
19
+
20
+ static async extractText(p: IExtract) {
21
+ const result = await spawnPromise(process.execPath, [
22
+ "--enable-source-maps",
23
+ fileURLToPath(import.meta.resolve("./extract/index.js")),
24
+ JSON.stringify(p),
25
+ ], {
26
+ logCommand: false,
27
+ logError: true
28
+ });
29
+
30
+ return result.all;
31
+ }
32
+
33
+ }
@@ -0,0 +1,4 @@
1
+ export default interface IExtract {
2
+ input: { contentType, fileName, path },
3
+ useOcr: boolean;
4
+ }
@@ -0,0 +1,59 @@
1
+ /* eslint-disable no-console */
2
+ import { readFile } from "fs/promises";
3
+ import tesseract from "tesseract.js";
4
+ import FileInfo from "../FileInfo.js";
5
+ import IExtract from "./IExtract.js";
6
+ const { recognize } = tesseract;
7
+
8
+ export class ExtractWorker {
9
+ static async text({ input: file, useOcr }: IExtract) {
10
+ try {
11
+ if (/^image\//.test(file.contentType)) {
12
+ if (useOcr) {
13
+ return this.ocr(file);
14
+ }
15
+ }
16
+
17
+ return await readFile(file.path, "utf8");
18
+ } catch (error) {
19
+ console.error(error);
20
+ }
21
+ return "";
22
+
23
+ }
24
+
25
+ static async ocr(file: FileInfo) {
26
+ try {
27
+ const buffer = await readFile(file.path);
28
+ const result = await recognize(buffer);
29
+ return result.data.text;
30
+ } catch (error) {
31
+ console.error(error);
32
+ }
33
+ return "";
34
+ }
35
+ };
36
+
37
+
38
+ const [execPath, self, p] = process.argv;
39
+
40
+
41
+ ExtractWorker.text(JSON.parse(p))
42
+ .then((r) => console.log(r))
43
+ .catch(console.error);
44
+
45
+
46
+ // parentPort.on("message", async ({ file, useOcr }) => {
47
+ // try {
48
+ // const result = await ExtractWorker.text(file, useOcr);
49
+ // parentPort.postMessage({ result });
50
+ // process.exit(0);
51
+ // } catch (error) {
52
+ // try {
53
+ // parentPort.postMessage({ error: error.stack ?? error.toString() });
54
+ // } catch (er1) {
55
+ // // we will ignore this.. we need to close process successfully.
56
+ // }
57
+ // process.exit(0);
58
+ // }
59
+ // });
@@ -0,0 +1,6 @@
1
+ export default interface IImageConverter {
2
+ type: string;
3
+ input: { path: string; },
4
+ output: { path: string;},
5
+ outputFileName: string;
6
+ }
@@ -1,8 +1,7 @@
1
1
  /* eslint-disable no-bitwise */
2
- import { LocalFile } from "@entity-access/server-pages/dist/core/LocalFile.js";
3
2
  import sharp from "sharp";
4
3
 
5
- export default async function (file: LocalFile, ... args: any[] ): Promise<sharp.Sharp> {
4
+ export default async function (file: { path: string }, ... args: any[] ): Promise<sharp.Sharp> {
6
5
 
7
6
  const size = {
8
7
  failOnError: false,
@@ -0,0 +1,73 @@
1
+ import sharp from "sharp";
2
+ import { parse } from "path";
3
+ import IImageConverter from "./IImageConverter.js";
4
+
5
+ async function transform({
6
+ type,
7
+ input,
8
+ output,
9
+ outputFileName = "file.jpg"
10
+ }: IImageConverter
11
+ ) {
12
+
13
+ let { ext } = parse(outputFileName);
14
+ let fileName = type;
15
+ const matches = type.match(/(\w+)\(([^\)]+)\)/);
16
+ let args = [];
17
+ if (matches) {
18
+ fileName = matches[1];
19
+ args = matches[2].split(',').map( (x) => parseFloat(x) );
20
+ switch(fileName) {
21
+ case "jpg":
22
+ ext = ".jpg";
23
+ fileName = "size";
24
+ break;
25
+ case "png":
26
+ ext = ".png";
27
+ fileName = "size";
28
+ break;
29
+ case "gif":
30
+ ext = ".gif";
31
+ fileName = "size";
32
+ break;
33
+ case "webp":
34
+ ext = ".webp";
35
+ fileName = "size";
36
+ break;
37
+ case "ico":
38
+ ext = ".ico";
39
+ fileName = "size";
40
+ break;
41
+ }
42
+ }
43
+
44
+ const { default: fx } = await import("./formats/" + fileName + ".js");
45
+ let r: sharp.Sharp = await fx(input, ... args);
46
+
47
+ switch(ext) {
48
+ case ".jpg":
49
+ r = r.jpeg({ quality: 95});
50
+ break;
51
+ case ".png":
52
+ r = r.png({
53
+ compressionLevel: 9
54
+ });
55
+ break;
56
+ case ".webp":
57
+ r = r.webp({
58
+ nearLossless: true,
59
+ quality: 95
60
+ });
61
+ break;
62
+ case ".gif":
63
+ r = r.gif();
64
+ break;
65
+ }
66
+
67
+ await r.toFile(output.path);
68
+ }
69
+
70
+ const [execPath, self, p] = process.argv;
71
+
72
+ transform(JSON.parse(p))
73
+ .catch(console.error);
@@ -2,7 +2,6 @@ import Inject, { RegisterScoped, ServiceProvider } from "@entity-access/entity-a
2
2
  import TempFileService from "../../storage/TempFileService.js";
3
3
  import { LocalFile } from "@entity-access/server-pages/dist/core/LocalFile.js";
4
4
  import { Convert } from "./Convert.js";
5
- import PdfDoc from "../extract/pdf/PdfDoc.js";
6
5
  import FFCommand from "./FFCommand.js";
7
6
  import AppFile from "../../model/entities/AppFile.js";
8
7
  import TimeSpan from "@entity-access/entity-access/dist/types/TimeSpan.js";
@@ -13,6 +12,7 @@ import Page from "@entity-access/server-pages/dist/Page.js";
13
12
  import StringFormat from "../../../common/StringFormat.js";
14
13
  import RateLimiterService from "../rate-limiter/RateLimiterService.js";
15
14
  import { globalEnv } from "../../../common/globalEnv.js";
15
+ import PdfDoc from "../extract/pdf/PdfDoc.js";
16
16
 
17
17
  interface IDownloadConvertedFile {
18
18
  appFile: AppFile;
@@ -6,10 +6,11 @@ import FileInfo from "./FileInfo.js";
6
6
  import { LocalFile } from "@entity-access/server-pages/dist/core/LocalFile.js";
7
7
  import TempFolder from "@entity-access/server-pages/dist/core/TempFolder.js";
8
8
  import { FileType } from "../../../common/FileType.js";
9
- import PdfDoc from "./pdf/PdfDoc.js";
10
9
  import { readFile } from "fs/promises";
11
10
  import { Convert } from "../convert/Convert.js";
12
11
  import LockFile from "../../storage/LockFile.js";
12
+ import PdfDoc from "./pdf/PdfDoc.js";
13
+ import IsolatedProcess from "../../../isolated/IsolatedProcess.js";
13
14
 
14
15
  export class Extract {
15
16
  static async text(src: LocalFile, useOcr = false) {
@@ -44,52 +45,6 @@ export class Extract {
44
45
 
45
46
  using lock = await LockFile.lock("extract-worker-lock");
46
47
 
47
- return await new Promise<string>((resolve, reject) => {
48
- let resolved = false;
49
- console.log(`Extracting text from ${file.path}`);
50
- const execArgv = ["--enable-source-maps"];
51
- if (process.argv.includes("--trace-deprecation")) {
52
- execArgv.push("--trace-deprecation");
53
- }
54
- const w = new Worker( dirname(fileURLToPath(import.meta.url)) + "/ExtractWorker.js",{
55
- execArgv,
56
- resourceLimits: {
57
- maxOldGenerationSizeMb: 1024
58
- }
59
- });
60
- w.on("message", ({ result, error }) => {
61
- if (resolved) {
62
- return;
63
- }
64
- if (result) {
65
- resolved = true;
66
- resolve(result);
67
- return;
68
- }
69
- if (error) {
70
- reject(error);
71
- }
72
- });
73
- w.on("error", (error) => {
74
- if(resolved) {
75
- return;
76
- }
77
- console.error(error);
78
- resolved = true;
79
- // reject(error);
80
- console.error(`Failed to extract text for ${src.fileName} ${error.stack ?? error}`);
81
- resolve("");
82
- });
83
- w.on("exit", (n) => {
84
- if (n>0) {
85
- if (resolved) {
86
- return;
87
- }
88
- resolved = true;
89
- reject(new Error(`Worker exited with ${n}`));
90
- }
91
- });
92
- w.postMessage({ file: { ... FileInfo.from(file)}, useOcr });
93
- });
48
+ return await IsolatedProcess.extractText({ input: { fileName: file.fileName, contentType: file.contentType, path: file.path }, useOcr });
94
49
  }
95
50
  };
@@ -1,6 +1,5 @@
1
1
  import Inject, { RegisterScoped } from "@entity-access/entity-access/dist/di/di.js";
2
2
  import TempFileService from "../../storage/TempFileService.js";
3
- import sharp from "sharp";
4
3
  import { join, parse } from "path";
5
4
  import { LocalFile } from "@entity-access/server-pages/dist/core/LocalFile.js";
6
5
  import { Convert } from "../convert/Convert.js";
@@ -9,6 +8,7 @@ import { spawnPromise } from "../../../common/spawnPromise.js";
9
8
  import { copyFile, readdir } from "fs/promises";
10
9
  import FFCommand from "../convert/FFCommand.js";
11
10
  import { ImagesFolder } from "../../../common/ImagesFolder.js";
11
+ import IsolatedProcess from "../../../isolated/IsolatedProcess.js";
12
12
 
13
13
  @RegisterScoped
14
14
  export default class ImageConverterService {
@@ -92,6 +92,7 @@ export default class ImageConverterService {
92
92
  async transform(type, file: LocalFile, outputFileName = "file.jpg") {
93
93
 
94
94
  let { ext } = parse(outputFileName);
95
+
95
96
  let fileName = type;
96
97
  const matches = type.match(/(\w+)\(([^\)]+)\)/);
97
98
  let args = [];
@@ -127,31 +128,15 @@ export default class ImageConverterService {
127
128
  file = ImagesFolder.localFile("png", "unavailable.png");
128
129
  }
129
130
 
130
- const { default: fx } = await import("./formats/" + fileName + ".js");
131
- let r: sharp.Sharp = await fx(file, ... args);
132
-
133
- switch(ext) {
134
- case ".jpg":
135
- r = r.jpeg({ quality: 95});
136
- break;
137
- case ".png":
138
- r = r.png({
139
- compressionLevel: 9
140
- });
141
- break;
142
- case ".webp":
143
- r = r.webp({
144
- nearLossless: true,
145
- quality: 95
146
- });
147
- break;
148
- case ".gif":
149
- r = r.gif();
150
- break;
151
- }
152
-
153
131
  const tf = await this.tempFileService.createTempFile(ext, outputFileName);
154
- await r.toFile(tf.path);
132
+
133
+ await IsolatedProcess.convertImage({
134
+ type,
135
+ input: { path: file.path },
136
+ output: { path: tf.path },
137
+ outputFileName
138
+ });
139
+
155
140
  return tf;
156
141
  }
157
142
 
@@ -1,4 +0,0 @@
1
- import { LocalFile } from "@entity-access/server-pages/dist/core/LocalFile.js";
2
- import sharp from "sharp";
3
- export default function (file: LocalFile, ...args: any[]): Promise<sharp.Sharp>;
4
- //# sourceMappingURL=size.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"size.d.ts","sourceRoot":"","sources":["../../../../../src/server/services/image-converter/formats/size.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oDAAoD,CAAC;AAC/E,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,yBAA+B,IAAI,EAAE,SAAS,EAAE,GAAI,IAAI,EAAE,GAAG,EAAE,GAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAmCtF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"size.js","sourceRoot":"","sources":["../../../../../src/server/services/image-converter/formats/size.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,CAAC,OAAO,CAAC,KAAK,WAAW,IAAe,EAAE,GAAI,IAAW;IAE3D,MAAM,IAAI,GAAG;QACT,WAAW,EAAE,KAAK;KACd,CAAC;IAET,IAAI,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC;QAExB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;YACf,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;QACpB,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,uCAAuC;YACvC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC;aAAM,CAAC;YACJ,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;YAC7B,uCAAuC;YACvC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;YACrB,uCAAuC;YACvC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;YACvB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC;QACvB,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;YACxC,OAAO,MAAO,KAAK,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAC,CAAS,CAAC;QACrE,CAAC;QACD,OAAO,MAAO,KAAK,CAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,EAAC,CAAS;aAC/D,MAAM,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;QAC1B,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;AACL,CAAC"}