react-native-bspatch 1.0.1 → 1.0.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/package.json +1 -1
- package/tools/build_ota.sh +63 -70
- package/tools/setup_project.js +17 -37
package/package.json
CHANGED
package/tools/build_ota.sh
CHANGED
|
@@ -81,86 +81,79 @@ REGISTRY_SHARED="$ROOT/ota_registry.json"
|
|
|
81
81
|
# ── Registry Sync ──────────────────────────────────────────────────────────
|
|
82
82
|
# Skip registry sync for reset/clean actions
|
|
83
83
|
if [ "$ACTION" != "reset" ]; then
|
|
84
|
-
# Download the latest ota_registry.json from server so we don't clobber other platforms
|
|
85
84
|
echo "Syncing remote registry..."
|
|
86
85
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
echo "
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
# Debug: show curl command for manual testing
|
|
109
|
-
echo " Login URL: ${BASE_URL}/public/authen/login"
|
|
110
|
-
|
|
111
|
-
LOGIN_RES=$(curl -s -X "POST" "$BASE_URL/public/authen/login" \
|
|
112
|
-
-H 'Content-Type: application/json; charset=utf-8' \
|
|
113
|
-
-w "\n---HTTP_STATUS:%{http_code}" \
|
|
114
|
-
-d "{\"username\": \"$UPCODE_USER\", \"password\": \"$UPCODE_PASS\"}")
|
|
115
|
-
|
|
116
|
-
# Extract HTTP status and response body
|
|
117
|
-
HTTP_STATUS=$(echo "$LOGIN_RES" | grep -o 'HTTP_STATUS:[0-9]*' | cut -d: -f2)
|
|
118
|
-
LOGIN_BODY=$(echo "$LOGIN_RES" | sed 's/---HTTP_STATUS:.*//')
|
|
119
|
-
|
|
120
|
-
# Debug: show login response on error or empty
|
|
121
|
-
if [ -z "$LOGIN_BODY" ] || [ "$HTTP_STATUS" != "200" ]; then
|
|
122
|
-
echo " ⚠ Login failed - HTTP $HTTP_STATUS"
|
|
123
|
-
echo " ⚠ Response: $LOGIN_BODY"
|
|
124
|
-
fi
|
|
125
|
-
|
|
126
|
-
TOKEN=$(echo "$LOGIN_BODY" | node -e "
|
|
127
|
-
try {
|
|
128
|
-
const r = JSON.parse(require('fs').readFileSync(0, 'utf8'));
|
|
129
|
-
console.log(r.data?.accessTokenInfo?.accessToken || '');
|
|
130
|
-
} catch(e) { console.log(''); }
|
|
131
|
-
")
|
|
132
|
-
|
|
133
|
-
if [[ -n "$TOKEN" ]]; then
|
|
134
|
-
REGISTRY_REMOTE_PATH="$BASE_FOLDER/ota_registry.json"
|
|
135
|
-
# Encode slash as %2F for MinIO API
|
|
136
|
-
ENCODED_PATH=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$REGISTRY_REMOTE_PATH', safe=''))")
|
|
137
|
-
GEN_LINK_URL="$BASE_URL/api/minio/gen-download-link?pathFile=$ENCODED_PATH"
|
|
138
|
-
|
|
139
|
-
LINK_RES=$(curl -s -X "GET" "$GEN_LINK_URL" -H "Authorization: Bearer $TOKEN")
|
|
140
|
-
REGISTRY_URL=$(echo "$LINK_RES" | node -e "
|
|
141
|
-
try {
|
|
142
|
-
const r = JSON.parse(require('fs').readFileSync(0, 'utf8'));
|
|
143
|
-
console.log(r.data || '');
|
|
144
|
-
} catch(e) { console.log(''); }
|
|
145
|
-
")
|
|
146
|
-
|
|
147
|
-
if [[ -n "$REGISTRY_URL" ]]; then
|
|
148
|
-
echo " Downloading remote registry..."
|
|
149
|
-
curl -s -o "$REGISTRY_SHARED" "$REGISTRY_URL"
|
|
150
|
-
echo " ✓ Registry synced"
|
|
86
|
+
BASE_URL="${OTA_BASE_URL:-https://sync-server.osp.com.vn}"
|
|
87
|
+
UPCODE_USER="${OTA_UPLOAD_USER:-}"
|
|
88
|
+
UPCODE_PASS="${OTA_UPLOAD_PASSWORD:-}"
|
|
89
|
+
BASE_FOLDER="${OTA_FOLDER:-ota}"
|
|
90
|
+
|
|
91
|
+
echo " Using URL: $BASE_URL"
|
|
92
|
+
echo " Using Folder: $BASE_FOLDER"
|
|
93
|
+
|
|
94
|
+
if [[ "$BASE_URL" == *"github"* ]] || [[ "$BASE_URL" == *"raw.githubusercontent"* ]]; then
|
|
95
|
+
echo " Downloading remote registry from GitHub..."
|
|
96
|
+
HTTP_CODE=$(curl -s -w "%{http_code}" -o "$REGISTRY_SHARED.tmp" "$BASE_URL/$BASE_FOLDER/ota_registry.json" 2>/dev/null || true)
|
|
97
|
+
if [ "$HTTP_CODE" != "200" ]; then
|
|
98
|
+
HTTP_CODE=$(curl -s -w "%{http_code}" -o "$REGISTRY_SHARED.tmp" "$BASE_URL/ota_registry.json" 2>/dev/null || true)
|
|
99
|
+
fi
|
|
100
|
+
if [ "$HTTP_CODE" = "200" ] && [ -s "$REGISTRY_SHARED.tmp" ]; then
|
|
101
|
+
mv "$REGISTRY_SHARED.tmp" "$REGISTRY_SHARED"
|
|
102
|
+
echo " ✓ Remote registry synced"
|
|
103
|
+
else
|
|
104
|
+
rm -f "$REGISTRY_SHARED.tmp"
|
|
105
|
+
echo " Notice: Remote registry not found on GitHub (starting fresh with local state)."
|
|
106
|
+
fi
|
|
151
107
|
else
|
|
152
|
-
|
|
153
|
-
|
|
108
|
+
if [[ -n "$UPCODE_USER" ]] && [[ -n "$UPCODE_PASS" ]]; then
|
|
109
|
+
LOGIN_RES=$(curl -s -X "POST" "$BASE_URL/public/authen/login" \
|
|
110
|
+
-H 'Content-Type: application/json; charset=utf-8' \
|
|
111
|
+
-w "\n---HTTP_STATUS:%{http_code}" \
|
|
112
|
+
-d "{\"username\": \"$UPCODE_USER\", \"password\": \"$UPCODE_PASS\"}")
|
|
113
|
+
HTTP_STATUS=$(echo "$LOGIN_RES" | grep -o 'HTTP_STATUS:[0-9]*' | cut -d: -f2)
|
|
114
|
+
LOGIN_BODY=$(echo "$LOGIN_RES" | sed 's/---HTTP_STATUS:.*//')
|
|
115
|
+
|
|
116
|
+
TOKEN=$(echo "$LOGIN_BODY" | node -e "
|
|
117
|
+
try {
|
|
118
|
+
const r = JSON.parse(require('fs').readFileSync(0, 'utf8'));
|
|
119
|
+
console.log(r.data?.accessTokenInfo?.accessToken || '');
|
|
120
|
+
} catch(e) { console.log(''); }
|
|
121
|
+
")
|
|
122
|
+
|
|
123
|
+
if [[ -n "$TOKEN" ]]; then
|
|
124
|
+
REGISTRY_REMOTE_PATH="$BASE_FOLDER/ota_registry.json"
|
|
125
|
+
ENCODED_PATH=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$REGISTRY_REMOTE_PATH', safe=''))")
|
|
126
|
+
GEN_LINK_URL="$BASE_URL/api/minio/gen-download-link?pathFile=$ENCODED_PATH"
|
|
127
|
+
LINK_RES=$(curl -s -X "GET" "$GEN_LINK_URL" -H "Authorization: Bearer $TOKEN")
|
|
128
|
+
REGISTRY_URL=$(echo "$LINK_RES" | node -e "
|
|
129
|
+
try {
|
|
130
|
+
const r = JSON.parse(require('fs').readFileSync(0, 'utf8'));
|
|
131
|
+
console.log(r.data || '');
|
|
132
|
+
} catch(e) { console.log(''); }
|
|
133
|
+
")
|
|
134
|
+
if [[ -n "$REGISTRY_URL" ]]; then
|
|
135
|
+
curl -s -o "$REGISTRY_SHARED" "$REGISTRY_URL"
|
|
136
|
+
echo " ✓ Registry synced"
|
|
137
|
+
fi
|
|
138
|
+
else
|
|
139
|
+
echo " ⚠ MinIO login skipped. Proceeding with local state."
|
|
140
|
+
fi
|
|
141
|
+
else
|
|
142
|
+
echo " ⚠ No MinIO credentials. Proceeding with local state."
|
|
143
|
+
fi
|
|
154
144
|
fi
|
|
155
|
-
else
|
|
156
|
-
echo " ⚠ Login failed during registry sync. Proceeding with local state."
|
|
157
|
-
fi
|
|
158
145
|
fi
|
|
159
146
|
|
|
160
147
|
# ── Helper: Download from Server ──────────────────────────────────────────────
|
|
161
148
|
download_from_minio() {
|
|
162
149
|
local REMOTE_PATH="$1"
|
|
163
150
|
local DEST="$2"
|
|
151
|
+
|
|
152
|
+
if [[ "$BASE_URL" == *"github"* ]] || [[ "$BASE_URL" == *"raw.githubusercontent"* ]]; then
|
|
153
|
+
curl -s -f -o "$DEST" "$BASE_URL/$REMOTE_PATH" 2>/dev/null || curl -s -f -o "$DEST" "$BASE_URL/$(basename "$REMOTE_PATH")" 2>/dev/null
|
|
154
|
+
return $?
|
|
155
|
+
fi
|
|
156
|
+
|
|
164
157
|
if [[ -z "$TOKEN" ]]; then return 1; fi
|
|
165
158
|
|
|
166
159
|
local ENCODED_PATH=$(python3 -c "import urllib.parse; print(urllib.parse.quote('$REMOTE_PATH', safe=''))")
|
package/tools/setup_project.js
CHANGED
|
@@ -91,44 +91,24 @@ function patchPbxproj(content) {
|
|
|
91
91
|
// Already patched?
|
|
92
92
|
if (content.includes(XCODE_BUNDLE_SYNC_MARKER)) return content;
|
|
93
93
|
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
94
|
+
// Search by phase name
|
|
95
|
+
const nameIdx = content.indexOf('name = "Bundle React Native code and images";');
|
|
96
|
+
if (nameIdx !== -1) {
|
|
97
|
+
const shellScriptIdx = content.indexOf('shellScript = "', nameIdx);
|
|
98
|
+
if (shellScriptIdx !== -1) {
|
|
99
|
+
const endIdx = content.indexOf('";', shellScriptIdx + 15);
|
|
100
|
+
if (endIdx !== -1) {
|
|
101
|
+
return (
|
|
102
|
+
content.slice(0, endIdx) +
|
|
103
|
+
XCODE_BUNDLE_SYNC_SNIPPET +
|
|
104
|
+
content.slice(endIdx)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
107
|
}
|
|
108
|
-
// Find the shellScript = "..." after this name line
|
|
109
|
-
const afterName = content.indexOf('shellScript = "', nameIdx - 500);
|
|
110
|
-
if (afterName === -1) return content;
|
|
111
|
-
|
|
112
|
-
// Find the end of this shellScript: look for \n\"; after it
|
|
113
|
-
const scriptEnd = content.indexOf('\\n";', afterName);
|
|
114
|
-
if (scriptEnd === -1) return content;
|
|
115
|
-
|
|
116
|
-
return (
|
|
117
|
-
content.slice(0, scriptEnd) +
|
|
118
|
-
XCODE_BUNDLE_SYNC_SNIPPET +
|
|
119
|
-
content.slice(scriptEnd)
|
|
120
|
-
);
|
|
121
108
|
}
|
|
122
109
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
// Remove trailing \n if present before closing
|
|
126
|
-
const insertPoint = match.index + match[1].length + scriptBody.length;
|
|
127
|
-
return (
|
|
128
|
-
content.slice(0, insertPoint) +
|
|
129
|
-
XCODE_BUNDLE_SYNC_SNIPPET +
|
|
130
|
-
content.slice(insertPoint)
|
|
131
|
-
);
|
|
110
|
+
console.log(' ⚠ Could not find "Bundle React Native code and images" build phase in project.pbxproj.');
|
|
111
|
+
return content;
|
|
132
112
|
}
|
|
133
113
|
|
|
134
114
|
// ── iOS: AppDelegate.swift ────────────────────────────────────────────────────
|
|
@@ -229,8 +209,8 @@ function main() {
|
|
|
229
209
|
// ── iOS ──
|
|
230
210
|
console.log('\n[iOS]');
|
|
231
211
|
|
|
232
|
-
// project.pbxproj
|
|
233
|
-
const pbxprojFiles = findFile(IOS_DIR, (name) => name === 'project.pbxproj');
|
|
212
|
+
// project.pbxproj (ignore CocoaPods project file)
|
|
213
|
+
const pbxprojFiles = findFile(IOS_DIR, (name, fullPath) => name === 'project.pbxproj' && !fullPath.includes('Pods'));
|
|
234
214
|
if (pbxprojFiles.length === 0) {
|
|
235
215
|
console.log(' ⚠ No project.pbxproj found. Is this an iOS project?');
|
|
236
216
|
} else {
|