| Name | Message | Date |
|---|---|---|
| 📄 build-assets.mjs | 10 hours ago | |
| 📄 package.mjs | 10 hours ago | |
| 📄 publish-edge.mjs | 10 hours ago |
📄
scripts/publish-edge.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Publishes the packaged extension to Microsoft Edge Add-ons via the official
// Publish API (v1.1): upload the zip as a new draft package, wait for it to
// finish, then submit the draft for review.
//
// Docs: https://learn.microsoft.com/en-us/microsoft-edge/extensions/update/api/using-addons-api
//
// Required environment variables (Partner Center → Microsoft Edge → Publish API):
// EDGE_PRODUCT_ID product ID of the extension (Partner Center → Extension overview)
// EDGE_CLIENT_ID client ID from the Publish API page
// EDGE_API_KEY API key from the Publish API page
// Optional:
// EDGE_NOTES notes for certification
import { readFile } from 'node:fs/promises';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
const API_ROOT = 'https://api.addons.microsoftedge.microsoft.com';
const POLL_INTERVAL_MS = 3_000;
const POLL_TIMEOUT_MS = 5 * 60_000;
const root = dirname(dirname(fileURLToPath(import.meta.url)));
const { EDGE_PRODUCT_ID: productId, EDGE_CLIENT_ID: clientId, EDGE_API_KEY: apiKey } = process.env;
const notes = process.env.EDGE_NOTES ?? '';
if (!productId || !clientId || !apiKey) {
console.error(
'Missing credentials. Set EDGE_PRODUCT_ID, EDGE_CLIENT_ID and EDGE_API_KEY\n' +
'(Partner Center → Microsoft Edge → Publish API), then try again.',
);
process.exit(1);
}
const authHeaders = { Authorization: `ApiKey ${apiKey}`, 'X-ClientID': clientId };
const manifest = JSON.parse(await readFile(join(root, 'public', 'manifest.json'), 'utf8'));
const zipPath = join(root, `vf-pdf-opener-${manifest.version}.zip`);
let zip;
try {
zip = await readFile(zipPath);
} catch {
console.error(`Package not found: ${zipPath}\nRun "npm run package" first.`);
process.exit(1);
}
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
function operationIdFrom(location) {
if (!location) throw new Error('No operation ID (Location header) in response.');
return location.split('/').filter(Boolean).pop();
}
async function post(path, body, contentType) {
const response = await fetch(`${API_ROOT}${path}`, {
method: 'POST',
headers: { ...authHeaders, 'Content-Type': contentType },
body,
});
if (response.status !== 202) {
throw new Error(`POST ${path} → HTTP ${response.status}: ${await response.text()}`);
}
return operationIdFrom(response.headers.get('location'));
}
async function poll(path, label) {
const deadline = Date.now() + POLL_TIMEOUT_MS;
for (;;) {
if (Date.now() > deadline) throw new Error(`Timed out waiting for ${label}.`);
const response = await fetch(`${API_ROOT}${path}`, { headers: authHeaders });
if (!response.ok) {
throw new Error(`GET ${path} → HTTP ${response.status}: ${await response.text()}`);
}
const operation = await response.json();
console.log(` ${label}: ${operation.status ?? 'unknown'}`);
const status = String(operation.status ?? '').toLowerCase();
if (status === 'succeeded') return operation;
if (status === 'failed') throw new Error(`${label} failed: ${JSON.stringify(operation)}`);
await sleep(POLL_INTERVAL_MS);
}
}
console.log(`Publishing vf-pdf-opener v${manifest.version} to Microsoft Edge Add-ons…`);
console.log('Uploading package…');
const uploadOperation = await post(
`/v1/products/${productId}/submissions/draft/package`,
zip,
'application/zip',
);
await poll(
`/v1/products/${productId}/submissions/draft/package/operations/${uploadOperation}`,
'upload',
);
console.log('Submitting for review…');
const publishOperation = await post(
`/v1/products/${productId}/submissions`,
JSON.stringify({ notes }),
'application/json',
);
await poll(`/v1/products/${productId}/submissions/operations/${publishOperation}`, 'publish');
console.log('Done — the new version is in review.');