fontastic 1.3.2 → 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.
- package/.github/workflows/claude-code-review.yml +1 -1
- package/.github/workflows/claude.yml +1 -1
- package/.github/workflows/macos.yml +5 -5
- package/.github/workflows/release-please.yml +1 -1
- package/.github/workflows/release.yml +2 -2
- package/.github/workflows/ubuntu.yml +7 -7
- package/.github/workflows/windows.yml +5 -5
- package/README.md +4 -4
- package/angular.json +8 -3
- package/app/core/FontFinder.js +17 -12
- package/app/core/FontFinder.ts +18 -12
- package/app/core/FontManager.js +13 -14
- package/app/core/FontManager.ts +12 -13
- package/app/core/MessageHandler.js +0 -1
- package/app/core/MessageHandler.ts +0 -4
- package/app/database/entity/Store.schema.js +1 -0
- package/app/database/entity/Store.schema.ts +1 -0
- package/app/database/repository/Collection.repository.js +0 -11
- package/app/database/repository/Collection.repository.ts +0 -22
- package/app/database/repository/Store.repository.js +50 -69
- package/app/database/repository/Store.repository.ts +47 -86
- package/app/enums/ChannelType.js +0 -1
- package/app/enums/ChannelType.ts +0 -1
- package/app/main.js +3 -2
- package/app/main.ts +4 -3
- package/app/package-lock.json +144 -1104
- package/app/package.json +4 -6
- package/app/preload.js +51 -0
- package/app/preload.ts +59 -0
- package/app/types/Bridge.js +3 -0
- package/app/types/Bridge.ts +19 -0
- package/app/types/index.js +1 -0
- package/app/types/index.ts +1 -0
- package/knip.json +18 -0
- package/package.json +44 -53
- package/src/app/app.component.spec.ts +3 -3
- package/src/app/app.component.ts +2 -15
- package/src/app/core/services/database/database.service.ts +8 -15
- package/src/app/core/services/electron/electron.service.ts +5 -46
- package/src/app/core/services/font-loader/font-loader.service.ts +60 -0
- package/src/app/core/services/index.ts +1 -0
- package/src/app/core/services/message/message.service.ts +19 -27
- package/src/app/core/services/presentation/presentation.service.ts +9 -2
- package/src/app/home/home.component.spec.ts +3 -3
- package/src/app/home/home.component.ts +4 -8
- package/src/app/layout/footer/footer.component.ts +6 -6
- package/src/app/shared/components/index.ts +0 -1
- package/src/app/shared/components/page-not-found/page-not-found.component.ts +2 -8
- package/src/app/shared/components/preview/preview.component.html +1 -0
- package/src/app/shared/components/preview/preview.component.ts +3 -31
- package/src/app/shared/components/rule-builder/rule-builder.component.html +4 -4
- package/src/app/shared/components/rule-builder/rule-builder.component.ts +13 -13
- package/src/app/shared/components/waterfall/waterfall.component.ts +1 -1
- package/src/app/shared/directives/index.ts +1 -1
- package/src/app/shared/directives/lazy-font/lazy-font.directive.ts +23 -0
- package/src/app/shared/shared.module.ts +3 -3
- package/src/main.ts +2 -2
- package/tsconfig.serve.json +4 -16
- package/app/helpers/command.js +0 -28
- package/app/helpers/command.ts +0 -20
- package/app/helpers/random.js +0 -16
- package/app/helpers/random.ts +0 -12
- package/src/app/shared/components/prompt-dialog/prompt-dialog.component.html +0 -36
- package/src/app/shared/components/prompt-dialog/prompt-dialog.component.ts +0 -40
- package/src/app/shared/directives/webview/webview.directive.spec.ts +0 -8
- package/src/app/shared/directives/webview/webview.directive.ts +0 -9
- package/src/styles/themes/dashboard.scss +0 -293
- package/src/styles/themes/euphoria.scss +0 -284
- package/src/styles/themes/mellow.scss +0 -281
- package/src/styles/themes/midnight.scss +0 -284
- package/src/styles/themes/passion.scss +0 -281
- package/src/styles/themes/swiss.scss +0 -284
|
@@ -24,10 +24,10 @@ jobs:
|
|
|
24
24
|
runs-on: macos-latest
|
|
25
25
|
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v7
|
|
28
28
|
|
|
29
29
|
- name: Cache Node modules
|
|
30
|
-
uses: actions/cache@
|
|
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@
|
|
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@
|
|
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
|
|
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@
|
|
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@
|
|
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@
|
|
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-
|
|
25
|
+
runs-on: ubuntu-24.04
|
|
26
26
|
|
|
27
27
|
steps:
|
|
28
|
-
- uses: actions/checkout@
|
|
28
|
+
- uses: actions/checkout@v7
|
|
29
29
|
|
|
30
30
|
- name: Cache Node modules
|
|
31
|
-
uses: actions/cache@
|
|
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@
|
|
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
|
|
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@
|
|
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
|
|
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@
|
|
31
|
+
- uses: actions/checkout@v7
|
|
32
32
|
|
|
33
33
|
- name: Cache Node modules
|
|
34
|
-
uses: actions/cache@
|
|
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@
|
|
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@
|
|
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
|
|
68
|
+
run: npx playwright install --with-deps
|
|
69
69
|
|
|
70
70
|
- name: Run headless unit test
|
|
71
71
|
run: npm run test -- --reporters=default
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Fontastic
|
|
2
2
|
|
|
3
|
-
[](https://angular.dev)
|
|
4
|
-
[](https://angular.dev)
|
|
4
|
+
[](https://electronjs.org)
|
|
5
5
|
[](https://www.typescriptlang.org)
|
|
6
6
|
[](LICENSE.md)
|
|
7
7
|
[](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)
|
|
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 +
|
|
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": [
|
|
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": [
|
|
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
|
-
[
|
|
103
|
+
[
|
|
104
|
+
"default",
|
|
105
|
+
{
|
|
106
|
+
"summary": true
|
|
107
|
+
}
|
|
108
|
+
],
|
|
104
109
|
[
|
|
105
110
|
"html",
|
|
106
111
|
{
|
package/app/core/FontFinder.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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
|
}
|
package/app/core/FontFinder.ts
CHANGED
|
@@ -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.
|
|
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
|
|
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
|
-
|
|
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
|
}
|
package/app/core/FontManager.js
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
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);
|
package/app/core/FontManager.ts
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
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) => {
|
|
@@ -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
|
|