@choochmeque/tauri-windows-bundle 0.1.15 → 0.1.16
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 +9 -0
- package/dist/cli.js +54 -2
- package/dist/core/manifest.d.ts +2 -0
- package/dist/index.js +55 -3
- package/dist/types.d.ts +4 -0
- package/dist/utils/exec.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ MSIX packaging tool for Tauri apps - create Windows Store ready bundles with mul
|
|
|
12
12
|
- **Multiarch Support** - Build for x64 and arm64 in one bundle
|
|
13
13
|
- **tauri.conf.json Integration** - Automatically reads app name, version, icons, and resources
|
|
14
14
|
- **Code Signing** - Support for PFX certificates and Windows certificate store
|
|
15
|
+
- **Resource Indexing** - Optional `resources.pri` generation for qualified assets
|
|
15
16
|
- **Windows Extensions** - Share Target, File Associations, Protocol Handlers, Startup Task, Context Menus, Background Tasks, App Execution Alias, App Services, Toast Activation, Autoplay, Print Task Settings, Thumbnail/Preview Handlers
|
|
16
17
|
|
|
17
18
|
## Prerequisites
|
|
@@ -69,6 +70,10 @@ Edit `src-tauri/gen/windows/bundle.config.json`:
|
|
|
69
70
|
"signing": {
|
|
70
71
|
"pfx": null,
|
|
71
72
|
"pfxPassword": null
|
|
73
|
+
},
|
|
74
|
+
"resourceIndex": {
|
|
75
|
+
"enabled": false,
|
|
76
|
+
"keepConfig": false
|
|
72
77
|
}
|
|
73
78
|
}
|
|
74
79
|
```
|
|
@@ -93,6 +98,10 @@ Edit `src-tauri/gen/windows/bundle.config.json`:
|
|
|
93
98
|
|
|
94
99
|
Note: `runFullTrust` is always auto-added (required for Tauri apps).
|
|
95
100
|
|
|
101
|
+
`resourceIndex.enabled` generates `resources.pri` via `msixbundle-cli --makepri` before packing. Enable this when using qualified assets (for example, scale-specific logos like `Square44x44Logo.scale-200.png`).
|
|
102
|
+
|
|
103
|
+
`resourceIndex.keepConfig` keeps generated `priconfig.xml` in each `AppxContent` directory for debugging.
|
|
104
|
+
|
|
96
105
|
**Auto-read from tauri.conf.json / tauri.windows.conf.json:**
|
|
97
106
|
- `displayName` ← `productName`
|
|
98
107
|
- `version` ← `version` (auto-converted to 4-part: `1.0.0` → `1.0.0.0`)
|
package/dist/cli.js
CHANGED
|
@@ -197,6 +197,10 @@ function generateBundleConfig(windowsDir, _tauriConfig) {
|
|
|
197
197
|
pfx: null,
|
|
198
198
|
pfxPassword: null,
|
|
199
199
|
},
|
|
200
|
+
resourceIndex: {
|
|
201
|
+
enabled: false,
|
|
202
|
+
keepConfig: false,
|
|
203
|
+
},
|
|
200
204
|
};
|
|
201
205
|
const configPath = path.join(windowsDir, 'bundle.config.json');
|
|
202
206
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
@@ -433,6 +437,17 @@ function generateManifest(config, arch, minVersion, windowsDir) {
|
|
|
433
437
|
};
|
|
434
438
|
return replaceTemplateVariables(getManifestTemplate(windowsDir), variables);
|
|
435
439
|
}
|
|
440
|
+
function getDefaultLanguageFromManifestXml(manifestXml) {
|
|
441
|
+
const languageMatch = manifestXml.match(/<Resource\b[^>]*\bLanguage="([^"]+)"/i);
|
|
442
|
+
return languageMatch?.[1];
|
|
443
|
+
}
|
|
444
|
+
function getDefaultLanguageFromManifestFile(manifestPath) {
|
|
445
|
+
if (!fs.existsSync(manifestPath)) {
|
|
446
|
+
return undefined;
|
|
447
|
+
}
|
|
448
|
+
const manifest = fs.readFileSync(manifestPath, 'utf-8');
|
|
449
|
+
return getDefaultLanguageFromManifestXml(manifest);
|
|
450
|
+
}
|
|
436
451
|
function generateExtensions(config) {
|
|
437
452
|
const extensions = [];
|
|
438
453
|
if (config.extensions?.shareTarget) {
|
|
@@ -714,6 +729,8 @@ function prepareAppxContent(projectRoot, arch, config, tauriConfig, minVersion,
|
|
|
714
729
|
const srcTauriDir = path.join(projectRoot, 'src-tauri');
|
|
715
730
|
const buildDir = path.join(srcTauriDir, 'target', target, 'release');
|
|
716
731
|
const appxDir = path.join(srcTauriDir, 'target', 'appx', arch);
|
|
732
|
+
// Clear stale output from previous builds
|
|
733
|
+
fs.rmSync(appxDir, { recursive: true, force: true });
|
|
717
734
|
// Create directories
|
|
718
735
|
fs.mkdirSync(path.join(appxDir, 'Assets'), { recursive: true });
|
|
719
736
|
// Copy exe
|
|
@@ -774,6 +791,16 @@ function copyBundledResources(projectRoot, appxDir, tauriConfig) {
|
|
|
774
791
|
|
|
775
792
|
const execPromise = promisify(exec);
|
|
776
793
|
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
794
|
+
function isCiEnvironment() {
|
|
795
|
+
const ci = process.env.CI;
|
|
796
|
+
if (!ci)
|
|
797
|
+
return false;
|
|
798
|
+
const normalized = ci.toLowerCase();
|
|
799
|
+
return normalized !== '0' && normalized !== 'false';
|
|
800
|
+
}
|
|
801
|
+
function shouldAnimateSpinner() {
|
|
802
|
+
return Boolean(process.stdout.isTTY) && !isCiEnvironment();
|
|
803
|
+
}
|
|
777
804
|
class Spinner {
|
|
778
805
|
frameIndex = 0;
|
|
779
806
|
intervalId = null;
|
|
@@ -838,7 +865,7 @@ function isVersionSufficient(version, minVersion) {
|
|
|
838
865
|
return false;
|
|
839
866
|
return patch >= minPatch;
|
|
840
867
|
}
|
|
841
|
-
const MIN_MSIXBUNDLE_CLI_VERSION = '1.1.
|
|
868
|
+
const MIN_MSIXBUNDLE_CLI_VERSION = '1.1.4';
|
|
842
869
|
async function promptInstall(message) {
|
|
843
870
|
const rl = readline.createInterface({
|
|
844
871
|
input: process.stdin,
|
|
@@ -854,6 +881,8 @@ async function promptInstall(message) {
|
|
|
854
881
|
async function execWithProgress(command, options) {
|
|
855
882
|
const verbose = options?.verbose ?? false;
|
|
856
883
|
const message = options?.message ?? 'Running...';
|
|
884
|
+
const useSpinner = !verbose && shouldAnimateSpinner();
|
|
885
|
+
const useStaticProgress = !verbose && !useSpinner;
|
|
857
886
|
return new Promise((resolve, reject) => {
|
|
858
887
|
const [cmd, ...args] = command.split(' ');
|
|
859
888
|
const child = spawn(cmd, args, {
|
|
@@ -863,10 +892,13 @@ async function execWithProgress(command, options) {
|
|
|
863
892
|
});
|
|
864
893
|
let spinner = null;
|
|
865
894
|
let capturedOutput = '';
|
|
866
|
-
if (
|
|
895
|
+
if (useSpinner) {
|
|
867
896
|
spinner = new Spinner(message);
|
|
868
897
|
spinner.start();
|
|
869
898
|
}
|
|
899
|
+
else if (useStaticProgress) {
|
|
900
|
+
console.log(message);
|
|
901
|
+
}
|
|
870
902
|
child.stdout?.on('data', (data) => {
|
|
871
903
|
if (verbose) {
|
|
872
904
|
process.stdout.write(data);
|
|
@@ -886,10 +918,16 @@ async function execWithProgress(command, options) {
|
|
|
886
918
|
child.on('close', (code) => {
|
|
887
919
|
if (code === 0) {
|
|
888
920
|
spinner?.stop(true);
|
|
921
|
+
if (useStaticProgress) {
|
|
922
|
+
console.log(`Done: ${message}`);
|
|
923
|
+
}
|
|
889
924
|
resolve();
|
|
890
925
|
}
|
|
891
926
|
else {
|
|
892
927
|
spinner?.fail();
|
|
928
|
+
if (useStaticProgress) {
|
|
929
|
+
console.error(`Failed: ${message}`);
|
|
930
|
+
}
|
|
893
931
|
if (!verbose && capturedOutput) {
|
|
894
932
|
console.error('\nBuild output:\n' + capturedOutput);
|
|
895
933
|
}
|
|
@@ -898,6 +936,9 @@ async function execWithProgress(command, options) {
|
|
|
898
936
|
});
|
|
899
937
|
child.on('error', (error) => {
|
|
900
938
|
spinner?.fail();
|
|
939
|
+
if (useStaticProgress) {
|
|
940
|
+
console.error(`Failed: ${message}`);
|
|
941
|
+
}
|
|
901
942
|
if (!verbose && capturedOutput) {
|
|
902
943
|
console.error('\nBuild output:\n' + capturedOutput);
|
|
903
944
|
}
|
|
@@ -1029,6 +1070,17 @@ async function build(options) {
|
|
|
1029
1070
|
outDir,
|
|
1030
1071
|
...appxDirs.flatMap(({ arch, dir }) => [`--dir-${arch}`, dir]),
|
|
1031
1072
|
];
|
|
1073
|
+
// Resource index generation (resources.pri)
|
|
1074
|
+
if (bundleConfig.resourceIndex?.enabled) {
|
|
1075
|
+
const defaultLanguage = getDefaultLanguageFromManifestFile(path.join(appxDirs[0].dir, 'AppxManifest.xml'));
|
|
1076
|
+
args.push('--makepri');
|
|
1077
|
+
if (defaultLanguage) {
|
|
1078
|
+
args.push('--makepri-default-language', defaultLanguage);
|
|
1079
|
+
}
|
|
1080
|
+
if (bundleConfig.resourceIndex.keepConfig) {
|
|
1081
|
+
args.push('--makepri-keep-config');
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1032
1084
|
// Signing
|
|
1033
1085
|
if (bundleConfig.signing?.pfx) {
|
|
1034
1086
|
args.push('--pfx', bundleConfig.signing.pfx);
|
package/dist/core/manifest.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ import type { MergedConfig } from '../types.js';
|
|
|
2
2
|
export declare function getPackageVersion(): string;
|
|
3
3
|
export declare function generateManifestTemplate(windowsDir: string): void;
|
|
4
4
|
export declare function generateManifest(config: MergedConfig, arch: string, minVersion: string, windowsDir: string): string;
|
|
5
|
+
export declare function getDefaultLanguageFromManifestXml(manifestXml: string): string | undefined;
|
|
6
|
+
export declare function getDefaultLanguageFromManifestFile(manifestPath: string): string | undefined;
|
package/dist/index.js
CHANGED
|
@@ -194,6 +194,10 @@ function generateBundleConfig(windowsDir, _tauriConfig) {
|
|
|
194
194
|
pfx: null,
|
|
195
195
|
pfxPassword: null,
|
|
196
196
|
},
|
|
197
|
+
resourceIndex: {
|
|
198
|
+
enabled: false,
|
|
199
|
+
keepConfig: false,
|
|
200
|
+
},
|
|
197
201
|
};
|
|
198
202
|
const configPath = path.join(windowsDir, 'bundle.config.json');
|
|
199
203
|
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n');
|
|
@@ -430,6 +434,17 @@ function generateManifest(config, arch, minVersion, windowsDir) {
|
|
|
430
434
|
};
|
|
431
435
|
return replaceTemplateVariables(getManifestTemplate(windowsDir), variables);
|
|
432
436
|
}
|
|
437
|
+
function getDefaultLanguageFromManifestXml(manifestXml) {
|
|
438
|
+
const languageMatch = manifestXml.match(/<Resource\b[^>]*\bLanguage="([^"]+)"/i);
|
|
439
|
+
return languageMatch?.[1];
|
|
440
|
+
}
|
|
441
|
+
function getDefaultLanguageFromManifestFile(manifestPath) {
|
|
442
|
+
if (!fs.existsSync(manifestPath)) {
|
|
443
|
+
return undefined;
|
|
444
|
+
}
|
|
445
|
+
const manifest = fs.readFileSync(manifestPath, 'utf-8');
|
|
446
|
+
return getDefaultLanguageFromManifestXml(manifest);
|
|
447
|
+
}
|
|
433
448
|
function generateExtensions(config) {
|
|
434
449
|
const extensions = [];
|
|
435
450
|
if (config.extensions?.shareTarget) {
|
|
@@ -711,6 +726,8 @@ function prepareAppxContent(projectRoot, arch, config, tauriConfig, minVersion,
|
|
|
711
726
|
const srcTauriDir = path.join(projectRoot, 'src-tauri');
|
|
712
727
|
const buildDir = path.join(srcTauriDir, 'target', target, 'release');
|
|
713
728
|
const appxDir = path.join(srcTauriDir, 'target', 'appx', arch);
|
|
729
|
+
// Clear stale output from previous builds
|
|
730
|
+
fs.rmSync(appxDir, { recursive: true, force: true });
|
|
714
731
|
// Create directories
|
|
715
732
|
fs.mkdirSync(path.join(appxDir, 'Assets'), { recursive: true });
|
|
716
733
|
// Copy exe
|
|
@@ -771,6 +788,16 @@ function copyBundledResources(projectRoot, appxDir, tauriConfig) {
|
|
|
771
788
|
|
|
772
789
|
const execPromise = promisify(exec);
|
|
773
790
|
const SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
791
|
+
function isCiEnvironment() {
|
|
792
|
+
const ci = process.env.CI;
|
|
793
|
+
if (!ci)
|
|
794
|
+
return false;
|
|
795
|
+
const normalized = ci.toLowerCase();
|
|
796
|
+
return normalized !== '0' && normalized !== 'false';
|
|
797
|
+
}
|
|
798
|
+
function shouldAnimateSpinner() {
|
|
799
|
+
return Boolean(process.stdout.isTTY) && !isCiEnvironment();
|
|
800
|
+
}
|
|
774
801
|
class Spinner {
|
|
775
802
|
frameIndex = 0;
|
|
776
803
|
intervalId = null;
|
|
@@ -835,7 +862,7 @@ function isVersionSufficient(version, minVersion) {
|
|
|
835
862
|
return false;
|
|
836
863
|
return patch >= minPatch;
|
|
837
864
|
}
|
|
838
|
-
const MIN_MSIXBUNDLE_CLI_VERSION = '1.1.
|
|
865
|
+
const MIN_MSIXBUNDLE_CLI_VERSION = '1.1.4';
|
|
839
866
|
async function promptInstall(message) {
|
|
840
867
|
const rl = readline.createInterface({
|
|
841
868
|
input: process.stdin,
|
|
@@ -851,6 +878,8 @@ async function promptInstall(message) {
|
|
|
851
878
|
async function execWithProgress(command, options) {
|
|
852
879
|
const verbose = options?.verbose ?? false;
|
|
853
880
|
const message = options?.message ?? 'Running...';
|
|
881
|
+
const useSpinner = !verbose && shouldAnimateSpinner();
|
|
882
|
+
const useStaticProgress = !verbose && !useSpinner;
|
|
854
883
|
return new Promise((resolve, reject) => {
|
|
855
884
|
const [cmd, ...args] = command.split(' ');
|
|
856
885
|
const child = spawn(cmd, args, {
|
|
@@ -860,10 +889,13 @@ async function execWithProgress(command, options) {
|
|
|
860
889
|
});
|
|
861
890
|
let spinner = null;
|
|
862
891
|
let capturedOutput = '';
|
|
863
|
-
if (
|
|
892
|
+
if (useSpinner) {
|
|
864
893
|
spinner = new Spinner(message);
|
|
865
894
|
spinner.start();
|
|
866
895
|
}
|
|
896
|
+
else if (useStaticProgress) {
|
|
897
|
+
console.log(message);
|
|
898
|
+
}
|
|
867
899
|
child.stdout?.on('data', (data) => {
|
|
868
900
|
if (verbose) {
|
|
869
901
|
process.stdout.write(data);
|
|
@@ -883,10 +915,16 @@ async function execWithProgress(command, options) {
|
|
|
883
915
|
child.on('close', (code) => {
|
|
884
916
|
if (code === 0) {
|
|
885
917
|
spinner?.stop(true);
|
|
918
|
+
if (useStaticProgress) {
|
|
919
|
+
console.log(`Done: ${message}`);
|
|
920
|
+
}
|
|
886
921
|
resolve();
|
|
887
922
|
}
|
|
888
923
|
else {
|
|
889
924
|
spinner?.fail();
|
|
925
|
+
if (useStaticProgress) {
|
|
926
|
+
console.error(`Failed: ${message}`);
|
|
927
|
+
}
|
|
890
928
|
if (!verbose && capturedOutput) {
|
|
891
929
|
console.error('\nBuild output:\n' + capturedOutput);
|
|
892
930
|
}
|
|
@@ -895,6 +933,9 @@ async function execWithProgress(command, options) {
|
|
|
895
933
|
});
|
|
896
934
|
child.on('error', (error) => {
|
|
897
935
|
spinner?.fail();
|
|
936
|
+
if (useStaticProgress) {
|
|
937
|
+
console.error(`Failed: ${message}`);
|
|
938
|
+
}
|
|
898
939
|
if (!verbose && capturedOutput) {
|
|
899
940
|
console.error('\nBuild output:\n' + capturedOutput);
|
|
900
941
|
}
|
|
@@ -1026,6 +1067,17 @@ async function build(options) {
|
|
|
1026
1067
|
outDir,
|
|
1027
1068
|
...appxDirs.flatMap(({ arch, dir }) => [`--dir-${arch}`, dir]),
|
|
1028
1069
|
];
|
|
1070
|
+
// Resource index generation (resources.pri)
|
|
1071
|
+
if (bundleConfig.resourceIndex?.enabled) {
|
|
1072
|
+
const defaultLanguage = getDefaultLanguageFromManifestFile(path.join(appxDirs[0].dir, 'AppxManifest.xml'));
|
|
1073
|
+
args.push('--makepri');
|
|
1074
|
+
if (defaultLanguage) {
|
|
1075
|
+
args.push('--makepri-default-language', defaultLanguage);
|
|
1076
|
+
}
|
|
1077
|
+
if (bundleConfig.resourceIndex.keepConfig) {
|
|
1078
|
+
args.push('--makepri-keep-config');
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1029
1081
|
// Signing
|
|
1030
1082
|
if (bundleConfig.signing?.pfx) {
|
|
1031
1083
|
args.push('--pfx', bundleConfig.signing.pfx);
|
|
@@ -1755,4 +1807,4 @@ async function extensionRemove(type, name, options) {
|
|
|
1755
1807
|
}
|
|
1756
1808
|
}
|
|
1757
1809
|
|
|
1758
|
-
export { DEFAULT_CAPABILITIES, DEFAULT_MIN_WINDOWS_VERSION, DEFAULT_RUNNER, DEVICE_CAPABILITIES, GENERAL_CAPABILITIES, MSIX_ASSETS, RESTRICTED_CAPABILITIES, build, extensionAddAppExecutionAlias, extensionAddAppService, extensionAddAutoplay, extensionAddBackgroundTask, extensionAddContextMenu, extensionAddFileAssociation, extensionAddPreviewHandler, extensionAddProtocol, extensionAddThumbnailHandler, extensionDisablePrintTaskSettings, extensionDisableShareTarget, extensionDisableStartupTask, extensionDisableToastActivation, extensionEnablePrintTaskSettings, extensionEnableShareTarget, extensionEnableStartupTask, extensionEnableToastActivation, extensionList, extensionRemove, findProjectRoot, generateManifest, generateManifestTemplate, getPackageVersion, getWindowsDir, init, prepareAppxContent, readBundleConfig$1 as readBundleConfig, readTauriConfig, readTauriWindowsConfig, resolveVersion, toFourPartVersion, validateCapabilities };
|
|
1810
|
+
export { DEFAULT_CAPABILITIES, DEFAULT_MIN_WINDOWS_VERSION, DEFAULT_RUNNER, DEVICE_CAPABILITIES, GENERAL_CAPABILITIES, MSIX_ASSETS, RESTRICTED_CAPABILITIES, build, extensionAddAppExecutionAlias, extensionAddAppService, extensionAddAutoplay, extensionAddBackgroundTask, extensionAddContextMenu, extensionAddFileAssociation, extensionAddPreviewHandler, extensionAddProtocol, extensionAddThumbnailHandler, extensionDisablePrintTaskSettings, extensionDisableShareTarget, extensionDisableStartupTask, extensionDisableToastActivation, extensionEnablePrintTaskSettings, extensionEnableShareTarget, extensionEnableStartupTask, extensionEnableToastActivation, extensionList, extensionRemove, findProjectRoot, generateManifest, generateManifestTemplate, getDefaultLanguageFromManifestFile, getDefaultLanguageFromManifestXml, getPackageVersion, getWindowsDir, init, prepareAppxContent, readBundleConfig$1 as readBundleConfig, readTauriConfig, readTauriWindowsConfig, resolveVersion, toFourPartVersion, validateCapabilities };
|
package/dist/types.d.ts
CHANGED
|
@@ -24,6 +24,10 @@ export interface CapabilitiesConfig {
|
|
|
24
24
|
export interface BundleConfig {
|
|
25
25
|
publisher?: string;
|
|
26
26
|
publisherDisplayName?: string;
|
|
27
|
+
resourceIndex?: {
|
|
28
|
+
enabled?: boolean;
|
|
29
|
+
keepConfig?: boolean;
|
|
30
|
+
};
|
|
27
31
|
capabilities?: CapabilitiesConfig;
|
|
28
32
|
extensions?: {
|
|
29
33
|
shareTarget?: boolean;
|
package/dist/utils/exec.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare function execAsync(command: string, options?: {
|
|
|
16
16
|
export declare function isMsixbundleCliInstalled(): Promise<boolean>;
|
|
17
17
|
export declare function getMsixbundleCliVersion(): Promise<string | null>;
|
|
18
18
|
export declare function isVersionSufficient(version: string, minVersion: string): boolean;
|
|
19
|
-
export declare const MIN_MSIXBUNDLE_CLI_VERSION = "1.1.
|
|
19
|
+
export declare const MIN_MSIXBUNDLE_CLI_VERSION = "1.1.4";
|
|
20
20
|
export declare function promptInstall(message: string): Promise<boolean>;
|
|
21
21
|
export interface ExecWithProgressOptions {
|
|
22
22
|
cwd?: string;
|