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.
- package/dist/json/src/JsonUtils.js +64 -8
- package/dist/json/src/index.js +31 -6
- package/dist/xlsx/template/xlsx.txt +13 -13
- package/package.json +1 -1
|
@@ -13,13 +13,29 @@ class JsonUtils {
|
|
|
13
13
|
* @param options JSON 合并选项
|
|
14
14
|
*/
|
|
15
15
|
merge(options) {
|
|
16
|
-
utils_1.utils.writeJson(this.
|
|
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
|
-
|
|
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.
|
|
38
|
-
const sourceFiles = utils_1.utils
|
|
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();
|
package/dist/json/src/index.js
CHANGED
|
@@ -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
|
|
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("
|
|
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("-
|
|
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
|
-
|
|
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
|
-
|
|
8
|
+
/** 生成 1 到 10 的数字 */
|
|
9
9
|
type NumberRange = Exclude<BuildNumbers<11>, 0>;
|
|
10
10
|
|
|
11
|
-
|
|
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
|
-
|
|
20
|
+
/** Excel工作表数据 */
|
|
21
21
|
type XlsxData<T = unknown> = { [key: string]: T };
|
|
22
22
|
|
|
23
|
-
|
|
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
|
/**
|