codeplay-common 4.9.7 → 4.10.0

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.
@@ -26,12 +26,12 @@ const path = require('node:path');
26
26
  const readline = require('node:readline/promises');
27
27
  const { spawn, spawnSync } = require('node:child_process');
28
28
  const sharp = require('sharp');
29
- const { frameStyles, createFrameSamples } = require('./scripts/screenshot/frame-samples.js');
29
+ const { frameStyles, createFrameSamples } = require('./scripts-common/screenshot/frame-samples.js');
30
30
  const {
31
31
  getDecorationSeed,
32
32
  createPromotionalDecorations,
33
33
  getPromotionalDecorationStyles,
34
- } = require('./scripts/screenshot/background-decorations.js');
34
+ } = require('./scripts-common/screenshot/background-decorations.js');
35
35
 
36
36
  const screenshotDirectory = path.join(__dirname, 'Auto-Screenshot', 'Store-image-Screenshot');
37
37
  const inFrameDirectory = path.join(__dirname, 'Auto-Screenshot', 'Store-image-Frame');
package/package.json CHANGED
@@ -1,15 +1,27 @@
1
1
  {
2
2
  "name": "codeplay-common",
3
- "version": "4.9.7",
3
+ "version": "4.10.0",
4
4
  "description": "Common build scripts and files",
5
5
  "scripts": {
6
- "postinstall": "node scripts/sync-files.js",
7
- "preinstall": "node scripts/uninstall.js"
6
+ "postinstall": "node scripts/sync-files.js",
7
+ "preinstall": "node scripts/uninstall.js"
8
+ },
9
+ "dependencies": {
10
+ "adm-zip": "^0.6.1",
11
+ "plist": "^3.1.0"
8
12
  },
9
13
  "repository": {
10
14
  "type": "git",
11
15
  "url": "https://github.com/merbin2012/codeplay-common.git"
12
16
  },
13
17
  "author": "Codeplay Technologies",
14
- "license": "MIT"
18
+ "license": "MIT",
19
+ "files": [
20
+ "files/",
21
+ "scripts/",
22
+ "README.md",
23
+ "CHANGELOG.md",
24
+ "RELEASE_NOTES.md",
25
+ "LICENSE"
26
+ ]
15
27
  }
@@ -1,110 +1,86 @@
1
- const fs = require("fs");
2
- const path = require("path");
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { updateBuildScripts, removeVersionedBuildScripts } = require('../files/buildCodeplay/project-scripts.cjs');
3
4
 
