0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2025-01-27 22:19:04 -05:00

feat: show diff

This commit is contained in:
Florian Lefebvre 2024-08-24 18:14:10 +02:00
parent aab90cfb92
commit 537c4aeded
4 changed files with 62 additions and 27 deletions

View file

@ -1008,7 +1008,7 @@ async function askToContinue({ flags }: { flags: Flags }): Promise<boolean> {
return Boolean(response.askToContinue);
}
function getDiffContent(input: string, output: string): string | null {
export function getDiffContent(input: string, output: string): string | null {
let changes = [];
for (const change of diffWords(input, output)) {
let lines = change.value.trim().split('\n').slice(0, change.count);

View file

@ -7,13 +7,17 @@ import type { AstroSettings } from '../../types/astro.js';
import type { AstroConfig } from '../../types/public/config.js';
import { markdownContentEntryType } from '../../vite-plugin-markdown/content-entry-type.js';
import { getDefaultClientDirectives } from '../client-directive/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js';
import { AstroError, AstroErrorData, createSafeError } from '../errors/index.js';
import { formatYAMLException, isYAMLException } from '../errors/utils.js';
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from './../constants.js';
import { AstroTimer } from './timer.js';
import { loadTSConfig, type TSConfig } from './tsconfig.js';
import { GENERATED_TSCONFIG_PATH } from './constants.js';
import type { Logger } from '../logger/core.js';
import boxen from 'boxen';
import { formatErrorMessage } from '../messages.js';
import { collectErrorMetadata } from '../errors/dev/utils.js';
import { getDiffContent } from '../../cli/add/index.js';
export function createBaseSettings(config: AstroConfig): AstroSettings {
const { contentDir } = getContentPaths(config);
@ -144,33 +148,62 @@ export async function createSettings(
}
function validateTsconfig(settings: AstroSettings, logger: Logger, rawConfig: TSConfig) {
const { typescript } = settings.config.experimental;
if (!typescript) {
return;
}
try {
const { typescript } = settings.config.experimental;
if (!typescript) {
return;
}
// TODO: show diff each time before error (depends on https://github.com/withastro/astro/pull/11772)
if (!rawConfig.extends) {
throw new AstroError(AstroErrorData.TSConfigInvalidExtends);
} else if (
typeof rawConfig.extends === 'string' &&
rawConfig.extends !== GENERATED_TSCONFIG_PATH
) {
throw new AstroError(AstroErrorData.TSConfigInvalidExtends);
} else if (!rawConfig.extends.includes(GENERATED_TSCONFIG_PATH)) {
throw new AstroError(AstroErrorData.TSConfigInvalidExtends);
}
let newConfig = { ...rawConfig };
if (rawConfig.include) {
logger.warn(
'types',
`Your root "tsconfig.json" has an "include" field. This will break types, please move it to your Astro config experimental.typescript.include option`,
);
}
if (rawConfig.exclude) {
logger.warn(
'types',
`Your root "tsconfig.json" has an "exclude" field. This will break types, please move it to your Astro config experimental.typescript.exclude option`,
if (!rawConfig.extends) {
newConfig.extends = ['astro/tsconfigs/base', GENERATED_TSCONFIG_PATH];
throw createTsconfigError(logger, rawConfig, newConfig);
} else if (
typeof rawConfig.extends === 'string' &&
rawConfig.extends !== GENERATED_TSCONFIG_PATH
) {
newConfig.extends = [rawConfig.extends, GENERATED_TSCONFIG_PATH];
throw createTsconfigError(logger, rawConfig, newConfig);
} else if (!rawConfig.extends.includes(GENERATED_TSCONFIG_PATH)) {
newConfig.extends = [...rawConfig.extends, GENERATED_TSCONFIG_PATH];
throw createTsconfigError(logger, rawConfig, newConfig);
}
if (rawConfig.include) {
logger.warn(
'types',
`Your root "tsconfig.json" has an "include" field. This will break types, please move it to your Astro config experimental.typescript.include option`,
);
}
if (rawConfig.exclude) {
logger.warn(
'types',
`Your root "tsconfig.json" has an "exclude" field. This will break types, please move it to your Astro config experimental.typescript.exclude option`,
);
}
} catch (err) {
const error = createSafeError(err);
logger.error(
'config',
formatErrorMessage(collectErrorMetadata(error), logger.level() === 'debug') + '\n',
);
// Will return exit code 1 in CLI
throw error;
}
}
function createTsconfigError(logger: Logger, rawConfig: TSConfig, newConfig: TSConfig): AstroError {
const diff = getDiffContent(
JSON.stringify(rawConfig, null, 2),
JSON.stringify(newConfig, null, 2),
)!;
const message = `\n${boxen(diff, {
margin: 0.5,
padding: 0.5,
borderStyle: 'round',
title: 'tsconfig.json',
})}\n`;
logger.info('SKIP_FORMAT', message);
return new AstroError(AstroErrorData.TSConfigInvalidExtends);
}

View file

@ -10,6 +10,7 @@ import {
} from 'tsconfck';
import type { CompilerOptions, TypeAcquisition } from 'typescript';
// TODO: update when experimental.typescript is out of experimental
export const defaultTSConfig: TSConfig = { extends: 'astro/tsconfigs/base' };
export type frameworkWithTSSettings = 'vue' | 'react' | 'preact' | 'solid-js';

View file

@ -1310,6 +1310,7 @@ export const UnknownFilesystemError = {
export const TSConfigInvalidExtends = {
name: 'TSConfigInvalidExtends',
title: 'Your `tsconfig.json` `extends` property is invalid',
message: 'Your `tsconfig.json` `extends` property is invalid',
hint: 'Check out what change you need to make in the terminal above.',
} satisfies ErrorData;