@redpanda-data/docs-extensions-and-macros 5.38.0 → 5.38.2
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.
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://redpanda.com/schemas/property-overrides.schema.json",
|
|
4
|
+
"title": "Property overrides",
|
|
5
|
+
"description": "Hand-authored corrections and additions applied on top of properties extracted from Redpanda's C++ source. See tools/property-extractor/README.adoc.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"properties": {
|
|
8
|
+
"properties": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"description": "Keyed by property key or name (see property_extractor.py's name-fallback lookup). An override key that matches neither creates a phantom stub property — see property_extractor.py's report_phantom_stubs().",
|
|
11
|
+
"additionalProperties": { "$ref": "#/$defs/propertyOverride" }
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"$defs": {
|
|
16
|
+
"propertyOverride": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"additionalProperties": false,
|
|
19
|
+
"properties": {
|
|
20
|
+
"_comment": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"description": "Free-text note to whoever edits this entry next. Never read by the generator."
|
|
23
|
+
},
|
|
24
|
+
"description": { "type": "string" },
|
|
25
|
+
"upstream_ref": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"description": "The upstream issue or PR (against the engineering repo whose defective string this description patches, either the short form 'redpanda-data/streaming-enterprise#12345' or the full URL) that will make this description override redundant once merged and released. A description override is a stopgap, not a fix: set this so the override is born with a retirement path, and remove both the override and this field once the fix ships. Only meaningful alongside 'description' — has no effect on generation or rendering."
|
|
28
|
+
},
|
|
29
|
+
"version": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "Version the property was introduced in (e.g. 'v23.1.0')."
|
|
32
|
+
},
|
|
33
|
+
"example": {
|
|
34
|
+
"description": "Literal example content, or an example_file/example_yaml reference resolved relative to this overrides file."
|
|
35
|
+
},
|
|
36
|
+
"example_file": { "type": "string" },
|
|
37
|
+
"example_yaml": { "type": "string" },
|
|
38
|
+
"default": {
|
|
39
|
+
"description": "Replaces the extracted default. Prefer leaving this unset — it silently pins a value the extractor would otherwise keep in sync with the C++ source on every release."
|
|
40
|
+
},
|
|
41
|
+
"type": { "type": "string" },
|
|
42
|
+
"config_scope": {
|
|
43
|
+
"enum": ["cluster", "broker", "topic", null],
|
|
44
|
+
"description": "Almost always inferred automatically from defined_in — see property_extractor.py's add_config_scope(). Only set this for an override-created property (defined_in: 'override'), which has no source file to infer from."
|
|
45
|
+
},
|
|
46
|
+
"exclude_from_docs": { "type": "boolean" },
|
|
47
|
+
"category": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"description": "Documentation grouping. Not inferable for cluster/broker properties; topic properties get a mechanical default from infer_category() that this can still override."
|
|
50
|
+
},
|
|
51
|
+
"accepted_values": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"description": "Replaces the enum field to filter displayed values (e.g. hiding an internal-only mode).",
|
|
54
|
+
"items": {}
|
|
55
|
+
},
|
|
56
|
+
"is_deprecated": { "type": "boolean" },
|
|
57
|
+
"visibility": { "type": "string" },
|
|
58
|
+
"related_topics": {
|
|
59
|
+
"type": "array",
|
|
60
|
+
"deprecated": true,
|
|
61
|
+
"description": "Deprecated — use see_also. A plain string, or one prefixed 'cloud-only:'/'self-managed-only:' for conditional display. The prefix is free text with no validation; still read for existing entries, normalized alongside see_also by seeAlsoView.js.",
|
|
62
|
+
"items": { "type": "string" }
|
|
63
|
+
},
|
|
64
|
+
"see_also": {
|
|
65
|
+
"type": "array",
|
|
66
|
+
"description": "Related commands or documentation pages, in the docs-data/rpk-overrides.json 'seeAlso' shape. Each item is a plain string (shown everywhere) or an object naming exactly one of cloud_only/self_hosted_only (shown only in that build).",
|
|
67
|
+
"items": {
|
|
68
|
+
"oneOf": [
|
|
69
|
+
{
|
|
70
|
+
"type": "string",
|
|
71
|
+
"description": "xref link or related-topic text, shown in every build."
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"type": "object",
|
|
75
|
+
"description": "Conditional see-also item shown only in the named build.",
|
|
76
|
+
"properties": {
|
|
77
|
+
"content": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"description": "The xref link or related-topic text."
|
|
80
|
+
},
|
|
81
|
+
"cloud_only": {
|
|
82
|
+
"type": "boolean",
|
|
83
|
+
"description": "If true, only shown in Cloud docs (wrapped with ifdef::env-cloud[])."
|
|
84
|
+
},
|
|
85
|
+
"self_hosted_only": {
|
|
86
|
+
"type": "boolean",
|
|
87
|
+
"description": "If true, only shown in self-hosted docs (wrapped with ifndef::env-cloud[])."
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"required": ["content"],
|
|
91
|
+
"additionalProperties": false,
|
|
92
|
+
"oneOf": [
|
|
93
|
+
{
|
|
94
|
+
"required": ["cloud_only"],
|
|
95
|
+
"not": { "required": ["self_hosted_only"] }
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"required": ["self_hosted_only"],
|
|
99
|
+
"not": { "required": ["cloud_only"] }
|
|
100
|
+
}
|
|
101
|
+
]
|
|
102
|
+
}
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"admonitions": {
|
|
107
|
+
"type": "array",
|
|
108
|
+
"description": "Structured NOTE/TIP/IMPORTANT/WARNING/CAUTION callouts, rendered as Asciidoctor admonition blocks instead of hand-written markup in description. Each entry needs type and text; title is optional. See property_extractor.py's _normalize_admonitions() -- an entry that doesn't match this shape is dropped with a warning, not rejected here, so the schema stays permissive on casing/whitespace that the generator itself normalizes.",
|
|
109
|
+
"items": {
|
|
110
|
+
"type": "object",
|
|
111
|
+
"required": ["type", "text"],
|
|
112
|
+
"properties": {
|
|
113
|
+
"type": {
|
|
114
|
+
"type": "string",
|
|
115
|
+
"description": "Case-insensitive; normalized to uppercase. One of note, tip, important, warning, caution.",
|
|
116
|
+
"enum": ["note", "tip", "important", "warning", "caution",
|
|
117
|
+
"NOTE", "TIP", "IMPORTANT", "WARNING", "CAUTION",
|
|
118
|
+
"Note", "Tip", "Important", "Warning", "Caution"]
|
|
119
|
+
},
|
|
120
|
+
"text": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"description": "Admonition body. May itself contain AsciiDoc markup."
|
|
123
|
+
},
|
|
124
|
+
"title": {
|
|
125
|
+
"type": "string",
|
|
126
|
+
"description": "Optional admonition title, shown in place of the default type label."
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
"additionalProperties": false
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redpanda-data/docs-extensions-and-macros",
|
|
3
|
-
"version": "5.38.
|
|
3
|
+
"version": "5.38.2",
|
|
4
4
|
"description": "Antora extensions and macros developed for Redpanda documentation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"antora",
|
|
@@ -106,9 +106,8 @@
|
|
|
106
106
|
"tools",
|
|
107
107
|
"docker-compose",
|
|
108
108
|
"mcp",
|
|
109
|
-
"docs-data
|
|
110
|
-
"docs-data/kapa-source-groups.json"
|
|
111
|
-
"docs-data/kapa-source-groups.schema.json"
|
|
109
|
+
"docs-data/*.schema.json",
|
|
110
|
+
"docs-data/kapa-source-groups.json"
|
|
112
111
|
],
|
|
113
112
|
"license": "ISC",
|
|
114
113
|
"engines": {
|
|
@@ -33,7 +33,11 @@ const CONVENTION = {
|
|
|
33
33
|
case: 'sentence',
|
|
34
34
|
terminal_period: true,
|
|
35
35
|
verbatim_asciidoc: true,
|
|
36
|
-
state_default:
|
|
36
|
+
// Not state_default. The rendered page builds a "Default:" row from the
|
|
37
|
+
// extractor's own field, so prose restating a concrete default duplicates
|
|
38
|
+
// structured data. Only a sentinel default (null, 0, -1, "") carries
|
|
39
|
+
// behavior that row cannot express.
|
|
40
|
+
state_sentinel_default: true
|
|
37
41
|
}
|
|
38
42
|
|
|
39
43
|
function run (cmd, args, options = {}) {
|
|
@@ -133,8 +137,9 @@ function mapExtractorJson (json, repo, options = {}) {
|
|
|
133
137
|
|
|
134
138
|
const lineStart = prop.line_start != null ? prop.line_start : null
|
|
135
139
|
const lineEnd = prop.line_end != null ? prop.line_end : lineStart
|
|
136
|
-
|
|
137
|
-
|
|
140
|
+
// null and "" are defaults too: the extractor emits null for every
|
|
141
|
+
// std::nullopt, and those are exactly the sentinels the rule below is for.
|
|
142
|
+
const hasDefault = Object.prototype.hasOwnProperty.call(prop, 'default')
|
|
138
143
|
|
|
139
144
|
declarations.push({
|
|
140
145
|
surface: 'properties',
|
|
@@ -148,6 +153,7 @@ function mapExtractorJson (json, repo, options = {}) {
|
|
|
148
153
|
meta: {
|
|
149
154
|
has_default: hasDefault,
|
|
150
155
|
default: hasDefault ? prop.default : null,
|
|
156
|
+
type: typeof prop.type === 'string' ? prop.type : null,
|
|
151
157
|
is_enum: Boolean(prop.is_enum),
|
|
152
158
|
nullable: Boolean(prop.nullable)
|
|
153
159
|
}
|
|
@@ -184,16 +190,52 @@ const RULES = [
|
|
|
184
190
|
}
|
|
185
191
|
},
|
|
186
192
|
{
|
|
187
|
-
name: 'default-
|
|
188
|
-
description: 'Property
|
|
193
|
+
name: 'sentinel-default-unexplained',
|
|
194
|
+
description: 'Property defaults to a sentinel whose meaning the description never explains',
|
|
189
195
|
severity: 'info',
|
|
196
|
+
// The rendered page already carries a "Default:" row built from the
|
|
197
|
+
// extractor's own `default` field, so asking the prose to restate a
|
|
198
|
+
// concrete default duplicates structured data -- and duplicated facts go
|
|
199
|
+
// stale. A real example: tombstone_retention_ms's description claimed "a
|
|
200
|
+
// typical default setting is 86400000" while the actual default was null.
|
|
201
|
+
//
|
|
202
|
+
// A SENTINEL default is the exception. null, 0, -1 and "" usually mean
|
|
203
|
+
// disabled, unlimited or unset, and which one is not inferable from the
|
|
204
|
+
// value, so "Default: null" leaves the reader guessing. That meaning is
|
|
205
|
+
// information the structured field cannot carry, which is the only case
|
|
206
|
+
// worth a finding.
|
|
190
207
|
check: (decl) => {
|
|
191
|
-
const text = decl.string || ''
|
|
208
|
+
const text = (decl.string || '').trim()
|
|
192
209
|
if (!text || !decl.meta || !decl.meta.has_default) return []
|
|
193
|
-
const
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
210
|
+
const value = decl.meta.default
|
|
211
|
+
// Booleans are never sentinels: `false` is a real setting, not a
|
|
212
|
+
// stand-in for "off".
|
|
213
|
+
if (typeof value === 'boolean') return []
|
|
214
|
+
// A string-typed property defaulting to null or "" is plainly "not
|
|
215
|
+
// configured" (credentials, bucket names, endpoints); the "Default:" row
|
|
216
|
+
// says that on its own, so only non-string sentinels are ambiguous.
|
|
217
|
+
if (decl.meta.type === 'string' && (value === null || value === '')) return []
|
|
218
|
+
const sentinels = [
|
|
219
|
+
{ match: (v) => v === null || v === 'null', token: /\bnull\b/i, label: 'null' },
|
|
220
|
+
{ match: (v) => v === '' , token: /\b(empty|blank)\b/i, label: 'an empty string' },
|
|
221
|
+
{ match: (v) => v === 0 || v === '0', token: /\b(0|zero)\b/i, label: '0' },
|
|
222
|
+
{ match: (v) => v === -1 || v === '-1', token: /-1\b/, label: '-1' }
|
|
223
|
+
]
|
|
224
|
+
const sentinel = sentinels.find((s) => s.match(value))
|
|
225
|
+
if (!sentinel) return []
|
|
226
|
+
// Either name the sentinel, or say what it does. Both forms explain it;
|
|
227
|
+
// neither is satisfied by an unrelated digit elsewhere in the sentence.
|
|
228
|
+
// "default"/"falls back"/"inherits"/"omitted" cover descriptions that
|
|
229
|
+
// explain the null case by naming what is used instead, which is the
|
|
230
|
+
// explanation being asked for.
|
|
231
|
+
const MEANING = /\b(disabl\w*|unlimited|no limit|unbounded|infinite|unset|not set|never|off|ignored|no maximum|no minimum|defaults?|inherit\w*|blank|omitted|not specified|falls? back)\b/i
|
|
232
|
+
if (sentinel.token.test(text) || MEANING.test(text)) return []
|
|
233
|
+
return [{
|
|
234
|
+
message: `Property defaults to ${sentinel.label}, and the description does not say what that means. `
|
|
235
|
+
+ 'A sentinel default carries behavior the rendered "Default:" row cannot: say whether it disables '
|
|
236
|
+
+ 'the property, means unlimited, or leaves it unset. There is no need to restate a concrete '
|
|
237
|
+
+ 'default value; the page already renders it from structured data.'
|
|
238
|
+
}]
|
|
197
239
|
}
|
|
198
240
|
}
|
|
199
241
|
]
|