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.
- package/dist/gulp/tasks/package.js +14 -1
- package/dist/gulp/tasks/publish.js +60 -11
- package/package.json +4 -2
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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(([
|
|
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.
|
|
58
|
-
logger.log('
|
|
59
|
-
logger.log('
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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.
|
|
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"
|