expose-kit 0.5.0 → 0.7.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 CHANGED
@@ -105,7 +105,7 @@ With this alone:
105
105
  ### 3. Apply transforms step by step
106
106
 
107
107
  After `safe-scope`, combine common techniques like:
108
- - `expand-array`, `expand-object` and more
108
+ - `expand-array`, `expand-object` and more
109
109
  - legacy obfuscator-specific commands
110
110
 
111
111
  After **each step**, run `parsable` again.
@@ -175,7 +175,7 @@ Args:
175
175
 
176
176
  ---
177
177
 
178
- ### `expose expand-array`
178
+ ### `expose expand-array`
179
179
 
180
180
  Expand array index access for primitive values.
181
181
  ```js
@@ -197,35 +197,91 @@ Args:
197
197
  - `--o, --output <file>`
198
198
  Output file path
199
199
 
200
+ Notes:
201
+ - Each replacement is validated by reparsing; unsafe replacements are skipped.
202
+ (This array is intended to be immutable, so caution is required)
203
+
204
+ ---
205
+
206
+ ### `expose expand-object`
207
+
208
+ Expand object property access for primitive values.
209
+ ```js
210
+ const obj = { a: 1, b: 2 };
211
+ // before
212
+ console.log(obj.a, obj["b"]);
213
+ // after
214
+ console.log(1, 2);
215
+ ```
216
+ Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-object/mocks).
217
+
218
+ ```bash
219
+ expose expand-object path/to/file.js --target objectName --output path/to/file.expand-object.js
220
+ ```
221
+
222
+ Args:
223
+ - `--target <name>`
224
+ Target object variable name
225
+ - `--o, --output <file>`
226
+ Output file path
227
+
200
228
  Notes:
201
- - Each replacement is validated by reparsing; invalid replacements (e.g. `++a[0]` or `a[0]++`) are skipped.-
229
+ - Each replacement is validated by reparsing; unsafe replacements are skipped.
230
+ (This object is intended to be immutable, so caution is required)
202
231
 
203
232
  ---
204
233
 
205
- ### `expose expand-object`
234
+ ### `expose object-packer`
235
+
236
+ Pack consecutive object property assignments into literals.
237
+ ```js
238
+ const obj = {};
239
+ // before
240
+ obj.a = 0;
241
+ obj["b"] = 1;
242
+ // after
243
+ const obj = { a: 0, b: 1 };
244
+ ```
245
+ Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/object-packer/mocks).
246
+
247
+ ```bash
248
+ expose object-packer path/to/file.js --output path/to/file.object-packer.js
249
+ ```
250
+
251
+ Args:
252
+ - `--o, --output <file>`
253
+ Output file path
254
+
255
+ Notes:
256
+ - Packs only consecutive assignments following an empty object literal.
257
+ - Stops when a property value references the object itself.
258
+
259
+ ---
260
+
261
+ ### `expose remove-updater`
206
262
 
207
- Expand object property access for primitive values.
263
+ Replace safe update expressions with += or -=.
208
264
  ```js
209
- const obj = { a: 1, b: 2 };
210
265
  // before
211
- console.log(obj.a, obj["b"]);
266
+ a++;
267
+ --b;
212
268
  // after
213
- console.log(1, 2);
269
+ a += 1;
270
+ b -= 1;
214
271
  ```
215
- Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-object/mocks).
272
+ Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-updater/mocks).
216
273
 
217
274
  ```bash
