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

Commit 6deb812

Browse files
TypeScript Rewrite (#1099)
1 parent b7426da commit 6deb812

27 files changed

+1908
-1039
lines changed

.eslintrc

+29-15
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,9 @@
11
{
2-
"extends": [
3-
"airbnb-base",
4-
"prettier"
5-
],
6-
"parser": "@babel/eslint-parser",
7-
"parserOptions": {
8-
"sourceType": "module",
9-
"requireConfigFile": false
10-
},
2+
"extends": ["airbnb-base", "prettier"],
113
"rules": {
12-
"wrap-iife": "off",
134
"no-bitwise": "off",
145
"no-continue": "off",
15-
"class-methods-use-this": "off",
6+
"no-nested-ternary": "off",
167
"no-await-in-loop": "off",
178
"no-constant-condition": "off",
189
"no-param-reassign": "off",
@@ -22,13 +13,36 @@
2213
"camelcase": "off"
2314
},
2415
"overrides": [
16+
{
17+
"files": ["*.ts"],
18+
"extends": ["plugin:@typescript-eslint/recommended", "prettier"],
19+
"parser": "@typescript-eslint/parser",
20+
"settings": {
21+
"import/resolver": {
22+
"typescript": {}
23+
}
24+
},
25+
"rules": {
26+
"@typescript-eslint/explicit-module-boundary-types": "off",
27+
"import/extensions": [
28+
"error",
29+
"ignorePackages",
30+
{
31+
"js": "never",
32+
"jsx": "never",
33+
"ts": "never",
34+
"tsx": "never"
35+
}
36+
]
37+
}
38+
},
2539
{
2640
"files": ["prelude/**/*"],
2741
"rules": {
2842
"strict": "off"
29-
},
30-
}
31-
, {
43+
}
44+
},
45+
{
3246
"files": ["test/**/*"],
3347
"rules": {
3448
"array-callback-return": "off",
@@ -57,5 +71,5 @@
5771
"strict": ["error", "global"]
5872
}
5973
}
60-
]
74+
]
6175
}

.github/workflows/ci.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ jobs:
3333

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

3838
- name: Build
39-
run: yarn run babel
39+
run: yarn build
4040

4141
- name: Test
42-
run: yarn run test
42+
run: yarn test

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ examples/express/node_modules
1919

2020
# Editors
2121
.vscode/
22-
yarn-error.log
22+
yarn-error.log
23+
tsconfig.tsbuildinfo

lib/bin.js lib/bin.ts

File renamed without changes.

lib/chmod.js lib/chmod.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { chmod, stat } from 'fs-extra';
22

