catalyst-core 0.1.0-canary.1 → 0.1.0-canary.2

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/changelog.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.1.0-canary.2] - 2026-01-28
4
+
5
+ - Adds mono-repository support for catalyst
6
+ - Notifications sound channel bug fix
7
+
3
8
  ## [0.1.0-canary.1] - 2026-01-12
4
9
 
5
10
  - Universal Merge
@@ -0,0 +1,176 @@
1
+ package io.yourname.androidproject.plugins
2
+
3
+ import android.app.Activity
4
+ import android.content.Intent
5
+ import android.util.Log
6
+ import android.webkit.WebView
7
+ import androidx.activity.result.ActivityResultLauncher
8
+ import androidx.activity.result.contract.ActivityResultContracts
9
+ import com.google.android.gms.auth.api.signin.GoogleSignIn
10
+ import com.google.android.gms.auth.api.signin.GoogleSignInAccount
11
+ import com.google.android.gms.auth.api.signin.GoogleSignInClient
12
+ import com.google.android.gms.auth.api.signin.GoogleSignInOptions as LegacyGoogleSignInOptions
13
+ import com.google.android.gms.common.api.ApiException
14
+ import io.yourname.androidproject.utils.BridgeUtils
15
+ import org.json.JSONObject
16
+
17
+ /**
18
+ * Legacy Google Sign-In Plugin
19
+ *
20
+ * DEPRECATION NOTICE: This plugin uses the deprecated Google Sign-In SDK.
21
+ * Google is removing this SDK from Play Services in 2025.
22
+ *
23
+ * Purpose: Provides serverAuthCode support for specific users who need
24
+ * authorization codes to exchange for access/refresh tokens on backend.
25
+ *
26
+ * Migration Path: Once backend supports ID token exchange for access tokens,
27
+ * this plugin can be removed by:
28
+ * 1. Delete this file
29
+ * 2. Remove legacy dependency from build.gradle.kts
30
+ * 3. Remove plugin registration from NativeBridge
31
+ *
32
+ * @see <a href="https://developer.android.com/identity/sign-in/legacy-gsi-migration">Legacy GSI Migration Guide</a>
33
+ */
34
+ class LegacyGoogleSignInPlugin(
35
+ private val activity: Activity,
36
+ private val webView: WebView
37
+ ) {
38
+ private var signInClient: GoogleSignInClient? = null
39
+ private var isInProgress: Boolean = false
40
+ private lateinit var launcher: ActivityResultLauncher<Intent>
41
+
42
+ companion object {
43
+ private const val TAG = "LegacyGoogleSignInPlugin"
44
+ }
45
+
46
+ /**
47
+ * Configuration for legacy Google Sign-In request
48
+ */
49
+ data class SignInConfig(
50
+ val clientId: String
51
+ )
52
+
53
+ /**
54
+ * Callback interface for sign-in results
55
+ */
56
+ interface SignInCallback {
57
+ fun onSuccess(result: JSONObject)
58
+ fun onCancelled()
59
+ fun onError(error: String)
60
+ }
61
+
62
+ private var currentCallback: SignInCallback? = null
63
+
64
+ /**
65
+ * Initialize the plugin
66
+ * Must be called during Activity initialization
67
+ */
68
+ fun initialize(launcher: ActivityResultLauncher<Intent>) {
69
+ this.launcher = launcher
70
+ Log.d(TAG, "Legacy Google Sign-In Plugin initialized")
71
+ }
72
+
73
+ /**
74
+ * Start legacy Google Sign-In flow
75
+ */
76
+ fun signIn(config: SignInConfig, callback: SignInCallback) {
77
+ if (isInProgress) {
78
+ callback.onError("Sign-in already in progress")
79
+ return
80
+ }
81
+
82
+ isInProgress = true
83
+ currentCallback = callback
84
+
85
+ try {
86
+ // Build legacy Google Sign-In options
87
+ val gso = LegacyGoogleSignInOptions.Builder(LegacyGoogleSignInOptions.DEFAULT_SIGN_IN)
88
+ .requestIdToken(config.clientId)
89
+ .requestServerAuthCode(config.clientId)
90
+ .requestEmail()
91
+ .requestProfile()
92
+ .build()
93
+ signInClient = GoogleSignIn.getClient(activity, gso)
94
+
95
+ Log.d(TAG, "Launching legacy Google Sign-In for serverAuthCode")
96
+ val signInIntent = signInClient?.signInIntent
97
+ launcher.launch(signInIntent)
98
+ } catch (e: Exception) {
99
+ isInProgress = false
100
+ currentCallback = null
101
+ callback.onError("Failed to start sign-in: ${e.message}")
102
+ }
103
+ }
104
+
105
+ /**
106
+ * Handle activity result from Google Sign-In
107
+ * Call this from ActivityResultLauncher callback
108
+ */
109
+ fun handleActivityResult(resultCode: Int, data: Intent?) {
110
+ if (resultCode == Activity.RESULT_OK) {
111
+ val task = GoogleSignIn.getSignedInAccountFromIntent(data)
112
+ try {
113
+ val account = task.getResult(ApiException::class.java)
114
+ handleSignInSuccess(account)
115
+ } catch (e: ApiException) {
116
+ handleSignInError(e)
117
+ }
118
+ } else {
119
+ handleSignInCancelled()
120
+ }
121
+ }
122
+
123
+ private fun handleSignInSuccess(account: GoogleSignInAccount) {
124
+ Log.d(TAG, "Legacy Google Sign-In successful")
125
+
126
+ val payload = JSONObject().apply {
127
+ account.idToken?.let { put("idToken", it) }
128
+ account.email?.let { put("email", it) }
129
+ account.displayName?.let { put("name", it) }
130
+ account.photoUrl?.toString()?.let { put("photoUrl", it) }
131
+ account.givenName?.let { put("givenName", it) }
132
+ account.familyName?.let { put("familyName", it) }
133
+
134
+ // This is the key - serverAuthCode from legacy SDK
135
+ account.serverAuthCode?.let { put("serverAuthCode", it) }
136
+
137
+ put("provider", "google")
138
+ }
139
+
140
+ isInProgress = false
141
+ val callback = currentCallback
142
+ currentCallback = null
143
+ callback?.onSuccess(payload)
144
+ }
145
+
146
+ private fun handleSignInError(error: ApiException) {
147
+ Log.e(TAG, "Legacy Google Sign-In failed: ${error.message}", error)
148
+ isInProgress = false
149
+ val callback = currentCallback
150
+ currentCallback = null
151
+ callback?.onError("Sign-in failed: ${error.message}")
152
+ }
153
+
154
+ private fun handleSignInCancelled() {
155
+ Log.d(TAG, "Legacy Google Sign-In cancelled")
156
+ isInProgress = false
157
+ val callback = currentCallback
158
+ currentCallback = null
159
+ callback?.onCancelled()
160
+ }
161
+
162
+ /**
163
+ * Check if sign-in is currently in progress
164
+ */
165
+ fun isSignInInProgress(): Boolean = isInProgress
166
+
167
+ /**
168
+ * Cleanup resources
169
+ */
170
+ fun cleanup() {
171
+ signInClient = null
172
+ currentCallback = null
173
+ isInProgress = false
174
+ Log.d(TAG, "Legacy Google Sign-In Plugin cleaned up")
175
+ }
176
+ }
@@ -0,0 +1,97 @@
1
+ # Plugins Directory
2
+
3
+ This directory contains optional plugin modules that extend NativeBridge functionality with features that may be deprecated or need to be conditionally included.
4
+
5
+ ## LegacyGoogleSignInPlugin
6
+
7
+ **Status:** ⚠️ DEPRECATED - Will be removed when backend supports ID token exchange
8
+
9
+ ### Purpose
10
+ Provides `serverAuthCode` support for Google Sign-In using the deprecated Google Sign-In SDK. The serverAuthCode can be exchanged on your backend for access and refresh tokens.
11
+
12
+ ### Why Plugin Architecture?
13
+ The legacy Google Sign-In SDK is being removed from Google Play Services in 2025. By isolating this in a plugin:
14
+ - Easy to remove when no longer needed
15
+ - Clear separation from modern Credential Manager implementation
16
+ - Single point of maintenance
17
+ - Self-documenting deprecation
18
+
19
+ ### Migration Timeline
20
+
21
+ 1. **Current State** (Using Plugin)
22
+ - Modern users: Credential Manager (no serverAuthCode)
23
+ - Legacy users: Plugin provides serverAuthCode via deprecated SDK
24
+
25
+ 2. **Future State** (Remove Plugin)
26
+ - All users: Credential Manager with ID token
27
+ - Backend: Exchange ID token for access tokens
28
+ - Plugin: Delete this file + remove dependency
29
+
30
+ ### Removal Checklist
31
+
32
+ When you're ready to remove the legacy Google Sign-In support:
33
+
34
+ #### Step 1: Update Backend
35
+ - [ ] Implement ID token validation endpoint
36
+ - [ ] Add token exchange logic (ID token → access/refresh tokens)
37
+ - [ ] Test with modern Credential Manager flow
38
+
39
+ #### Step 2: Update Frontend
40
+ - [ ] Remove `requestServerAuthCode` flag from all sign-in calls
41
+ - [ ] Update backend calls to use ID token instead of serverAuthCode
42
+
43
+ #### Step 3: Remove Plugin (Android)
44
+ - [ ] Delete `LegacyGoogleSignInPlugin.kt` file
45
+ - [ ] Remove legacy dependency from `build.gradle.kts`:
46
+ ```kotlin
47
+ // DELETE THIS LINE:
48
+ implementation("com.google.android.gms:play-services-auth:21.0.0")
49
+ ```
50
+ - [ ] In `NativeBridge.kt`:
51
+ - Remove `legacyGoogleSignInPlugin` property
52
+ - Remove `legacyGoogleSignInLauncher`
53
+ - Remove `initializeLegacyGoogleSignInLauncher()` call
54
+ - Remove `useLegacyGoogleSignIn()` method
55
+ - Remove plugin cleanup in `cleanup()`
56
+ - Remove legacy routing in `launchGoogleSignIn()`
57
+ - [ ] Remove `requestServerAuthCode` field from `GoogleSignInOptions`
58
+
59
+ #### Step 4: Test
60
+ - [ ] Test sign-in flow with modern Credential Manager
61
+ - [ ] Verify backend receives and validates ID tokens
62
+ - [ ] Verify token exchange works correctly
63
+
64
+ ### Usage (Current)
65
+
66
+ ```javascript
67
+ // In JavaScript
68
+ signIn({
69
+ clientId: "YOUR_WEB_CLIENT_ID",
70
+ requestServerAuthCode: true // Triggers plugin
71
+ });
72
+
73
+ // Returns:
74
+ {
75
+ idToken: "...",
76
+ email: "...",
77
+ serverAuthCode: "..." // From plugin
78
+ }
79
+ ```
80
+
81
+ ### Architecture
82
+
83
+ ```
84
+ NativeBridge
85
+ ├─ Modern Flow: CredentialManager (default)
86
+ └─ Legacy Flow: LegacyGoogleSignInPlugin (conditional)
87
+ ```
88
+
89
+ The plugin is:
90
+ - ✅ Isolated in separate file
91
+ - ✅ Clearly marked as deprecated
92
+ - ✅ Easy to remove (no entanglement with main code)
93
+ - ✅ Self-documenting with removal checklist
94
+
95
+ ### References
96
+ - [Google Sign-In Migration Guide](https://developer.android.com/identity/sign-in/legacy-gsi-migration)
97
+ - [Credential Manager Documentation](https://developer.android.com/identity/sign-in/credential-manager-siwg)
@@ -1,4 +1,4 @@
1
- "use strict";var _fs=_interopRequireDefault(require("fs"));var _child_process=require("child_process");var _utils=require("./utils.js");var _TerminalProgress=_interopRequireDefault(require("./TerminalProgress.js"));var _setupServer=require("./setupServer.js");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e};}const pwd=`${process.cwd()}/node_modules/catalyst-core/dist/native`;const configPath=`${process.env.PWD}/config/config.json`;const steps={java:"Check Java Environment",config:"Initialize Configuration",androidTools:"Validate Android Tools",emulator:"Configure Android Emulator",properties:"Update Local Properties",saveConfig:"Save Configuration",setupServer:"Setup Server"};const progressPaddingConfig={titlePaddingTop:2,titlePaddingBottom:1,stepPaddingLeft:4,stepSpacing:1,errorPaddingLeft:6,bottomMargin:2};const progress=new _TerminalProgress.default(steps,"Catalyst Universal Android Setup",progressPaddingConfig);async function checkJavaInstallation(){try{(0,_utils.runCommand)("java -version");(0,_utils.runCommand)("javac -version");progress.log("Java is installed and configured","success");return true;}catch(error){progress.log("Java installation not found or not properly configured","error");return false;}}async function installJava(){progress.log("Installing Java (Zulu JDK 17)...");try{try{(0,_utils.runCommand)("brew --version");}catch(error){throw new Error("Homebrew is required but not installed. Please install Homebrew first.");}const javaHome="/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home";// Try installing Java
1
+ "use strict";var _fs=_interopRequireDefault(require("fs"));var _path=_interopRequireDefault(require("path"));var _child_process=require("child_process");var _utils=require("./utils.js");var _TerminalProgress=_interopRequireDefault(require("./TerminalProgress.js"));var _setupServer=require("./setupServer.js");function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e};}const catalystCorePath=_path.default.dirname(require.resolve("catalyst-core/package.json"));const pwd=_path.default.join(catalystCorePath,"dist/native");const configPath=`${process.env.PWD}/config/config.json`;const steps={java:"Check Java Environment",config:"Initialize Configuration",androidTools:"Validate Android Tools",emulator:"Configure Android Emulator",properties:"Update Local Properties",saveConfig:"Save Configuration",setupServer:"Setup Server"};const progressPaddingConfig={titlePaddingTop:2,titlePaddingBottom:1,stepPaddingLeft:4,stepSpacing:1,errorPaddingLeft:6,bottomMargin:2};const progress=new _TerminalProgress.default(steps,"Catalyst Universal Android Setup",progressPaddingConfig);async function checkJavaInstallation(){try{(0,_utils.runCommand)("java -version");(0,_utils.runCommand)("javac -version");progress.log("Java is installed and configured","success");return true;}catch(error){progress.log("Java installation not found or not properly configured","error");return false;}}async function installJava(){progress.log("Installing Java (Zulu JDK 17)...");try{try{(0,_utils.runCommand)("brew --version");}catch(error){throw new Error("Homebrew is required but not installed. Please install Homebrew first.");}const javaHome="/Library/Java/JavaVirtualMachines/zulu-17.jdk/Contents/Home";// Try installing Java
2
2
  try{await(0,_utils.runCommand)("brew install --cask zulu@17");}catch(error){if(error.message.includes("already installed")){progress.log("Attempting to reinstall Java...","info");try{await(0,_utils.runCommand)("brew reinstall --cask zulu@17");}catch(reinstallError){throw new Error(`Failed to reinstall Java: ${reinstallError.message}. Please run 'brew reinstall --cask zulu@17' manually.`);}}else{throw error;}}// Verify Java installation
3
3
  if(!_fs.default.existsSync(javaHome)){throw new Error(`Java installation not found at ${javaHome}. Please verify the installation manually.`);}// Set up environment variables
4
4
  const homeDir=process.env.HOME;const shellProfile=`${homeDir}/.zshrc`;const exportCommand=`\n# Java Configuration\nexport JAVA_HOME=${javaHome}\nexport PATH=$JAVA_HOME/bin:$PATH\n`;try{_fs.default.appendFileSync(shellProfile,exportCommand);}catch(error){throw new Error(`Failed to update ${shellProfile}: ${error.message}. Please add the following lines manually:\n${exportCommand}`);}// Set for current process
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable no-extra-semi */"use strict";var _renameAndroidProject=require("./renameAndroidProject.js");var _child_process=require("child_process");var _fs=_interopRequireDefault(require("fs"));var _path=_interopRequireDefault(require("path"));var _utils=require("./utils.js");var _TerminalProgress=_interopRequireDefault(require("./TerminalProgress.js"));// Import the AAB builder
2
- function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e};}const configPath=`${process.env.PWD}/config/config.json`;const publicPath=`${process.env.PWD}/public`;const pwd=`${process.cwd()}/node_modules/catalyst-core/dist/native`;const ANDROID_PACKAGE="io.yourname.androidproject";// Default values for AAB building
2
+ function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e};}const configPath=`${process.env.PWD}/config/config.json`;const publicPath=`${process.env.PWD}/public`;const catalystCorePath=_path.default.dirname(require.resolve("catalyst-core/package.json"));const pwd=_path.default.join(catalystCorePath,"dist/native");const ANDROID_PACKAGE="io.yourname.androidproject";// Default values for AAB building
3
3
  const DEFAULT_PROJECT_PATH=`${pwd}/androidProject`;const DEFAULT_DEPLOYMENT_PATH="./deployment";const DEFAULT_OLD_PROJECT_NAME="androidProject";// Use actual project name in catalyst
