storm-lua-minify 0.2.0 → 0.3.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.
Files changed (81) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +79 -37
  3. package/dist/ast2lua.js +67 -14
  4. package/dist/cli.js +28 -2
  5. package/dist/globalRename.js +35 -0
  6. package/dist/keywordLocator.js +68 -0
  7. package/dist/linker.js +13 -0
  8. package/dist/minifier.js +75 -1
  9. package/dist/renamer.js +16 -2
  10. package/dist/resolver.js +10 -4
  11. package/dist/transform.js +401 -0
  12. package/package.json +41 -33
  13. package/.github/workflows/ci.yml +0 -39
  14. package/.github/workflows/publish.yml +0 -39
  15. package/.prettierignore +0 -3
  16. package/.prettierrc.json +0 -1
  17. package/eslint.config.js +0 -29
  18. package/src/ast2lua.ts +0 -940
  19. package/src/cli.ts +0 -86
  20. package/src/linker.ts +0 -108
  21. package/src/minifier.ts +0 -284
  22. package/src/output.ts +0 -71
  23. package/src/renamer.ts +0 -134
  24. package/src/resolver.ts +0 -378
  25. package/test/circular-require.test.ts +0 -19
  26. package/test/fixtures/bare-require/main.lua +0 -2
  27. package/test/fixtures/bare-require/mod.lua +0 -1
  28. package/test/fixtures/bitwise-precedence/main.lua +0 -10
  29. package/test/fixtures/circular-require/a.lua +0 -2
  30. package/test/fixtures/circular-require/b.lua +0 -2
  31. package/test/fixtures/circular-require/main.lua +0 -2
  32. package/test/fixtures/dofile/greet.lua +0 -1
  33. package/test/fixtures/dofile/main.lua +0 -2
  34. package/test/fixtures/entry-scope-many-requires/dep_alpha.lua +0 -2
  35. package/test/fixtures/entry-scope-many-requires/dep_bravo.lua +0 -2
  36. package/test/fixtures/entry-scope-many-requires/dep_charlie.lua +0 -2
  37. package/test/fixtures/entry-scope-many-requires/dep_delta.lua +0 -2
  38. package/test/fixtures/entry-scope-many-requires/dep_echo.lua +0 -2
  39. package/test/fixtures/entry-scope-many-requires/dep_foxtrot.lua +0 -2
  40. package/test/fixtures/entry-scope-many-requires/dep_golf.lua +0 -2
  41. package/test/fixtures/entry-scope-many-requires/dep_hotel.lua +0 -2
  42. package/test/fixtures/entry-scope-many-requires/dep_india.lua +0 -2
  43. package/test/fixtures/entry-scope-many-requires/dep_juliet.lua +0 -2
  44. package/test/fixtures/entry-scope-many-requires/dep_kilo.lua +0 -2
  45. package/test/fixtures/entry-scope-many-requires/main.lua +0 -25
  46. package/test/fixtures/multi-require/common.lua +0 -1
  47. package/test/fixtures/multi-require/main.lua +0 -3
  48. package/test/fixtures/nested-module/main.lua +0 -2
  49. package/test/fixtures/nested-module/sub/deep.lua +0 -1
  50. package/test/fixtures/require-call/main.lua +0 -2
  51. package/test/fixtures/require-call/mod.lua +0 -5
  52. package/test/fixtures/require-in-expression/main.lua +0 -1
  53. package/test/fixtures/require-in-expression/mod.lua +0 -1
  54. package/test/fixtures/require-string-call/main.lua +0 -2
  55. package/test/fixtures/require-string-call/mod.lua +0 -5
  56. package/test/fixtures/single-file/main.lua +0 -15
  57. package/test/identifier-collision.test.ts +0 -28
  58. package/test/lib/collision.ts +0 -131
  59. package/test/lib/helpers.ts +0 -124
  60. package/test/no-rename.test.ts +0 -19
  61. package/test/output.test.ts +0 -95
  62. package/test/precedence.test.ts +0 -28
  63. package/test/renamer.test.ts +0 -130
  64. package/test/resolver.test.ts +0 -206
  65. package/test/roundtrip.test.ts +0 -26
  66. package/test/snapshot.test.ts +0 -27
  67. package/test/snapshots/bare-require.sl.lua +0 -1
  68. package/test/snapshots/bitwise-precedence.sl.lua +0 -2
  69. package/test/snapshots/dofile.sl.lua +0 -1
  70. package/test/snapshots/entry-scope-many-requires.m.lua +0 -14
  71. package/test/snapshots/multi-require.m.lua +0 -4
  72. package/test/snapshots/multi-require.sl.lua +0 -1
  73. package/test/snapshots/nested-module.m.lua +0 -4
  74. package/test/snapshots/require-call.m.lua +0 -5
  75. package/test/snapshots/require-call.sl.lua +0 -1
  76. package/test/snapshots/require-in-expression.sl.lua +0 -1
  77. package/test/snapshots/require-string-call.m.lua +0 -5
  78. package/test/snapshots/single-file.sl.lua +0 -6
  79. package/test/sourcemap.test.ts +0 -105
  80. package/tsconfig.eslint.json +0 -8
  81. package/tsconfig.json +0 -111