218
- expose expand-object path/to/file.js --target objectName --output path/to/file.expand-object.js
275
+ expose remove-updater path/to/file.js --output path/to/file.remove-updater.js
219
276
  ```
220
277
 
221
278
  Args:
222
- - `--target <name>`
223
- Target object variable name
224
279
  - `--o, --output <file>`
225
280
  Output file path
226
281
 
227
282
  Notes:
228
- - Each replacement is validated by reparsing; invalid replacements are skipped.
283
+ - Only replaces update expressions whose value is not used.
284
+ - Safe for expression statements and for-loop update clauses.
229
285
 
230
286
  ---
231
287
 
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // index.ts
4
4
  import { Command } from "commander";
5
- import { dirname as dirname6, join as join6 } from "path";
5
+ import { dirname as dirname8, join as join8 } from "path";
6
6
  import { fileURLToPath } from "url";
7
7
  import chalk4 from "chalk";
8
8
 
@@ -776,7 +776,7 @@ var expand_object_default = createCommand((program2) => {
776
776
  );
777
777
  });
778
778
 
779
- // commands/pre-evaluate/index.ts
779
+ // commands/object-packer/index.ts
780
780
  import { readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
781
781
  import { basename as basename4, dirname as dirname4, extname as extname4, join as join4 } from "path";
782
782
  import { parse as parse5 } from "@babel/parser";
@@ -787,10 +787,192 @@ import loading5 from "loading-cli";
787
787
  var createDefaultOutputPath4 = (inputPath) => {
788
788
  const ext = extname4(inputPath);
789
789
  if (!ext) {
790
- return `${inputPath}.pre-evaluate.js`;
790
+ return `${inputPath}.object-packer.js`;
791
791
  }
792
792
  const base = basename4(inputPath, ext);
793
- return join4(dirname4(inputPath), `${base}.pre-evaluate${ext}`);
793
+ return join4(dirname4(inputPath), `${base}.object-packer${ext}`);
794
+ };
795
+ var isEmptyObjectExpression = (node) => {
796
+ return t3.isObjectExpression(node) && node.properties.length === 0;
797
+ };
798
+ var isPropertyAssignment = (node, objectName) => {
799
+ return t3.isAssignmentExpression(node) && t3.isMemberExpression(node.left) && t3.isIdentifier(node.left.object, { name: objectName });
800
+ };
801
+ var hasSelfReference = (value, statementPath, arrayIndex, binding, log) => {
802
+ try {
803
+ const statementContainerPath = statementPath.parentPath?.get(
804
+ `${statementPath.parentKey}.${arrayIndex}`
805
+ );
806
+ let detected = false;
807
+ patchDefault(traverse4)(
808
+ value,
809
+ {
810
+ Identifier(path) {
811
+ if (detected) return;
812
+ if (path.node.name !== binding.identifier.name) return;
813
+ if (path.scope.getBinding(binding.identifier.name) === binding) {
814
+ detected = true;
815
+ path.stop();
816
+ }
817
+ }
818
+ },
819
+ statementContainerPath.scope,
820
+ void 0,
821
+ statementContainerPath
822
+ );
823
+ return detected;
824
+ } catch (error) {
825
+ log(
826
+ `Error looking for self reference when object packing: ${error instanceof Error ? error.message : String(error)}`
827
+ );
828
+ return false;
829
+ }
830
+ };
831
+ var packObjectProperties = (code, filename) => {
832
+ const ast = parse5(code, createParseOptions(filename));
833
+ let packedCount = 0;
834
+ let removedStatements = 0;
835
+ const log = (message) => console.warn(message);
836
+ patchDefault(traverse4)(ast, {
837
+ VariableDeclarator(path) {
838
+ if (!t3.isIdentifier(path.node.id)) return;
839
+ if (!path.node.init || !isEmptyObjectExpression(path.node.init)) return;
840
+ const binding = path.scope.getBinding(path.node.id.name);
841
+ if (!binding || !binding.constant) return;
842
+ const objectExpression = path.node.init;
843
+ const statementPath = path.getStatementParent();
844
+ if (!statementPath || !statementPath.parentPath || typeof statementPath.key !== "number") {
845
+ return;
846
+ }
847
+ const statements = statementPath.parentPath.node[statementPath.parentKey];
848
+ let localRemoved = 0;
849
+ let localPacked = 0;
850
+ for (let i = statementPath.key + 1; i < statements.length; i++) {
851
+ const node = statements[i];
852
+ if (t3.isExpressionStatement(node) && isPropertyAssignment(node.expression, path.node.id.name)) {
853
+ const assignment = node.expression;
854
+ if (isPropertyAssignment(assignment.right, path.node.id.name)) {
855
+ const properties = [assignment.left];
856
+ let right = assignment.right;
857
+ while (isPropertyAssignment(right, path.node.id.name)) {
858
+ properties.push(right.left);
859
+ right = right.right;
860
+ }
861
+ if (!t3.isLiteral(right)) {
862
+ break;
863
+ }
864
+ for (const { property } of properties) {
865
+ if (t3.isPrivateName(property)) {
866
+ break;
867
+ }
868
+ const isComputed = !t3.isStringLiteral(property) && !t3.isNumericLiteral(property) && !t3.isIdentifier(property);
869
+ objectExpression.properties.push(
870
+ t3.objectProperty(
871
+ t3.cloneNode(property),
872
+ t3.cloneNode(right, true),
873
+ isComputed
874
+ )
875
+ );
876
+ localPacked += 1;
877
+ }
878
+ localRemoved += 1;
879
+ } else {
880
+ const key = assignment.left.property;
881
+ if (t3.isPrivateName(key)) {
882
+ break;
883
+ }
884
+ const isComputed = !t3.isStringLiteral(key) && !t3.isNumericLiteral(key) && !t3.isIdentifier(key);
885
+ if (hasSelfReference(assignment.right, statementPath, i, binding, log)) {
886
+ break;
887
+ }
888
+ objectExpression.properties.push(
889
+ t3.objectProperty(
890
+ t3.cloneNode(key),
891
+ t3.cloneNode(assignment.right, true),
892
+ isComputed
893
+ )
894
+ );
895
+ localPacked += 1;
896
+ localRemoved += 1;
897
+ }
898
+ } else {
899
+ break;
900
+ }
901
+ }
902
+ if (localRemoved > 0) {
903
+ statements.splice(statementPath.key + 1, localRemoved);
904
+ packedCount += localPacked;
905
+ removedStatements += localRemoved;
906
+ }
907
+ }
908
+ });
909
+ return {
910
+ code: patchDefault(generate4)(ast).code,
911
+ packedCount,
912
+ removedStatements
913
+ };
914
+ };
915
+ var object_packer_default = createCommand((program2) => {
916
+ program2.command("object-packer").description("Pack consecutive object property assignments into literals").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
917
+ async (fileArgument, options) => {
918
+ await timeout(
919
+ async ({ finish }) => {
920
+ const filename = fileArgument ?? options.file ?? await createPrompt("Enter the file path:");
921
+ if (!filename) {
922
+ showError("No file provided");
923
+ return finish();
924
+ }
925
+ try {
926
+ const fileContent = readFileSync5(filename, "utf8");
927
+ const defaultOutputPath = createDefaultOutputPath4(filename);
928
+ let outputPath = options.output;
929
+ if (!outputPath) {
930
+ const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
931
+ outputPath = promptPath || defaultOutputPath;
932
+ }
933
+ const loader = loading5("Packing object properties...").start();
934
+ try {
935
+ const { code: output, packedCount, removedStatements } = packObjectProperties(fileContent, filename);
936
+ writeFileSync4(outputPath, output, "utf8");
937
+ loader.succeed(
938
+ `Saved object-packer file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${packedCount} properties packed, ${removedStatements} statements removed)`
939
+ );
940
+ return finish();
941
+ } catch (error) {
942
+ loader.fail("Failed to apply object-packer transform");
943
+ showError(
944
+ `Error transforming file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
945
+ );
946
+ return finish();
947
+ }
948
+ } catch (error) {
949
+ showError(
950
+ `Error reading file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
951
+ );
952
+ return finish();
953
+ }
954
+ },
955
+ options.unlimited ? null : 120 * 1e3
956
+ );
957
+ }
958
+ );
959
+ });
960
+
961
+ // commands/pre-evaluate/index.ts
962
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
963
+ import { basename as basename5, dirname as dirname5, extname as extname5, join as join5 } from "path";
964
+ import { parse as parse6 } from "@babel/parser";
965
+ import traverse5 from "@babel/traverse";
966
+ import generate5 from "@babel/generator";
967
+ import * as t4 from "@babel/types";
968
+ import loading6 from "loading-cli";
969
+ var createDefaultOutputPath5 = (inputPath) => {
970
+ const ext = extname5(inputPath);
971
+ if (!ext) {
972
+ return `${inputPath}.pre-evaluate.js`;
973
+ }
974
+ const base = basename5(inputPath, ext);
975
+ return join5(dirname5(inputPath), `${base}.pre-evaluate${ext}`);
794
976
  };
795
977
  var isSupportedNumberOperator = (operator) => {
796
978
  return operator === "-" || operator === "*" || operator === "/" || operator === "%" || operator === "**" || operator === "<<" || operator === ">>" || operator === ">>>" || operator === "|" || operator === "&" || operator === "^";
@@ -924,13 +1106,13 @@ var shouldSkipReferencedIdentifier = (path) => {
924
1106
  return false;
925
1107
  };
926
1108
  var preEvaluate = (code, filename) => {
927
- const ast = parse5(code, createParseOptions(filename));
1109
+ const ast = parse6(code, createParseOptions(filename));
928
1110
  const state = {
929
1111
  bindingValues: /* @__PURE__ */ new Map(),
930
1112
  bindingStack: /* @__PURE__ */ new Set()
931
1113
  };
932
1114
  let replacedCount = 0;
933
- patchDefault(traverse4)(ast, {
1115
+ patchDefault(traverse5)(ast, {
934
1116
  ReferencedIdentifier(path) {
935
1117
  if (shouldSkipReferencedIdentifier(path)) {
936
1118
  return;
@@ -938,9 +1120,9 @@ var preEvaluate = (code, filename) => {
938
1120
  const value = evaluateExpression(path, state);
939
1121
  if (value === null) return;
940
1122
  if (typeof value === "number") {
941
- path.replaceWith(t3.numericLiteral(value));
1123
+ path.replaceWith(t4.numericLiteral(value));
942
1124
  } else {
943
- path.replaceWith(t3.stringLiteral(value));
1125
+ path.replaceWith(t4.stringLiteral(value));
944
1126
  }
945
1127
  replacedCount += 1;
946
1128
  },
@@ -949,9 +1131,9 @@ var preEvaluate = (code, filename) => {
949
1131
  const value = evaluateExpression(path, state);
950
1132
  if (value === null) return;
951
1133
  if (typeof value === "number") {
952
- path.replaceWith(t3.numericLiteral(value));
1134
+ path.replaceWith(t4.numericLiteral(value));
953
1135
  } else {
954
- path.replaceWith(t3.stringLiteral(value));
1136
+ path.replaceWith(t4.stringLiteral(value));
955
1137
  }
956
1138
  replacedCount += 1;
957
1139
  }
@@ -961,9 +1143,9 @@ var preEvaluate = (code, filename) => {
961
1143
  const value = evaluateExpression(path, state);
962
1144
  if (value === null) return;
963
1145
  if (typeof value === "number") {
964
- path.replaceWith(t3.numericLiteral(value));
1146
+ path.replaceWith(t4.numericLiteral(value));
965
1147
  } else {
966
- path.replaceWith(t3.stringLiteral(value));
1148
+ path.replaceWith(t4.stringLiteral(value));
967
1149
  }
968
1150
  replacedCount += 1;
969
1151
  }
@@ -973,16 +1155,16 @@ var preEvaluate = (code, filename) => {
973
1155
  const value = evaluateExpression(path, state);
974
1156
  if (value === null) return;
975
1157
  if (typeof value === "number") {
976
- path.replaceWith(t3.numericLiteral(value));
1158
+ path.replaceWith(t4.numericLiteral(value));
977
1159
  } else {
978
- path.replaceWith(t3.stringLiteral(value));
1160
+ path.replaceWith(t4.stringLiteral(value));
979
1161
  }
980
1162
  replacedCount += 1;
981
1163
  }
982
1164
  }
983
1165
  });
984
1166
  return {
985
- code: patchDefault(generate4)(ast).code,
1167
+ code: patchDefault(generate5)(ast).code,
986
1168
  replacedCount
987
1169
  };
988
1170
  };
@@ -997,20 +1179,20 @@ var pre_evaluate_default = createCommand((program2) => {
997
1179
  return finish();
998
1180
  }
999
1181
  try {
1000
- const fileContent = readFileSync5(filename, "utf8");
1001
- const defaultOutputPath = createDefaultOutputPath4(filename);
1182
+ const fileContent = readFileSync6(filename, "utf8");
1183
+ const defaultOutputPath = createDefaultOutputPath5(filename);
1002
1184
  let outputPath = options.output;
1003
1185
  if (!outputPath) {
1004
1186
  const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
1005
1187
  outputPath = promptPath || defaultOutputPath;
1006
1188
  }
1007
- const loader = loading5("Pre-evaluating constants...").start();
1189
+ const loader = loading6("Pre-evaluating constants...").start();
1008
1190
  try {
1009
1191
  const { code: output, replacedCount } = preEvaluate(
1010
1192
  fileContent,
1011
1193
  filename
1012
1194
  );
1013
- writeFileSync4(outputPath, output, "utf8");
1195
+ writeFileSync5(outputPath, output, "utf8");
1014
1196
  loader.succeed(
1015
1197
  `Saved pre-evaluate file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${replacedCount} replacements)`
1016
1198
  );
@@ -1035,30 +1217,124 @@ var pre_evaluate_default = createCommand((program2) => {
1035
1217
  );
1036
1218
  });
1037
1219
 
1220
+ // commands/remove-updater/index.ts
1221
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
1222
+ import { basename as basename6, dirname as dirname6, extname as extname6, join as join6 } from "path";
1223
+ import { parse as parse7 } from "@babel/parser";
1224
+ import traverse6 from "@babel/traverse";
1225
+ import generate6 from "@babel/generator";
1226
+ import * as t5 from "@babel/types";
1227
+ import loading7 from "loading-cli";
1228
+ var createDefaultOutputPath6 = (inputPath) => {
1229
+ const ext = extname6(inputPath);
1230
+ if (!ext) {
1231
+ return `${inputPath}.remove-updater.js`;
1232
+ }
1233
+ const base = basename6(inputPath, ext);
1234
+ return join6(dirname6(inputPath), `${base}.remove-updater${ext}`);
1235
+ };
1236
+ var isSafeStandaloneUpdate = (path) => {
1237
+ const parent = path.parentPath;
1238
+ if (!parent) return false;
1239
+ if (parent.isExpressionStatement()) return true;
1240
+ if (parent.isForStatement() && path.key === "update") return true;
1241
+ return false;
1242
+ };
1243
+ var removeUpdaters = (code, filename) => {
1244
+ const ast = parse7(code, createParseOptions(filename));
1245
+ let replacedCount = 0;
1246
+ patchDefault(traverse6)(ast, {
1247
+ UpdateExpression(path) {
1248
+ if (!isSafeStandaloneUpdate(path)) return;
1249
+ const operator = path.node.operator === "++" ? "+=" : "-=";
1250
+ const left = t5.cloneNode(path.node.argument, true);
1251
+ const replacement = t5.assignmentExpression(
1252
+ operator,
1253
+ left,
1254
+ t5.numericLiteral(1)
1255
+ );
1256
+ path.replaceWith(replacement);
1257
+ replacedCount += 1;
1258
+ }
1259
+ });
1260
+ return {
1261
+ code: patchDefault(generate6)(ast).code,
1262
+ replacedCount
1263
+ };
1264
+ };
1265
+ var remove_updater_default = createCommand((program2) => {
1266
+ program2.command("remove-updater").description("Replace safe update expressions with += or -=").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
1267
+ async (fileArgument, options) => {
1268
+ await timeout(
1269
+ async ({ finish }) => {
1270
+ const filename = fileArgument ?? options.file ?? await createPrompt("Enter the file path:");
1271
+ if (!filename) {
1272
+ showError("No file provided");
1273
+ return finish();
1274
+ }
1275
+ try {
1276
+ const fileContent = readFileSync7(filename, "utf8");
1277
+ const defaultOutputPath = createDefaultOutputPath6(filename);
1278
+ let outputPath = options.output;
1279
+ if (!outputPath) {
1280
+ const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
1281
+ outputPath = promptPath || defaultOutputPath;
1282
+ }
1283
+ const loader = loading7("Removing update expressions...").start();
1284
+ try {
1285
+ const { code: output, replacedCount } = removeUpdaters(
1286
+ fileContent,
1287
+ filename
1288
+ );
1289
+ writeFileSync6(outputPath, output, "utf8");
1290
+ loader.succeed(
1291
+ `Saved remove-updater file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${replacedCount} updates replaced)`
1292
+ );
1293
+ return finish();
1294
+ } catch (error) {
1295
+ loader.fail("Failed to apply remove-updater transform");
1296
+ showError(
1297
+ `Error transforming file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
1298
+ );
1299
+ return finish();
1300
+ }
1301
+ } catch (error) {
1302
+ showError(
1303
+ `Error reading file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
1304
+ );
1305
+ return finish();
1306
+ }
1307
+ },
1308
+ options.unlimited ? null : 120 * 1e3
1309
+ );
1310
+ }
1311
+ );
1312
+ });
1313
+
1038
1314
  // commands/remove-unused/index.ts
1039
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
1040
- import { basename as basename5, dirname as dirname5, extname as extname5, join as join5 } from "path";
1041
- import { parse as parse6 } from "@babel/parser";
1042
- import traverse5 from "@babel/traverse";
1043
- import generate5 from "@babel/generator";
1044
- import * as t4 from "@babel/types";
1045
- import loading6 from "loading-cli";
1046
- var createDefaultOutputPath5 = (inputPath) => {
1047
- const ext = extname5(inputPath);
1315
+ import { readFileSync as readFileSync8, writeFileSync as writeFileSync7 } from "fs";
1316
+ import { basename as basename7, dirname as dirname7, extname as extname7, join as join7 } from "path";
1317
+ import { parse as parse8 } from "@babel/parser";
1318
+ import traverse7 from "@babel/traverse";
1319
+ import generate7 from "@babel/generator";
1320
+ import * as t6 from "@babel/types";
1321
+ import loading8 from "loading-cli";
1322
+ var createDefaultOutputPath7 = (inputPath) => {
1323
+ const ext = extname7(inputPath);
1048
1324
  if (!ext) {
1049
1325
  return `${inputPath}.remove-unused.js`;
1050
1326
  }
1051
- const base = basename5(inputPath, ext);
1052
- return join5(dirname5(inputPath), `${base}.remove-unused${ext}`);
1327
+ const base = basename7(inputPath, ext);
1328
+ return join7(dirname7(inputPath), `${base}.remove-unused${ext}`);
1053
1329
  };
1054
1330
  var removeUnusedVariables = (code, filename) => {
1055
- const ast = parse6(code, createParseOptions(filename));
1331
+ const ast = parse8(code, createParseOptions(filename));
1056
1332
  let changed = false;
1057
- patchDefault(traverse5)(ast, {
1333
+ patchDefault(traverse7)(ast, {
1058
1334
  Scope(path) {
1059
1335
  for (const binding of Object.values(path.scope.bindings)) {
1060
1336
  if (!binding.referenced && binding.constantViolations.length === 0 && binding.path.key !== "handler" && !binding.path.isFunctionExpression()) {
1061
- if (t4.isProgram(binding.scope.block) && (binding.kind === "var" || binding.kind === "hoisted")) {
1337
+ if (t6.isProgram(binding.scope.block) && (binding.kind === "var" || binding.kind === "hoisted")) {
1062
1338
  continue;
1063
1339
  }
1064
1340
  const targets = binding.path.parentKey === "params" ? [...binding.referencePaths, ...binding.constantViolations] : [
@@ -1067,11 +1343,11 @@ var removeUnusedVariables = (code, filename) => {
1067
1343
  ...binding.constantViolations
1068
1344
  ];
1069
1345
  for (const targetPath of targets) {
1070
- if (targetPath.isVariableDeclarator() && (t4.isArrayPattern(targetPath.node.id) && targetPath.node.id.elements.length > 1 || t4.isObjectPattern(targetPath.node.id) && targetPath.node.id.properties.length > 1)) {
1346
+ if (targetPath.isVariableDeclarator() && (t6.isArrayPattern(targetPath.node.id) && targetPath.node.id.elements.length > 1 || t6.isObjectPattern(targetPath.node.id) && targetPath.node.id.properties.length > 1)) {
1071
1347
  continue;
1072
1348
  }
1073
1349
  if (targetPath.key === "consequent" || targetPath.key === "alternate" || targetPath.key === "body") {
1074
- targetPath.replaceWith(t4.blockStatement([]));
1350
+ targetPath.replaceWith(t6.blockStatement([]));
1075
1351
  } else {
1076
1352
  const parentPath = targetPath.parentPath;
1077
1353
  if (parentPath?.isVariableDeclaration() && parentPath.node.declarations.length === 1) {
@@ -1087,7 +1363,7 @@ var removeUnusedVariables = (code, filename) => {
1087
1363
  }
1088
1364
  });
1089
1365
  return {
1090
- code: patchDefault(generate5)(ast).code,
1366
+ code: patchDefault(generate7)(ast).code,
1091
1367
  changed
1092
1368
  };
1093
1369
  };
@@ -1102,20 +1378,20 @@ var remove_unused_default = createCommand((program2) => {
1102
1378
  return finish();
1103
1379
  }
1104
1380
  try {
1105
- const fileContent = readFileSync6(filename, "utf8");
1106
- const defaultOutputPath = createDefaultOutputPath5(filename);
1381
+ const fileContent = readFileSync8(filename, "utf8");
1382
+ const defaultOutputPath = createDefaultOutputPath7(filename);
1107
1383
  let outputPath = options.output;
1108
1384
  if (!outputPath) {
1109
1385
  const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
1110
1386
  outputPath = promptPath || defaultOutputPath;
1111
1387
  }
1112
- const loader = loading6("Removing unused variables...").start();
1388
+ const loader = loading8("Removing unused variables...").start();
1113
1389
  try {
1114
1390
  const { code: output, changed } = removeUnusedVariables(
1115
1391
  fileContent,
1116
1392
  filename
1117
1393
  );
1118
- writeFileSync5(outputPath, output, "utf8");
1394
+ writeFileSync7(outputPath, output, "utf8");
1119
1395
  const diffLines = diff(fileContent, output).length;
1120
1396
  loader.succeed(
1121
1397
  `Saved remove-unused file to: ${outputPath} (${diffLines} lines changed${changed ? ", removed unused declarations" : ", no changes"})`
@@ -1165,10 +1441,10 @@ var calmGradienrain = (text) => {
1165
1441
  const endHue = 300;
1166
1442
  const saturation = 0.45;
1167
1443
  const value = 0.8;
1168
- const ease = (t5) => t5 * t5 * (3 - 2 * t5);
1444
+ const ease = (t7) => t7 * t7 * (3 - 2 * t7);
1169
1445
  return text.split("").map((char, i) => {
1170
- const t5 = ease(i / Math.max(text.length - 1, 1));
1171
- const hue = startHue + (endHue - startHue) * t5;
1446
+ const t7 = ease(i / Math.max(text.length - 1, 1));
1447
+ const hue = startHue + (endHue - startHue) * t7;
1172
1448
  const c = value * saturation;
1173
1449
  const h = hue / 60;
1174
1450
  const x = c * (1 - Math.abs(h % 2 - 1));
@@ -1192,10 +1468,10 @@ ${calmGradienrain(`Expose Kit v${VERSION}`)}
1192
1468
  `;
1193
1469
 
1194
1470
  // index.ts
1195
- import { readFileSync as readFileSync7 } from "fs";
1471
+ import { readFileSync as readFileSync9 } from "fs";
1196
1472
  var __filename = fileURLToPath(import.meta.url);
1197
- var __dirname = dirname6(__filename);
1198
- var pkg = JSON.parse(readFileSync7(join6(__dirname, "package.json"), "utf8"));
1473
+ var __dirname = dirname8(__filename);
1474
+ var pkg = JSON.parse(readFileSync9(join8(__dirname, "package.json"), "utf8"));
1199
1475
  console.log(showCredit(pkg.version));
1200
1476
  console.log();
1201
1477
  var program = new Command();
@@ -1209,7 +1485,9 @@ var commands = [
1209
1485
  safe_scope_default,
1210
1486
  expand_array_default,
1211
1487
  expand_object_default,
1488
+ object_packer_default,
1212
1489
  pre_evaluate_default,
1490
+ remove_updater_default,
1213
1491
  remove_unused_default
1214
1492
  ];
1215
1493
  for (const command of commands) {
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expose-kit",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "author": "EdamAmex <edame8080@gmail.com> (https://github.com/EdamAme-x)",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expose-kit",
3
- "version": "0.5.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "author": "EdamAmex <edame8080@gmail.com> (https://github.com/EdamAme-x)",