codeplay-common 4.6.6 → 4.6.7

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.
@@ -86,7 +86,8 @@ const analysisFrameDirectory = path.join(temporaryDirectory, 'ai-analysis');
86
86
  const endCardBannerPath = path.join(outputVideoDirectory, `${appFilePrefix}-ai-end-card-banner.png`);
87
87
  const promoCopySchemaPath = path.join(temporaryDirectory, 'promo-copy-schema.json');
88
88
  const promoCopyResultPath = path.join(temporaryDirectory, 'promo-copy-result.json');
89
- const ffmpegFallbackDirectory = String(process.env.FFMPEG_BIN || '').trim();
89
+ const ffmpegFallbackDirectory = String(process.env.FFMPEG_BIN || '').trim()
90
+ || path.join(projectDirectory, 'tools', 'ffmpeg');
90
91
  const minimumSceneCount = 7;
91
92
  const minimumSourceDuration = 12;
92
93
  let expectedDuration = 34;
@@ -466,14 +467,12 @@ function commandExists(command) {
466
467
  return !result.error && result.status === 0;
467
468
  }
468
469
 
469
- function getExecutable(command) {
470
- if (commandExists(command)) return command;
471
-
472
- if (!ffmpegFallbackDirectory) return '';
473
- const executableName = process.platform === 'win32' ? `${command}.exe` : command;
474
- const fallbackPath = path.join(ffmpegFallbackDirectory, executableName);
475
- return fs.existsSync(fallbackPath) ? fallbackPath : '';
476
- }
470
+ function getExecutable(command) {
471
+ const executableName = process.platform === 'win32' ? `${command}.exe` : command;
472
+ const fallbackPath = path.join(ffmpegFallbackDirectory, executableName);
473
+ if (fs.existsSync(fallbackPath)) return fallbackPath;
474
+ return commandExists(command) ? command : '';
475
+ }
477
476
 
478
477
  function detectRedundantStaticRanges(ffmpegCommand, inputPath, sourceDuration) {
479
478
  const minimumStaticDuration = Math.max(2, Math.min(4, sourceDuration / 60));
@@ -641,7 +640,7 @@ function resolvePromoLayout(requestedLayout) {
641
640
  }
642
641
 
643
642
  function getPythonExecutable() {
644
- for (const candidate of ['py', 'python']) {
643
+ for (const candidate of ['py', 'python', 'python3']) {
645
644
  const result = spawnSync(candidate, ['-m', 'edge_tts', '--version'], {
646
645
  encoding: 'utf8',
647
646
  windowsHide: true,
@@ -788,7 +787,7 @@ function getCodexCandidates() {
788
787
  const configuredCodexPath = String(process.env.CODEX_BIN || '').trim();
789
788
  if (configuredCodexPath) candidates.unshift(configuredCodexPath);
790
789
 
791
- if (process.platform === 'win32') {
790
+ if (process.platform === 'win32' || process.platform === 'darwin' || process.platform === 'linux') {
792
791
  const userProfile = process.env.USERPROFILE || process.env.HOME;
793
792
  const extensionRoots = [
794
793
  path.join(userProfile || '', '.vscode', 'extensions'),
@@ -796,7 +795,7 @@ function getCodexCandidates() {
796
795
  path.join(userProfile || '', '.vscode-server', 'extensions'),
797
796
  path.join(userProfile || '', '.vscode-server-insiders', 'extensions'),
798
797
  ];
799
- const executableNames = ['codex.exe', 'codex'];
798
+ const executableNames = process.platform === 'win32' ? ['codex.exe', 'codex'] : ['codex'];
800
799
 
801
800
  for (const extensionRoot of extensionRoots) {
802
801
  if (!fs.existsSync(extensionRoot)) continue;
@@ -916,7 +915,7 @@ Rules:
916
915
  - footer_keywords must contain exactly 3 distinct, natural app-search phrases, each 2-24 characters.
917
916
  - Generate a YouTube upload title and description from the same verified features.
918
917
  - YouTube title: 40-100 characters, include ${JSON.stringify(appName)} and one strong natural search phrase, without clickbait.
919
- - YouTube description: 350-1500 characters with readable paragraphs. Put the clearest app summary and primary search phrase in the opening two lines, explain the demonstrated features, add a simple call to action, and finish with exactly 3 relevant hashtags on one line.
918
+ - YouTube description: 350-1500 characters with readable paragraphs. Put the clearest app summary and primary search phrase in the opening two lines, explain the demonstrated features, add a simple call to action, then insert a newline and finish with exactly 3 relevant hashtags on that separate final line. The hashtags must not be appended to the preceding paragraph.
920
919
  - Do not add download links or URLs; the script will append the verified Google Play URL built from the configured package ID. Do not add chapter timestamps or unsupported availability claims.
921
920
  - Keep YouTube text natural and useful; do not repeat keywords unnaturally.
922
921
  - Avoid prices, ratings, awards, competitor names, unsupported superlatives, and words such as best, guaranteed, or free.
@@ -1026,8 +1025,14 @@ function validatePromoCopy(value) {
1026
1025
  throw new Error(`The final scene must mention the app name ${JSON.stringify(appName)}.`);
1027
1026
  }
1028
1027
 
1029
- const youtubeTitle = cleanGeneratedString(value.youtube.title);
1030
- const youtubeDescription = cleanGeneratedDescription(value.youtube.description);
1028
+ const youtubeTitle = cleanGeneratedString(value.youtube.title);
1029
+ let youtubeDescription = cleanGeneratedDescription(value.youtube.description);
1030
+ const trailingHashtagGroup = youtubeDescription.match(
1031
+ /(?:^|\s)(#[\p{L}\p{N}_]+\s+#[\p{L}\p{N}_]+\s+#[\p{L}\p{N}_]+)\s*$/u,
1032
+ );
1033
+ if (trailingHashtagGroup) {
1034
+ youtubeDescription = `${youtubeDescription.slice(0, trailingHashtagGroup.index).trimEnd()}\n${trailingHashtagGroup[1]}`;
1035
+ }
1031
1036
  if (youtubeTitle.length < 40 || youtubeTitle.length > 100) {
1032
1037
  throw new Error('YouTube title must be 40-100 characters.');
1033
1038
  }
@@ -1,145 +1,145 @@
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
- }
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
+ }
@@ -1,7 +1,7 @@
1
- {
2
- "name": "merbin-test-app",
3
- "integrations": {
4
- "capacitor": {}
5
- },
6
- "type": "custom"
1
+ {
2
+ "name": "merbin-test-app",
3
+ "integrations": {
4
+ "capacitor": {}
5
+ },
6
+ "type": "custom"
7
7
  }