Skip to content

Commit

Permalink
chore(preferences): finalize TODOs
Browse files Browse the repository at this point in the history
  • Loading branch information
natemoo-re committed Nov 29, 2023
1 parent dc56ae7 commit 7a8b40a
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 22 deletions.
66 changes: 46 additions & 20 deletions packages/astro/src/cli/preferences/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,20 @@
import type yargs from 'yargs-parser';
import type { AstroSettings } from '../../@types/astro.js';

import { cyan, bold } from 'kleur/colors';
import { bold } from 'kleur/colors';
import { fileURLToPath } from 'node:url';

import * as msg from '../../core/messages.js';
import { createLoggerFromFlags, flagsToAstroInlineConfig } from '../flags.js';
import { resolveConfig } from '../../core/config/config.js';
import { createSettings } from '../../core/config/settings.js';
import { isValidKey, type PreferenceKey } from '../../preferences/index.js';
import { coerce, isValidKey, type PreferenceKey } from '../../preferences/index.js';
import { DEFAULT_PREFERENCES } from '../../preferences/defaults.js';
import dlv from 'dlv';
// @ts-expect-error flattie types are mispackaged
import { flattie } from 'flattie';
import { formatWithOptions } from 'node:util';
import { collectErrorMetadata } from '../../core/errors/dev/utils.js';

interface PreferencesOptions {
flags: yargs.Arguments;
Expand All @@ -31,16 +32,21 @@ export async function preferences(subcommand: string, key: string, value: string
if (!isValidSubcommand(subcommand) || flags?.help || flags?.h) {
msg.printHelp({
commandName: 'astro preferences',
usage: 'set [key] [:value]',
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', 'Change setting value globally.'],
['--help (-h)', 'See all available flags.'],
['--global', 'Scope command to global preferences (all Astro projects) rather than the current project'],
],
},
description: `Starts a local server to serve your static dist/ directory. Check ${cyan(
'https://docs.astro.build/en/reference/cli-reference/#astro-preview'
)} for more information.`,
});
return 0;
}
Expand Down Expand Up @@ -69,8 +75,7 @@ export async function preferences(subcommand: string, key: string, value: string

if (subcommand === 'set' && value === undefined) {
const type = typeof dlv(DEFAULT_PREFERENCES, key);
// TODO: better error message
logger.error('preferences', `Please provide a ${type} value for "${key}"\n`);
console.error(msg.formatErrorMessage(collectErrorMetadata(new Error(`Please provide a ${type} value for "${key}"`))));
return 1;
}

Expand All @@ -92,26 +97,43 @@ interface SubcommandOptions {
// Default `location` to "project" to avoid reading default preferencesa
async function getPreference(settings: AstroSettings, key: PreferenceKey, { location = 'project' }: SubcommandOptions) {
try {
const value = await settings.preferences.get(key, { location });
// TODO: guard against printing objects
if (value !== undefined) {
console.log(msg.preferenceGet(key, value));
} else {
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 === undefined) {
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: AstroSettings, key: PreferenceKey, value: unknown, { location }: SubcommandOptions) {
try {
await settings.preferences.set(key, value as any, { location });
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 {}
return 1;
} catch (e) {
if (e instanceof Error) {
console.error(msg.formatErrorMessage(collectErrorMetadata(e)));
return 1;
}
throw e;
}
}

async function enablePreference(settings: AstroSettings, key: PreferenceKey, { location }: SubcommandOptions) {
Expand Down Expand Up @@ -148,10 +170,14 @@ async function listPreferences(settings: AstroSettings, { location, json }: Subc
console.log(JSON.stringify(store, null, 2));
return 0;
}
const flattened = flattie(store);
prettyPrint(store);
return 0;
}

function prettyPrint(value: Record<string, string | number | boolean>) {
const flattened = flattie(value);
const table = formatTable(flattened, ['Preference', 'Value']);
console.log(table);
return 0;
}

const chars = {
Expand Down
4 changes: 4 additions & 0 deletions packages/astro/src/core/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ export function preferenceGet(name: string, value: any) {
return `${green('◉')} ${name} is set to ${bgGreen(black(` ${JSON.stringify(value)} `))}\n`;
}

export function preferenceDefaultIntro(name: string) {
return `${yellow('◯')} ${name} has not been set. It defaults to\n`;
}

export function preferenceDefault(name: string, value: any) {
return `${yellow('◯')} ${name} has not been set. It defaults to ${bgYellow(black(` ${JSON.stringify(value)} `))}\n`;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/astro/src/preferences/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export interface AstroPreferences {
export function isValidKey(key: string): key is PreferenceKey {
return dget(DEFAULT_PREFERENCES, key) !== undefined;
}
export function coerce(key: string, value: string | number) {
export function coerce(key: string, value: unknown) {
const type = typeof dget(DEFAULT_PREFERENCES, key);
switch (type) {
case 'string': return value;
Expand All @@ -43,7 +43,7 @@ export function coerce(key: string, value: string | number) {
if (value === 'false' || value === 0) return false;
}
}
throw new Error(`Unable to convert "${value}" to a ${type} for "${key}".`)
return value as any;
}

export default function createPreferences(config: AstroConfig): AstroPreferences {
Expand Down

0 comments on commit 7a8b40a

Please sign in to comment.