codeplay-common 2.1.51 → 3.0.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.
@@ -1,403 +1,403 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
-
4
-
5
- /**
6
- * Adds user permissions to AndroidManifest.xml if not already present
7
- * based on capacitor.config.json appId matching.
8
- *
9
- * @param {string} targetAppId - appId you want to match
10
- * @param {string[]} permissionsToAdd - permission tags to insert
11
- */
12
- function addAndroidPermissions(permissionsToAdd) {
13
- try {
14
-
15
- if (!Array.isArray(permissionsToAdd) || permissionsToAdd.length === 0) {
16
- console.log("ℹ️ No permissions to add");
17
- return;
18
- }
19
-
20
- // read capacitor.config.json
21
- const configPath = path.join(process.cwd(), 'capacitor.config.json');
22
- if (!fs.existsSync(configPath)) {
23
- console.error(`❌ capacitor.config.json not found at: ${configPath}`);
24
- return;
25
- }
26
-
27
- const rawData = fs.readFileSync(configPath, 'utf8');
28
- const config = JSON.parse(rawData);
29
-
30
-
31
-
32
- const androidManifestPath = path.join(
33
- process.cwd(),
34
- 'android',
35
- 'app',
36
- 'src',
37
- 'main',
38
- 'AndroidManifest.xml'
39
- );
40
-
41
- if (!fs.existsSync(androidManifestPath)) {
42
- console.error(`❌ AndroidManifest.xml not found at: ${androidManifestPath}`);
43
- return;
44
- }
45
-
46
- let manifestContent = fs.readFileSync(androidManifestPath, 'utf8');
47
- let updated = false;
48
-
49
- permissionsToAdd.forEach(permission => {
50
- if (!manifestContent.includes(permission)) {
51
- console.log(`🔧 Adding permission: ${permission}`);
52
- manifestContent = manifestContent.replace(
53
- '</manifest>',
54
- ` ${permission}\n</manifest>`
55
- );
56
- updated = true;
57
- } else {
58
- console.log(`ℹ️ Permission already exists: ${permission}`);
59
- }
60
- });
61
-
62
- if (updated) {
63
- fs.writeFileSync(androidManifestPath, manifestContent, 'utf8');
64
- console.log('✅ AndroidManifest.xml updated successfully.');
65
- } else {
66
- console.log('✅ All required permissions already present.');
67
- }
68
-
69
- } catch (error) {
70
- console.error(`❌ Error: ${error.message}`);
71
- }
72
- }
73
-
74
-
75
-
76
- const addFavIconCode=()=>{
77
- const htmlFilePath = path.join(process.cwd(), 'src', 'index.html');
78
-
79
- if (fs.existsSync(htmlFilePath)) {
80
- let htmlContent = fs.readFileSync(htmlFilePath, 'utf8');
81
-
82
- const faviconTag = '<link rel="icon" href="data:;base64,iVBORw0KGgo=">';
83
-
84
- if (!htmlContent.includes(faviconTag)) {
85
- const headOpenTag = '<head>';
86
- const headIndex = htmlContent.indexOf(headOpenTag);
87
-
88
- if (headIndex !== -1) {
89
- const insertPos = headIndex + headOpenTag.length;
90
- htmlContent =
91
- htmlContent.slice(0, insertPos) +
92
- `\n ${faviconTag}` +
93
- htmlContent.slice(insertPos);
94
-
95
- fs.writeFileSync(htmlFilePath, htmlContent, 'utf8');
96
- console.log(`✅ Favicon link added successfully to index.html`);
97
- } else {
98
- console.error('❌ <head> tag not found in index.html');
99
- }
100
- } else {
101
- console.log('ℹ️ Favicon link already exists in index.html');
102
- }
103
- } else {
104
- console.error(`❌ index.html not found at: ${htmlFilePath}`);
105
- }
106
- }
107
-
108
-
109
- const appJssmallModifications=()=>{
110
-
111
- const appJsPath = path.join(process.cwd(), 'src', 'js', 'app.js');
112
-
113
- if (fs.existsSync(appJsPath)) {
114
- let appJsContent = fs.readFileSync(appJsPath, 'utf8');
115
-
116
- // 1. ensure iosOverlaysWebView is true
117
- if (/iosOverlaysWebView\s*:\s*false/.test(appJsContent)) {
118
- appJsContent = appJsContent.replace(/iosOverlaysWebView\s*:\s*false/, 'iosOverlaysWebView: true');
119
- console.log('✅ iosOverlaysWebView changed to true');
120
- } else if (!/iosOverlaysWebView\s*:/.test(appJsContent)) {
121
- // add if missing
122
- appJsContent = appJsContent.replace(
123
- /statusbar\s*:\s*\{/,
124
- `statusbar: {\n iosOverlaysWebView: true,`
125
- );
126
- console.log('✅ iosOverlaysWebView added');
127
- } else {
128
- console.log('ℹ️ iosOverlaysWebView already true');
129
- }
130
-
131
- // 2. ensure androidOverlaysWebView is true
132
- if (/androidOverlaysWebView\s*:\s*false/.test(appJsContent)) {
133
- appJsContent = appJsContent.replace(/androidOverlaysWebView\s*:\s*false/, 'androidOverlaysWebView: true');
134
- console.log('✅ androidOverlaysWebView changed to true');
135
- } else if (!/androidOverlaysWebView\s*:/.test(appJsContent)) {
136
- // add if missing
137
- appJsContent = appJsContent.replace(
138
- /statusbar\s*:\s*\{/,
139
- `statusbar: {\n androidOverlaysWebView: true,`
140
- );
141
- console.log('✅ androidOverlaysWebView added');
142
- } else {
143
- console.log('ℹ️ androidOverlaysWebView already true');
144
- }
145
-
146
- // 3. change theme
147
- const themeRegex = /theme\s*:\s*['"]auto['"]/;
148
- if (themeRegex.test(appJsContent)) {
149
- appJsContent = appJsContent.replace(themeRegex, `theme: 'md'`);
150
- console.log('✅ theme changed to md');
151
- } else {
152
- console.log('ℹ️ theme: auto not found, no changes made');
153
- }
154
-
155
- fs.writeFileSync(appJsPath, appJsContent, 'utf8');
156
- console.log('✅ app.js updated successfully');
157
- } else {
158
- console.error(`❌ src/js/app.js not found at: ${appJsPath}`);
159
- }
160
- }
161
-
162
-
163
- const ensureTouchHighlightDisabled = () => {
164
- const appJsPath = path.join(process.cwd(), 'src', 'js', 'app.js');
165
-
166
- if (!fs.existsSync(appJsPath)) {
167
- console.error(`❌ src/js/app.js not found at: ${appJsPath}`);
168
- return;
169
- }
170
-
171
- let content = fs.readFileSync(appJsPath, 'utf8');
172
-
173
- // 1️⃣ If explicitly true → change to false
174
- if (/touchHighlightElements\s*:\s*true/.test(content)) {
175
- content = content.replace(
176
- /touchHighlightElements\s*:\s*true/g,
177
- 'touchHighlightElements: false'
178
- );
179
- console.log('✅ Updated touchHighlightElements true → false');
180
- }
181
-
182
- // 2️⃣ If already false → skip
183
- else if (/touchHighlightElements\s*:\s*false/.test(content)) {
184
- console.log('ℹ️ touchHighlightElements already false');
185
- return;
186
- }
187
-
188
- // 3️⃣ If touch block exists → add inside it
189
- else if (/touch\s*:\s*\{/.test(content)) {
190
- content = content.replace(
191
- /(touch\s*:\s*\{)/,
192
- `$1\n touchHighlightElements: false,`
193
- );
194
- console.log('✅ Added touchHighlightElements inside existing touch block');
195
- }
196
-
197
- // 4️⃣ If no touch block → create one
198
- else {
199
- content = content.replace(
200
- /new Framework7\s*\(\s*\{/,
201
- `new Framework7({\n touch: {\n touchHighlightElements: false\n },`
202
- );
203
- console.log('✅ Created new touch block with touchHighlightElements:false');
204
- }
205
-
206
- fs.writeFileSync(appJsPath, content, 'utf8');
207
- console.log('✅ Done updating app.js');
208
- };
209
-
210
-
211
- const replaceKeyboardSet=()=>{
212
-
213
-
214
- const appJsPath = path.join(process.cwd(), 'src', 'js', 'capacitor-app.js');
215
-
216
- if (fs.existsSync(appJsPath)) {
217
- let appJsContent = fs.readFileSync(appJsPath, 'utf8');
218
-
219
- const lines = appJsContent.split(/\r?\n/);
220
- const newLines = [];
221
-
222
- const targetKeywords = [
223
- 'Keyboard.setResizeMode',
224
- 'Keyboard.setScroll',
225
- 'Keyboard.setAccessoryBarVisible',
226
- ];
227
-
228
- let insideIosWrap = false;
229
-
230
- lines.forEach((line, index) => {
231
- const trimmed = line.trim();
232
-
233
- // detect already inside ios check
234
- if (/if\s*\(\s*Capacitor\.getPlatform\(\)\s*===\s*['"]ios['"]\s*\)/.test(trimmed)) {
235
- insideIosWrap = true;
236
- newLines.push(line);
237
- return;
238
- }
239
-
240
- // detect closing of a block
241
- if (insideIosWrap && trimmed === '}') {
242
- insideIosWrap = false;
243
- newLines.push(line);
244
- return;
245
- }
246
-
247
- const isKeyboardSetCall = targetKeywords.some((kw) => trimmed.startsWith(kw));
248
-
249
- if (isKeyboardSetCall) {
250
- if (!insideIosWrap) {
251
- const indentMatch = line.match(/^(\s*)/);
252
- const indent = indentMatch ? indentMatch[1] : '';
253
- newLines.push(`${indent}if (Capacitor.getPlatform() === 'ios') {`);
254
- newLines.push(`${indent} ${trimmed}`);
255
- newLines.push(`${indent}}`);
256
- console.log(`✅ Wrapped line ${index + 1} with ios check`);
257
- } else {
258
- // already inside ios wrap, leave alone
259
- newLines.push(line);
260
- }
261
- } else {
262
- newLines.push(line);
263
- }
264
- });
265
-
266
- fs.writeFileSync(appJsPath, newLines.join('\n'), 'utf8');
267
- console.log(`✅ All Keyboard.set* lines wrapped safely with ios check`);
268
- }
269
- else
270
- {
271
-
272
-
273
- const configPath = path.join(process.cwd(), 'capacitor.config.json');
274
-
275
- const rawData = fs.readFileSync(configPath, 'utf8');
276
- const config = JSON.parse(rawData);
277
-
278
- const appUniqueId=config.android.APP_UNIQUE_ID
279
-
280
- if(appUniqueId!=172)
281
- console.error(`❌ src/js/capacitor-app.js not found at: ${appJsPath}`);
282
- }
283
-
284
-
285
-
286
- }
287
-
288
-
289
-
290
-
291
-
292
-
293
- addFavIconCode()
294
- appJssmallModifications();
295
- replaceKeyboardSet()
296
-
297
- ensureTouchHighlightDisabled()
298
-
299
-
300
-
301
-
302
-
303
- const configPath = path.join(process.cwd(), 'capacitor.config.json');
304
- if (!fs.existsSync(configPath)) {
305
- console.error(`❌ capacitor.config.json not found at: ${configPath}`);
306
- //return;
307
- }
308
- const rawData = fs.readFileSync(configPath, 'utf8');
309
- const config = JSON.parse(rawData);
310
- const targetAppId=config.appId
311
-
312
-
313
-
314
-
315
-
316
-
317
-
318
-
319
- function isNotificationFeatureUsed() {
320
- const jsDir = path.join(process.cwd(), 'src', 'js');
321
-
322
- if (!fs.existsSync(jsDir)) return false;
323
-
324
- const notificationFiles = fs.readdirSync(jsDir).filter(file =>
325
- /^onesignal-.*\.js$/.test(file) || /^localNotification-.*\.js$/.test(file)
326
- );
327
-
328
- if (notificationFiles.length === 0) return false;
329
-
330
- // collect all js files to scan imports
331
- const allJsFiles = [];
332
-
333
- const walk = (dir) => {
334
- fs.readdirSync(dir).forEach(file => {
335
- const fullPath = path.join(dir, file);
336
- if (fs.statSync(fullPath).isDirectory()) {
337
- walk(fullPath);
338
- } else if (file.endsWith('.js')) {
339
- allJsFiles.push(fullPath);
340
- }
341
- });
342
- };
343
-
344
- walk(path.join(process.cwd(), 'src'));
345
-
346
- // check if notification file is imported anywhere
347
- for (const notifFile of notificationFiles) {
348
- const importRegex = new RegExp(notifFile.replace('.js', ''), 'g');
349
-
350
- for (const file of allJsFiles) {
351
- const content = fs.readFileSync(file, 'utf8');
352
- if (importRegex.test(content)) {
353
- console.log(`🔔 Notification feature detected via ${notifFile}`);
354
- return true;
355
- }
356
- }
357
- }
358
-
359
- return false;
360
- }
361
-
362
- function addPostNotificationPermissionIfNeeded() {
363
- const permission =
364
- '<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />';
365
-
366
- if (!isNotificationFeatureUsed()) {
367
- console.log('ℹ️ Notification feature not used. Skipping POST_NOTIFICATIONS permission.');
368
- return;
369
- }
370
-
371
- console.log('✅ Notification feature is used. Ensuring POST_NOTIFICATIONS permission...');
372
- addAndroidPermissions([permission]);
373
- }
374
-
375
-
376
- addPostNotificationPermissionIfNeeded();
377
-
378
-
379
-
380
-
381
- //console.log("TARGET APP ID IS : "+ targetAppId)
382
-
383
- let permissions;
384
- if(targetAppId=='apk.bulk.app.uninstaller' || targetAppId=='apk.extractor.installer')
385
- {
386
- permissions=[
387
- '<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>',
388
- '<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>',
389
- '<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>'
390
- ];
391
-
392
- // EXAMPLE USAGE
393
- addAndroidPermissions(permissions);
394
- }
395
- else if(targetAppId=="image.to.text.document")
396
- {
397
- permissions=[
398
- '<uses-permission android:name="android.permission.CAMERA" />',
399
- '<uses-feature android:name="android.hardware.camera" android:required="true" />',
400
- ];
401
- }
402
-
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+
4
+
5
+ /**
6
+ * Adds user permissions to AndroidManifest.xml if not already present
7
+ * based on capacitor.config.json appId matching.
8
+ *
9
+ * @param {string} targetAppId - appId you want to match
10
+ * @param {string[]} permissionsToAdd - permission tags to insert
11
+ */
12
+ function addAndroidPermissions(permissionsToAdd) {
13
+ try {
14
+
15
+ if (!Array.isArray(permissionsToAdd) || permissionsToAdd.length === 0) {
16
+ console.log("ℹ️ No permissions to add");
17
+ return;
18
+ }
19
+
20
+ // read capacitor.config.json
21
+ const configPath = path.join(process.cwd(), 'capacitor.config.json');
22
+ if (!fs.existsSync(configPath)) {
23
+ console.error(`❌ capacitor.config.json not found at: ${configPath}`);
24
+ return;
25
+ }
26
+
27
+ const rawData = fs.readFileSync(configPath, 'utf8');
28
+ const config = JSON.parse(rawData);
29
+
30
+
31
+
32
+ const androidManifestPath = path.join(
33
+ process.cwd(),
34
+ 'android',
35
+ 'app',
36
+ 'src',
37
+ 'main',
38
+ 'AndroidManifest.xml'
39
+ );
40
+
41
+ if (!fs.existsSync(androidManifestPath)) {
42
+ console.error(`❌ AndroidManifest.xml not found at: ${androidManifestPath}`);
43
+ return;
44
+ }
45
+
46
+ let manifestContent = fs.readFileSync(androidManifestPath, 'utf8');
47
+ let updated = false;
48
+
49
+ permissionsToAdd.forEach(permission => {
50
+ if (!manifestContent.includes(permission)) {
51
+ console.log(`🔧 Adding permission: ${permission}`);
52
+ manifestContent = manifestContent.replace(
53
+ '</manifest>',
54
+ ` ${permission}\n</manifest>`
55
+ );
56
+ updated = true;
57
+ } else {
58
+ console.log(`ℹ️ Permission already exists: ${permission}`);
59
+ }
60
+ });
61
+
62
+ if (updated) {
63
+ fs.writeFileSync(androidManifestPath, manifestContent, 'utf8');
64
+ console.log('✅ AndroidManifest.xml updated successfully.');
65
+ } else {
66
+ console.log('✅ All required permissions already present.');
67
+ }
68
+
69
+ } catch (error) {
70
+ console.error(`❌ Error: ${error.message}`);
71
+ }
72
+ }
73
+
74
+
75
+
76
+ const addFavIconCode=()=>{
77
+ const htmlFilePath = path.join(process.cwd(), 'src', 'index.html');
78
+
79
+ if (fs.existsSync(htmlFilePath)) {
80
+ let htmlContent = fs.readFileSync(htmlFilePath, 'utf8');
81
+
82
+ const faviconTag = '<link rel="icon" href="data:;base64,iVBORw0KGgo=">';
83
+
84
+ if (!htmlContent.includes(faviconTag)) {
85
+ const headOpenTag = '<head>';
86
+ const headIndex = htmlContent.indexOf(headOpenTag);
87
+
88
+ if (headIndex !== -1) {
89
+ const insertPos = headIndex + headOpenTag.length;
90
+ htmlContent =
91
+ htmlContent.slice(0, insertPos) +
92
+ `\n ${faviconTag}` +
93
+ htmlContent.slice(insertPos);
94
+
95
+ fs.writeFileSync(htmlFilePath, htmlContent, 'utf8');
96
+ console.log(`✅ Favicon link added successfully to index.html`);
97
+ } else {
98
+ console.error('❌ <head> tag not found in index.html');
99
+ }
100
+ } else {
101
+ console.log('ℹ️ Favicon link already exists in index.html');
102
+ }
103
+ } else {
104
+ console.error(`❌ index.html not found at: ${htmlFilePath}`);
105
+ }
106
+ }
107
+
108
+
109
+ const appJssmallModifications=()=>{
110
+
111
+ const appJsPath = path.join(process.cwd(), 'src', 'js', 'app.js');
112
+
113
+ if (fs.existsSync(appJsPath)) {
114
+ let appJsContent = fs.readFileSync(appJsPath, 'utf8');
115
+
116
+ // 1. ensure iosOverlaysWebView is true
117
+ if (/iosOverlaysWebView\s*:\s*false/.test(appJsContent)) {
118
+ appJsContent = appJsContent.replace(/iosOverlaysWebView\s*:\s*false/, 'iosOverlaysWebView: true');
119
+ console.log('✅ iosOverlaysWebView changed to true');
120
+ } else if (!/iosOverlaysWebView\s*:/.test(appJsContent)) {
121
+ // add if missing
122
+ appJsContent = appJsContent.replace(
123
+ /statusbar\s*:\s*\{/,
124
+ `statusbar: {\n iosOverlaysWebView: true,`
125
+ );
126
+ console.log('✅ iosOverlaysWebView added');
127
+ } else {
128
+ console.log('ℹ️ iosOverlaysWebView already true');
129
+ }
130
+
131
+ // 2. ensure androidOverlaysWebView is true
132
+ if (/androidOverlaysWebView\s*:\s*false/.test(appJsContent)) {
133
+ appJsContent = appJsContent.replace(/androidOverlaysWebView\s*:\s*false/, 'androidOverlaysWebView: true');
134
+ console.log('✅ androidOverlaysWebView changed to true');
135
+ } else if (!/androidOverlaysWebView\s*:/.test(appJsContent)) {
136
+ // add if missing
137
+ appJsContent = appJsContent.replace(
138
+ /statusbar\s*:\s*\{/,
139
+ `statusbar: {\n androidOverlaysWebView: true,`
140
+ );
141
+ console.log('✅ androidOverlaysWebView added');
142
+ } else {
143
+ console.log('ℹ️ androidOverlaysWebView already true');
144
+ }
145
+
146
+ // 3. change theme
147
+ const themeRegex = /theme\s*:\s*['"]auto['"]/;
148
+ if (themeRegex.test(appJsContent)) {
149
+ appJsContent = appJsContent.replace(themeRegex, `theme: 'md'`);
150
+ console.log('✅ theme changed to md');
151
+ } else {
152
+ console.log('ℹ️ theme: auto not found, no changes made');
153
+ }
154
+
155
+ fs.writeFileSync(appJsPath, appJsContent, 'utf8');
156
+ console.log('✅ app.js updated successfully');
157
+ } else {
158
+ console.error(`❌ src/js/app.js not found at: ${appJsPath}`);
159
+ }
160
+ }
161
+
162
+
163
+ const ensureTouchHighlightDisabled = () => {
164
+ const appJsPath = path.join(process.cwd(), 'src', 'js', 'app.js');
165
+
166
+ if (!fs.existsSync(appJsPath)) {
167
+ console.error(`❌ src/js/app.js not found at: ${appJsPath}`);
168
+ return;
169
+ }
170
+
171
+ let content = fs.readFileSync(appJsPath, 'utf8');
172
+
173
+ // 1️⃣ If explicitly true → change to false
174
+ if (/touchHighlightElements\s*:\s*true/.test(content)) {
175
+ content = content.replace(
176
+ /touchHighlightElements\s*:\s*true/g,
177
+ 'touchHighlightElements: false'
178
+ );
179
+ console.log('✅ Updated touchHighlightElements true → false');
180
+ }
181
+
182
+ // 2️⃣ If already false → skip
183
+ else if (/touchHighlightElements\s*:\s*false/.test(content)) {
184
+ console.log('ℹ️ touchHighlightElements already false');
185
+ return;
186
+ }
187
+
188
+ // 3️⃣ If touch block exists → add inside it
189
+ else if (/touch\s*:\s*\{/.test(content)) {
190
+ content = content.replace(
191
+ /(touch\s*:\s*\{)/,
192
+ `$1\n touchHighlightElements: false,`
193
+ );
194
+ console.log('✅ Added touchHighlightElements inside existing touch block');
195
+ }
196
+
197
+ // 4️⃣ If no touch block → create one
198
+ else {
199
+ content = content.replace(
200
+ /new Framework7\s*\(\s*\{/,
201
+ `new Framework7({\n touch: {\n touchHighlightElements: false\n },`
202
+ );
203
+ console.log('✅ Created new touch block with touchHighlightElements:false');
204
+ }
205
+
206
+ fs.writeFileSync(appJsPath, content, 'utf8');
207
+ console.log('✅ Done updating app.js');
208
+ };
209
+
210
+
211
+ const replaceKeyboardSet=()=>{
212
+
213
+
214
+ const appJsPath = path.join(process.cwd(), 'src', 'js', 'capacitor-app.js');
215
+
216
+ if (fs.existsSync(appJsPath)) {
217
+ let appJsContent = fs.readFileSync(appJsPath, 'utf8');
218
+
219
+ const lines = appJsContent.split(/\r?\n/);
220
+ const newLines = [];
221
+
222
+ const targetKeywords = [
223
+ 'Keyboard.setResizeMode',
224
+ 'Keyboard.setScroll',
225
+ 'Keyboard.setAccessoryBarVisible',
226
+ ];
227
+
228
+ let insideIosWrap = false;
229
+
230
+ lines.forEach((line, index) => {
231
+ const trimmed = line.trim();
232
+
233
+ // detect already inside ios check
234
+ if (/if\s*\(\s*Capacitor\.getPlatform\(\)\s*===\s*['"]ios['"]\s*\)/.test(trimmed)) {
235
+ insideIosWrap = true;
236
+ newLines.push(line);
237
+ return;
238
+ }
239
+
240
+ // detect closing of a block
241
+ if (insideIosWrap && trimmed === '}') {
242
+ insideIosWrap = false;
243
+ newLines.push(line);
244
+ return;
245
+ }
246
+
247
+ const isKeyboardSetCall = targetKeywords.some((kw) => trimmed.startsWith(kw));
248
+
249
+ if (isKeyboardSetCall) {
250
+ if (!insideIosWrap) {
251
+ const indentMatch = line.match(/^(\s*)/);
252
+ const indent = indentMatch ? indentMatch[1] : '';
253
+ newLines.push(`${indent}if (Capacitor.getPlatform() === 'ios') {`);
254
+ newLines.push(`${indent} ${trimmed}`);
255
+ newLines.push(`${indent}}`);
256
+ console.log(`✅ Wrapped line ${index + 1} with ios check`);
257
+ } else {
258
+ // already inside ios wrap, leave alone
259
+ newLines.push(line);
260
+ }
261
+ } else {
262
+ newLines.push(line);
263
+ }
264
+ });
265
+
266
+ fs.writeFileSync(appJsPath, newLines.join('\n'), 'utf8');
267
+ console.log(`✅ All Keyboard.set* lines wrapped safely with ios check`);
268
+ }
269
+ else
270
+ {
271
+
272
+
273
+ const configPath = path.join(process.cwd(), 'capacitor.config.json');
274
+
275
+ const rawData = fs.readFileSync(configPath, 'utf8');
276
+ const config = JSON.parse(rawData);
277
+
278
+ const appUniqueId=config.android.APP_UNIQUE_ID
279
+
280
+ if(appUniqueId!=172)
281
+ console.error(`❌ src/js/capacitor-app.js not found at: ${appJsPath}`);
282
+ }
283
+
284
+
285
+
286
+ }
287
+
288
+
289
+
290
+
291
+
292
+
293
+ addFavIconCode()
294
+ appJssmallModifications();
295
+ replaceKeyboardSet()
296
+
297
+ ensureTouchHighlightDisabled()
298
+
299
+
300
+
301
+
302
+
303
+ const configPath = path.join(process.cwd(), 'capacitor.config.json');
304
+ if (!fs.existsSync(configPath)) {
305
+ console.error(`❌ capacitor.config.json not found at: ${configPath}`);
306
+ //return;
307
+ }
308
+ const rawData = fs.readFileSync(configPath, 'utf8');
309
+ const config = JSON.parse(rawData);
310
+ const targetAppId=config.appId
311
+
312
+
313
+
314
+
315
+
316
+
317
+
318
+
319
+ function isNotificationFeatureUsed() {
320
+ const jsDir = path.join(process.cwd(), 'src', 'js');
321
+
322
+ if (!fs.existsSync(jsDir)) return false;
323
+
324
+ const notificationFiles = fs.readdirSync(jsDir).filter(file =>
325
+ /^onesignal-.*\.js$/.test(file) || /^localNotification-.*\.js$/.test(file)
326
+ );
327
+
328
+ if (notificationFiles.length === 0) return false;
329
+
330
+ // collect all js files to scan imports
331
+ const allJsFiles = [];
332
+
333
+ const walk = (dir) => {
334
+ fs.readdirSync(dir).forEach(file => {
335
+ const fullPath = path.join(dir, file);
336
+ if (fs.statSync(fullPath).isDirectory()) {
337
+ walk(fullPath);
338
+ } else if (file.endsWith('.js')) {
339
+ allJsFiles.push(fullPath);
340
+ }
341
+ });
342
+ };
343
+
344
+ walk(path.join(process.cwd(), 'src'));
345
+
346
+ // check if notification file is imported anywhere
347
+ for (const notifFile of notificationFiles) {
348
+ const importRegex = new RegExp(notifFile.replace('.js', ''), 'g');
349
+
350
+ for (const file of allJsFiles) {
351
+ const content = fs.readFileSync(file, 'utf8');
352
+ if (importRegex.test(content)) {
353
+ console.log(`🔔 Notification feature detected via ${notifFile}`);
354
+ return true;
355
+ }
356
+ }
357
+ }
358
+
359
+ return false;
360
+ }
361
+
362
+ function addPostNotificationPermissionIfNeeded() {
363
+ const permission =
364
+ '<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />';
365
+
366
+ if (!isNotificationFeatureUsed()) {
367
+ console.log('ℹ️ Notification feature not used. Skipping POST_NOTIFICATIONS permission.');
368
+ return;
369
+ }
370
+
371
+ console.log('✅ Notification feature is used. Ensuring POST_NOTIFICATIONS permission...');
372
+ addAndroidPermissions([permission]);
373
+ }
374
+
375
+
376
+ addPostNotificationPermissionIfNeeded();
377
+
378
+
379
+
380
+
381
+ //console.log("TARGET APP ID IS : "+ targetAppId)
382
+
383
+ let permissions;
384
+ if(targetAppId=='apk.bulk.app.uninstaller' || targetAppId=='apk.extractor.installer')
385
+ {
386
+ permissions=[
387
+ '<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>',
388
+ '<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>',
389
+ '<uses-permission android:name="android.permission.GET_PACKAGE_SIZE"/>'
390
+ ];
391
+
392
+ // EXAMPLE USAGE
393
+ addAndroidPermissions(permissions);
394
+ }
395
+ else if(targetAppId=="image.to.text.document")
396
+ {
397
+ permissions=[
398
+ '<uses-permission android:name="android.permission.CAMERA" />',
399
+ '<uses-feature android:name="android.hardware.camera" android:required="true" />',
400
+ ];
401
+ }
402
+
403
403
  addAndroidPermissions(permissions);