fontastic 1.3.1 → 1.4.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.
Files changed (74) hide show
  1. package/.github/workflows/claude-code-review.yml +1 -1
  2. package/.github/workflows/claude.yml +1 -1
  3. package/.github/workflows/macos.yml +5 -5
  4. package/.github/workflows/release-please.yml +1 -1
  5. package/.github/workflows/release.yml +2 -2
  6. package/.github/workflows/ubuntu.yml +7 -7
  7. package/.github/workflows/windows.yml +5 -5
  8. package/.release-please-manifest.json +1 -1
  9. package/CHANGELOG.md +7 -0
  10. package/README.md +4 -4
  11. package/angular.json +8 -3
  12. package/app/core/FontFinder.js +17 -12
  13. package/app/core/FontFinder.ts +18 -12
  14. package/app/core/FontManager.js +13 -14
  15. package/app/core/FontManager.ts +12 -13
  16. package/app/core/MessageHandler.js +0 -1
  17. package/app/core/MessageHandler.ts +0 -4
  18. package/app/database/entity/Store.schema.js +1 -0
  19. package/app/database/entity/Store.schema.ts +1 -0
  20. package/app/database/repository/Collection.repository.js +0 -11
  21. package/app/database/repository/Collection.repository.ts +0 -22
  22. package/app/database/repository/Store.repository.js +50 -69
  23. package/app/database/repository/Store.repository.ts +47 -86
  24. package/app/enums/ChannelType.js +0 -1
  25. package/app/enums/ChannelType.ts +0 -1
  26. package/app/main.js +3 -2
  27. package/app/main.ts +3 -2
  28. package/app/package-lock.json +144 -1104
  29. package/app/package.json +4 -6
  30. package/app/preload.js +51 -0
  31. package/app/preload.ts +59 -0
  32. package/app/types/Bridge.js +3 -0
  33. package/app/types/Bridge.ts +19 -0
  34. package/app/types/index.js +1 -0
  35. package/app/types/index.ts +1 -0
  36. package/knip.json +18 -0
  37. package/package.json +44 -53
  38. package/src/app/app.component.spec.ts +3 -3
  39. package/src/app/app.component.ts +2 -15
  40. package/src/app/core/services/database/database.service.ts +8 -15
  41. package/src/app/core/services/electron/electron.service.ts +5 -46
  42. package/src/app/core/services/font-loader/font-loader.service.ts +60 -0
  43. package/src/app/core/services/index.ts +1 -0
  44. package/src/app/core/services/message/message.service.ts +19 -27
  45. package/src/app/core/services/presentation/presentation.service.ts +9 -2
  46. package/src/app/home/home.component.spec.ts +3 -3
  47. package/src/app/home/home.component.ts +4 -8
  48. package/src/app/layout/footer/footer.component.ts +6 -6
  49. package/src/app/shared/components/index.ts +0 -1
  50. package/src/app/shared/components/page-not-found/page-not-found.component.ts +2 -8
  51. package/src/app/shared/components/preview/preview.component.html +1 -0
  52. package/src/app/shared/components/preview/preview.component.ts +3 -31
  53. package/src/app/shared/components/rule-builder/rule-builder.component.html +4 -4
  54. package/src/app/shared/components/rule-builder/rule-builder.component.ts +13 -13
  55. package/src/app/shared/components/waterfall/waterfall.component.ts +1 -1
  56. package/src/app/shared/directives/index.ts +1 -1
  57. package/src/app/shared/directives/lazy-font/lazy-font.directive.ts +23 -0
  58. package/src/app/shared/shared.module.ts +3 -3
  59. package/src/main.ts +2 -2
  60. package/tsconfig.serve.json +4 -16
  61. package/app/helpers/command.js +0 -28
  62. package/app/helpers/command.ts +0 -20
  63. package/app/helpers/random.js +0 -16
  64. package/app/helpers/random.ts +0 -12
  65. package/src/app/shared/components/prompt-dialog/prompt-dialog.component.html +0 -36
  66. package/src/app/shared/components/prompt-dialog/prompt-dialog.component.ts +0 -40
  67. package/src/app/shared/directives/webview/webview.directive.spec.ts +0 -8
  68. package/src/app/shared/directives/webview/webview.directive.ts +0 -9
  69. package/src/styles/themes/dashboard.scss +0 -293
  70. package/src/styles/themes/euphoria.scss +0 -284
  71. package/src/styles/themes/mellow.scss +0 -281
  72. package/src/styles/themes/midnight.scss +0 -284
  73. package/src/styles/themes/passion.scss +0 -281
  74. package/src/styles/themes/swiss.scss +0 -284