package/dist/resolver.js CHANGED
@@ -6,6 +6,7 @@ function resolveScopes(chunk) {
6
6
  const allSymbols = [];
7
7
  const globals = new Map();
8
8
  const identifierSymbols = new WeakMap();
9
+ const globalReferenceNodes = new WeakSet();
9
10
  function createScope(kind, parent) {
10
11
  const scope = {
11
12
  kind,
@@ -67,7 +68,7 @@ function resolveScopes(chunk) {
67
68
  }
68
69
  return undefined;
69
70
  }
70
- function reference(scope, node) {
71
+ function reference(scope, node, isWrite = false) {
71
72
  const symbol = lookupBinding(scope, node.name);
72
73
  if (symbol) {
73
74
  symbol.references.push(node);
@@ -76,10 +77,14 @@ function resolveScopes(chunk) {
76
77
  }
77
78
  let binding = globals.get(node.name);
78
79
  if (!binding) {
79
- binding = { name: node.name, references: [] };
80
+ binding = { name: node.name, references: [], writes: [] };
80
81
  globals.set(node.name, binding);
81
82
  }
82
83
  binding.references.push(node);
84
+ if (isWrite) {
85
+ binding.writes.push(node);
86
+ }
87
+ globalReferenceNodes.add(node);
83
88
  }
84
89
  // ラベルはブロック内での宣言位置に関わらずブロック全体から参照できる
85
90
  // (前方goto)ため、通常の宣言文と違い先読みで登録する。
@@ -112,7 +117,7 @@ function resolveScopes(chunk) {
112
117
  });
113
118
  statement.variables.forEach((v) => {
114
119
  if (v.type === "Identifier") {
115
- reference(scope, v);
120
+ reference(scope, v, true);
116
121
  }
117
122
  else {
118
123
  resolveExpression(v, scope);
@@ -205,7 +210,7 @@ function resolveScopes(chunk) {
205
210
  }
206
211
  else {
207
212
  // 非local: 既存のローカル/グローバルへの代入として扱う(新規宣言ではない)
208
- reference(scope, fn.identifier);
213
+ reference(scope, fn.identifier, true);
209
214
  }
210
215
  }
211
216
  else {
@@ -299,5 +304,6 @@ function resolveScopes(chunk) {
299
304
  symbols: allSymbols,
300
305
  globals,
301
306
  symbolOf: (identifier) => identifierSymbols.get(identifier),
307
+ isGlobalReference: (identifier) => globalReferenceNodes.has(identifier),
302
308
  };
303
309
  }
@@ -0,0 +1,401 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mergeLocalDeclarations = mergeLocalDeclarations;
4
+ exports.originalNameOf = originalNameOf;
5
+ exports.insertGlobalAliases = insertGlobalAliases;
6
+ const linker_1 = require("./linker");
7
+ function mergeLocalDeclarations(chunk, resolveResult, options) {
8
+ processBlock(chunk.body, resolveResult, options);
9
+ }
10
+ // 十分に非現実的な接頭辞を使い、実在の識別子との衝突を避ける
11
+ // (このパスの直後にresolveScopesが再実行され、最終的な短縮名は
12
+ // Renameパスが決めるため、この仮名自体が出力に残ることはない)。
13
+ const ALIAS_TEMP_NAME_PREFIX = "__mergeAlias";
14
+ // エイリアス化で`.name`を書き換えた参照ノードについて、Source Mapに載せる
15
+ // べき「元の名前」を記録する。ast2lua.tsのgenerateIdentifierはこれを参照し、
16
+ // 位置情報(loc)はそのままなのにSource Mapのnamesフィールドだけ書き換え後の
17
+ // 仮名(あるいは最終的な短縮名)になってしまう不具合を避ける。
18
+ const aliasedOriginalNames = new WeakMap();
19
+ function originalNameOf(identifier) {
20
+ return aliasedOriginalNames.get(identifier);
21
+ }
22
+ // 代入コスト(`local X=`相当、8バイト)を、参照1回あたりの節約バイト数
23
+ // (元の名前の長さ-1文字、エイリアス名を1文字と仮定)で上回るかどうかで判定する。
24
+ function isWorthAliasing(name, referenceCount) {
25
+ const savingsPerReference = name.length - 1;
26
+ const declarationCost = 8 + name.length;
27
+ return referenceCount * savingsPerReference > declarationCost;
28
+ }
29
+ function insertGlobalAliases(chunk, resolveResult, options) {
30
+ const newLocals = [];
31
+ let aliasCounter = 0;
32
+ resolveResult.globals.forEach((binding) => {
33
+ // 一度でも代入されているグローバルは#8aが直接リネームする対象(か、そちらが
34
+ // 保護対象として保持する)なので、ここでの対象は代入が一度もないものに限る。
35
+ if (binding.writes.length > 0) {
36
+ return;
37
+ }
38
+ if (options.excludeNames.has(binding.name)) {
39
+ return;
40
+ }
41
+ // require/dofileはPrintパスが名前文字列で再検出するため、
42
+ // エイリアス化して名前を変えると検出できなくなり壊れる。
43
+ if (linker_1.RESERVED_MODULE_FUNCTION_NAMES.has(binding.name)) {
44
+ return;
45
+ }
46
+ if (!isWorthAliasing(binding.name, binding.references.length)) {
47
+ return;
48
+ }
49
+ const tempName = ALIAS_TEMP_NAME_PREFIX + String(aliasCounter++);
50
+ binding.references.forEach((ref) => {
51
+ aliasedOriginalNames.set(ref, ref.name);
52
+ ref.name = tempName;
53
+ });
54
+ newLocals.push({
55
+ type: "LocalStatement",
56
+ variables: [{ type: "Identifier", name: tempName }],
57
+ init: [{ type: "Identifier", name: binding.name }],
58
+ });
59
+ });
60
+ if (newLocals.length > 0) {
61
+ chunk.body.unshift(...newLocals);
62
+ }
63
+ }
64
+ // resolver.tsのresolveStatement/resolveExpressionの分岐を鏡写しにした
65
+ // 汎用ウォーカー。「参照として現れる識別子」と「ネストしたブロック本体」を
66
+ // どちらも一度の走査で収集できるようにし、resolver.tsの走査ロジックの
67
+ // 重複を避ける。
68
+ function walkStatement(statement, visitor) {
69
+ switch (statement.type) {
70
+ case "LocalStatement":
71
+ // 宣言される変数自体は参照ではないため辿らない
72
+ statement.init.forEach((expr) => {
73
+ walkExpression(expr, visitor);
74
+ });
75
+ return;
76
+ case "AssignmentStatement":
77
+ statement.variables.forEach((v) => {
78
+ if (v.type === "Identifier") {
79
+ visitor.onIdentifierReference?.(v);
80
+ }
81
+ else {
82
+ walkExpression(v, visitor);
83
+ }
84
+ });
85
+ statement.init.forEach((expr) => {
86
+ walkExpression(expr, visitor);
87
+ });
88
+ return;
89
+ case "CallStatement":
90
+ walkExpression(statement.expression, visitor);
91
+ return;
92
+ case "DoStatement":
93
+ visitor.onBlock?.(statement.body);
94
+ return;
95
+ case "WhileStatement":
96
+ walkExpression(statement.condition, visitor);
97
+ visitor.onBlock?.(statement.body);
98
+ return;
99
+ case "RepeatStatement":
100
+ visitor.onBlock?.(statement.body);
101
+ walkExpression(statement.condition, visitor);
102
+ return;
103
+ case "IfStatement":
104
+ statement.clauses.forEach((clause) => {
105
+ if (clause.type !== "ElseClause") {
106
+ walkExpression(clause.condition, visitor);
107
+ }
108
+ visitor.onBlock?.(clause.body);
109
+ });
110
+ return;
111
+ case "ForNumericStatement":
112
+ walkExpression(statement.start, visitor);
113
+ walkExpression(statement.end, visitor);
114
+ if (statement.step) {
115
+ walkExpression(statement.step, visitor);
116
+ }
117
+ visitor.onBlock?.(statement.body);
118
+ return;
119
+ case "ForGenericStatement":
120
+ statement.iterators.forEach((iterator) => {
121
+ walkExpression(iterator, visitor);
122
+ });
123
+ visitor.onBlock?.(statement.body);
124
+ return;
125
+ case "FunctionDeclaration":
126
+ if (statement.identifier) {
127
+ if (statement.identifier.type === "Identifier") {
128
+ if (!statement.isLocal) {
129
+ // 非local: 既存のローカル/グローバルへの代入(参照扱い)
130
+ visitor.onIdentifierReference?.(statement.identifier);
131
+ }
132
+ // isLocalの場合は宣言自体であり参照ではないため辿らない
133
+ }
134
+ else {
135
+ walkExpression(statement.identifier, visitor);
136
+ }
137
+ }
138
+ visitor.onBlock?.(statement.body);
139
+ return;
140
+ case "ReturnStatement":
141
+ statement.arguments.forEach((argument) => {
142
+ walkExpression(argument, visitor);
143
+ });
144
+ return;
145
+ case "BreakStatement":
146
+ case "LabelStatement":
147
+ case "GotoStatement":
148
+ return;
149
+ default: {
150
+ const exhaustive = statement;
151
+ throw new TypeError("Unknown statement type: `" + JSON.stringify(exhaustive) + "`");
152
+ }
153
+ }
154
+ }
155
+ function walkExpression(expr, visitor) {
156
+ switch (expr.type) {
157
+ case "Identifier":
158
+ visitor.onIdentifierReference?.(expr);
159
+ return;
160
+ case "StringLiteral":
161
+ case "NumericLiteral":
162
+ case "BooleanLiteral":
163
+ case "NilLiteral":
164
+ case "VarargLiteral":
165
+ return;
166
+ case "LogicalExpression":
167
+ case "BinaryExpression":
168
+ walkExpression(expr.left, visitor);
169
+ walkExpression(expr.right, visitor);
170
+ return;
171
+ case "UnaryExpression":
172
+ walkExpression(expr.argument, visitor);
173
+ return;
174
+ case "CallExpression":
175
+ walkExpression(expr.base, visitor);
176
+ expr.arguments.forEach((argument) => {
177
+ walkExpression(argument, visitor);
178
+ });
179
+ return;
180
+ case "TableCallExpression":
181
+ walkExpression(expr.base, visitor);
182
+ walkExpression(expr.arguments, visitor);
183
+ return;
184
+ case "StringCallExpression":
185
+ walkExpression(expr.base, visitor);
186
+ walkExpression(expr.argument, visitor);
187
+ return;
188
+ case "IndexExpression":
189
+ walkExpression(expr.base, visitor);
190
+ walkExpression(expr.index, visitor);
191
+ return;
192
+ case "MemberExpression":
193
+ walkExpression(expr.base, visitor);
194
+ // フィールド名(`.identifier`)は変数参照ではないため辿らない
195
+ return;
196
+ case "FunctionDeclaration":
197
+ visitor.onBlock?.(expr.body);
198
+ return;
199
+ case "TableConstructorExpression":
200
+ expr.fields.forEach((field) => {
201
+ if (field.type === "TableKey") {
202
+ walkExpression(field.key, visitor);
203
+ walkExpression(field.value, visitor);
204
+ }
205
+ else {
206
+ walkExpression(field.value, visitor);
207
+ }
208
+ });
209
+ return;
210
+ default: {
211
+ const exhaustive = expr;
212
+ throw new TypeError("Unknown expression type: `" + JSON.stringify(exhaustive) + "`");
213
+ }
214
+ }
215
+ }
216
+ function processBlock(body, resolveResult, options) {
217
+ // 先に子ブロック(ネストしたスコープ)を処理する。子ブロックは別配列なので
218
+ // このレベルでのまとめ上げには影響しない。
219
+ body.forEach((statement) => {
220
+ walkStatement(statement, {
221
+ onBlock: (nested) => {
222
+ processBlock(nested, resolveResult, options);
223
+ },
224
+ });
225
+ });
226
+ mergeRunsInPlace(body, resolveResult, options);
227
+ }
228
+ // あるexpr(候補文のinit式)の中に現れる識別子参照をすべて収集する。
229
+ // ネストした関数リテラルの本体も再帰的に辿る(ハザード1: クロージャの
230
+ // 字句スコープは実行タイミングに関わらず即座に確定するため)。
231
+ function collectIdentifierReferences(expr) {
232
+ const found = [];
233
+ const visitor = {
234
+ onIdentifierReference: (id) => found.push(id),
235
+ onBlock: (body) => {
236
+ body.forEach((s) => {
237
+ walkStatement(s, visitor);
238
+ });
239
+ },
240
+ };
241
+ walkExpression(expr, visitor);
242
+ return found;
243
+ }
244
+ // ============================================================
245
+ // ハザード判定
246
+ // ============================================================
247
+ function isExpandable(expr) {
248
+ return (expr.type === "CallExpression" ||
249
+ expr.type === "TableCallExpression" ||
250
+ expr.type === "StringCallExpression" ||
251
+ expr.type === "VarargLiteral");
252
+ }
253
+ // ハザード2(複数値展開): statementをグループの非末尾要素として
254
+ // 後ろに文を連結してよいかどうかを判定する。
255
+ // - 変数と初期化式の個数が一致: 常に安全(パディング不要)
256
+ // - 変数が多い(不足): 最後の初期化式が展開可能でなければnilパディングで安全。
257
+ // 展開可能な式に依存している場合は非末尾にできない。
258
+ // - 初期化式が多い(過剰): 常に非末尾として不安全
259
+ // (余剰の値が後続文の変数へずれ込むため、パディングでは救えない)
260
+ function classifyNonTerminal(statement) {
261
+ const varCount = statement.variables.length;
262
+ const initCount = statement.init.length;
263
+ if (varCount === initCount) {
264
+ return { safe: true, needsPadding: false };
265
+ }
266
+ if (varCount > initCount) {
267
+ const lastInit = initCount > 0 ? statement.init[initCount - 1] : undefined;
268
+ if (!lastInit || !isExpandable(lastInit)) {
269
+ return { safe: true, needsPadding: true };
270
+ }
271
+ return { safe: false };
272
+ }
273
+ return { safe: false };
274
+ }
275
+ // ハザード1(参照順序): candidateのinit式が、groupSoFarで宣言済みの
276
+ // 変数を参照していないかを判定する。参照していれば統合するとLuaの
277
+ // スコープ規則上意味が変わってしまうため、そこでグループを閉じる必要がある。
278
+ function initReferencesDeclaredInGroup(candidate, groupSoFar, resolveResult) {
279
+ const declaredInGroup = new Set();
280
+ groupSoFar.forEach((statement) => {
281
+ statement.variables.forEach((v) => {
282
+ const symbol = resolveResult.symbolOf(v);
283
+ if (symbol) {
284
+ declaredInGroup.add(symbol);
285
+ }
286
+ });
287
+ });
288
+ return candidate.init.some((expr) => collectIdentifierReferences(expr).some((id) => {
289
+ const symbol = resolveResult.symbolOf(id);
290
+ return symbol !== undefined && declaredInGroup.has(symbol);
291
+ }));
292
+ }
293
+ // ハザード4: SLモードでtrySpliceRequireStatement(#29)の対象になり得る
294
+ // `local x = require(<静的文字列>)`形式の文かどうかを判定する。
295
+ function isSpliceEligibleRequire(statement) {
296
+ if (statement.variables.length !== 1 || statement.init.length !== 1) {
297
+ return false;
298
+ }
299
+ return isStaticRequireCall(statement.init[0]);
300
+ }
301
+ function isStaticRequireCall(expr) {
302
+ if (expr.type === "CallExpression") {
303
+ return (expr.base.type === "Identifier" &&
304
+ expr.base.name === "require" &&
305
+ expr.arguments.length > 0 &&
306
+ (0, linker_1.staticStringArgument)(expr.arguments[0]) !== undefined);
307
+ }
308
+ if (expr.type === "StringCallExpression") {
309
+ return (expr.base.type === "Identifier" &&
310
+ expr.base.name === "require" &&
311
+ (0, linker_1.staticStringArgument)(expr.argument) !== undefined);
312
+ }
313
+ return false;
314
+ }
315
+ // ============================================================
316
+ // グループ化とマージ
317
+ // ============================================================
318
+ function nilLiteral() {
319
+ return { type: "NilLiteral", value: null, raw: "nil" };
320
+ }
321
+ function combineGroup(group) {
322
+ const variables = [];
323
+ const init = [];
324
+ group.forEach((statement, index) => {
325
+ variables.push(...statement.variables);
326
+ const isLast = index === group.length - 1;
327
+ init.push(...statement.init);
328
+ if (!isLast) {
329
+ const safety = classifyNonTerminal(statement);
330
+ if (safety.safe && safety.needsPadding) {
331
+ const padCount = statement.variables.length - statement.init.length;
332
+ for (let i = 0; i < padCount; i++) {
333
+ init.push(nilLiteral());
334
+ }
335
+ }
336
+ }
337
+ });
338
+ // 末尾の合成nilは、Luaが変数超過分を自動的にnilで埋めるため省略できる
339
+ // (元から書かれていた明示的なnilを末尾で省略しても意味は変わらない)。
340
+ while (init.length > 0 && init[init.length - 1].type === "NilLiteral") {
341
+ init.pop();
342
+ }
343
+ return {
344
+ type: "LocalStatement",
345
+ variables,
346
+ init,
347
+ };
348
+ }
349
+ function mergeRun(run, resolveResult, options) {
350
+ const output = [];
351
+ let groupStart = 0;
352
+ const flushGroup = (endExclusive) => {
353
+ if (endExclusive <= groupStart) {
354
+ return;
355
+ }
356
+ const group = run.slice(groupStart, endExclusive);
357
+ output.push(group.length >= 2 ? combineGroup(group) : group[0]);
358
+ };
359
+ for (let k = 0; k < run.length; k++) {
360
+ const statement = run[k];
361
+ if (options.preserveRequireSplice && isSpliceEligibleRequire(statement)) {
362
+ flushGroup(k);
363
+ output.push(statement);
364
+ groupStart = k + 1;
365
+ continue;
366
+ }
367
+ if (k === groupStart) {
368
+ continue;
369
+ }
370
+ const previous = run[k - 1];
371
+ const previousSafety = classifyNonTerminal(previous);
372
+ const referencesGroupLocal = initReferencesDeclaredInGroup(statement, run.slice(groupStart, k), resolveResult);
373
+ if (!previousSafety.safe || referencesGroupLocal) {
374
+ flushGroup(k);
375
+ groupStart = k;
376
+ }
377
+ }
378
+ flushGroup(run.length);
379
+ return output;
380
+ }
381
+ function mergeRunsInPlace(body, resolveResult, options) {
382
+ const result = [];
383
+ let i = 0;
384
+ while (i < body.length) {
385
+ const statement = body[i];
386
+ if (statement.type !== "LocalStatement") {
387
+ result.push(statement);
388
+ i++;
389
+ continue;
390
+ }
391
+ let j = i;
392
+ const run = [];
393
+ while (j < body.length && body[j].type === "LocalStatement") {
394
+ run.push(body[j]);
395
+ j++;
396
+ }
397
+ result.push(...mergeRun(run, resolveResult, options));
398
+ i = j;
399
+ }
400
+ body.splice(0, body.length, ...result);
401
+ }
package/package.json CHANGED
@@ -1,33 +1,41 @@
1
- {
2
- "name": "storm-lua-minify",
3
- "description": "A Lua minifier also outputs source map",
4
- "version": "0.2.0",
5
- "dependencies": {
6
- "commander": "^12.1.0",
7
- "luaparse": "^0.3.1",
8
- "source-map": "^0.7.4"
9
- },
10
- "devDependencies": {
11
- "@eslint/js": "^9.39.5",
12
- "@types/node": "^22.20.1",
13
- "@types/luaparse": "^0.2.13",
14
- "eslint": "^9.39.5",
15
- "eslint-config-prettier": "^10.1.8",
16
- "globals": "^17.7.0",
17
- "prettier": "^3.9.5",
18
- "ts-node": "^10.9.2",
19
- "typescript": "^5.9.3",
20
- "typescript-eslint": "^8.63.0"
21
- },
22
- "bin": "dist/cli.js",
23
- "scripts": {
24
- "start": "node ./dist/index.js",
25
- "build": "npx tsc",
26
- "test": "node -r ts-node/register/transpile-only --test \"test/**/*.test.ts\"",
27
- "lint": "eslint .",
28
- "format": "prettier --write .",
29
- "format:check": "prettier --check ."
30
- },
31
- "author": "Nona Takahara <nona_t_2612@yahoo.co.jp>",
32
- "license": "MIT"
33
- }
1
+ {
2
+ "name": "storm-lua-minify",
3
+ "description": "A Lua minifier also outputs source map",
4
+ "version": "0.3.0",
5
+ "engines": {
6
+ "node": ">=22"
7
+ },
8
+ "files": [
9
+ "dist"
10
+ ],
11
+ "dependencies": {
12
+ "commander": "^12.1.0",
13
+ "luaparse": "^0.3.1",
14
+ "source-map": "^0.7.4"
15
+ },
16
+ "devDependencies": {
17
+ "@eslint/js": "^9.39.5",
18
+ "@types/luaparse": "^0.2.13",
19
+ "@types/node": "^22.20.1",
20
+ "eslint": "^9.39.5",
21
+ "eslint-config-prettier": "^10.1.8",
22
+ "globals": "^17.7.0",
23
+ "prettier": "^3.9.5",
24
+ "typescript": "^5.9.3",
25
+ "typescript-eslint": "^8.63.0",
26
+ "vitest": "^4.1.10"
27
+ },
28
+ "author": "Nona Takahara <nona_t_2612@yahoo.co.jp>",
29
+ "license": "MIT",
30
+ "scripts": {
31
+ "start": "node ./dist/cli.js",
32
+ "build": "tsc",
33
+ "test": "tsc -p tsconfig.eslint.json && npx vitest run",
34
+ "lint": "eslint .",
35
+ "format": "prettier --write .",
36
+ "format:check": "prettier --check ."
37
+ },
38
+ "bin": {
39
+ "storm-lua-minify": "dist/cli.js"
40
+ }
41
+ }
@@ -1,39 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- - develop
8
- pull_request:
9
- branches:
10
- - main
11
- - develop
12
-
13
- jobs:
14
- build-lint-test:
15
- runs-on: ubuntu-latest
16
- steps:
17
- - name: Checkout
18
- uses: actions/checkout@v4
19
-
20
- - name: Setup Node.js
21
- uses: actions/setup-node@v4
22
- with:
23
- node-version: "22.x"
24
- cache: "npm"
25
-
26
- - name: Install dependencies
27
- run: npm ci
28
-
29
- - name: Build
30
- run: npm run build
31
-
32
- - name: Lint
33
- run: npm run lint
34
-
35
- - name: Check formatting
36
- run: npm run format:check
37
-
38
- - name: Test
39
- run: npm test
@@ -1,39 +0,0 @@
1
- name: Publish to npm
2
-
3
- # NOTE: npm publish is disabled for now (see issue #10).
4
- # Once the repository is ready to publish (NPM_TOKEN secret configured,
5
- # owner sign-off), uncomment the "Publish" step below.
6
- on:
7
- release:
8
- types: [published]
9
-
10
- jobs:
11
- publish:
12
- runs-on: ubuntu-latest
13
- steps:
14
- - name: Checkout
15
- uses: actions/checkout@v4
16
-
17
- - name: Setup Node.js
18
- uses: actions/setup-node@v4
19
- with:
20
- node-version: "22.x"
21
- cache: "npm"
22
- registry-url: "https://registry.npmjs.org"
23
-
24
- - name: Install dependencies
25
- run: npm ci
26
-
27
- - name: Build
28
- run: npm run build
29
-
30
- - name: Lint
31
- run: npm run lint
32
-
33
- - name: Test
34
- run: npm test
35
-
36
- # - name: Publish
37
- # run: npm publish
38
- # env:
39
- # NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/.prettierignore DELETED
@@ -1,3 +0,0 @@
1
- dist
2
- node_modules
3
- package-lock.json
package/.prettierrc.json DELETED
@@ -1 +0,0 @@
1
- {}
package/eslint.config.js DELETED
@@ -1,29 +0,0 @@
1
- // @ts-check
2
- const eslint = require("@eslint/js");
3
- const tseslint = require("typescript-eslint");
4
- const globals = require("globals");
5
- const eslintConfigPrettier = require("eslint-config-prettier");
6
-
7
- module.exports = tseslint.config(
8
- {
9
- ignores: ["dist/**"],
10
- },
11
- {
12
- files: ["src/**/*.ts", "test/**/*.ts"],
13
- extends: [
14
- eslint.configs.recommended,
15
- ...tseslint.configs.strictTypeChecked,
16
- ...tseslint.configs.stylistic,
17
- ],
18
- languageOptions: {
19
- globals: {
20
- ...globals.node,
21
- },
22
- parserOptions: {
23
- project: "./tsconfig.eslint.json",
24
- tsconfigRootDir: __dirname,
25
- },
26
- },
27
- },
28
- eslintConfigPrettier,
29
- );