Urara-Blog/node_modules/.pnpm-store/v3/files/cd/7941b84f1d56aae070c6aff7642f91741a727e6bb8a29678ad2e33d1de567a9ad2160e1839e0300624870a594f89ad410bafd6fba810b6c98e7573cae73496
2022-08-14 01:14:53 +08:00

273 lines
6.9 KiB
Text

import fs__default from 'fs';
import path__default from 'path';
import { $ } from './index.js';
import { m as mkdirp, p as posixify } from './filesystem.js';
/** @type {Map<string, string>} */
const previous_contents = new Map();
/**
* @param {string} file
* @param {string} code
*/
function write_if_changed(file, code) {
if (code !== previous_contents.get(file)) {
write(file, code);
}
}
/**
* @param {string} file
* @param {string} code
*/
function write(file, code) {
previous_contents.set(file, code);
mkdirp(path__default.dirname(file));
fs__default.writeFileSync(file, code);
}
/** @param {string} str */
function trim(str) {
const indentation = /** @type {RegExpExecArray} */ (/\n?(\s*)/.exec(str))[1];
const pattern = new RegExp(`^${indentation}`, 'gm');
return str.replace(pattern, '').trim();
}
const reserved = new Set([
'do',
'if',
'in',
'for',
'let',
'new',
'try',
'var',
'case',
'else',
'enum',
'eval',
'null',
'this',
'true',
'void',
'with',
'await',
'break',
'catch',
'class',
'const',
'false',
'super',
'throw',
'while',
'yield',
'delete',
'export',
'import',
'public',
'return',
'static',
'switch',
'typeof',
'default',
'extends',
'finally',
'package',
'private',
'continue',
'debugger',
'function',
'arguments',
'interface',
'protected',
'implements',
'instanceof'
]);
const valid_identifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
/**
* @param {string} cwd
* @param {string} file
*/
function maybe_file(cwd, file) {
const resolved = path__default.resolve(cwd, file);
if (fs__default.existsSync(resolved)) {
return resolved;
}
}
/**
* @param {string} file
*/
function project_relative(file) {
return posixify(path__default.relative('.', file));
}
/**
* @param {string} file
*/
function remove_trailing_slashstar(file) {
if (file.endsWith('/*')) {
return file.slice(0, -2);
} else {
return file;
}
}
/**
* Writes the tsconfig that the user's tsconfig inherits from.
* @param {import('types').ValidatedKitConfig} config
*/
function write_tsconfig(config, cwd = process.cwd()) {
const out = path__default.join(config.outDir, 'tsconfig.json');
const user_file = maybe_file(cwd, 'tsconfig.json') || maybe_file(cwd, 'jsconfig.json');
if (user_file) validate(config, cwd, out, user_file);
/** @param {string} file */
const config_relative = (file) => posixify(path__default.relative(config.outDir, file));
const include = ['ambient.d.ts'];
for (const dir of [config.files.routes, config.files.lib]) {
const relative = project_relative(path__default.dirname(dir));
include.push(config_relative(`${relative}/**/*.js`));
include.push(config_relative(`${relative}/**/*.ts`));
include.push(config_relative(`${relative}/**/*.svelte`));
}
write_if_changed(
out,
JSON.stringify(
{
compilerOptions: {
// generated options
baseUrl: config_relative('.'),
paths: get_tsconfig_paths(config),
rootDirs: [config_relative('.'), './types'],
// essential options
// svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
// to enforce using \`import type\` instead of \`import\` for Types.
importsNotUsedAsValues: 'error',
// Vite compiles modules one at a time
isolatedModules: true,
// TypeScript doesn't know about import usages in the template because it only sees the
// script of a Svelte file. Therefore preserve all value imports. Requires TS 4.5 or higher.
preserveValueImports: true,
// This is required for svelte-kit package to work as expected
// Can be overwritten
lib: ['esnext', 'DOM', 'DOM.Iterable'],
moduleResolution: 'node',
module: 'esnext',
target: 'esnext'
},
include,
exclude: [config_relative('node_modules/**'), './[!ambient.d.ts]**']
},
null,
'\t'
)
);
}
/**
* @param {import('types').ValidatedKitConfig} config
* @param {string} cwd
* @param {string} out
* @param {string} user_file
*/
function validate(config, cwd, out, user_file) {
// we have to eval the file, since it's not parseable as JSON (contains comments)
const user_tsconfig_json = fs__default.readFileSync(user_file, 'utf-8');
const user_tsconfig = (0, eval)(`(${user_tsconfig_json})`);
// we need to check that the user's tsconfig extends the framework config
const extend = user_tsconfig.extends;
const extends_framework_config = extend && path__default.resolve(cwd, extend) === out;
const kind = path__default.basename(user_file);
if (extends_framework_config) {
const { paths: user_paths } = user_tsconfig.compilerOptions || {};
if (user_paths && fs__default.existsSync(config.files.lib)) {
/** @type {string[]} */
const lib = user_paths['$lib'] || [];
/** @type {string[]} */
const lib_ = user_paths['$lib/*'] || [];
const missing_lib_paths =
!lib.some((relative) => path__default.resolve(cwd, relative) === config.files.lib) ||
!lib_.some((relative) => path__default.resolve(cwd, relative) === path__default.join(config.files.lib, '/*'));
if (missing_lib_paths) {
console.warn(
$
.bold()
.yellow(`Your compilerOptions.paths in ${kind} should include the following:`)
);
const relative = posixify(path__default.relative('.', config.files.lib));
console.warn(`{\n "$lib":["${relative}"],\n "$lib/*":["${relative}/*"]\n}`);
}
}
} else {
let relative = posixify(path__default.relative('.', out));
if (!relative.startsWith('./')) relative = './' + relative;
console.warn(
$.bold().yellow(`Your ${kind} should extend the configuration generated by SvelteKit:`)
);
console.warn(`{\n "extends": "${relative}"\n}`);
}
}
// <something><optional /*>
const alias_regex = /^(.+?)(\/\*)?$/;
// <path><optional /* or .fileending>
const value_regex = /^(.*?)((\/\*)|(\.\w+))?$/;
/**
* Generates tsconfig path aliases from kit's aliases.
* Related to vite alias creation.
*
* @param {import('types').ValidatedKitConfig} config
*/
function get_tsconfig_paths(config) {
const alias = {
...config.alias
};
if (fs__default.existsSync(project_relative(config.files.lib))) {
alias['$lib'] = project_relative(config.files.lib);
}
/** @type {Record<string, string[]>} */
const paths = {};
for (const [key, value] of Object.entries(alias)) {
const key_match = alias_regex.exec(key);
if (!key_match) throw new Error(`Invalid alias key: ${key}`);
const value_match = value_regex.exec(value);
if (!value_match) throw new Error(`Invalid alias value: ${value}`);
const rel_path = project_relative(remove_trailing_slashstar(value));
const slashstar = key_match[2];
if (slashstar) {
paths[key] = [rel_path + '/*'];
} else {
paths[key] = [rel_path];
const fileending = value_match[4];
if (!fileending && !(key + '/*' in alias)) {
paths[key + '/*'] = [rel_path + '/*'];
}
}
}
return paths;
}
export { write as a, write_tsconfig as b, reserved as r, trim as t, valid_identifier as v, write_if_changed as w };