codeplay-common 4.10.0 → 4.10.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
@@ -28,20 +28,20 @@ Files changed: `package.json`, `scripts/sync-files.js`, `files/buildCodeplay/cod
28
28
  - Preserve app-owned ad configuration and select each app's existing IAP analytics module.
29
29
  - Download every AdMob folder ZIP from htmlcodeplay.com; no AdMob archive is included in this npm package.
30
30
  - Validate ZIP contents before switching imports; retain the working package when a remote update fails.
31
- - Validate the selected folder controller during final-release checks while continuing to reject test aliases.
32
-
33
- ## 4.7.7 — 2026-10-07
34
-
35
- Version name: 4.7.7. Version code/build number: not applicable to this npm package.
36
- Bundled pre-build script: 6.4.
37
-
38
- Files changed: `package.json`, `scripts/sync-files.js`, `files/buildCodeplay/codeplayBeforeBuild-6.4.js`
39
- (replaces `codeplayBeforeBuild-6.3.js`), `README.md`, `CHANGELOG.md`, `RELEASE_NOTES.md`.
40
-
41
- - Keep `npm run build` as the Android default on every host; add `npm run build:ios` automatically during installation.
42
- - Route `build-capacitor-android` through the same pre-build validation before copying the web build.
43
- - Migrate direct save-gallery imports to `@saveGallery` and select the matching platform helper in Vite after one detailed Enter/y confirmation.
44
- - Stop without import writes on cancellation, missing helpers, mixed versions, unsupported query/hash aliases or concurrent source edits.
45
- - Reuse source directory traversal and combine gallery, retired OneSignal import, StatusBar and editor checks in one content pass.
46
- - Automatically remove an installed/declared `onesignal-cordova-plugin` with a warning; skip legacy OneSignal patching/helper downloads and stop on remaining package imports.
47
- - Keep `agent-temp/` ignored and remove existing `buildCodeplay/` ignore entries without adding them in future projects.
31
+ - Validate the selected folder controller during final-release checks while continuing to reject test aliases.
32
+
33
+ ## 4.7.7 — 2026-10-07
34
+
35
+ Version name: 4.7.7. Version code/build number: not applicable to this npm package.
36
+ Bundled pre-build script: 6.4.
37
+
38
+ Files changed: `package.json`, `scripts/sync-files.js`, `files/buildCodeplay/codeplayBeforeBuild-6.4.js`
39
+ (replaces `codeplayBeforeBuild-6.3.js`), `README.md`, `CHANGELOG.md`, `RELEASE_NOTES.md`.
40
+
41
+ - Keep `npm run build` as the Android default on every host; add `npm run build:ios` automatically during installation.
42
+ - Route `build-capacitor-android` through the same pre-build validation before copying the web build.
43
+ - Migrate direct save-gallery imports to `@saveGallery` and select the matching platform helper in Vite after one detailed Enter/y confirmation.
44
+ - Stop without import writes on cancellation, missing helpers, mixed versions, unsupported query/hash aliases or concurrent source edits.
45
+ - Reuse source directory traversal and combine gallery, retired OneSignal import, StatusBar and editor checks in one content pass.
46
+ - Automatically remove an installed/declared `onesignal-cordova-plugin` with a warning; skip legacy OneSignal patching/helper downloads and stop on remaining package imports.
47
+ - Keep `agent-temp/` ignored and remove existing `buildCodeplay/` ignore entries without adding them in future projects.
package/RELEASE_NOTES.md CHANGED
@@ -28,18 +28,18 @@ Files changed: `package.json`, `scripts/sync-files.js`, `files/buildCodeplay/cod
28
28
  - Preserve app-owned ad configuration and select each app's existing IAP analytics module.
29
29
  - Download every AdMob folder ZIP from htmlcodeplay.com; no AdMob archive is included in this npm package.
30
30
  - Validate ZIP contents before switching imports; retain the working package when a remote update fails.
