Skip to content
This repository has been archived by the owner on Jan 13, 2024. It is now read-only.

Commit

Permalink
TypeScript Rewrite (#1099)
Browse files Browse the repository at this point in the history
  • Loading branch information
hipstersmoothie committed Apr 1, 2021
1 parent b7426da commit 6deb812
Show file tree
Hide file tree
Showing 27 changed files with 1,908 additions and 1,039 deletions.
44 changes: 29 additions & 15 deletions .eslintrc
@@ -1,18 +1,9 @@
{
"extends": [
"airbnb-base",
"prettier"
],
"parser": "@babel/eslint-parser",
"parserOptions": {
"sourceType": "module",
"requireConfigFile": false
},
"extends": ["airbnb-base", "prettier"],
"rules": {
"wrap-iife": "off",
"no-bitwise": "off",
"no-continue": "off",
"class-methods-use-this": "off",
"no-nested-ternary": "off",
"no-await-in-loop": "off",
"no-constant-condition": "off",
"no-param-reassign": "off",
Expand All @@ -22,13 +13,36 @@
"camelcase": "off"
},
"overrides": [
{
"files": ["*.ts"],
"extends": ["plugin:@typescript-eslint/recommended", "prettier"],
"parser": "@typescript-eslint/parser",
"settings": {
"import/resolver": {
"typescript": {}
}
},
"rules": {
"@typescript-eslint/explicit-module-boundary-types": "off",
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never"
}
]
}
},
{
"files": ["prelude/**/*"],
"rules": {
"strict": "off"
},
}
, {
}
},
{
"files": ["test/**/*"],
"rules": {
"array-callback-return": "off",
Expand Down Expand Up @@ -57,5 +71,5 @@
"strict": ["error", "global"]
}
}
]
]
}
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Expand Up @@ -33,10 +33,10 @@ jobs:

- name: Lint
if: matrix['node-version'] == '14.x' && matrix['os'] == 'ubuntu-latest'
run: yarn run lint
run: yarn lint

- name: Build
run: yarn run babel
run: yarn build

- name: Test
run: yarn run test
run: yarn test
3 changes: 2 additions & 1 deletion .gitignore
Expand Up @@ -19,4 +19,5 @@ examples/express/node_modules

# Editors
.vscode/
yarn-error.log
yarn-error.log
tsconfig.tsbuildinfo
File renamed without changes.
8 changes: 6 additions & 2 deletions lib/chmod.js → lib/chmod.ts
@@ -1,9 +1,13 @@
import { chmod, stat } from 'fs-extra';

