Skip to content
This repository has been archived by the owner on Jun 12, 2023. It is now read-only.

Commit

Permalink
chore: utils
Browse files Browse the repository at this point in the history
  • Loading branch information
Zolyn committed Mar 20, 2022
1 parent 6e2bf04 commit adc8339
Showing 1 changed file with 80 additions and 18 deletions.
98 changes: 80 additions & 18 deletions src/core/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import fg from 'fast-glob';
import { dirname, join } from 'path';
import { existsSync, readFileSync } from 'fs';
import { resolveModule } from 'local-pkg';
import { dirname, extname, join } from 'path';
import { Alias, AliasOptions } from 'vite';
import { IImport } from './ast';

type Pkg = Partial<Record<'types' | 'typings', string>>;

/**
* Source: https://github.com/rollup/plugins/blob/master/packages/alias/src/index.ts
*/
Expand All @@ -14,32 +18,81 @@ export function matches(pattern: string | RegExp, importee: string) {
if (importee === pattern) return true;

const importeeStartsWithKey = importee.indexOf(pattern) === 0;
const importeeHasSlashAfterKey = importee.substring(pattern.length)[0] === '/';
const importeeHasSlashAfterKey = importee.slice(pattern.length)[0] === '/';
return importeeStartsWithKey && importeeHasSlashAfterKey;
}

// https://github.com/antfu/local-pkg/blob/main/index.mjs
function searchPackageJSON(dir: string): string | undefined {
let packageJsonPath;
while (true) {
if (!dir) return;
const newDir = dirname(dir);
if (newDir === dir) return;
// eslint-disable-next-line no-param-reassign
dir = newDir;
packageJsonPath = join(dir, 'package.json');
if (existsSync(packageJsonPath)) break;
}

return packageJsonPath;
}

export function resolvePath(path: string, from: string, aliases: ((AliasOptions | undefined) & Alias[]) | undefined) {
const matchedEntry = aliases?.find((entry) => matches(entry.find, path));

// Path which is using aliases. e.g. '~/types'
if (matchedEntry) return path.replace(matchedEntry.find, matchedEntry.replacement);

return join(dirname(from), path);
const resolved_path = resolveModule(path);

// Not a module. e.g. '../types'
if (!resolved_path) {
return join(dirname(from), path);
}

// Result is a typescript file. e.g. 'vue/macros-global.d.ts'
if (extname(resolved_path) === 'ts') {
return resolved_path;
}
// Not a typescript file, find declaration file
// The only situation is that the types are imported from the main entry. e.g. 'vue' -> 'vue/dist/vue.d.ts'
else {
const packageJsonPath = searchPackageJSON(resolved_path);

if (!packageJsonPath) {
return;
}

const { types, typings } = JSON.parse(readFileSync(packageJsonPath, 'utf-8')) as Pkg;

let result: string | undefined;

try {
// @ts-ignore
result = join(dirname(packageJsonPath), types || typings);
} catch {}

return result;
}
}

export async function resolveModulePath(
path: string,
from: string,
aliases: ((AliasOptions | undefined) & Alias[]) | undefined,
) {
const maybePath = resolvePath(path, from, aliases);
const files = await fg(
[
`${maybePath.replace(/\\/g, '/')}`,
`${maybePath.replace(/\\/g, '/')}*.+(ts|d.ts)`,
`${maybePath.replace(/\\/g, '/')}*/index.+(ts|d.ts)`,
],
{ onlyFiles: true },
);
const maybePath = resolvePath(path, from, aliases)?.replace(/\\/g, '/');

if (!maybePath) {
return null;
}

// console.log('MaybePath', maybePath.replace(/\\/g, '/'));

const files = await fg([`${maybePath}`, `${maybePath}*.+(ts|d.ts)`, `${maybePath}*/index.+(ts|d.ts)`], {
onlyFiles: true,
});

if (files.length > 0) return files[0];

Expand All @@ -58,9 +111,9 @@ export function groupImports(imports: IImport[]) {
}, {});
}

export function intersect(a: Array<any>, b: Array<any>) {
export function intersect<R = any>(a: Array<any>, b: Array<any>) {
const setB = new Set(b);
return [...new Set(a)].filter((x) => setB.has(x));
return [...new Set(a)].filter((x) => setB.has(x)) as R[];
}

export interface Replacement {
Expand All @@ -71,20 +124,21 @@ export interface Replacement {

/**
* Replace all items at specified indexes while keeping indexes relative during replacements.
* TODO: Still needs to be improved
*/
export function replaceAtIndexes(source: string, replacements: Replacement[]) {
export function replaceAtIndexes(source: string, replacements: Replacement[]): string {
let result = source;
let offset = 0;

for (const node of replacements) {
if (node.empty) {
// eslint-disable-next-line no-param-reassign
source = source.slice(0, node.start + offset) + source.slice(node.end + offset);
result = result.slice(0, node.start + offset) + result.slice(node.end + offset);

offset -= node.end - node.start;
}
}

return source;
return result;
}

export function getInterfaceCode(source: string): string | false {
Expand All @@ -110,3 +164,11 @@ export function mergeInterfaceCode(source: string): string | false {

return result;
}

/**
* Remove '\n' in the end of file
* TODO: Still needs to be improved
*/
export function removeAdditionalEscapeChar(source: string): string {
return source.slice(0, source.length - 1);
}

0 comments on commit adc8339

Please sign in to comment.