astro-ghostcms/.pnpm-store/v3/files/7a/334cb997c32b80a3171cc158c00...

297 lines
9.5 KiB
Plaintext

import { bgGreen, black, bold, dim, yellow } from "kleur/colors";
import { fileURLToPath } from "node:url";
import dlv from "dlv";
import { resolveConfig } from "../../core/config/config.js";
import { createSettings } from "../../core/config/settings.js";
import * as msg from "../../core/messages.js";
import { DEFAULT_PREFERENCES } from "../../preferences/defaults.js";
import { coerce, isValidKey } from "../../preferences/index.js";
import { createLoggerFromFlags, flagsToAstroInlineConfig } from "../flags.js";
import { flattie } from "flattie";
import { formatWithOptions } from "node:util";
import { collectErrorMetadata } from "../../core/errors/dev/utils.js";
const PREFERENCES_SUBCOMMANDS = [
"get",
"set",
"enable",
"disable",
"delete",
"reset",
"list"
];
function isValidSubcommand(subcommand) {
return PREFERENCES_SUBCOMMANDS.includes(subcommand);
}
async function preferences(subcommand, key, value, { flags }) {
if (!isValidSubcommand(subcommand) || flags?.help || flags?.h) {
msg.printHelp({
commandName: "astro preferences",
usage: "[command]",
tables: {
Commands: [
["list", "Pretty print all current preferences"],
["list --json", "Log all current preferences as a JSON object"],
["get [key]", "Log current preference value"],
["set [key] [value]", "Update preference value"],
["reset [key]", "Reset preference value to default"],
["enable [key]", "Set a boolean preference to true"],
["disable [key]", "Set a boolean preference to false"]
],
Flags: [
[
"--global",
"Scope command to global preferences (all Astro projects) rather than the current project"
]
]
}
});
return 0;
}
const inlineConfig = flagsToAstroInlineConfig(flags);
const logger = createLoggerFromFlags(flags);
const { astroConfig } = await resolveConfig(inlineConfig ?? {}, "dev");
const settings = await createSettings(astroConfig, fileURLToPath(astroConfig.root));
const opts = {
location: flags.global ? "global" : void 0,
json: flags.json
};
if (subcommand === "list") {
return listPreferences(settings, opts);
}
if (subcommand === "enable" || subcommand === "disable") {
key = `${key}.enabled`;
}
if (!isValidKey(key)) {
logger.error("preferences", `Unknown preference "${key}"
`);
return 1;
}
if (subcommand === "set" && value === void 0) {
const type = typeof dlv(DEFAULT_PREFERENCES, key);
console.error(
msg.formatErrorMessage(
collectErrorMetadata(new Error(`Please provide a ${type} value for "${key}"`)),
true
)
);
return 1;
}
switch (subcommand) {
case "get":
return getPreference(settings, key, opts);
case "set":
return setPreference(settings, key, value, opts);
case "reset":
case "delete":
return resetPreference(settings, key, opts);
case "enable":
return enablePreference(settings, key, opts);
case "disable":
return disablePreference(settings, key, opts);
}
}
async function getPreference(settings, key, { location = "project" }) {
try {
let value = await settings.preferences.get(key, { location });
if (value && typeof value === "object" && !Array.isArray(value)) {
if (Object.keys(value).length === 0) {
value = dlv(DEFAULT_PREFERENCES, key);
console.log(msg.preferenceDefaultIntro(key));
}
prettyPrint({ [key]: value });
return 0;
}
if (value === void 0) {
const defaultValue = await settings.preferences.get(key);
console.log(msg.preferenceDefault(key, defaultValue));
return 0;
}
console.log(msg.preferenceGet(key, value));
return 0;
} catch {
}
return 1;
}
async function setPreference(settings, key, value, { location }) {
try {
const defaultType = typeof dlv(DEFAULT_PREFERENCES, key);
if (typeof coerce(key, value) !== defaultType) {
throw new Error(`${key} expects a "${defaultType}" value!`);
}
await settings.preferences.set(key, coerce(key, value), { location });
console.log(msg.preferenceSet(key, value));
return 0;
} catch (e) {
if (e instanceof Error) {
console.error(msg.formatErrorMessage(collectErrorMetadata(e), true));
return 1;
}
throw e;
}
}
async function enablePreference(settings, key, { location }) {
try {
await settings.preferences.set(key, true, { location });
console.log(msg.preferenceEnabled(key.replace(".enabled", "")));
return 0;
} catch {
}
return 1;
}
async function disablePreference(settings, key, { location }) {
try {
await settings.preferences.set(key, false, { location });
console.log(msg.preferenceDisabled(key.replace(".enabled", "")));
return 0;
} catch {
}
return 1;
}
async function resetPreference(settings, key, { location }) {
try {
await settings.preferences.set(key, void 0, { location });
console.log(msg.preferenceReset(key));
return 0;
} catch {
}
return 1;
}
function annotate(flat, annotation) {
return Object.fromEntries(
Object.entries(flat).map(([key, value]) => [key, { annotation, value }])
);
}
function userValues(flatDefault, flatProject, flatGlobal) {
const result = {};
for (const key of Object.keys(flatDefault)) {
if (key in flatProject) {
result[key] = {
value: flatProject[key],
annotation: ""
};
if (key in flatGlobal) {
result[key].annotation += ` (also modified globally)`;
}
} else if (key in flatGlobal) {
result[key] = { value: flatGlobal[key], annotation: "(global)" };
}
}
return result;
}
async function listPreferences(settings, { location, json }) {
if (json) {
const resolved = await settings.preferences.getAll();
console.log(JSON.stringify(resolved, null, 2));
return 0;
}
const { global, project, fromAstroConfig, defaults } = await settings.preferences.list({
location
});
const flatProject = flattie(project);
const flatGlobal = flattie(global);
const flatDefault = flattie(defaults);
const flatUser = userValues(flatDefault, flatProject, flatGlobal);
const userKeys = Object.keys(flatUser);
if (userKeys.length > 0) {
const badge = bgGreen(black(` Your Preferences `));
const table = formatTable(flatUser, ["Preference", "Value"]);
console.log(["", badge, table].join("\n"));
} else {
const badge = bgGreen(black(` Your Preferences `));
const message = dim("No preferences set");
console.log(["", badge, "", message].join("\n"));
}
const flatUnset = annotate(Object.assign({}, flatDefault), "");
for (const key of userKeys) {
delete flatUnset[key];
}
const unsetKeys = Object.keys(flatUnset);
if (unsetKeys.length > 0) {
const badge = bgGreen(black(` Default Preferences `));
const table = formatTable(flatUnset, ["Preference", "Value"]);
console.log(["", badge, table].join("\n"));
} else {
const badge = bgGreen(black(` Default Preferences `));
const message = dim("All preferences have been set");
console.log(["", badge, "", message].join("\n"));
}
if (fromAstroConfig.devToolbar?.enabled === false && flatUser["devToolbar.enabled"]?.value !== false) {
console.log(
yellow(
"The dev toolbar is currently disabled. To enable it, set devToolbar: {enabled: true} in your astroConfig file."
)
);
}
return 0;
}
function prettyPrint(value) {
const flattened = flattie(value);
const table = formatTable(flattened, ["Preference", "Value"]);
console.log(table);
}
const chars = {
h: "\u2500",
hThick: "\u2501",
hThickCross: "\u253F",
v: "\u2502",
vRight: "\u251C",
vRightThick: "\u251D",
vLeft: "\u2524",
vLeftThick: "\u2525",
hTop: "\u2534",
hBottom: "\u252C",
topLeft: "\u256D",
topRight: "\u256E",
bottomLeft: "\u2570",
bottomRight: "\u256F"
};
function annotatedFormat(mv) {
return mv.annotation ? `${mv.value} ${mv.annotation}` : mv.value.toString();
}
function formatAnnotated(mv, style = (v) => v.toString()) {
return mv.annotation ? `${style(mv.value)} ${dim(mv.annotation)}` : style(mv.value);
}
function formatTable(object, columnLabels) {
const [colA, colB] = columnLabels;
const colALength = [colA, ...Object.keys(object)].reduce(longest, 0) + 3;
const colBLength = [colB, ...Object.values(object).map(annotatedFormat)].reduce(longest, 0) + 3;
function formatRow(i2, a, b, style = (v) => v.toString()) {
return `${dim(chars.v)} ${style(a)} ${space(colALength - a.length - 2)} ${dim(
chars.v
)} ${formatAnnotated(b, style)} ${space(colBLength - annotatedFormat(b).length - 3)} ${dim(
chars.v
)}`;
}
const top = dim(
`${chars.topLeft}${chars.h.repeat(colALength + 1)}${chars.hBottom}${chars.h.repeat(
colBLength
)}${chars.topRight}`
);
const bottom = dim(
`${chars.bottomLeft}${chars.h.repeat(colALength + 1)}${chars.hTop}${chars.h.repeat(
colBLength
)}${chars.bottomRight}`
);
const divider = dim(
`${chars.vRightThick}${chars.hThick.repeat(colALength + 1)}${chars.hThickCross}${chars.hThick.repeat(colBLength)}${chars.vLeftThick}`
);
const rows = [top, formatRow(-1, colA, { value: colB, annotation: "" }, bold), divider];
let i = 0;
for (const [key, value] of Object.entries(object)) {
rows.push(formatRow(i, key, value, (v) => formatWithOptions({ colors: true }, v)));
i++;
}
rows.push(bottom);
return rows.join("\n");
}
function space(len) {
return " ".repeat(len);
}
const longest = (a, b) => {
const { length: len } = b.toString();
return a > len ? a : len;
};
export {
preferences
};