@tilua/compiler 8.1.0 → 9.0.0
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/README.md +108 -13
- package/dist/{chunk-WOBHMGGC.js → chunk-VUIF62OE.js} +406 -56
- package/dist/cli.cjs +572 -95
- package/dist/cli.js +156 -24
- package/dist/index.cjs +415 -63
- package/dist/index.d.cts +52 -9
- package/dist/index.d.ts +52 -9
- package/dist/index.js +14 -5
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -1,33 +1,42 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
WRITTEN_BY_TILUA,
|
|
3
4
|
bundle,
|
|
4
5
|
resolveConfig
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-VUIF62OE.js";
|
|
6
7
|
|
|
7
8
|
// src/cli.ts
|
|
8
|
-
import { mkdirSync, writeFileSync } from "fs";
|
|
9
|
-
import { basename, dirname, join, relative, resolve } from "path";
|
|
10
|
-
var usage = "usage: tilua <entry> [--out <file>] [--output single|chunks|
|
|
9
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, watch, writeFileSync } from "fs";
|
|
10
|
+
import { basename, dirname, join, relative, resolve, sep } from "path";
|
|
11
|
+
var usage = "usage: tilua [<entry>] [--out <file>] [--output single|chunks|files] [--config <tilua.config.json>] [--noCheck] [--noLineMap] [--minify] [--watch]\n tilua init";
|
|
11
12
|
var args = process.argv.slice(2);
|
|
12
13
|
var entry;
|
|
13
14
|
var out;
|
|
14
15
|
var config;
|
|
15
16
|
var typeCheck = true;
|
|
16
17
|
var lineMap;
|
|
18
|
+
var minify;
|
|
17
19
|
var output;
|
|
20
|
+
var watching = false;
|
|
18
21
|
for (let i = 0; i < args.length; i++) {
|
|
19
22
|
const arg = args[i];
|
|
20
23
|
if (arg === "--out") out = args[++i];
|
|
21
24
|
else if (arg === "--config") config = args[++i];
|
|
22
25
|
else if (arg === "--noCheck") typeCheck = false;
|
|
23
26
|
else if (arg === "--noLineMap") lineMap = false;
|
|
27
|
+
else if (arg === "--minify") minify = true;
|
|
28
|
+
else if (arg === "--watch" || arg === "-w") watching = true;
|
|
24
29
|
else if (arg === "--target") {
|
|
25
30
|
console.error(`--target is gone: the output runs on Lua 5.1 to 5.4, LuaJIT and Luau, and a library says what more its Lua has \u2014 add "luau" to the config's 'types'`);
|
|
26
31
|
process.exit(2);
|
|
27
32
|
} else if (arg === "--output") {
|
|
28
33
|
const value = args[++i];
|
|
29
|
-
if (value
|
|
30
|
-
console.error(
|
|
34
|
+
if (value === "modules") {
|
|
35
|
+
console.error("--output modules is gone: --output files writes one file per module, each of which returns its exports");
|
|
36
|
+
process.exit(2);
|
|
37
|
+
}
|
|
38
|
+
if (value !== "single" && value !== "chunks" && value !== "files") {
|
|
39
|
+
console.error(`--output must be 'single', 'chunks' or 'files', not '${value}'`);
|
|
31
40
|
process.exit(2);
|
|
32
41
|
}
|
|
33
42
|
output = value;
|
|
@@ -36,39 +45,162 @@ for (let i = 0; i < args.length; i++) {
|
|
|
36
45
|
process.exit(0);
|
|
37
46
|
} else entry = arg;
|
|
38
47
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
process.
|
|
48
|
+
var shown = (path) => relative(process.cwd(), path) || ".";
|
|
49
|
+
function init() {
|
|
50
|
+
const folder = process.cwd();
|
|
51
|
+
for (const name of ["tilua.config.json", "tilua.config.jsonc"]) {
|
|
52
|
+
if (existsSync(join(folder, name))) {
|
|
53
|
+
console.error(`${name} is already here`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
let rootDir = "src";
|
|
58
|
+
const project = join(folder, "default.project.json");
|
|
59
|
+
if (existsSync(project)) {
|
|
60
|
+
const paths = [];
|
|
61
|
+
const walk = (node) => {
|
|
62
|
+
if (!node || typeof node !== "object") return;
|
|
63
|
+
const path = node.$path;
|
|
64
|
+
const named = typeof path === "string" ? path : path?.optional;
|
|
65
|
+
if (typeof named === "string" && !/\.\w+$/.test(named)) paths.push(named);
|
|
66
|
+
for (const [key, child] of Object.entries(node)) if (!key.startsWith("$")) walk(child);
|
|
67
|
+
};
|
|
68
|
+
try {
|
|
69
|
+
walk(JSON.parse(readFileSync(project, "utf8")).tree);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
console.error(`default.project.json: ${error.message}`);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
const split = paths.map((path) => path.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/$/, "").split("/"));
|
|
75
|
+
const shared = [];
|
|
76
|
+
for (let i = 0; split.length && split.every((parts) => parts.length > i && parts[i] === split[0][i]); i++) shared.push(split[0][i]);
|
|
77
|
+
if (split.length) rootDir = shared.join("/") || ".";
|
|
78
|
+
} else {
|
|
79
|
+
console.error('No default.project.json here: rootDir is "src". Change it if the project reads its files from elsewhere.');
|
|
80
|
+
}
|
|
81
|
+
const written = { types: ["roblox"], output: "files", rootDir };
|
|
82
|
+
writeFileSync(join(folder, "tilua.config.json"), JSON.stringify(written, null, 4) + "\n");
|
|
83
|
+
console.log("tilua.config.json: a .luau beside each .tilua under " + rootDir);
|
|
84
|
+
console.log("Next: npm i -D @tilua/compiler @tilua-types/roblox, then run `npx tilua --watch` beside `rojo serve`.");
|
|
85
|
+
process.exit(0);
|
|
86
|
+
}
|
|
87
|
+
function writtenByTilua(folder) {
|
|
88
|
+
const found = [];
|
|
89
|
+
const walk = (at) => {
|
|
90
|
+
let items;
|
|
91
|
+
try {
|
|
92
|
+
items = readdirSync(at, { withFileTypes: true });
|
|
93
|
+
} catch {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
for (const item of items) {
|
|
97
|
+
if (item.name.startsWith(".") || item.name === "node_modules") continue;
|
|
98
|
+
const path = join(at, item.name);
|
|
99
|
+
if (item.isDirectory()) walk(path);
|
|
100
|
+
else if (/\.luau?$/.test(item.name) && isTilua(path)) found.push(path);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
walk(folder);
|
|
104
|
+
return found;
|
|
105
|
+
}
|
|
106
|
+
function isTilua(path) {
|
|
107
|
+
try {
|
|
108
|
+
const text = readFileSync(path, "utf8").trimEnd();
|
|
109
|
+
return text.slice(text.lastIndexOf("\n") + 1).startsWith(WRITTEN_BY_TILUA);
|
|
110
|
+
} catch {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
42
113
|
}
|
|
43
|
-
async function
|
|
44
|
-
const found = resolveConfig(config, resolve(from)).config;
|
|
114
|
+
async function build(from) {
|
|
115
|
+
const found = resolveConfig(config, resolve(from ?? "tilua.config.json")).config;
|
|
45
116
|
const mode = output ?? found?.output ?? "single";
|
|
46
|
-
|
|
47
|
-
|
|
117
|
+
if (mode !== "files" && from === void 0) {
|
|
118
|
+
console.error(usage);
|
|
119
|
+
process.exit(2);
|
|
120
|
+
}
|
|
121
|
+
const perFile = mode === "files";
|
|
122
|
+
const entryFile = perFile || from === void 0 ? void 0 : out ?? from.replace(/\.tilua$/, "") + ".luau";
|
|
123
|
+
const folder = resolve(entryFile !== void 0 ? dirname(entryFile) : out ?? found?.outDir ?? process.cwd());
|
|
48
124
|
const result = await bundle({
|
|
49
|
-
entry: from,
|
|
125
|
+
entry: perFile ? void 0 : from,
|
|
50
126
|
config,
|
|
51
127
|
typeCheck,
|
|
52
128
|
output: mode,
|
|
53
129
|
lineMap,
|
|
130
|
+
minify,
|
|
131
|
+
outDir: perFile ? out : void 0,
|
|
54
132
|
outFile: entryFile !== void 0 ? basename(entryFile) : void 0
|
|
55
133
|
});
|
|
56
134
|
for (const d of result.diagnostics) {
|
|
57
|
-
console.error(`${
|
|
135
|
+
console.error(`${shown(d.file)}:${d.line}:${d.column} ${d.severity === "warning" ? "warning: " : ""}${d.message}`);
|
|
58
136
|
}
|
|
59
137
|
if (result.code === void 0) {
|
|
60
|
-
console.error("no
|
|
61
|
-
|
|
138
|
+
console.error("no output written");
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
const targets = result.files.map((file) => ({ ...file, target: join(folder, file.path) }));
|
|
142
|
+
if (perFile) {
|
|
143
|
+
const theirs = targets.filter((file) => existsSync(file.target) && !isTilua(file.target));
|
|
144
|
+
for (const file of theirs) {
|
|
145
|
+
console.error(`${shown(file.target)}: this file was not written by tilua, and a .tilua would replace it \u2014 rename or remove one of them`);
|
|
146
|
+
}
|
|
147
|
+
if (theirs.length) return false;
|
|
148
|
+
}
|
|
149
|
+
for (const file of targets) {
|
|
150
|
+
if (existsSync(file.target) && readFileSync(file.target, "utf8") === file.code) continue;
|
|
151
|
+
mkdirSync(dirname(file.target), { recursive: true });
|
|
152
|
+
writeFileSync(file.target, file.code);
|
|
153
|
+
console.log(`${shown(file.target)}: ${file.modules.length} module${file.modules.length === 1 ? "" : "s"}`);
|
|
62
154
|
}
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
155
|
+
if (perFile) {
|
|
156
|
+
const kept = new Set(targets.map((file) => resolve(file.target)));
|
|
157
|
+
for (const stale of writtenByTilua(folder)) {
|
|
158
|
+
if (kept.has(resolve(stale))) continue;
|
|
159
|
+
rmSync(stale);
|
|
160
|
+
console.log(`${shown(stale)}: removed, its .tilua is gone`);
|
|
161
|
+
}
|
|
68
162
|
}
|
|
69
|
-
|
|
163
|
+
return !result.diagnostics.some((d) => d.severity !== "warning");
|
|
164
|
+
}
|
|
165
|
+
async function watchAndBuild(from) {
|
|
166
|
+
const found = resolveConfig(config, resolve(from ?? "tilua.config.json")).config;
|
|
167
|
+
const folder = found?.directory ?? (from !== void 0 ? dirname(resolve(from)) : process.cwd());
|
|
168
|
+
let running = false;
|
|
169
|
+
let again = false;
|
|
170
|
+
let timer;
|
|
171
|
+
const run = async () => {
|
|
172
|
+
if (running) {
|
|
173
|
+
again = true;
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
running = true;
|
|
177
|
+
const ok = await build(from).catch((error) => {
|
|
178
|
+
console.error(error instanceof Error ? error.message : error);
|
|
179
|
+
return false;
|
|
180
|
+
});
|
|
181
|
+
console.log(`[${(/* @__PURE__ */ new Date()).toLocaleTimeString()}] ${ok ? "built" : "built with errors"}; watching ${shown(folder)}`);
|
|
182
|
+
running = false;
|
|
183
|
+
if (again) {
|
|
184
|
+
again = false;
|
|
185
|
+
await run();
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
await run();
|
|
189
|
+
watch(folder, { recursive: true }, (_event, name) => {
|
|
190
|
+
if (!name) return;
|
|
191
|
+
const path = name.toString();
|
|
192
|
+
if (path.split(sep).includes("node_modules")) return;
|
|
193
|
+
if (!/\.tilua$|tilua\.config\.jsonc?$|\.project\.json$/.test(path)) return;
|
|
194
|
+
clearTimeout(timer);
|
|
195
|
+
timer = setTimeout(() => void run(), 100);
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async function main() {
|
|
199
|
+
if (entry === "init") init();
|
|
200
|
+
if (watching) return watchAndBuild(entry);
|
|
201
|
+
process.exit(await build(entry) ? 0 : 1);
|
|
70
202
|
}
|
|
71
|
-
main(
|
|
203
|
+
main().catch((error) => {
|
|
72
204
|
console.error(error instanceof Error ? error.message : error);
|
|
73
205
|
process.exit(1);
|
|
74
206
|
});
|