UNPKG

chrome-webstore-upload-cli

Version:

CLI tool to upload Chrome Extensions to the Chrome Web Store

184 lines (153 loc) 5.53 kB
#!/usr/bin/env node import path from 'node:path'; import process from 'node:process'; import meow from 'meow'; import createConfig from './config.js'; import { upload, publish, fetchToken } from './wrapper.js'; import { isUploadSuccess, handlePublishStatus } from './util.js'; const cli = meow(` Usage $ chrome-webstore-upload [command] where [command] can be one of upload, publish if the command is missing, it will both upload and publish the extension. Options --source Path to either a zip file, a crx file, or a directory to be zipped. Defaults to the value of webExt.sourceDir in package.json or the current directory if not specified --extension-id The ID of the Chrome Extension (environment variable EXTENSION_ID) --client-id OAuth2 Client ID (environment variable CLIENT_ID) --client-secret OAuth2 Client Secret (environment variable CLIENT_SECRET) --refresh-token OAuth2 Refresh Token (environment variable REFRESH_TOKEN) --auto-publish Can be used with the "upload" command (deprecated, use \`chrome-webstore-upload\` without a command instead) --trusted-testers Can be used with the "publish" command --deploy-percentage Can be used with the "publish" command. Defaults to 100 --max-await-in-progress Max time to wait for the upload to complete, if it's returning IN_PROGRESS (in seconds) Examples Upload and publish a new version, using existing environment variables and the default value for --source $ chrome-webstore-upload Upload new extension archive to the Chrome Web Store $ chrome-webstore-upload upload --source my-custom-zip.zip Publish the last uploaded version (whether it was uploaded via web UI or via CLI) $ chrome-webstore-upload publish --extension-id elomekmlfonmdhmpmdfldcjgdoacjcba `, { importMeta: import.meta, flags: { source: { type: 'string', }, maxAwaitInProgress: { type: 'number', }, }, }); if (cli.input.length > 1) { console.error('Too many parameters'); cli.showHelp(1); } const { apiConfig, zipPath, isUpload, isPublish, autoPublish, trustedTesters, deployPercentage, maxAwaitInProgress, } = await createConfig(cli.input[0], cli.flags); async function doAutoPublish() { console.log('Fetching token...'); const token = await fetchToken(apiConfig); console.log(`Uploading ${path.basename(zipPath)}...`); const uploadResponse = await upload({ apiConfig, token, zipPath, maxAwaitInProgress, }); if (!isUploadSuccess(uploadResponse)) { throw uploadResponse; } console.log('Publishing...'); const publishResponse = await publish( { apiConfig, token }, trustedTesters && 'trustedTesters', deployPercentage, ); handlePublishStatus(publishResponse); } async function doUpload() { console.log(`Uploading ${path.basename(zipPath)}`); const response = await upload({ apiConfig, zipPath, maxAwaitInProgress, }); if (!isUploadSuccess(response)) { throw response; } console.log('Upload completed'); } async function doPublish() { console.log('Publishing'); const response = await publish( { apiConfig }, trustedTesters && 'trustedTesters', deployPercentage, ); handlePublishStatus(response); } function errorHandler(error) { console.log(error?.response?.body ?? error); process.exitCode = 1; if (error?.name === 'HTTPError') { const response = JSON.parse(error?.response?.body ?? '{}'); const { clientId, refreshToken } = apiConfig; if (response.error_description === 'The OAuth client was not found.') { console.error( 'Probably the provided client ID is not valid. Try following the guide again', ); console.error( 'https://github.com/fregante/chrome-webstore-upload-keys', ); console.error({ clientId }); return; } if (response.error_description === 'Bad Request') { const { clientId } = apiConfig; console.error( 'Probably the provided refresh token is not valid. Try following the guide again', ); console.error( 'https://github.com/fregante/chrome-webstore-upload-keys', ); console.error({ clientId, refreshToken }); return; } if (error?.message === 'Response code 400 (Bad Request)') { // Nothing else to add return; } } if (error?.itemError?.length > 0) { for (const itemError of error.itemError) { console.error('Error: ' + itemError.error_code); console.error(itemError.error_detail); } } if (error?.uploadState === 'IN_PROGRESS') { console.log('Upload is in progress. Try setting or increasing --max-await-in-progress flag to wait for the upload to complete'); } } async function init() { if (isUpload && autoPublish) { await doAutoPublish(); } else if (isUpload) { await doUpload(); } else if (isPublish) { await doPublish(); } } try { await init(); } catch (error) { errorHandler(error); }