"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeployManifestCommand = void 0;
const utils_array_1 = require("@ionic/utils-array");
const utils_fs_1 = require("@ionic/utils-fs");
const utils_terminal_1 = require("@ionic/utils-terminal");
const crypto = require("crypto");
const fs = require("fs");
const path = require("path");
const color_1 = require("../../lib/color");
const errors_1 = require("../../lib/errors");
const core_1 = require("./core");
class DeployManifestCommand extends core_1.DeployCoreCommand {
async getMetadata() {
return {
name: 'manifest',
type: 'project',
summary: 'Generates a manifest file for the deploy service from a built app directory',
groups: ["paid" /* PAID */],
};
}
async run() {
if (!this.project) {
throw new errors_1.FatalException(`Cannot run ${color_1.input('ionic deploy manifest')} outside a project directory.`);
}
await this.requireNativeIntegration();
const buildDir = await this.project.getDistDir();
const manifest = await this.getFilesAndSizesAndHashesForGlobPattern(buildDir);
const manifestPath = path.resolve(buildDir, 'pro-manifest.json');
await utils_fs_1.writeFile(manifestPath, JSON.stringify(manifest, undefined, 2), { encoding: 'utf8' });
this.env.log.ok(`Appflow Deploy manifest written to ${color_1.input(utils_terminal_1.prettyPath(manifestPath))}!`);
}
async getFilesAndSizesAndHashesForGlobPattern(buildDir) {
const contents = await utils_fs_1.readdirp(buildDir, { filter: item => !/(css|js)\.map$/.test(item.path) });
const stats = await utils_array_1.map(contents, async (f) => [f, await utils_fs_1.stat(f)]);
const files = stats.filter(([, s]) => !s.isDirectory());
const items = await Promise.all(files.map(([f, s]) => this.getFileAndSizeAndHashForFile(buildDir, f, s)));
return items.filter(item => item.href !== 'pro-manifest.json');
}
async getFileAndSizeAndHashForFile(buildDir, file, s) {
const buffer = await this.readFile(file);
return {
href: path.relative(buildDir, file),
size: s.size,
integrity: this.getIntegrity(buffer),
};
}
async readFile(file) {
return new Promise((resolve, reject) => {
fs.readFile(file, (err, buffer) => {
if (err) {
return reject(err);
}
resolve(buffer);
});
});
}
getIntegrity(data) {
return ['sha256', 'sha384', 'sha512']
.map(algorithm => {
const hash = crypto.createHash(algorithm);
hash.update(data);
return algorithm + '-' + hash.digest('base64');
})
.join(' ');
}
}
exports.DeployManifestCommand = DeployManifestCommand;