web-ext
Version:
A command line tool to help build, run, and test web extensions
130 lines (128 loc) • 4.09 kB
JavaScript
import path from 'path';
import defaultBuilder from './build.js';
import { isErrorWithCode, UsageError, WebExtError } from '../errors.js';
import { prepareArtifactsDir } from '../util/artifacts.js';
import { createLogger } from '../util/logger.js';
import getValidatedManifest, { getManifestId } from '../util/manifest.js';
import { defaultAsyncFsReadFile, signAddon as defaultSubmitAddonSigner } from '../util/submit-addon.js';
import { withTempDir } from '../util/temp-dir.js';
const log = createLogger(import.meta.url);
export const extensionIdFile = '.web-extension-id';
export const uploadUuidFile = '.amo-upload-uuid';
// Sign command types and implementation.
export default function sign({
amoBaseUrl,
apiKey,
apiProxy,
apiSecret,
artifactsDir,
ignoreFiles = [],
sourceDir,
timeout,
approvalTimeout,
channel,
amoMetadata,
uploadSourceCode,
webextVersion
}, {
build = defaultBuilder,
preValidatedManifest,
submitAddon = defaultSubmitAddonSigner,
asyncFsReadFile = defaultAsyncFsReadFile
} = {}) {
return withTempDir(async function (tmpDir) {
await prepareArtifactsDir(artifactsDir);
let manifestData;
const savedIdPath = path.join(sourceDir, extensionIdFile);
const savedUploadUuidPath = path.join(sourceDir, uploadUuidFile);
if (preValidatedManifest) {
manifestData = preValidatedManifest;
} else {
manifestData = await getValidatedManifest(sourceDir);
}
const [buildResult, idFromSourceDir] = await Promise.all([build({
sourceDir,
ignoreFiles,
artifactsDir: tmpDir.path()
}, {
manifestData,
showReadyMessage: false
}), getIdFromFile(savedIdPath)]);
const id = getManifestId(manifestData);
if (idFromSourceDir && !id) {
throw new UsageError('Cannot use previously auto-generated extension ID ' + `${idFromSourceDir} - This extension ID must be specified in the manifest.json file.`);
}
if (!id) {
// We only auto-generate add-on IDs for MV2 add-ons on AMO.
if (manifestData.manifest_version !== 2) {
throw new UsageError('An extension ID must be specified in the manifest.json file.');
}
log.warn('No extension ID specified (it will be auto-generated the first time)');
}
if (!channel) {
throw new UsageError('You must specify a channel');
}
let metaDataJson;
if (amoMetadata) {
const metadataFileBuffer = await asyncFsReadFile(amoMetadata);
try {
metaDataJson = JSON.parse(metadataFileBuffer.toString());
} catch (err) {
throw new UsageError('Invalid JSON in listing metadata');
}
}
const userAgentString = `web-ext/${webextVersion}`;
const signSubmitArgs = {
apiKey,
apiSecret,
apiProxy,
id,
xpiPath: buildResult.extensionPath,
downloadDir: artifactsDir,
channel
};
try {
const result = await submitAddon({
...signSubmitArgs,
amoBaseUrl,
channel,
savedIdPath,
savedUploadUuidPath,
metaDataJson,
userAgentString,
validationCheckTimeout: timeout,
approvalCheckTimeout: approvalTimeout !== undefined ? approvalTimeout : timeout,
submissionSource: uploadSourceCode
});
return result;
} catch (clientError) {
throw new WebExtError(clientError.message);
}
});
}
export async function getIdFromFile(filePath, asyncFsReadFile = defaultAsyncFsReadFile) {
let content;
try {
content = await asyncFsReadFile(filePath);
} catch (error) {
if (isErrorWithCode('ENOENT', error)) {
log.debug(`No ID file found at: ${filePath}`);
return;
}
throw error;
}
let lines = content.toString().split('\n');
lines = lines.filter(line => {
line = line.trim();
if (line && !line.startsWith('#')) {
return line;
}
});
const id = lines[0];
log.debug(`Found extension ID ${id} in ${filePath}`);
if (!id) {
throw new UsageError(`No ID found in extension ID file ${filePath}`);
}
return id;
}
//# sourceMappingURL=sign.js.map