@ainc/fs 0.1.15 → 0.1.16
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/helpers/stripComments.d.ts.map +1 -1
- package/dist/helpers/stripComments.js +46 -44
- package/dist/helpers/stripComments.js.map +1 -1
- package/dist/jsonc.d.ts +7 -1
- package/dist/jsonc.d.ts.map +1 -1
- package/dist/jsonc.js +17 -8
- package/dist/jsonc.js.map +1 -1
- package/package.json +1 -1
- package/src/helpers/stripComments.ts +57 -51
- package/src/jsonc.ts +21 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stripComments.d.ts","sourceRoot":"","sources":["../../src/helpers/stripComments.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stripComments.d.ts","sourceRoot":"","sources":["../../src/helpers/stripComments.ts"],"names":[],"mappings":"AA6GA;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAyDrD"}
|
|
@@ -21,20 +21,6 @@ function isEscaped(index, source) {
|
|
|
21
21
|
// 判断是否转义
|
|
22
22
|
return count % 2;
|
|
23
23
|
}
|
|
24
|
-
/**
|
|
25
|
-
*****************************************
|
|
26
|
-
* 判断是否为结尾的逗号
|
|
27
|
-
*****************************************
|
|
28
|
-
*/
|
|
29
|
-
function isTrailingComma(start, source) {
|
|
30
|
-
let ch = source[start];
|
|
31
|
-
// 过滤空白字符
|
|
32
|
-
while (' \n\r'.indexOf(ch) > -1) {
|
|
33
|
-
ch = source[++start];
|
|
34
|
-
}
|
|
35
|
-
// 返回是否为结束符
|
|
36
|
-
return '}]'.indexOf(ch) > -1;
|
|
37
|
-
}
|
|
38
24
|
/**
|
|
39
25
|
*****************************************
|
|
40
26
|
* 查找字符串结束
|
|
@@ -82,64 +68,80 @@ function indexBlockCommentEnd(start, source) {
|
|
|
82
68
|
return indexBlockCommentEnd(idx + 1, source);
|
|
83
69
|
}
|
|
84
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
*****************************************
|
|
73
|
+
* 过滤末尾逗号
|
|
74
|
+
*****************************************
|
|
75
|
+
*/
|
|
76
|
+
function stripTrailingComma(buffer, offset) {
|
|
77
|
+
let idx = offset - 1;
|
|
78
|
+
let code = buffer[idx];
|
|
79
|
+
// 路过空白字符
|
|
80
|
+
while ([0x20, 0x0a, 0x0d].includes(buffer[idx])) {
|
|
81
|
+
idx--;
|
|
82
|
+
code = buffer[idx];
|
|
83
|
+
}
|
|
84
|
+
// 判断为非逗号
|
|
85
|
+
if (code !== 0x2c) {
|
|
86
|
+
return offset;
|
|
87
|
+
}
|
|
88
|
+
// 移动字符
|
|
89
|
+
while (idx < offset) {
|
|
90
|
+
buffer[idx] = buffer[++idx];
|
|
91
|
+
}
|
|
92
|
+
// 返回新索引
|
|
93
|
+
return offset - 1;
|
|
94
|
+
}
|
|
85
95
|
/**
|
|
86
96
|
*****************************************
|
|
87
97
|
* 过滤注释
|
|
88
98
|
*****************************************
|
|
89
99
|
*/
|
|
90
100
|
function stripComments(content) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
let
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
101
|
+
const size = content.length;
|
|
102
|
+
const buffer = Buffer.alloc(3 * size);
|
|
103
|
+
// 定义索引位置
|
|
104
|
+
let idx = content.charCodeAt(0) === 0xFEFF ? 1 : 0;
|
|
105
|
+
let offset = 0;
|
|
106
|
+
// 写入内容
|
|
107
|
+
function write(value) {
|
|
108
|
+
// 去除末尾的逗号
|
|
109
|
+
if (value === ']' || value === '}') {
|
|
110
|
+
offset = stripTrailingComma(buffer, offset);
|
|
111
|
+
}
|
|
112
|
+
// 写入内容
|
|
113
|
+
offset += buffer.write(value, offset, 'utf8');
|
|
98
114
|
}
|
|
99
115
|
// 遍历字符
|
|
100
|
-
while (idx <
|
|
101
|
-
|
|
116
|
+
while (idx < size) {
|
|
117
|
+
let ch = content.charAt(idx);
|
|
102
118
|
// 跳过字符串
|
|
103
119
|
if (ch === '"' || ch === '\'') {
|
|
104
|
-
idx = indexStringEnd(idx + 1, ch, content);
|
|
120
|
+
write(content.slice(idx, idx = indexStringEnd(idx + 1, ch, content)));
|
|
105
121
|
continue;
|
|
106
122
|
}
|
|
107
123
|
// 自增偏移
|
|
108
124
|
idx++;
|
|
109
|
-
// 判断是为结尾的逗号
|
|
110
|
-
if (ch === ',' && isTrailingComma(idx, content)) {
|
|
111
|
-
result += content.slice(start, idx - 1);
|
|
112
|
-
start = idx;
|
|
113
|
-
idx = start + 1;
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
125
|
// 非注释
|
|
117
126
|
if (ch !== '/') {
|
|
127
|
+
write(ch);
|
|
118
128
|
continue;
|
|
119
129
|
}
|
|
120
130
|
// 获取下一字符
|
|
121
|
-
const next = content
|
|
131
|
+
const next = content.charAt(idx);
|
|
122
132
|
// 处理行注释
|
|
123
133
|
if (next === '/') {
|
|
124
|
-
|
|
125
|
-
start = indexLineCommentEnd(idx + 1, content);
|
|
126
|
-
idx = start + 1;
|
|
134
|
+
idx = indexLineCommentEnd(idx + 1, content);
|
|
127
135
|
continue;
|
|
128
136
|
}
|
|
129
137
|
// 处理多行注释
|
|
130
138
|
if (next === '*') {
|
|
131
|
-
|
|
132
|
-
start = indexBlockCommentEnd(idx + 2, content);
|
|
133
|
-
idx = start;
|
|
139
|
+
idx = indexBlockCommentEnd(idx + 2, content);
|
|
134
140
|
continue;
|
|
135
141
|
}
|
|
136
142
|
}
|
|
137
|
-
//
|
|
138
|
-
|
|
139
|
-
result += content.slice(start);
|
|
140
|
-
}
|
|
141
|
-
// 返回结果
|
|
142
|
-
return result;
|
|
143
|
+
// 输出结果
|
|
144
|
+
return buffer.slice(0, offset).toString('utf8');
|
|
143
145
|
}
|
|
144
146
|
exports.stripComments = stripComments;
|
|
145
147
|
//# sourceMappingURL=stripComments.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stripComments.js","sourceRoot":"","sources":["../../src/helpers/stripComments.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,CAAC;;;AAGb;;;;GAIG;AACH,SAAS,SAAS,CAAC,KAAa,EAAE,MAAc;IAC5C,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,SAAS;IACT,OAAO,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE;QACnC,KAAK,EAAG,CAAC;KACZ;IAED,SAAS;IACT,OAAO,KAAK,GAAG,CAAC,CAAC;AACrB,CAAC;AAGD;;;;GAIG;AACH,SAAS,
|
|
1
|
+
{"version":3,"file":"stripComments.js","sourceRoot":"","sources":["../../src/helpers/stripComments.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,CAAC;;;AAGb;;;;GAIG;AACH,SAAS,SAAS,CAAC,KAAa,EAAE,MAAc;IAC5C,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,SAAS;IACT,OAAO,MAAM,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,EAAE;QACnC,KAAK,EAAG,CAAC;KACZ;IAED,SAAS;IACT,OAAO,KAAK,GAAG,CAAC,CAAC;AACrB,CAAC;AAGD;;;;GAIG;AACH,SAAS,cAAc,CAAC,KAAa,EAAE,EAAU,EAAE,MAAc;IAC7D,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAEtC,WAAW;IACX,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE;QACZ,OAAO,MAAM,CAAC,MAAM,CAAC;KACxB;SAAM;QACH,OAAO,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;KACjF;AACL,CAAC;AAGD;;;;GAIG;AACH,SAAS,mBAAmB,CAAC,KAAa,EAAE,MAAc;IACtD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAExC,WAAW;IACX,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE;QACZ,OAAO,MAAM,CAAC,MAAM,CAAC;KACxB;SAAM;QACH,OAAO,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;KACnD;AACL,CAAC;AAGD;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,KAAa,EAAE,MAAc;IACvD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEvC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE;QACZ,OAAO,MAAM,CAAC,MAAM,CAAC;KACxB;SAAM,IAAI,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE;QAChC,OAAO,GAAG,GAAG,CAAC,CAAC;KAClB;SAAM;QACH,OAAO,oBAAoB,CAAC,GAAG,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;KAChD;AACL,CAAC;AAGD;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,MAAc,EAAE,MAAc;IACtD,IAAI,GAAG,GAAG,MAAM,GAAG,CAAC,CAAC;IACrB,IAAI,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAEvB,SAAS;IACT,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE;QAC7C,GAAG,EAAG,CAAC;QACP,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;KACtB;IAED,SAAS;IACT,IAAI,IAAI,KAAK,IAAI,EAAE;QACf,OAAO,MAAM,CAAC;KACjB;IAED,OAAO;IACP,OAAO,GAAG,GAAG,MAAM,EAAE;QACjB,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,EAAG,GAAG,CAAC,CAAC;KAChC;IAED,QAAQ;IACR,OAAO,MAAM,GAAG,CAAC,CAAC;AACtB,CAAC;AAGD;;;;GAIG;AACH,SAAgB,aAAa,CAAC,OAAe;IACzC,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEtC,SAAS;IACT,IAAI,GAAG,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,OAAO;IACP,SAAS,KAAK,CAAC,KAAa;QAExB,UAAU;QACV,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE;YAChC,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;SAC/C;QAED,OAAO;QACP,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAED,OAAO;IACP,OAAO,GAAG,GAAG,IAAI,EAAE;QACf,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAE7B,QAAQ;QACR,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE;YAC3B,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,cAAc,CAAC,GAAG,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;YACtE,SAAS;SACZ;QAED,OAAO;QACP,GAAG,EAAG,CAAC;QAEP,MAAM;QACN,IAAI,EAAE,KAAK,GAAG,EAAE;YACZ,KAAK,CAAC,EAAE,CAAC,CAAC;YACV,SAAS;SACZ;QAED,SAAS;QACT,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEjC,QAAQ;QACR,IAAI,IAAI,KAAK,GAAG,EAAE;YACd,GAAG,GAAG,mBAAmB,CAAC,GAAG,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;YAC5C,SAAS;SACZ;QAED,SAAS;QACT,IAAI,IAAI,KAAK,GAAG,EAAE;YACd,GAAG,GAAG,oBAAoB,CAAC,GAAG,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;YAC7C,SAAS;SACZ;KACJ;IAED,OAAO;IACP,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACpD,CAAC;AAzDD,sCAyDC"}
|
package/dist/jsonc.d.ts
CHANGED
|
@@ -6,6 +6,12 @@
|
|
|
6
6
|
interface Data {
|
|
7
7
|
[key: string]: unknown;
|
|
8
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
*****************************************
|
|
11
|
+
* 解析内容
|
|
12
|
+
*****************************************
|
|
13
|
+
*/
|
|
14
|
+
declare function parse<T = Data>(content: string): T | null;
|
|
9
15
|
/**
|
|
10
16
|
*****************************************
|
|
11
17
|
* 读取/写入【jsonc】文件
|
|
@@ -18,5 +24,5 @@ declare function jsonc<T = Data>(path: string, data: T): T;
|
|
|
18
24
|
* 抛出接口
|
|
19
25
|
*****************************************
|
|
20
26
|
*/
|
|
21
|
-
export { jsonc };
|
|
27
|
+
export { jsonc, parse };
|
|
22
28
|
//# sourceMappingURL=jsonc.d.ts.map
|
package/dist/jsonc.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonc.d.ts","sourceRoot":"","sources":["../src/jsonc.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,UAAU,IAAI;IACV,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAGD;;;;GAIG;AACH,iBAAS,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC;AACjD,iBAAS,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"jsonc.d.ts","sourceRoot":"","sources":["../src/jsonc.ts"],"names":[],"mappings":"AAoBA;;;;GAIG;AACH,UAAU,IAAI;IACV,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAGD;;;;GAIG;AACH,iBAAS,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAUlD;AAGD;;;;GAIG;AACH,iBAAS,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,IAAI,CAAC;AACjD,iBAAS,KAAK,CAAC,CAAC,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;AAqBnD;;;;GAIG;AACH,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC"}
|
package/dist/jsonc.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
'use strict';
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.jsonc = void 0;
|
|
9
|
+
exports.parse = exports.jsonc = void 0;
|
|
10
10
|
/**
|
|
11
11
|
*****************************************
|
|
12
12
|
* 加载依赖
|
|
@@ -16,6 +16,20 @@ const stat_1 = require("./stat");
|
|
|
16
16
|
const readFile_1 = require("./readFile");
|
|
17
17
|
const writeFile_1 = require("./writeFile");
|
|
18
18
|
const stripComments_1 = require("./helpers/stripComments");
|
|
19
|
+
/**
|
|
20
|
+
*****************************************
|
|
21
|
+
* 解析内容
|
|
22
|
+
*****************************************
|
|
23
|
+
*/
|
|
24
|
+
function parse(content) {
|
|
25
|
+
// 格式化内容
|
|
26
|
+
content = (0, stripComments_1.stripComments)(content);
|
|
27
|
+
// 打印输出
|
|
28
|
+
// console.log(content);
|
|
29
|
+
// 解析文件
|
|
30
|
+
return content ? JSON.parse(content) : null;
|
|
31
|
+
}
|
|
32
|
+
exports.parse = parse;
|
|
19
33
|
function jsonc(...args) {
|
|
20
34
|
const [name, data] = args;
|
|
21
35
|
// 读写数据
|
|
@@ -24,14 +38,9 @@ function jsonc(...args) {
|
|
|
24
38
|
}
|
|
25
39
|
else {
|
|
26
40
|
const stats = (0, stat_1.stat)(name);
|
|
41
|
+
// 解析文件
|
|
27
42
|
if (stats && stats.isFile()) {
|
|
28
|
-
|
|
29
|
-
// 空白文件
|
|
30
|
-
if (!content.trim()) {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
// 解析文件
|
|
34
|
-
return JSON.parse(content);
|
|
43
|
+
return parse((0, readFile_1.readFile)(stats.path));
|
|
35
44
|
}
|
|
36
45
|
}
|
|
37
46
|
// 返回数据
|
package/dist/jsonc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jsonc.js","sourceRoot":"","sources":["../src/jsonc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,CAAC;;;AAGb;;;;GAIG;AACH,iCAA8B;AAC9B,yCAAsC;AACtC,2CAAwC;AACxC,2DAAwD;
|
|
1
|
+
{"version":3,"file":"jsonc.js","sourceRoot":"","sources":["../src/jsonc.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,YAAY,CAAC;;;AAGb;;;;GAIG;AACH,iCAA8B;AAC9B,yCAAsC;AACtC,2CAAwC;AACxC,2DAAwD;AAaxD;;;;GAIG;AACH,SAAS,KAAK,CAAW,OAAe;IAEpC,QAAQ;IACR,OAAO,GAAG,IAAA,6BAAa,EAAC,OAAO,CAAC,CAAC;IAEjC,OAAO;IACP,wBAAwB;IAExB,OAAO;IACP,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAmCe,sBAAK;AAzBrB,SAAS,KAAK,CAAW,GAAG,IAA4B;IACpD,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;IAE1B,OAAO;IACP,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;QACjB,IAAA,qBAAS,EAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;KACzC;SAAM;QACH,MAAM,KAAK,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,CAAC;QAEzB,OAAO;QACP,IAAI,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE;YACzB,OAAO,KAAK,CAAC,IAAA,mBAAQ,EAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;SACtC;KACJ;IAED,OAAO;IACP,OAAO,IAAI,IAAI,IAAI,CAAC;AACxB,CAAC;AAQQ,sBAAK"}
|
package/package.json
CHANGED
|
@@ -25,24 +25,6 @@ function isEscaped(index: number, source: string): number {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
/**
|
|
29
|
-
*****************************************
|
|
30
|
-
* 判断是否为结尾的逗号
|
|
31
|
-
*****************************************
|
|
32
|
-
*/
|
|
33
|
-
function isTrailingComma(start: number, source: string): boolean {
|
|
34
|
-
let ch = source[start];
|
|
35
|
-
|
|
36
|
-
// 过滤空白字符
|
|
37
|
-
while (' \n\r'.indexOf(ch) > -1) {
|
|
38
|
-
ch = source[++ start];
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// 返回是否为结束符
|
|
42
|
-
return '}]'.indexOf(ch) > -1;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
28
|
/**
|
|
47
29
|
*****************************************
|
|
48
30
|
* 查找字符串结束
|
|
@@ -95,73 +77,97 @@ function indexBlockCommentEnd(start: number, source: string): number {
|
|
|
95
77
|
}
|
|
96
78
|
|
|
97
79
|
|
|
80
|
+
/**
|
|
81
|
+
*****************************************
|
|
82
|
+
* 过滤末尾逗号
|
|
83
|
+
*****************************************
|
|
84
|
+
*/
|
|
85
|
+
function stripTrailingComma(buffer: Buffer, offset: number): number {
|
|
86
|
+
let idx = offset - 1;
|
|
87
|
+
let code = buffer[idx];
|
|
88
|
+
|
|
89
|
+
// 路过空白字符
|
|
90
|
+
while ([0x20, 0x0a, 0x0d].includes(buffer[idx])) {
|
|
91
|
+
idx --;
|
|
92
|
+
code = buffer[idx];
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 判断为非逗号
|
|
96
|
+
if (code !== 0x2c) {
|
|
97
|
+
return offset;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 移动字符
|
|
101
|
+
while (idx < offset) {
|
|
102
|
+
buffer[idx] = buffer[++ idx];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 返回新索引
|
|
106
|
+
return offset - 1;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
98
110
|
/**
|
|
99
111
|
*****************************************
|
|
100
112
|
* 过滤注释
|
|
101
113
|
*****************************************
|
|
102
114
|
*/
|
|
103
115
|
export function stripComments(content: string): string {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
116
|
+
const size = content.length;
|
|
117
|
+
const buffer = Buffer.alloc(3 * size);
|
|
118
|
+
|
|
119
|
+
// 定义索引位置
|
|
120
|
+
let idx = content.charCodeAt(0) === 0xFEFF ? 1 : 0;
|
|
121
|
+
let offset = 0;
|
|
122
|
+
|
|
123
|
+
// 写入内容
|
|
124
|
+
function write(value: string): void {
|
|
125
|
+
|
|
126
|
+
// 去除末尾的逗号
|
|
127
|
+
if (value === ']' || value === '}') {
|
|
128
|
+
offset = stripTrailingComma(buffer, offset);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 写入内容
|
|
132
|
+
offset += buffer.write(value, offset, 'utf8');
|
|
112
133
|
}
|
|
113
134
|
|
|
114
135
|
// 遍历字符
|
|
115
|
-
while (idx <
|
|
116
|
-
|
|
136
|
+
while (idx < size) {
|
|
137
|
+
let ch = content.charAt(idx);
|
|
117
138
|
|
|
118
139
|
// 跳过字符串
|
|
119
140
|
if (ch === '"' || ch === '\'') {
|
|
120
|
-
idx = indexStringEnd(idx + 1, ch, content);
|
|
141
|
+
write(content.slice(idx, idx = indexStringEnd(idx + 1, ch, content)));
|
|
121
142
|
continue;
|
|
122
143
|
}
|
|
123
144
|
|
|
124
145
|
// 自增偏移
|
|
125
146
|
idx ++;
|
|
126
147
|
|
|
127
|
-
// 判断是为结尾的逗号
|
|
128
|
-
if (ch === ',' && isTrailingComma(idx, content)) {
|
|
129
|
-
result += content.slice(start, idx - 1);
|
|
130
|
-
start = idx;
|
|
131
|
-
idx = start + 1;
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
148
|
// 非注释
|
|
136
149
|
if (ch !== '/') {
|
|
150
|
+
write(ch);
|
|
137
151
|
continue;
|
|
138
152
|
}
|
|
139
153
|
|
|
140
154
|
// 获取下一字符
|
|
141
|
-
const next = content
|
|
155
|
+
const next = content.charAt(idx);
|
|
142
156
|
|
|
143
157
|
// 处理行注释
|
|
144
158
|
if (next === '/') {
|
|
145
|
-
|
|
146
|
-
start = indexLineCommentEnd(idx + 1, content);
|
|
147
|
-
idx = start + 1;
|
|
159
|
+
idx = indexLineCommentEnd(idx + 1, content);
|
|
148
160
|
continue;
|
|
149
161
|
}
|
|
150
162
|
|
|
151
163
|
// 处理多行注释
|
|
152
164
|
if (next === '*') {
|
|
153
|
-
|
|
154
|
-
start = indexBlockCommentEnd(idx + 2, content);
|
|
155
|
-
idx = start;
|
|
165
|
+
idx = indexBlockCommentEnd(idx + 2, content);
|
|
156
166
|
continue;
|
|
157
167
|
}
|
|
158
168
|
}
|
|
159
169
|
|
|
160
|
-
//
|
|
161
|
-
|
|
162
|
-
result += content.slice(start);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// 返回结果
|
|
166
|
-
return result;
|
|
170
|
+
// 输出结果
|
|
171
|
+
return buffer.slice(0, offset).toString('utf8');
|
|
167
172
|
}
|
|
173
|
+
|
package/src/jsonc.ts
CHANGED
|
@@ -28,6 +28,24 @@ interface Data {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
*****************************************
|
|
33
|
+
* 解析内容
|
|
34
|
+
*****************************************
|
|
35
|
+
*/
|
|
36
|
+
function parse<T = Data>(content: string): T | null {
|
|
37
|
+
|
|
38
|
+
// 格式化内容
|
|
39
|
+
content = stripComments(content);
|
|
40
|
+
|
|
41
|
+
// 打印输出
|
|
42
|
+
// console.log(content);
|
|
43
|
+
|
|
44
|
+
// 解析文件
|
|
45
|
+
return content ? JSON.parse(content) : null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
31
49
|
/**
|
|
32
50
|
*****************************************
|
|
33
51
|
* 读取/写入【jsonc】文件
|
|
@@ -44,16 +62,9 @@ function jsonc<T = Data>(...args: [string] | [string, T]): T | null {
|
|
|
44
62
|
} else {
|
|
45
63
|
const stats = stat(name);
|
|
46
64
|
|
|
65
|
+
// 解析文件
|
|
47
66
|
if (stats && stats.isFile()) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
// 空白文件
|
|
51
|
-
if (!content.trim()) {
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// 解析文件
|
|
56
|
-
return JSON.parse(content);
|
|
67
|
+
return parse(readFile(stats.path));
|
|
57
68
|
}
|
|
58
69
|
}
|
|
59
70
|
|
|
@@ -67,4 +78,4 @@ function jsonc<T = Data>(...args: [string] | [string, T]): T | null {
|
|
|
67
78
|
* 抛出接口
|
|
68
79
|
*****************************************
|
|
69
80
|
*/
|
|
70
|
-
export { jsonc };
|
|
81
|
+
export { jsonc, parse };
|