@@ -22,7 +22,7 @@ jobs:
22
22
 
23
23
  steps:
24
24
  - name: Checkout repository
25
- uses: actions/checkout@v6
25
+ uses: actions/checkout@v7
26
26
  with:
27
27
  fetch-depth: 1
28
28
 
@@ -26,7 +26,7 @@ jobs:
26
26
  actions: read # Required for Claude to read CI results on PRs
27
27
  steps:
28
28
  - name: Checkout repository
29
- uses: actions/checkout@v6
29
+ uses: actions/checkout@v7
30
30
  with:
31
31
  fetch-depth: 1
32
32
 
@@ -24,10 +24,10 @@ jobs:
24
24
  runs-on: macos-latest
25
25
 
26
26
  steps:
27
- - uses: actions/checkout@v6
27
+ - uses: actions/checkout@v7
28
28
 
29
29
  - name: Cache Node modules
30
- uses: actions/cache@v5
30
+ uses: actions/cache@v6
31
31
  with:
32
32
  # npm cache files are stored in ~/.npm
33
33
  path: ~/.npm
@@ -36,7 +36,7 @@ jobs:
36
36
  ${{ runner.os }}-node-
37
37
 
38
38
  - name: Cache Electron binaries
39
- uses: actions/cache@v5
39
+ uses: actions/cache@v6
40
40
  with:
41
41
  path: |
42
42
  ~/Library/Caches/electron
@@ -51,7 +51,7 @@ jobs:
51
51
  node-version: ${{ matrix.node-version }}
52
52
 
53
53
  - name: Install Dependencies
54
- uses: nick-fields/retry@v3
54
+ uses: nick-fields/retry@v4
55
55
  with:
56
56
  timeout_minutes: 10
57
57
  max_attempts: 3
@@ -61,7 +61,7 @@ jobs:
61
61
  run: npm run lint
62
62
 
63
63
  - name: Install Playwright Browsers
64
- run: npx playwright@1.58.2 install --with-deps
64
+ run: npx playwright install --with-deps
65
65
 
66
66
  - name: Run headless unit test
67
67
  run: npm run test -- --reporters=default
@@ -18,7 +18,7 @@ jobs:
18
18
  release-please:
19
19
  runs-on: ubuntu-latest
20
20
  steps:
21
- - uses: googleapis/release-please-action@v4.4.0
21
+ - uses: googleapis/release-please-action@v5.0.0
22
22
  with:
23
23
  token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
24
24
  config-file: release-please-config.json
@@ -21,7 +21,7 @@ jobs:
21
21
  runs-on: ${{ matrix.os }}
22
22
  steps:
23
23
  - name: Checkout tag
24
- uses: actions/checkout@v6
24
+ uses: actions/checkout@v7
25
25
  with:
26
26
  ref: ${{ github.event.release.tag_name }}
27
27
 
@@ -37,7 +37,7 @@ jobs:
37
37
  sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf
38
38
 
39
39
  - name: Install dependencies
40
- uses: nick-fields/retry@v3
40
+ uses: nick-fields/retry@v4
41
41
  with:
42
42
  timeout_minutes: 10
43
43
  max_attempts: 3
@@ -22,13 +22,13 @@ jobs:
22
22
  node-version: [24]
23
23
 
24
24
  # The type of runner that the job will run on
25
- runs-on: ubuntu-22.04
25
+ runs-on: ubuntu-24.04
26
26
 
27
27
  steps:
28
- - uses: actions/checkout@v6
28
+ - uses: actions/checkout@v7
29
29
 
30
30
  - name: Cache Node modules
31
- uses: actions/cache@v5
31
+ uses: actions/cache@v6
32
32
  with:
33
33
  # npm cache files are stored in ~/.npm
34
34
  path: ~/.npm
@@ -37,7 +37,7 @@ jobs:
37
37
  ${{ runner.os }}-node-
38
38
 