4
- const projectRoot = path.resolve(__dirname, "../../../"); // Your project's root
5
- const commonBuildPath = path.join(__dirname, "../files"); // Path to common files
6
- const buildCodeplayPath = path.join(commonBuildPath, "buildCodeplay"); // Correct path
7
- const packageJsonPath = path.join(projectRoot, "package.json");
8
-
9
- // Ensure package.json exists
10
- if (!fs.existsSync(packageJsonPath)) {
11
- process.stderr.write("❌ package.json not found!\n");
12
- process.exit(1);
13
- }
14
-
15
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
16
-
17
- function copyFolderSync(source, destination) {
18
- try {
19
- fs.cpSync(source, destination, { recursive: true });
20
- process.stdout.write(`✅ Copied folder: ${source} -> ${destination}\n`);
21
- } catch (error) {
22
- process.stderr.write(`⚠️ Failed to copy folder: ${source} - ${error.message}\n`);
5
+ function migrateAppScripts(projectRoot) {
6
+ const root = path.resolve(projectRoot);
7
+ const source = path.resolve(root, 'scripts');
8
+ const destination = path.resolve(root, 'scripts-common');
9
+ if (path.dirname(source) !== root || path.dirname(destination) !== root) throw new Error('Invalid app scripts path.');
10
+ if (!fs.existsSync(source)) return;
11
+ // Preflight the entire tree before moving anything. Never overwrite a
12
+ // different existing file or follow a linked directory.
13
+ function check(from, to) {
14
+ if (fs.lstatSync(from).isSymbolicLink() || (fs.existsSync(to) && fs.lstatSync(to).isSymbolicLink())) throw new Error('Cannot migrate linked script paths.');
15
+ if (!fs.existsSync(to)) return;
16
+ if (fs.statSync(from).isDirectory() && fs.statSync(to).isDirectory()) {
17
+ for (const name of fs.readdirSync(from)) check(path.join(from, name), path.join(to, name));
18
+ } else if (!fs.statSync(from).isFile() || !fs.statSync(to).isFile() || !fs.readFileSync(from).equals(fs.readFileSync(to))) {
19
+ throw new Error(`Scripts folder conflict; both files preserved: ${to}`);
23
20
  }
21
+ }
22
+ function move(from, to) {
23
+ if (!fs.existsSync(to)) { fs.renameSync(from, to); return; }
24
+ if (fs.statSync(from).isDirectory()) {
25
+ for (const name of fs.readdirSync(from)) move(path.join(from, name), path.join(to, name));
26
+ fs.rmdirSync(from);
27
+ } else fs.unlinkSync(from); // Identical existing file, verified above.
28
+ }
29
+ check(source, destination);
30
+ move(source, destination);
24
31
  }
25
32
 
26
- // Copy all files from `common-build-files/files/` to the project root
27
- fs.readdirSync(commonBuildPath).forEach(file => {
28
- // Never distribute or overwrite app-owned screenshot data.
29
- if (file === "scripts-screenshot") return;
30
- const sourcePath = path.join(commonBuildPath, file);
31
- const destPath = path.join(projectRoot, file);
32
-
33
- if (fs.statSync(sourcePath).isDirectory()) {
34
- copyFolderSync(sourcePath, destPath);
35
- } else {
36
- try {
37
- fs.copyFileSync(sourcePath, destPath);
38
- process.stdout.write(`✅ Copied file: ${file}\n`);
39
- } catch (error) {
40
- process.stderr.write(`⚠️ Failed to copy file: ${file} - ${error.message}\n`);
41
- }
42
- }
43
- });
44
-
45
- // Function to get the latest versioned file from files/buildCodeplay
46
- function getLatestFile(prefix) {
47
- if (!fs.existsSync(buildCodeplayPath)) return null; // Ensure directory exists
48
-
49
- const files = fs.readdirSync(buildCodeplayPath).filter(file => file.startsWith(prefix));
50
- if (files.length === 0) return null;
51
- files.sort((a, b) => b.localeCompare(a, undefined, { numeric: true }));
52
- return files[0];
33
+ function findProjectRoot() {
34
+ // npm may execute a file: dependency's lifecycle in its source directory.
35
+ // INIT_CWD identifies the app that invoked npm in that case.
36
+ for (const candidate of [process.env.INIT_CWD, path.join(__dirname, '../../..')]) {
37
+ if (!candidate) continue;
38
+ const root = path.resolve(candidate);
39
+ const file = path.join(root, 'package.json');
40
+ if (!fs.existsSync(file)) continue;
41
+ if (JSON.parse(fs.readFileSync(file, 'utf8')).name !== 'codeplay-common' && fs.existsSync(path.join(root, 'capacitor.config.json'))) return root;
42
+ }
43
+ return null;
53
44
  }
54
45
 
55
- // Detect latest script versions
56
- const latestSplashScreen = getLatestFile("add-splash-screen-");
57
- const latestSplashAnimation = getLatestFile("setSplashAnimation-");
58
- const latestCodeplayBuild = getLatestFile("codeplayBeforeBuild-");
59
-
60
- const latestPackageIdModification = getLatestFile("packageidBaseModification-");
61
- const baselineProfileSetupScript = "node scripts/setup-baseline-profile.js";
62
- const baselineProfileGenerateScript = "cd android && gradlew.bat :app:generateBaselineProfile --console=plain";
63
-
64
- function appendIfMissing(base, suffix) {
65
- if (!suffix) return base;
66
- if (!base || typeof base !== "string") return suffix;
67
- if (base.includes(suffix)) return base;
68
- return `${base} && ${suffix}`;
69
- }
70
-
71
-
72
- // Ensure scripts object exists
73
- packageJson.scripts = packageJson.scripts || {};
74
-
75
- // Update or add necessary scripts
76
- if (latestCodeplayBuild) {
77
- packageJson.scripts["build"] = `node buildCodeplay/${latestCodeplayBuild} && node buildCodeplay/${latestPackageIdModification} && cross-env NODE_ENV=production vite build --logLevel warn`;
78
- }
79
- if (latestSplashScreen && latestSplashAnimation) {
80
- packageJson.scripts["capacitor:sync:after"] = appendIfMissing(
81
- `node buildCodeplay/${latestSplashScreen} && node buildCodeplay/${latestSplashAnimation} && node buildCodeplay/manifestModification.js`,
82
- baselineProfileSetupScript
83
- );
84
- //node buildCodeplay/ios-emi-admob-modification.js &&
85
- } else if (packageJson.scripts["capacitor:sync:after"]) {
86
- packageJson.scripts["capacitor:sync:after"] = appendIfMissing(
87
- packageJson.scripts["capacitor:sync:after"],
88
- baselineProfileSetupScript
89
- );
46
+ function install(options = {}) {
47
+ const resolved = options.projectRoot || findProjectRoot();
48
+ if (!resolved) {
49
+ console.log('codeplay-common: no consuming Capacitor app found; skipping source-package setup.');
50
+ return null;
51
+ }
52
+ const projectRoot = path.resolve(resolved);
53
+ const commonFiles = path.resolve(__dirname, '../files');
54
+ const packagePath = path.join(projectRoot, 'package.json');
55
+ if (!fs.existsSync(packagePath)) throw new Error('Consuming application package.json was not found.');
56
+ const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
57
+ const scripts = updateBuildScripts(pkg.scripts || {});
58
+ migrateAppScripts(projectRoot);
59
+ // Copy the common templates into each application for local testing.
60
+ const buildSource = path.join(commonFiles, 'buildCodeplay');
61
+ const buildTarget = path.join(projectRoot, 'buildCodeplay');
62
+ fs.mkdirSync(buildTarget, { recursive: true });
63
+ for (const name of fs.readdirSync(buildSource)) {
64
+ const target = path.join(buildTarget, name);
65
+ if ((name === 'release-sync.config.json' || name === 'splashxml') && fs.existsSync(target)) continue;
66
+ fs.cpSync(path.join(buildSource, name), target, { recursive: true });
67
+ }
68
+ fs.copyFileSync(path.join(commonFiles, 'finalrelease'), path.join(projectRoot, 'finalrelease'));
69
+ if (options.copyAssets !== false) {
70
+ for (const name of fs.readdirSync(commonFiles)) {
71
+ if (name === 'buildCodeplay' || name === 'scripts-screenshot') continue;
72
+ fs.cpSync(path.join(commonFiles, name), path.join(projectRoot, name), { recursive: true });
73
+ }
74
+ }
75
+ pkg.scripts = scripts;
76
+ fs.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + '\n');
77
+ // Cleanup happens only after replacement assets and package commands exist.
78
+ removeVersionedBuildScripts(projectRoot);
79
+ console.log('codeplay-common: unversioned build scripts copied to app buildCodeplay; app-owned settings preserved.');
80
+ // Coupled IAP/AdMob/Home migrations run together during before-build.
81
+ return pkg;
90
82
  }
91
- packageJson.scripts["baseline-profile:setup"] = baselineProfileSetupScript;
92
- packageJson.scripts["baseline-profile:generate"] = baselineProfileGenerateScript;
93
-
94
- // Keep Android as the default; iOS explicitly selects its save-gallery helper.
95
- packageJson.scripts["build:ios"] = "cross-env CODEPLAY_BUILD_PLATFORM=ios npm run build";
96
- packageJson.scripts["build-capacitor-android"] = "npm run build && npx cap copy android";
97
-
98
- packageJson.scripts["ionic:build"] = "npm run build";
99
- packageJson.scripts["ionic:serve"] = "cross-env NODE_ENV=development vite";
100
- packageJson.scripts["build:storeid1"] = "vite build --mode storeid1";
101
- packageJson.scripts["build:storeid2"] = "vite build --mode storeid2";
102
- packageJson.scripts["build:storeid3"] = "vite build --mode storeid3";
103
- packageJson.scripts["build:storeid4"] = "vite build --mode storeid4";
104
- packageJson.scripts["build:storeid5"] = "vite build --mode storeid5";
105
- //packageJson.scripts["build:storeid6"] = "vite build --mode storeid6";
106
- packageJson.scripts["build:storeid7"] = "vite build --mode storeid7";
107
- packageJson.scripts["build:storeid8"] = "vite build --mode storeid8";
108
- // Save changes
109
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2), "utf8");
110
- process.stdout.write("✅ package.json updated!\n");
83
+ module.exports = { install, findProjectRoot, migrateAppScripts };
84
+ if (require.main === module) {
85
+ try { install(); } catch (error) { console.error(error.message); process.exitCode = 1; }
86
+ }
@@ -1,123 +1,3 @@
1
- // Define file prefixes to delete
2
- const filePrefixes = [
3
- "add-splash-screen",
4
- "setSplashAnimation",
5
- "codeplayBeforeBuild",
6
- "finalrelease"
7
- ];
8
-
9
- const fs = require("fs");
10
- const path = require("path");
11
-
12
- const projectRoot = path.resolve(__dirname, "../../../"); // Project root
13
- const commonBuildPath = path.join(__dirname, "../files"); // Path where files were copied from
14
- const splashXmlPath = path.join(projectRoot, "buildCodeplay"); // Path to splashxml folder
15
- const baselineProfileSetupScript = path.join(projectRoot, "scripts", "setup-baseline-profile.js");
16
- const baselineProfileBackup = path.join(projectRoot, "baselineProfiles", "baseline-prof.txt");
17
-
18
- const isAgentInstructionAsset = (file) => {
19
- const normalizedName = file.toLowerCase();
20
- return normalizedName === "agents" || normalizedName === "agents.md";
21
- };
22
-
23
- process.stdout.write("🚀 Uninstalling: Removing old and copied files...\n");
24
-
25
- const removeDirectory = (dirPath) => {
26
- if (fs.existsSync(dirPath)) {
27
- fs.readdirSync(dirPath).forEach(file => {
28
- const currentPath = path.join(dirPath, file);
29
- if (fs.lstatSync(currentPath).isDirectory()) {
30
- removeDirectory(currentPath);
31
- } else {
32
- fs.unlinkSync(currentPath);
33
- }
34
- });
35
- fs.rmdirSync(dirPath);
36
- process.stdout.write(`🗑️ Removed folder: ${dirPath}\n`);
37
- }
38
- };
39
-
40
- removeDirectory(splashXmlPath);
41
- removeDirectory(path.join(projectRoot, "splashxml")); // Remove old splashxml folder
42
-
43
- // Step 1: Find all matching files in the project directory
44
- const filePatternsToRemove = [
45
- /^add-splash-screen-.*$/,
46
- /^setSplashAnimation-.*$/,
47
- /^codeplayBeforeBuild-.*$/,
48
- /^modify-plugin-xml\.xml$/,
49
- /^finalrelease.*$/,
50
- /^iap-install-\d+(\.\d+)?\.js$/,
51
- /^\.env\.storeid[1-7]$/,
52
- /^modify-plugin-xml\.js$/
53
- ];
54
-
55
- const filesInProject = fs.readdirSync(projectRoot);
56
-
57
- filesInProject.forEach(file => {
58
- if (filePatternsToRemove.some(pattern => pattern.test(file))) {
59
- const filePath = path.join(projectRoot, file);
60
- try {
61
- fs.unlinkSync(filePath);
62
- process.stdout.write(`🗑️ Removed file: ${filePath}\n`);
63
- } catch (error) {
64
- process.stderr.write(`⚠️ Failed to remove ${filePath}: ${error.message}\n`);
65
- }
66
- }
67
- });
68
-
69
- // Remove files and folders listed in commonBuildPath
70
- if (fs.existsSync(commonBuildPath)) {
71
- fs.readdirSync(commonBuildPath).forEach(file => {
72
- const destPath = path.join(projectRoot, file);
73
- // Screenshot data belongs to the app, including folders from older releases.
74
- if (file === "scripts" || file === "scripts-screenshot" || isAgentInstructionAsset(file)) {
75
- return;
76
- }
77
- if (fs.existsSync(destPath)) {
78
- try {
79
- if (fs.lstatSync(destPath).isDirectory()) {
80
- removeDirectory(destPath);
81
- } else {
82
- fs.unlinkSync(destPath);
83
- process.stdout.write(`🗑️ Removed file: ${destPath}\n`);
84
- }
85
- } catch (error) {
86
- process.stderr.write(`⚠️ Failed to remove ${destPath}: ${error.message}\n`);
87
- }
88
- }
89
- });
90
- }
91
-
92
- for (const helperDirectory of [
93
- path.join(projectRoot, "scripts", "screenshot"),
94
- path.join(projectRoot, "scripts-screenshot", "screenshot")
95
- ]) {
96
- for (const helperName of ["frame-samples.js", "background-decorations.js"]) {
97
- const helperPath = path.join(helperDirectory, helperName);
98
- if (fs.existsSync(helperPath)) {
99
- fs.unlinkSync(helperPath);
100
- process.stdout.write(`🗑️ Removed file: ${helperPath}\n`);
101
- }
102
- }
103
- }
104
-
105
- if (fs.existsSync(baselineProfileSetupScript)) {
106
- try {
107
- fs.unlinkSync(baselineProfileSetupScript);
108
- process.stdout.write(`🗑️ Removed file: ${baselineProfileSetupScript}\n`);
109
- } catch (error) {
110
- process.stderr.write(`⚠️ Failed to remove ${baselineProfileSetupScript}: ${error.message}\n`);
111
- }
112
- }
113
-
114
- if (fs.existsSync(baselineProfileBackup)) {
115
- try {
116
- fs.unlinkSync(baselineProfileBackup);
117
- process.stdout.write(`🗑️ Removed file: ${baselineProfileBackup}\n`);
118
- } catch (error) {
119
- process.stderr.write(`⚠️ Failed to remove ${baselineProfileBackup}: ${error.message}\n`);
120
- }
121
- }
122
-
123
- process.stdout.write("✅ Uninstall cleanup complete!\n");
1
+ // Preserve working app files during preinstall. Postinstall migrates commands
2
+ // first, then removes only recognized copied build scripts.
3
+ console.log('codeplay-common: preserving app files until installation completes.');
package/.gitattributes DELETED
@@ -1,2 +0,0 @@
1
- # Auto detect text files and perform LF normalization
2
- * text=auto
@@ -1,145 +0,0 @@
1
- const fs = require('fs');
2
- const path = require('path');
3
-
4
-
5
-
6
- const androidManifestPath = path.join("android", "app", "src", "main", "AndroidManifest.xml");
7
-
8
- // Find the vite config file
9
- const possibleConfigFiles = ['vite.config.mjs', 'vite.config.js'];
10
- let viteConfigPath;
11
-
12
- for (const configFile of possibleConfigFiles) {
13
- const fullPath = path.resolve(configFile);
14
- if (fs.existsSync(fullPath)) {
15
- viteConfigPath = fullPath;
16
- break;
17
- }
18
- }
19
-
20
- if (!viteConfigPath) {
21
- console.error('Error: No vite.config.mjs or vite.config.js file found.');
22
- process.exit(1);
23
- }
24
-
25
- try {
26
- // Read vite config file
27
- const viteConfigContent = fs.readFileSync(viteConfigPath, 'utf-8');
28
-
29
- // Extract @common alias path
30
- const aliasPattern = /'@common':\s*path\.resolve\(__dirname,\s*'(.+?)'\)/;
31
- const match = viteConfigContent.match(aliasPattern);
32
-
33
- if (!match) {
34
- console.error(`Error: @common alias not found in ${viteConfigPath}`);
35
- process.exit(1);
36
- }
37
-
38
- const commonFilePath = match[1];
39
- const resolvedCommonPath = path.resolve(__dirname, commonFilePath);
40
-
41
- // Read the common file content
42
- if (!fs.existsSync(resolvedCommonPath)) {
43
- console.error(`Error: Resolved common file does not exist: ${resolvedCommonPath}`);
44
- process.exit(1);
45
- }
46
-
47
- const commonFileContent = fs.readFileSync(resolvedCommonPath, 'utf-8');
48
-
49
- // Extract _storeid value
50
- const storeIdPattern = /export\s+let\s+_storeid\s*=\s*import\.meta\.env\.VITE_STORE_ID\s*\|\|\s*(\d+)\s*;/;
51
-
52
- const storeMatch = commonFileContent.match(storeIdPattern);
53
-
54
-
55
- if (!storeMatch) {
56
- console.error(`Error: _storeid not found in ${resolvedCommonPath}`);
57
- process.exit(1);
58
- }
59
-
60
- const _storeid = parseInt(storeMatch[1], 10);
61
-
62
- // Determine the store name based on _storeid
63
- let storeName = "";
64
- if (_storeid === 1) {
65
- storeName = "PlayStore";
66
- } else if (_storeid === 2) {
67
- storeName = "SamsungStore";
68
- } else if (_storeid === 7) {
69
- storeName = "AmazonStore";
70
- } else {
71
- console.error(`Error: Unsupported _storeid value: ${_storeid}`);
72
- process.exit(1);
73
- }
74
-
75
-
76
- // Call managePackages with the determined store name
77
- managePackages(storeName);
78
-
79
- console.log(commonFilePath, `Success - _storeid found: ${_storeid}, Store: ${storeName}`);
80
- } catch (error) {
81
- console.error('Error:', error);
82
- process.exit(1);
83
- }
84
-
85
- function managePackages(store) {
86
- console.log(`Managing packages for store: ${store}`);
87
-
88
- let install = "";
89
- let uninstall = "";
90
-
91
- //let androidManifestPath = "path/to/AndroidManifest.xml"; // Update this path
92
-
93
-
94
- let manifestContent = fs.readFileSync(androidManifestPath, 'utf-8');
95
-
96
- const permissionsToRemove = [
97
- 'com.android.vending.BILLING',
98
- 'com.samsung.android.iap.permission.BILLING'
99
- ];
100
-
101
- permissionsToRemove.forEach(permission => {
102
- const permissionRegex = new RegExp(`^\\s*<uses-permission\\s+android:name="${permission}"\\s*/?>\\s*[\r\n]?`, 'm');
103
- if (permissionRegex.test(manifestContent)) {
104
- manifestContent = manifestContent.replace(permissionRegex, '');
105
- console.log(`Removed <uses-permission android:name="${permission}" /> from AndroidManifest.xml`);
106
- }
107
- });
108
-
109
- // Write the updated content back to the file
110
- fs.writeFileSync(androidManifestPath, manifestContent, 'utf-8');
111
-
112
- if (store === "PlayStore") {
113
- install = '@revenuecat/purchases-capacitor';
114
- uninstall = 'cordova-plugin-samsungiap';
115
- } else if (store === "AmazonStore") {
116
- install = '@revenuecat/purchases-capacitor';
117
- uninstall = 'cordova-plugin-samsungiap';
118
- } else if (store === "SamsungStore") {
119
- install = 'cordova-plugin-samsungiap';
120
- uninstall = '@revenuecat/purchases-capacitor';
121
- } else {
122
- console.log("No valid store specified. Uninstalling both plugins.");
123
- try {
124
- require('child_process').execSync(`npm uninstall cordova-plugin-samsungiap`, { stdio: 'inherit' });
125
- require('child_process').execSync(`npm uninstall @revenuecat/purchases-capacitor`, { stdio: 'inherit' });
126
- console.log("Both plugins uninstalled successfully.");
127
- } catch (err) {
128
- console.error("Error uninstalling plugins:", err);
129
- }
130
- return;
131
- }
132
-
133
- console.log(`Installing ${install} and uninstalling ${uninstall} for ${store}...`);
134
- try {
135
- if (install) {
136
- require('child_process').execSync(`npm install ${install}`, { stdio: 'inherit' });
137
- }
138
- if (uninstall) {
139
- require('child_process').execSync(`npm uninstall ${uninstall}`, { stdio: 'inherit' });
140
- }
141
- console.log(`${install} installed and ${uninstall} uninstalled successfully.`);
142
- } catch (err) {
143
- console.error(`Error managing packages for ${store}:`, err);
144
- }
145
- }