mihomo-cli 3.3.0 → 3.4.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/CHANGELOG.md +20 -0
- package/dist/index.js +332 -190
- package/package.json +5 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [3.4.0] - 2026-08-15
|
|
4
|
+
|
|
5
|
+
### 修复
|
|
6
|
+
|
|
7
|
+
- **配置 `controller_secret` 后测速与热重载失效** - 访问 external-controller 的 HTTP 客户端从不发送 `Authorization`,设置密钥后 `test`/`clean`(走主实例)所有节点返回 401 被判失败,保活的配置热重载也恒 401 回退到 sudo 重启。现测速(主实例)与热重载请求均携带 `Bearer <secret>`;隔离测速实例自身无密钥,不受影响
|
|
8
|
+
- **并行更新订阅时缓存临时文件互相踩踏** - `atomicWriteFileSync` 的临时文件名仅含 pid,同进程 `Promise.all` 并行更新多个订阅时写向同名临时文件,导致内容交错或 `rename` 失败。临时名改为 pid + 进程内自增序号,各写入落到独立临时文件
|
|
9
|
+
|
|
10
|
+
### 安全
|
|
11
|
+
|
|
12
|
+
- **YAML 别名炸弹 DoS 防护(回归修复)** - 解析订阅/覆写/运行时配置的 `yaml.load` 未设别名上限,js-yaml 默认无限制,恶意配置可借指数级别名膨胀耗尽内存/CPU。现统一设 `maxAliases` 上限
|
|
13
|
+
- **序列化对歧义标量加引号** - 配置序列化改用会给 `on`/`off`/`yes`/`no` 等歧义标量加引号的默认 schema。此前裸输出的 `name: on` 虽被 mihomo(go-yaml v3)读作字符串,但流经 PyYAML 等 YAML 1.1 工具会被误解析为布尔,造成静默的配置损坏
|
|
14
|
+
- **内核下载文件名路径穿越防护** - 下载内核时临时路径直接拼接 GitHub API 返回的 asset 名,被篡改的响应/镜像可借 `../` 写出内核目录之外。现用 `basename` 剥离目录成分
|
|
15
|
+
- **`open` 命令 URL 参数注入防护** - 打开订阅页面/日志文件时,服务器可控的 URL(订阅响应头 `web_page_url`)若以 `-` 开头会被 `open` 当作选项。现加 `--` 终止选项解析
|
|
16
|
+
- **测速实例终止前校验进程身份** - 停止隔离测速实例时按 pid 文件裸值 `SIGKILL`,pid 被系统复用后可能误杀无关进程。现杀进程前校验其命令行确属该测速实例
|
|
17
|
+
|
|
18
|
+
### 变更
|
|
19
|
+
|
|
20
|
+
- **覆写 `~proxies` 注入的节点纳入 include-all 排除** - `~key` 就地合并在同名节点不存在时会追加新节点,此前只有 `+proxies`/`proxies+` 注入的节点会从 `include-all` 分组排除,`~proxies` 追加的节点会被重复纳入。现一并排除
|
|
21
|
+
- **依赖升级** - `js-yaml` 5.2.1 → 5.3.0(修复 flow collections 指数解析 DoS)、`esbuild` 经 overrides 提升至 0.28.2(修复 dev server 任意文件读取)、`@types/node` → 26、`@biomejs/biome` → 2.5.8、`lint-staged`/`tsx` 跟随最新;`npm audit` 无告警
|
|
22
|
+
|
|
3
23
|
## [3.3.0] - 2026-08-15
|
|
4
24
|
|
|
5
25
|
### 新增
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,6 @@ import fs4 from "fs";
|
|
|
6
6
|
|
|
7
7
|
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
8
8
|
var NOT_RESOLVED = /* @__PURE__ */ Symbol("NOT_RESOLVED");
|
|
9
|
-
var MERGE_KEY = /* @__PURE__ */ Symbol("MERGE_KEY");
|
|
10
9
|
function defineScalarTag(tagName, options) {
|
|
11
10
|
return {
|
|
12
11
|
tagName,
|
|
@@ -15,9 +14,9 @@ function defineScalarTag(tagName, options) {
|
|
|
15
14
|
matchByTagPrefix: options.matchByTagPrefix ?? false,
|
|
16
15
|
implicitFirstChars: options.implicitFirstChars ?? null,
|
|
17
16
|
resolve: options.resolve,
|
|
18
|
-
identify: options.identify
|
|
17
|
+
identify: options.identify,
|
|
19
18
|
represent: options.represent ?? ((data) => String(data)),
|
|
20
|
-
representTagName: options.representTagName ??
|
|
19
|
+
representTagName: options.representTagName ?? (() => tagName)
|
|
21
20
|
};
|
|
22
21
|
}
|
|
23
22
|
function defineSequenceTag(tagName, options) {
|
|
@@ -31,9 +30,9 @@ function defineSequenceTag(tagName, options) {
|
|
|
31
30
|
addItem: options.addItem,
|
|
32
31
|
finalize: options.finalize ?? ((carrier) => carrier),
|
|
33
32
|
carrierIsResult,
|
|
34
|
-
identify: options.identify
|
|
33
|
+
identify: options.identify,
|
|
35
34
|
represent: options.represent ?? ((data) => data),
|
|
36
|
-
representTagName: options.representTagName ??
|
|
35
|
+
representTagName: options.representTagName ?? (() => tagName)
|
|
37
36
|
};
|
|
38
37
|
}
|
|
39
38
|
function defineMappingTag(tagName, options) {
|
|
@@ -50,9 +49,9 @@ function defineMappingTag(tagName, options) {
|
|
|
50
49
|
get: options.get,
|
|
51
50
|
finalize: options.finalize ?? ((carrier) => carrier),
|
|
52
51
|
carrierIsResult,
|
|
53
|
-
identify: options.identify
|
|
52
|
+
identify: options.identify,
|
|
54
53
|
represent: options.represent ?? ((data) => data),
|
|
55
|
-
representTagName: options.representTagName ??
|
|
54
|
+
representTagName: options.representTagName ?? (() => tagName)
|
|
56
55
|
};
|
|
57
56
|
}
|
|
58
57
|
var strTag = defineScalarTag("tag:yaml.org,2002:str", {
|
|
@@ -401,9 +400,10 @@ var mergeTag = defineScalarTag("tag:yaml.org,2002:merge", {
|
|
|
401
400
|
implicit: true,
|
|
402
401
|
implicitFirstChars: ["<"],
|
|
403
402
|
resolve: (source, isExplicit) => {
|
|
404
|
-
if (source === "<<" || isExplicit && source === "") return
|
|
403
|
+
if (source === "<<" || isExplicit && source === "") return "<<";
|
|
405
404
|
return NOT_RESOLVED;
|
|
406
|
-
}
|
|
405
|
+
},
|
|
406
|
+
identify: () => false
|
|
407
407
|
});
|
|
408
408
|
var BASE64_PATTERN = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
409
409
|
function resolveYamlBinary(source) {
|
|
@@ -426,6 +426,11 @@ var binaryTag = defineScalarTag("tag:yaml.org,2002:binary", {
|
|
|
426
426
|
});
|
|
427
427
|
var YAML_DATE_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9])-([0-9][0-9])$");
|
|
428
428
|
var YAML_TIMESTAMP_REGEXP = /* @__PURE__ */ new RegExp("^([0-9][0-9][0-9][0-9])-([0-9][0-9]?)-([0-9][0-9]?)(?:[Tt]|[ \\t]+)([0-9][0-9]?):([0-9][0-9]):([0-9][0-9])(?:\\.([0-9]*))?(?:[ \\t]*(Z|([-+])([0-9][0-9]?)(?::([0-9][0-9]))?))?$");
|
|
429
|
+
function makeUtcDate(year, month, day, hour = 0, minute = 0, second = 0, fraction = 0) {
|
|
430
|
+
const date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
|
|
431
|
+
date.setUTCFullYear(year, month, day);
|
|
432
|
+
return date;
|
|
433
|
+
}
|
|
429
434
|
function resolveYamlTimestamp(source) {
|
|
430
435
|
let match = YAML_DATE_REGEXP.exec(source);
|
|
431
436
|
if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(source);
|
|
@@ -434,7 +439,7 @@ function resolveYamlTimestamp(source) {
|
|
|
434
439
|
const month = +match[2] - 1;
|
|
435
440
|
const day = +match[3];
|
|
436
441
|
if (!match[4]) {
|
|
437
|
-
const date2 =
|
|
442
|
+
const date2 = makeUtcDate(year, month, day);
|
|
438
443
|
if (date2.getUTCFullYear() !== year || date2.getUTCMonth() !== month || date2.getUTCDate() !== day) return NOT_RESOLVED;
|
|
439
444
|
return date2;
|
|
440
445
|
}
|
|
@@ -448,7 +453,7 @@ function resolveYamlTimestamp(source) {
|
|
|
448
453
|
while (value.length < 3) value += "0";
|
|
449
454
|
fraction = +value;
|
|
450
455
|
}
|
|
451
|
-
const date =
|
|
456
|
+
const date = makeUtcDate(year, month, day, hour, minute, second, fraction);
|
|
452
457
|
if (date.getUTCFullYear() !== year || date.getUTCMonth() !== month || date.getUTCDate() !== day) return NOT_RESOLVED;
|
|
453
458
|
if (match[9]) {
|
|
454
459
|
const offsetHour = +match[10];
|
|
@@ -503,7 +508,8 @@ var omapTag = defineSequenceTag("tag:yaml.org,2002:omap", {
|
|
|
503
508
|
carrier.list.push(item);
|
|
504
509
|
return "";
|
|
505
510
|
},
|
|
506
|
-
finalize: (carrier) => carrier.list
|
|
511
|
+
finalize: (carrier) => carrier.list,
|
|
512
|
+
identify: () => false
|
|
507
513
|
});
|
|
508
514
|
var pairsTag = defineSequenceTag("tag:yaml.org,2002:pairs", {
|
|
509
515
|
create: () => [],
|
|
@@ -519,7 +525,8 @@ var pairsTag = defineSequenceTag("tag:yaml.org,2002:pairs", {
|
|
|
519
525
|
if (keys.length !== 1) return "cannot resolve a pairs item";
|
|
520
526
|
container.push([keys[0], object[keys[0]]]);
|
|
521
527
|
return "";
|
|
522
|
-
}
|
|
528
|
+
},
|
|
529
|
+
identify: () => false
|
|
523
530
|
});
|
|
524
531
|
var mapTag = defineMappingTag("tag:yaml.org,2002:map", {
|
|
525
532
|
create: () => ({}),
|
|
@@ -546,7 +553,11 @@ var mapTag = defineMappingTag("tag:yaml.org,2002:map", {
|
|
|
546
553
|
return Object.prototype.hasOwnProperty.call(container, String(key));
|
|
547
554
|
},
|
|
548
555
|
keys: (container) => Object.keys(container),
|
|
549
|
-
get: (container, key) =>
|
|
556
|
+
get: (container, key) => {
|
|
557
|
+
const normalizedKey = String(key);
|
|
558
|
+
if (!Object.prototype.hasOwnProperty.call(container, normalizedKey)) return null;
|
|
559
|
+
return container[normalizedKey];
|
|
560
|
+
}
|
|
550
561
|
});
|
|
551
562
|
var setTag = defineMappingTag("tag:yaml.org,2002:set", {
|
|
552
563
|
create: () => /* @__PURE__ */ new Set(),
|
|
@@ -567,9 +578,9 @@ var setTag = defineMappingTag("tag:yaml.org,2002:set", {
|
|
|
567
578
|
});
|
|
568
579
|
function createTagDefinitionMap() {
|
|
569
580
|
return {
|
|
570
|
-
scalar:
|
|
571
|
-
sequence:
|
|
572
|
-
mapping:
|
|
581
|
+
scalar: /* @__PURE__ */ Object.create(null),
|
|
582
|
+
sequence: /* @__PURE__ */ Object.create(null),
|
|
583
|
+
mapping: /* @__PURE__ */ Object.create(null)
|
|
573
584
|
};
|
|
574
585
|
}
|
|
575
586
|
function createTagDefinitionListMap() {
|
|
@@ -596,11 +607,35 @@ function compileTags(tags) {
|
|
|
596
607
|
}
|
|
597
608
|
var Schema = class Schema2 {
|
|
598
609
|
tags;
|
|
610
|
+
/** @internal */
|
|
599
611
|
implicitScalarTags;
|
|
612
|
+
/**
|
|
613
|
+
* Dispatch implicit scalar resolvers by `source.charAt(0)`. Each bucket holds
|
|
614
|
+
* the resolvers that may match that key, in schema order; a key absent from
|
|
615
|
+
* the map uses
|
|
616
|
+
* {@link Schema.implicitScalarAnyFirstChar}
|
|
617
|
+
* (resolvers that declared no first-char constraint, so they apply to any
|
|
618
|
+
* first character).
|
|
619
|
+
*/
|
|
600
620
|
implicitScalarByFirstChar;
|
|
601
621
|
implicitScalarAnyFirstChar;
|
|
622
|
+
/**
|
|
623
|
+
* The default scalar tag (`!!str`), resolved once so the composer's fallback
|
|
624
|
+
* for unresolved plain scalars avoids a keyed lookup per scalar.
|
|
625
|
+
*
|
|
626
|
+
* @internal
|
|
627
|
+
*/
|
|
602
628
|
defaultScalarTag;
|
|
629
|
+
/**
|
|
630
|
+
* The default container tags (`!!seq` / `!!map`), used by the dumper: when a
|
|
631
|
+
* value is identified by its default tag, the tag is implicit and not
|
|
632
|
+
* printed. Undefined if the schema does not define them (then such values
|
|
633
|
+
* can't be dumped).
|
|
634
|
+
*
|
|
635
|
+
* @internal
|
|
636
|
+
*/
|
|
603
637
|
defaultSequenceTag;
|
|
638
|
+
/** @internal */
|
|
604
639
|
defaultMappingTag;
|
|
605
640
|
exact;
|
|
606
641
|
prefix;
|
|
@@ -646,6 +681,52 @@ var Schema = class Schema2 {
|
|
|
646
681
|
this.exact = exact;
|
|
647
682
|
this.prefix = prefix;
|
|
648
683
|
}
|
|
684
|
+
/** @internal */
|
|
685
|
+
lookupScalarTag(tagName) {
|
|
686
|
+
const exactTag = this.exact.scalar[tagName];
|
|
687
|
+
if (exactTag) return exactTag;
|
|
688
|
+
for (const tag of this.prefix.scalar) if (tagName.startsWith(tag.tagName)) return tag;
|
|
689
|
+
}
|
|
690
|
+
/** @internal */
|
|
691
|
+
lookupSequenceTag(tagName) {
|
|
692
|
+
const exactTag = this.exact.sequence[tagName];
|
|
693
|
+
if (exactTag) return exactTag;
|
|
694
|
+
for (const tag of this.prefix.sequence) if (tagName.startsWith(tag.tagName)) return tag;
|
|
695
|
+
}
|
|
696
|
+
/** @internal */
|
|
697
|
+
lookupMappingTag(tagName) {
|
|
698
|
+
const exactTag = this.exact.mapping[tagName];
|
|
699
|
+
if (exactTag) return exactTag;
|
|
700
|
+
for (const tag of this.prefix.mapping) if (tagName.startsWith(tag.tagName)) return tag;
|
|
701
|
+
}
|
|
702
|
+
/** @internal */
|
|
703
|
+
resolveImplicitScalarTag(source) {
|
|
704
|
+
const candidates = this.implicitScalarByFirstChar.get(source.charAt(0)) ?? this.implicitScalarAnyFirstChar;
|
|
705
|
+
for (const tag2 of candidates) {
|
|
706
|
+
const value = tag2.resolve(source, false, tag2.tagName);
|
|
707
|
+
if (value !== NOT_RESOLVED) return {
|
|
708
|
+
value,
|
|
709
|
+
tag: tag2
|
|
710
|
+
};
|
|
711
|
+
}
|
|
712
|
+
const tag = this.defaultScalarTag;
|
|
713
|
+
return {
|
|
714
|
+
value: tag.resolve(source, false, tag.tagName),
|
|
715
|
+
tag
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Creates a new schema with the specified tags added. If a tag already
|
|
720
|
+
* exists, it is replaced by the specified tag.
|
|
721
|
+
*
|
|
722
|
+
* @example
|
|
723
|
+
*
|
|
724
|
+
* ```javascript
|
|
725
|
+
* import { CORE_SCHEMA, mergeTag, realMapTag } from 'js-yaml'
|
|
726
|
+
*
|
|
727
|
+
* const schema = CORE_SCHEMA.withTags(mergeTag, realMapTag)
|
|
728
|
+
* ```
|
|
729
|
+
*/
|
|
649
730
|
withTags(...tags) {
|
|
650
731
|
let flatTags = [];
|
|
651
732
|
for (const tag of tags) flatTags = flatTags.concat(tag);
|
|
@@ -684,6 +765,19 @@ var YAML11_SCHEMA = new Schema([
|
|
|
684
765
|
pairsTag,
|
|
685
766
|
setTag
|
|
686
767
|
]);
|
|
768
|
+
var DUMP_SCHEMA = YAML11_SCHEMA.withTags({
|
|
769
|
+
...intYaml11Tag,
|
|
770
|
+
resolve: (source, isExplicit, tagName) => {
|
|
771
|
+
const result = intYaml11Tag.resolve(source, isExplicit, tagName);
|
|
772
|
+
return result === NOT_RESOLVED ? intCoreTag.resolve(source, isExplicit, tagName) : result;
|
|
773
|
+
}
|
|
774
|
+
}, {
|
|
775
|
+
...floatYaml11Tag,
|
|
776
|
+
resolve: (source, isExplicit, tagName) => {
|
|
777
|
+
const result = floatYaml11Tag.resolve(source, isExplicit, tagName);
|
|
778
|
+
return result === NOT_RESOLVED ? floatCoreTag.resolve(source, isExplicit, tagName) : result;
|
|
779
|
+
}
|
|
780
|
+
});
|
|
687
781
|
var realMapTag = defineMappingTag("tag:yaml.org,2002:map", {
|
|
688
782
|
create: () => /* @__PURE__ */ new Map(),
|
|
689
783
|
addPair: (container, key, value) => {
|
|
@@ -739,7 +833,11 @@ var legacyMapTag = defineMappingTag("tag:yaml.org,2002:map", {
|
|
|
739
833
|
return normalizedKey !== null && Object.prototype.hasOwnProperty.call(container, normalizedKey);
|
|
740
834
|
},
|
|
741
835
|
keys: (container) => Object.keys(container),
|
|
742
|
-
get: (container, key) =>
|
|
836
|
+
get: (container, key) => {
|
|
837
|
+
const normalizedKey = String(key);
|
|
838
|
+
if (!Object.prototype.hasOwnProperty.call(container, normalizedKey)) return null;
|
|
839
|
+
return container[normalizedKey];
|
|
840
|
+
}
|
|
743
841
|
});
|
|
744
842
|
var DEFAULT_SNIPPET_OPTIONS = {
|
|
745
843
|
maxLength: 79,
|
|
@@ -816,9 +914,13 @@ function formatError(exception, compact) {
|
|
|
816
914
|
${exception.mark.snippet}`;
|
|
817
915
|
return `${exception.reason} ${where}`;
|
|
818
916
|
}
|
|
819
|
-
var YAMLException = class extends Error {
|
|
917
|
+
var YAMLException = class YAMLException2 extends Error {
|
|
820
918
|
reason;
|
|
821
919
|
mark;
|
|
920
|
+
/**
|
|
921
|
+
* Optional `mark` contains source snippet data. Usually, use
|
|
922
|
+
* {@link YAMLException.throwAt} instead of passing it directly.
|
|
923
|
+
*/
|
|
822
924
|
constructor(reason, mark) {
|
|
823
925
|
super();
|
|
824
926
|
this.name = "YAMLException";
|
|
@@ -827,34 +929,65 @@ var YAMLException = class extends Error {
|
|
|
827
929
|
this.message = formatError(this, false);
|
|
828
930
|
if (Error.captureStackTrace) Error.captureStackTrace(this, this.constructor);
|
|
829
931
|
}
|
|
932
|
+
/**
|
|
933
|
+
* Returns the formatted error, omitting the source snippet in compact mode.
|
|
934
|
+
*/
|
|
830
935
|
toString(compact) {
|
|
831
936
|
return `${this.name}: ${formatError(this, compact)}`;
|
|
832
937
|
}
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
938
|
+
/**
|
|
939
|
+
* Builds a YAMLException with a source snippet and throws it. `source` is
|
|
940
|
+
* the raw input text; `position` is an offset into it.
|
|
941
|
+
*/
|
|
942
|
+
static throwAt(source, position, message, filename = "") {
|
|
943
|
+
let line = 0;
|
|
944
|
+
let lineStart = 0;
|
|
945
|
+
for (let index = 0; index < position; index++) {
|
|
946
|
+
const ch = source.charCodeAt(index);
|
|
947
|
+
if (ch === 10) {
|
|
948
|
+
line++;
|
|
949
|
+
lineStart = index + 1;
|
|
950
|
+
} else if (ch === 13) {
|
|
951
|
+
line++;
|
|
952
|
+
if (source.charCodeAt(index + 1) === 10) index++;
|
|
953
|
+
lineStart = index + 1;
|
|
954
|
+
}
|
|
846
955
|
}
|
|
956
|
+
const mark = {
|
|
957
|
+
name: filename,
|
|
958
|
+
buffer: source,
|
|
959
|
+
position,
|
|
960
|
+
line,
|
|
961
|
+
column: position - lineStart
|
|
962
|
+
};
|
|
963
|
+
mark.snippet = makeSnippet(mark);
|
|
964
|
+
throw new YAMLException2(message, mark);
|
|
847
965
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
966
|
+
};
|
|
967
|
+
var EVENT_ID = {
|
|
968
|
+
DOCUMENT: 1,
|
|
969
|
+
SEQUENCE: 2,
|
|
970
|
+
MAPPING: 3,
|
|
971
|
+
SCALAR: 4,
|
|
972
|
+
ALIAS: 5,
|
|
973
|
+
POP: 6
|
|
974
|
+
};
|
|
975
|
+
var SCALAR_STYLE = {
|
|
976
|
+
PLAIN: 1,
|
|
977
|
+
SINGLE_QUOTED: 2,
|
|
978
|
+
DOUBLE_QUOTED: 3,
|
|
979
|
+
LITERAL_BLOCK: 4,
|
|
980
|
+
FOLDED_BLOCK: 5
|
|
981
|
+
};
|
|
982
|
+
var COLLECTION_STYLE = {
|
|
983
|
+
BLOCK: 1,
|
|
984
|
+
FLOW: 2
|
|
985
|
+
};
|
|
986
|
+
var CHOMPING_MODE = {
|
|
987
|
+
CLIP: 1,
|
|
988
|
+
STRIP: 2,
|
|
989
|
+
KEEP: 3
|
|
990
|
+
};
|
|
858
991
|
var NO_RANGE$3 = -1;
|
|
859
992
|
function simpleEscapeSequence(c) {
|
|
860
993
|
switch (c) {
|
|
@@ -1052,8 +1185,8 @@ function getBlockValue(input, start2, end, indent, chomping, folded) {
|
|
|
1052
1185
|
didReadContent = true;
|
|
1053
1186
|
emptyLines = 0;
|
|
1054
1187
|
}
|
|
1055
|
-
if (chomping ===
|
|
1056
|
-
else if (chomping !==
|
|
1188
|
+
if (chomping === CHOMPING_MODE.KEEP) result += "\n".repeat(didReadContent ? 1 + emptyLines : emptyLines);
|
|
1189
|
+
else if (chomping !== CHOMPING_MODE.STRIP) {
|
|
1057
1190
|
if (didReadContent) result += "\n";
|
|
1058
1191
|
}
|
|
1059
1192
|
return result;
|
|
@@ -1063,22 +1196,22 @@ function getScalarValue(input, scalar) {
|
|
|
1063
1196
|
const { valueStart, valueEnd } = scalar;
|
|
1064
1197
|
if (scalar.fast) return input.slice(valueStart, valueEnd);
|
|
1065
1198
|
switch (scalar.style) {
|
|
1066
|
-
case
|
|
1199
|
+
case SCALAR_STYLE.SINGLE_QUOTED:
|
|
1067
1200
|
return getSingleQuotedValue(input, valueStart, valueEnd);
|
|
1068
|
-
case
|
|
1201
|
+
case SCALAR_STYLE.DOUBLE_QUOTED:
|
|
1069
1202
|
return getDoubleQuotedValue(input, valueStart, valueEnd);
|
|
1070
|
-
case
|
|
1203
|
+
case SCALAR_STYLE.LITERAL_BLOCK:
|
|
1071
1204
|
return getBlockValue(input, valueStart, valueEnd, scalar.indent, scalar.chomping, false);
|
|
1072
|
-
case
|
|
1205
|
+
case SCALAR_STYLE.FOLDED_BLOCK:
|
|
1073
1206
|
return getBlockValue(input, valueStart, valueEnd, scalar.indent, scalar.chomping, true);
|
|
1074
1207
|
default:
|
|
1075
1208
|
return getPlainValue(input, valueStart, valueEnd);
|
|
1076
1209
|
}
|
|
1077
1210
|
}
|
|
1078
|
-
var DEFAULT_TAG_HANDLERS = {
|
|
1211
|
+
var DEFAULT_TAG_HANDLERS = Object.assign(/* @__PURE__ */ Object.create(null), {
|
|
1079
1212
|
"!": "!",
|
|
1080
1213
|
"!!": "tag:yaml.org,2002:"
|
|
1081
|
-
};
|
|
1214
|
+
});
|
|
1082
1215
|
function tagPercentEncode(source) {
|
|
1083
1216
|
return encodeURI(source).replace(/!/g, "%21");
|
|
1084
1217
|
}
|
|
@@ -1099,6 +1232,7 @@ function tagNameShort(fullTag) {
|
|
|
1099
1232
|
return `!<${tagPercentEncode(tag)}>`;
|
|
1100
1233
|
}
|
|
1101
1234
|
var NO_RANGE$2 = -1;
|
|
1235
|
+
var MERGE_TAG_NAME = "tag:yaml.org,2002:merge";
|
|
1102
1236
|
var DEFAULT_CONSTRUCTOR_OPTIONS = {
|
|
1103
1237
|
filename: "",
|
|
1104
1238
|
schema: CORE_SCHEMA,
|
|
@@ -1114,26 +1248,16 @@ function eventPosition$1(event) {
|
|
|
1114
1248
|
return 0;
|
|
1115
1249
|
}
|
|
1116
1250
|
function throwError$1(state, message) {
|
|
1117
|
-
|
|
1251
|
+
YAMLException.throwAt(state.source, state.position, message, state.filename);
|
|
1118
1252
|
}
|
|
1119
1253
|
function finalizeCollection(state, position, tag, carrier) {
|
|
1120
1254
|
try {
|
|
1121
1255
|
return tag.finalize(carrier);
|
|
1122
1256
|
} catch (error) {
|
|
1123
1257
|
if (error instanceof YAMLException) throw error;
|
|
1124
|
-
|
|
1258
|
+
YAMLException.throwAt(state.source, position, error instanceof Error ? error.message : String(error), state.filename);
|
|
1125
1259
|
}
|
|
1126
1260
|
}
|
|
1127
|
-
function lookupTag(exact, prefix, tagName) {
|
|
1128
|
-
const exactTag = exact[tagName];
|
|
1129
|
-
if (exactTag) return exactTag;
|
|
1130
|
-
for (const tag of prefix) if (tagName.startsWith(tag.tagName)) return tag;
|
|
1131
|
-
}
|
|
1132
|
-
function findExplicitTag(state, exact, prefix, tagName, nodeKind) {
|
|
1133
|
-
const tag = lookupTag(exact, prefix, tagName);
|
|
1134
|
-
if (tag) return tag;
|
|
1135
|
-
throwError$1(state, `unknown ${nodeKind} tag !<${tagName}>`);
|
|
1136
|
-
}
|
|
1137
1261
|
function constructScalar(state, event) {
|
|
1138
1262
|
const source = getScalarValue(state.source, event);
|
|
1139
1263
|
const rawTag = event.tagStart === NO_RANGE$2 ? "" : state.source.slice(event.tagStart, event.tagEnd);
|
|
@@ -1144,7 +1268,7 @@ function constructScalar(state, event) {
|
|
|
1144
1268
|
tag: strTag2
|
|
1145
1269
|
};
|
|
1146
1270
|
const tagName = tagNameFull(rawTag, state.tagHandlers);
|
|
1147
|
-
const scalarTag =
|
|
1271
|
+
const scalarTag = state.schema.lookupScalarTag(tagName);
|
|
1148
1272
|
if (scalarTag) {
|
|
1149
1273
|
const result = scalarTag.resolve(source, true, tagName);
|
|
1150
1274
|
if (result === NOT_RESOLVED) throwError$1(state, `cannot resolve a node with !<${tagName}> explicit tag`);
|
|
@@ -1153,7 +1277,7 @@ function constructScalar(state, event) {
|
|
|
1153
1277
|
tag: scalarTag
|
|
1154
1278
|
};
|
|
1155
1279
|
}
|
|
1156
|
-
const collectionTagDef =
|
|
1280
|
+
const collectionTagDef = state.schema.lookupMappingTag(tagName) ?? state.schema.lookupSequenceTag(tagName);
|
|
1157
1281
|
if (collectionTagDef) {
|
|
1158
1282
|
if (source !== "") throwError$1(state, `cannot resolve a node with !<${tagName}> explicit tag`);
|
|
1159
1283
|
const carrier = collectionTagDef.create(tagName);
|
|
@@ -1164,28 +1288,15 @@ function constructScalar(state, event) {
|
|
|
1164
1288
|
}
|
|
1165
1289
|
throwError$1(state, `unknown scalar tag !<${tagName}>`);
|
|
1166
1290
|
}
|
|
1167
|
-
if (event.style ===
|
|
1168
|
-
const candidates = state.schema.implicitScalarByFirstChar.get(source.charAt(0)) ?? state.schema.implicitScalarAnyFirstChar;
|
|
1169
|
-
for (const tag of candidates) {
|
|
1170
|
-
const result = tag.resolve(source, false, tag.tagName);
|
|
1171
|
-
if (result !== NOT_RESOLVED) return {
|
|
1172
|
-
value: result,
|
|
1173
|
-
tag
|
|
1174
|
-
};
|
|
1175
|
-
}
|
|
1176
|
-
}
|
|
1291
|
+
if (event.style === SCALAR_STYLE.PLAIN) return state.schema.resolveImplicitScalarTag(source);
|
|
1177
1292
|
return {
|
|
1178
1293
|
value: strTag2.resolve(source, false, strTag2.tagName),
|
|
1179
1294
|
tag: strTag2
|
|
1180
1295
|
};
|
|
1181
1296
|
}
|
|
1182
|
-
function
|
|
1297
|
+
function collectionTagName(state, event, defaultTagName) {
|
|
1183
1298
|
const rawTag = event.tagStart === NO_RANGE$2 ? "" : state.source.slice(event.tagStart, event.tagEnd);
|
|
1184
|
-
|
|
1185
|
-
return {
|
|
1186
|
-
tagName,
|
|
1187
|
-
tag: findExplicitTag(state, exact, prefix, tagName, nodeKind)
|
|
1188
|
-
};
|
|
1299
|
+
return rawTag === "" || rawTag === "!" ? defaultTagName : tagNameFull(rawTag, state.tagHandlers);
|
|
1189
1300
|
}
|
|
1190
1301
|
function isMappingTag(tag) {
|
|
1191
1302
|
return tag.nodeKind === "mapping";
|
|
@@ -1202,12 +1313,16 @@ function mergeKeys(state, frame, source, sourceTag) {
|
|
|
1202
1313
|
function mergeSource(state, frame, source, sourceTag) {
|
|
1203
1314
|
state.position = frame.keyPosition;
|
|
1204
1315
|
if (isMappingTag(sourceTag)) mergeKeys(state, frame, source, sourceTag);
|
|
1205
|
-
else if (sourceTag.nodeKind === "sequence" && Array.isArray(source)) for (const element of source)
|
|
1316
|
+
else if (sourceTag.nodeKind === "sequence" && Array.isArray(source)) for (const element of source) {
|
|
1317
|
+
const elementTag = state.nodeTags.get(element);
|
|
1318
|
+
if (!elementTag) throwError$1(state, "cannot merge mappings; the provided source object is unacceptable");
|
|
1319
|
+
mergeKeys(state, frame, element, elementTag);
|
|
1320
|
+
}
|
|
1206
1321
|
else throwError$1(state, "cannot merge mappings; the provided source object is unacceptable");
|
|
1207
1322
|
}
|
|
1208
1323
|
function addMappingValue(state, frame, key, value, tag) {
|
|
1209
1324
|
state.position = frame.keyPosition;
|
|
1210
|
-
if (
|
|
1325
|
+
if (frame.keyIsMerge) {
|
|
1211
1326
|
mergeSource(state, frame, value, tag);
|
|
1212
1327
|
return;
|
|
1213
1328
|
}
|
|
@@ -1222,9 +1337,7 @@ function addValue(state, value, tag) {
|
|
|
1222
1337
|
frame.value = value;
|
|
1223
1338
|
frame.hasValue = true;
|
|
1224
1339
|
} else if (frame.kind === "sequence") {
|
|
1225
|
-
if (
|
|
1226
|
-
if (!isMappingTag(tag)) throwError$1(state, "cannot merge mappings; the provided source object is unacceptable");
|
|
1227
|
-
}
|
|
1340
|
+
if (isMappingTag(tag)) state.nodeTags.set(value, tag);
|
|
1228
1341
|
const err = frame.tag.addItem(frame.value, value, frame.index++);
|
|
1229
1342
|
if (err) throwError$1(state, err);
|
|
1230
1343
|
} else if (frame.hasKey) {
|
|
@@ -1236,6 +1349,7 @@ function addValue(state, value, tag) {
|
|
|
1236
1349
|
frame.key = value;
|
|
1237
1350
|
frame.keyPosition = state.position;
|
|
1238
1351
|
frame.hasKey = true;
|
|
1352
|
+
frame.keyIsMerge = tag.tagName === MERGE_TAG_NAME;
|
|
1239
1353
|
}
|
|
1240
1354
|
}
|
|
1241
1355
|
function storeAnchor(state, event, value, tag, isValueFinal) {
|
|
@@ -1260,6 +1374,7 @@ function constructFromEvents(events, options) {
|
|
|
1260
1374
|
position: 0,
|
|
1261
1375
|
frames: [],
|
|
1262
1376
|
anchors: /* @__PURE__ */ new Map(),
|
|
1377
|
+
nodeTags: /* @__PURE__ */ new Map(),
|
|
1263
1378
|
tagHandlers: /* @__PURE__ */ Object.create(null),
|
|
1264
1379
|
totalMergeKeys: 0,
|
|
1265
1380
|
aliasCount: 0
|
|
@@ -1268,8 +1383,9 @@ function constructFromEvents(events, options) {
|
|
|
1268
1383
|
const event = state.events[state.eventIndex++];
|
|
1269
1384
|
state.position = eventPosition$1(event);
|
|
1270
1385
|
switch (event.type) {
|
|
1271
|
-
case
|
|
1386
|
+
case EVENT_ID.DOCUMENT:
|
|
1272
1387
|
state.anchors = /* @__PURE__ */ new Map();
|
|
1388
|
+
state.nodeTags = /* @__PURE__ */ new Map();
|
|
1273
1389
|
state.aliasCount = 0;
|
|
1274
1390
|
state.tagHandlers = /* @__PURE__ */ Object.create(null);
|
|
1275
1391
|
for (const directive of event.directives) if (directive.kind === "tag") state.tagHandlers[directive.handle] = directive.prefix;
|
|
@@ -1280,47 +1396,49 @@ function constructFromEvents(events, options) {
|
|
|
1280
1396
|
hasValue: false
|
|
1281
1397
|
});
|
|
1282
1398
|
break;
|
|
1283
|
-
case
|
|
1399
|
+
case EVENT_ID.SCALAR: {
|
|
1284
1400
|
const { value, tag } = constructScalar(state, event);
|
|
1285
1401
|
storeAnchor(state, event, value, tag, true);
|
|
1286
1402
|
addValue(state, value, tag);
|
|
1287
1403
|
break;
|
|
1288
1404
|
}
|
|
1289
|
-
case
|
|
1290
|
-
const
|
|
1291
|
-
const
|
|
1292
|
-
|
|
1293
|
-
const
|
|
1294
|
-
const
|
|
1405
|
+
case EVENT_ID.SEQUENCE: {
|
|
1406
|
+
const tagName = collectionTagName(state, event, "tag:yaml.org,2002:seq");
|
|
1407
|
+
const tag = state.schema.lookupSequenceTag(tagName);
|
|
1408
|
+
if (!tag) throwError$1(state, `unknown sequence tag !<${tagName}>`);
|
|
1409
|
+
const value = tag.create(tagName);
|
|
1410
|
+
const anchor = storeAnchor(state, event, value, tag, tag.carrierIsResult);
|
|
1295
1411
|
state.frames.push({
|
|
1296
1412
|
kind: "sequence",
|
|
1297
1413
|
position: state.position,
|
|
1298
1414
|
value,
|
|
1299
|
-
tag
|
|
1415
|
+
tag,
|
|
1300
1416
|
anchor,
|
|
1301
|
-
index: 0
|
|
1302
|
-
merge
|
|
1417
|
+
index: 0
|
|
1303
1418
|
});
|
|
1304
1419
|
break;
|
|
1305
1420
|
}
|
|
1306
|
-
case
|
|
1307
|
-
const
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1421
|
+
case EVENT_ID.MAPPING: {
|
|
1422
|
+
const tagName = collectionTagName(state, event, "tag:yaml.org,2002:map");
|
|
1423
|
+
const tag = state.schema.lookupMappingTag(tagName);
|
|
1424
|
+
if (!tag) throwError$1(state, `unknown mapping tag !<${tagName}>`);
|
|
1425
|
+
const value = tag.create(tagName);
|
|
1426
|
+
const anchor = storeAnchor(state, event, value, tag, tag.carrierIsResult);
|
|
1310
1427
|
state.frames.push({
|
|
1311
1428
|
kind: "mapping",
|
|
1312
1429
|
position: state.position,
|
|
1313
1430
|
value,
|
|
1314
|
-
tag
|
|
1431
|
+
tag,
|
|
1315
1432
|
anchor,
|
|
1316
1433
|
key: void 0,
|
|
1317
1434
|
keyPosition: state.position,
|
|
1318
1435
|
hasKey: false,
|
|
1436
|
+
keyIsMerge: false,
|
|
1319
1437
|
overridable: null
|
|
1320
1438
|
});
|
|
1321
1439
|
break;
|
|
1322
1440
|
}
|
|
1323
|
-
case
|
|
1441
|
+
case EVENT_ID.ALIAS: {
|
|
1324
1442
|
if (state.maxAliases !== -1 && ++state.aliasCount > state.maxAliases) throwError$1(state, `aliases exceeded maxAliases (${state.maxAliases})`);
|
|
1325
1443
|
const name = state.source.slice(event.anchorStart, event.anchorEnd);
|
|
1326
1444
|
const anchor = state.anchors.get(name);
|
|
@@ -1329,8 +1447,12 @@ function constructFromEvents(events, options) {
|
|
|
1329
1447
|
addValue(state, anchor.value, anchor.tag);
|
|
1330
1448
|
break;
|
|
1331
1449
|
}
|
|
1332
|
-
case
|
|
1450
|
+
case EVENT_ID.POP: {
|
|
1333
1451
|
const frame = state.frames.pop();
|
|
1452
|
+
if (frame.kind === "mapping" && frame.hasKey) {
|
|
1453
|
+
state.position = frame.keyPosition;
|
|
1454
|
+
throwError$1(state, "incomplete mapping pair in event stream");
|
|
1455
|
+
}
|
|
1334
1456
|
if (frame.kind === "document") state.documents.push(frame.value);
|
|
1335
1457
|
else {
|
|
1336
1458
|
const value = frame.tag.carrierIsResult ? frame.value : finalizeCollection(state, frame.position, frame.tag, frame.value);
|
|
@@ -1366,7 +1488,7 @@ var DEFAULT_PARSER_OPTIONS = {
|
|
|
1366
1488
|
};
|
|
1367
1489
|
function addDocumentEvent(state, explicitStart, explicitEnd) {
|
|
1368
1490
|
state.events.push({
|
|
1369
|
-
type:
|
|
1491
|
+
type: EVENT_ID.DOCUMENT,
|
|
1370
1492
|
explicitStart,
|
|
1371
1493
|
explicitEnd,
|
|
1372
1494
|
directives: state.directives
|
|
@@ -1374,7 +1496,7 @@ function addDocumentEvent(state, explicitStart, explicitEnd) {
|
|
|
1374
1496
|
}
|
|
1375
1497
|
function addSequenceEvent(state, start2, anchorStart, anchorEnd, tagStart, tagEnd, style) {
|
|
1376
1498
|
state.events.push({
|
|
1377
|
-
type:
|
|
1499
|
+
type: EVENT_ID.SEQUENCE,
|
|
1378
1500
|
start: start2,
|
|
1379
1501
|
anchorStart,
|
|
1380
1502
|
anchorEnd,
|
|
@@ -1385,7 +1507,7 @@ function addSequenceEvent(state, start2, anchorStart, anchorEnd, tagStart, tagEn
|
|
|
1385
1507
|
}
|
|
1386
1508
|
function addMappingEvent(state, start2, anchorStart, anchorEnd, tagStart, tagEnd, style) {
|
|
1387
1509
|
state.events.push({
|
|
1388
|
-
type:
|
|
1510
|
+
type: EVENT_ID.MAPPING,
|
|
1389
1511
|
start: start2,
|
|
1390
1512
|
anchorStart,
|
|
1391
1513
|
anchorEnd,
|
|
@@ -1394,9 +1516,20 @@ function addMappingEvent(state, start2, anchorStart, anchorEnd, tagStart, tagEnd
|
|
|
1394
1516
|
style
|
|
1395
1517
|
});
|
|
1396
1518
|
}
|
|
1397
|
-
function
|
|
1519
|
+
function insertFlowPairMappingEvent(state, snapshot) {
|
|
1520
|
+
state.events.splice(snapshot.eventsLength, 0, {
|
|
1521
|
+
type: EVENT_ID.MAPPING,
|
|
1522
|
+
start: snapshot.position,
|
|
1523
|
+
anchorStart: NO_RANGE$1,
|
|
1524
|
+
anchorEnd: NO_RANGE$1,
|
|
1525
|
+
tagStart: NO_RANGE$1,
|
|
1526
|
+
tagEnd: NO_RANGE$1,
|
|
1527
|
+
style: COLLECTION_STYLE.FLOW
|
|
1528
|
+
});
|
|
1529
|
+
}
|
|
1530
|
+
function addScalarEvent(state, valueStart, valueEnd, anchorStart, anchorEnd, tagStart, tagEnd, style, chomping = CHOMPING_MODE.CLIP, indent = -1, fast = false) {
|
|
1398
1531
|
state.events.push({
|
|
1399
|
-
type:
|
|
1532
|
+
type: EVENT_ID.SCALAR,
|
|
1400
1533
|
valueStart,
|
|
1401
1534
|
valueEnd,
|
|
1402
1535
|
anchorStart,
|
|
@@ -1411,16 +1544,16 @@ function addScalarEvent(state, valueStart, valueEnd, anchorStart, anchorEnd, tag
|
|
|
1411
1544
|
}
|
|
1412
1545
|
function addAliasEvent(state, anchorStart, anchorEnd) {
|
|
1413
1546
|
state.events.push({
|
|
1414
|
-
type:
|
|
1547
|
+
type: EVENT_ID.ALIAS,
|
|
1415
1548
|
anchorStart,
|
|
1416
1549
|
anchorEnd
|
|
1417
1550
|
});
|
|
1418
1551
|
}
|
|
1419
1552
|
function addPopEvent(state) {
|
|
1420
|
-
state.events.push({ type:
|
|
1553
|
+
state.events.push({ type: EVENT_ID.POP });
|
|
1421
1554
|
}
|
|
1422
1555
|
function addEmptyScalarEvent(state) {
|
|
1423
|
-
addScalarEvent(state, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1,
|
|
1556
|
+
addScalarEvent(state, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, NO_RANGE$1, SCALAR_STYLE.PLAIN);
|
|
1424
1557
|
}
|
|
1425
1558
|
function emptyProperties() {
|
|
1426
1559
|
return {
|
|
@@ -1449,7 +1582,7 @@ function restoreState(state, snapshot) {
|
|
|
1449
1582
|
state.events.length = snapshot.eventsLength;
|
|
1450
1583
|
}
|
|
1451
1584
|
function throwError(state, message) {
|
|
1452
|
-
|
|
1585
|
+
YAMLException.throwAt(state.input.slice(0, state.length), state.position, message, state.filename);
|
|
1453
1586
|
}
|
|
1454
1587
|
function isEol(c) {
|
|
1455
1588
|
return c === 10 || c === 13;
|
|
@@ -1617,7 +1750,7 @@ function readSingleQuotedScalar(state, nodeIndent, props) {
|
|
|
1617
1750
|
}
|
|
1618
1751
|
const end = state.position;
|
|
1619
1752
|
state.position++;
|
|
1620
|
-
addScalarEvent(state, start2, end, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd,
|
|
1753
|
+
addScalarEvent(state, start2, end, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, SCALAR_STYLE.SINGLE_QUOTED, CHOMPING_MODE.CLIP, -1, simple);
|
|
1621
1754
|
return true;
|
|
1622
1755
|
}
|
|
1623
1756
|
if (isEol(ch)) {
|
|
@@ -1639,7 +1772,7 @@ function readDoubleQuotedScalar(state, nodeIndent, props) {
|
|
|
1639
1772
|
if (ch === 34) {
|
|
1640
1773
|
const end = state.position;
|
|
1641
1774
|
state.position++;
|
|
1642
|
-
addScalarEvent(state, start2, end, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd,
|
|
1775
|
+
addScalarEvent(state, start2, end, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, SCALAR_STYLE.DOUBLE_QUOTED, CHOMPING_MODE.CLIP, -1, simple);
|
|
1643
1776
|
return true;
|
|
1644
1777
|
}
|
|
1645
1778
|
if (ch === 92) {
|
|
@@ -1667,18 +1800,18 @@ function readDoubleQuotedScalar(state, nodeIndent, props) {
|
|
|
1667
1800
|
}
|
|
1668
1801
|
function readBlockScalar(state, parentIndent, props) {
|
|
1669
1802
|
const ch = state.input.charCodeAt(state.position);
|
|
1670
|
-
let chomping =
|
|
1803
|
+
let chomping = CHOMPING_MODE.CLIP;
|
|
1671
1804
|
let indent = -1;
|
|
1672
1805
|
let detectedIndent = false;
|
|
1673
1806
|
if (ch !== 124 && ch !== 62) return false;
|
|
1674
|
-
const style = ch === 124 ?
|
|
1807
|
+
const style = ch === 124 ? SCALAR_STYLE.LITERAL_BLOCK : SCALAR_STYLE.FOLDED_BLOCK;
|
|
1675
1808
|
state.position++;
|
|
1676
1809
|
while (state.input.charCodeAt(state.position) !== 0) {
|
|
1677
1810
|
const current = state.input.charCodeAt(state.position);
|
|
1678
1811
|
const digit = fromDecimalCode(current);
|
|
1679
1812
|
if (current === 43 || current === 45) {
|
|
1680
|
-
if (chomping !==
|
|
1681
|
-
chomping = current === 43 ?
|
|
1813
|
+
if (chomping !== CHOMPING_MODE.CLIP) throwError(state, "repeat of a chomping mode identifier");
|
|
1814
|
+
chomping = current === 43 ? CHOMPING_MODE.KEEP : CHOMPING_MODE.STRIP;
|
|
1682
1815
|
state.position++;
|
|
1683
1816
|
} else if (digit >= 0) {
|
|
1684
1817
|
if (digit === 0) throwError(state, "bad explicit indentation width of a block scalar; it cannot be less than one");
|
|
@@ -1793,7 +1926,7 @@ function readPlainScalar(state, nodeIndent, nodeContext, props) {
|
|
|
1793
1926
|
}
|
|
1794
1927
|
if (end === start2) return false;
|
|
1795
1928
|
checkPrintable(state, start2, end);
|
|
1796
|
-
addScalarEvent(state, start2, end, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd,
|
|
1929
|
+
addScalarEvent(state, start2, end, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, SCALAR_STYLE.PLAIN, CHOMPING_MODE.CLIP, -1, !multiline);
|
|
1797
1930
|
return true;
|
|
1798
1931
|
}
|
|
1799
1932
|
function skipFlowSeparationSpace(state, nodeIndent) {
|
|
@@ -1808,8 +1941,8 @@ function readFlowCollection(state, nodeIndent, props) {
|
|
|
1808
1941
|
let readNext = true;
|
|
1809
1942
|
if (ch !== 91 && ch !== 123) return false;
|
|
1810
1943
|
const terminator = isMapping ? 125 : 93;
|
|
1811
|
-
if (isMapping) addMappingEvent(state, start2, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd,
|
|
1812
|
-
else addSequenceEvent(state, start2, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd,
|
|
1944
|
+
if (isMapping) addMappingEvent(state, start2, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, COLLECTION_STYLE.FLOW);
|
|
1945
|
+
else addSequenceEvent(state, start2, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, COLLECTION_STYLE.FLOW);
|
|
1813
1946
|
state.position++;
|
|
1814
1947
|
while (state.input.charCodeAt(state.position) !== 0) {
|
|
1815
1948
|
skipFlowSeparationSpace(state, nodeIndent);
|
|
@@ -1837,12 +1970,8 @@ function readFlowCollection(state, nodeIndent, props) {
|
|
|
1837
1970
|
state.position++;
|
|
1838
1971
|
skipFlowSeparationSpace(state, nodeIndent);
|
|
1839
1972
|
if (!isMapping) {
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
if (!parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true)) addEmptyScalarEvent(state);
|
|
1843
|
-
skipFlowSeparationSpace(state, nodeIndent);
|
|
1844
|
-
state.position++;
|
|
1845
|
-
skipFlowSeparationSpace(state, nodeIndent);
|
|
1973
|
+
insertFlowPairMappingEvent(state, entryStart);
|
|
1974
|
+
if (!keyWasRead) addEmptyScalarEvent(state);
|
|
1846
1975
|
} else if (!keyWasRead) addEmptyScalarEvent(state);
|
|
1847
1976
|
if (!parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true)) addEmptyScalarEvent(state);
|
|
1848
1977
|
skipFlowSeparationSpace(state, nodeIndent);
|
|
@@ -1852,9 +1981,8 @@ function readFlowCollection(state, nodeIndent, props) {
|
|
|
1852
1981
|
addEmptyScalarEvent(state);
|
|
1853
1982
|
} else if (isMapping) addEmptyScalarEvent(state);
|
|
1854
1983
|
else if (isPair) {
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
parseNode(state, nodeIndent, CONTEXT_FLOW_IN, false, true);
|
|
1984
|
+
insertFlowPairMappingEvent(state, entryStart);
|
|
1985
|
+
if (!keyWasRead) addEmptyScalarEvent(state);
|
|
1858
1986
|
addEmptyScalarEvent(state);
|
|
1859
1987
|
addPopEvent(state);
|
|
1860
1988
|
}
|
|
@@ -1868,7 +1996,7 @@ function readFlowCollection(state, nodeIndent, props) {
|
|
|
1868
1996
|
}
|
|
1869
1997
|
function readBlockSequence(state, nodeIndent, props) {
|
|
1870
1998
|
if (state.firstTabInLine !== -1 || state.input.charCodeAt(state.position) !== 45 || !isWsOrEolOrEnd(state.input.charCodeAt(state.position + 1))) return false;
|
|
1871
|
-
addSequenceEvent(state, state.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd,
|
|
1999
|
+
addSequenceEvent(state, state.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, COLLECTION_STYLE.BLOCK);
|
|
1872
2000
|
while (state.input.charCodeAt(state.position) === 45 && isWsOrEolOrEnd(state.input.charCodeAt(state.position + 1))) {
|
|
1873
2001
|
if (state.firstTabInLine !== -1) {
|
|
1874
2002
|
state.position = state.firstTabInLine;
|
|
@@ -1904,7 +2032,7 @@ function readBlockMapping(state, nodeIndent, flowIndent, props) {
|
|
|
1904
2032
|
const entryLine = state.line;
|
|
1905
2033
|
if ((ch === 63 || ch === 58) && isWsOrEolOrEnd(following)) {
|
|
1906
2034
|
if (!mappingOpened) {
|
|
1907
|
-
addMappingEvent(state, state.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd,
|
|
2035
|
+
addMappingEvent(state, state.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, COLLECTION_STYLE.BLOCK);
|
|
1908
2036
|
mappingOpened = true;
|
|
1909
2037
|
}
|
|
1910
2038
|
if (ch === 63) {
|
|
@@ -1934,7 +2062,7 @@ function readBlockMapping(state, nodeIndent, flowIndent, props) {
|
|
|
1934
2062
|
if (!isWsOrEolOrEnd(ch)) throwError(state, "a whitespace character is expected after the key-value separator within a block mapping");
|
|
1935
2063
|
if (!mappingOpened) {
|
|
1936
2064
|
restoreState(state, beforeKey);
|
|
1937
|
-
addMappingEvent(state, beforeKey.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd,
|
|
2065
|
+
addMappingEvent(state, beforeKey.position, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, COLLECTION_STYLE.BLOCK);
|
|
1938
2066
|
mappingOpened = true;
|
|
1939
2067
|
parseNode(state, flowIndent, CONTEXT_FLOW_OUT, false, true);
|
|
1940
2068
|
ch = state.input.charCodeAt(state.position);
|
|
@@ -1995,10 +2123,6 @@ function parseNode(state, parentIndent, nodeContext, allowToSeek, allowCompact,
|
|
|
1995
2123
|
else if (state.lineIndent === parentIndent) indentStatus = 0;
|
|
1996
2124
|
else indentStatus = -1;
|
|
1997
2125
|
}
|
|
1998
|
-
if (state.position === state.lineStart && testDocumentSeparator(state)) {
|
|
1999
|
-
state.depth--;
|
|
2000
|
-
return false;
|
|
2001
|
-
}
|
|
2002
2126
|
if (indentStatus === 1) while (true) {
|
|
2003
2127
|
const ch = state.input.charCodeAt(state.position);
|
|
2004
2128
|
const propertyState = snapshotState(state);
|
|
@@ -2006,7 +2130,7 @@ function parseNode(state, parentIndent, nodeContext, allowToSeek, allowCompact,
|
|
|
2006
2130
|
if (atNewLine && allowBlockStyles && (props.tagStart !== NO_RANGE$1 || props.anchorStart !== NO_RANGE$1) && (ch === 33 || ch === 38)) {
|
|
2007
2131
|
const fallbackState = snapshotState(state);
|
|
2008
2132
|
const flowIndent = parentIndent + 1;
|
|
2009
|
-
if (readBlockMapping(state, state.position - state.lineStart, flowIndent, props) && state.events[fallbackState.eventsLength]?.type ===
|
|
2133
|
+
if (readBlockMapping(state, state.position - state.lineStart, flowIndent, props) && state.events[fallbackState.eventsLength]?.type === EVENT_ID.MAPPING) {
|
|
2010
2134
|
state.depth--;
|
|
2011
2135
|
return true;
|
|
2012
2136
|
}
|
|
@@ -2034,7 +2158,7 @@ function parseNode(state, parentIndent, nodeContext, allowToSeek, allowCompact,
|
|
|
2034
2158
|
const fallbackState = snapshotState(state);
|
|
2035
2159
|
const propertyIndent = propertyStart.position - propertyStart.lineStart;
|
|
2036
2160
|
restoreState(state, propertyStart);
|
|
2037
|
-
if (readBlockMapping(state, propertyIndent, flowIndent, emptyProperties()) && state.events[fallbackState.eventsLength]?.type ===
|
|
2161
|
+
if (readBlockMapping(state, propertyIndent, flowIndent, emptyProperties()) && state.events[fallbackState.eventsLength]?.type === EVENT_ID.MAPPING) hasContent = true;
|
|
2038
2162
|
else restoreState(state, fallbackState);
|
|
2039
2163
|
}
|
|
2040
2164
|
if (!hasContent && (allowBlockScalars && readBlockScalar(state, flowIndent, props) || readSingleQuotedScalar(state, flowIndent, props) || readDoubleQuotedScalar(state, flowIndent, props) || readAlias(state, props) || readPlainScalar(state, flowIndent, nodeContext, props))) hasContent = true;
|
|
@@ -2043,7 +2167,7 @@ function parseNode(state, parentIndent, nodeContext, allowToSeek, allowCompact,
|
|
|
2043
2167
|
}
|
|
2044
2168
|
allowBlockScalars = allowBlockScalars && !hasContent;
|
|
2045
2169
|
if (!hasContent && (props.anchorStart !== NO_RANGE$1 || props.tagStart !== NO_RANGE$1 || allowBlockScalars)) {
|
|
2046
|
-
addScalarEvent(state, NO_RANGE$1, NO_RANGE$1, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd,
|
|
2170
|
+
addScalarEvent(state, NO_RANGE$1, NO_RANGE$1, props.anchorStart, props.anchorEnd, props.tagStart, props.tagEnd, SCALAR_STYLE.PLAIN);
|
|
2047
2171
|
hasContent = true;
|
|
2048
2172
|
}
|
|
2049
2173
|
state.depth--;
|
|
@@ -2128,7 +2252,7 @@ function readDocument(state) {
|
|
|
2128
2252
|
}
|
|
2129
2253
|
}
|
|
2130
2254
|
const documentEvent = state.events[documentEventIndex];
|
|
2131
|
-
if (documentEvent?.type ===
|
|
2255
|
+
if (documentEvent?.type === EVENT_ID.DOCUMENT) documentEvent.explicitEnd = explicitEnd;
|
|
2132
2256
|
addPopEvent(state);
|
|
2133
2257
|
if (!explicitEnd && state.position < state.length && !(state.position === state.lineStart && testDocumentSeparator(state))) throwError(state, "end of the stream or a document separator is expected");
|
|
2134
2258
|
}
|
|
@@ -2150,7 +2274,7 @@ function parseEvents(input, options) {
|
|
|
2150
2274
|
events: []
|
|
2151
2275
|
};
|
|
2152
2276
|
const nullpos = input.indexOf("\0");
|
|
2153
|
-
if (nullpos !== -1)
|
|
2277
|
+
if (nullpos !== -1) YAMLException.throwAt(input, nullpos, "null byte is not allowed in input", state.filename);
|
|
2154
2278
|
if (state.input.charCodeAt(state.position) === 65279) state.position++;
|
|
2155
2279
|
while (state.position < state.length) {
|
|
2156
2280
|
skipSeparationSpace(state, true);
|
|
@@ -2186,6 +2310,7 @@ function load(input, options) {
|
|
|
2186
2310
|
throw new YAMLException("expected a single document in the stream, but found more");
|
|
2187
2311
|
}
|
|
2188
2312
|
var Style = class {
|
|
2313
|
+
/** Whether to print the node's tag explicitly. */
|
|
2189
2314
|
tagged = false;
|
|
2190
2315
|
flow = false;
|
|
2191
2316
|
singleQuoted = false;
|
|
@@ -2221,9 +2346,9 @@ function buildRepresentTypes(schema) {
|
|
|
2221
2346
|
function matchTag(state, object) {
|
|
2222
2347
|
for (let index = 0, length = state.representTypes.length; index < length; index += 1) {
|
|
2223
2348
|
const { tag, implicitTag } = state.representTypes[index];
|
|
2224
|
-
if (tag.identify
|
|
2349
|
+
if (tag.identify(object)) {
|
|
2225
2350
|
let tagName;
|
|
2226
|
-
if (tag.matchByTagPrefix
|
|
2351
|
+
if (tag.matchByTagPrefix) tagName = tag.representTagName(object);
|
|
2227
2352
|
else tagName = tag.tagName;
|
|
2228
2353
|
return {
|
|
2229
2354
|
tag,
|
|
@@ -2423,8 +2548,7 @@ function createPresenterState(options) {
|
|
|
2423
2548
|
};
|
|
2424
2549
|
return {
|
|
2425
2550
|
...opts,
|
|
2426
|
-
defaultScalarTagName: opts.schema.defaultScalarTag.tagName
|
|
2427
|
-
implicitResolvers: opts.schema.implicitScalarTags
|
|
2551
|
+
defaultScalarTagName: opts.schema.defaultScalarTag.tagName
|
|
2428
2552
|
};
|
|
2429
2553
|
}
|
|
2430
2554
|
function encodeNonPrintable(character) {
|
|
@@ -2465,13 +2589,6 @@ function scalarLayout(state, level) {
|
|
|
2465
2589
|
lineWidth: state.lineWidth === -1 ? -1 : Math.max(Math.min(state.lineWidth, 40), state.lineWidth - indent)
|
|
2466
2590
|
};
|
|
2467
2591
|
}
|
|
2468
|
-
function resolveImplicitTag(state, str) {
|
|
2469
|
-
for (let index = 0, length = state.implicitResolvers.length; index < length; index += 1) {
|
|
2470
|
-
const tagDefinition = state.implicitResolvers[index];
|
|
2471
|
-
if (tagDefinition.resolve(str, false, tagDefinition.tagName) !== NOT_RESOLVED) return tagDefinition.tagName;
|
|
2472
|
-
}
|
|
2473
|
-
return state.defaultScalarTagName;
|
|
2474
|
-
}
|
|
2475
2592
|
function isWhitespace(c) {
|
|
2476
2593
|
return c === CHAR_SPACE || c === CHAR_TAB;
|
|
2477
2594
|
}
|
|
@@ -2491,7 +2608,7 @@ function isNsCharOrWhitespace(c) {
|
|
|
2491
2608
|
function isPlainSafe(c, prev, inblock) {
|
|
2492
2609
|
const cIsNsCharOrWhitespace = isNsCharOrWhitespace(c);
|
|
2493
2610
|
const cIsNsChar = cIsNsCharOrWhitespace && !isWhitespace(c);
|
|
2494
|
-
return (inblock ? cIsNsCharOrWhitespace : cIsNsCharOrWhitespace && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET) && c !== CHAR_SHARP && !(prev === CHAR_COLON && !cIsNsChar) || isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP || prev === CHAR_COLON && cIsNsChar;
|
|
2611
|
+
return (inblock ? cIsNsCharOrWhitespace : cIsNsCharOrWhitespace && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET) && c !== CHAR_SHARP && !(prev === CHAR_COLON && !cIsNsChar) || isNsCharOrWhitespace(prev) && !isWhitespace(prev) && c === CHAR_SHARP || prev === CHAR_COLON && cIsNsChar && (inblock || c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET);
|
|
2495
2612
|
}
|
|
2496
2613
|
function isPlainSafeFirst(c) {
|
|
2497
2614
|
return isPrintable(c) && c !== CHAR_BOM && !isWhitespace(c) && c !== CHAR_MINUS && c !== CHAR_QUESTION && c !== CHAR_COLON && c !== CHAR_COMMA && c !== CHAR_LEFT_SQUARE_BRACKET && c !== CHAR_RIGHT_SQUARE_BRACKET && c !== CHAR_LEFT_CURLY_BRACKET && c !== CHAR_RIGHT_CURLY_BRACKET && c !== CHAR_SHARP && c !== CHAR_AMPERSAND && c !== CHAR_ASTERISK && c !== CHAR_EXCLAMATION && c !== CHAR_VERTICAL_LINE && c !== CHAR_EQUALS && c !== CHAR_GREATER_THAN && c !== CHAR_SINGLE_QUOTE && c !== CHAR_DOUBLE_QUOTE && c !== CHAR_PERCENT && c !== CHAR_COMMERCIAL_AT && c !== CHAR_GRAVE_ACCENT;
|
|
@@ -2547,14 +2664,14 @@ function chooseScalarStyle(state, string, layout, singleLineOnly, forceQuote, in
|
|
|
2547
2664
|
if (char === CHAR_LINE_FEED) {
|
|
2548
2665
|
hasLineBreak = true;
|
|
2549
2666
|
if (shouldTrackWidth) {
|
|
2550
|
-
hasFoldableLine = hasFoldableLine || i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1]
|
|
2667
|
+
hasFoldableLine = hasFoldableLine || i - previousLineBreak - 1 > lineWidth && !isMoreIndented(string[previousLineBreak + 1]);
|
|
2551
2668
|
previousLineBreak = i;
|
|
2552
2669
|
}
|
|
2553
2670
|
} else if (!isPrintable(char)) return STYLE_DOUBLE;
|
|
2554
2671
|
plain = plain && isPlainSafe(char, prevChar, inblock);
|
|
2555
2672
|
prevChar = char;
|
|
2556
2673
|
}
|
|
2557
|
-
hasFoldableLine = hasFoldableLine || shouldTrackWidth && i - previousLineBreak - 1 > lineWidth && string[previousLineBreak + 1]
|
|
2674
|
+
hasFoldableLine = hasFoldableLine || shouldTrackWidth && i - previousLineBreak - 1 > lineWidth && !isMoreIndented(string[previousLineBreak + 1]);
|
|
2558
2675
|
}
|
|
2559
2676
|
if (!hasLineBreak && !hasFoldableLine) {
|
|
2560
2677
|
if (plain && !forceQuote) return STYLE_PLAIN;
|
|
@@ -2588,11 +2705,11 @@ function resolveScalarStyle(state, node, layout, iskey, inblock) {
|
|
|
2588
2705
|
}
|
|
2589
2706
|
const string = node.value;
|
|
2590
2707
|
if (string.length === 0) {
|
|
2591
|
-
if (node.style.tagged ||
|
|
2708
|
+
if (node.style.tagged || state.schema.resolveImplicitScalarTag(string).tag.tagName === node.tag) return STYLE_PLAIN;
|
|
2592
2709
|
return state.quoteStyle === "double" ? STYLE_DOUBLE : STYLE_SINGLE;
|
|
2593
2710
|
}
|
|
2594
2711
|
const style = chooseScalarStyle(state, string, layout, singleLineOnly, state.forceQuotes && !iskey, inblock);
|
|
2595
|
-
if (style === STYLE_PLAIN && !node.style.tagged &&
|
|
2712
|
+
if (style === STYLE_PLAIN && !node.style.tagged && state.schema.resolveImplicitScalarTag(string).tag.tagName !== node.tag) return state.quoteStyle === "double" ? STYLE_DOUBLE : STYLE_SINGLE;
|
|
2596
2713
|
return style;
|
|
2597
2714
|
}
|
|
2598
2715
|
function blockHeader(string, indentPerLevel) {
|
|
@@ -2619,27 +2736,30 @@ function encodeFlowBreaks(string, indent) {
|
|
|
2619
2736
|
function dropEndingNewline(string) {
|
|
2620
2737
|
return string[string.length - 1] === "\n" ? string.slice(0, -1) : string;
|
|
2621
2738
|
}
|
|
2739
|
+
function isMoreIndented(char) {
|
|
2740
|
+
return char === " " || char === " ";
|
|
2741
|
+
}
|
|
2622
2742
|
function foldBlockScalar(string, width) {
|
|
2623
2743
|
const lineRe = /(\n+)([^\n]*)/g;
|
|
2624
2744
|
let nextLF = string.indexOf("\n");
|
|
2625
2745
|
if (nextLF === -1) nextLF = string.length;
|
|
2626
2746
|
lineRe.lastIndex = nextLF;
|
|
2627
2747
|
let result = foldLine(string.slice(0, nextLF), width);
|
|
2628
|
-
let prevMoreIndented = string[0] === "\n" || string[0]
|
|
2748
|
+
let prevMoreIndented = string[0] === "\n" || isMoreIndented(string[0]);
|
|
2629
2749
|
let moreIndented;
|
|
2630
2750
|
let match;
|
|
2631
2751
|
while (match = lineRe.exec(string)) {
|
|
2632
2752
|
const prefix = match[1];
|
|
2633
2753
|
const line = match[2];
|
|
2634
|
-
moreIndented = line
|
|
2754
|
+
moreIndented = line !== "" && isMoreIndented(line[0]);
|
|
2635
2755
|
result += prefix + (!prevMoreIndented && !moreIndented && line !== "" ? "\n" : "") + foldLine(line, width);
|
|
2636
2756
|
prevMoreIndented = moreIndented;
|
|
2637
2757
|
}
|
|
2638
2758
|
return result;
|
|
2639
2759
|
}
|
|
2640
2760
|
function foldLine(line, width) {
|
|
2641
|
-
if (line === "" || line[0]
|
|
2642
|
-
const breakRe = / [^ ]/g;
|
|
2761
|
+
if (line === "" || isMoreIndented(line[0])) return line;
|
|
2762
|
+
const breakRe = / [^ \t]/g;
|
|
2643
2763
|
let match;
|
|
2644
2764
|
let start2 = 0;
|
|
2645
2765
|
let end;
|
|
@@ -2873,22 +2993,9 @@ function present(documents, options) {
|
|
|
2873
2993
|
}
|
|
2874
2994
|
return result;
|
|
2875
2995
|
}
|
|
2876
|
-
var DEFAULT_DUMP_SCHEMA = YAML11_SCHEMA.withTags({
|
|
2877
|
-
...intYaml11Tag,
|
|
2878
|
-
resolve: (source, isExplicit, tagName) => {
|
|
2879
|
-
const result = intYaml11Tag.resolve(source, isExplicit, tagName);
|
|
2880
|
-
return result === NOT_RESOLVED ? intCoreTag.resolve(source, isExplicit, tagName) : result;
|
|
2881
|
-
}
|
|
2882
|
-
}, {
|
|
2883
|
-
...floatYaml11Tag,
|
|
2884
|
-
resolve: (source, isExplicit, tagName) => {
|
|
2885
|
-
const result = floatYaml11Tag.resolve(source, isExplicit, tagName);
|
|
2886
|
-
return result === NOT_RESOLVED ? floatCoreTag.resolve(source, isExplicit, tagName) : result;
|
|
2887
|
-
}
|
|
2888
|
-
});
|
|
2889
2996
|
var DEFAULT_DUMP_OPTIONS = {
|
|
2890
2997
|
...DEFAULT_PRESENTER_OPTIONS,
|
|
2891
|
-
schema:
|
|
2998
|
+
schema: DUMP_SCHEMA,
|
|
2892
2999
|
skipInvalid: false,
|
|
2893
3000
|
noRefs: false,
|
|
2894
3001
|
flowLevel: -1,
|
|
@@ -2915,6 +3022,22 @@ function dump(input, options = {}) {
|
|
|
2915
3022
|
schema: opts.schema
|
|
2916
3023
|
});
|
|
2917
3024
|
}
|
|
3025
|
+
var EVENT_DOCUMENT = EVENT_ID.DOCUMENT;
|
|
3026
|
+
var EVENT_SEQUENCE = EVENT_ID.SEQUENCE;
|
|
3027
|
+
var EVENT_MAPPING = EVENT_ID.MAPPING;
|
|
3028
|
+
var EVENT_SCALAR = EVENT_ID.SCALAR;
|
|
3029
|
+
var EVENT_ALIAS = EVENT_ID.ALIAS;
|
|
3030
|
+
var EVENT_POP = EVENT_ID.POP;
|
|
3031
|
+
var SCALAR_STYLE_PLAIN = SCALAR_STYLE.PLAIN;
|
|
3032
|
+
var SCALAR_STYLE_SINGLE_QUOTED = SCALAR_STYLE.SINGLE_QUOTED;
|
|
3033
|
+
var SCALAR_STYLE_DOUBLE_QUOTED = SCALAR_STYLE.DOUBLE_QUOTED;
|
|
3034
|
+
var SCALAR_STYLE_LITERAL_BLOCK = SCALAR_STYLE.LITERAL_BLOCK;
|
|
3035
|
+
var SCALAR_STYLE_FOLDED_BLOCK = SCALAR_STYLE.FOLDED_BLOCK;
|
|
3036
|
+
var COLLECTION_STYLE_BLOCK = COLLECTION_STYLE.BLOCK;
|
|
3037
|
+
var COLLECTION_STYLE_FLOW = COLLECTION_STYLE.FLOW;
|
|
3038
|
+
var CHOMPING_CLIP = CHOMPING_MODE.CLIP;
|
|
3039
|
+
var CHOMPING_STRIP = CHOMPING_MODE.STRIP;
|
|
3040
|
+
var CHOMPING_KEEP = CHOMPING_MODE.KEEP;
|
|
2918
3041
|
|
|
2919
3042
|
// src/constants.ts
|
|
2920
3043
|
var AVAILABLE_MIRRORS = ["v6.gh-proxy.org", "gh-proxy.org", "hk.gh-proxy.org", "cdn.gh-proxy.org"];
|
|
@@ -3027,8 +3150,9 @@ function ensureDirs() {
|
|
|
3027
3150
|
}
|
|
3028
3151
|
}
|
|
3029
3152
|
}
|
|
3153
|
+
var atomicWriteSeq = 0;
|
|
3030
3154
|
function atomicWriteFileSync(filePath, content, options) {
|
|
3031
|
-
const tmp = `${filePath}.${process.pid}.tmp`;
|
|
3155
|
+
const tmp = `${filePath}.${process.pid}.${atomicWriteSeq++}.tmp`;
|
|
3032
3156
|
try {
|
|
3033
3157
|
fs.writeFileSync(tmp, content, options);
|
|
3034
3158
|
fs.renameSync(tmp, filePath);
|
|
@@ -3401,7 +3525,7 @@ function loadOverwriteFile() {
|
|
|
3401
3525
|
const filePath = path3.join(dir, file);
|
|
3402
3526
|
try {
|
|
3403
3527
|
const content = fs3.readFileSync(filePath, "utf8");
|
|
3404
|
-
const parsed = load(content);
|
|
3528
|
+
const parsed = load(content, { maxAliases: 200 });
|
|
3405
3529
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
3406
3530
|
const { match, ...config } = parsed;
|
|
3407
3531
|
results.push({ name: file, path: filePath, config, match: normalizeMatch(match, file) });
|
|
@@ -3581,6 +3705,15 @@ function isProcessRunning(pid) {
|
|
|
3581
3705
|
return false;
|
|
3582
3706
|
}
|
|
3583
3707
|
}
|
|
3708
|
+
function isProcessCommandMatching(pid, needle) {
|
|
3709
|
+
if (!pid) return false;
|
|
3710
|
+
try {
|
|
3711
|
+
const result = spawnSync("ps", ["-p", String(pid), "-o", "command="], { encoding: "utf8", timeout: 5e3 });
|
|
3712
|
+
return (result.stdout || "").includes(needle);
|
|
3713
|
+
} catch {
|
|
3714
|
+
return false;
|
|
3715
|
+
}
|
|
3716
|
+
}
|
|
3584
3717
|
function isProcessRoot(pid) {
|
|
3585
3718
|
if (!pid) return false;
|
|
3586
3719
|
try {
|
|
@@ -3591,7 +3724,8 @@ function isProcessRoot(pid) {
|
|
|
3591
3724
|
}
|
|
3592
3725
|
}
|
|
3593
3726
|
function createHttpClient(options = {}) {
|
|
3594
|
-
const { timeout = 6e4 } = options;
|
|
3727
|
+
const { timeout = 6e4, secret } = options;
|
|
3728
|
+
const authHeaders = secret ? { Authorization: `Bearer ${secret}` } : {};
|
|
3595
3729
|
return {
|
|
3596
3730
|
async get(url, config) {
|
|
3597
3731
|
const controller = new AbortController();
|
|
@@ -3600,7 +3734,7 @@ function createHttpClient(options = {}) {
|
|
|
3600
3734
|
try {
|
|
3601
3735
|
const response = await fetch(url, {
|
|
3602
3736
|
signal,
|
|
3603
|
-
headers: { "User-Agent": `mihomo-cli/${VERSION}
|
|
3737
|
+
headers: { "User-Agent": `mihomo-cli/${VERSION}`, ...authHeaders }
|
|
3604
3738
|
});
|
|
3605
3739
|
if (!response.ok) {
|
|
3606
3740
|
const error = new Error(`HTTP ${response.status}`);
|
|
@@ -3699,12 +3833,16 @@ function isProxyValid(proxy) {
|
|
|
3699
3833
|
}
|
|
3700
3834
|
|
|
3701
3835
|
// src/config.ts
|
|
3836
|
+
var SAFE_YAML_LOAD_OPTIONS = { maxAliases: 200 };
|
|
3837
|
+
function loadYamlSafe(content) {
|
|
3838
|
+
return load(content, SAFE_YAML_LOAD_OPTIONS);
|
|
3839
|
+
}
|
|
3702
3840
|
function parseYamlOrJson(content, errorMsg) {
|
|
3703
3841
|
if (!content?.trim()) {
|
|
3704
3842
|
throw new Error(`${errorMsg || "\u5185\u5BB9"}\u4E3A\u7A7A`);
|
|
3705
3843
|
}
|
|
3706
3844
|
try {
|
|
3707
|
-
const result =
|
|
3845
|
+
const result = loadYamlSafe(content);
|
|
3708
3846
|
if (result != null && typeof result === "object" && !Array.isArray(result)) return result;
|
|
3709
3847
|
} catch {
|
|
3710
3848
|
}
|
|
@@ -3715,13 +3853,13 @@ function parseYamlOrJson(content, errorMsg) {
|
|
|
3715
3853
|
}
|
|
3716
3854
|
}
|
|
3717
3855
|
function dumpYaml(obj) {
|
|
3718
|
-
return dump(obj, { indent: 2, lineWidth: -1
|
|
3856
|
+
return dump(obj, { indent: 2, lineWidth: -1 });
|
|
3719
3857
|
}
|
|
3720
3858
|
function collectOverwriteProxyNames(overwriteFiles) {
|
|
3721
3859
|
const names = [];
|
|
3722
3860
|
for (const file of overwriteFiles) {
|
|
3723
3861
|
for (const [key, value] of Object.entries(file.config)) {
|
|
3724
|
-
if ((key === "+proxies" || key === "proxies+") && Array.isArray(value)) {
|
|
3862
|
+
if ((key === "+proxies" || key === "proxies+" || key === "~proxies") && Array.isArray(value)) {
|
|
3725
3863
|
for (const proxy of value) {
|
|
3726
3864
|
if (proxy && typeof proxy === "object" && "name" in proxy) {
|
|
3727
3865
|
const name = proxy.name;
|
|
@@ -3916,7 +4054,7 @@ function getConfigInfo() {
|
|
|
3916
4054
|
if (!hasConfig()) return null;
|
|
3917
4055
|
try {
|
|
3918
4056
|
const content = fs4.readFileSync(PATHS.configFile, "utf8");
|
|
3919
|
-
const cfg =
|
|
4057
|
+
const cfg = loadYamlSafe(content);
|
|
3920
4058
|
if (!cfg) return null;
|
|
3921
4059
|
const proxies = cfg.proxies;
|
|
3922
4060
|
const proxyGroups = cfg["proxy-groups"];
|
|
@@ -4535,7 +4673,7 @@ function getLogPathByName(name) {
|
|
|
4535
4673
|
}
|
|
4536
4674
|
function openUrl(url) {
|
|
4537
4675
|
try {
|
|
4538
|
-
const child = spawn("open", [url], { stdio: "ignore", detached: true });
|
|
4676
|
+
const child = spawn("open", ["--", url], { stdio: "ignore", detached: true });
|
|
4539
4677
|
child.unref();
|
|
4540
4678
|
child.on("error", () => {
|
|
4541
4679
|
});
|
|
@@ -4723,10 +4861,13 @@ function disableDaemon() {
|
|
|
4723
4861
|
async function tryHotReload() {
|
|
4724
4862
|
const controller = new AbortController();
|
|
4725
4863
|
const timer = setTimeout(() => controller.abort(), HOT_RELOAD_TIMEOUT_MS);
|
|
4864
|
+
const secret = readSettings().controller_secret;
|
|
4865
|
+
const headers = { "Content-Type": "application/json" };
|
|
4866
|
+
if (secret) headers.Authorization = `Bearer ${secret}`;
|
|
4726
4867
|
try {
|
|
4727
4868
|
const res = await fetch(`${CONTROLLER_BASE_URL}/configs?force=true`, {
|
|
4728
4869
|
method: "PUT",
|
|
4729
|
-
headers
|
|
4870
|
+
headers,
|
|
4730
4871
|
body: "{}",
|
|
4731
4872
|
signal: controller.signal
|
|
4732
4873
|
});
|
|
@@ -5124,7 +5265,8 @@ async function testSubscriptionProxies(subName, options = {}) {
|
|
|
5124
5265
|
if (proxies.length === 0) {
|
|
5125
5266
|
return { total: 0, alive: 0, dead: 0, results: [] };
|
|
5126
5267
|
}
|
|
5127
|
-
const
|
|
5268
|
+
const secret = apiBase === CONTROLLER_BASE_URL ? readSettings().controller_secret : void 0;
|
|
5269
|
+
const client = createHttpClient({ timeout: timeout + 3e3, secret });
|
|
5128
5270
|
const results = new Array(proxies.length);
|
|
5129
5271
|
let completedCount = 0;
|
|
5130
5272
|
let nextIndex = 0;
|
|
@@ -5576,7 +5718,7 @@ async function downloadKernel(progressCallback, mirror, releaseInfo) {
|
|
|
5576
5718
|
\u5E73\u53F0: ${platform}, \u67B6\u6784: ${arch}${hint}`);
|
|
5577
5719
|
}
|
|
5578
5720
|
const downloadUrl = withMirror(asset.browser_download_url, mirror);
|
|
5579
|
-
const tempPath = path6.join(DIRS.kernel, asset.name);
|
|
5721
|
+
const tempPath = path6.join(DIRS.kernel, path6.basename(asset.name));
|
|
5580
5722
|
const sizeMB = (asset.size / 1024 / 1024).toFixed(2);
|
|
5581
5723
|
if (mirror && progressCallback) {
|
|
5582
5724
|
progressCallback("\u63D0\u793A: \u7ECF\u7B2C\u4E09\u65B9\u955C\u50CF\u4E2D\u8F6C\u4E0B\u8F7D\uFF0C\u65E0\u6CD5\u9A8C\u8BC1\u6765\u6E90\u5B8C\u6574\u6027\uFF0C\u5EFA\u8BAE\u76F4\u8FDE\u6216\u81EA\u884C\u6821\u9A8C\u4EA7\u7269");
|
|
@@ -6484,7 +6626,7 @@ function stopTestInstance() {
|
|
|
6484
6626
|
} catch {
|
|
6485
6627
|
return;
|
|
6486
6628
|
}
|
|
6487
|
-
if (pid > 0 && isProcessRunning(pid)) {
|
|
6629
|
+
if (pid > 0 && isProcessRunning(pid) && isProcessCommandMatching(pid, TEST_PATHS.configFile)) {
|
|
6488
6630
|
process.kill(pid, "SIGKILL");
|
|
6489
6631
|
for (let i = 0; i < 20; i++) {
|
|
6490
6632
|
if (!isProcessRunning(pid)) break;
|
|
@@ -7249,5 +7391,5 @@ main().catch((e) => {
|
|
|
7249
7391
|
/*! Bundled license information:
|
|
7250
7392
|
|
|
7251
7393
|
js-yaml/dist/js-yaml.mjs:
|
|
7252
|
-
(*! js-yaml 5.
|
|
7394
|
+
(*! js-yaml 5.3.0 https://github.com/nodeca/js-yaml @license MIT *)
|
|
7253
7395
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mihomo-cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A terminal-based mihomo (Clash.Meta) client for macOS",
|
|
6
6
|
"bin": {
|
|
@@ -47,9 +47,12 @@
|
|
|
47
47
|
"lint-staged": {
|
|
48
48
|
"*.{ts,json,md}": "biome check --fix --no-errors-on-unmatched"
|
|
49
49
|
},
|
|
50
|
+
"overrides": {
|
|
51
|
+
"esbuild": "^0.28.0"
|
|
52
|
+
},
|
|
50
53
|
"devDependencies": {
|
|
51
54
|
"@biomejs/biome": "^2.5.4",
|
|
52
|
-
"@types/node": "^
|
|
55
|
+
"@types/node": "^26.2.0",
|
|
53
56
|
"husky": "^9.1.7",
|
|
54
57
|
"lint-staged": "^17.0.8",
|
|
55
58
|
"tsup": "^8.5.1",
|