@azure/static-web-apps-cli
Version:
Azure Static Web Apps CLI
120 lines • 5.23 kB
JavaScript
import fs from "node:fs";
import { fetchWithProxy as fetch } from "./utils/fetch-proxy.js";
import os from "node:os";
import path from "node:path";
import { STATIC_SITE_CLIENT_RELEASE_METADATA_URL, DEPLOY_BINARY_NAME, DEPLOY_FOLDER, DEPLOY_BINARY_STABLE_TAG } from "./constants.js";
import { downloadAndValidateBinary } from "./download-binary-helper.js";
import { swaCLIEnv } from "./env.js";
import { logger } from "./utils/logger.js";
import { getPlatform } from "./utils/platform.js";
export async function getDeployClientPath() {
const platform = getPlatform();
if (!platform) {
throw new Error(`Unsupported platform: ${os.platform()}`);
}
const localClientMetadata = getLocalClientMetadata();
const binaryVersion = swaCLIEnv().SWA_CLI_DEPLOY_BINARY_VERSION || DEPLOY_BINARY_STABLE_TAG;
const remoteClientMetadata = await fetchClientVersionDefinition(binaryVersion);
if (remoteClientMetadata === undefined) {
throw new Error(`Could not load ${DEPLOY_BINARY_NAME} metadata from remote. Please check your internet connection.`);
}
// if the latest version is the same as the local version, we can skip the download
if (localClientMetadata) {
if (!localClientMetadata.metadata || !localClientMetadata.binary || !localClientMetadata.checksum) {
logger.warn(`Local client metadata is invalid!`);
}
else {
const localChecksum = localClientMetadata.checksum;
const releaseChecksum = remoteClientMetadata.files[platform].sha.toLowerCase();
const remoteBuildId = remoteClientMetadata.buildId;
const localBuildId = localClientMetadata.metadata.buildId;
if (remoteBuildId === localBuildId) {
if (localChecksum === releaseChecksum) {
logger.silly(`Local client binary is up to date. Skipping download.`);
return {
binary: localClientMetadata.binary,
buildId: localBuildId,
};
}
else {
logger.warn(`Local metatada contains invalid checksum hash!`);
logger.warn(` Expected ${releaseChecksum}`);
logger.warn(` Received ${localChecksum}`);
}
}
else {
if (localBuildId) {
logger.warn(`${DEPLOY_BINARY_NAME} is outdated! Expected ${remoteBuildId}, got ${localBuildId}`);
}
}
}
}
return {
binary: await downloadAndValidateBinary(remoteClientMetadata, DEPLOY_BINARY_NAME, DEPLOY_FOLDER, remoteClientMetadata.buildId, platform),
buildId: remoteClientMetadata.buildId,
};
}
export function getLocalClientMetadata() {
const metadataFilename = path.join(DEPLOY_FOLDER, `${DEPLOY_BINARY_NAME}.json`);
if (!fs.existsSync(metadataFilename)) {
logger.warn(`Could not find ${DEPLOY_BINARY_NAME} local binary`);
return null;
}
let metadata = null;
try {
metadata = JSON.parse(fs.readFileSync(metadataFilename, "utf8"));
}
catch (err) {
logger.warn(`Could not read ${DEPLOY_BINARY_NAME} metadata: ${err}`);
return null;
}
if (metadata) {
if (!fs.existsSync(metadata.binary)) {
logger.warn(`Could not find ${DEPLOY_BINARY_NAME} binary: ${metadata.binary}`);
return null;
}
else if (fs.existsSync(metadata.binary)) {
return metadata;
}
}
return null;
}
export async function fetchClientVersionDefinition(releaseVersion) {
logger.silly(`Fetching release metadata for version: ${releaseVersion}. Please wait...`);
try {
logger.silly(`GET ${STATIC_SITE_CLIENT_RELEASE_METADATA_URL}`);
const response = await fetch(STATIC_SITE_CLIENT_RELEASE_METADATA_URL);
if (!response.ok) {
logger.silly(`Response.status = ${response.status} ${response.statusText}`);
return undefined;
}
const remoteVersionDefinitions = (await response.json());
logger.silly(`Decode JSON: ${JSON.stringify(remoteVersionDefinitions, null, 2)}`);
if (Array.isArray(remoteVersionDefinitions) && remoteVersionDefinitions.length) {
const releaseMetadata = remoteVersionDefinitions.find((v) => v?.version === releaseVersion);
logger.silly(`Release Metadata for ${releaseVersion}: ${JSON.stringify(releaseMetadata, null, 2)}`);
return releaseMetadata;
}
}
catch (err) {
logger.silly(`Error fetching release metadata: ${err}`);
}
logger.silly(`Could not find release metadata; returning undefined`);
return undefined;
}
// TODO: get StaticSiteClient to remove zip files
// TODO: can these ZIPs be created under /tmp?
export function cleanUp() {
const clean = (file) => {
const filepath = path.join(process.cwd(), file);
if (fs.existsSync(filepath)) {
try {
fs.unlinkSync(filepath);
}
catch { }
}
};
clean(".\\app.zip");
clean(".\\api.zip");
}
//# sourceMappingURL=deploy-client.js.map