ts-arc 1.1.11 → 1.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +109 -3
- package/dist/cli.js +124 -0
- package/dist/loader.js +131 -2
- package/package.json +3 -3
package/dist/bin.js
CHANGED
|
@@ -1,3 +1,109 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
// src/bin.ts
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import { register } from "node:module";
|
|
4
|
+
import { createRequire } from "node:module";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
import * as url from "node:url";
|
|
7
|
+
var __filename = url.fileURLToPath(import.meta.url);
|
|
8
|
+
var __dirname = path.dirname(__filename);
|
|
9
|
+
var loaderPath = path.join(__dirname, "loader.js");
|
|
10
|
+
var require2 = createRequire(import.meta.url);
|
|
11
|
+
function stripJsonComments(input) {
|
|
12
|
+
let output = "";
|
|
13
|
+
let insideString = false;
|
|
14
|
+
let i = 0;
|
|
15
|
+
while (i < input.length) {
|
|
16
|
+
const char = input[i];
|
|
17
|
+
if (insideString) {
|
|
18
|
+
output += char;
|
|
19
|
+
if (char === '"' && input[i - 1] !== "\\") insideString = false;
|
|
20
|
+
i++;
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (char === '"') {
|
|
24
|
+
insideString = true;
|
|
25
|
+
output += char;
|
|
26
|
+
i++;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (char === "/" && input[i + 1] === "/") {
|
|
30
|
+
i += 2;
|
|
31
|
+
while (i < input.length && input[i] !== "\n") i++;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (char === "/" && input[i + 1] === "*") {
|
|
35
|
+
i += 2;
|
|
36
|
+
while (i < input.length && !(input[i - 1] === "*" && input[i] === "/")) i++;
|
|
37
|
+
if (i < input.length) i++;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
output += char;
|
|
41
|
+
i++;
|
|
42
|
+
}
|
|
43
|
+
return output;
|
|
44
|
+
}
|
|
45
|
+
function loadConfig(filePath) {
|
|
46
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
47
|
+
const stripped = stripJsonComments(content);
|
|
48
|
+
const config = JSON.parse(stripped);
|
|
49
|
+
if (!config.extends) {
|
|
50
|
+
return config;
|
|
51
|
+
}
|
|
52
|
+
const extendsVal = config.extends;
|
|
53
|
+
const tsconfigDir = path.dirname(filePath);
|
|
54
|
+
let extendsPath;
|
|
55
|
+
if (extendsVal.startsWith("./") || extendsVal.startsWith("../")) {
|
|
56
|
+
extendsPath = path.resolve(tsconfigDir, extendsVal);
|
|
57
|
+
if (!extendsPath.endsWith(".json")) {
|
|
58
|
+
extendsPath += ".json";
|
|
59
|
+
}
|
|
60
|
+
} else {
|
|
61
|
+
try {
|
|
62
|
+
extendsPath = require2.resolve(extendsVal);
|
|
63
|
+
} catch {
|
|
64
|
+
extendsPath = require2.resolve(extendsVal + "/tsconfig.json");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const baseConfig = loadConfig(extendsPath);
|
|
68
|
+
const merged = { ...baseConfig, ...config };
|
|
69
|
+
merged.compilerOptions = { ...baseConfig.compilerOptions || {}, ...config.compilerOptions || {} };
|
|
70
|
+
return merged;
|
|
71
|
+
}
|
|
72
|
+
function findTsConfig(dir) {
|
|
73
|
+
let current = dir;
|
|
74
|
+
while (current !== path.parse(current).root) {
|
|
75
|
+
const tsconfigPath = path.join(current, "tsconfig.json");
|
|
76
|
+
if (fs.existsSync(tsconfigPath)) {
|
|
77
|
+
return tsconfigPath;
|
|
78
|
+
}
|
|
79
|
+
current = path.dirname(current);
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
var tsArcConfig = { baseUrl: null, paths: {}, tsconfigDir: null };
|
|
84
|
+
async function registerLoader() {
|
|
85
|
+
const loaderUrl = url.pathToFileURL(loaderPath).href;
|
|
86
|
+
register(loaderUrl, { data: tsArcConfig });
|
|
87
|
+
}
|
|
88
|
+
async function loadModule(scriptUrl) {
|
|
89
|
+
const scriptPath = url.fileURLToPath(scriptUrl);
|
|
90
|
+
const tsconfigPath = findTsConfig(path.dirname(scriptPath));
|
|
91
|
+
if (tsconfigPath) {
|
|
92
|
+
const mergedConfig = loadConfig(tsconfigPath);
|
|
93
|
+
const compilerOptions = mergedConfig.compilerOptions || {};
|
|
94
|
+
const tsconfigDir = path.dirname(tsconfigPath);
|
|
95
|
+
const baseUrlStr = compilerOptions.baseUrl;
|
|
96
|
+
tsArcConfig.baseUrl = baseUrlStr ? path.resolve(tsconfigDir, baseUrlStr) : null;
|
|
97
|
+
tsArcConfig.paths = compilerOptions.paths || {};
|
|
98
|
+
tsArcConfig.tsconfigDir = tsconfigDir;
|
|
99
|
+
}
|
|
100
|
+
await registerLoader();
|
|
101
|
+
import(scriptUrl).catch((err) => {
|
|
102
|
+
console.error(err);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
export {
|
|
107
|
+
loadModule,
|
|
108
|
+
registerLoader
|
|
109
|
+
};
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import * as path2 from "node:path";
|
|
5
|
+
import * as url2 from "node:url";
|
|
6
|
+
|
|
7
|
+
// src/bin.ts
|
|
8
|
+
import * as fs from "node:fs";
|
|
9
|
+
import { register } from "node:module";
|
|
10
|
+
import { createRequire } from "node:module";
|
|
11
|
+
import * as path from "node:path";
|
|
12
|
+
import * as url from "node:url";
|
|
13
|
+
var __filename = url.fileURLToPath(import.meta.url);
|
|
14
|
+
var __dirname = path.dirname(__filename);
|
|
15
|
+
var loaderPath = path.join(__dirname, "loader.js");
|
|
16
|
+
var require2 = createRequire(import.meta.url);
|
|
17
|
+
function stripJsonComments(input) {
|
|
18
|
+
let output = "";
|
|
19
|
+
let insideString = false;
|
|
20
|
+
let i = 0;
|
|
21
|
+
while (i < input.length) {
|
|
22
|
+
const char = input[i];
|
|
23
|
+
if (insideString) {
|
|
24
|
+
output += char;
|
|
25
|
+
if (char === '"' && input[i - 1] !== "\\") insideString = false;
|
|
26
|
+
i++;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
if (char === '"') {
|
|
30
|
+
insideString = true;
|
|
31
|
+
output += char;
|
|
32
|
+
i++;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (char === "/" && input[i + 1] === "/") {
|
|
36
|
+
i += 2;
|
|
37
|
+
while (i < input.length && input[i] !== "\n") i++;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
if (char === "/" && input[i + 1] === "*") {
|
|
41
|
+
i += 2;
|
|
42
|
+
while (i < input.length && !(input[i - 1] === "*" && input[i] === "/")) i++;
|
|
43
|
+
if (i < input.length) i++;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
output += char;
|
|
47
|
+
i++;
|
|
48
|
+
}
|
|
49
|
+
return output;
|
|
50
|
+
}
|
|
51
|
+
function loadConfig(filePath) {
|
|
52
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
53
|
+
const stripped = stripJsonComments(content);
|
|
54
|
+
const config = JSON.parse(stripped);
|
|
55
|
+
if (!config.extends) {
|
|
56
|
+
return config;
|
|
57
|
+
}
|
|
58
|
+
const extendsVal = config.extends;
|
|
59
|
+
const tsconfigDir = path.dirname(filePath);
|
|
60
|
+
let extendsPath;
|
|
61
|
+
if (extendsVal.startsWith("./") || extendsVal.startsWith("../")) {
|
|
62
|
+
extendsPath = path.resolve(tsconfigDir, extendsVal);
|
|
63
|
+
if (!extendsPath.endsWith(".json")) {
|
|
64
|
+
extendsPath += ".json";
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
try {
|
|
68
|
+
extendsPath = require2.resolve(extendsVal);
|
|
69
|
+
} catch {
|
|
70
|
+
extendsPath = require2.resolve(extendsVal + "/tsconfig.json");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const baseConfig = loadConfig(extendsPath);
|
|
74
|
+
const merged = { ...baseConfig, ...config };
|
|
75
|
+
merged.compilerOptions = { ...baseConfig.compilerOptions || {}, ...config.compilerOptions || {} };
|
|
76
|
+
return merged;
|
|
77
|
+
}
|
|
78
|
+
function findTsConfig(dir) {
|
|
79
|
+
let current = dir;
|
|
80
|
+
while (current !== path.parse(current).root) {
|
|
81
|
+
const tsconfigPath = path.join(current, "tsconfig.json");
|
|
82
|
+
if (fs.existsSync(tsconfigPath)) {
|
|
83
|
+
return tsconfigPath;
|
|
84
|
+
}
|
|
85
|
+
current = path.dirname(current);
|
|
86
|
+
}
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
var tsArcConfig = { baseUrl: null, paths: {}, tsconfigDir: null };
|
|
90
|
+
async function registerLoader() {
|
|
91
|
+
const loaderUrl = url.pathToFileURL(loaderPath).href;
|
|
92
|
+
register(loaderUrl, { data: tsArcConfig });
|
|
93
|
+
}
|
|
94
|
+
async function loadModule(scriptUrl2) {
|
|
95
|
+
const scriptPath2 = url.fileURLToPath(scriptUrl2);
|
|
96
|
+
const tsconfigPath = findTsConfig(path.dirname(scriptPath2));
|
|
97
|
+
if (tsconfigPath) {
|
|
98
|
+
const mergedConfig = loadConfig(tsconfigPath);
|
|
99
|
+
const compilerOptions = mergedConfig.compilerOptions || {};
|
|
100
|
+
const tsconfigDir = path.dirname(tsconfigPath);
|
|
101
|
+
const baseUrlStr = compilerOptions.baseUrl;
|
|
102
|
+
tsArcConfig.baseUrl = baseUrlStr ? path.resolve(tsconfigDir, baseUrlStr) : null;
|
|
103
|
+
tsArcConfig.paths = compilerOptions.paths || {};
|
|
104
|
+
tsArcConfig.tsconfigDir = tsconfigDir;
|
|
105
|
+
}
|
|
106
|
+
await registerLoader();
|
|
107
|
+
import(scriptUrl2).catch((err) => {
|
|
108
|
+
console.error(err);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/cli.ts
|
|
114
|
+
var script = process.argv[2];
|
|
115
|
+
if (!script) {
|
|
116
|
+
console.error("Usage: ts-arc <script.ts> [args...]");
|
|
117
|
+
process.exit(1);
|
|
118
|
+
}
|
|
119
|
+
var scriptPath = path2.resolve(script);
|
|
120
|
+
var scriptUrl = url2.pathToFileURL(scriptPath).href;
|
|
121
|
+
process.argv = [process.argv[0], script, ...process.argv.slice(3)];
|
|
122
|
+
(async () => {
|
|
123
|
+
await loadModule(scriptUrl);
|
|
124
|
+
})();
|
package/dist/loader.js
CHANGED
|
@@ -1,4 +1,133 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
// src/loader.ts
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import * as url from "url";
|
|
7
|
+
import { transformSync } from "esbuild";
|
|
8
|
+
var config = {
|
|
9
|
+
baseUrl: null,
|
|
10
|
+
paths: {},
|
|
11
|
+
tsconfigDir: null
|
|
12
|
+
};
|
|
13
|
+
function initialize(initContext) {
|
|
14
|
+
config = initContext;
|
|
15
|
+
}
|
|
16
|
+
function getEffectiveBase() {
|
|
17
|
+
const { baseUrl, tsconfigDir } = config;
|
|
18
|
+
if (baseUrl) {
|
|
19
|
+
return path.resolve(tsconfigDir ?? process.cwd(), baseUrl);
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
async function resolveLocal(baseDir, relativePath) {
|
|
24
|
+
const fullPath = path.resolve(baseDir, relativePath);
|
|
25
|
+
const candidates = [
|
|
26
|
+
fullPath,
|
|
27
|
+
fullPath + ".ts",
|
|
28
|
+
fullPath + ".tsx",
|
|
29
|
+
path.join(fullPath, "index.ts"),
|
|
30
|
+
path.join(fullPath, "index.tsx"),
|
|
31
|
+
path.join(fullPath, "page.ts"),
|
|
32
|
+
path.join(fullPath, "page.tsx")
|
|
33
|
+
];
|
|
34
|
+
for (const candidate of candidates) {
|
|
35
|
+
try {
|
|
36
|
+
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
|
|
37
|
+
return { url: url.pathToFileURL(candidate).href };
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
throw Object.assign(new Error(`Cannot find module '${relativePath}'`), { code: "ERR_MODULE_NOT_FOUND" });
|
|
43
|
+
}
|
|
44
|
+
async function resolve2(specifier, context, nextResolve) {
|
|
45
|
+
let parentPath = process.cwd();
|
|
46
|
+
if (context.parentURL) {
|
|
47
|
+
parentPath = path.dirname(url.fileURLToPath(context.parentURL));
|
|
48
|
+
}
|
|
49
|
+
if (specifier.startsWith("file://")) {
|
|
50
|
+
const filePath = url.fileURLToPath(specifier);
|
|
51
|
+
const dir = path.dirname(filePath);
|
|
52
|
+
const baseName = path.basename(filePath);
|
|
53
|
+
const relative = path.extname(baseName) ? baseName : baseName;
|
|
54
|
+
const resolved = await resolveLocal(dir, relative);
|
|
55
|
+
return { ...resolved, shortCircuit: true };
|
|
56
|
+
}
|
|
57
|
+
const isPathLike = specifier.startsWith(".") || specifier.startsWith("/");
|
|
58
|
+
if (isPathLike) {
|
|
59
|
+
console.log("Attempting to resolve a path-like specifier:", specifier);
|
|
60
|
+
const resolved = await resolveLocal(parentPath, specifier);
|
|
61
|
+
return { ...resolved, shortCircuit: true };
|
|
62
|
+
} else {
|
|
63
|
+
console.log("Attempting to resolve non path-like specifier:", specifier);
|
|
64
|
+
const { paths } = config;
|
|
65
|
+
const effectiveBase = getEffectiveBase();
|
|
66
|
+
console.log("That specifiers effectiveBase is:", specifier);
|
|
67
|
+
for (const key of Object.keys(paths)) {
|
|
68
|
+
let capture = null;
|
|
69
|
+
const isWildcard = key.endsWith("/*");
|
|
70
|
+
const prefix = isWildcard ? key.slice(0, -2) : key;
|
|
71
|
+
if (isWildcard && specifier.startsWith(prefix + "/")) {
|
|
72
|
+
capture = specifier.slice(prefix.length + 1);
|
|
73
|
+
} else if (!isWildcard && specifier === key) {
|
|
74
|
+
capture = "";
|
|
75
|
+
}
|
|
76
|
+
if (capture !== null) {
|
|
77
|
+
for (const target of paths[key]) {
|
|
78
|
+
const mapped = isWildcard ? target.replace(/\*/g, capture) : target;
|
|
79
|
+
if (effectiveBase) {
|
|
80
|
+
try {
|
|
81
|
+
const resolved2 = await resolveLocal(effectiveBase, mapped);
|
|
82
|
+
return { ...resolved2, shortCircuit: true };
|
|
83
|
+
} catch (error) {
|
|
84
|
+
if (error.code !== "ERR_MODULE_NOT_FOUND") {
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (effectiveBase) {
|
|
93
|
+
try {
|
|
94
|
+
const resolved2 = await resolveLocal(effectiveBase, specifier);
|
|
95
|
+
return { ...resolved2, shortCircuit: true };
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (error.code !== "ERR_MODULE_NOT_FOUND") {
|
|
98
|
+
throw error;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const resolved = await nextResolve(specifier, context);
|
|
103
|
+
return { ...resolved, shortCircuit: true };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function load(urlStr, context, nextLoad) {
|
|
107
|
+
if (!urlStr.endsWith(".ts") && !urlStr.endsWith(".tsx")) {
|
|
108
|
+
return nextLoad(urlStr, context);
|
|
109
|
+
}
|
|
110
|
+
const esbuildLoader = urlStr.endsWith(".tsx") ? "tsx" : "ts";
|
|
111
|
+
const filePath = url.fileURLToPath(urlStr);
|
|
112
|
+
const rawSource = fs.readFileSync(filePath, "utf8");
|
|
113
|
+
const { code } = transformSync(rawSource, {
|
|
114
|
+
loader: esbuildLoader,
|
|
115
|
+
format: "esm",
|
|
116
|
+
target: `node${process.versions.node}`,
|
|
117
|
+
sourcemap: "inline",
|
|
118
|
+
sourcefile: filePath,
|
|
119
|
+
banner: `
|
|
3
120
|
import { createRequire } from 'module';
|
|
4
|
-
const require = createRequire(import.meta.url);`
|
|
121
|
+
const require = createRequire(import.meta.url);`
|
|
122
|
+
});
|
|
123
|
+
return {
|
|
124
|
+
format: "module",
|
|
125
|
+
source: code,
|
|
126
|
+
shortCircuit: true
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
export {
|
|
130
|
+
initialize,
|
|
131
|
+
load,
|
|
132
|
+
resolve2 as resolve
|
|
133
|
+
};
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-arc",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A simple typescript runtime.",
|
|
6
6
|
"main": "dist/bin.js",
|
|
7
7
|
"bin": {
|
|
8
|
-
"ts-arc": "./dist/
|
|
8
|
+
"ts-arc": "./dist/cli.js"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
|
-
"build": "npx esbuild ./src/loader.ts ./src/bin.ts --outdir=./dist --platform=node --format=esm --
|
|
11
|
+
"build": "npx esbuild ./src/cli.ts ./src/loader.ts ./src/bin.ts --outdir=./dist --platform=node --format=esm --bundle --external:fs --external:path --external:esbuild"
|
|
12
12
|
},
|
|
13
13
|
"keywords": [],
|
|
14
14
|
"author": "",
|