browser-extension-manager 1.2.4 → 1.2.6

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.
@@ -189,6 +189,14 @@ async function compileManifest(outputDir) {
189
189
  // Add package version to manifest
190
190
  manifest.version = project.version;
191
191
 
192
+ // Add Firefox compatibility for background scripts
193
+ // Firefox MV3 uses "scripts" array instead of "service_worker"
194
+ // Chrome ignores "scripts", Firefox ignores "service_worker"
195
+ if (manifest.background?.service_worker && !manifest.background?.scripts) {
196
+ manifest.background.scripts = [manifest.background.service_worker];
197
+ logger.log(`Added Firefox-compatible background.scripts`);
198
+ }
199
+
192
200
  // Save as regular JSON
193
201
  jetpack.write(outputPath, JSON.stringify(manifest, null, 2));
194
202
 
@@ -286,7 +294,12 @@ async function packageZip() {
286
294
 
287
295
  // Create packed extension (.zip)
288
296
  if (Manager.isBuildMode()) {
289
- await execute(`zip -r ${zipPath} ${inputDir}`);
297
+ // Remove existing zip if it exists
298
+ jetpack.remove(zipPath);
299
+
300
+ // Zip contents of raw directory (not the directory itself)
301
+ // This ensures manifest.json is at the root of the zip
302
+ await execute(`cd ${inputDir} && zip -r ../../${zipPath} .`);
290
303
  logger.log(`Zipped package created at ${zipPath}`);
291
304
  } else {
292
305
  logger.log(`Skipping zip (not in build mode)`);
@@ -12,19 +12,36 @@ const project = Manager.getPackage('project');
12
12
  // Paths
13
13
  const zipPath = path.join(process.cwd(), 'packaged', 'extension.zip');
14
14
 
15
+ // Helper to check if a credential is valid (not empty or placeholder)
16
+ function isValidCredential(value) {
17
+ return value && !value.startsWith('your-');
18
+ }
19
+
15
20
  // Store configurations - all credentials come from .env file
16
21
  const STORES = {
17
22
  chrome: {
18
23
  name: 'Chrome Web Store',
19
- enabled: () => !!(process.env.CHROME_EXTENSION_ID && process.env.CHROME_CLIENT_ID),
24
+ submitUrl: 'https://chrome.google.com/webstore/devconsole',
25
+ apiUrl: 'https://developer.chrome.com/docs/webstore/using_webstore_api/',
26
+ enabled: () => isValidCredential(process.env.CHROME_EXTENSION_ID) && isValidCredential(process.env.CHROME_CLIENT_ID),
20
27
  },
21
28
  firefox: {
22
29
  name: 'Firefox Add-ons',
23
- enabled: () => !!(process.env.FIREFOX_API_KEY && process.env.FIREFOX_API_SECRET),
30
+ submitUrl: 'https://addons.mozilla.org/en-US/developers/addon/submit/distribution',
31
+ apiUrl: 'https://addons.mozilla.org/developers/addon/api/key/',
32
+ enabled: () => isValidCredential(process.env.FIREFOX_API_KEY) && isValidCredential(process.env.FIREFOX_API_SECRET),
24
33
  },
25
34
  edge: {
26
35
  name: 'Microsoft Edge Add-ons',
27
- enabled: () => !!(process.env.EDGE_PRODUCT_ID && process.env.EDGE_CLIENT_ID),
36
+ submitUrl: 'https://partner.microsoft.com/dashboard/microsoftedge/',
37
+ apiUrl: 'https://learn.microsoft.com/en-us/microsoft-edge/extensions-chromium/publish/api/using-addons-api',
38
+ enabled: () => isValidCredential(process.env.EDGE_PRODUCT_ID) && isValidCredential(process.env.EDGE_CLIENT_ID),
39
+ },
40
+ opera: {
41
+ name: 'Opera Add-ons',
42
+ submitUrl: 'https://addons.opera.com/developer/',
43
+ apiUrl: null,
44
+ enabled: () => false,
28
45
  },
29
46
  };
30
47
 
@@ -50,21 +67,30 @@ async function publish(complete) {
50
67
 
51
68
  // Get enabled stores
52
69
  const enabledStores = Object.entries(STORES)
53
- .filter(([key, store]) => store.enabled())
70
+ .filter(([, store]) => store.enabled())
54
71
  .map(([key]) => key);
55
72
 
73
+ // If no stores are configured, error and show all store info
56
74
  if (enabledStores.length === 0) {
57
- logger.warn('No stores configured for publishing. Add credentials to .env file');
58
- logger.log('Required environment variables:');
59
- logger.log(' Chrome: CHROME_EXTENSION_ID, CHROME_CLIENT_ID, CHROME_CLIENT_SECRET, CHROME_REFRESH_TOKEN');
60
- logger.log(' Firefox: FIREFOX_EXTENSION_ID, FIREFOX_API_KEY, FIREFOX_API_SECRET');
61
- logger.log(' Edge: EDGE_PRODUCT_ID, EDGE_CLIENT_ID, EDGE_API_KEY');
62
- logger.log(' Opera: No API available - submit manually at https://addons.opera.com/developer/');
63
- return complete();
75
+ logger.error('No stores configured for publishing. Add credentials to .env file');
76
+ logger.log('');
77
+ logger.log('Store URLs and API documentation:');
78
+ Object.entries(STORES).forEach(([, store]) => {
79
+ logger.log(` ${store.name}:`);
80
+ logger.log(` Submit: ${store.submitUrl}`);
81
+ logger.log(` API: ${store.apiUrl || 'N/A (manual submission only)'}`);
82
+ });
83
+ throw new Error('No stores configured for publishing');
64
84
  }
65
85
 
66
86
  logger.log(`Publishing to: ${enabledStores.join(', ')}`);
67
87
 
88
+ // Track results
89
+ const results = {
90
+ success: [],
91
+ failed: [],
92
+ };
93
+
68
94
  // Run publish tasks in parallel
69
95
  const publishTasks = enabledStores.map(async (store) => {
70
96
  try {
@@ -80,14 +106,37 @@ async function publish(complete) {
80
106
  break;
81
107
  }
82
108
  logger.log(`[${store}] Published successfully`);
109
+ results.success.push(store);
83
110
  } catch (e) {
84
111
  logger.error(`[${store}] Publish failed: ${e.message}`);
112
+ results.failed.push(store);
85
113
  }
86
114
  });
87
115
 
88
116
  await Promise.all(publishTasks);
89
117
 
118
+ // Log completion and show all store URLs
119
+ logger.log('');
120
+ logger.log('Store URLs:');
121
+ Object.entries(STORES).forEach(([key, store]) => {
122
+ let status = '○ Manual';
123
+ if (results.success.includes(key)) {
124
+ status = '✓ Published';
125
+ } else if (results.failed.includes(key)) {
126
+ status = '✗ Failed';
127
+ }
128
+ logger.log(` ${store.name}: ${status}`);
129
+ logger.log(` Submit: ${store.submitUrl}`);
130
+ logger.log(` API: ${store.apiUrl || 'N/A (manual submission only)'}`);
131
+ });
132
+
133
+ // Throw error if any failed
134
+ if (results.failed.length > 0) {
135
+ throw new Error(`Publish failed for: ${results.failed.join(', ')}`);
136
+ }
137
+
90
138
  // Log
139
+ logger.log('');
91
140
  logger.log('Publish finished!');
92
141
 
93
142
  // Complete
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "browser-extension-manager",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "Browser Extension Manager dependency manager",
5
5
  "main": "dist/index.js",
6
6
  "exports": {
@@ -38,7 +38,9 @@
38
38
  "projectScripts": {
39
39
  "start": "npx bxm clean && npx bxm setup && npm run gulp --",
40
40
  "gulp": "gulp --cwd ./ --gulpfile ./node_modules/browser-extension-manager/dist/gulp/main.js",
41
- "build": "npx bxm clean && npx bxm setup && BXM_BUILD_MODE=true npm run gulp -- build"
41
+ "build": "npx bxm clean && npx bxm setup && BXM_BUILD_MODE=true npm run gulp -- build",
42
+ "publish": "BXM_IS_PUBLISH=true npm run gulp -- publish",
43
+ "release": "npm run build && npm run publish"
42
44
  },
43
45
  "engines": {
44
46
  "node": "22"