39
39
  - name: Cache Electron binaries
40
- uses: actions/cache@v5
40
+ uses: actions/cache@v6
41
41
  with:
42
42
  path: |
43
43
  ~/.cache/electron
@@ -54,10 +54,10 @@ jobs:
54
54
  - name: Install linux dependencies
55
55
  run: |
56
56
  sudo apt-get update
57
- sudo apt-get install -y libgtk-3-dev webkit2gtk-4.0 libappindicator3-dev librsvg2-dev patchelf
57
+ sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev librsvg2-dev patchelf
58
58
 
59
59
  - name: Install Dependencies
60
- uses: nick-fields/retry@v3
60
+ uses: nick-fields/retry@v4
61
61
  with:
62
62
  timeout_minutes: 10
63
63
  max_attempts: 3
@@ -67,7 +67,7 @@ jobs:
67
67
  run: npm run lint
68
68
 
69
69
  - name: Install Playwright Browsers
70
- run: npx playwright@1.58.2 install --with-deps
70
+ run: npx playwright install --with-deps
71
71
 
72
72
  - name: Run headless unit test
73
73
  uses: GabrielBB/xvfb-action@v1
@@ -28,10 +28,10 @@ jobs:
28
28
  runs-on: windows-latest
29
29
 
30
30
  steps:
31
- - uses: actions/checkout@v6
31
+ - uses: actions/checkout@v7
32
32
 
33
33
  - name: Cache Node modules
34
- uses: actions/cache@v5
34
+ uses: actions/cache@v6
35
35
  with:
36
36
  # npm cache files are stored in ~/.npm
37
37
  path: ~/.npm
@@ -40,7 +40,7 @@ jobs:
40
40
  ${{ runner.os }}-node-
41
41
 
42
42
  - name: Cache Electron binaries
43
- uses: actions/cache@v5
43
+ uses: actions/cache@v6
44
44
  with:
45
45
  path: |
46
46
  ${{ env.LOCALAPPDATA }}\electron\Cache
@@ -55,7 +55,7 @@ jobs:
55
55
  node-version: ${{ matrix.node-version }}
56
56
 
57
57
  - name: Install Dependencies
58
- uses: nick-fields/retry@v3
58
+ uses: nick-fields/retry@v4
59
59
  with:
60
60
  timeout_minutes: 10
61
61
  max_attempts: 3
@@ -65,7 +65,7 @@ jobs:
65
65
  run: npm run lint
66
66
 
67
67
  - name: Install Playwright Browsers
68
- run: npx playwright@1.58.2 install --with-deps
68
+ run: npx playwright install --with-deps
69
69
 
70
70
  - name: Run headless unit test
