@extension.dev/deploy 1.0.0 → 1.1.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.
- package/CHANGELOG.md +21 -0
- package/README.md +9 -1
- package/dist/module.js +96 -23
- package/dist/module.mjs +95 -22
- package/dist/src/chrome.d.ts +13 -10
- package/dist/src/chrome.d.ts.map +1 -1
- package/dist/src/cli-commands.d.ts.map +1 -1
- package/dist/src/cli-usage.d.ts.map +1 -1
- package/dist/src/config.d.ts +3 -0
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/types.d.ts +63 -11
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/watch.d.ts +4 -3
- package/dist/src/watch.d.ts.map +1 -1
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.1.0
|
|
4
|
+
|
|
5
|
+
- Chrome: service account authentication (`CHROME_SERVICE_ACCOUNT_JSON` /
|
|
6
|
+
`--chrome-service-account-json`, JSON key content or file path) as an
|
|
7
|
+
alternative to the OAuth client/secret/refresh-token trio. The service
|
|
8
|
+
account wins when both are set. Avoids the 7-day refresh-token expiry of
|
|
9
|
+
OAuth clients whose consent screen is in "Testing" status. Add the
|
|
10
|
+
account's email to your publisher in the dev console (Account section).
|
|
11
|
+
|
|
12
|
+
## 1.0.0
|
|
13
|
+
|
|
14
|
+
- BREAKING: Chrome Web Store API v2 only (`chromewebstore.googleapis.com`).
|
|
15
|
+
`CHROME_PUBLISHER_ID` is required; the v1.1 path, `publishTarget`, and the
|
|
16
|
+
trusted-testers target were removed (staged rollout via
|
|
17
|
+
`CHROME_DEPLOY_PERCENTAGE` replaces them).
|
|
18
|
+
|
|
19
|
+
## 0.3.0
|
|
20
|
+
|
|
21
|
+
- Chrome Web Store API v2 support, opt-in via `CHROME_PUBLISHER_ID`
|
|
22
|
+
(v1.1 fallback retained).
|
|
23
|
+
|
|
3
24
|
## 0.2.5
|
|
4
25
|
|
|
5
26
|
Current release. Earlier history is tracked in the source monorepo; entries
|
package/README.md
CHANGED
|
@@ -79,6 +79,7 @@ Run `extension-deploy --help` for the full list of flags.
|
|
|
79
79
|
| `--chrome-zip <path>` | `CHROME_ZIP` | Path to the extension ZIP file |
|
|
80
80
|
| `--chrome-extension-id <id>` | `CHROME_EXTENSION_ID` | Chrome Web Store extension ID |
|
|
81
81
|
| `--chrome-publisher-id <uuid>` | `CHROME_PUBLISHER_ID` | Publisher UUID from the dev console (required) |
|
|
82
|
+
| `--chrome-service-account-json <v>` | `CHROME_SERVICE_ACCOUNT_JSON` | Service account JSON key (content or file path); alternative to the OAuth trio below |
|
|
82
83
|
| `--chrome-client-id <id>` | `CHROME_CLIENT_ID` | OAuth2 client ID |
|
|
83
84
|
| `--chrome-client-secret <secret>` | `CHROME_CLIENT_SECRET` | OAuth2 client secret |
|
|
84
85
|
| `--chrome-refresh-token <token>` | `CHROME_REFRESH_TOKEN` | OAuth2 refresh token |
|
|
@@ -86,6 +87,13 @@ Run `extension-deploy --help` for the full list of flags.
|
|
|
86
87
|
| `--chrome-review-exemption` | `CHROME_REVIEW_EXEMPTION` | Request expedited review |
|
|
87
88
|
| `--chrome-skip-submit-review` | `CHROME_SKIP_SUBMIT_REVIEW` | Upload only, skip publish step |
|
|
88
89
|
|
|
90
|
+
Chrome accepts two credential shapes: a Google Cloud **service account** JSON key
|
|
91
|
+
(recommended for CI; add the account's email to your publisher under
|
|
92
|
+
dev console > Account, one per publisher) or the classic OAuth2
|
|
93
|
+
client ID / client secret / refresh token trio. When both are set, the service
|
|
94
|
+
account is used. Service accounts avoid the 7-day refresh-token expiry that
|
|
95
|
+
affects OAuth clients whose consent screen is in "Testing" status.
|
|
96
|
+
|
|
89
97
|
### Firefox AMO
|
|
90
98
|
|
|
91
99
|
| Flag | Env var | Description |
|
|
@@ -156,7 +164,7 @@ const result = await deploy({
|
|
|
156
164
|
clientId: "123.apps.googleusercontent.com",
|
|
157
165
|
clientSecret: "GOCSPX-xxx",
|
|
158
166
|
refreshToken: "1//0xxx",
|
|
159
|
-
|
|
167
|
+
publisherId: "00000000-0000-0000-0000-000000000000", // required
|
|
160
168
|
deployPercentage: 10, // optional: staged rollout
|
|
161
169
|
},
|
|
162
170
|
firefox: {
|
package/dist/module.js
CHANGED
|
@@ -59,13 +59,28 @@ const external_zod_namespaceObject = require("zod");
|
|
|
59
59
|
const chromeOptionsSchema = external_zod_namespaceObject.z.object({
|
|
60
60
|
zip: external_zod_namespaceObject.z.string().min(1),
|
|
61
61
|
extensionId: external_zod_namespaceObject.z.string().min(1).trim(),
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
serviceAccountJson: external_zod_namespaceObject.z.string().trim().default(""),
|
|
63
|
+
clientId: external_zod_namespaceObject.z.string().trim().default(""),
|
|
64
|
+
clientSecret: external_zod_namespaceObject.z.string().trim().default(""),
|
|
65
|
+
refreshToken: external_zod_namespaceObject.z.string().trim().default(""),
|
|
65
66
|
publisherId: external_zod_namespaceObject.z.string().min(1).trim(),
|
|
66
67
|
deployPercentage: external_zod_namespaceObject.z.number().int().min(1).max(100).optional(),
|
|
67
68
|
reviewExemption: external_zod_namespaceObject.z.boolean().default(false),
|
|
68
69
|
skipSubmitReview: external_zod_namespaceObject.z.boolean().default(false)
|
|
70
|
+
}).superRefine((val, ctx)=>{
|
|
71
|
+
if (val.serviceAccountJson) return;
|
|
72
|
+
const missing = [
|
|
73
|
+
"clientId",
|
|
74
|
+
"clientSecret",
|
|
75
|
+
"refreshToken"
|
|
76
|
+
].filter((k)=>!val[k]);
|
|
77
|
+
for (const key of missing)ctx.addIssue({
|
|
78
|
+
code: external_zod_namespaceObject.z.ZodIssueCode.custom,
|
|
79
|
+
path: [
|
|
80
|
+
key
|
|
81
|
+
],
|
|
82
|
+
message: "Required unless a service account key is provided (CHROME_SERVICE_ACCOUNT_JSON)."
|
|
83
|
+
});
|
|
69
84
|
});
|
|
70
85
|
const firefoxOptionsSchema = external_zod_namespaceObject.z.object({
|
|
71
86
|
zip: external_zod_namespaceObject.z.string().min(1),
|
|
@@ -109,6 +124,7 @@ function resolveConfig(flags) {
|
|
|
109
124
|
chrome: null == chromeZip ? void 0 : {
|
|
110
125
|
zip: chromeZip,
|
|
111
126
|
extensionId: flags.chromeExtensionId ?? envStr("CHROME_EXTENSION_ID") ?? "",
|
|
127
|
+
serviceAccountJson: flags.chromeServiceAccountJson ?? envStr("CHROME_SERVICE_ACCOUNT_JSON") ?? "",
|
|
112
128
|
clientId: flags.chromeClientId ?? envStr("CHROME_CLIENT_ID") ?? "",
|
|
113
129
|
clientSecret: flags.chromeClientSecret ?? envStr("CHROME_CLIENT_SECRET") ?? "",
|
|
114
130
|
refreshToken: flags.chromeRefreshToken ?? envStr("CHROME_REFRESH_TOKEN") ?? "",
|
|
@@ -139,6 +155,7 @@ function pathToEnvName(segments) {
|
|
|
139
155
|
}
|
|
140
156
|
const SETUP_HINTS = {
|
|
141
157
|
CHROME_EXTENSION_ID: "Find this in the Chrome Web Store Developer Dashboard URL for your extension.",
|
|
158
|
+
CHROME_SERVICE_ACCOUNT_JSON: "Optional alternative to OAuth: a Google Cloud service account JSON key (content or file path), added to your publisher under dev console > Account.",
|
|
142
159
|
CHROME_CLIENT_ID: "Create OAuth 2.0 credentials at https://console.cloud.google.com/apis/credentials",
|
|
143
160
|
CHROME_CLIENT_SECRET: "Generated alongside the Client ID in the Google Cloud Console.",
|
|
144
161
|
CHROME_REFRESH_TOKEN: "Obtain by completing the OAuth consent flow. See the Chrome Web Store API docs.",
|
|
@@ -183,6 +200,8 @@ function envInt(name) {
|
|
|
183
200
|
const val = process.env[name];
|
|
184
201
|
return null == val ? void 0 : parseInt(val, 10);
|
|
185
202
|
}
|
|
203
|
+
const external_node_crypto_namespaceObject = require("node:crypto");
|
|
204
|
+
var external_node_crypto_default = /*#__PURE__*/ __webpack_require__.n(external_node_crypto_namespaceObject);
|
|
186
205
|
const promises_namespaceObject = require("node:fs/promises");
|
|
187
206
|
var promises_default = /*#__PURE__*/ __webpack_require__.n(promises_namespaceObject);
|
|
188
207
|
const DEFAULT_TIMEOUT_MS = 60000;
|
|
@@ -271,7 +290,51 @@ function requirePublisherId(publisherId, op) {
|
|
|
271
290
|
function chromeStoreUrl(extensionId) {
|
|
272
291
|
return `https://chromewebstore.google.com/detail/${extensionId}`;
|
|
273
292
|
}
|
|
274
|
-
|
|
293
|
+
const CWS_SCOPE = "https://www.googleapis.com/auth/chromewebstore";
|
|
294
|
+
async function resolveServiceAccountKey(value) {
|
|
295
|
+
const trimmed = value.trim();
|
|
296
|
+
const raw = trimmed.startsWith("{") ? trimmed : await promises_default().readFile(trimmed, "utf-8").catch(()=>{
|
|
297
|
+
throw new Error(`Chrome service account key: "${trimmed.slice(0, 80)}" is neither JSON nor a readable file path.`);
|
|
298
|
+
});
|
|
299
|
+
let parsed;
|
|
300
|
+
try {
|
|
301
|
+
parsed = JSON.parse(raw);
|
|
302
|
+
} catch {
|
|
303
|
+
throw new Error("Chrome service account key is not valid JSON.");
|
|
304
|
+
}
|
|
305
|
+
if (!parsed.client_email || !parsed.private_key) throw new Error("Chrome service account key is missing client_email or private_key. Download the JSON key from the Google Cloud Console.");
|
|
306
|
+
return {
|
|
307
|
+
client_email: parsed.client_email,
|
|
308
|
+
private_key: parsed.private_key
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
async function authenticateServiceAccount(serviceAccountJson) {
|
|
312
|
+
const key = await resolveServiceAccountKey(serviceAccountJson);
|
|
313
|
+
const iat = Math.floor(Date.now() / 1000);
|
|
314
|
+
const encode = (obj)=>Buffer.from(JSON.stringify(obj)).toString("base64url");
|
|
315
|
+
const unsigned = `${encode({
|
|
316
|
+
alg: "RS256",
|
|
317
|
+
typ: "JWT"
|
|
318
|
+
})}.${encode({
|
|
319
|
+
iss: key.client_email,
|
|
320
|
+
scope: CWS_SCOPE,
|
|
321
|
+
aud: CWS_OAUTH_URL,
|
|
322
|
+
iat,
|
|
323
|
+
exp: iat + 3600
|
|
324
|
+
})}`;
|
|
325
|
+
const signature = external_node_crypto_default().createSign("RSA-SHA256").update(unsigned).sign(key.private_key).toString("base64url");
|
|
326
|
+
return fetchJson(CWS_OAUTH_URL, {
|
|
327
|
+
method: "POST",
|
|
328
|
+
body: new URLSearchParams({
|
|
329
|
+
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
330
|
+
assertion: `${unsigned}.${signature}`
|
|
331
|
+
}).toString(),
|
|
332
|
+
headers: {
|
|
333
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
async function authenticateOauth(clientId, clientSecret, refreshToken) {
|
|
275
338
|
return fetchJson(CWS_OAUTH_URL, {
|
|
276
339
|
method: "POST",
|
|
277
340
|
body: JSON.stringify({
|
|
@@ -286,6 +349,11 @@ async function authenticate(clientId, clientSecret, refreshToken) {
|
|
|
286
349
|
}
|
|
287
350
|
});
|
|
288
351
|
}
|
|
352
|
+
async function authenticate(creds) {
|
|
353
|
+
if (creds.serviceAccountJson) return authenticateServiceAccount(creds.serviceAccountJson);
|
|
354
|
+
if (creds.clientId && creds.clientSecret && creds.refreshToken) return authenticateOauth(creds.clientId, creds.clientSecret, creds.refreshToken);
|
|
355
|
+
throw new Error("Chrome credentials missing: provide a service account key (CHROME_SERVICE_ACCOUNT_JSON) or the OAuth client ID, client secret, and refresh token.");
|
|
356
|
+
}
|
|
289
357
|
async function chrome_upload(extensionId, publisherId, zipPath, token) {
|
|
290
358
|
const body = await promises_default().readFile(zipPath);
|
|
291
359
|
const url = `${CWS_V2_UPLOAD_BASE}/${v2ItemName(publisherId, extensionId)}:upload`;
|
|
@@ -331,8 +399,8 @@ async function publishChrome(options, dryRun) {
|
|
|
331
399
|
await assertFilePresent(options.zip);
|
|
332
400
|
const zipSize = await getFileSize(options.zip);
|
|
333
401
|
const publisherId = requirePublisherId(options.publisherId, "submit");
|
|
334
|
-
log("chrome",
|
|
335
|
-
const token = await authenticate(options
|
|
402
|
+
log("chrome", `Authenticating with Chrome Web Store (API v2, ${options.serviceAccountJson ? "service account" : "OAuth"})`);
|
|
403
|
+
const token = await authenticate(options);
|
|
336
404
|
const outcome = {
|
|
337
405
|
storeUrl: chromeStoreUrl(options.extensionId),
|
|
338
406
|
submissionId: options.extensionId
|
|
@@ -371,7 +439,7 @@ async function publishChrome(options, dryRun) {
|
|
|
371
439
|
}
|
|
372
440
|
async function getChromeItem(params) {
|
|
373
441
|
var _rev_distributionChannels_, _rev_distributionChannels;
|
|
374
|
-
const token = await authenticate(params
|
|
442
|
+
const token = await authenticate(params);
|
|
375
443
|
const auth = {
|
|
376
444
|
Authorization: `${token.token_type} ${token.access_token}`
|
|
377
445
|
};
|
|
@@ -390,11 +458,12 @@ async function getChromeItem(params) {
|
|
|
390
458
|
async function verifyChromeCredentials(params) {
|
|
391
459
|
let token;
|
|
392
460
|
try {
|
|
393
|
-
token = await authenticate(params
|
|
461
|
+
token = await authenticate(params);
|
|
394
462
|
} catch (err) {
|
|
463
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
395
464
|
return {
|
|
396
465
|
ok: false,
|
|
397
|
-
message: `OAuth token exchange failed. Verify your Client ID, Client Secret, and Refresh Token are correct.\n${
|
|
466
|
+
message: params.serviceAccountJson ? `Service account token exchange failed. Verify the JSON key is intact and the account was added to your publisher (dev console > Account).\n${detail}` : `OAuth token exchange failed. Verify your Client ID, Client Secret, and Refresh Token are correct.\n${detail}`
|
|
398
467
|
};
|
|
399
468
|
}
|
|
400
469
|
const auth = {
|
|
@@ -418,7 +487,7 @@ async function verifyChromeCredentials(params) {
|
|
|
418
487
|
};
|
|
419
488
|
if (msg.includes("403")) return {
|
|
420
489
|
ok: false,
|
|
421
|
-
message: "Access denied. Check the publisher ID matches this extension's account, and that the extension ID is correct."
|
|
490
|
+
message: params.serviceAccountJson ? "Access denied. Check the publisher ID, and that this service account's email was added to the publisher (dev console > Account)." : "Access denied. Check the publisher ID matches this extension's account, and that the extension ID is correct."
|
|
422
491
|
};
|
|
423
492
|
return {
|
|
424
493
|
ok: false,
|
|
@@ -431,8 +500,6 @@ function delay(ms) {
|
|
|
431
500
|
setTimeout(resolve, ms);
|
|
432
501
|
});
|
|
433
502
|
}
|
|
434
|
-
const external_node_crypto_namespaceObject = require("node:crypto");
|
|
435
|
-
var external_node_crypto_default = /*#__PURE__*/ __webpack_require__.n(external_node_crypto_namespaceObject);
|
|
436
503
|
const AMO_BASE = "https://addons.mozilla.org/api/v5/addons";
|
|
437
504
|
function signJwt(issuer, secret, expiresInSeconds = 30) {
|
|
438
505
|
const header = {
|
|
@@ -909,6 +976,8 @@ CHROME
|
|
|
909
976
|
--chrome-zip <path> Path to Chrome extension ZIP
|
|
910
977
|
--chrome-extension-id <id> Chrome extension ID
|
|
911
978
|
--chrome-publisher-id <uuid> Publisher UUID from the dev console (required)
|
|
979
|
+
--chrome-service-account-json <v> Service account JSON key content or file path
|
|
980
|
+
(alternative to the OAuth flags below)
|
|
912
981
|
--chrome-client-id <id> OAuth2 client ID
|
|
913
982
|
--chrome-client-secret <secret> OAuth2 client secret
|
|
914
983
|
--chrome-refresh-token <token> OAuth2 refresh token
|
|
@@ -1504,17 +1573,21 @@ async function runWatch(flags) {
|
|
|
1504
1573
|
const timeoutMs = (flags.watchTimeout ?? 3600) * 1000;
|
|
1505
1574
|
let terminal;
|
|
1506
1575
|
try {
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1576
|
+
if ("chrome" === store) {
|
|
1577
|
+
const serviceAccountJson = flags.chromeServiceAccountJson ?? process.env.CHROME_SERVICE_ACCOUNT_JSON;
|
|
1578
|
+
terminal = await watchChromeSubmission({
|
|
1579
|
+
serviceAccountJson,
|
|
1580
|
+
clientId: serviceAccountJson ? flags.chromeClientId : mustEnv("CHROME_CLIENT_ID", flags.chromeClientId),
|
|
1581
|
+
clientSecret: serviceAccountJson ? flags.chromeClientSecret : mustEnv("CHROME_CLIENT_SECRET", flags.chromeClientSecret),
|
|
1582
|
+
refreshToken: serviceAccountJson ? flags.chromeRefreshToken : mustEnv("CHROME_REFRESH_TOKEN", flags.chromeRefreshToken),
|
|
1583
|
+
extensionId: mustEnv("CHROME_EXTENSION_ID", flags.chromeExtensionId),
|
|
1584
|
+
publisherId: mustEnv("CHROME_PUBLISHER_ID", flags.chromePublisherId)
|
|
1585
|
+
}, {
|
|
1586
|
+
pollIntervalMs,
|
|
1587
|
+
timeoutMs,
|
|
1588
|
+
onEvent
|
|
1589
|
+
});
|
|
1590
|
+
} else terminal = "firefox" === store ? await watchFirefoxSubmission({
|
|
1518
1591
|
jwtIssuer: mustEnv("FIREFOX_JWT_ISSUER", flags.firefoxJwtIssuer),
|
|
1519
1592
|
jwtSecret: mustEnv("FIREFOX_JWT_SECRET", flags.firefoxJwtSecret),
|
|
1520
1593
|
extensionId: mustEnv("FIREFOX_EXTENSION_ID", flags.firefoxExtensionId),
|
package/dist/module.mjs
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
1
|
import external_node_fs_default from "node:fs";
|
|
2
2
|
import external_node_path_default from "node:path";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import external_node_crypto_default from "node:crypto";
|
|
4
5
|
import promises_default from "node:fs/promises";
|
|
5
6
|
import external_pintor_default from "pintor";
|
|
6
|
-
import external_node_crypto_default from "node:crypto";
|
|
7
7
|
import external_node_readline_default from "node:readline";
|
|
8
8
|
const chromeOptionsSchema = z.object({
|
|
9
9
|
zip: z.string().min(1),
|
|
10
10
|
extensionId: z.string().min(1).trim(),
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
serviceAccountJson: z.string().trim().default(""),
|
|
12
|
+
clientId: z.string().trim().default(""),
|
|
13
|
+
clientSecret: z.string().trim().default(""),
|
|
14
|
+
refreshToken: z.string().trim().default(""),
|
|
14
15
|
publisherId: z.string().min(1).trim(),
|
|
15
16
|
deployPercentage: z.number().int().min(1).max(100).optional(),
|
|
16
17
|
reviewExemption: z.boolean().default(false),
|
|
17
18
|
skipSubmitReview: z.boolean().default(false)
|
|
19
|
+
}).superRefine((val, ctx)=>{
|
|
20
|
+
if (val.serviceAccountJson) return;
|
|
21
|
+
const missing = [
|
|
22
|
+
"clientId",
|
|
23
|
+
"clientSecret",
|
|
24
|
+
"refreshToken"
|
|
25
|
+
].filter((k)=>!val[k]);
|
|
26
|
+
for (const key of missing)ctx.addIssue({
|
|
27
|
+
code: z.ZodIssueCode.custom,
|
|
28
|
+
path: [
|
|
29
|
+
key
|
|
30
|
+
],
|
|
31
|
+
message: "Required unless a service account key is provided (CHROME_SERVICE_ACCOUNT_JSON)."
|
|
32
|
+
});
|
|
18
33
|
});
|
|
19
34
|
const firefoxOptionsSchema = z.object({
|
|
20
35
|
zip: z.string().min(1),
|
|
@@ -58,6 +73,7 @@ function resolveConfig(flags) {
|
|
|
58
73
|
chrome: null == chromeZip ? void 0 : {
|
|
59
74
|
zip: chromeZip,
|
|
60
75
|
extensionId: flags.chromeExtensionId ?? envStr("CHROME_EXTENSION_ID") ?? "",
|
|
76
|
+
serviceAccountJson: flags.chromeServiceAccountJson ?? envStr("CHROME_SERVICE_ACCOUNT_JSON") ?? "",
|
|
61
77
|
clientId: flags.chromeClientId ?? envStr("CHROME_CLIENT_ID") ?? "",
|
|
62
78
|
clientSecret: flags.chromeClientSecret ?? envStr("CHROME_CLIENT_SECRET") ?? "",
|
|
63
79
|
refreshToken: flags.chromeRefreshToken ?? envStr("CHROME_REFRESH_TOKEN") ?? "",
|
|
@@ -88,6 +104,7 @@ function pathToEnvName(segments) {
|
|
|
88
104
|
}
|
|
89
105
|
const SETUP_HINTS = {
|
|
90
106
|
CHROME_EXTENSION_ID: "Find this in the Chrome Web Store Developer Dashboard URL for your extension.",
|
|
107
|
+
CHROME_SERVICE_ACCOUNT_JSON: "Optional alternative to OAuth: a Google Cloud service account JSON key (content or file path), added to your publisher under dev console > Account.",
|
|
91
108
|
CHROME_CLIENT_ID: "Create OAuth 2.0 credentials at https://console.cloud.google.com/apis/credentials",
|
|
92
109
|
CHROME_CLIENT_SECRET: "Generated alongside the Client ID in the Google Cloud Console.",
|
|
93
110
|
CHROME_REFRESH_TOKEN: "Obtain by completing the OAuth consent flow. See the Chrome Web Store API docs.",
|
|
@@ -216,7 +233,51 @@ function requirePublisherId(publisherId, op) {
|
|
|
216
233
|
function chromeStoreUrl(extensionId) {
|
|
217
234
|
return `https://chromewebstore.google.com/detail/${extensionId}`;
|
|
218
235
|
}
|
|
219
|
-
|
|
236
|
+
const CWS_SCOPE = "https://www.googleapis.com/auth/chromewebstore";
|
|
237
|
+
async function resolveServiceAccountKey(value) {
|
|
238
|
+
const trimmed = value.trim();
|
|
239
|
+
const raw = trimmed.startsWith("{") ? trimmed : await promises_default.readFile(trimmed, "utf-8").catch(()=>{
|
|
240
|
+
throw new Error(`Chrome service account key: "${trimmed.slice(0, 80)}" is neither JSON nor a readable file path.`);
|
|
241
|
+
});
|
|
242
|
+
let parsed;
|
|
243
|
+
try {
|
|
244
|
+
parsed = JSON.parse(raw);
|
|
245
|
+
} catch {
|
|
246
|
+
throw new Error("Chrome service account key is not valid JSON.");
|
|
247
|
+
}
|
|
248
|
+
if (!parsed.client_email || !parsed.private_key) throw new Error("Chrome service account key is missing client_email or private_key. Download the JSON key from the Google Cloud Console.");
|
|
249
|
+
return {
|
|
250
|
+
client_email: parsed.client_email,
|
|
251
|
+
private_key: parsed.private_key
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
async function authenticateServiceAccount(serviceAccountJson) {
|
|
255
|
+
const key = await resolveServiceAccountKey(serviceAccountJson);
|
|
256
|
+
const iat = Math.floor(Date.now() / 1000);
|
|
257
|
+
const encode = (obj)=>Buffer.from(JSON.stringify(obj)).toString("base64url");
|
|
258
|
+
const unsigned = `${encode({
|
|
259
|
+
alg: "RS256",
|
|
260
|
+
typ: "JWT"
|
|
261
|
+
})}.${encode({
|
|
262
|
+
iss: key.client_email,
|
|
263
|
+
scope: CWS_SCOPE,
|
|
264
|
+
aud: CWS_OAUTH_URL,
|
|
265
|
+
iat,
|
|
266
|
+
exp: iat + 3600
|
|
267
|
+
})}`;
|
|
268
|
+
const signature = external_node_crypto_default.createSign("RSA-SHA256").update(unsigned).sign(key.private_key).toString("base64url");
|
|
269
|
+
return fetchJson(CWS_OAUTH_URL, {
|
|
270
|
+
method: "POST",
|
|
271
|
+
body: new URLSearchParams({
|
|
272
|
+
grant_type: "urn:ietf:params:oauth:grant-type:jwt-bearer",
|
|
273
|
+
assertion: `${unsigned}.${signature}`
|
|
274
|
+
}).toString(),
|
|
275
|
+
headers: {
|
|
276
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
async function authenticateOauth(clientId, clientSecret, refreshToken) {
|
|
220
281
|
return fetchJson(CWS_OAUTH_URL, {
|
|
221
282
|
method: "POST",
|
|
222
283
|
body: JSON.stringify({
|
|
@@ -231,6 +292,11 @@ async function authenticate(clientId, clientSecret, refreshToken) {
|
|
|
231
292
|
}
|
|
232
293
|
});
|
|
233
294
|
}
|
|
295
|
+
async function authenticate(creds) {
|
|
296
|
+
if (creds.serviceAccountJson) return authenticateServiceAccount(creds.serviceAccountJson);
|
|
297
|
+
if (creds.clientId && creds.clientSecret && creds.refreshToken) return authenticateOauth(creds.clientId, creds.clientSecret, creds.refreshToken);
|
|
298
|
+
throw new Error("Chrome credentials missing: provide a service account key (CHROME_SERVICE_ACCOUNT_JSON) or the OAuth client ID, client secret, and refresh token.");
|
|
299
|
+
}
|
|
234
300
|
async function chrome_upload(extensionId, publisherId, zipPath, token) {
|
|
235
301
|
const body = await promises_default.readFile(zipPath);
|
|
236
302
|
const url = `${CWS_V2_UPLOAD_BASE}/${v2ItemName(publisherId, extensionId)}:upload`;
|
|
@@ -276,8 +342,8 @@ async function publishChrome(options, dryRun) {
|
|
|
276
342
|
await assertFilePresent(options.zip);
|
|
277
343
|
const zipSize = await getFileSize(options.zip);
|
|
278
344
|
const publisherId = requirePublisherId(options.publisherId, "submit");
|
|
279
|
-
log("chrome",
|
|
280
|
-
const token = await authenticate(options
|
|
345
|
+
log("chrome", `Authenticating with Chrome Web Store (API v2, ${options.serviceAccountJson ? "service account" : "OAuth"})`);
|
|
346
|
+
const token = await authenticate(options);
|
|
281
347
|
const outcome = {
|
|
282
348
|
storeUrl: chromeStoreUrl(options.extensionId),
|
|
283
349
|
submissionId: options.extensionId
|
|
@@ -316,7 +382,7 @@ async function publishChrome(options, dryRun) {
|
|
|
316
382
|
}
|
|
317
383
|
async function getChromeItem(params) {
|
|
318
384
|
var _rev_distributionChannels_, _rev_distributionChannels;
|
|
319
|
-
const token = await authenticate(params
|
|
385
|
+
const token = await authenticate(params);
|
|
320
386
|
const auth = {
|
|
321
387
|
Authorization: `${token.token_type} ${token.access_token}`
|
|
322
388
|
};
|
|
@@ -335,11 +401,12 @@ async function getChromeItem(params) {
|
|
|
335
401
|
async function verifyChromeCredentials(params) {
|
|
336
402
|
let token;
|
|
337
403
|
try {
|
|
338
|
-
token = await authenticate(params
|
|
404
|
+
token = await authenticate(params);
|
|
339
405
|
} catch (err) {
|
|
406
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
340
407
|
return {
|
|
341
408
|
ok: false,
|
|
342
|
-
message: `OAuth token exchange failed. Verify your Client ID, Client Secret, and Refresh Token are correct.\n${
|
|
409
|
+
message: params.serviceAccountJson ? `Service account token exchange failed. Verify the JSON key is intact and the account was added to your publisher (dev console > Account).\n${detail}` : `OAuth token exchange failed. Verify your Client ID, Client Secret, and Refresh Token are correct.\n${detail}`
|
|
343
410
|
};
|
|
344
411
|
}
|
|
345
412
|
const auth = {
|
|
@@ -363,7 +430,7 @@ async function verifyChromeCredentials(params) {
|
|
|
363
430
|
};
|
|
364
431
|
if (msg.includes("403")) return {
|
|
365
432
|
ok: false,
|
|
366
|
-
message: "Access denied. Check the publisher ID matches this extension's account, and that the extension ID is correct."
|
|
433
|
+
message: params.serviceAccountJson ? "Access denied. Check the publisher ID, and that this service account's email was added to the publisher (dev console > Account)." : "Access denied. Check the publisher ID matches this extension's account, and that the extension ID is correct."
|
|
367
434
|
};
|
|
368
435
|
return {
|
|
369
436
|
ok: false,
|
|
@@ -852,6 +919,8 @@ CHROME
|
|
|
852
919
|
--chrome-zip <path> Path to Chrome extension ZIP
|
|
853
920
|
--chrome-extension-id <id> Chrome extension ID
|
|
854
921
|
--chrome-publisher-id <uuid> Publisher UUID from the dev console (required)
|
|
922
|
+
--chrome-service-account-json <v> Service account JSON key content or file path
|
|
923
|
+
(alternative to the OAuth flags below)
|
|
855
924
|
--chrome-client-id <id> OAuth2 client ID
|
|
856
925
|
--chrome-client-secret <secret> OAuth2 client secret
|
|
857
926
|
--chrome-refresh-token <token> OAuth2 refresh token
|
|
@@ -1445,17 +1514,21 @@ async function runWatch(flags) {
|
|
|
1445
1514
|
const timeoutMs = (flags.watchTimeout ?? 3600) * 1000;
|
|
1446
1515
|
let terminal;
|
|
1447
1516
|
try {
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1517
|
+
if ("chrome" === store) {
|
|
1518
|
+
const serviceAccountJson = flags.chromeServiceAccountJson ?? process.env.CHROME_SERVICE_ACCOUNT_JSON;
|
|
1519
|
+
terminal = await watchChromeSubmission({
|
|
1520
|
+
serviceAccountJson,
|
|
1521
|
+
clientId: serviceAccountJson ? flags.chromeClientId : mustEnv("CHROME_CLIENT_ID", flags.chromeClientId),
|
|
1522
|
+
clientSecret: serviceAccountJson ? flags.chromeClientSecret : mustEnv("CHROME_CLIENT_SECRET", flags.chromeClientSecret),
|
|
1523
|
+
refreshToken: serviceAccountJson ? flags.chromeRefreshToken : mustEnv("CHROME_REFRESH_TOKEN", flags.chromeRefreshToken),
|
|
1524
|
+
extensionId: mustEnv("CHROME_EXTENSION_ID", flags.chromeExtensionId),
|
|
1525
|
+
publisherId: mustEnv("CHROME_PUBLISHER_ID", flags.chromePublisherId)
|
|
1526
|
+
}, {
|
|
1527
|
+
pollIntervalMs,
|
|
1528
|
+
timeoutMs,
|
|
1529
|
+
onEvent
|
|
1530
|
+
});
|
|
1531
|
+
} else terminal = "firefox" === store ? await watchFirefoxSubmission({
|
|
1459
1532
|
jwtIssuer: mustEnv("FIREFOX_JWT_ISSUER", flags.firefoxJwtIssuer),
|
|
1460
1533
|
jwtSecret: mustEnv("FIREFOX_JWT_SECRET", flags.firefoxJwtSecret),
|
|
1461
1534
|
extensionId: mustEnv("FIREFOX_EXTENSION_ID", flags.firefoxExtensionId),
|
package/dist/src/chrome.d.ts
CHANGED
|
@@ -5,8 +5,9 @@ export declare function chromeStoreUrl(extensionId: string): string;
|
|
|
5
5
|
export interface CwsAccessToken {
|
|
6
6
|
access_token: string;
|
|
7
7
|
expires_in: number;
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
/** Absent for service-account (JWT bearer) grants. */
|
|
9
|
+
refresh_token?: string;
|
|
10
|
+
scope?: string;
|
|
10
11
|
token_type: string;
|
|
11
12
|
}
|
|
12
13
|
export interface ChromeVerifyResult {
|
|
@@ -14,6 +15,14 @@ export interface ChromeVerifyResult {
|
|
|
14
15
|
message: string;
|
|
15
16
|
extensionTitle?: string;
|
|
16
17
|
}
|
|
18
|
+
/** Credential fields shared by every Chrome API entry point. */
|
|
19
|
+
export interface ChromeCredentials {
|
|
20
|
+
serviceAccountJson?: string;
|
|
21
|
+
clientId?: string;
|
|
22
|
+
clientSecret?: string;
|
|
23
|
+
refreshToken?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function authenticate(creds: ChromeCredentials): Promise<CwsAccessToken>;
|
|
17
26
|
export interface ChromePublishOutcome {
|
|
18
27
|
storeUrl: string;
|
|
19
28
|
submissionId: string;
|
|
@@ -30,17 +39,11 @@ export interface ChromeItemStatus {
|
|
|
30
39
|
/** v2 review state (PENDING_REVIEW | STAGED | PUBLISHED | REJECTED | ...). */
|
|
31
40
|
state?: string;
|
|
32
41
|
}
|
|
33
|
-
export declare function getChromeItem(params: {
|
|
34
|
-
clientId: string;
|
|
35
|
-
clientSecret: string;
|
|
36
|
-
refreshToken: string;
|
|
42
|
+
export declare function getChromeItem(params: ChromeCredentials & {
|
|
37
43
|
extensionId: string;
|
|
38
44
|
publisherId: string;
|
|
39
45
|
}): Promise<ChromeItemStatus>;
|
|
40
|
-
export declare function verifyChromeCredentials(params: {
|
|
41
|
-
clientId: string;
|
|
42
|
-
clientSecret: string;
|
|
43
|
-
refreshToken: string;
|
|
46
|
+
export declare function verifyChromeCredentials(params: ChromeCredentials & {
|
|
44
47
|
extensionId: string;
|
|
45
48
|
publisherId: string;
|
|
46
49
|
}): Promise<ChromeVerifyResult>;
|
package/dist/src/chrome.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chrome.d.ts","sourceRoot":"","sources":["../../src/chrome.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"chrome.d.ts","sourceRoot":"","sources":["../../src/chrome.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAoB7C,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAI3E;AAeD,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,gEAAgE;AAChE,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAsFD,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,cAAc,CAAC,CAczB;AA6DD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,OAAO,GACd,OAAO,CAAC,oBAAoB,CAAC,CAuD/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,KAAK,CAAC;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAwBD,wBAAsB,aAAa,CACjC,MAAM,EAAE,iBAAiB,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,GACA,OAAO,CAAC,gBAAgB,CAAC,CAgB3B;AAED,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,iBAAiB,GAAG;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB,GACA,OAAO,CAAC,kBAAkB,CAAC,CAkD7B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-commands.d.ts","sourceRoot":"","sources":["../../src/cli-commands.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAGxE;AAED,wBAAsB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"cli-commands.d.ts","sourceRoot":"","sources":["../../src/cli-commands.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAKzC,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAGxE;AAED,wBAAsB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFtE;AAmBD,wBAAsB,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAwB5E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-usage.d.ts","sourceRoot":"","sources":["../../src/cli-usage.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"cli-usage.d.ts","sourceRoot":"","sources":["../../src/cli-usage.ts"],"names":[],"mappings":"AAAA,wBAAgB,KAAK,IAAI,MAAM,CA4D9B"}
|
package/dist/src/config.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare function validateConfig(raw: DeployConfig): {
|
|
|
5
5
|
chrome?: {
|
|
6
6
|
zip: string;
|
|
7
7
|
extensionId: string;
|
|
8
|
+
serviceAccountJson: string;
|
|
8
9
|
clientId: string;
|
|
9
10
|
clientSecret: string;
|
|
10
11
|
refreshToken: string;
|
|
@@ -46,6 +47,8 @@ export interface CliFlags {
|
|
|
46
47
|
watchTimeout: number;
|
|
47
48
|
chromeZip: string;
|
|
48
49
|
chromeExtensionId: string;
|
|
50
|
+
/** Service account JSON key content or file path (alternative to OAuth). */
|
|
51
|
+
chromeServiceAccountJson: string;
|
|
49
52
|
chromeClientId: string;
|
|
50
53
|
chromeClientSecret: string;
|
|
51
54
|
chromeRefreshToken: string;
|
package/dist/src/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAEhE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,YAAY,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAEhE,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,YAAY,CAkEpE;AA2CD,wBAAgB,cAAc,CAAC,GAAG,EAAE,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmB/C;AAiBD,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,yEAAyE;IACzE,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,OAAO,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IACrC,8CAA8C;IAC9C,UAAU,EAAE,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IAC1C,4EAA4E;IAC5E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gDAAgD;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4EAA4E;IAC5E,wBAAwB,EAAE,MAAM,CAAC;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,2EAA2E;IAC3E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,sBAAsB,EAAE,OAAO,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,mFAAmF;IACnF,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,cAAc,EAAE,OAAO,CAAC;IACxB,2DAA2D;IAC3D,SAAS,EAAE,OAAO,CAAC;CACpB"}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export type StoreKey = "chrome" | "firefox" | "edge";
|
|
3
|
-
export declare const chromeOptionsSchema: z.ZodObject<{
|
|
3
|
+
export declare const chromeOptionsSchema: z.ZodEffects<z.ZodObject<{
|
|
4
4
|
zip: z.ZodString;
|
|
5
5
|
extensionId: z.ZodString;
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
serviceAccountJson: z.ZodDefault<z.ZodString>;
|
|
7
|
+
clientId: z.ZodDefault<z.ZodString>;
|
|
8
|
+
clientSecret: z.ZodDefault<z.ZodString>;
|
|
9
|
+
refreshToken: z.ZodDefault<z.ZodString>;
|
|
9
10
|
publisherId: z.ZodString;
|
|
10
11
|
deployPercentage: z.ZodOptional<z.ZodNumber>;
|
|
11
12
|
reviewExemption: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -13,6 +14,7 @@ export declare const chromeOptionsSchema: z.ZodObject<{
|
|
|
13
14
|
}, "strip", z.ZodTypeAny, {
|
|
14
15
|
zip: string;
|
|
15
16
|
extensionId: string;
|
|
17
|
+
serviceAccountJson: string;
|
|
16
18
|
clientId: string;
|
|
17
19
|
clientSecret: string;
|
|
18
20
|
refreshToken: string;
|
|
@@ -23,10 +25,33 @@ export declare const chromeOptionsSchema: z.ZodObject<{
|
|
|
23
25
|
}, {
|
|
24
26
|
zip: string;
|
|
25
27
|
extensionId: string;
|
|
28
|
+
publisherId: string;
|
|
29
|
+
serviceAccountJson?: string | undefined;
|
|
30
|
+
clientId?: string | undefined;
|
|
31
|
+
clientSecret?: string | undefined;
|
|
32
|
+
refreshToken?: string | undefined;
|
|
33
|
+
deployPercentage?: number | undefined;
|
|
34
|
+
reviewExemption?: boolean | undefined;
|
|
35
|
+
skipSubmitReview?: boolean | undefined;
|
|
36
|
+
}>, {
|
|
37
|
+
zip: string;
|
|
38
|
+
extensionId: string;
|
|
39
|
+
serviceAccountJson: string;
|
|
26
40
|
clientId: string;
|
|
27
41
|
clientSecret: string;
|
|
28
42
|
refreshToken: string;
|
|
29
43
|
publisherId: string;
|
|
44
|
+
reviewExemption: boolean;
|
|
45
|
+
skipSubmitReview: boolean;
|
|
46
|
+
deployPercentage?: number | undefined;
|
|
47
|
+
}, {
|
|
48
|
+
zip: string;
|
|
49
|
+
extensionId: string;
|
|
50
|
+
publisherId: string;
|
|
51
|
+
serviceAccountJson?: string | undefined;
|
|
52
|
+
clientId?: string | undefined;
|
|
53
|
+
clientSecret?: string | undefined;
|
|
54
|
+
refreshToken?: string | undefined;
|
|
30
55
|
deployPercentage?: number | undefined;
|
|
31
56
|
reviewExemption?: boolean | undefined;
|
|
32
57
|
skipSubmitReview?: boolean | undefined;
|
|
@@ -91,12 +116,13 @@ export declare const edgeOptionsSchema: z.ZodObject<{
|
|
|
91
116
|
export type EdgeOptions = z.infer<typeof edgeOptionsSchema>;
|
|
92
117
|
export declare const deployConfigSchema: z.ZodObject<{
|
|
93
118
|
dryRun: z.ZodDefault<z.ZodBoolean>;
|
|
94
|
-
chrome: z.ZodOptional<z.ZodObject<{
|
|
119
|
+
chrome: z.ZodOptional<z.ZodEffects<z.ZodObject<{
|
|
95
120
|
zip: z.ZodString;
|
|
96
121
|
extensionId: z.ZodString;
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
122
|
+
serviceAccountJson: z.ZodDefault<z.ZodString>;
|
|
123
|
+
clientId: z.ZodDefault<z.ZodString>;
|
|
124
|
+
clientSecret: z.ZodDefault<z.ZodString>;
|
|
125
|
+
refreshToken: z.ZodDefault<z.ZodString>;
|
|
100
126
|
publisherId: z.ZodString;
|
|
101
127
|
deployPercentage: z.ZodOptional<z.ZodNumber>;
|
|
102
128
|
reviewExemption: z.ZodDefault<z.ZodBoolean>;
|
|
@@ -104,6 +130,7 @@ export declare const deployConfigSchema: z.ZodObject<{
|
|
|
104
130
|
}, "strip", z.ZodTypeAny, {
|
|
105
131
|
zip: string;
|
|
106
132
|
extensionId: string;
|
|
133
|
+
serviceAccountJson: string;
|
|
107
134
|
clientId: string;
|
|
108
135
|
clientSecret: string;
|
|
109
136
|
refreshToken: string;
|
|
@@ -114,10 +141,33 @@ export declare const deployConfigSchema: z.ZodObject<{
|
|
|
114
141
|
}, {
|
|
115
142
|
zip: string;
|
|
116
143
|
extensionId: string;
|
|
144
|
+
publisherId: string;
|
|
145
|
+
serviceAccountJson?: string | undefined;
|
|
146
|
+
clientId?: string | undefined;
|
|
147
|
+
clientSecret?: string | undefined;
|
|
148
|
+
refreshToken?: string | undefined;
|
|
149
|
+
deployPercentage?: number | undefined;
|
|
150
|
+
reviewExemption?: boolean | undefined;
|
|
151
|
+
skipSubmitReview?: boolean | undefined;
|
|
152
|
+
}>, {
|
|
153
|
+
zip: string;
|
|
154
|
+
extensionId: string;
|
|
155
|
+
serviceAccountJson: string;
|
|
117
156
|
clientId: string;
|
|
118
157
|
clientSecret: string;
|
|
119
158
|
refreshToken: string;
|
|
120
159
|
publisherId: string;
|
|
160
|
+
reviewExemption: boolean;
|
|
161
|
+
skipSubmitReview: boolean;
|
|
162
|
+
deployPercentage?: number | undefined;
|
|
163
|
+
}, {
|
|
164
|
+
zip: string;
|
|
165
|
+
extensionId: string;
|
|
166
|
+
publisherId: string;
|
|
167
|
+
serviceAccountJson?: string | undefined;
|
|
168
|
+
clientId?: string | undefined;
|
|
169
|
+
clientSecret?: string | undefined;
|
|
170
|
+
refreshToken?: string | undefined;
|
|
121
171
|
deployPercentage?: number | undefined;
|
|
122
172
|
reviewExemption?: boolean | undefined;
|
|
123
173
|
skipSubmitReview?: boolean | undefined;
|
|
@@ -182,6 +232,7 @@ export declare const deployConfigSchema: z.ZodObject<{
|
|
|
182
232
|
chrome?: {
|
|
183
233
|
zip: string;
|
|
184
234
|
extensionId: string;
|
|
235
|
+
serviceAccountJson: string;
|
|
185
236
|
clientId: string;
|
|
186
237
|
clientSecret: string;
|
|
187
238
|
refreshToken: string;
|
|
@@ -209,10 +260,11 @@ export declare const deployConfigSchema: z.ZodObject<{
|
|
|
209
260
|
chrome?: {
|
|
210
261
|
zip: string;
|
|
211
262
|
extensionId: string;
|
|
212
|
-
clientId: string;
|
|
213
|
-
clientSecret: string;
|
|
214
|
-
refreshToken: string;
|
|
215
263
|
publisherId: string;
|
|
264
|
+
serviceAccountJson?: string | undefined;
|
|
265
|
+
clientId?: string | undefined;
|
|
266
|
+
clientSecret?: string | undefined;
|
|
267
|
+
refreshToken?: string | undefined;
|
|
216
268
|
deployPercentage?: number | undefined;
|
|
217
269
|
reviewExemption?: boolean | undefined;
|
|
218
270
|
skipSubmitReview?: boolean | undefined;
|
package/dist/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAErD,eAAO,MAAM,mBAAmB
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;AAErD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiC5B,CAAC;AACL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqB7B,CAAC;AACL,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;EAM5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,CAAC;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qFAAqF;IACrF,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,WAAW,GACnB,SAAS,GACT,WAAW,GACX,YAAY,GACZ,WAAW,GACX,UAAU,GACV,QAAQ,CAAC;AAEb,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,WAAW,CAAC;IACpB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC"}
|
package/dist/src/watch.d.ts
CHANGED
|
@@ -15,9 +15,10 @@ export interface WatchLoopOptions {
|
|
|
15
15
|
onEvent?: (event: WatchEvent) => void;
|
|
16
16
|
}
|
|
17
17
|
export interface ChromeWatchInput {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
serviceAccountJson?: string;
|
|
19
|
+
clientId?: string;
|
|
20
|
+
clientSecret?: string;
|
|
21
|
+
refreshToken?: string;
|
|
21
22
|
extensionId: string;
|
|
22
23
|
publisherId: string;
|
|
23
24
|
}
|
package/dist/src/watch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/watch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAY,UAAU,EAAe,MAAM,SAAS,CAAC;AAajE,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACvC;AAUD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/watch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAY,UAAU,EAAe,MAAM,SAAS,CAAC;AAajE,MAAM,WAAW,gBAAgB;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACvC;AAUD,MAAM,WAAW,gBAAgB;IAC/B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,wBAAwB,CAC5C,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,UAAU,CAAC,CAqCrB;AAED,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,gBAAgB,EACvB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAErB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB;AAgBD,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC,UAAU,CAAC,CA2BrB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAErB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAUD,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,UAAU,CAAC,CA2BrB;AAED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,iBAAiB,EACxB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,UAAU,CAAC,CAMrB"}
|
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"ci",
|
|
20
20
|
"manifest-v3"
|
|
21
21
|
],
|
|
22
|
-
"version": "1.
|
|
22
|
+
"version": "1.1.0",
|
|
23
23
|
"repository": {
|
|
24
24
|
"type": "git",
|
|
25
25
|
"url": "git+https://github.com/extensiondev/deploy.git"
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"compile": "rslib build",
|
|
61
61
|
"test": "vitest run",
|
|
62
62
|
"build": "pnpm run compile",
|
|
63
|
+
"prepare": "pnpm run compile",
|
|
63
64
|
"prepublishOnly": "pnpm run test && pnpm run compile"
|
|
64
65
|
},
|
|
65
66
|
"publishConfig": {
|