31
- - Validate the selected folder controller during final-release checks while continuing to reject test aliases.
32
-
33
- ## 4.7.7 — 2026-10-07
34
-
35
- Version name: 4.7.7. Version code/build number: not applicable to this npm package.
36
-
37
- Files changed: `package.json`, `scripts/sync-files.js`, `files/buildCodeplay/codeplayBeforeBuild-6.4.js`
38
- (replaces `codeplayBeforeBuild-6.3.js`), `README.md`, `CHANGELOG.md`, `RELEASE_NOTES.md`.
39
-
40
- - Installation automatically configures Android and iOS build commands in your app's `package.json`.
41
- - Android builds remain the default; use `npm run build:ios` for iOS.
42
- - Save-gallery imports use one alias with a platform-specific helper and a clear confirmation before source changes.
43
- - Shared checks reuse file traversal to reduce repeated scanning.
44
- - Builds warn and automatically uninstall the retired OneSignal Cordova plugin when found.
45
- - `agent-temp/` stays ignored, while `buildCodeplay/` is removed from ignore rules.
31
+ - Validate the selected folder controller during final-release checks while continuing to reject test aliases.
32
+
33
+ ## 4.7.7 — 2026-10-07
34
+
35
+ Version name: 4.7.7. Version code/build number: not applicable to this npm package.
36
+
37
+ Files changed: `package.json`, `scripts/sync-files.js`, `files/buildCodeplay/codeplayBeforeBuild-6.4.js`
38
+ (replaces `codeplayBeforeBuild-6.3.js`), `README.md`, `CHANGELOG.md`, `RELEASE_NOTES.md`.
39
+
40
+ - Installation automatically configures Android and iOS build commands in your app's `package.json`.
41
+ - Android builds remain the default; use `npm run build:ios` for iOS.
42
+ - Save-gallery imports use one alias with a platform-specific helper and a clear confirmation before source changes.
43
+ - Shared checks reuse file traversal to reduce repeated scanning.
44
+ - Builds warn and automatically uninstall the retired OneSignal Cordova plugin when found.
45
+ - `agent-temp/` stays ignored, while `buildCodeplay/` is removed from ignore rules.
@@ -5,6 +5,138 @@ const fs = require('fs');
5
5
  const path = require('path');
6
6
  const plist = require('plist');
7
7
 