71
71
  run: npm run test -- --reporters=default
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "1.3.1"
2
+ ".": "1.3.2"
3
3
  }
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.3.2](https://github.com/tomshaw/fontastic/compare/fontastic-v1.3.1...fontastic-v1.3.2) (2026-03-17)
4
+
5
+
6
+ ### 🛠️ Fixes
7
+
8
+ * update Content Security Policy to allow inline styles ([d95f7b5](https://github.com/tomshaw/fontastic/commit/d95f7b50f6cf0265052ad5964915ee42367d2c70))
9
+
3
10
  ## [1.3.1](https://github.com/tomshaw/fontastic/compare/fontastic-v1.3.0...fontastic-v1.3.1) (2026-03-17)
4
11
 
5
12
 
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # Fontastic
2
2
 
3
- [![Angular](https://img.shields.io/badge/Angular-21-dd0031?style=plastic&logo=angular&logoColor=white)](https://angular.dev)
4
- [![Electron](https://img.shields.io/badge/Electron-40-47848f?style=plastic&logo=electron&logoColor=white)](https://electronjs.org)
3
+ [![Angular](https://img.shields.io/badge/Angular-21.2.17-dd0031?style=plastic&logo=angular&logoColor=white)](https://angular.dev)
4
+ [![Electron](https://img.shields.io/badge/Electron-43-47848f?style=plastic&logo=electron&logoColor=white)](https://electronjs.org)
5
5
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-3178c6?style=plastic&logo=typescript&logoColor=white)](https://www.typescriptlang.org)
6
6
  [![License](https://img.shields.io/badge/License-MIT-f59e0b?style=plastic)](LICENSE.md)
7
7
  [![PRs Welcome](https://img.shields.io/badge/PRs-Welcome-22c55e?style=plastic)](http://makeapullrequest.com)
@@ -56,11 +56,11 @@ npm start
56
56
  | Category | Technology |
57
57
  |---|---|
58
58
  | Framework | [Angular](https://angular.dev) 21 |
59
- | Desktop | [Electron](https://electronjs.org) 40 |
59
+ | Desktop | [Electron](https://electronjs.org) 43 |
60
60
  | Language | [TypeScript](https://www.typescriptlang.org) 5.9 |
61
61
  | Database | [TypeORM](https://typeorm.io) + SQLite |
62
62
  | Font Parsing | [Fontkit](https://github.com/foliojs/fontkit) |
63
- | Styling | [Tailwind CSS](https://tailwindcss.com) 4 + SCSS |
63
+ | Styling | [Tailwind CSS](https://tailwindcss.com) 4 + CSS variables |
64
64
  | i18n | [@ngx-translate](https://github.com/ngx-translate/core) |
65
65
  | Testing | [Vitest](https://vitest.dev) + [Playwright](https://playwright.dev) |
66
66
  | Linting | [ESLint](https://eslint.org) + [Prettier](https://prettier.io) |
package/angular.json CHANGED
@@ -28,7 +28,7 @@
28
28
  "base": "dist"
29
29
  },
30
30
  "index": "src/index.html",
31
- "polyfills": ["zone.js"],
31
+ "polyfills": [],
32
32
  "tsConfig": "src/tsconfig.app.json",
33
33
  "inlineStyleLanguage": "css",
34
34
  "assets": ["src/favicon.ico", "src/assets"],
@@ -66,7 +66,7 @@
66
66
  ]
67
67
  },
68
68
  "testing": {
69
- "polyfills": ["zone.js", "zone.js/testing"]
69
+ "polyfills": []
70
70
  }
71
71
  }
72
72
  },
@@ -100,7 +100,12 @@
100
100
  "coverage": true,
101
101
  "coverageReporters": ["html", "lcovonly"],
102
102
  "reporters": [
103
- ["default", { "summary": true }],
103
+ [
104
+ "default",
105
+ {
106
+ "summary": true
107
+ }
108
+ ],
104
109
  [
105
110
  "html",
106
111
  {
@@ -79,9 +79,21 @@ class FontFinder {
79
79
  processInBatches(fontFiles, options) {
80
80
  return __awaiter(this, void 0, void 0, function* () {
81
81
  const total = fontFiles.length;
82
+ const repository = this.connectionManager.getStoreRepository();
82
83
  for (let i = 0; i < fontFiles.length; i += SCAN_CONCURRENCY) {
83
84
  const batch = fontFiles.slice(i, i + SCAN_CONCURRENCY);
84
- yield Promise.all(batch.map(({ fp, fileType }) => this.processFont(fp, fileType, options)));
85
+ const parsed = yield Promise.all(batch.map(({ fp, fileType }) => this.parseFont(fp, fileType, options)));
86
+ const rows = parsed.filter((row) => row !== null);
87
+ if (rows.length) {
88
+ try {
89
+ // One multi-row INSERT per batch instead of one statement per font.
90
+ yield repository.createMany(rows);
91
+ this.counter += rows.length;
92
+ }
93
+ catch (err) {
94
+ this.errors.push(...rows.map((row) => ({ file: row.file_path, message: err.message })));
95
+ }
96
+ }
85
97
  if (this.onProgress) {
86
98
  const lastFile = batch[batch.length - 1];
87
99
  this.onProgress({
@@ -94,12 +106,12 @@ class FontFinder {
94
106
  }
95
107
  });
96
108
  }
97
- processFont(fp, fileType, options) {
109
+ parseFont(fp, fileType, options) {
98
110
  return __awaiter(this, void 0, void 0, function* () {
99
111
  const font = new FontObject_1.default(fp);
100
112
  if (font.hasError()) {
101
113
  this.errors.push(font.getError());
102
- return;
114
+ return null;
103
115
  }
104
116
  let stat;
105
117
  try {
@@ -107,16 +119,9 @@ class FontFinder {
107
119
  }
108
120
  catch (err) {
109
121
  this.errors.push({ file: fp, message: err.message });
110
- return;
111
- }
112
- const data = Object.assign(Object.assign({ file_path: fp, file_name: path.basename(fp), file_size: stat.size, file_size_pretty: prettyBytes(stat.size), file_type: fileType, installable: mimes_1.installable.includes(fileType) }, options), font.getNamesTable());
113
- try {
114
- yield this.connectionManager.getStoreRepository().create(data);
115
- this.counter++;
116
- }
117
- catch (err) {
118
- this.errors.push({ file: fp, message: err.message });
122
+ return null;
119
123
  }
124
+ return Object.assign(Object.assign({ file_path: fp, file_name: path.basename(fp), file_size: stat.size, file_size_pretty: prettyBytes(stat.size), file_type: fileType, installable: mimes_1.installable.includes(fileType) }, options), font.getNamesTable());
120
125
  });
121
126
  }
122
127
  }
@@ -81,9 +81,22 @@ export default class FontFinder {
81
81
 
82
82
  private async processInBatches(fontFiles: { fp: string; fileType: string }[], options: any) {
83
83
  const total = fontFiles.length;
84
+ const repository = this.connectionManager.getStoreRepository();
85
+
84
86
  for (let i = 0; i < fontFiles.length; i += SCAN_CONCURRENCY) {
85
87
  const batch = fontFiles.slice(i, i + SCAN_CONCURRENCY);
86
- await Promise.all(batch.map(({ fp, fileType }) => this.processFont(fp, fileType, options)));
88
+ const parsed = await Promise.all(batch.map(({ fp, fileType }) => this.parseFont(fp, fileType, options)));
89
+ const rows = parsed.filter((row) => row !== null);
90
+
91
+ if (rows.length) {
92
+ try {
93
+ // One multi-row INSERT per batch instead of one statement per font.
94
+ await repository.createMany(rows);
95
+ this.counter += rows.length;
96
+ } catch (err: any) {
97
+ this.errors.push(...rows.map((row) => ({ file: row.file_path, message: err.message })));
98
+ }
99
+ }
87
100
 
88
101
  if (this.onProgress) {
89
102
  const lastFile = batch[batch.length - 1];
@@ -97,12 +110,12 @@ export default class FontFinder {
97
110
  }
98
111
  }
99
112
 
100
- private async processFont(fp: string, fileType: string, options: any) {
113
+ private async parseFont(fp: string, fileType: string, options: any): Promise<any | null> {
101
114
  const font = new FontObject(fp);
102
115
 
103
116
  if (font.hasError()) {
104
117
  this.errors.push(font.getError());
105
- return;
118
+ return null;
106
119
  }
107
120
 
108
121
  let stat;
@@ -110,10 +123,10 @@ export default class FontFinder {
110
123
  stat = await fs.stat(fp);
111
124
  } catch (err: any) {
112
125
  this.errors.push({ file: fp, message: err.message });
113
- return;
126
+ return null;
114
127
  }
115
128
 
116
- const data = {
129
+ return {
117
130
  file_path: fp,
118
131
  file_name: path.basename(fp),
119
132
  file_size: stat.size,
@@ -123,12 +136,5 @@ export default class FontFinder {
123
136
  ...options,
124
137
  ...font.getNamesTable(),
125
138
  };
126
-
127
- try {
128
- await this.connectionManager.getStoreRepository().create(data);
129
- this.counter++;
130
- } catch (err: any) {
131
- this.errors.push({ file: fp, message: err.message });
132
- }
133
139
  }
134
140
  }
@@ -12,10 +12,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const electron_1 = require("electron");
13
13
  const FontCatalog_1 = require("./FontCatalog");
14
14
  const FontFinder_1 = require("./FontFinder");
15
- const command_1 = require("../helpers/command");
16
15
  const StorageType_1 = require("../enums/StorageType");
17
16
  const path = require("path");
18
- const fetch = require('node-fetch');
19
17
  class FontManager {
20
18
  constructor(systemManager, configManager, connectionManager) {
21
19
  this.catalog = new FontCatalog_1.default();
@@ -51,16 +49,6 @@ class FontManager {
51
49
  return this.configManager.get(StorageType_1.StorageType.User);
52
50
  });
53
51
  }
54
- executeCommand(args) {
55
- return __awaiter(this, void 0, void 0, function* () {
56
- try {
57
- return yield (0, command_1.execute)(args.cmd, args.options);
58
- }
59
- catch (err) {
60
- return err;
61
- }
62
- });
63
- }
64
52
  getDestinationFolder(collectionId) {
65
53
  return path.join(this.systemManager.getCatalogPath(), String(collectionId));
66
54
  }
@@ -91,7 +79,7 @@ class FontManager {
91
79
  });
92
80
  }
93
81
  showMessageBox(options) {
94
- return electron_1.dialog.showMessageBox(null, options);
82
+ return electron_1.dialog.showMessageBox(options);
95
83
  }
96
84
  showOpenDialog(options) {
97
85
  return electron_1.dialog.showOpenDialog(options);
@@ -103,7 +91,18 @@ class FontManager {
103
91
  electron_1.shell.openPath(path);
104
92
  }
105
93
  openExternal(url) {
106
- electron_1.shell.openExternal(url);
94
+ // Only allow web URLs — anything else (file:, smb:, custom schemes) is a
95
+ // request the renderer should never be able to make.
96
+ let protocol;
97
+ try {
98
+ protocol = new URL(url).protocol;
99
+ }
100
+ catch (_a) {
101
+ return;
102
+ }
103
+ if (protocol === 'https:' || protocol === 'http:') {
104
+ electron_1.shell.openExternal(url);
105
+ }
107
106
  }
108
107
  showItemInFolder(fullPath) {
109
108
  electron_1.shell.showItemInFolder(fullPath);
@@ -6,14 +6,11 @@ import ConnectionManager from './ConnectionManager';
6
6
 
7
7
  import FontCatalog from './FontCatalog';
8
8
  import FontFinder, { ProgressCallback } from './FontFinder';
9
- import { execute } from '../helpers/command';
10
9
 
11
10
  import { StorageType } from '../enums/StorageType';
12
11
 
13
12
  import * as path from 'path';
14
13
 
15
- const fetch = require('node-fetch');
16
-
17
14
  export default class FontManager {
18
15
  systemManager: SystemManager;
19
16
  configManager: ConfigManager;
@@ -56,14 +53,6 @@ export default class FontManager {
56
53
  return this.configManager.get(StorageType.User);
57
54
  }
58
55
 
59
- async executeCommand(args: any) {
60
- try {
61
- return await execute(args.cmd, args.options);
62
- } catch (err) {
63
- return err;
64
- }
65
- }
66
-
67
56
  getDestinationFolder(collectionId: number) {
68
57
  return path.join(this.systemManager.getCatalogPath(), String(collectionId));
69
58
  }
@@ -91,7 +80,7 @@ export default class FontManager {
91
80
  }
92
81
 
93
82
  showMessageBox(options: any) {
94
- return dialog.showMessageBox(null, options);
83
+ return dialog.showMessageBox(options);
95
84
  }
96
85
 
97
86
  showOpenDialog(options: any) {
@@ -107,7 +96,17 @@ export default class FontManager {
107
96
  }
108
97
 
109
98
  openExternal(url: string) {
110
- shell.openExternal(url);
99
+ // Only allow web URLs — anything else (file:, smb:, custom schemes) is a
100
+ // request the renderer should never be able to make.
101
+ let protocol: string;
102
+ try {
103
+ protocol = new URL(url).protocol;
104
+ } catch {
105
+ return;
106
+ }
107
+ if (protocol === 'https:' || protocol === 'http:') {
108
+ shell.openExternal(url);
109
+ }
111
110
  }
112
111
 
113
112
  showItemInFolder(fullPath: string) {
@@ -75,7 +75,6 @@ class MessageHandler {
75
75
  }));
76
76
  this.handle(ChannelType_1.ChannelType.IPC_DATABASE_DROP, (_event) => __awaiter(this, void 0, void 0, function* () { return this.connectionManager.getDataSource().dropDatabase(); }));
77
77
  // Font Manager
78
- this.handle(ChannelType_1.ChannelType.IPC_EXEC_CMD, (_event, args) => __awaiter(this, void 0, void 0, function* () { return this.fontManager.executeCommand(args).catch((err) => this.sendMessage('error', err.message)); }));
79
78
  this.handle(ChannelType_1.ChannelType.IPC_AUTH_USER, (_event, args) => __awaiter(this, void 0, void 0, function* () { return this.fontManager.systemAuthenticate(args); }));
80
79
  this.handle(ChannelType_1.ChannelType.IPC_SCAN_FILES, (_event, args) => __awaiter(this, void 0, void 0, function* () {
81
80
  const { port1, port2 } = new electron_1.MessageChannelMain();
@@ -108,10 +108,6 @@ export default class MessageHandler {
108
108
 
109
109
  // Font Manager
110
110
 
111
- this.handle(ChannelType.IPC_EXEC_CMD, async (_event: IpcMainEvent, args: any) =>
112
- this.fontManager.executeCommand(args).catch((err: Error) => this.sendMessage('error', err.message)),
113
- );
114
-
115
111
  this.handle(ChannelType.IPC_AUTH_USER, async (_event: IpcMainEvent, args: any) => this.fontManager.systemAuthenticate(args));
116
112
 
117
113
  this.handle(ChannelType.IPC_SCAN_FILES, async (_event: IpcMainEvent, args: any) => {
@@ -21,6 +21,7 @@ __decorate([
21
21
  ], Store.prototype, "id", void 0);
22
22
  __decorate([
23
23
  (0, typeorm_1.Column)('int'),
24
+ (0, typeorm_1.Index)(),
24
25
  __metadata("design:type", Number)
25
26
  ], Store.prototype, "collection_id", void 0);
26
27
  __decorate([
@@ -9,6 +9,7 @@ export class Store {
9
9
  id: number;
10
10
 
11
11
  @Column('int')
12
+ @Index()
12
13
  collection_id: number;
13
14
 
14
15
  @Column({ type: 'varchar', length: 255, default: '', nullable: true })
@@ -17,17 +17,6 @@ exports.CollectionRepository = {
17
17
  return __awaiter(this, void 0, void 0, function* () {
18
18
  const db = this.createQueryBuilder('collection');
19
19
  db.where('collection.is_system = 0');
20
- db.leftJoin('collection.stores', 'store');
21
- db.loadRelationCountAndMap('store.storeCount', 'collection.stores'); // correct
22
- db.loadRelationCountAndMap('store.installableCount', 'collection.stores', 'store', (qb) => qb.andWhere('store.installable = :placeholder', {
23
- placeholder: true,
24
- }));
25
- db.loadRelationCountAndMap('store.temporaryCount', 'collection.stores', 'store', (qb) => qb.andWhere('store.temporary = :placeholder', {
26
- placeholder: true,
27
- }));
28
- db.loadRelationCountAndMap('store.favoriteCount', 'collection.stores', 'store', (qb) => qb.andWhere('store.favorite = :placeholder', {
29
- placeholder: true,
30
- }));
31
20
  db.orderBy('collection.orderby', 'ASC');
32
21
  db.addOrderBy('LOWER(collection.title)', 'ASC');
33
22
  return yield db.getMany();
@@ -7,28 +7,6 @@ export const CollectionRepository = {
7
7
 
8
8
  db.where('collection.is_system = 0');
9
9
 
10
- db.leftJoin('collection.stores', 'store');
11
-
12
- db.loadRelationCountAndMap('store.storeCount', 'collection.stores'); // correct
13
-
14
- db.loadRelationCountAndMap('store.installableCount', 'collection.stores', 'store', (qb: any) =>
15
- qb.andWhere('store.installable = :placeholder', {
16
- placeholder: true,
17
- }),
18
- );
19
-
20
- db.loadRelationCountAndMap('store.temporaryCount', 'collection.stores', 'store', (qb: any) =>
21
- qb.andWhere('store.temporary = :placeholder', {
22
- placeholder: true,
23
- }),
24
- );
25
-
26
- db.loadRelationCountAndMap('store.favoriteCount', 'collection.stores', 'store', (qb: any) =>
27
- qb.andWhere('store.favorite = :placeholder', {
28
- placeholder: true,
29
- }),
30
- );
31
-
32
10
  db.orderBy('collection.orderby', 'ASC');
33
11
  db.addOrderBy('LOWER(collection.title)', 'ASC');
34
12