Son CV dans un terminal web en Javascript!
https://terminal-cv.gregandev.fr
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
3.8 KiB
159 lines
3.8 KiB
// @flow
|
|
|
|
import type {ConfigResult, File, FilePath} from '@parcel/types';
|
|
import type {FileSystem} from '@parcel/fs';
|
|
import ThrowableDiagnostic from '@parcel/diagnostic';
|
|
import path from 'path';
|
|
import clone from 'clone';
|
|
import json5 from 'json5';
|
|
import {parse as toml} from '@iarna/toml';
|
|
import LRU from 'lru-cache';
|
|
|
|
export type ConfigOutput = {|
|
|
config: ConfigResult,
|
|
files: Array<File>,
|
|
|};
|
|
|
|
export type ConfigOptions = {|
|
|
parse?: boolean,
|
|
parser?: string => any,
|
|
|};
|
|
|
|
const configCache = new LRU<FilePath, ConfigOutput>({max: 500});
|
|
const resolveCache = new Map();
|
|
|
|
export function resolveConfig(
|
|
fs: FileSystem,
|
|
filepath: FilePath,
|
|
filenames: Array<FilePath>,
|
|
projectRoot: FilePath,
|
|
): Promise<?FilePath> {
|
|
// Cache the result of resolving config for this directory.
|
|
// This is automatically invalidated at the end of the current build.
|
|
let key = path.dirname(filepath) + filenames.join(',');
|
|
let cached = resolveCache.get(key);
|
|
if (cached !== undefined) {
|
|
return Promise.resolve(cached);
|
|
}
|
|
|
|
let resolved = fs.findAncestorFile(
|
|
filenames,
|
|
path.dirname(filepath),
|
|
projectRoot,
|
|
);
|
|
resolveCache.set(key, resolved);
|
|
return Promise.resolve(resolved);
|
|
}
|
|
|
|
export function resolveConfigSync(
|
|
fs: FileSystem,
|
|
filepath: FilePath,
|
|
filenames: Array<FilePath>,
|
|
projectRoot: FilePath,
|
|
): ?FilePath {
|
|
return fs.findAncestorFile(filenames, path.dirname(filepath), projectRoot);
|
|
}
|
|
|
|
export async function loadConfig(
|
|
fs: FileSystem,
|
|
filepath: FilePath,
|
|
filenames: Array<FilePath>,
|
|
projectRoot: FilePath,
|
|
opts: ?ConfigOptions,
|
|
): Promise<ConfigOutput | null> {
|
|
let parse = opts?.parse ?? true;
|
|
let configFile = await resolveConfig(fs, filepath, filenames, projectRoot);
|
|
if (configFile) {
|
|
let cachedOutput = configCache.get(String(parse) + configFile);
|
|
if (cachedOutput) {
|
|
return cachedOutput;
|
|
}
|
|
|
|
try {
|
|
let extname = path.extname(configFile).slice(1);
|
|
if (extname === 'js') {
|
|
let output = {
|
|
// $FlowFixMe
|
|
config: clone(require(configFile)),
|
|
files: [{filePath: configFile}],
|
|
};
|
|
|
|
configCache.set(configFile, output);
|
|
return output;
|
|
}
|
|
|
|
let configContent = await fs.readFile(configFile, 'utf8');
|
|
|
|
let config;
|
|
if (parse === false) {
|
|
config = configContent;
|
|
} else {
|
|
let parse = opts?.parser ?? getParser(extname);
|
|
try {
|
|
config = parse(configContent);
|
|
} catch (e) {
|
|
if (extname !== '' && extname !== 'json') {
|
|
throw e;
|
|
}
|
|
|
|
let pos = {
|
|
line: e.lineNumber,
|
|
column: e.columnNumber,
|
|
};
|
|
|
|
throw new ThrowableDiagnostic({
|
|
diagnostic: {
|
|
message: `Failed to parse ${path.basename(configFile)}`,
|
|
origin: '@parcel/utils',
|
|
codeFrames: [
|
|
{
|
|
language: 'json5',
|
|
filePath: configFile,
|
|
code: configContent,
|
|
codeHighlights: [
|
|
{
|
|
start: pos,
|
|
end: pos,
|
|
message: e.message,
|
|
},
|
|
],
|
|
},
|
|
],
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
let output = {
|
|
config,
|
|
files: [{filePath: configFile}],
|
|
};
|
|
|
|
configCache.set(String(parse) + configFile, output);
|
|
return output;
|
|
} catch (err) {
|
|
if (err.code === 'MODULE_NOT_FOUND' || err.code === 'ENOENT') {
|
|
return null;
|
|
}
|
|
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
loadConfig.clear = () => {
|
|
configCache.reset();
|
|
resolveCache.clear();
|
|
};
|
|
|
|
function getParser(extname) {
|
|
switch (extname) {
|
|
case 'toml':
|
|
return toml;
|
|
case 'json':
|
|
default:
|
|
return json5.parse;
|
|
}
|
|
}
|
|
|