@redpanda-data/docs-extensions-and-macros 4.6.1 → 4.6.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.
- package/bin/doc-tools.js +26 -18
- package/package.json +1 -1
- package/tools/redpanda-connect/generate-rpcn-connector-docs.js +1 -1
- package/tools/redpanda-connect/helpers/renderConnectFields.js +46 -51
- package/tools/redpanda-connect/helpers/renderLeafField.js +40 -17
- package/tools/redpanda-connect/helpers/renderYamlList.js +20 -6
package/bin/doc-tools.js
CHANGED
|
@@ -546,22 +546,27 @@ automation
|
|
|
546
546
|
}
|
|
547
547
|
|
|
548
548
|
if (options.draftMissing) {
|
|
549
|
-
console.log('⏳ Drafting missing connectors
|
|
549
|
+
console.log('⏳ Drafting missing connectors…');
|
|
550
550
|
try {
|
|
551
551
|
const connectorList = await parseCSVConnectors(options.csv, console);
|
|
552
|
-
const validConnectors = connectorList.filter(
|
|
552
|
+
const validConnectors = connectorList.filter(r => r.name && r.type);
|
|
553
553
|
|
|
554
|
-
const
|
|
554
|
+
const roots = {
|
|
555
|
+
pages: path.resolve(process.cwd(), 'modules/components/pages'),
|
|
556
|
+
partials:path.resolve(process.cwd(), 'modules/components/partials/components'),
|
|
557
|
+
};
|
|
558
|
+
|
|
559
|
+
// find any connector that has NO .adoc under pages/TYPEs or partials/TYPEs
|
|
555
560
|
const allMissing = validConnectors.filter(({ name, type }) => {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
return !fs.existsSync(expected);
|
|
561
|
+
const relPath = path.join(`${type}s`, `${name}.adoc`);
|
|
562
|
+
const existsInAny = Object.values(roots).some(root =>
|
|
563
|
+
fs.existsSync(path.join(root, relPath))
|
|
564
|
+
);
|
|
565
|
+
return !existsInAny;
|
|
562
566
|
});
|
|
563
567
|
|
|
564
|
-
|
|
568
|
+
// still skip sql_driver
|
|
569
|
+
const missingConnectors = allMissing.filter(c => !c.name.includes('sql_driver'));
|
|
565
570
|
|
|
566
571
|
if (missingConnectors.length === 0) {
|
|
567
572
|
console.log('✅ All connectors (excluding sql_drivers) already have docs—nothing to draft.');
|
|
@@ -572,17 +577,20 @@ automation
|
|
|
572
577
|
});
|
|
573
578
|
console.log('');
|
|
574
579
|
|
|
580
|
+
// build your filtered JSON as before…
|
|
575
581
|
const rawData = fs.readFileSync(dataFile, 'utf8');
|
|
576
582
|
const dataObj = JSON.parse(rawData);
|
|
577
|
-
|
|
578
583
|
const filteredDataObj = {};
|
|
584
|
+
|
|
579
585
|
for (const [key, arr] of Object.entries(dataObj)) {
|
|
580
586
|
if (!Array.isArray(arr)) {
|
|
581
587
|
filteredDataObj[key] = arr;
|
|
582
588
|
continue;
|
|
583
589
|
}
|
|
584
590
|
filteredDataObj[key] = arr.filter(component =>
|
|
585
|
-
missingConnectors.some(
|
|
591
|
+
missingConnectors.some(
|
|
592
|
+
m => m.name === component.name && `${m.type}s` === key
|
|
593
|
+
)
|
|
586
594
|
);
|
|
587
595
|
}
|
|
588
596
|
|
|
@@ -590,12 +598,12 @@ automation
|
|
|
590
598
|
fs.writeFileSync(tempDataPath, JSON.stringify(filteredDataObj, null, 2), 'utf8');
|
|
591
599
|
|
|
592
600
|
const draftResult = await generateRpcnConnectorDocs({
|
|
593
|
-
data:
|
|
594
|
-
overrides:
|
|
595
|
-
template:
|
|
596
|
-
templateFields:
|
|
597
|
-
templateExamples:
|
|
598
|
-
templateIntro:
|
|
601
|
+
data: tempDataPath,
|
|
602
|
+
overrides: options.overrides,
|
|
603
|
+
template: options.templateMain,
|
|
604
|
+
templateFields: options.templateFields,
|
|
605
|
+
templateExamples:options.templateExamples,
|
|
606
|
+
templateIntro: options.templateIntro,
|
|
599
607
|
writeFullDrafts: true
|
|
600
608
|
});
|
|
601
609
|
|
package/package.json
CHANGED
|
@@ -185,7 +185,7 @@ async function generateRpcnConnectorDocs(options) {
|
|
|
185
185
|
partialFiles.push(path.relative(process.cwd(), fPath));
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
if (examplesOut.trim()) {
|
|
188
|
+
if (examplesOut.trim() && type !== 'bloblang-functions' && type !== 'bloblang-methods') {
|
|
189
189
|
const ePath = path.join(examplesOutRoot, type, `${name}.adoc`);
|
|
190
190
|
fs.mkdirSync(path.dirname(ePath), { recursive: true });
|
|
191
191
|
fs.writeFileSync(ePath, examplesOut);
|
|
@@ -26,7 +26,7 @@ module.exports = function renderConnectFields(children, prefix = '') {
|
|
|
26
26
|
sorted.forEach(child => {
|
|
27
27
|
if (child.is_deprecated || !child.name) return;
|
|
28
28
|
|
|
29
|
-
// Normalize type
|
|
29
|
+
// Normalize type: arrays and unknown-map as object
|
|
30
30
|
let displayType;
|
|
31
31
|
if (child.type === 'string' && child.kind === 'array') {
|
|
32
32
|
displayType = 'array';
|
|
@@ -56,27 +56,49 @@ module.exports = function renderConnectFields(children, prefix = '') {
|
|
|
56
56
|
|
|
57
57
|
block += `*Type*: \`${displayType}\`\n\n`;
|
|
58
58
|
|
|
59
|
-
// Default
|
|
60
|
-
if (child.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
block += `*Default*:
|
|
64
|
-
}
|
|
59
|
+
// Default value
|
|
60
|
+
if (child.default !== undefined) {
|
|
61
|
+
// Empty array
|
|
62
|
+
if (Array.isArray(child.default) && child.default.length === 0) {
|
|
63
|
+
block += `*Default*: \`[]\`\n\n`;
|
|
64
|
+
}
|
|
65
|
+
// Empty object
|
|
66
|
+
else if (
|
|
67
|
+
child.default !== null &&
|
|
68
|
+
typeof child.default === 'object' &&
|
|
69
|
+
!Array.isArray(child.default) &&
|
|
70
|
+
Object.keys(child.default).length === 0
|
|
71
|
+
) {
|
|
72
|
+
block += `*Default*: \`{}\`\n\n`;
|
|
73
|
+
}
|
|
74
|
+
// Complex object/array
|
|
75
|
+
else if (typeof child.default === 'object') {
|
|
65
76
|
const defYaml = yaml.stringify(child.default).trim();
|
|
66
77
|
block += `*Default*:\n[source,yaml]\n----\n${defYaml}\n----\n\n`;
|
|
67
78
|
}
|
|
79
|
+
// Primitive
|
|
80
|
+
else {
|
|
81
|
+
const display = typeof child.default === 'string'
|
|
82
|
+
? (child.default.startsWith('"') && child.default.endsWith('"')
|
|
83
|
+
? child.default
|
|
84
|
+
: child.default === ''
|
|
85
|
+
? '""'
|
|
86
|
+
: child.default)
|
|
87
|
+
: String(child.default);
|
|
88
|
+
block += `*Default*: \`${display}\`\n\n`;
|
|
89
|
+
}
|
|
68
90
|
}
|
|
69
91
|
|
|
70
|
-
// Annotated options
|
|
92
|
+
// Annotated options table
|
|
71
93
|
if (child.annotated_options && child.annotated_options.length) {
|
|
72
|
-
block += `[cols
|
|
94
|
+
block += `[cols="1m,2a"]\n|===\n|Option |Summary\n\n`;
|
|
73
95
|
child.annotated_options.forEach(([opt, summary]) => {
|
|
74
96
|
block += `|${opt}\n|${summary}\n\n`;
|
|
75
97
|
});
|
|
76
98
|
block += `|===\n\n`;
|
|
77
99
|
}
|
|
78
100
|
|
|
79
|
-
//
|
|
101
|
+
// Simple options list
|
|
80
102
|
if (child.options && child.options.length) {
|
|
81
103
|
block += `*Options*: ${child.options.map(opt => `\`${opt}\``).join(', ')}\n\n`;
|
|
82
104
|
}
|
|
@@ -84,54 +106,27 @@ module.exports = function renderConnectFields(children, prefix = '') {
|
|
|
84
106
|
// Examples
|
|
85
107
|
if (child.examples && child.examples.length) {
|
|
86
108
|
block += `[source,yaml]\n----\n# Examples:\n`;
|
|
87
|
-
if (child.
|
|
88
|
-
|
|
89
|
-
block += renderYamlList(child.name, child.examples);
|
|
90
|
-
} else {
|
|
91
|
-
child.examples.forEach(example => {
|
|
92
|
-
if (typeof example === 'string' && example.includes('\n')) {
|
|
93
|
-
block += `${child.name}: |-\n`;
|
|
94
|
-
block += example.split('\n').map(line => ' ' + line).join('\n') + '\n';
|
|
95
|
-
} else {
|
|
96
|
-
block += `${child.name}: \`${example}\`\n`;
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
block += '\n';
|
|
100
|
-
}
|
|
101
|
-
} else if (child.type === 'processor') {
|
|
102
|
-
if (child.kind === 'array') {
|
|
103
|
-
block += renderYamlList(child.name, child.examples);
|
|
104
|
-
} else {
|
|
105
|
-
child.examples.forEach(example => {
|
|
106
|
-
block += `${child.name}: \`${String(example)}\`\n`;
|
|
107
|
-
});
|
|
108
|
-
block += '\n';
|
|
109
|
-
}
|
|
110
|
-
} else if (child.type === 'object') {
|
|
111
|
-
if (child.kind === 'array') {
|
|
112
|
-
block += renderYamlList(child.name, child.examples);
|
|
113
|
-
} else {
|
|
114
|
-
child.examples.forEach(example => {
|
|
115
|
-
if (typeof example === 'object') {
|
|
116
|
-
const snippet = yaml.stringify(example).trim();
|
|
117
|
-
block += `${child.name}:\n`;
|
|
118
|
-
block += snippet.split('\n').map(line => ' ' + line).join('\n') + '\n';
|
|
119
|
-
} else {
|
|
120
|
-
block += `${child.name}: \`${String(example)}\`\n`;
|
|
121
|
-
}
|
|
122
|
-
});
|
|
123
|
-
block += '\n';
|
|
124
|
-
}
|
|
109
|
+
if (child.kind === 'array') {
|
|
110
|
+
block += renderYamlList(child.name, child.examples);
|
|
125
111
|
} else {
|
|
126
112
|
child.examples.forEach(example => {
|
|
127
|
-
|
|
113
|
+
if (typeof example === 'object') {
|
|
114
|
+
const snippet = yaml.stringify(example).trim();
|
|
115
|
+
block += `${child.name}:\n`;
|
|
116
|
+
block += snippet.split('\n').map(line => ' ' + line).join('\n') + '\n';
|
|
117
|
+
} else if (typeof example === 'string' && example.includes('\n')) {
|
|
118
|
+
block += `${child.name}: |-\n`;
|
|
119
|
+
block += example.split('\n').map(line => ' ' + line).join('\n') + '\n';
|
|
120
|
+
} else {
|
|
121
|
+
// Primitive values
|
|
122
|
+
block += `${child.name}: ${example}\n`;
|
|
123
|
+
}
|
|
128
124
|
});
|
|
129
|
-
block += '\n';
|
|
130
125
|
}
|
|
131
126
|
block += `----\n\n`;
|
|
132
127
|
}
|
|
133
128
|
|
|
134
|
-
// Nested
|
|
129
|
+
// Nested children
|
|
135
130
|
if (child.children && child.children.length) {
|
|
136
131
|
block += renderConnectFields(child.children, currentPath);
|
|
137
132
|
}
|
|
@@ -31,34 +31,57 @@ module.exports = function renderLeafField(field, indentLevel) {
|
|
|
31
31
|
|
|
32
32
|
// If a default is provided, use it:
|
|
33
33
|
if (field.default !== undefined) {
|
|
34
|
-
//
|
|
34
|
+
// Empty array inline
|
|
35
|
+
if (Array.isArray(field.default) && field.default.length === 0) {
|
|
36
|
+
return `${indent}${name}: []`;
|
|
37
|
+
}
|
|
38
|
+
// Empty object inline
|
|
39
|
+
if (
|
|
40
|
+
field.default !== null &&
|
|
41
|
+
typeof field.default === 'object' &&
|
|
42
|
+
!Array.isArray(field.default) &&
|
|
43
|
+
Object.keys(field.default).length === 0
|
|
44
|
+
) {
|
|
45
|
+
return `${indent}${name}: {}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Complex object/array: dump as YAML block
|
|
35
49
|
if (typeof field.default === 'object') {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// Indent each line of rawYaml by (indentLevel + 2) spaces:
|
|
40
|
-
const indentedYaml = rawYaml
|
|
50
|
+
try {
|
|
51
|
+
const rawYaml = yaml.stringify(field.default).trim();
|
|
52
|
+
const indentedYaml = rawYaml
|
|
41
53
|
.split('\n')
|
|
42
54
|
.map(line => ' '.repeat(indentLevel + 2) + line)
|
|
43
55
|
.join('\n');
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
return `${indent}${name}:\n${indentedYaml}`;
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.warn(`Failed to serialize default for ${field.name}:`, error);
|
|
59
|
+
return `${indent}${name}: {} # Error serializing default`;
|
|
60
|
+
}
|
|
49
61
|
}
|
|
50
62
|
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
63
|
+
// Primitive default: string, number, boolean
|
|
64
|
+
let value;
|
|
65
|
+
if (typeof field.default === 'string') {
|
|
66
|
+
// Preserve existing quotes
|
|
67
|
+
if (field.default.startsWith('"') && field.default.endsWith('"')) {
|
|
68
|
+
value = field.default;
|
|
69
|
+
} else if (field.default === '') {
|
|
70
|
+
value = '""';
|
|
71
|
+
} else {
|
|
72
|
+
value = field.default;
|
|
73
|
+
}
|
|
74
|
+
} else {
|
|
75
|
+
value = String(field.default);
|
|
54
76
|
}
|
|
55
|
-
|
|
77
|
+
|
|
78
|
+
return `${indent}${name}: ${value}`;
|
|
56
79
|
}
|
|
57
80
|
|
|
58
|
-
// No default → choose representation
|
|
81
|
+
// No default → choose representation
|
|
59
82
|
if (field.kind === 'array') {
|
|
60
83
|
return `${indent}${name}: [] ${comment}`;
|
|
61
84
|
} else {
|
|
62
85
|
return `${indent}${name}: "" ${comment}`;
|
|
63
86
|
}
|
|
64
|
-
}
|
|
87
|
+
};
|
|
@@ -12,13 +12,27 @@ module.exports = function renderYamlList(name, exampleGroups) {
|
|
|
12
12
|
exampleGroups.forEach(group => {
|
|
13
13
|
const items = Array.isArray(group) ? group : [group];
|
|
14
14
|
items.forEach(item => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
// Scalars
|
|
16
|
+
if (typeof item === 'string' || typeof item === 'number' || typeof item === 'boolean') {
|
|
17
|
+
let value = String(item);
|
|
18
|
+
// Quote when needed: already-quoted scalars stay as-is; otherwise quote `*`
|
|
19
|
+
// and any value containing YAML-special characters.
|
|
20
|
+
if (!(value.startsWith('"') && value.endsWith('"'))) {
|
|
21
|
+
if (value === '*' || /[:\[\]\{\},&>|%@`]/.test(value)) {
|
|
22
|
+
value = `"${value}"`;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
out += ` - ${value}\n`;
|
|
26
|
+
} else {
|
|
27
|
+
// Objects/arrays: stringify with indentation
|
|
28
|
+
const snippet = yaml.stringify(item).trim();
|
|
29
|
+
const lines = snippet.split('\n');
|
|
30
|
+
out += lines
|
|
31
|
+
.map((line, idx) => (idx === 0 ? ` - ${line}` : ` ${line}`))
|
|
32
|
+
.join('\n') + '\n';
|
|
33
|
+
}
|
|
20
34
|
});
|
|
21
35
|
out += '\n';
|
|
22
36
|
});
|
|
23
37
|
return out;
|
|
24
|
-
}
|
|
38
|
+
};
|