more refactor

This commit is contained in:
LiBr
2026-04-10 20:34:14 +08:00
parent 8d31144741
commit 72123cc922
47 changed files with 868 additions and 365 deletions

19
dependencies/webmuxd/src/browser.ts vendored Normal file
View File

@@ -0,0 +1,19 @@
export { CONSOLE_LOGGER, NULL_LOGGER, type Logger } from "./logger"
export { WebUsbTransport, type WebUsbTransportOptions } from "./core/webusb-transport"
export {
DirectUsbMuxClient,
LOCKDOWN_PORT,
installIpaViaInstProxy,
sanitizeIpaFileName,
createHostId,
createSystemBuid,
encodeStoredPairRecord,
decodeStoredPairRecord,
type PairRecord,
type StoredPairRecordPayload,
type WebUsbTransportInstance,
} from "./core/imobiledevice-client"
export {
createOpenSslWasmTlsFactory,
generatePairRecordWithOpenSslWasm,
} from "./core/openssl-wasm-browser"

View File

@@ -0,0 +1,112 @@
import type { TlsConnection, TlsConnectionFactory } from "./imobiledevice-client"
import type {
OpenSslWasmConnectionRequest,
OpenSslWasmPairRecordRequest,
} from "./openssl-wasm"
interface OpenSslWasmBrowserModule {
default(input?: unknown): Promise<unknown>
OpensslClient: new (
serverName: string,
caCertificatePem: string,
certificatePem: string,
privateKeyPem: string,
) => TlsConnection
libimobiledevice_generate_pair_record(
devicePublicKey: Uint8Array,
hostId: string,
systemBuid: string,
): string
}
const OPENSSL_WASM_MODULE_URL = new URL(
"../openssl-wasm/dist/index.mjs",
import.meta.url,
)
let opensslWasmModule: OpenSslWasmBrowserModule | null = null
let opensslWasmModulePromise: Promise<OpenSslWasmBrowserModule> | null = null
let opensslWasmInitPromise: Promise<void> | null = null
const toOpenSslWasmModule = (moduleValue: unknown): OpenSslWasmBrowserModule => {
if (!moduleValue || typeof moduleValue !== "object") {
throw new Error("OpenSSL wasm module did not return an object")
}
const candidate = moduleValue as Record<string, unknown>
if (typeof candidate.default !== "function") {
throw new Error("OpenSSL wasm module is missing its default initializer")
}
if (typeof candidate.OpensslClient !== "function") {
throw new Error("OpenSSL wasm module is missing OpensslClient")
}
if (typeof candidate.libimobiledevice_generate_pair_record !== "function") {
throw new Error("OpenSSL wasm module is missing pair record generation")
}
return candidate as unknown as OpenSslWasmBrowserModule
}
const loadOpenSslWasmModule = async (): Promise<OpenSslWasmBrowserModule> => {
if (!opensslWasmModulePromise) {
opensslWasmModulePromise = import(
/* @vite-ignore */
OPENSSL_WASM_MODULE_URL.href
).then((moduleValue) => {
const loadedModule = toOpenSslWasmModule(moduleValue)
opensslWasmModule = loadedModule
return loadedModule
})
}
return await opensslWasmModulePromise
}
const requireOpenSslWasmModule = (): OpenSslWasmBrowserModule => {
if (!opensslWasmModule) {
throw new Error("OpenSSL wasm is not ready. Call ensureOpenSslWasmReady() first.")
}
return opensslWasmModule
}
export const ensureOpenSslWasmReady = async (): Promise<void> => {
if (!opensslWasmInitPromise) {
opensslWasmInitPromise = loadOpenSslWasmModule().then(async (moduleValue) => {
await moduleValue.default()
})
}
await opensslWasmInitPromise
}
export const createOpenSslWasmConnection = (
request: OpenSslWasmConnectionRequest,
): TlsConnection => {
const moduleValue = requireOpenSslWasmModule()
return new moduleValue.OpensslClient(
request.serverName,
request.caCertificatePem,
request.certificatePem,
request.privateKeyPem,
)
}
export const createOpenSslWasmTlsFactory = (): TlsConnectionFactory => {
return {
ensureReady: ensureOpenSslWasmReady,
createConnection: createOpenSslWasmConnection,
}
}
export const generatePairRecordWithOpenSslWasm = async (
request: OpenSslWasmPairRecordRequest,
): Promise<string> => {
await ensureOpenSslWasmReady()
const moduleValue = requireOpenSslWasmModule()
return moduleValue.libimobiledevice_generate_pair_record(
new Uint8Array(request.devicePublicKey),
request.hostId,
request.systemBuid,
)
}

