fast-cocos 1.1.22 → 1.1.24

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.
@@ -13,13 +13,29 @@ class JsonUtils {
13
13
  * @param options JSON 合并选项
14
14
  */
15
15
  merge(options) {
16
- utils_1.utils.writeJson(this.getOutputPath(options), this.mergeJsonFiles(options));
16
+ utils_1.utils.writeJson(this.getMergeOutputPath(options), this.mergeJsonFiles(options));
17
+ }
18
+ /**
19
+ * 将单个 JSON 文件拆分为多个文件。
20
+ * @param options JSON 拆分选项
21
+ */
22
+ split(options) {
23
+ const content = utils_1.utils.readJson(options.source);
24
+ if (content == null) {
25
+ throw new Error(`source json not found: ${options.source}`);
26
+ }
27
+ utils_1.utils.mkdir(options.output);
28
+ if (options.type === "array") {
29
+ this.splitArray(content, options);
30
+ return;
31
+ }
32
+ this.splitMap(content, options);
17
33
  }
18
34
  /**
19
35
  * 获取合并结果的输出路径。
20
36
  * @param options JSON 合并选项
21
37
  */
22
- getOutputPath(options) {
38
+ getMergeOutputPath(options) {
23
39
  return path_1.default.join(options.output, options.file || DEFAULT_MERGE_FILE);
24
40
  }
25
41
  /**
@@ -30,21 +46,61 @@ class JsonUtils {
30
46
  return path_1.default.basename(filePath, path_1.default.extname(filePath));
31
47
  }
32
48
  /**
33
- * 递归读取目录中的 JSON 文件,并按文件名合并为一个对象。
49
+ * 递归读取目录中的 JSON 文件,并按 type 合并为对象映射表或数组。
34
50
  * @param options JSON 合并选项
35
51
  */
36
52
  mergeJsonFiles(options) {
37
- const outputPath = this.getOutputPath(options);
38
- const sourceFiles = utils_1.utils.findFiles(options.source, [".json"]);
53
+ const outputPath = this.getMergeOutputPath(options);
54
+ const sourceFiles = utils_1.utils
55
+ .findFiles(options.source, [".json"])
56
+ .filter((filePath) => path_1.default.resolve(filePath) !== path_1.default.resolve(outputPath));
57
+ if (options.type === "array") {
58
+ return sourceFiles.map((filePath) => utils_1.utils.readJson(filePath));
59
+ }
39
60
  const merged = {};
40
61
  // 将每个 JSON 文件内容挂到对应文件名 key 下。
41
- sourceFiles
42
- .filter((filePath) => path_1.default.resolve(filePath) !== path_1.default.resolve(outputPath))
43
- .forEach((filePath) => {
62
+ sourceFiles.forEach((filePath) => {
44
63
  const json = utils_1.utils.readJson(filePath);
45
64
  merged[this.getJsonFileKey(filePath)] = json;
46
65
  });
47
66
  return merged;
48
67
  }
68
+ /**
69
+ * 按对象 key 拆分映射表。
70
+ * @param content JSON 内容
71
+ * @param options 拆分选项
72
+ */
73
+ splitMap(content, options) {
74
+ if (Array.isArray(content) || typeof content !== "object") {
75
+ throw new Error("type=map expects a JSON object");
76
+ }
77
+ Object.entries(content).forEach(([key, value]) => {
78
+ utils_1.utils.writeJson(path_1.default.join(options.output, `${key}.json`), value);
79
+ });
80
+ }
81
+ /**
82
+ * 按指定字段拆分数组。
83
+ * @param content JSON 内容
84
+ * @param options 拆分选项
85
+ */
86
+ splitArray(content, options) {
87
+ if (!Array.isArray(content)) {
88
+ throw new Error("type=array expects a JSON array");
89
+ }
90
+ if (!options.field) {
91
+ throw new Error("split with type=array requires field");
92
+ }
93
+ const field = options.field;
94
+ content.forEach((item, index) => {
95
+ if (item == null || typeof item !== "object" || Array.isArray(item)) {
96
+ throw new Error(`array item at index ${index} is not an object`);
97
+ }
98
+ const fileName = item[field];
99
+ if (fileName == null || fileName === "") {
100
+ throw new Error(`array item at index ${index} missing field: ${field}`);
101
+ }
102
+ utils_1.utils.writeJson(path_1.default.join(options.output, `${String(fileName)}.json`), item);
103
+ });
104
+ }
49
105
  }
50
106
  exports.jsonUtils = new JsonUtils();
@@ -12,21 +12,46 @@ Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const commander_1 = require("commander");
13
13
  const JsonUtils_1 = require("./JsonUtils");
14
14
  /**
15
- * 解析 JSON 合并命令参数,并将目录中的 JSON 文件合并输出。
15
+ * 解析 JSON 合并/拆分命令参数,并执行对应操作。
16
16
  */
17
17
  function main() {
18
18
  return __awaiter(this, void 0, void 0, function* () {
19
19
  commander_1.program
20
20
  .name("json")
21
- .description("json utility")
21
+ .description("Merge or split JSON files. Default action is merge.")
22
22
  .version("1.0.0")
23
- .requiredOption("-s, --source <source>", "source directory")
23
+ .requiredOption("-s, --source <source>", "merge: source directory; split: source JSON file")
24
24
  .requiredOption("-o, --output <output>", "output directory")
25
- .option("-m, --merge <merge>")
26
- .option("-f, --file <file name>", "file name")
25
+ .option("-p, --split", "split one JSON file into multiple files", false)
26
+ .option("-f, --file <file name>", "merge: output file name (default: merge.json)")
27
+ .option("-t, --type <type>", "JSON content format: map | array", "map")
28
+ .option("-k, --field <field>", "split + array: field used as output file name")
27
29
  .parse(process.argv);
28
30
  const options = commander_1.program.opts();
29
- JsonUtils_1.jsonUtils.merge(options);
31
+ if (options.type !== "map" && options.type !== "array") {
32
+ console.error(`invalid type: ${options.type}, expected map | array`);
33
+ process.exit(1);
34
+ }
35
+ const type = options.type;
36
+ if (options.split) {
37
+ if (type === "array" && !options.field) {
38
+ console.error("split with type=array requires -k, --field <field>");
39
+ process.exit(1);
40
+ }
41
+ JsonUtils_1.jsonUtils.split({
42
+ source: options.source,
43
+ output: options.output,
44
+ type,
45
+ field: options.field
46
+ });
47
+ return;
48
+ }
49
+ JsonUtils_1.jsonUtils.merge({
50
+ source: options.source,
51
+ output: options.output,
52
+ file: options.file,
53
+ type
54
+ });
30
55
  });
31
56
  }
32
57
  // 捕获入口异步异常并以非零状态码退出。
@@ -1,32 +1,32 @@
1
- // 数字序列
1
+ /** 数字序列 */
2
2
  type BuildNumbers<N extends number, Result extends number[] = []> = Result["length"] extends N
3
3
  ? never
4
4
  : [...Result, Result["length"]] extends [infer _, ...infer Rest]
5
5
  ? Result["length"] | BuildNumbers<N, [...Result, Result["length"]]>
6
6
  : never;
7
7
 
8
- // 生成 1 到 10 的数字
8
+ /** 生成 1 到 10 的数字 */
9
9
  type NumberRange = Exclude<BuildNumbers<11>, 0>;
10
10
 
11
- // Excel版本
11
+ /** Excel版本 */
12
12
  type XlsxVersion = `v${NumberRange}`;
13
13
 
14
- // 整数
14
+ /** 整数 */
15
15
  export type int = number;
16
16
 
17
- // 浮点数
17
+ /** 浮点数 */
18
18
  export type float = number;
19
19
 
20
- // Excel工作表数据
20
+ /** Excel工作表数据 */
21
21
  type XlsxData<T = unknown> = { [key: string]: T };
22
22
 
23
- // Excel工作表管理
23
+ /** Excel工作表管理 */
24
24
  class Xlsx {
25
25
  private static _instance: Xlsx;
26
26
  public static get instance(): Xlsx {
27
27
  return Xlsx._instance ?? (Xlsx._instance = new Xlsx());
28
28
  }
29
- [key: string]: any;
29
+ // [key: string]: any;
30
30
  private readonly sheetToKey: Map<string, string>;
31
31
  {0}
32
32
  private constructor() {
@@ -35,7 +35,7 @@ class Xlsx {
35
35
  const keys = Object.keys(this).filter((it) => it != "sheetToKey");
36
36
  const values = Object.values(this);
37
37
  for (const value of values) {
38
- const key = keys.find((key) => this[key] === value);
38
+ const key = keys.find((key) => (this as any)[key] === value);
39
39
  key && this.sheetToKey.set(value, key);
40
40
  }
41
41
  }
@@ -56,24 +56,24 @@ class Xlsx {
56
56
  public updateSheet<T>(sheetName: string, data: T): void {
57
57
  const key = this.sheetToKey.get(sheetName);
58
58
  if (!key) {
59
- this[sheetName] = data;
59
+ (this as any)[sheetName] = data;
60
60
  console.warn(`强制更新表【${sheetName}】`);
61
61
  return;
62
62
  }
63
63
 
64
64
  if (sheetName.endsWith("KVMap") || (!sheetName.endsWith("VMap") && sheetName.endsWith("Map"))) {
65
- this[key] = this.toMap(data as { [key: string]: unknown });
65
+ (this as any)[key] = this.toMap(data as { [key: string]: unknown });
66
66
  return;
67
67
  }
68
68
 
69
- this[key] = data;
69
+ (this as any)[key] = data;
70
70
  }
71
71
 
72
72
  /**
73
73
  * 检查没有的配置表
74
74
  */
75
75
  public checkNotSheet(): string[] {
76
- return [...this.sheetToKey.keys()].filter((sheetName) => typeof this[sheetName] == "string");
76
+ return [...this.sheetToKey.keys()].filter((sheetName) => typeof (this as any)[sheetName] == "string");
77
77
  }
78
78
 
79
79
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fast-cocos",
3
- "version": "1.1.22",
3
+ "version": "1.1.24",
4
4
  "scripts": {
5
5
  "clean": "rm -rf dist",
6
6
  "start": "node ./dist/index.js",