catalyst-core 0.2.0-beta.2 → 0.3.0-beta.1
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/babel.native.config.cjs +8 -0
- package/bin/catalyst.js +49 -105
- package/changelog.md +8 -0
- package/dist/caching.js +1 -1
- package/dist/index.jsx +8 -0
- package/dist/logger.js +74 -3
- package/dist/native/androidProject/app/build.gradle.kts +1 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/CustomWebview.kt +143 -4
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/MainActivity.kt +26 -6
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/MetricsMonitor.kt +143 -17
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/NativeBridge.kt +6 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/WebCacheManager.kt +26 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/BridgeUtils.kt +56 -1
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/KeyboardUtil.kt +48 -8
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/PerfDeliveryState.kt +36 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/PerfEventBuffer.kt +289 -0
- package/dist/native/androidProject/app/src/main/java/io/yourname/androidproject/utils/ProfilerNavigationState.kt +13 -0
- package/dist/native/androidProject/app/src/test/java/io/yourname/androidproject/ProfilerLifecycleTest.kt +51 -0
- package/dist/native/androidSetup.js +300 -8
- package/dist/native/bridge/WebBridge.js +481 -59
- package/dist/native/bridge/constants/NativeInterfaces.js +290 -44
- package/dist/native/bridge/errors.js +250 -26
- package/dist/native/bridge/hooks/index.js +125 -1
- package/dist/native/bridge/hooks/useCamera.js +347 -9
- package/dist/native/bridge/hooks/useDataProtection.js +200 -2
- package/dist/native/bridge/hooks/useDeviceInfo.js +71 -2
- package/dist/native/bridge/hooks/useFilePicker.js +429 -2
- package/dist/native/bridge/hooks/useGoogleSignIn.js +81 -1
- package/dist/native/bridge/hooks/useHapticFeedback.js +196 -1
- package/dist/native/bridge/hooks/useIntent.js +95 -1
- package/dist/native/bridge/hooks/useNativeTransition.js +202 -27
- package/dist/native/bridge/hooks/useNetworkStatus.js +84 -3
- package/dist/native/bridge/hooks/useNotification.js +318 -2
- package/dist/native/bridge/hooks/useSafeArea.js +84 -2
- package/dist/native/bridge/hooks/useVideoStream.js +434 -6
- package/dist/native/bridge/hooks/utils.js +27 -1
- package/dist/native/bridge/hooks.js +16 -1
- package/dist/native/bridge/perf/collectors/ApiCollector.js +85 -0
- package/dist/native/bridge/perf/collectors/CacheCollector.js +215 -0
- package/dist/native/bridge/perf/collectors/HookCollector.js +165 -0
- package/dist/native/bridge/perf/collectors/InsightsCollector.js +505 -0
- package/dist/native/bridge/perf/collectors/InteractionCollector.js +273 -0
- package/dist/native/bridge/perf/collectors/KeyboardCollector.js +124 -0
- package/dist/native/bridge/perf/collectors/NavigationCollector.js +294 -0
- package/dist/native/bridge/perf/collectors/NetworkTimingCollector.js +183 -0
- package/dist/native/bridge/perf/collectors/RenderCollector.js +284 -0
- package/dist/native/bridge/perf/collectors/ScrollCollector.js +111 -0
- package/dist/native/bridge/perf/collectors/ThreadCollector.js +111 -0
- package/dist/native/bridge/perf/core/constants.js +126 -0
- package/dist/native/bridge/perf/core/measure.js +189 -0
- package/dist/native/bridge/perf/core/session.js +100 -0
- package/dist/native/bridge/perf/core/store.js +554 -0
- package/dist/native/bridge/perf/core/summary.js +174 -0
- package/dist/native/bridge/perf/core/traceExport.js +240 -0
- package/dist/native/bridge/perf/core/waterfalls.js +146 -0
- package/dist/native/bridge/perf/index.js +402 -0
- package/dist/native/bridge/safeArea.js +53 -5
- package/dist/native/bridge/standardizedHooks.js +595 -82
- package/dist/native/bridge/useBaseHook.js +274 -38
- package/dist/native/bridge/utils/CameraUtils.js +201 -56
- package/dist/native/bridge/utils/FileObjectConverter.js +129 -18
- package/dist/native/bridge/utils/NativeBridge.js +425 -141
- package/dist/native/buildAndroid/assets.js +510 -13
- package/dist/native/buildAndroid/build.js +296 -19
- package/dist/native/buildAndroid/config.js +87 -1
- package/dist/native/buildAndroid/index.js +374 -1
- package/dist/native/buildAppAndroid.js +34 -2
- package/dist/native/buildAppIos.js +62 -2
- package/dist/native/buildIos/assets.js +609 -8
- package/dist/native/buildIos/build.js +639 -20
- package/dist/native/buildIos/config.js +294 -12
- package/dist/native/buildIos/index.js +343 -6
- package/dist/native/buildIos/plugins.js +343 -16
- package/dist/native/internal-plugins/device-info-plugin/android/DeviceInfoPlugin.kt +43 -0
- package/dist/native/internal-plugins/device-info-plugin/ios/DeviceInfoPlugin.swift +28 -0
- package/dist/native/internal-plugins/device-info-plugin/manifest.json +19 -0
- package/dist/native/internalPluginUtils.js +232 -7
- package/dist/native/iosnativeWebView/Sources/Core/Constants/CatalystConstants.swift +19 -0
- package/dist/native/iosnativeWebView/Sources/Core/Constants/ConfigConstants.swift +4 -0
- package/dist/native/iosnativeWebView/Sources/Core/Utils/BootTimingUtility.swift +5 -1
- package/dist/native/iosnativeWebView/Sources/Core/Utils/CacheManager.swift +10 -0
- package/dist/native/iosnativeWebView/Sources/Core/Utils/DisplayLinkPerfMonitor.swift +89 -0
- package/dist/native/iosnativeWebView/Sources/Core/Utils/PerfEventBuffer.swift +373 -0
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeFileHandler.swift +35 -1
- package/dist/native/iosnativeWebView/Sources/Core/WebView/BridgeMessageValidator.swift +24 -11
- package/dist/native/iosnativeWebView/Sources/Core/WebView/NativeBridge.swift +9 -0
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebView.swift +126 -0
- package/dist/native/iosnativeWebView/Sources/Core/WebView/WebViewNavigationDelegate.swift +75 -1
- package/dist/native/iosnativeWebView/iosnativeWebViewTests/BridgeMessageValidatorTests.swift +13 -0
- package/dist/native/package.json +3 -0
- package/dist/native/plugin-bridge/PluginBridge.js +227 -1
- package/dist/native/pluginComposerAndroid.js +407 -23
- package/dist/native/pluginComposerIos.js +435 -11
- package/dist/native/renameAndroidProject.js +1094 -88
- package/dist/native/setupEmulatorIos.js +289 -22
- package/dist/native/setupServer.js +160 -19
- package/dist/native/terminalProgress.js +199 -11
- package/dist/native/utils.js +193 -15
- package/dist/offline/catalyst-sw.js +145 -1
- package/dist/offline/registerServiceWorker.js +33 -1
- package/dist/otel.js +375 -46
- package/dist/router/ClientRouter.js +14 -2
- package/dist/router/ServerRouter.js +9 -1
- package/dist/router.js +1 -1
- package/dist/scripts/build.js +112 -3
- package/dist/scripts/checkVersion.js +3 -1
- package/dist/scripts/cleanCache.js +30 -1
- package/dist/scripts/generateOfflineManifest.js +116 -1
- package/dist/scripts/loadEnvironmentVariables.js +32 -6
- package/dist/scripts/plugins.js +309 -1
- package/dist/scripts/preServerInit.js +13 -0
- package/dist/scripts/scriptUtils.js +54 -3
- package/dist/scripts/serve.js +51 -4
- package/dist/scripts/start.js +47 -10
- package/dist/scripts/validator.js +149 -1
- package/dist/sentry.cjs +127 -0
- package/dist/sentry.js +125 -5
- package/dist/server/expressServer.js +250 -5
- package/dist/server/manifestCache.js +36 -0
- package/dist/server/renderer/ChunkExtractor.js +144 -0
- package/dist/server/renderer/document/Body.jsx +59 -0
- package/dist/server/renderer/document/FastRefresh.jsx +20 -0
- package/dist/server/renderer/document/Head.jsx +60 -0
- package/dist/server/renderer/document/index.jsx +2 -0
- package/dist/server/renderer/extract.js +149 -31
- package/dist/server/renderer/handler.jsx +433 -0
- package/dist/server/renderer/index.js +8 -1
- package/dist/server/renderer/render.js +47 -0
- package/dist/server/utils/botDetectionMiddleware.js +29 -0
- package/dist/server/utils/cjsRequire.js +10 -0
- package/dist/server/utils/userAgentUtil.js +87 -9
- package/dist/server/utils/validator.js +164 -1
- package/dist/vite/FastRefresh.jsx +20 -0
- package/dist/vite/inject-cache-key-plugin.js +276 -0
- package/dist/vite/loadCustomViteConfig.js +22 -0
- package/dist/vite/manifest-categorization-plugin.js +455 -0
- package/dist/vite/node-loader.mjs +458 -0
- package/dist/vite/scssParams.js +21 -0
- package/dist/vite/vite.config.client.js +130 -0
- package/dist/vite/vite.config.js +422 -0
- package/dist/vite/vite.config.server.js +84 -0
- package/dist/web-router/components/MetaTag.jsx +34 -0
- package/dist/web-router/components/RouterDataProvider.jsx +332 -0
- package/dist/web-router/components/Split.jsx +200 -0
- package/dist/web-router/components/SplitInview.jsx +106 -0
- package/dist/web-router/components/SsrRequestContext.jsx +14 -0
- package/dist/web-router/context.jsx +12 -0
- package/dist/web-router/hooks.jsx +72 -0
- package/dist/web-router/types/components/MetaTag.d.ts +2 -0
- package/dist/web-router/types/components/RouterDataProvider.d.ts +95 -0
- package/dist/web-router/types/context.d.ts +14 -0
- package/dist/web-router/types/hooks.d.ts +1 -0
- package/dist/web-router/types/index.d.ts +3 -0
- package/dist/web-router/types/utils/metaDataUtils.d.ts +24 -0
- package/dist/web-router/utils/metaDataUtils.jsx +119 -0
- package/mcp_v2/conversion-tasks.json +35 -17
- package/mcp_v2/knowledge-base.json +124 -13
- package/mcp_v2/lib/helpers.js +10 -0
- package/mcp_v2/mcp.js +4 -4
- package/mcp_v2/package.json +1 -0
- package/mcp_v2/tools/build.js +116 -20
- package/mcp_v2/tools/conversion.js +106 -5
- package/mcp_v2/tools/tasks.js +18 -14
- package/package.json +35 -68
- package/babel.config.js +0 -32
- package/dist/index.js +0 -1
- package/dist/scripts/devBuild.js +0 -3
- package/dist/scripts/devServe.js +0 -3
- package/dist/scripts/loadScriptsBeforeServerStarts.js +0 -4
- package/dist/scripts/registerAliases.js +0 -6
- package/dist/server/renderer/document/Body.js +0 -11
- package/dist/server/renderer/document/Head.js +0 -9
- package/dist/server/renderer/document/index.js +0 -1
- package/dist/server/renderer/handler.js +0 -47
- package/dist/server/startServer.js +0 -57
- package/dist/webpack/babel-plugins/remove-client.plugin.js +0 -5
- package/dist/webpack/babel-plugins/remove-ssr.plugin.js +0 -5
- package/dist/webpack/babel.config.client.js +0 -1
- package/dist/webpack/babel.config.ssr.js +0 -1
- package/dist/webpack/base.babel.js +0 -7
- package/dist/webpack/development.client.babel.js +0 -10
- package/dist/webpack/production.client.babel.js +0 -4
- package/dist/webpack/production.ssr.babel.js +0 -8
- package/dist/webpack/scssParams.js +0 -9
|
@@ -1,19 +1,234 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
const
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _child_process = require("child_process");
|
|
4
|
+
var _fs = _interopRequireDefault(require("fs"));
|
|
5
|
+
var _utils = require("./utils.js");
|
|
6
|
+
var _TerminalProgress = _interopRequireDefault(require("./TerminalProgress.js"));
|
|
7
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
8
|
+
const configPath = `${process.env.PWD}/config/config.json`;
|
|
9
|
+
const {
|
|
10
|
+
setupServer
|
|
11
|
+
} = require("./setupServer.js");
|
|
12
|
+
const ITEMS_PER_PAGE = 10;
|
|
13
|
+
const steps = {
|
|
14
|
+
platform: "Check Platform Compatibility",
|
|
15
|
+
config: "Initialize Configuration",
|
|
16
|
+
simulator: "Configure iOS Simulator",
|
|
17
|
+
launch: "Launch iOS Simulator",
|
|
18
|
+
saveConfig: "Saving configuration",
|
|
19
|
+
setupServer: "Setup Server"
|
|
20
|
+
};
|
|
21
|
+
const progressPaddingConfig = {
|
|
22
|
+
titlePaddingTop: 2,
|
|
23
|
+
titlePaddingBottom: 1,
|
|
24
|
+
stepPaddingLeft: 4,
|
|
25
|
+
stepSpacing: 1,
|
|
26
|
+
errorPaddingLeft: 6,
|
|
27
|
+
bottomMargin: 2
|
|
28
|
+
};
|
|
29
|
+
const progress = new _TerminalProgress.default(steps, "Catalyst Universal Ios Setup", progressPaddingConfig);
|
|
30
|
+
async function initializeConfig() {
|
|
31
|
+
const configFile = _fs.default.readFileSync(configPath, "utf8");
|
|
32
|
+
const config = JSON.parse(configFile);
|
|
33
|
+
const {
|
|
34
|
+
WEBVIEW_CONFIG
|
|
35
|
+
} = config;
|
|
36
|
+
if (!WEBVIEW_CONFIG || Object.keys(WEBVIEW_CONFIG).length === 0) {
|
|
37
|
+
progress.log("WebView Config missing in " + configPath, "error");
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
if (!WEBVIEW_CONFIG.ios) {
|
|
41
|
+
WEBVIEW_CONFIG.ios = {};
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
WEBVIEW_CONFIG
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
async function saveConfig(newConfig) {
|
|
48
|
+
try {
|
|
49
|
+
// Read the existing config
|
|
50
|
+
const existingConfigFile = _fs.default.readFileSync(configPath, "utf8");
|
|
51
|
+
const existingConfig = JSON.parse(existingConfigFile);
|
|
52
|
+
|
|
53
|
+
// Merge the new WEBVIEW_CONFIG with existing config
|
|
54
|
+
const updatedConfig = {
|
|
55
|
+
...existingConfig,
|
|
56
|
+
// Preserve all existing keys
|
|
57
|
+
WEBVIEW_CONFIG: {
|
|
58
|
+
...existingConfig.WEBVIEW_CONFIG,
|
|
59
|
+
ios: newConfig.WEBVIEW_CONFIG.ios
|
|
60
|
+
} // Update only WEBVIEW_CONFIG
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
// Save the merged config
|
|
64
|
+
_fs.default.writeFileSync(configPath, JSON.stringify(updatedConfig, null, 2));
|
|
65
|
+
progress.log("Configuration saved successfully", "success");
|
|
66
|
+
} catch (error) {
|
|
67
|
+
progress.log("Failed to save configuration: " + error.message, "error");
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function setupIOSEnvironment() {
|
|
72
|
+
try {
|
|
73
|
+
progress.start("platform");
|
|
74
|
+
if (process.platform !== "darwin") {
|
|
75
|
+
progress.log("iOS Simulator is only available on macOS.");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
progress.complete("platform");
|
|
79
|
+
progress.start("config");
|
|
80
|
+
const {
|
|
81
|
+
WEBVIEW_CONFIG
|
|
82
|
+
} = await initializeConfig();
|
|
83
|
+
progress.complete("config");
|
|
84
|
+
progress.start("simulator");
|
|
85
|
+
await configureSimulator(WEBVIEW_CONFIG);
|
|
86
|
+
progress.complete("simulator");
|
|
87
|
+
progress.start("launch");
|
|
88
|
+
await launchIOSSimulator(WEBVIEW_CONFIG.ios.simulatorName);
|
|
89
|
+
progress.complete("launch");
|
|
90
|
+
progress.start("saveConfig");
|
|
91
|
+
const config = await (0, _utils.validateAndCompleteConfig)("ios", configPath);
|
|
92
|
+
progress.complete("saveConfig");
|
|
93
|
+
progress.start("setupServer");
|
|
94
|
+
await setupServer(configPath);
|
|
95
|
+
progress.start("setupServer");
|
|
96
|
+
progress.printTreeContent("Configuration Explanation", ["WEBVIEW_CONFIG: Main configuration object for the WebView setup", {
|
|
97
|
+
text: "port: Port number for the WebView server",
|
|
98
|
+
indent: 1,
|
|
99
|
+
prefix: "├─ ",
|
|
100
|
+
color: "gray"
|
|
101
|
+
}, {
|
|
102
|
+
text: "ios: iOS-specific configuration",
|
|
103
|
+
indent: 1,
|
|
104
|
+
prefix: "└─ ",
|
|
105
|
+
color: "gray"
|
|
106
|
+
}, {
|
|
107
|
+
text: "buildType: Build type (debug/release)",
|
|
108
|
+
indent: 2,
|
|
109
|
+
prefix: "├─ ",
|
|
110
|
+
color: "gray"
|
|
111
|
+
}, {
|
|
112
|
+
text: "appBundleId: iOS application bundle identifier",
|
|
113
|
+
indent: 2,
|
|
114
|
+
prefix: "├─ ",
|
|
115
|
+
color: "gray"
|
|
116
|
+
}, {
|
|
117
|
+
text: "simulatorName: Selected iOS simulator name",
|
|
118
|
+
indent: 2,
|
|
119
|
+
prefix: "└─ ",
|
|
120
|
+
color: "gray"
|
|
121
|
+
}]);
|
|
122
|
+
progress.printTreeContent("Final Configuration", [JSON.stringify(config, null, 2)]);
|
|
123
|
+
process.exit(0);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (progress.currentStep) {
|
|
126
|
+
progress.fail(progress.currentStep.id, error.message);
|
|
127
|
+
}
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async function displayPaginatedList(items, startIndex) {
|
|
132
|
+
const endIndex = Math.min(startIndex + ITEMS_PER_PAGE, items.length);
|
|
133
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
134
|
+
console.log(`${i + 1}. ${items[i]}`);
|
|
135
|
+
}
|
|
136
|
+
if (endIndex < items.length) {
|
|
137
|
+
console.log(`\nShowing ${startIndex + 1}-${endIndex} of ${items.length} items`);
|
|
138
|
+
console.log('Type "more" to see more items, or enter your selection: ');
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
async function getRuntime() {
|
|
144
|
+
const runtimesOutput = (0, _child_process.execSync)("xcrun simctl list runtimes -j").toString();
|
|
145
|
+
const parsedRuntimes = JSON.parse(runtimesOutput).runtimes;
|
|
146
|
+
const availableRuntime = parsedRuntimes.find(runtime => runtime.isAvailable || runtime.availability === "(available)" || runtime.availability === "available");
|
|
147
|
+
if (!availableRuntime) {
|
|
148
|
+
const runningSimulators = (0, _child_process.execSync)("xcrun simctl list devices booted").toString();
|
|
149
|
+
if (runningSimulators.includes("(Booted)") && parsedRuntimes.length > 0) {
|
|
150
|
+
console.log(`Using runtime: ${parsedRuntimes[0].name}`);
|
|
151
|
+
return parsedRuntimes[0];
|
|
152
|
+
}
|
|
153
|
+
console.error("No available iOS runtime found. Please install one through Xcode.");
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
console.log(`Using runtime: ${availableRuntime.name}`);
|
|
157
|
+
return availableRuntime;
|
|
158
|
+
}
|
|
159
|
+
async function configureSimulator(config) {
|
|
160
|
+
// If a simulator is already configured, skip the interactive picker
|
|
161
|
+
if (config.ios.simulatorName) {
|
|
162
|
+
progress.log(`Using configured simulator: ${config.ios.simulatorName}`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
progress.pause();
|
|
166
|
+
|
|
167
|
+
// Get the current runtime first
|
|
168
|
+
const runtime = await getRuntime();
|
|
169
|
+
|
|
170
|
+
// Get simulators specifically for this runtime
|
|
171
|
+
const simulatorsJson = JSON.parse((0, _child_process.execSync)("xcrun simctl list devices -j").toString());
|
|
172
|
+
const runtimeSimulators = simulatorsJson.devices[runtime.identifier] || [];
|
|
173
|
+
|
|
174
|
+
// Filter for available simulators only
|
|
175
|
+
const availableSimulators = runtimeSimulators.filter(sim => sim.availability === "(available)" || sim.isAvailable).map(sim => `${sim.name} (${sim.udid})`);
|
|
176
|
+
if (availableSimulators.length === 0) {
|
|
177
|
+
progress.log(`No available simulators found for runtime: ${runtime.name}`, "error");
|
|
178
|
+
progress.resume();
|
|
179
|
+
process.exit(1);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
let startIndex = 0;
|
|
183
|
+
console.log(`\nAvailable simulators for ${runtime.name} (or type 'new' to create a new one):`);
|
|
184
|
+
|
|
185
|
+
// eslint-disable-next-line no-constant-condition
|
|
186
|
+
while (true) {
|
|
187
|
+
const hasMore = await displayPaginatedList(availableSimulators, startIndex);
|
|
188
|
+
const simulatorChoice = await (0, _utils.promptUser)(hasMore ? "" : "\nEnter selection: ");
|
|
189
|
+
if (simulatorChoice.toLowerCase() === "more" && hasMore) {
|
|
190
|
+
startIndex += ITEMS_PER_PAGE;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (simulatorChoice.toLowerCase() === "new") {
|
|
194
|
+
const deviceTypes = JSON.parse((0, _child_process.execSync)("xcrun simctl list devicetypes --json").toString()).devicetypes;
|
|
195
|
+
const simulatorName = await (0, _utils.promptUser)("Enter a name for the new simulator: ");
|
|
196
|
+
|
|
197
|
+
// Use iPhone 15 Pro as default device type
|
|
198
|
+
const defaultDevice = deviceTypes.find(dt => dt.name.includes("iPhone 15 Pro")) || deviceTypes[0];
|
|
199
|
+
try {
|
|
200
|
+
(0, _utils.runCommand)(`xcrun simctl create "${simulatorName}" "${defaultDevice.identifier}" "${runtime.identifier}"`);
|
|
201
|
+
console.log(`Simulator "${simulatorName}" created successfully.`);
|
|
202
|
+
config.ios.simulatorName = simulatorName;
|
|
203
|
+
} catch (error) {
|
|
204
|
+
console.log(`Failed to create simulator "${simulatorName}". Error: ${error.message}`);
|
|
205
|
+
process.exit(1);
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
} else {
|
|
209
|
+
const index = parseInt(simulatorChoice) - 1;
|
|
210
|
+
if (index >= 0 && index < availableSimulators.length) {
|
|
211
|
+
const selectedSimulator = availableSimulators[index];
|
|
212
|
+
// Extract only the simulator name without ID and state
|
|
213
|
+
const simulatorName = selectedSimulator.split(" (")[0];
|
|
214
|
+
config.ios.simulatorName = simulatorName;
|
|
215
|
+
break;
|
|
216
|
+
} else {
|
|
217
|
+
console.log("Invalid selection. Please try again.");
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
progress.resume();
|
|
222
|
+
await saveConfig({
|
|
223
|
+
WEBVIEW_CONFIG: config
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// async function createDefaultSimulator(config, runtime) {
|
|
14
228
|
// const deviceTypes = JSON.parse(execSync("xcrun simctl list devicetypes --json").toString()).devicetypes
|
|
15
229
|
// const defaultDevice = deviceTypes.find((dt) => dt.name.includes("iPhone 15 Pro")) || deviceTypes[0]
|
|
16
230
|
// const simulatorName = `Default ${defaultDevice.name.split(" (")[0]}`
|
|
231
|
+
|
|
17
232
|
// try {
|
|
18
233
|
// runCommand(
|
|
19
234
|
// `xcrun simctl create "${simulatorName}" "${defaultDevice.identifier}" "${runtime.identifier}"`
|
|
@@ -26,13 +241,65 @@ const simulatorName=selectedSimulator.split(" (")[0];config.ios.simulatorName=si
|
|
|
26
241
|
// process.exit(1)
|
|
27
242
|
// }
|
|
28
243
|
// }
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
244
|
+
|
|
245
|
+
async function launchIOSSimulator(simulatorName) {
|
|
246
|
+
progress.log("Launching iOS Simulator...");
|
|
247
|
+
try {
|
|
248
|
+
// Get all simulators including both available and booted ones
|
|
249
|
+
const allSimulatorInfo = (0, _child_process.execSync)("xcrun simctl list devices -j").toString();
|
|
250
|
+
const simulatorsJson = JSON.parse(allSimulatorInfo);
|
|
251
|
+
const runtimesOutput = (0, _child_process.execSync)("xcrun simctl list runtimes -j").toString();
|
|
252
|
+
const availableRuntimeIds = new Set(JSON.parse(runtimesOutput).runtimes.filter(r => r.isAvailable || r.availability === "(available)" || r.availability === "available").map(r => r.identifier));
|
|
253
|
+
|
|
254
|
+
// Search through all runtimes and their devices
|
|
255
|
+
let foundSimulator = null;
|
|
256
|
+
let foundSimulatorId = null;
|
|
257
|
+
let isBooted = false;
|
|
258
|
+
|
|
259
|
+
// Prefer devices under an available runtime; fall back to already-booted ones
|
|
260
|
+
Object.entries(simulatorsJson.devices).forEach(([runtimeId, devices]) => {
|
|
261
|
+
const isAvailableRuntime = availableRuntimeIds.has(runtimeId);
|
|
262
|
+
devices.forEach(device => {
|
|
263
|
+
if (device.name === simulatorName) {
|
|
264
|
+
const alreadyBooted = device.state === "Booted";
|
|
265
|
+
// Take this match if: no match yet, or this runtime is available and current isn't, or device is already booted
|
|
266
|
+
if (!foundSimulator || isAvailableRuntime && !foundSimulator._fromAvailableRuntime || alreadyBooted) {
|
|
267
|
+
foundSimulator = {
|
|
268
|
+
...device,
|
|
269
|
+
_fromAvailableRuntime: isAvailableRuntime
|
|
270
|
+
};
|
|
271
|
+
foundSimulatorId = device.udid;
|
|
272
|
+
isBooted = alreadyBooted;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
});
|
|
277
|
+
if (!foundSimulator) {
|
|
278
|
+
console.log(`Configured simulator "${simulatorName}" not found.`);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (!isBooted) {
|
|
282
|
+
console.log(`Booting simulator: ${simulatorName}`);
|
|
283
|
+
(0, _utils.runCommand)(`xcrun simctl boot ${foundSimulatorId}`);
|
|
284
|
+
} else {
|
|
285
|
+
console.log(`Simulator ${simulatorName} is already booted`);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Open Simulator.app and focus
|
|
289
|
+
progress.log("Opening Simulator.app...");
|
|
290
|
+
(0, _utils.runCommand)("open -a Simulator");
|
|
291
|
+
|
|
292
|
+
// Give the simulator a moment to open/focus
|
|
293
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
294
|
+
|
|
295
|
+
// Activate the Simulator.app window to bring it to front
|
|
296
|
+
(0, _utils.runCommand)("osascript -e 'tell application \"Simulator\" to activate'");
|
|
297
|
+
console.log("iOS Simulator launched successfully.");
|
|
298
|
+
} catch (error) {
|
|
299
|
+
console.error("Failed to launch iOS Simulator. Error:", error.message);
|
|
300
|
+
}
|
|
301
|
+
// process.exit(0);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// Execute the main setup
|
|
38
305
|
setupIOSEnvironment();
|
|
@@ -1,27 +1,168 @@
|
|
|
1
|
-
"use strict";
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
exec,
|
|
5
|
+
execFile,
|
|
6
|
+
execSync
|
|
7
|
+
} = require("child_process");
|
|
8
|
+
const fs = require("fs");
|
|
9
|
+
|
|
10
|
+
/**
|
|
2
11
|
* Get local IP address on macOS using ifconfig
|
|
3
|
-
*/
|
|
12
|
+
*/
|
|
13
|
+
function getLocalIPAddress() {
|
|
14
|
+
try {
|
|
15
|
+
const command = `ifconfig | grep "inet " | grep -v 127.0.0.1 | head -n 1 | awk '{print $2}'`;
|
|
16
|
+
return execSync(command).toString().trim();
|
|
17
|
+
} catch (error) {
|
|
18
|
+
console.warn("Could not get local IP, using localhost");
|
|
19
|
+
return "localhost";
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
4
24
|
* Check if server is running on given port
|
|
5
|
-
*/
|
|
25
|
+
*/
|
|
26
|
+
async function isServerRunning(port) {
|
|
27
|
+
return new Promise(resolve => {
|
|
28
|
+
const normalizedPort = Number(port);
|
|
29
|
+
if (!Number.isInteger(normalizedPort) || normalizedPort < 1 || normalizedPort > 65535) {
|
|
30
|
+
resolve(false);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
execFile("lsof", ["-i", `:${normalizedPort}`], (error, stdout) => {
|
|
34
|
+
if (error) {
|
|
35
|
+
resolve(false);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
resolve(stdout.includes("LISTEN"));
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
6
44
|
* Start server in background using npm start
|
|
7
|
-
*/
|
|
8
|
-
|
|
45
|
+
*/
|
|
46
|
+
function startServerBackground() {
|
|
47
|
+
console.log("Starting server in background...");
|
|
48
|
+
const serverProcess = exec("npm start", {
|
|
49
|
+
detached: true,
|
|
50
|
+
stdio: "ignore"
|
|
51
|
+
});
|
|
52
|
+
if (serverProcess.pid) {
|
|
53
|
+
serverProcess.unref(); // Allow parent to exit
|
|
54
|
+
console.log("Server started in background");
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
9
59
|
* Recursively replace localhost and different IPs with current local IP
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const
|
|
60
|
+
*/
|
|
61
|
+
function replaceIPInObject(obj, localIP, path = "") {
|
|
62
|
+
let updated = false;
|
|
63
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
64
|
+
const currentPath = path ? `${path}.${key}` : key;
|
|
65
|
+
if (typeof value === "string") {
|
|
66
|
+
let newValue = value;
|
|
67
|
+
let shouldUpdate = false;
|
|
68
|
+
|
|
69
|
+
// Replace localhost with local IP
|
|
70
|
+
if (value.includes("localhost")) {
|
|
71
|
+
newValue = value.replace(/localhost/g, localIP);
|
|
72
|
+
shouldUpdate = true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Replace different IP addresses in URLs
|
|
76
|
+
const urlPattern = /http:\/\/(\d+\.\d+\.\d+\.\d+)/g;
|
|
77
|
+
const matches = [...value.matchAll(urlPattern)];
|
|
78
|
+
for (const match of matches) {
|
|
79
|
+
if (match[1] !== localIP) {
|
|
80
|
+
newValue = newValue.replace(match[1], localIP);
|
|
81
|
+
shouldUpdate = true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Replace standalone IP addresses that are not localhost
|
|
86
|
+
const ipPattern = /^(\d+\.\d+\.\d+\.\d+)$/;
|
|
87
|
+
const ipMatch = value.match(ipPattern);
|
|
88
|
+
if (ipMatch && ipMatch[1] !== localIP) {
|
|
89
|
+
newValue = localIP;
|
|
90
|
+
shouldUpdate = true;
|
|
91
|
+
}
|
|
92
|
+
if (shouldUpdate && newValue !== value) {
|
|
93
|
+
console.log(`Updating ${currentPath}: ${value} -> ${newValue}`);
|
|
94
|
+
obj[key] = newValue;
|
|
95
|
+
updated = true;
|
|
96
|
+
}
|
|
97
|
+
} else if (typeof value === "object" && value !== null) {
|
|
98
|
+
// Recursively process nested objects
|
|
99
|
+
const nestedUpdated = replaceIPInObject(value, localIP, currentPath);
|
|
100
|
+
updated = updated || nestedUpdated;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return updated;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
15
107
|
* Update config.json with current local IP address
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
|
|
108
|
+
*/
|
|
109
|
+
function updateConfigWithLocalIP(configPath, localIP) {
|
|
110
|
+
try {
|
|
111
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
112
|
+
|
|
113
|
+
// Recursively update all IP addresses in the config
|
|
114
|
+
const updated = replaceIPInObject(config, localIP);
|
|
115
|
+
|
|
116
|
+
// Write back if updated
|
|
117
|
+
if (updated) {
|
|
118
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2), "utf8");
|
|
119
|
+
console.log("Configuration updated with current IP address");
|
|
120
|
+
} else {
|
|
121
|
+
console.log("No IP addresses needed updating in configuration");
|
|
122
|
+
}
|
|
123
|
+
return config;
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.error("Error updating config:", error.message);
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
19
131
|
* Main function: Setup server with IP validation and background startup
|
|
20
132
|
* @param {string} configPath - Path to config.json file
|
|
21
133
|
* @returns {Promise<{serverURL: string, localIP: string, port: number}>}
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
134
|
+
*/
|
|
135
|
+
async function setupServer(configPath) {
|
|
136
|
+
console.log("Setting up server...");
|
|
137
|
+
|
|
138
|
+
// Get local IP
|
|
139
|
+
const localIP = getLocalIPAddress();
|
|
140
|
+
console.log(`Local IP: ${localIP}`);
|
|
141
|
+
|
|
142
|
+
// Update config with current IP
|
|
143
|
+
const config = updateConfigWithLocalIP(configPath, localIP);
|
|
144
|
+
|
|
145
|
+
// Get port from config
|
|
146
|
+
const port = config.WEBVIEW_CONFIG?.port || 3005;
|
|
147
|
+
const serverURL = `http://${localIP}:${port}`;
|
|
148
|
+
|
|
149
|
+
// Check if server is running
|
|
150
|
+
const running = await isServerRunning(port);
|
|
151
|
+
if (!running) {
|
|
152
|
+
console.log(`Server not running on ${serverURL}, starting...`);
|
|
153
|
+
startServerBackground();
|
|
154
|
+
// Give it a moment to start
|
|
155
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
156
|
+
} else {
|
|
157
|
+
console.log(`Server already running on ${serverURL}`);
|
|
158
|
+
}
|
|
159
|
+
console.log(`Server setup complete: ${serverURL}`);
|
|
160
|
+
return {
|
|
161
|
+
serverURL,
|
|
162
|
+
localIP,
|
|
163
|
+
port
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
module.exports = {
|
|
167
|
+
setupServer
|
|
168
|
+
};
|