View File

@@ -28,7 +28,7 @@ interface OpenSslWasmModule {
): string
}
const OPENSSL_WASM_MODULE_SPECIFIER = "../openssl-wasm/openssl_wasm.js"
const OPENSSL_WASM_MODULE_SPECIFIER = "../openssl-wasm/dist/index.mjs"
/**
* Keep native `import()` intact in the CommonJS build so bundlers can defer the

View File

@@ -1,4 +1,4 @@
import { CONSOLE_LOGGER, Logger, NULL_LOGGER } from "../webmuxd"
import { CONSOLE_LOGGER, Logger, NULL_LOGGER } from "../logger"
import { DataHandler, DisconnectHandler, UsbMuxTransport } from "./transport"
const USBMUX_CLASS = 255

38
dependencies/webmuxd/src/logger.ts vendored Normal file
View File

@@ -0,0 +1,38 @@
type LogLevel = "debug" | "info" | "warn" | "error"
export interface Logger {
log(level: LogLevel, message: string): void
}
export const NULL_LOGGER = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
log: (level: LogLevel, message: string): void => {
return
},
}
export const CONSOLE_LOGGER = {
log: (level: LogLevel, message: string): void => {
switch (level) {
case "info":
// eslint-disable-next-line no-console
console.log(message)
break
case "warn":
// eslint-disable-next-line no-console
console.warn(message)
break
case "error":
// eslint-disable-next-line no-console
console.error(message)
break
case "debug":
// eslint-disable-next-line no-console
console.debug(message)
break
default:
// eslint-disable-next-line no-console
console.error(`Unknown log level ${level}: ${message}`)
}
},
}

View File

@@ -0,0 +1,2 @@
export { default } from "../../../../../wasm/openssl/dist/index.mjs"
export * from "../../../../../wasm/openssl/dist/index.mjs"

View File

@@ -1,47 +1,11 @@
import { NULL_LOGGER, type Logger } from "./logger"
const USBMUX_USB_FILTER = [{ vendorId: 0x5ac, productId: 0x12a8 }];
const USBMUX_CLASS = 255;
const USBMUX_SUBCLASS = 254;
const USBMUX_PROTOCOL = 2;
type LogLevel = "debug" | "info" | "warn" | "error"
export interface Logger {
log(level: LogLevel, message: string): void
}
export const NULL_LOGGER = {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
log: (level: LogLevel, message: string): void => {
return
}
}
export const CONSOLE_LOGGER = {
log: (level: LogLevel, message: string): void => {
switch (level) {
case "info":
// eslint-disable-next-line no-console
console.log(message)
break
case "warn":
// eslint-disable-next-line no-console
console.warn(message)
break
case "error":
// eslint-disable-next-line no-console
console.error(message)
break
case "debug":
// eslint-disable-next-line no-console
console.debug(message)
break
default:
// eslint-disable-next-line no-console
console.error(`Unknown log level ${level}: ${message}`)
}
}
}
export { CONSOLE_LOGGER, NULL_LOGGER, type Logger } from "./logger"
export default class MobileDevice {
static logger: Logger = NULL_LOGGER