@mondaycom/apps-cli
Version:
A cli tool to manage apps (and monday-code projects) in monday.com
101 lines (100 loc) • 4.81 kB
JavaScript
import { createAppFromManifestUrl, updateAppFromManifestUrl } from '../consts/urls.js';
import { execute } from './api-service.js';
import { compressFilesToZip, readZipFileAsBuffer } from './files-service.js';
import { PromptService } from './prompt-service.js';
import { HttpMethodTypes } from '../types/services/api-service.js';
import { loadFile, saveToFile, unlink } from '../utils/file-system.js';
import logger from '../utils/logger.js';
import { processTemplate } from '../utils/templating.js';
import { TIME_IN_MILLISECONDS } from '../utils/time-utils.js';
import { appsUrlBuilder } from '../utils/urls-builder.js';
export const uploadManifestTsk = async (ctx, task) => {
try {
const processedManifest = await processManifestTemplate(ctx.manifestFilePath, ctx.allowMissingVariables);
ctx.manifestFilePath = `${ctx.manifestFilePath}.processed`;
await saveToFile(ctx.manifestFilePath, JSON.stringify(processedManifest));
task.output = `Zipping your manifest file`;
const zipFilePath = await compressFilesToZip([{ path: ctx.manifestFilePath, replaceName: 'manifest.json' }]);
const buffer = readZipFileAsBuffer(zipFilePath);
task.output = `Uploading your app manifest`;
await uploadZippedManifest(buffer, { appId: ctx.appId, appVersionId: ctx.appVersionId });
task.output = `your app manifest has been uploaded successfully`;
}
finally {
await unlink(ctx.manifestFilePath);
}
};
export const processManifestTemplate = async (manifestFilePath, allowMissingVariables = false) => {
try {
const manifestJson = await loadFile(manifestFilePath);
const parsedManifest = JSON.parse(manifestJson);
const processedManifest = processTemplate(parsedManifest, process.env, {
failOnMissingVariable: !allowMissingVariables,
});
return processedManifest;
}
catch (error) {
logger.debug(error);
if (error instanceof SyntaxError) {
throw new TypeError(`Failed to parse manifest file. Please verify that "${manifestFilePath}" contains valid JSON.`);
}
if (error instanceof Error && error.message.includes('Missing variable')) {
throw new Error(`Failed to process manifest template: ${error.message}. Please ensure all required environment variables are set.`);
}
throw new Error(`Failed to process manifest file "${manifestFilePath}". ${error instanceof Error ? error.message : ''}`);
}
};
export const shouldCreateNewApp = async (flags) => {
if (flags.newApp || flags.appId || flags.appVersionId) {
return true;
}
const CREATE_NEW_APP = 'Create new app';
const IMPORT_TO_EXISTING_APP = 'Import to override an existing app';
const userChoice = await PromptService.promptList('How do you want to import your app', [IMPORT_TO_EXISTING_APP, CREATE_NEW_APP], IMPORT_TO_EXISTING_APP);
return userChoice === CREATE_NEW_APP;
};
export const shouldCreateNewAppVersion = async (flags) => {
if (flags.appVersionId || flags.newApp) {
return false;
}
const CREATE_NEW_VERSION = 'Create a new version';
const OVERRIDE_EXISTING_VERSION = 'Override an existing version';
const userChoice = await PromptService.promptList('How do you want to import your app', [OVERRIDE_EXISTING_VERSION, CREATE_NEW_VERSION], OVERRIDE_EXISTING_VERSION);
return userChoice === CREATE_NEW_VERSION;
};
export const uploadZippedManifest = async (buffer, options) => {
const { appId, appVersionId } = options || {};
if (appId) {
return updateAppFromManifest(buffer, appId, appVersionId);
}
return createAppFromManifest(buffer);
};
const updateAppFromManifest = async (buffer, appId, appVersionId) => {
const baseUrl = updateAppFromManifestUrl(appId);
const url = appsUrlBuilder(baseUrl);
const formData = new FormData();
formData.append('zipfile', new Blob([buffer]));
const response = await execute({
url,
headers: { Accept: 'application/json', 'Content-Type': 'multipart/form-data' },
method: HttpMethodTypes.PUT,
body: formData,
query: { ...(appVersionId && { appVersionId }) },
timeout: TIME_IN_MILLISECONDS.SECOND * 30,
});
return response;
};
const createAppFromManifest = async (buffer) => {
const baseUrl = createAppFromManifestUrl();
const url = appsUrlBuilder(baseUrl);
const formData = new FormData();
formData.append('zipfile', new Blob([buffer]));
const response = await execute({
url,
headers: { Accept: 'application/json', 'Content-Type': 'multipart/form-data' },
method: HttpMethodTypes.POST,
body: formData,
timeout: TIME_IN_MILLISECONDS.SECOND * 30,
});
return response;
};