UNPKG

constatic

Version:

Constatic is a CLI for creating and managing modern TypeScript projects, providing an organized structure and features that streamline development.

317 lines (316 loc) 10.2 kB
// src/menus/main/presets/scripts/actions/modify.ts import { divider, fetchNpmPackage, instructions, log, searchSelect, sleep, theme, uiMessage, withDefaults } from "#helpers"; import { packageJsonHasDeps } from "#shared/presets/scripts/deps.js"; import { checkbox, input, select, Separator } from "@inquirer/prompts"; import ck from "chalk"; import ora from "ora"; import { glob } from "tinyglobby"; import { formatPresetFiles } from "./format.js"; import { printPreview } from "./preview.js"; async function modifyScriptPresetMenu(_cli, preset, existing = false) { let status = "progress"; const queryFiles = async (term) => { if (!term) return formatPresetFiles(preset.files); return formatPresetFiles(preset.files.filter(({ path, dist = path }) => dist.startsWith(term) || dist.endsWith(term) || dist.includes(term))); }; while (status === "progress") { const hasFiles = preset.files.length > 0; const hasDeps = packageJsonHasDeps(preset.packageJson ?? {}); const disabled = !hasFiles && !hasDeps ? " " : false; const action = await select(withDefaults({ message: uiMessage({ "pt-BR": "❑ Nova predefinições de script", "en-US": "❑ New script preset" }, ck.reset.cyan.underline), choices: [ existing ? { name: uiMessage({ "en-US": "✎ Edit name", "pt-BR": "✎ Editar nome" }, ck.blue), value: "name" } : null, { name: uiMessage({ "en-US": "✎ Edit alias", "pt-BR": "✎ Editar alias" }, ck.blue), value: "alias" }, { name: uiMessage({ "en-US": "\uD83D\uDDD0 Select files", "pt-BR": "\uD83D\uDDD0 Selecionar arquivos" }, ck.green), value: "select" }, hasFiles && { name: uiMessage({ "en-US": "✗ Remove files", "pt-BR": "✗ Remover arquivos" }, ck.redBright), value: "rm" }, { name: uiMessage({ "en-US": "☶ Add dependencies", "pt-BR": "☶ Adicionar dependências" }, ck.green), value: "deps" }, hasDeps && { name: uiMessage({ "en-US": "✗ Remove dependencies", "pt-BR": "✗ Remover dependências" }, ck.redBright), value: "uninstall" }, { name: uiMessage({ "en-US": "⦿ Preview", "pt-BR": "⦿ Previsualizar" }, ck.green), value: "preview", disabled }, { name: uiMessage({ "en-US": "↯ Save", "pt-BR": "↯ Salvar" }, ck.green), value: "save", disabled }, { name: uiMessage({ "pt-BR": "⤶ Cancelar", "en-US": "⤶ Cancel" }, ck.red), value: "cancel" } ].filter((choice) => !!choice), pageSize: 10 })); divider(); switch (action) { case "name": { preset.name = await input(withDefaults({ message: uiMessage({ "en-US": "Preset name", "pt-BR": "Nome da predefinição" }), required: true })); divider(); continue; } case "alias": { preset.alias = await input(withDefaults({ message: uiMessage({ "en-US": "Preset alias", "pt-BR": "Alias da predefinição" }), required: true })); divider(); continue; } case "select": { const filepaths = await glob([ "./**", "!**/node_modules/**" ]); const files = await searchSelect(withDefaults({ message: uiMessage({ "en-US": "Select the files you want", "pt-BR": "Selecione os arquivos que deseja" }), theme: theme.searchSelect, async options(term) { const format = (value) => ({ name: value, value }); if (!term) return filepaths.map(format); return filepaths.filter((filepath) => filepath.startsWith(term) || filepath.endsWith(term) || filepath.includes(term)).map(format); }, instructions: instructions.searchSelect })); const filtered = files.filter((filepath) => !preset.files.some((p) => p.path === filepath)); preset.files.push(...filtered.map((p) => ({ path: p, dist: p }))); continue; } case "rm": { const files = await searchSelect(withDefaults({ message: uiMessage({ "en-US": "Select the files you want delete", "pt-BR": "Selecione os arquivos que deseja deletar" }), options: queryFiles })); divider(); preset.files = preset.files.filter(({ path, dist = path }) => !files.includes(dist)); continue; } case "deps": { const name = await input(withDefaults({ message: uiMessage({ "en-US": "Enter the dependency name:", "pt-BR": "Insira o nome da dependência:" }), required: true })); const loading = ora({ text: uiMessage({ "en-US": "Fetching package", "pt-BR": "Buscando pacote" }) }).start(); const result = await fetchNpmPackage(name); loading.stop(); divider(); if (!result.success) { log.error(result.error); await sleep(300); continue; } const packageName = result.data.name; const version = result.data.selectedVersion; log.success(uiMessage({ "en-US": `Package ${packageName} / version: ${version}`, "pt-BR": `Pacote ${packageName} / versão: ${version}` })); divider(); const type = await select(withDefaults({ message: uiMessage({ "pt-BR": "Selecione o tipo de dependência", "en-US": "Select the type of dependency" }), choices: [ { name: uiMessage({ "en-US": "Production dependency", "pt-BR": "Dependência de produção" }, ck.green), value: "dependencies" }, { name: uiMessage({ "en-US": "Development dependency", "pt-BR": "Dependência de desenvolvimento" }, ck.green), value: "devDependencies" } ] })); divider(); preset.packageJson ??= {}; preset.packageJson[type] ??= {}; preset.packageJson[type][packageName] = version; log.success(uiMessage({ "en-US": `Dependency successfully added to preset`, "pt-BR": `Dependência adicionada com sucesso à predefinição` })); divider(); continue; } case "uninstall": { const { dependencies, devDependencies } = preset.packageJson ?? {}; const choices = []; if (dependencies) { choices.push(new Separator(ck.dim("dependencies")), ...Object.entries(dependencies).map(([name, version]) => ({ name: `${name}@${version}`, value: name }))); } if (devDependencies) { choices.push(new Separator(ck.dim("devDependencies")), ...Object.entries(devDependencies).map(([name, version]) => ({ name: `${name}@${version}`, value: name }))); } const deps = await checkbox({ message: uiMessage({ "en-US": `Select the dependencies you want to remove`, "pt-BR": `Selecione as dependências que deseja remover` }), choices, instructions: instructions.checkbox }); divider(); for (const key in preset.packageJson?.dependencies ?? {}) { if (deps.includes(key)) { delete (preset.packageJson?.dependencies ?? {})[key]; } } for (const key in preset.packageJson?.devDependencies ?? {}) { if (deps.includes(key)) { delete (preset.packageJson?.devDependencies ?? {})[key]; } } continue; } case "preview": { printPreview(preset); divider(); await sleep(400); continue; } case "save": { if (!preset.files.length && !preset.packageJson) { log.error(uiMessage({ "en-US": `You need to add files and/or dependencies to create a preset.`, "pt-BR": `É necessário adicionar arquivos e/ou dependendências para criar uma predefinição` })); divider(); await sleep(400); continue; } printPreview(preset); divider(); const action2 = await select(withDefaults({ message: uiMessage({ "pt-BR": `❑ Salvar predefinições de script`, "en-US": "❑ Save script preset" }, ck.reset.cyan.underline), choices: [ { name: uiMessage({ "en-US": "↪ Continue to save", "pt-BR": "↪ Continuar para salvar" }, ck.green), value: "continue" }, { name: uiMessage({ "en-US": "✎ Back to edit", "pt-BR": "✎ Voltar a edição" }, ck.blue), value: "back" }, { name: uiMessage({ "pt-BR": "⤶ Cancelar", "en-US": "⤶ Cancel" }, ck.red), value: "cancel" } ] })); divider(); if (action2 === "cancel") { status = action2; break; } if (action2 === "back") continue; status = "save"; break; } case "cancel": { status = action; continue; } } } return status; } export { modifyScriptPresetMenu };