3-
export async function plusx(file) {
3+
export async function plusx(file: string) {
44
const s = await stat(file);
55
const newMode = s.mode | 64 | 8 | 1;
6-
if (s.mode === newMode) return;
6+
7+
if (s.mode === newMode) {
8+
return;
9+
}
10+
711
const base8 = newMode.toString(8).slice(-3);
812
await chmod(file, base8);
913
}

lib/common.ts

+282
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
import assert from 'assert';
2+
import fs from 'fs';
3+
import path from 'path';
4+
5+
export const STORE_BLOB = 0;
6+
export const STORE_CONTENT = 1;
7+
export const STORE_LINKS = 2;
8+
export const STORE_STAT = 3;
9+
export const ALIAS_AS_RELATIVE = 0; // require("./file.js") // file or directory
10+
export const ALIAS_AS_RESOLVABLE = 1; // require("package")
11+
12+
const win32 = process.platform === 'win32';
13+
const hasURL = typeof URL !== 'undefined';
14+
15+
function uppercaseDriveLetter(f: string) {
16+
if (f.slice(1, 3) !== ':\\') return f;
17+
return f[0].toUpperCase() + f.slice(1);
18+
}
19+
20+
function removeTrailingSlashes(f: string) {
21+
if (f === '/') {
22+
return f; // dont remove from "/"
23+
}
24+
25+
if (f.slice(1) === ':\\') {
26+
return f; // dont remove from "D:\"
27+
}
28+
29+
let last = f.length - 1;
30+
31+
while (true) {
32+
const char = f.charAt(last);
33+
34+
if (char === '\\') {
35+
f = f.slice(0, -1);
36+
last -= 1;
37+
} else if (char === '/') {
38+
f = f.slice(0, -1);
39+
last -= 1;
40+
} else {
41+
break;
42+
}
43+
}
44+
return f;
45+
}
46+
47+
const isUrl = (p: unknown): p is URL => hasURL && p instanceof URL;
48+
49+
export function isRootPath(p: string | URL | Buffer) {
50+
let file = Buffer.isBuffer(p) ? p.toString() : isUrl(p) ? p.pathname : p;
51+
52+
if (file === '.') {
53+
file = path.resolve(file);
54+
}
55+
56+
return path.dirname(file) === p;
57+
}
58+
59+
export function normalizePath(f: string | URL | Buffer) {
60+
if (win32) {
61+
let file = Buffer.isBuffer(f)
62+
? f.toString()
63+
: isUrl(f)
64+
? f.pathname.replace(/^\//, '')
65+
: f;
66+
67+
if (!/^.:$/.test(file)) {
68+
file = path.normalize(file);
69+
} // 'c:' -> 'c:.'
70+
71+
file = uppercaseDriveLetter(file);
72+
73+
return removeTrailingSlashes(file);
74+
}
75+
76+
let file = Buffer.isBuffer(f) ? f.toString() : isUrl(f) ? f.pathname : f;
77+
78+
if (!/^.:$/.test(file)) {
79+
file = path.normalize(file);
80+
} // 'c:' -> 'c:.'
81+
82+
return removeTrailingSlashes(file);
83+
}
84+
85+
export function isPackageJson(file: string) {
86+
return path.basename(file) === 'package.json';
87+
}
88+
89+
export function isDotJS(file: string) {
90+
return path.extname(file) === '.js';
91+
}
92+
93+
export function isDotJSON(file: string) {
94+
return path.extname(file) === '.json';
95+
}
96+
97+
export function isDotNODE(file: string) {
98+
return path.extname(file) === '.node';
99+
}
100+
101+
function replaceSlashes(file: string, slash: string) {
102+
if (/^.:\\/.test(file)) {
103+
if (slash === '/') {
104+
return file.slice(2).replace(/\\/g, '/');
105+
}
106+
} else if (/^\//.test(file)) {
107+
if (slash === '\\') {
108+
return `C:${file.replace(/\//g, '\\')}`;
109+
}
110+
}
111+
112+
return file;
113+
}
114+
115+
function injectSnapshot(file: string) {
116+
if (/^.:\\/.test(file)) {
117+
// C:\path\to
118+
if (file.length === 3) {
119+
// C:\
120+
file = file.slice(0, -1);
121+
}
122+
123+
return `${file[0]}:\\snapshot${file.slice(2)}`;
124+
}
125+
126+
if (/^\//.test(file)) {
127+
// /home/user/project
128+
if (file.length === 1) {
129+
// /
130+
file = file.slice(0, -1);
131+
}
132+
133+
return `/snapshot${file}`;
134+
}
135+
136+
return file;
137+
}
138+
139+
function longestCommonLength(s1: string, s2: string) {
140+
const length = Math.min(s1.length, s2.length);
141+
142+
for (let i = 0; i < length; i += 1) {
143+
if (s1.charCodeAt(i) !== s2.charCodeAt(i)) {
144+
return i;
145+
}
146+
}
147+
148+
return length;
149+
}
150+
151+
function withoutNodeModules(file: string) {
152+
return file.split(`${path.sep}node_modules${path.sep}`)[0];
153+
}
154+
155+
export function retrieveDenominator(files: string[]) {
156+
assert(files.length > 0);
157+
158+
let s1 = withoutNodeModules(files[0]) + path.sep;
159+
160+
for (let i = 1; i < files.length; i += 1) {
161+
const s2 = withoutNodeModules(files[i]) + path.sep;
162+
s1 = s1.slice(0, longestCommonLength(s1, s2));
163+
}
164+
165+
if (s1 === '') {
166+
return win32 ? 2 : 0;
167+
}
168+
169+
return s1.lastIndexOf(path.sep);
170+
}
171+
172+
export function substituteDenominator(f: string, denominator: number) {
173+
const rootLength = win32 ? 2 : 0;
174+
return f.slice(0, rootLength) + f.slice(denominator);
175+
}
176+
177+
export function snapshotify(file: string, slash: string) {
178+
return injectSnapshot(replaceSlashes(file, slash));
179+
}
180+
181+
export function insideSnapshot(f: Buffer | string | URL) {
182+
if (win32) {
183+
if (Buffer.isBuffer(f)) {
184+
f = f.toString();
185+
}
186+
187+
if (hasURL && f instanceof URL) {
188+
f = f.pathname.replace(/^\//, '');
189+
}
190+
191+
if (typeof f !== 'string') {
192+
return false;
193+
}
194+
195+
const slice112 = f.slice(1, 12);
196+
197+
return (
198+
slice112 === ':\\snapshot\\' ||
199+
slice112 === ':/snapshot\\' ||
200+
slice112 === ':\\snapshot/' ||
201+
slice112 === ':/snapshot/' ||
202+
slice112 === ':\\snapshot' ||
203+
slice112 === ':/snapshot'
204+
);
205+
}
206+
207+
if (Buffer.isBuffer(f)) {
208+
f = f.toString();
209+
}
210+
211+
if (hasURL && f instanceof URL) {
212+
f = f.pathname;
213+
}
214+
215+
if (typeof f !== 'string') {
216+
return false;
217+
}
218+
219+
const slice010 = f.slice(0, 10);
220+
221+
return slice010 === '/snapshot/' || slice010 === '/snapshot';
222+
}
223+
224+
export function stripSnapshot(f: string) {
225+
const file = normalizePath(f);
226+
227+
if (/^.:\\snapshot$/.test(file)) {
228+
return `${file[0]}:\\**\\`;
229+
}
230+
231+
if (/^.:\\snapshot\\/.test(file)) {
232+
return `${file[0]}:\\**${file.slice(11)}`;
233+
}
234+
235+
if (/^\/snapshot$/.test(file)) {
236+
return '/**/';
237+
}
238+
239+
if (/^\/snapshot\//.test(file)) {
240+
return `/**${file.slice(9)}`;
241+
}
242+
243+
return f; // not inside
244+
}
245+
246+
export function removeUplevels(f: string) {
247+
if (win32) {
248+
while (true) {
249+
if (f.slice(0, 3) === '..\\') {
250+
f = f.slice(3);
251+
} else if (f === '..') {
252+
f = '.';
253+
} else {
254+
break;
255+
}
256+
}
257+
258+
return f;
259+
}
260+
261+
while (true) {
262+
if (f.slice(0, 3) === '../') {
263+
f = f.slice(3);
264+
} else if (f === '..') {
265+
f = '.';
266+
} else {
267+
break;
268+
}
269+
}
270+
271+
return f;
272+
}
273+
274+
export function toNormalizedRealPath(requestPath: string) {
275+
const file = normalizePath(requestPath);
276+
277+
if (fs.existsSync(file)) {
278+
return fs.realpathSync(file);
279+
}
280+
281+
return file;
282+
}

0 commit comments

Comments
 (0)