export async function plusx(file) {
export async function plusx(file: string) {
const s = await stat(file);
const newMode = s.mode | 64 | 8 | 1;
if (s.mode === newMode) return;

if (s.mode === newMode) {
return;
}

const base8 = newMode.toString(8).slice(-3);
await chmod(file, base8);
}
282 changes: 282 additions & 0 deletions lib/common.ts
@@ -0,0 +1,282 @@
import assert from 'assert';
import fs from 'fs';
import path from 'path';

export const STORE_BLOB = 0;
export const STORE_CONTENT = 1;
export const STORE_LINKS = 2;
export const STORE_STAT = 3;
export const ALIAS_AS_RELATIVE = 0; // require("./file.js") // file or directory
export const ALIAS_AS_RESOLVABLE = 1; // require("package")

const win32 = process.platform === 'win32';
const hasURL = typeof URL !== 'undefined';

function uppercaseDriveLetter(f: string) {
if (f.slice(1, 3) !== ':\\') return f;
return f[0].toUpperCase() + f.slice(1);
}

function removeTrailingSlashes(f: string) {
if (f === '/') {
return f; // dont remove from "/"
}

if (f.slice(1) === ':\\') {
return f; // dont remove from "D:\"
}

let last = f.length - 1;

while (true) {
const char = f.charAt(last);

if (char === '\\') {
f = f.slice(0, -1);
last -= 1;
} else if (char === '/') {
f = f.slice(0, -1);
last -= 1;
} else {
break;
}
}
return f;
}

const isUrl = (p: unknown): p is URL => hasURL && p instanceof URL;

export function isRootPath(p: string | URL | Buffer) {
let file = Buffer.isBuffer(p) ? p.toString() : isUrl(p) ? p.pathname : p;

if (file === '.') {
file = path.resolve(file);
}

return path.dirname(file) === p;
}

export function normalizePath(f: string | URL | Buffer) {
if (win32) {
let file = Buffer.isBuffer(f)
? f.toString()
: isUrl(f)
? f.pathname.replace(/^\//, '')
: f;

if (!/^.:$/.test(file)) {
file = path.normalize(file);
} // 'c:' -> 'c:.'

file = uppercaseDriveLetter(file);

return removeTrailingSlashes(file);
}

let file = Buffer.isBuffer(f) ? f.toString() : isUrl(f) ? f.pathname : f;

if (!/^.:$/.test(file)) {
file = path.normalize(file);
} // 'c:' -> 'c:.'

return removeTrailingSlashes(file);
}

export function isPackageJson(file: string) {
return path.basename(file) === 'package.json';
}

export function isDotJS(file: string) {
return path.extname(file) === '.js';
}

export function isDotJSON(file: string) {
return path.extname(file) === '.json';
}

export function isDotNODE(file: string) {
return path.extname(file) === '.node';
}

function replaceSlashes(file: string, slash: string) {
if (/^.:\\/.test(file)) {
if (slash === '/') {
return file.slice(2).replace(/\\/g, '/');
}
} else if (/^\//.test(file)) {
if (slash === '\\') {
return `C:${file.replace(/\//g, '\\')}`;
}
}

return file;
}

function injectSnapshot(file: string) {
if (/^.:\\/.test(file)) {
// C:\path\to
if (file.length === 3) {
// C:\
file = file.slice(0, -1);
}

return `${file[0]}:\\snapshot${file.slice(2)}`;
}

if (/^\//.test(file)) {
// /home/user/project
if (file.length === 1) {
// /
file = file.slice(0, -1);
}

return `/snapshot${file}`;
}

return file;
}

function longestCommonLength(s1: string, s2: string) {
const length = Math.min(s1.length, s2.length);

for (let i = 0; i < length; i += 1) {
if (s1.charCodeAt(i) !== s2.charCodeAt(i)) {
return i;
}
}

return length;
}

function withoutNodeModules(file: string) {
return file.split(`${path.sep}node_modules${path.sep}`)[0];
}

export function retrieveDenominator(files: string[]) {
assert(files.length > 0);

let s1 = withoutNodeModules(files[0]) + path.sep;

for (let i = 1; i < files.length; i += 1) {
const s2 = withoutNodeModules(files[i]) + path.sep;
s1 = s1.slice(0, longestCommonLength(s1, s2));
}

if (s1 === '') {
return win32 ? 2 : 0;
}

return s1.lastIndexOf(path.sep);
}

export function substituteDenominator(f: string, denominator: number) {
const rootLength = win32 ? 2 : 0;
return f.slice(0, rootLength) + f.slice(denominator);
}

export function snapshotify(file: string, slash: string) {
return injectSnapshot(replaceSlashes(file, slash));
}

export function insideSnapshot(f: Buffer | string | URL) {
if (win32) {
if (Buffer.isBuffer(f)) {
f = f.toString();
}

if (hasURL && f instanceof URL) {
f = f.pathname.replace(/^\//, '');
}

if (typeof f !== 'string') {
return false;
}

const slice112 = f.slice(1, 12);

return (
slice112 === ':\\snapshot\\' ||
slice112 === ':/snapshot\\' ||
slice112 === ':\\snapshot/' ||
slice112 === ':/snapshot/' ||
slice112 === ':\\snapshot' ||
slice112 === ':/snapshot'
);
}

if (Buffer.isBuffer(f)) {
f = f.toString();
}

if (hasURL && f instanceof URL) {
f = f.pathname;
}

if (typeof f !== 'string') {
return false;
}

const slice010 = f.slice(0, 10);

return slice010 === '/snapshot/' || slice010 === '/snapshot';
}

export function stripSnapshot(f: string) {
const file = normalizePath(f);

if (/^.:\\snapshot$/.test(file)) {
return `${file[0]}:\\**\\`;
}

if (/^.:\\snapshot\\/.test(file)) {
return `${file[0]}:\\**${file.slice(11)}`;
}

if (/^\/snapshot$/.test(file)) {
return '/**/';
}

if (/^\/snapshot\//.test(file)) {
return `/**${file.slice(9)}`;
}

return f; // not inside
}

export function removeUplevels(f: string) {
if (win32) {
while (true) {
if (f.slice(0, 3) === '..\\') {
f = f.slice(3);
} else if (f === '..') {
f = '.';
} else {
break;
}
}

return f;
}

while (true) {
if (f.slice(0, 3) === '../') {
f = f.slice(3);
} else if (f === '..') {
f = '.';
} else {
break;
}
}

return f;
}

export function toNormalizedRealPath(requestPath: string) {
const file = normalizePath(requestPath);

if (fs.existsSync(file)) {
return fs.realpathSync(file);
}

return file;
}

0 comments on commit 6deb812

Please sign in to comment.