bridgerator 1.0.8 → 1.1.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/README.md +76 -14
- package/assets/bridgerator.ico +0 -0
- package/assets/icon-16.png +0 -0
- package/assets/icon-20.png +0 -0
- package/assets/icon-24.png +0 -0
- package/assets/icon-256.png +0 -0
- package/assets/icon-32.png +0 -0
- package/assets/icon-48.png +0 -0
- package/assets/icon-64.png +0 -0
- package/assets/logo.svg +1 -0
- package/install.ps1 +455 -56
- package/npm-shrinkwrap.json +8621 -0
- package/package.json +55 -49
- package/recipes/backup-folder.json +31 -0
- package/recipes/clean-downloads.json +48 -0
- package/recipes/disk-report.json +66 -0
- package/recipes/sort-folder.json +49 -0
- package/recipes/update-apps.json +25 -0
- package/src/ask-lib.ps1 +230 -0
- package/src/ask.mjs +51 -0
- package/src/ask.ps1 +17 -0
- package/src/automations.mjs +673 -0
- package/src/batch.mjs +221 -0
- package/src/bridge.mjs +720 -29
- package/src/cli.mjs +529 -74
- package/src/confirm.mjs +418 -0
- package/src/dc-config-hooks.mjs +18 -8
- package/src/dc-isolate.mjs +5 -0
- package/src/delegate.mjs +555 -0
- package/src/docs-tool.mjs +494 -0
- package/src/doctor.mjs +200 -0
- package/src/events.mjs +21 -0
- package/src/extra-tools.mjs +122 -0
- package/src/guard.mjs +34 -0
- package/src/notice.mjs +84 -23
- package/src/pair.mjs +27 -4
- package/src/pc-check.mjs +112 -0
- package/src/pc-check.ps1 +103 -0
- package/src/pc-text.mjs +94 -0
- package/src/pdf-font.mjs +245 -0
- package/src/photos-tool.mjs +187 -0
- package/src/photos.ps1 +145 -0
- package/src/plan.mjs +90 -0
- package/src/policy.mjs +293 -124
- package/src/queue.mjs +194 -0
- package/src/recent.mjs +48 -0
- package/src/recipes.mjs +108 -0
- package/src/recycle.mjs +185 -0
- package/src/recycle.ps1 +110 -0
- package/src/screen-tool.mjs +185 -0
- package/src/screen.ps1 +285 -0
- package/src/search-tool.mjs +189 -0
- package/src/search.ps1 +129 -0
- package/src/settings-tool.mjs +186 -0
- package/src/setup-tool.mjs +129 -0
- package/src/software-tool.mjs +185 -0
- package/src/telemetry.mjs +86 -0
- package/src/tool-lib.mjs +177 -0
- package/src/tool-text.mjs +45 -0
- package/src/tray.mjs +97 -0
- package/src/tray.ps1 +359 -0
- package/src/undo.mjs +313 -0
- package/src/win.mjs +17 -0
- package/ui/app.css +388 -0
- package/ui/app.js +868 -0
- package/ui/i18n/en.json +598 -0
- package/ui/i18n/ru.json +598 -0
- package/ui/index.html +26 -0
- package/vendor/webview2/LICENSE.txt +27 -0
- package/vendor/webview2/Microsoft.Web.WebView2.Core.dll +0 -0
- package/vendor/webview2/Microsoft.Web.WebView2.WinForms.dll +0 -0
- package/vendor/webview2/NOTICE.txt +85 -0
- package/vendor/webview2/SHA256SUMS.txt +4 -0
- package/vendor/webview2/SOURCE.txt +1 -0
- package/vendor/webview2/arm64/WebView2Loader.dll +0 -0
- package/vendor/webview2/x64/WebView2Loader.dll +0 -0
package/src/ask.mjs
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// The question on the PC: a native Windows notification in the bottom-right (our own app id
|
|
2
|
+
// "Bridgerator" under HKCU, scenario "reminder" = stays until answered) with buttons. A helper
|
|
3
|
+
// PowerShell waits for the click (ToastNotification.Activated) or the timeout (then the toast is
|
|
4
|
+
// removed and the answer is Deny). If our notifications are turned off or the toast fails: a small
|
|
5
|
+
// borderless window in the bottom-right above the taskbar, same buttons, never steals focus.
|
|
6
|
+
// No protocol handler is registered: a click on a stale toast in the Action Center does nothing.
|
|
7
|
+
// Texts reach PowerShell only as environment variables (XML-escaped there), never in the script.
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import os from 'node:os';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
import { execFile } from 'node:child_process';
|
|
12
|
+
import { POWERSHELL, psArgs } from './win.mjs';
|
|
13
|
+
import { localizeAsk, attrLine } from './pc-text.mjs';
|
|
14
|
+
|
|
15
|
+
const read = (f) => fs.readFileSync(new URL(f, import.meta.url), 'utf8');
|
|
16
|
+
export const ASK_LIB = read('./ask-lib.ps1');
|
|
17
|
+
export const ASK_PS = ASK_LIB + '\n' + read('./ask.ps1');
|
|
18
|
+
const LIB_FILE = fileURLToPath(new URL('./ask-lib.ps1', import.meta.url));
|
|
19
|
+
const MAIN_FILE = fileURLToPath(new URL('./ask.ps1', import.meta.url));
|
|
20
|
+
// PowerShell also ends a single-quoted string at the typographic quotes U+2018/2019/201A/201B: each is doubled too.
|
|
21
|
+
export const q = (x) => `'${String(x).replace(/['\u2018\u2019\u201A\u201B]/g, '$&$&')}'`;
|
|
22
|
+
// The scripts are too long for -EncodedCommand: read from the package and run as one scriptblock
|
|
23
|
+
// (no double quotes, so it also passes as a plain -Command argument).
|
|
24
|
+
// The release build signs every .ps1 (Authenticode block at the end); PowerShell refuses code after a
|
|
25
|
+
// signature block, so each file's block is cut before joining (the joined text is never verified anyway).
|
|
26
|
+
export const runFilesPs = (...files) => `. ([scriptblock]::Create((${files.map((f) => `([IO.File]::ReadAllText(${q(f)}, [Text.Encoding]::UTF8) -replace '(?s)# SIG # Begin signature block.*$', '')`).join(' + [Environment]::NewLine + ')})))`;
|
|
27
|
+
|
|
28
|
+
/** process.env without BR_* / BRIDGERATOR_* (test hooks are never taken from the environment). */
|
|
29
|
+
export const stripOurs = (env) => Object.fromEntries(Object.entries(env).filter(([k]) => !/^(BR_|BRIDGERATOR_)/i.test(k)));
|
|
30
|
+
|
|
31
|
+
let seq = 0;
|
|
32
|
+
/**
|
|
33
|
+
* Asks the person at the PC → the key of the button they chose; Deny ('deny') when they close it,
|
|
34
|
+
* don't answer within `secs`, or anything fails. buttons: [key, label, kind ('deny' = red)].
|
|
35
|
+
*/
|
|
36
|
+
export const ICON = fileURLToPath(new URL('../assets/icon-64.png', import.meta.url));
|
|
37
|
+
export function askOnPc(q0) {
|
|
38
|
+
if (process.platform !== 'win32') return Promise.resolve('deny');
|
|
39
|
+
const { head, text, buttons, secs = 120, host = os.hostname(), auto = 'auto-deny', theme = 'system', silent = false, style = 'toast', lang = 'en' } = localizeAsk({ ...q0, auto: q0.auto || 'auto-deny' }, q0.lang);
|
|
40
|
+
const attr = attrLine(host, auto, secs, lang);
|
|
41
|
+
const env = {
|
|
42
|
+
...stripOurs(process.env), BR_HEAD: head, BR_DETAIL: text, BR_ATTR: attr, BR_HOSTNAME: host, BR_AUTOWORD: auto, BR_SECS: String(secs),
|
|
43
|
+
BR_BUTTONS: buttons.map((b) => b.join('=')).join('|'), BR_TAG: `ask${process.pid}-${++seq}`, BR_THEME: theme, BR_ICON: ICON, BR_SILENT: silent ? '1' : '', BR_STYLE: style, BR_LANG: lang === 'ru' ? 'ru' : 'en',
|
|
44
|
+
};
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
execFile(POWERSHELL, psArgs(runFilesPs(LIB_FILE, MAIN_FILE)), { windowsHide: true, timeout: (secs + 30) * 1000, env }, (e, out) => {
|
|
47
|
+
const r = String(out || '').trim();
|
|
48
|
+
resolve(!e && buttons.some((b) => b[0] === r) ? r : 'deny');
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
package/src/ask.ps1
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Bridgerator: one question per process (when the tray helper is not running); values from BR_* env vars.
|
|
2
|
+
$ErrorActionPreference = 'Stop'
|
|
3
|
+
$specs = @(); foreach ($s in ($env:BR_BUTTONS -split '\|')) { $k, $t, $kind = $s -split '=', 3; $specs += ,@($k, $t, $kind) }
|
|
4
|
+
$q = @{ specs = $specs; head = $env:BR_HEAD; detail = $env:BR_DETAIL; attr = $env:BR_ATTR; host = $env:BR_HOSTNAME; auto = $(if ($env:BR_AUTOWORD) { $env:BR_AUTOWORD } else { 'auto-deny' }); secs = [int]$env:BR_SECS; tag = $env:BR_TAG; theme = $env:BR_THEME; scale = $env:BR_SCALE; shot = $env:BR_SHOT; icon = $env:BR_ICON; silent = ($env:BR_SILENT -eq '1'); lang = $env:BR_LANG }
|
|
5
|
+
$w = New-Object BrWait; $w.Keys = [string[]]@($specs | ForEach-Object { $_[0] })
|
|
6
|
+
$result = $null
|
|
7
|
+
try {
|
|
8
|
+
if ($env:BR_FORCE_FALLBACK -or $env:BR_STYLE -eq 'popup') { throw 'compact pop-up chosen' }
|
|
9
|
+
Show-AskToast $q $w
|
|
10
|
+
if (-not $w.Done.WaitOne($q.secs * 1000)) { Remove-AskToast $q.tag; $result = 'deny' }
|
|
11
|
+
elseif ($w.Result -eq 'failed') { throw 'the notification failed' }
|
|
12
|
+
else { $result = $w.Result }
|
|
13
|
+
} catch {
|
|
14
|
+
[Console]::Error.WriteLine("toast: $_")
|
|
15
|
+
try { Initialize-Windows; $f = New-AskForm $q; [void]$f.ShowDialog(); $result = $f.Tag.pick } catch { [Console]::Error.WriteLine("fallback: $_"); $result = 'deny' }
|
|
16
|
+
}
|
|
17
|
+
[Console]::Out.Write($result)
|