@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 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(row => row.name && row.type);
552
+ const validConnectors = connectorList.filter(r => r.name && r.type);
553
553
 
554
- const pagesRoot = path.resolve(process.cwd(), 'modules/components/pages');
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
- if (!name || !type) {
557
- console.warn(`⚠️ Skipping invalid connector entry:`, { name, type });
558
- return false;
559
- }
560
- const expected = path.join(pagesRoot, `${type}s`, `${name}.adoc`);
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
- const missingConnectors = allMissing.filter(({ name }) => !name.includes('sql_driver'));
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(m => m.name === component.name && `${m.type}s` === key)
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: tempDataPath,
594
- overrides: options.overrides,
595
- template: options.templateMain,
596
- templateFields: options.templateFields,
597
- templateExamples: options.templateExamples,
598
- templateIntro: options.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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redpanda-data/docs-extensions-and-macros",
3
- "version": "4.6.1",
3
+ "version": "4.6.2",
4
4
  "description": "Antora extensions and macros developed for Redpanda documentation.",
5
5
  "keywords": [
6
6
  "antora",
@@ -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.type !== 'object' && child.default !== undefined) {
61
- if (typeof child.default !== 'object') {
62
- const display = child.default === '' ? '""' : String(child.default);
63
- block += `*Default*: \`${display}\`\n\n`;
64
- } else {
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=\"1m,2a\"]\n|===\n|Option |Summary\n\n`;
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
- // Options list
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.type === 'string') {
88
- if (child.kind === 'array') {
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
- block += `${child.name}: \`${String(example)}\`\n`;
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
- // If default is itself an object or array → dump as YAML block
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
- try {
37
- // Turn the object/array into a YAML string. We also need to indent that block
38
- const rawYaml = yaml.stringify(field.default).trim();
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
- return `${indent}${name}:\n${indentedYaml}`;
45
- } catch (error) {
46
- console.warn(`Failed to serialize default value for field ${field.name}:`, error);
47
- return `${indent}${name}: {} # Error serializing default value`;
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
- // Otherwise, default is a primitive (string/number/bool)
52
- if (field.type === 'string') {
53
- return `${indent}${name}: ${yaml.stringify(field.default)}`;
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
- return `${indent}${name}: ${field.default}`;
77
+
78
+ return `${indent}${name}: ${value}`;
56
79
  }
57
80
 
58
- // No default → choose representation based on kind
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
- const snippet = yaml.stringify(item).trim();
16
- const lines = snippet.split('\n');
17
- out += lines
18
- .map((line, idx) => (idx === 0 ? ` - ${line}` : ` ${line}`))
19
- .join('\n') + '\n';
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
+ };