4
4
  const DEFAULT_OVERWRITE_EXISTING=true;const steps={config:"Initialize Configuration",tools:"Validate Android Tools",emulator:"Check and Start Emulator",copyAssets:"Copy Build Assets",build:"Build and Install Application",aab:"Build Signed AAB"};const progressConfig={titlePaddingTop:2,titlePaddingBottom:1,stepPaddingLeft:4,stepSpacing:1,errorPaddingLeft:6,bottomMargin:2};const progress=new _TerminalProgress.default(steps,"Catalyst Android Build",progressConfig);async function initializeConfig(){const configFile=_fs.default.readFileSync(configPath,"utf8");const config=JSON.parse(configFile);const{WEBVIEW_CONFIG,BUILD_OUTPUT_PATH}=config;if(!WEBVIEW_CONFIG||Object.keys(WEBVIEW_CONFIG).length===0){throw new Error("WebView Config missing in "+configPath);}if(!WEBVIEW_CONFIG.android){throw new Error("Android config missing in WebView Config");}// Log build type information
5
5
  const buildType=WEBVIEW_CONFIG.android.buildType||"debug";progress.log(`Build Type: ${buildType}`,"info");if(buildType==="release"){progress.log("Release build detected - AAB will be generated","info");}return{WEBVIEW_CONFIG,BUILD_OUTPUT_PATH};}function validateAndroidTools(androidConfig){const ANDROID_SDK=androidConfig.sdkPath;const ADB_PATH=`${ANDROID_SDK}/platform-tools/adb`;const EMULATOR_PATH=`${ANDROID_SDK}/emulator/emulator`;progress.log("Validating Android tools...","info");if(!ANDROID_SDK){throw new Error("Android SDK path is not configured");}if(!_fs.default.existsSync(ANDROID_SDK)){throw new Error(`Android SDK path does not exist: ${ANDROID_SDK}`);}if(!_fs.default.existsSync(ADB_PATH)){throw new Error(`ADB not found at: ${ADB_PATH}`);}try{;(0,_utils.runCommand)(`${ADB_PATH} version`);progress.log("ADB validation successful","success");}catch(error){throw new Error(`ADB is not working properly: ${error.message}`);}// Skip emulator validation for release builds
@@ -52,10 +52,13 @@ await addNotificationPermissions();await generateNotificationResources(WEBVIEW_C
52
52
  <!-- Firebase default notification configuration -->
53
53
  <meta-data
54
54
  android:name="com.google.firebase.messaging.default_notification_channel_id"
55
- android:value="fcm_default_channel" />
55
+ android:value="default" />
56
56
  <meta-data
57
57
  android:name="com.google.firebase.messaging.default_notification_icon"
58
58
  android:resource="@drawable/ic_notification" />
59
+ <meta-data
60
+ android:name="com.google.firebase.messaging.default_notification_sound"
61
+ android:resource="@raw/notification_sound_default" />
59
62
 
60
63
  <!-- Push Notification Service -->
61
64
  <service
@@ -88,7 +91,7 @@ async function cleanupNotificationPermissions(){try{const manifestPath=`${pwd}/a
88
91
  const notificationPermissions=["android.permission.POST_NOTIFICATIONS","android.permission.VIBRATE","android.permission.WAKE_LOCK","android.permission.RECEIVE_BOOT_COMPLETED"];notificationPermissions.forEach(permission=>{const permissionRegex=new RegExp(`\\s*<uses-permission android:name="${permission}"[^>]*/>`,"g");manifestContent=manifestContent.replace(permissionRegex,"");});_fs.default.writeFileSync(manifestPath,manifestContent);}catch(error){// Don't throw error for cleanup operations, just log
89
92
  progress.log(`Warning: Error cleaning notification permissions: ${error.message}`,"warning");}}async function cleanupNotificationResources(){try{const colorsPath=`${pwd}/androidProject/app/src/main/res/values/colors.xml`;let colorsContent=_fs.default.readFileSync(colorsPath,"utf8");// Remove notification color
90
93
  const existingColorLine=colorsContent.split("\n").find(line=>line.includes('name="notification_color"'));if(existingColorLine){colorsContent=colorsContent.replace(existingColorLine,"");_fs.default.writeFileSync(colorsPath,colorsContent);}}catch(error){progress.log(`Warning: Error cleaning notification resources: ${error.message}`,"warning");}}async function cleanupNotificationMetadata(){try{const manifestPath=`${pwd}/androidProject/app/src/main/AndroidManifest.xml`;let manifestContent=_fs.default.readFileSync(manifestPath,"utf8");// Remove notification metadata entries
91
- const metadataNames=["default_notification_channel_id","default_notification_icon","default_notification_color","com.google.firebase.messaging.default_notification_channel_id","com.google.firebase.messaging.default_notification_icon"];metadataNames.forEach(metadataName=>{// Remove the meta-data block including comments
94
+ const metadataNames=["default_notification_channel_id","default_notification_icon","default_notification_color","com.google.firebase.messaging.default_notification_channel_id","com.google.firebase.messaging.default_notification_icon","com.google.firebase.messaging.default_notification_sound"];metadataNames.forEach(metadataName=>{// Remove the meta-data block including comments
92
95
  const metadataRegex=new RegExp(`\\s*<!--[^>]*notification[^>]*-->\\s*<meta-data[^>]*android:name="${metadataName}"[\\s\\S]*?/>|\\s*<meta-data[^>]*android:name="${metadataName}"[\\s\\S]*?/>`,"gi");manifestContent=manifestContent.replace(metadataRegex,"");});// Remove Push Notification Service
93
96
  const serviceRegex=/\s*<!--\s*Push Notification Service\s*-->\s*<service[^>]*android:name="[^"]*PushNotificationUtils"[\s\S]*?<\/service>/gi;manifestContent=manifestContent.replace(serviceRegex,"");// Clean up any standalone notification comments
94
97
  manifestContent=manifestContent.replace(/\s*<!--\s*Default notification configuration\s*-->/gi,"");manifestContent=manifestContent.replace(/\s*<!--\s*Firebase default notification configuration\s*-->/gi,"");manifestContent=manifestContent.replace(/\s*<!--\s*Push Notification Service\s*-->/gi,"");_fs.default.writeFileSync(manifestPath,manifestContent);}catch(error){progress.log(`Warning: Error cleaning notification metadata: ${error.message}`,"warning");}}async function cleanupNotificationAssets(){try{const destPath=`${pwd}/androidProject/app/src/main/res`;const imageFormats=["png","jpg","jpeg","gif","bmp","svg","webp","xml"];const audioFormats=["mp3","wav","ogg"];// Define notification icons to clean up
@@ -1,4 +1,4 @@
1
- "use strict";const{exec,execSync}=require("child_process");const fs=require("fs");const path=require("path");const TerminalProgress=require("./TerminalProgress.js").default;const crypto=require("crypto");const pwd=`${process.cwd()}/node_modules/catalyst-core/dist/native`;const{WEBVIEW_CONFIG,BUILD_OUTPUT_PATH}=require(`${process.env.PWD}/config/config.json`);// Configuration constants
1
+ "use strict";const{exec,execSync}=require("child_process");const fs=require("fs");const path=require("path");const TerminalProgress=require("./TerminalProgress.js").default;const crypto=require("crypto");const catalystCorePath=path.dirname(require.resolve("catalyst-core/package.json"));const pwd=path.join(catalystCorePath,"dist/native");const{WEBVIEW_CONFIG,BUILD_OUTPUT_PATH}=require(`${process.env.PWD}/config/config.json`);// Configuration constants
2
2
  const iosConfig=WEBVIEW_CONFIG.ios;const protocol=WEBVIEW_CONFIG.useHttps?"https":"http";const ip=WEBVIEW_CONFIG.LOCAL_IP||"localhost";const port=WEBVIEW_CONFIG.port?WEBVIEW_CONFIG.useHttps?443:WEBVIEW_CONFIG.port:null;let url=port?`${protocol}://${ip}:${port}`:`${protocol}://${ip}`;const PUBLIC_PATH=`${process.env.PWD}/public`;const PROJECT_DIR=`${pwd}/iosnativeWebView`;const SCHEME_NAME="iosnativeWebView";const APP_BUNDLE_ID=iosConfig.appBundleId||"com.debug.webview";const PROJECT_NAME=path.basename(PROJECT_DIR);const IPHONE_MODEL=iosConfig.simulatorName;const GOOGLE_SERVICES_FILENAME="GoogleService-Info.plist";function generateProjectObjectId(identifier,suffix=""){return crypto.createHash("md5").update(`${identifier}:${suffix}`).digest("hex").substring(0,24).toUpperCase();}function getXcodeProjectFilePath(){return path.join(PROJECT_DIR,`${PROJECT_NAME}.xcodeproj`,"project.pbxproj");}// Define build steps for progress tracking
3
3
  const steps={config:"Generating Required Configuration for build",deviceDetection:"Detecting Physical Device",launchSimulator:"Launch iOS Simulator",clean:"Clean Build Artifacts",assets:"Process Notification Assets",build:"Build IOS Project",findApp:"Locate Built Application",install:"Install Application",launch:"Launch Application"};// Configure progress display
4
4
  const progressConfig={titlePaddingTop:2,titlePaddingBottom:1,stepPaddingLeft:4,stepSpacing:1,errorPaddingLeft:6,bottomMargin:2};const progress=new TerminalProgress(steps,"Catalyst iOS Build",progressConfig);// Utility function to run shell commands
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catalyst-core",
3
- "version": "0.1.0-canary.1",
3
+ "version": "0.1.0-canary.2",
4
4
  "main": "index.js",
5
5
  "description": "Web framework that provides great performance out of the box",
6
6
  "bin": {
@@ -26,6 +26,7 @@
26
26
  },
27
27
  "exports": {
28
28
  ".": "./dist/index.js",
29
+ "./package.json": "./package.json",
29
30
  "./logger": "./dist/logger.js",
30
31
  "./caching": "./dist/caching.js",
31
32
  "./router/ClientRouter": "./dist/router/ClientRouter.js",