ace-support-items 0.15.15 → 0.15.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.
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a38caecfe7baec161ef92edffb6b0682c8347a2aa5595bf16659806af50556c0
|
|
4
|
+
data.tar.gz: f1a1c662c2cf9f570e7cded9997632ec0462953acb5aa772a6fe2c951d0ed394
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 784f3f6d39072de1b71fdab2fa6a22bc5c8ac06289cb642fb724bac3c6b062260b1f53a27e882259ed8d248cb34805d89bb2479c220cacfbe098811cb27b27cc
|
|
7
|
+
data.tar.gz: f8b3d574bfc6c5033bc9138f813010ecf48b46d7dd979f27a9d45a908a35a59788b3b6c4b2b4374ab5dd7790034bbc9cb8185c9478a5eef4c23cf94685c3d2bb
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.15.16] - 2026-10-29
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- Frontmatter flow sequences serialize every string element with the same quoting rules as flat values, so a question or tag containing `: ` parses back as the same string instead of a single-pair hash; compound elements raise `ArgumentError` instead of emitting Ruby rocket syntax that is not YAML (the 8xsdfo ask-flow corruption: recipient/reply_to frontmatter was silently dropped, so native sync refused the captain's reply and the answer wake never fired).
|
|
15
|
+
- `FrontmatterParser.parse!` gives mutating paths a strict parse, and `FieldUpdater` refuses to rewrite a file whose frontmatter YAML is invalid — an unparsable block now aborts the update loudly instead of rebuilding the file from an empty frontmatter.
|
|
16
|
+
|
|
10
17
|
## [0.15.15] - 2026-10-18
|
|
11
18
|
|
|
12
19
|
### Added
|
|
@@ -13,6 +13,21 @@ module Ace
|
|
|
13
13
|
# @param content [String] The markdown content with optional frontmatter
|
|
14
14
|
# @return [Hash] Parsed frontmatter data (empty hash if no frontmatter)
|
|
15
15
|
def self.parse_frontmatter(content)
|
|
16
|
+
parse_frontmatter!(content)
|
|
17
|
+
rescue Psych::SyntaxError
|
|
18
|
+
# Read paths tolerate arbitrary user files: an unparsable block
|
|
19
|
+
# yields an empty hash instead of crashing scans.
|
|
20
|
+
{}
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Strict variant for mutating paths (FieldUpdater and friends): a
|
|
24
|
+
# syntax error must stop the change instead of silently rebuilding
|
|
25
|
+
# the file from an empty frontmatter (the 8xsdfo ask-flow corruption
|
|
26
|
+
# amplified one bad line into total frontmatter loss).
|
|
27
|
+
# @param content [String] The markdown content with optional frontmatter
|
|
28
|
+
# @return [Hash] Parsed frontmatter data (empty hash if no frontmatter)
|
|
29
|
+
# @raise [Psych::SyntaxError] when a frontmatter block is unparsable
|
|
30
|
+
def self.parse_frontmatter!(content)
|
|
16
31
|
return {} if content.nil? || content.empty?
|
|
17
32
|
return {} unless content.start_with?("---\n")
|
|
18
33
|
|
|
@@ -21,11 +36,7 @@ module Ace
|
|
|
21
36
|
|
|
22
37
|
yaml_content = content[4...end_index]
|
|
23
38
|
|
|
24
|
-
|
|
25
|
-
YAML.safe_load(yaml_content, permitted_classes: [Date, Time, Symbol]) || {}
|
|
26
|
-
rescue Psych::SyntaxError
|
|
27
|
-
{}
|
|
28
|
-
end
|
|
39
|
+
YAML.safe_load(yaml_content, permitted_classes: [Date, Time, Symbol]) || {}
|
|
29
40
|
end
|
|
30
41
|
|
|
31
42
|
# Extract content after frontmatter
|
|
@@ -50,6 +61,14 @@ module Ace
|
|
|
50
61
|
def self.parse(content)
|
|
51
62
|
[parse_frontmatter(content), extract_body(content)]
|
|
52
63
|
end
|
|
64
|
+
|
|
65
|
+
# Strict parse for mutating paths: raises on an unparsable block.
|
|
66
|
+
# @param content [String] The markdown content
|
|
67
|
+
# @return [Array(Hash, String)] Tuple of [frontmatter, body]
|
|
68
|
+
# @raise [Psych::SyntaxError] when a frontmatter block is unparsable
|
|
69
|
+
def self.parse!(content)
|
|
70
|
+
[parse_frontmatter!(content), extract_body(content)]
|
|
71
|
+
end
|
|
53
72
|
end
|
|
54
73
|
end
|
|
55
74
|
end
|
|
@@ -31,7 +31,7 @@ module Ace
|
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
# Serialize a single key-value entry with indentation support.
|
|
34
|
-
def self.serialize_entry(lines, key, value, indent:)
|
|
34
|
+
private_class_method def self.serialize_entry(lines, key, value, indent:)
|
|
35
35
|
prefix = " " * indent
|
|
36
36
|
case value
|
|
37
37
|
when Hash
|
|
@@ -43,7 +43,7 @@ module Ace
|
|
|
43
43
|
lines << if value.empty?
|
|
44
44
|
"#{prefix}#{key}: []"
|
|
45
45
|
else
|
|
46
|
-
"#{prefix}#{key}: [#{value.join(", ")}]"
|
|
46
|
+
"#{prefix}#{key}: [#{value.map { |element| flow_element(element, key) }.join(", ")}]"
|
|
47
47
|
end
|
|
48
48
|
when String
|
|
49
49
|
lines << if needs_quoting?(value)
|
|
@@ -56,7 +56,27 @@ module Ace
|
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
|
|
59
|
+
# One element inside a flow sequence: strings follow the same
|
|
60
|
+
# quoting rules as flat values (a plain scalar containing `: ` would
|
|
61
|
+
# parse back as a hash, silently corrupting the value across
|
|
62
|
+
# read-modify-write cycles). Numbers, booleans and nil serialize to
|
|
63
|
+
# their YAML literals; compound values have no safe flow form and
|
|
64
|
+
# fail loudly instead of emitting YAML that parses back as a
|
|
65
|
+
# different structure (the 8xsdfo ask-flow corruption).
|
|
66
|
+
def self.flow_element(element, key)
|
|
67
|
+
case element
|
|
68
|
+
when String
|
|
69
|
+
needs_quoting?(element) ? "\"#{escape_yaml_string(element)}\"" : element
|
|
70
|
+
when Integer, Float, true, false
|
|
71
|
+
element.to_s
|
|
72
|
+
when nil
|
|
73
|
+
"null"
|
|
74
|
+
else
|
|
75
|
+
raise ArgumentError,
|
|
76
|
+
"frontmatter array '#{key}' cannot safely carry a #{element.class} element; use scalar strings"
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
private_class_method :flow_element
|
|
60
80
|
|
|
61
81
|
# Check if a string value needs YAML quoting
|
|
62
82
|
# @param value [String] Value to check
|
|
@@ -25,7 +25,7 @@ module Ace
|
|
|
25
25
|
|
|
26
26
|
file.rewind
|
|
27
27
|
content = file.read
|
|
28
|
-
frontmatter, body =
|
|
28
|
+
frontmatter, body = parse_strict(file_path, content)
|
|
29
29
|
# Strip leading newline from body so rebuild doesn't double-space
|
|
30
30
|
body = body.sub(/\A\n/, "")
|
|
31
31
|
|
|
@@ -118,6 +118,16 @@ module Ace
|
|
|
118
118
|
file.fsync
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
+
# Strict parse with an actionable message: an unparsable block must
|
|
122
|
+
# abort the update (the rewrite would silently drop the whole
|
|
123
|
+
# frontmatter), never proceed with an empty hash.
|
|
124
|
+
def self.parse_strict(file_path, content)
|
|
125
|
+
Atoms::FrontmatterParser.parse!(content)
|
|
126
|
+
rescue Psych::SyntaxError => e
|
|
127
|
+
raise ArgumentError,
|
|
128
|
+
"#{file_path}: frontmatter YAML is invalid (#{e.message}); refusing to rewrite the file"
|
|
129
|
+
end
|
|
130
|
+
|
|
121
131
|
private_class_method :apply_nested_set, :rewrite_locked_file
|
|
122
132
|
end
|
|
123
133
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ace-support-items
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.15.
|
|
4
|
+
version: 0.15.16
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michal Czyz
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-10-
|
|
10
|
+
date: 2026-10-29 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: ace-support-core
|