8
+ // Edit only build.rollupOptions.treeshake in the exported Vite config.
9
+ // Keep source formatting/comments and valid custom option objects intact.
10
+ const migrateViteTreeShaking = (content) => {
11
+ const newline = content.includes('\r\n') ? '\r\n' : '\n';
12
+ const tokens = [];
13
+ const pairs = new Map();
14
+ const stack = [];
15
+ const lexer = /\s+|\/\*[\s\S]*?\*\/|\/\/[^\r\n]*|"(?:\\[\s\S]|[^"\\])*"|'(?:\\[\s\S]|[^'\\])*'|`(?:\\[\s\S]|[^`\\])*`|=>|\.\.\.|[\w$]+|[^\s]/gy;
16
+ let match;
17
+ while ((match = lexer.exec(content))) {
18
+ const value = match[0];
19
+ if (/^\s|^\/\*|^\/\//.test(value)) continue;
20
+ // Regex literals may contain braces/commas; treat them as a single value.
21
+ if (value === '/' && (!tokens.length || /^(?:=|\(|\[|:|,|return|=>|!|\?|\||&)$/.test(tokens.at(-1).value))) {
22
+ const regex = /^\/(?:\\[^\r\n]|\[(?:\\[^\r\n]|[^\]\\\r\n])*\]|[^/\\[\r\n])+\/[a-z]*/.exec(content.slice(match.index));
23
+ if (!regex) throw new Error('Cannot safely read Vite regex literal; configuration preserved.');
24
+ lexer.lastIndex = match.index + regex[0].length;
25
+ tokens.push({ value: regex[0], start: match.index, end: lexer.lastIndex });
26
+ continue;
27
+ }
28
+ const index = tokens.length;
29
+ tokens.push({ value, start: match.index, end: lexer.lastIndex });
30
+ if (['{', '[', '('].includes(value)) stack.push(index);
31
+ else if (['}', ']', ')'].includes(value)) {
32
+ const open = stack.pop();
33
+ if (open === undefined || tokens[open].value !== ({ '}': '{', ']': '[', ')': '(' })[value]) {
34
+ throw new Error('Cannot safely read Vite configuration; file preserved.');
35
+ }
36
+ pairs.set(open, index);
37
+ }
38
+ }
39
+ if (stack.length) throw new Error('Unbalanced Vite configuration; file preserved.');
40
+ const value = index => tokens[index]?.value;
41
+ const edits = [];
42
+ const properties = open => {
43
+ const result = [];
44
+ const close = pairs.get(open);
45
+ for (let i = open + 1; i < close;) {
46
+ if (value(i) === ',') { i++; continue; }
47
+ const start = i;
48
+ let key = i;
49
+ if (value(i) === '[') {
50
+ if (pairs.get(i) !== i + 2 || !/^['"]/.test(value(i + 1))) throw new Error('Dynamic Vite property name; file preserved.');
51
+ key = i + 1;
52
+ }
53
+ const accessor = ['get', 'set'].includes(value(i)) && value(i + 2) === '(';
54
+ if (accessor) key = i + 1;
55
+ const name = value(key).replace(/^(['"])(.*)\1$/, '$2');
56
+ const afterKey = value(start) === '[' ? pairs.get(start) + 1 : key + 1;
57
+ const colon = value(afterKey) === ':';
58
+ while (i < close && value(i) !== ',') i = pairs.has(i) ? pairs.get(i) + 1 : i + 1;
59
+ if (colon || (key === start && i === start + 1) || value(afterKey) === '(') {
60
+ result.push({ name, start, first: colon ? afterKey + 1 : start, end: i, comma: value(i) === ',', colon });
61
+ }
62
+ }
63
+ return result;
64
+ };
65
+ const findConfig = (index, visited = new Set()) => {
66
+ if (visited.has(index)) throw new Error('Circular Vite configuration reference; file preserved.');
67
+ visited.add(index);
68
+ if (value(index) === 'async') return findConfig(index + 1, visited);
69
+ if (value(index) === '(') {
70
+ const close = pairs.get(index);
71
+ if (value(close + 1) === '=>') return findBody(close + 2, visited);
72
+ return findConfig(index + 1, visited);
73
+ }
74
+ if (value(index + 1) === '=>') return findBody(index + 2, visited);
75
+ if (value(index) === 'function') {
76
+ let body = index + 1;
77
+ while (body < tokens.length && value(body) !== '{') body++;
78
+ return findBody(body, visited);
79
+ }
80
+ if (value(index) === '{') return index;
81
+ if (value(index + 1) === '(') return findConfig(index + 2, visited);
82
+ const declaration = tokens.findIndex((token, i) => ['const', 'let', 'var'].includes(token.value) && value(i + 1) === value(index) && value(i + 2) === '=');
83
+ if (declaration >= 0) return findConfig(declaration + 3, visited);
84
+ throw new Error('Unsupported dynamic Vite config; cannot safely set treeshake. File preserved.');
85
+ };
86
+ const findBody = (index, visited) => {
87
+ if (value(index) !== '{') return findConfig(index, visited);
88
+ const returns = [];
89
+ for (let i = index + 1; i < pairs.get(index); i++) {
90
+ if (value(i) === 'return') returns.push(i + 1);
91
+ if (pairs.has(i)) i = pairs.get(i);
92
+ }
93
+ if (returns.length !== 1) throw new Error('Vite config must return one static object for automatic treeshake migration. File preserved.');
94
+ return findConfig(returns[0], visited);
95
+ };
96
+ const append = (open, property) => {
97
+ const close = pairs.get(open);
98
+ const last = tokens[close - 1];
99
+ const line = content.slice(content.lastIndexOf('\n', tokens[open].start) + 1, tokens[open].start);
100
+ const indent = line.match(/^[ \t]*/)[0];
101
+ const needsComma = close > open + 1 && last.value !== ',';
102
+ const inlineComma = needsComma && last.end === tokens[close].start;
103
+ if (needsComma && !inlineComma) edits.push({ start: last.end, end: last.end, text: ',' });
104
+ edits.push({ start: tokens[close].start, end: tokens[close].start, text: `${inlineComma ? ',' : ''}${newline}${indent} ${property},${newline}${indent}` });
105
+ };
106
+ let exported = tokens.findIndex((token, i) => token.value === 'export' && value(i + 1) === 'default');
107
+ if (exported >= 0) exported += 2;
108
+ else {
109
+ exported = tokens.findIndex((token, i) => token.value === 'module' && value(i + 1) === '.' && value(i + 2) === 'exports' && value(i + 3) === '=');
110
+ if (exported >= 0) exported += 4;
111
+ }
112
+ if (exported < 0) throw new Error('No supported Vite config export found; file preserved.');
113
+ const config = findConfig(exported);
114
+ const build = properties(config).filter(property => property.name === 'build').at(-1);
115
+ if (!build) append(config, 'build: { rollupOptions: { treeshake: true } }');
116
+ else {
117
+ if (value(build.first) !== '{' || pairs.get(build.first) !== build.end - 1) throw new Error('Dynamic Vite build settings; file preserved.');
118
+ const rollup = properties(build.first).filter(property => property.name === 'rollupOptions').at(-1);
119
+ if (!rollup) append(build.first, 'rollupOptions: { treeshake: true }');
120
+ else {
121
+ if (value(rollup.first) !== '{' || pairs.get(rollup.first) !== rollup.end - 1) throw new Error('Dynamic Vite rollupOptions; file preserved.');
122
+ const entries = properties(rollup.first).filter(property => property.name === 'treeshake');
123
+ if (!entries.length) append(rollup.first, 'treeshake: true');
124
+ else {
125
+ // JavaScript uses the last duplicate; retain that setting and remove earlier ones.
126
+ const keep = entries.at(-1);
127
+ for (const entry of entries.slice(0, -1)) {
128
+ edits.push({ start: tokens[entry.start].start, end: entry.comma ? tokens[entry.end].end : tokens[entry.end - 1].end, text: '' });
129
+ }
130
+ const isTrue = value(keep.first) === 'true' && keep.end === keep.first + 1;
131
+ const isObject = value(keep.first) === '{' && pairs.get(keep.first) === keep.end - 1;
132
+ if (!isTrue && !isObject) edits.push({ start: tokens[keep.first].start, end: tokens[keep.end - 1].end, text: keep.colon ? 'true' : 'treeshake: true' });
133
+ }
134
+ }
135
+ }
136
+ for (const edit of edits.sort((a, b) => b.start - a.start)) content = content.slice(0, edit.start) + edit.text + content.slice(edit.end);
137
+ return content;
138
+ };
139
+
8
140
 
9
141
 
10
142
  // BEGIN IAP BUILD MIGRATION
@@ -2938,6 +3070,17 @@ function getViteConfigPath() {
2938
3070
  .find(filePath => fs.existsSync(filePath));
2939
3071
  };
2940
3072
 
3073
+ const syncViteTreeShaking = () => {
3074
+ const configPath = getViteConfigPath();
3075
+ if (!configPath) return;
3076
+ const current = fs.readFileSync(configPath, 'utf8');
3077
+ const next = migrateViteTreeShaking(current);
3078
+ if (next !== current) {
3079
+ fs.writeFileSync(configPath, next, 'utf8');
3080
+ console.log('✅ Vite treeshake setting updated without duplicate entries.');
3081
+ }
3082
+ };
3083
+
2941
3084
  const getLatestIapDir = () => {
2942
3085
  const adsDir = path.join(process.cwd(), "src", "js", "Ads");
2943
3086
 
@@ -4483,6 +4626,7 @@ async function main() {
4483
4626
  syncRevenueCatIapSetup();
4484
4627
  syncFirebaseAnalyticsSetup();
4485
4628
  checkAndupdateDropInViteConfig();
4629
+ syncViteTreeShaking();
4486
4630
  checkAdmobConfigurationProperty();
4487
4631
  syncAndroidAdIdPermission();
4488
4632
  syncAndroidBuildOptimization();
@@ -1,27 +1,27 @@
1
- {
2
- "plugins":[
3
- {"name":"backbutton","pattern":"backbutton-(\\d+\\.\\d+)\\.js$","minVersion":"2.1","baseDir":"js","mandatoryUpdate":true},
1
+ {
2
+ "plugins":[
3
+ {"name":"backbutton","pattern":"backbutton-(\\d+\\.\\d+)\\.js$","minVersion":"2.1","baseDir":"js","mandatoryUpdate":true},
4
4
  {"name":"common-js","pattern":"common-(\\d+\\.\\d+)(?:-beta-(\\d+))?\\.js$","minVersion":"6.7","baseDir":"js","mandatoryUpdate":true},
5
-
5
+
6
6
  {"name":"admob-nextgen","pattern":"admob-nextgen-(\\d+(?:\\.\\d+)*)$","minVersion":"4.1","baseDir":"js/Ads","mandatoryUpdate":true,"isFolder":true},
7
- {"name":"video-player","pattern":"video-player-(\\d+\\.\\d+)\\.js$","minVersion":"1.6","baseDir":"js","mandatoryUpdate":true},
8
- {"name":"image-cropper","pattern":"image-cropper-(\\d+\\.\\d+)\\.js$","minVersion":"1.1","baseDir":"js","mandatoryUpdate":true},
9
- {"name":"beautify","pattern":"beautify-(\\d+\\.\\d+)\\.js$","minVersion":"1.1","baseDir":"js","mandatoryUpdate":true},
10
-
11
-
12
- {"name":"localization","pattern":"localization-(\\d+\\.\\d+)$","minVersion":"1.8","baseDir":"js/localization","mandatoryUpdate":true,"isFolder":true},
13
- {"name": "localization_settings","pattern": "localization_settings-(\\d+\\.\\d+)\\.js$","minVersion": "1.1","required": true,"baseDir": "js/localization","mandatoryUpdate": true},
14
-
15
-
16
- {"name":"editor","pattern":"editor-(\\d+\\.\\d+)$","minVersion":"2.0","baseDir":"js/editor","mandatoryUpdate":true,"isFolder":true},
17
- {"name":"ffmpeg","pattern":"ffmpeg-(\\d+\\.\\d+)$","minVersion":"1.6","baseDir":"js","mandatoryUpdate":true,"isFolder":true},
18
- {"name":"theme","pattern":"theme-(\\d+\\.\\d+)$","minVersion":"3.5","baseDir":"theme","destDir":"theme","mandatoryUpdate":true,"isFolder":true},
19
- {"name":"certificatejs","pattern":"certificatejs-(\\d+\\.\\d+)$","minVersion":"1.9","baseDir":"certificate","destDir":"certificate","mandatoryUpdate":true,"isFolder":true},
7
+ {"name":"video-player","pattern":"video-player-(\\d+\\.\\d+)\\.js$","minVersion":"1.6","baseDir":"js","mandatoryUpdate":true},
8
+ {"name":"image-cropper","pattern":"image-cropper-(\\d+\\.\\d+)\\.js$","minVersion":"1.1","baseDir":"js","mandatoryUpdate":true},
9
+ {"name":"beautify","pattern":"beautify-(\\d+\\.\\d+)\\.js$","minVersion":"1.1","baseDir":"js","mandatoryUpdate":true},
10
+
11
+
12
+ {"name":"localization","pattern":"localization-(\\d+\\.\\d+)$","minVersion":"1.8","baseDir":"js/localization","mandatoryUpdate":true,"isFolder":true},
13
+ {"name": "localization_settings","pattern": "localization_settings-(\\d+\\.\\d+)\\.js$","minVersion": "1.1","required": true,"baseDir": "js/localization","mandatoryUpdate": true},
14
+
15
+
16
+ {"name":"editor","pattern":"editor-(\\d+\\.\\d+)$","minVersion":"2.0","baseDir":"js/editor","mandatoryUpdate":true,"isFolder":true},
17
+ {"name":"ffmpeg","pattern":"ffmpeg-(\\d+\\.\\d+)$","minVersion":"1.6","baseDir":"js","mandatoryUpdate":true,"isFolder":true},
18
+ {"name":"theme","pattern":"theme-(\\d+\\.\\d+)$","minVersion":"3.5","baseDir":"theme","destDir":"theme","mandatoryUpdate":true,"isFolder":true},
19
+ {"name":"certificatejs","pattern":"certificatejs-(\\d+\\.\\d+)$","minVersion":"1.9","baseDir":"certificate","destDir":"certificate","mandatoryUpdate":true,"isFolder":true},
20
20
  {"name":"IAP","pattern":"IAP-(\\d+\\.\\d+)$","minVersion":"4.6","baseDir":"js/Ads","mandatoryUpdate":true,"isFolder":true},
21
- {"name":"common-less","pattern":"common-(\\d+\\.\\d+)\\.less$","minVersion":"1.8","baseDir":"assets/css","mandatoryUpdate":true},
22
- {"name":"localNotification_AppSettings","pattern":"localNotification_AppSettings-(\\d+\\.\\d+)\\.js$","minVersion":"1.0","baseDir":"js","mandatoryUpdate":true},
23
- {"name":"localNotification","pattern":"localNotification-(\\d+\\.\\d+)\\.js$","minVersion":"2.2","baseDir":"js","mandatoryUpdate":true},
24
- {"name":"onesignal","pattern":"onesignal-(\\d+\\.\\d+)\\.js$","minVersion":"2.4","baseDir":"js","mandatoryUpdate":true},
25
- {"name":"saveToGalleryAndSaveAnyFile","pattern":"saveToGalleryAndSaveAnyFile-(\\d+\\.\\d+)(-ios)?\\.js$","minVersion":"3.1","baseDir":"js","mandatoryUpdate":true}
26
- ]
21
+ {"name":"common-less","pattern":"common-(\\d+\\.\\d+)\\.less$","minVersion":"1.8","baseDir":"assets/css","mandatoryUpdate":true},
22
+ {"name":"localNotification_AppSettings","pattern":"localNotification_AppSettings-(\\d+\\.\\d+)\\.js$","minVersion":"1.0","baseDir":"js","mandatoryUpdate":true},
23
+ {"name":"localNotification","pattern":"localNotification-(\\d+\\.\\d+)\\.js$","minVersion":"2.2","baseDir":"js","mandatoryUpdate":true},
24
+ {"name":"onesignal","pattern":"onesignal-(\\d+\\.\\d+)\\.js$","minVersion":"2.4","baseDir":"js","mandatoryUpdate":true},
25
+ {"name":"saveToGalleryAndSaveAnyFile","pattern":"saveToGalleryAndSaveAnyFile-(\\d+\\.\\d+)(-ios)?\\.js$","minVersion":"3.1","baseDir":"js","mandatoryUpdate":true}
26
+ ]
27
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeplay-common",
3
- "version": "4.10.0",
3
+ "version": "4.10.2",
4
4
  "description": "Common build scripts and files",
5
5
  "scripts": {
6
6
  "postinstall": "node scripts/sync-files.js",