win_webview2 1.1.14 → 1.1.15
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/dist/node/builder/versiontool.js +1 -0
- package/dist/node/tsExport/dirnameTool.js +7 -0
- package/dist/node/tsExport/downloadModule.d.ts +32 -0
- package/dist/node/tsExport/downloadModule.js +66 -0
- package/dist/node/tsExport/downloader.d.ts +6 -0
- package/dist/node/tsExport/downloader.js +78 -0
- package/dist/node/tsExport/winwebview2.d.ts +1 -31
- package/dist/node/tsExport/winwebview2.js +3 -33
- package/dist/node/tsExport/ww2_config.d.ts +3 -1
- package/package.json +2 -2
- package/src/srcNode/builder/versiontool.ts +2 -2
- package/src/srcNode/tsExport/dirnameTool.ts +14 -5
- package/src/srcNode/tsExport/downloadModule.ts +128 -0
- package/src/srcNode/tsExport/downloader.ts +51 -0
- package/src/srcNode/tsExport/winwebview2.ts +4 -79
- package/src/srcNode/tsExport/ww2_config.ts +5 -1
- package/srcInternal/copyDll.ts +5 -5
- package/win_lib/Win32/WebView2Loader.dll +0 -0
- package/win_lib/Win32/exeOpenner.exe +0 -0
- package/win_lib/Win32/splash.png +0 -0
- package/win_lib/Win32/ww2_addon.node +0 -0
|
@@ -31,5 +31,12 @@ function getWWVNodeModuleFolder() {
|
|
|
31
31
|
if (userRootProject == null)
|
|
32
32
|
throw "root project user not found";
|
|
33
33
|
let nodeModuleFolder = node_path_1.default.join(userRootProject, "node_modules/win_webview2");
|
|
34
|
+
if (!(0, node_fs_1.existsSync)(nodeModuleFolder)) {
|
|
35
|
+
if (userRootProject.endsWith("win_webview2")) {
|
|
36
|
+
console.log("on source win_webview2folder \n\n");
|
|
37
|
+
let npath = node_path_1.default.join(nodeModuleFolder, "../../");
|
|
38
|
+
nodeModuleFolder = npath;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
34
41
|
return nodeModuleFolder;
|
|
35
42
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
interface Ww2WebConfig {
|
|
2
|
+
callback: (err: any, data: any) => void;
|
|
3
|
+
wclassname: string;
|
|
4
|
+
url: string;
|
|
5
|
+
title: string;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
isKiosk: boolean;
|
|
9
|
+
isMaximize: boolean;
|
|
10
|
+
isDebug: boolean;
|
|
11
|
+
}
|
|
12
|
+
interface WW2FileDialogArg {
|
|
13
|
+
callback: (err: any, data: any) => void;
|
|
14
|
+
filter: string;
|
|
15
|
+
ownerClassName: string;
|
|
16
|
+
}
|
|
17
|
+
export interface WW2ControlWindowsArg {
|
|
18
|
+
wndClassName: string;
|
|
19
|
+
controlcmd: "close" | "move" | "maximize" | "minimize" | "resize" | "check";
|
|
20
|
+
left?: number;
|
|
21
|
+
top?: number;
|
|
22
|
+
height?: number;
|
|
23
|
+
width?: number;
|
|
24
|
+
}
|
|
25
|
+
interface Ww2Module {
|
|
26
|
+
openWeb: (arg: Ww2WebConfig) => void;
|
|
27
|
+
openFileDialog: (arg: WW2FileDialogArg) => void;
|
|
28
|
+
openFolderDialog: (arg: WW2FileDialogArg) => void;
|
|
29
|
+
controlWindow: (arg: WW2ControlWindowsArg) => void;
|
|
30
|
+
}
|
|
31
|
+
export declare function getModule(): Promise<Ww2Module>;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getModule = getModule;
|
|
7
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
+
const dirnameTool_1 = require("./dirnameTool");
|
|
9
|
+
const ww2_config_1 = require("./ww2_config");
|
|
10
|
+
const node_fs_1 = require("node:fs");
|
|
11
|
+
const downloader_1 = require("./downloader");
|
|
12
|
+
const promises_1 = require("node:fs/promises");
|
|
13
|
+
function getLibFilePath(libName, platform) {
|
|
14
|
+
let modulePath = (0, dirnameTool_1.getWWVNodeModuleFolder)();
|
|
15
|
+
modulePath = node_path_1.default.join(modulePath, "win_lib", platform, libName);
|
|
16
|
+
return modulePath;
|
|
17
|
+
}
|
|
18
|
+
const binFileVersion = "1.1.14";
|
|
19
|
+
async function downloadModuleFile(libname, platform) {
|
|
20
|
+
let filePath = getLibFilePath(libname, platform);
|
|
21
|
+
let url = `https://github.com/nnttoo/win_webview2/releases/download/${binFileVersion}_${platform}/${libname}`;
|
|
22
|
+
console.log("Bin File Version : " + binFileVersion);
|
|
23
|
+
console.log("downloading :\n", url);
|
|
24
|
+
try {
|
|
25
|
+
let dir = node_path_1.default.dirname(filePath);
|
|
26
|
+
await (0, promises_1.mkdir)(dir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
}
|
|
30
|
+
await (0, downloader_1.downloadFile)(url, filePath);
|
|
31
|
+
}
|
|
32
|
+
async function downloadModule(platform) {
|
|
33
|
+
await downloadModuleFile("ww2_addon.node", platform);
|
|
34
|
+
await downloadModuleFile("WebView2Loader.dll", platform);
|
|
35
|
+
await downloadModuleFile("exeOpenner.exe", platform);
|
|
36
|
+
await downloadModuleFile("splash.png", platform);
|
|
37
|
+
}
|
|
38
|
+
async function getModule() {
|
|
39
|
+
let addOnName = "ww2_addon.node";
|
|
40
|
+
let config = await (0, ww2_config_1.readConfig)();
|
|
41
|
+
if (config == null)
|
|
42
|
+
throw "cannot read config";
|
|
43
|
+
let filepath = (() => {
|
|
44
|
+
let userFolder = (0, dirnameTool_1.findUserProjectRoot)();
|
|
45
|
+
if (userFolder == null)
|
|
46
|
+
return null;
|
|
47
|
+
let r = node_path_1.default.join(userFolder, addOnName);
|
|
48
|
+
if (!(0, node_fs_1.existsSync)(r))
|
|
49
|
+
return null;
|
|
50
|
+
return r;
|
|
51
|
+
})();
|
|
52
|
+
filepath = await (async () => {
|
|
53
|
+
if (filepath != null)
|
|
54
|
+
return filepath;
|
|
55
|
+
let wwvModulePath = (0, dirnameTool_1.getWWVNodeModuleFolder)();
|
|
56
|
+
let r = node_path_1.default.join(wwvModulePath, `win_lib/${config.platform}/ww2_addon.node`);
|
|
57
|
+
return r;
|
|
58
|
+
})();
|
|
59
|
+
if (filepath == null)
|
|
60
|
+
throw "file path is null";
|
|
61
|
+
if (!(0, node_fs_1.existsSync)(filepath)) {
|
|
62
|
+
await downloadModule(config.platform);
|
|
63
|
+
}
|
|
64
|
+
let myAddon = require(filepath);
|
|
65
|
+
return myAddon;
|
|
66
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.downloadFile = downloadFile;
|
|
37
|
+
const http = __importStar(require("http"));
|
|
38
|
+
const https = __importStar(require("https"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const url_1 = require("url");
|
|
41
|
+
/**
|
|
42
|
+
* Fungsi download native dengan TypeScript
|
|
43
|
+
* @param src - URL sumber file
|
|
44
|
+
* @param filePath - Path lengkap tujuan penyimpanan
|
|
45
|
+
*/
|
|
46
|
+
async function downloadFile(src, filePath) {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const url = new url_1.URL(src);
|
|
49
|
+
const protocol = url.protocol === 'https:' ? https : http;
|
|
50
|
+
// Gunakan flags 'w' untuk memastikan file dibuka untuk ditulisi
|
|
51
|
+
const file = fs.createWriteStream(filePath, { flags: 'w' });
|
|
52
|
+
protocol.get(src, (response) => {
|
|
53
|
+
const { statusCode } = response;
|
|
54
|
+
if (statusCode && statusCode >= 300 && statusCode < 400 && response.headers.location) {
|
|
55
|
+
file.destroy(); // Hancurkan stream sebelum redirect
|
|
56
|
+
return resolve(downloadFile(response.headers.location, filePath));
|
|
57
|
+
}
|
|
58
|
+
if (statusCode !== 200) {
|
|
59
|
+
file.destroy();
|
|
60
|
+
fs.unlink(filePath, () => { });
|
|
61
|
+
return reject(new Error(`Download gagal! Status: ${statusCode}`));
|
|
62
|
+
}
|
|
63
|
+
response.pipe(file);
|
|
64
|
+
// GANTI DISINI: Gunakan event 'close' bukan 'finish'
|
|
65
|
+
file.on('close', () => {
|
|
66
|
+
resolve(filePath);
|
|
67
|
+
});
|
|
68
|
+
file.on('error', (err) => {
|
|
69
|
+
fs.unlink(filePath, () => { });
|
|
70
|
+
reject(err);
|
|
71
|
+
});
|
|
72
|
+
}).on('error', (err) => {
|
|
73
|
+
file.destroy();
|
|
74
|
+
fs.unlink(filePath, () => { });
|
|
75
|
+
reject(err);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
@@ -1,37 +1,7 @@
|
|
|
1
1
|
import { getWWVNodeModuleFolder } from "./dirnameTool";
|
|
2
2
|
import { readConfig } from "./ww2_config";
|
|
3
|
-
interface Ww2WebConfig {
|
|
4
|
-
callback: (err: any, data: any) => void;
|
|
5
|
-
wclassname: string;
|
|
6
|
-
url: string;
|
|
7
|
-
title: string;
|
|
8
|
-
width: number;
|
|
9
|
-
height: number;
|
|
10
|
-
isKiosk: boolean;
|
|
11
|
-
isMaximize: boolean;
|
|
12
|
-
isDebug: boolean;
|
|
13
|
-
}
|
|
14
|
-
interface WW2FileDialogArg {
|
|
15
|
-
callback: (err: any, data: any) => void;
|
|
16
|
-
filter: string;
|
|
17
|
-
ownerClassName: string;
|
|
18
|
-
}
|
|
19
|
-
export interface WW2ControlWindowsArg {
|
|
20
|
-
wndClassName: string;
|
|
21
|
-
controlcmd: "close" | "move" | "maximize" | "minimize" | "resize" | "check";
|
|
22
|
-
left?: number;
|
|
23
|
-
top?: number;
|
|
24
|
-
height?: number;
|
|
25
|
-
width?: number;
|
|
26
|
-
}
|
|
27
|
-
interface Ww2Module {
|
|
28
|
-
openWeb: (arg: Ww2WebConfig) => void;
|
|
29
|
-
openFileDialog: (arg: WW2FileDialogArg) => void;
|
|
30
|
-
openFolderDialog: (arg: WW2FileDialogArg) => void;
|
|
31
|
-
controlWindow: (arg: WW2ControlWindowsArg) => void;
|
|
32
|
-
}
|
|
33
|
-
export declare function getModule(): Promise<Ww2Module>;
|
|
34
3
|
export declare function closeSplash(): Promise<void>;
|
|
4
|
+
export * from "./downloadModule";
|
|
35
5
|
export * from "./ww2_server";
|
|
36
6
|
export { findUserProjectRoot } from "./dirnameTool";
|
|
37
7
|
export { readConfig };
|
|
@@ -13,53 +13,23 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
|
|
|
13
13
|
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
-
};
|
|
19
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
17
|
exports.getWWVNodeModuleFolder = exports.readConfig = exports.findUserProjectRoot = void 0;
|
|
21
|
-
exports.getModule = getModule;
|
|
22
18
|
exports.closeSplash = closeSplash;
|
|
23
|
-
const node_fs_1 = require("node:fs");
|
|
24
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
25
19
|
const dirnameTool_1 = require("./dirnameTool");
|
|
26
20
|
Object.defineProperty(exports, "getWWVNodeModuleFolder", { enumerable: true, get: function () { return dirnameTool_1.getWWVNodeModuleFolder; } });
|
|
27
21
|
const ww2_config_1 = require("./ww2_config");
|
|
28
22
|
Object.defineProperty(exports, "readConfig", { enumerable: true, get: function () { return ww2_config_1.readConfig; } });
|
|
29
|
-
|
|
30
|
-
let addOnName = "ww2_addon.node";
|
|
31
|
-
let filepath = (() => {
|
|
32
|
-
let userFolder = (0, dirnameTool_1.findUserProjectRoot)();
|
|
33
|
-
if (userFolder == null)
|
|
34
|
-
return null;
|
|
35
|
-
let r = node_path_1.default.join(userFolder, addOnName);
|
|
36
|
-
if (!(0, node_fs_1.existsSync)(r))
|
|
37
|
-
return null;
|
|
38
|
-
return r;
|
|
39
|
-
})();
|
|
40
|
-
filepath = await (async () => {
|
|
41
|
-
if (filepath != null)
|
|
42
|
-
return filepath;
|
|
43
|
-
let wwvModulePath = (0, dirnameTool_1.getWWVNodeModuleFolder)();
|
|
44
|
-
let config = await (0, ww2_config_1.readConfig)();
|
|
45
|
-
if (config == null)
|
|
46
|
-
return null;
|
|
47
|
-
let r = node_path_1.default.join(wwvModulePath, `win_lib/${config.platform}/ww2_addon.node`);
|
|
48
|
-
return r;
|
|
49
|
-
})();
|
|
50
|
-
if (filepath == null)
|
|
51
|
-
throw "file not found";
|
|
52
|
-
let myAddon = require(filepath);
|
|
53
|
-
return myAddon;
|
|
54
|
-
}
|
|
23
|
+
const downloadModule_1 = require("./downloadModule");
|
|
55
24
|
function closeSplash() {
|
|
56
|
-
return getModule().then((module) => {
|
|
25
|
+
return (0, downloadModule_1.getModule)().then((module) => {
|
|
57
26
|
module.controlWindow({
|
|
58
27
|
controlcmd: "close",
|
|
59
28
|
wndClassName: "mysplashclassname"
|
|
60
29
|
});
|
|
61
30
|
});
|
|
62
31
|
}
|
|
32
|
+
__exportStar(require("./downloadModule"), exports);
|
|
63
33
|
__exportStar(require("./ww2_server"), exports);
|
|
64
34
|
var dirnameTool_2 = require("./dirnameTool");
|
|
65
35
|
Object.defineProperty(exports, "findUserProjectRoot", { enumerable: true, get: function () { return dirnameTool_2.findUserProjectRoot; } });
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
export type WwvPlatFrom = 'x86' | 'x64';
|
|
2
|
+
export type WwfBinFileName = "exeOpenner.exe" | "WebView2Loader.dll" | "ww2_addon.node" | "splash.png";
|
|
1
3
|
export type ConfigWW2 = {
|
|
2
4
|
appname: string;
|
|
3
5
|
entry_point: string;
|
|
4
6
|
outdir: string;
|
|
5
|
-
platform:
|
|
7
|
+
platform: WwvPlatFrom;
|
|
6
8
|
};
|
|
7
9
|
export declare function readConfig(): Promise<ConfigWW2>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "win_webview2",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.15",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/nnttoo/win_webview2"
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"type": "commonjs",
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build_node": "tsc -p ./src/srcNode/tsconfig.json",
|
|
28
|
-
"build_node_watch": "npm run
|
|
28
|
+
"build_node_watch": "npm run build_node -- --watch",
|
|
29
29
|
"build_browser": "tsc -p ./src/srcBrowser/tsconfig.json",
|
|
30
30
|
"build_browser_watch": "npm run build_browser -- --watch",
|
|
31
31
|
"build_all" : "npm run build_node && npm run build_browser",
|
|
@@ -10,7 +10,7 @@ export async function getWWvVersion(){
|
|
|
10
10
|
let result = "";
|
|
11
11
|
|
|
12
12
|
try {
|
|
13
|
-
let wwvModulePath = getWWVNodeModuleFolder();
|
|
13
|
+
let wwvModulePath = getWWVNodeModuleFolder();
|
|
14
14
|
let jsonPath = path.join(wwvModulePath,"package.json");
|
|
15
15
|
let jsontxt = await readFile(jsonPath,"utf-8");
|
|
16
16
|
let jsonObj = JSON.parse(jsontxt) as { version : string};
|
|
@@ -18,7 +18,7 @@ export async function getWWvVersion(){
|
|
|
18
18
|
result = jsonObj.version;
|
|
19
19
|
|
|
20
20
|
} catch (error) {
|
|
21
|
-
|
|
21
|
+
console.log(error);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
return result;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import path, { dirname } from 'node:path';
|
|
1
|
+
import path from 'node:path';
|
|
3
2
|
import { existsSync } from 'node:fs';
|
|
4
3
|
|
|
5
4
|
|
|
@@ -26,11 +25,21 @@ export function findUserProjectRoot() {
|
|
|
26
25
|
}
|
|
27
26
|
return findUserProjectRootRecrusive(process.cwd());
|
|
28
27
|
}
|
|
29
|
-
|
|
28
|
+
|
|
30
29
|
export function getWWVNodeModuleFolder(){
|
|
31
|
-
let userRootProject = findUserProjectRoot();
|
|
30
|
+
let userRootProject = findUserProjectRoot();
|
|
32
31
|
if(userRootProject == null) throw "root project user not found";
|
|
33
32
|
|
|
34
33
|
let nodeModuleFolder = path.join(userRootProject,"node_modules/win_webview2");
|
|
34
|
+
|
|
35
|
+
if(!existsSync(nodeModuleFolder)){
|
|
36
|
+
if(userRootProject.endsWith("win_webview2")){
|
|
37
|
+
console.log("on source win_webview2folder \n\n")
|
|
38
|
+
|
|
39
|
+
let npath = path.join(nodeModuleFolder,"../../");
|
|
40
|
+
nodeModuleFolder = npath;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
}
|
|
35
44
|
return nodeModuleFolder;
|
|
36
|
-
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { findUserProjectRoot, getWWVNodeModuleFolder } from "./dirnameTool";
|
|
3
|
+
import { readConfig, WwfBinFileName, WwvPlatFrom } from "./ww2_config";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { config } from "node:process";
|
|
6
|
+
import { getWWvVersion } from "../builder/versiontool";
|
|
7
|
+
import { downloadFile } from "./downloader";
|
|
8
|
+
import { mkdir } from "node:fs/promises";
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
interface Ww2WebConfig {
|
|
14
|
+
callback: (err: any, data: any) => void;
|
|
15
|
+
wclassname: string;
|
|
16
|
+
url: string;
|
|
17
|
+
title: string;
|
|
18
|
+
|
|
19
|
+
width: number;
|
|
20
|
+
height: number;
|
|
21
|
+
isKiosk: boolean;
|
|
22
|
+
isMaximize: boolean;
|
|
23
|
+
isDebug: boolean;
|
|
24
|
+
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface WW2FileDialogArg {
|
|
28
|
+
callback: (err: any, data: any) => void;
|
|
29
|
+
filter: string;
|
|
30
|
+
ownerClassName: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
export interface WW2ControlWindowsArg {
|
|
36
|
+
wndClassName: string;
|
|
37
|
+
controlcmd: "close" | "move" | "maximize" | "minimize" | "resize" | "check",
|
|
38
|
+
left?: number;
|
|
39
|
+
top?: number;
|
|
40
|
+
height?: number;
|
|
41
|
+
width?: number;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
interface Ww2Module {
|
|
48
|
+
openWeb: (arg: Ww2WebConfig) => void;
|
|
49
|
+
openFileDialog: (arg: WW2FileDialogArg) => void;
|
|
50
|
+
openFolderDialog: (arg: WW2FileDialogArg) => void;
|
|
51
|
+
controlWindow: (arg: WW2ControlWindowsArg) => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function getLibFilePath(libName: WwfBinFileName, platform: WwvPlatFrom) {
|
|
55
|
+
let modulePath = getWWVNodeModuleFolder();
|
|
56
|
+
modulePath = path.join(modulePath, "win_lib", platform, libName);
|
|
57
|
+
|
|
58
|
+
return modulePath;
|
|
59
|
+
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const binFileVersion = "1.1.14";
|
|
63
|
+
|
|
64
|
+
async function downloadModuleFile(libname: WwfBinFileName, platform: WwvPlatFrom) {
|
|
65
|
+
let filePath = getLibFilePath(libname, platform);
|
|
66
|
+
let url = `https://github.com/nnttoo/win_webview2/releases/download/${binFileVersion}_${platform}/${libname}`;
|
|
67
|
+
console.log("Bin File Version : " + binFileVersion);
|
|
68
|
+
console.log("downloading :\n",url);
|
|
69
|
+
try {
|
|
70
|
+
|
|
71
|
+
let dir = path.dirname(filePath);
|
|
72
|
+
await mkdir(dir,{recursive : true});
|
|
73
|
+
} catch (error) {
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
await downloadFile(url,filePath);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
async function downloadModule(platform: WwvPlatFrom) {
|
|
81
|
+
await downloadModuleFile("ww2_addon.node", platform);
|
|
82
|
+
await downloadModuleFile("WebView2Loader.dll", platform);
|
|
83
|
+
await downloadModuleFile("exeOpenner.exe", platform);
|
|
84
|
+
await downloadModuleFile("splash.png", platform);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
export async function getModule() {
|
|
90
|
+
let addOnName = "ww2_addon.node";
|
|
91
|
+
|
|
92
|
+
let config = await readConfig();
|
|
93
|
+
if (config == null) throw "cannot read config";
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
let filepath = (() => {
|
|
97
|
+
|
|
98
|
+
let userFolder = findUserProjectRoot();
|
|
99
|
+
if (userFolder == null) return null;
|
|
100
|
+
let r = path.join(
|
|
101
|
+
userFolder,
|
|
102
|
+
addOnName
|
|
103
|
+
);
|
|
104
|
+
|
|
105
|
+
if (!existsSync(r)) return null;
|
|
106
|
+
|
|
107
|
+
return r;
|
|
108
|
+
|
|
109
|
+
})();
|
|
110
|
+
|
|
111
|
+
filepath = await (async () => {
|
|
112
|
+
if (filepath != null) return filepath;
|
|
113
|
+
let wwvModulePath = getWWVNodeModuleFolder();
|
|
114
|
+
let r = path.join(wwvModulePath, `win_lib/${config.platform}/ww2_addon.node`);
|
|
115
|
+
|
|
116
|
+
return r;
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
})();
|
|
120
|
+
|
|
121
|
+
if (filepath == null) throw "file path is null";
|
|
122
|
+
if (!existsSync(filepath)) {
|
|
123
|
+
await downloadModule(config.platform);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
let myAddon = require(filepath) as Ww2Module;
|
|
127
|
+
return myAddon;
|
|
128
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as http from 'http';
|
|
2
|
+
import * as https from 'https';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import { URL } from 'url';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Fungsi download native dengan TypeScript
|
|
8
|
+
* @param src - URL sumber file
|
|
9
|
+
* @param filePath - Path lengkap tujuan penyimpanan
|
|
10
|
+
*/
|
|
11
|
+
export async function downloadFile(src: string, filePath: string): Promise<string> {
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const url = new URL(src);
|
|
14
|
+
const protocol = url.protocol === 'https:' ? https : http;
|
|
15
|
+
|
|
16
|
+
// Gunakan flags 'w' untuk memastikan file dibuka untuk ditulisi
|
|
17
|
+
const file = fs.createWriteStream(filePath, { flags: 'w' });
|
|
18
|
+
|
|
19
|
+
protocol.get(src, (response: http.IncomingMessage) => {
|
|
20
|
+
const { statusCode } = response;
|
|
21
|
+
|
|
22
|
+
if (statusCode && statusCode >= 300 && statusCode < 400 && response.headers.location) {
|
|
23
|
+
file.destroy(); // Hancurkan stream sebelum redirect
|
|
24
|
+
return resolve(downloadFile(response.headers.location, filePath));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (statusCode !== 200) {
|
|
28
|
+
file.destroy();
|
|
29
|
+
fs.unlink(filePath, () => {});
|
|
30
|
+
return reject(new Error(`Download gagal! Status: ${statusCode}`));
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
response.pipe(file);
|
|
34
|
+
|
|
35
|
+
// GANTI DISINI: Gunakan event 'close' bukan 'finish'
|
|
36
|
+
file.on('close', () => {
|
|
37
|
+
resolve(filePath);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
file.on('error', (err: Error) => {
|
|
41
|
+
fs.unlink(filePath, () => {});
|
|
42
|
+
reject(err);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
}).on('error', (err: Error) => {
|
|
46
|
+
file.destroy();
|
|
47
|
+
fs.unlink(filePath, () => {});
|
|
48
|
+
reject(err);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
}
|
|
@@ -1,84 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { findUserProjectRoot, getWWVNodeModuleFolder } from "./dirnameTool";
|
|
6
|
-
import { ConfigWW2, readConfig } from "./ww2_config";
|
|
1
|
+
import { getWWVNodeModuleFolder } from "./dirnameTool";
|
|
2
|
+
import { readConfig } from "./ww2_config";
|
|
3
|
+
import { getModule } from "./downloadModule";
|
|
7
4
|
|
|
8
|
-
interface Ww2WebConfig {
|
|
9
|
-
callback: (err: any, data: any) => void;
|
|
10
|
-
wclassname: string;
|
|
11
|
-
url: string;
|
|
12
|
-
title: string;
|
|
13
5
|
|
|
14
|
-
width: number;
|
|
15
|
-
height: number;
|
|
16
|
-
isKiosk: boolean;
|
|
17
|
-
isMaximize: boolean;
|
|
18
|
-
isDebug: boolean;
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
interface WW2FileDialogArg {
|
|
23
|
-
callback: (err: any, data: any) => void;
|
|
24
|
-
filter: string;
|
|
25
|
-
ownerClassName: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export interface WW2ControlWindowsArg {
|
|
29
|
-
wndClassName: string;
|
|
30
|
-
controlcmd: "close" | "move" | "maximize" | "minimize" | "resize" | "check",
|
|
31
|
-
left?: number;
|
|
32
|
-
top?: number;
|
|
33
|
-
height?: number;
|
|
34
|
-
width?: number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
interface Ww2Module {
|
|
38
|
-
openWeb: (arg: Ww2WebConfig) => void;
|
|
39
|
-
openFileDialog: (arg: WW2FileDialogArg) => void;
|
|
40
|
-
openFolderDialog: (arg: WW2FileDialogArg) => void;
|
|
41
|
-
controlWindow: (arg: WW2ControlWindowsArg) => void;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
export async function getModule() {
|
|
47
|
-
let addOnName = "ww2_addon.node";
|
|
48
|
-
|
|
49
|
-
let filepath = (()=>{
|
|
50
|
-
|
|
51
|
-
let userFolder = findUserProjectRoot();
|
|
52
|
-
if(userFolder == null) return null;
|
|
53
|
-
let r = path.join(
|
|
54
|
-
userFolder,
|
|
55
|
-
addOnName
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
if(!existsSync(r)) return null;
|
|
59
|
-
|
|
60
|
-
return r;
|
|
61
|
-
|
|
62
|
-
})();
|
|
63
|
-
|
|
64
|
-
filepath = await ( async ()=>{
|
|
65
|
-
if(filepath != null) return filepath;
|
|
66
|
-
let wwvModulePath = getWWVNodeModuleFolder();
|
|
67
|
-
let config = await readConfig();
|
|
68
|
-
if(config == null) return null;
|
|
69
|
-
|
|
70
|
-
let r = path.join(wwvModulePath, `win_lib/${config.platform}/ww2_addon.node`);
|
|
71
|
-
|
|
72
|
-
return r;
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
})();
|
|
76
|
-
|
|
77
|
-
if(filepath == null) throw "file not found";
|
|
78
|
-
|
|
79
|
-
let myAddon = require(filepath) as Ww2Module;
|
|
80
|
-
return myAddon;
|
|
81
|
-
}
|
|
82
6
|
|
|
83
7
|
export function closeSplash(){
|
|
84
8
|
return getModule().then((module)=>{
|
|
@@ -90,6 +14,7 @@ export function closeSplash(){
|
|
|
90
14
|
}
|
|
91
15
|
|
|
92
16
|
|
|
17
|
+
export * from "./downloadModule"
|
|
93
18
|
|
|
94
19
|
export * from "./ww2_server"
|
|
95
20
|
export {findUserProjectRoot } from "./dirnameTool"
|
|
@@ -3,11 +3,15 @@ import { findUserProjectRoot } from "./dirnameTool";
|
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
|
|
6
|
+
export type WwvPlatFrom = 'x86' | 'x64';
|
|
7
|
+
|
|
8
|
+
export type WwfBinFileName = "exeOpenner.exe" | "WebView2Loader.dll" | "ww2_addon.node" | "splash.png"
|
|
9
|
+
|
|
6
10
|
export type ConfigWW2 = {
|
|
7
11
|
appname: string;
|
|
8
12
|
entry_point: string;
|
|
9
13
|
outdir: string;
|
|
10
|
-
platform:
|
|
14
|
+
platform: WwvPlatFrom
|
|
11
15
|
};
|
|
12
16
|
|
|
13
17
|
|
package/srcInternal/copyDll.ts
CHANGED
|
@@ -34,7 +34,7 @@ function debugDir(dirPath: string) {
|
|
|
34
34
|
|
|
35
35
|
}
|
|
36
36
|
try{
|
|
37
|
-
await mkdir(path.join(ww2SourcePath, "win_lib/
|
|
37
|
+
await mkdir(path.join(ww2SourcePath, "win_lib/x86"));
|
|
38
38
|
|
|
39
39
|
} catch{
|
|
40
40
|
|
|
@@ -58,21 +58,21 @@ function debugDir(dirPath: string) {
|
|
|
58
58
|
|
|
59
59
|
await copyFromRoot(
|
|
60
60
|
"exeOpener/build/x86/exeOpenner.exe",
|
|
61
|
-
"win_webview2/win_lib/
|
|
61
|
+
"win_webview2/win_lib/x86/exeOpenner.exe"
|
|
62
62
|
);
|
|
63
63
|
await copyFromRoot(
|
|
64
64
|
"exeOpener/build/x86/splash.png",
|
|
65
|
-
"win_webview2/win_lib/
|
|
65
|
+
"win_webview2/win_lib/x86/splash.png"
|
|
66
66
|
);
|
|
67
67
|
|
|
68
68
|
console.log("copy webview2 32");
|
|
69
69
|
await copyFromRoot(
|
|
70
70
|
"nodeAddOn/build/ia32/Release/ww2_addon.node",
|
|
71
|
-
"win_webview2/win_lib/
|
|
71
|
+
"win_webview2/win_lib/x86/ww2_addon.node"
|
|
72
72
|
);
|
|
73
73
|
await copyFromRoot(
|
|
74
74
|
"nodeAddOn/build/ia32/Release/WebView2Loader.dll",
|
|
75
|
-
"win_webview2/win_lib/
|
|
75
|
+
"win_webview2/win_lib/x86/WebView2Loader.dll"
|
|
76
76
|
);
|
|
77
77
|
|
|
78
78
|
console.log("copy webview2 64");
|
|
Binary file
|
|
Binary file
|
package/win_lib/Win32/splash.png
DELETED
|
Binary file
|
|
Binary file
|