@redpanda-data/docs-extensions-and-macros 4.13.2 → 4.13.4
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-mcp.js +1 -1
- package/bin/doc-tools.js +1 -1
- package/bin/mcp-tools/generated-docs-review.js +2 -2
- package/bin/mcp-tools/mcp-validation.js +1 -1
- package/bin/mcp-tools/openapi.js +2 -2
- package/extensions/generate-rp-connect-categories.js +0 -1
- package/package.json +1 -1
- package/tools/bundle-openapi.js +1 -1
- package/tools/redpanda-connect/README.adoc +4 -4
- package/tools/redpanda-connect/connector-binary-analyzer.js +1 -1
- package/tools/redpanda-connect/pr-summary-formatter.js +74 -9
- package/tools/redpanda-connect/report-delta.js +1 -0
- package/tools/redpanda-connect/rpcn-connector-docs-handler.js +122 -17
- package/tools/redpanda-connect/update-nav.js +12 -1
package/bin/doc-tools-mcp.js
CHANGED
|
@@ -362,7 +362,7 @@ const tools = [
|
|
|
362
362
|
},
|
|
363
363
|
surface: {
|
|
364
364
|
type: 'string',
|
|
365
|
-
description: 'Which API
|
|
365
|
+
description: 'Which API surfaces to bundle (optional, defaults to "both")',
|
|
366
366
|
enum: ['admin', 'connect', 'both']
|
|
367
367
|
},
|
|
368
368
|
out_admin: {
|
package/bin/doc-tools.js
CHANGED
|
@@ -1630,7 +1630,7 @@ automation
|
|
|
1630
1630
|
.option('-t, --tag <tag>', 'Git tag for released content')
|
|
1631
1631
|
.option('-b, --branch <branch>', 'Branch name for in-progress content')
|
|
1632
1632
|
.option('--repo <url>', 'Repository URL', 'https://github.com/redpanda-data/redpanda.git')
|
|
1633
|
-
.addOption(new Option('-s, --surface <surface>', 'Which API
|
|
1633
|
+
.addOption(new Option('-s, --surface <surface>', 'Which API surfaces to bundle').choices(['admin', 'connect', 'both']).makeOptionMandatory())
|
|
1634
1634
|
.option('--out-admin <path>', 'Output path for admin API', 'admin/redpanda-admin-api.yaml')
|
|
1635
1635
|
.option('--out-connect <path>', 'Output path for connect API', 'connect/redpanda-connect-api.yaml')
|
|
1636
1636
|
.option('--admin-major <string>', 'Admin API major version', 'v2.0.0')
|
|
@@ -306,10 +306,10 @@ function generateReviewReport(results, outputPath) {
|
|
|
306
306
|
// Next steps
|
|
307
307
|
report += `== Next Steps\n\n`;
|
|
308
308
|
if (errorIssues.length > 0) {
|
|
309
|
-
report += `. *Fix errors first* - Address the ${errorIssues.length}
|
|
309
|
+
report += `. *Fix errors first* - Address the ${errorIssues.length} errors above\n`;
|
|
310
310
|
}
|
|
311
311
|
if (warningIssues.length > 0) {
|
|
312
|
-
report += `${errorIssues.length > 0 ? '. ' : '. '}*Review warnings* - Prioritize the ${warningIssues.length}
|
|
312
|
+
report += `${errorIssues.length > 0 ? '. ' : '. '}*Review warnings* - Prioritize the ${warningIssues.length} warnings\n`;
|
|
313
313
|
}
|
|
314
314
|
const step = errorIssues.length > 0 && warningIssues.length > 0 ? 3 : errorIssues.length > 0 || warningIssues.length > 0 ? 2 : 1;
|
|
315
315
|
report += `${step > 1 ? '. ' : '. '}*Regenerate documentation* - After making changes, regenerate the docs\n`;
|
|
@@ -250,7 +250,7 @@ function formatValidationResults(results, config) {
|
|
|
250
250
|
lines.push('✓ Validation passed');
|
|
251
251
|
} else {
|
|
252
252
|
lines.push('✗ Validation failed');
|
|
253
|
-
lines.push(` ${results.errors.length}
|
|
253
|
+
lines.push(` ${results.errors.length} errors must be fixed`);
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
return lines.join('\n');
|
package/bin/mcp-tools/openapi.js
CHANGED
|
@@ -16,7 +16,7 @@ const { getAntoraStructure } = require('./antora');
|
|
|
16
16
|
* @param {string} [args.tag] - Git tag for released content (for example, "v24.3.2" or "24.3.2")
|
|
17
17
|
* @param {string} [args.branch] - Branch name for in-progress content (for example, "dev", "main")
|
|
18
18
|
* @param {string} [args.repo] - Repository URL
|
|
19
|
-
* @param {string} [args.surface] - Which API
|
|
19
|
+
* @param {string} [args.surface] - Which API surfaces to bundle: 'admin', 'connect', or 'both'
|
|
20
20
|
* @param {string} [args.out_admin] - Output path for admin API
|
|
21
21
|
* @param {string} [args.out_connect] - Output path for connect API
|
|
22
22
|
* @param {string} [args.admin_major] - Admin API major version
|
|
@@ -155,7 +155,7 @@ function generateBundleOpenApi(args) {
|
|
|
155
155
|
surface,
|
|
156
156
|
files_generated: filesGenerated,
|
|
157
157
|
output: output.trim(),
|
|
158
|
-
summary: `Bundled OpenAPI documentation for ${surface}
|
|
158
|
+
summary: `Bundled OpenAPI documentation for ${surface} APIs at ${refType} ${version}`
|
|
159
159
|
};
|
|
160
160
|
} catch (err) {
|
|
161
161
|
return {
|
|
@@ -73,7 +73,6 @@ module.exports.register = function ({ config }) {
|
|
|
73
73
|
const status = attrs.status || extractAttribute(file, 'status')
|
|
74
74
|
const driverSupport = attrs['driver-support'] || extractAttribute(file, 'driver-support')
|
|
75
75
|
const cacheSupport = attrs['cache-support'] || extractAttribute(file, 'cache-support')
|
|
76
|
-
// FIXED: Use correct attribute name (page-commercial-names, not commercial-names)
|
|
77
76
|
const commercialNames = attrs['page-commercial-names'] || extractAttribute(file, 'page-commercial-names')
|
|
78
77
|
|
|
79
78
|
const pubUrl = file.pub.url
|
package/package.json
CHANGED
package/tools/bundle-openapi.js
CHANGED
|
@@ -551,7 +551,7 @@ function postProcessBundle(filePath, options, quiet = false) {
|
|
|
551
551
|
}
|
|
552
552
|
|
|
553
553
|
/**
|
|
554
|
-
* Bundle OpenAPI fragments for the specified API
|
|
554
|
+
* Bundle OpenAPI fragments for the specified API surfaces from a repository tag and write the resulting bundled YAML files to disk.
|
|
555
555
|
*
|
|
556
556
|
* @param {Object} options - Configuration options.
|
|
557
557
|
* @param {string} options.tag - Git tag to checkout (for example, 'v25.1.1').
|
|
@@ -665,13 +665,13 @@ Connectors can have human-friendly commercial names that appear in catalogs and
|
|
|
665
665
|
----
|
|
666
666
|
= kafka_franz
|
|
667
667
|
:type: input
|
|
668
|
-
:commercial-names: Franz-go, Apache Kafka
|
|
668
|
+
:page-commercial-names: Franz-go, Apache Kafka
|
|
669
669
|
:categories: ["Services"]
|
|
670
670
|
----
|
|
671
671
|
|
|
672
672
|
The `generate-rp-connect-categories` extension reads these commercial names and uses the first one as the primary display name. If multiple names are provided (comma-separated), only the first is used for display.
|
|
673
673
|
|
|
674
|
-
*Default behavior:* If no `:commercial-names:` attribute is found, the connector key name is used (
|
|
674
|
+
*Default behavior:* If no `:page-commercial-names:` attribute is found, the connector key name is used (such as `kafka_franz`).
|
|
675
675
|
|
|
676
676
|
*Adding commercial names to new connectors:*
|
|
677
677
|
|
|
@@ -681,12 +681,12 @@ When generating documentation for new connectors with `--draft-missing`, writers
|
|
|
681
681
|
----
|
|
682
682
|
### ✍️ Writer Action Required
|
|
683
683
|
|
|
684
|
-
For each new connector, please add the `:commercial-names:` attribute to the frontmatter:
|
|
684
|
+
For each new connector, please add the `:page-commercial-names:` attribute to the frontmatter:
|
|
685
685
|
|
|
686
686
|
```asciidoc
|
|
687
687
|
= Connector Name
|
|
688
688
|
:type: input
|
|
689
|
-
:commercial-names: Commercial Name, Alternative Name
|
|
689
|
+
:page-commercial-names: Commercial Name, Alternative Name
|
|
690
690
|
```
|
|
691
691
|
|
|
692
692
|
_This helps improve discoverability and ensures proper categorization._
|
|
@@ -503,7 +503,7 @@ async function analyzeAllBinaries(ossVersion, cloudVersion = null, dataDir = nul
|
|
|
503
503
|
// These are connectors that require cgo-enabled builds
|
|
504
504
|
cgoOnly = findCgoOnlyConnectors(ossIndex, cgoIndex);
|
|
505
505
|
|
|
506
|
-
console.log(`Done: Cgo analysis complete: ${cgoOnly.length} cgo-only
|
|
506
|
+
console.log(`Done: Cgo analysis complete: ${cgoOnly.length} cgo-only connectors found`);
|
|
507
507
|
if (cgoOnly.length > 0) {
|
|
508
508
|
console.log(' cgo-only connectors:');
|
|
509
509
|
cgoOnly.forEach(c => console.log(` • ${c.type}/${c.name} (${c.status})`));
|
|
@@ -30,7 +30,7 @@ function generatePRSummary(diffData, binaryAnalysis = null, draftedConnectors =
|
|
|
30
30
|
|
|
31
31
|
// High-level stats
|
|
32
32
|
const stats = diffData.summary;
|
|
33
|
-
const hasChanges = Object.values(stats).some(v => v > 0);
|
|
33
|
+
const hasChanges = Object.values(stats).some(v => v > 0) || (draftedConnectors && draftedConnectors.length > 0);
|
|
34
34
|
|
|
35
35
|
if (!hasChanges) {
|
|
36
36
|
lines.push('✅ **No changes detected** - Documentation is up to date');
|
|
@@ -91,16 +91,78 @@ function generatePRSummary(diffData, binaryAnalysis = null, draftedConnectors =
|
|
|
91
91
|
if (stats.newComponents > 0) {
|
|
92
92
|
lines.push('### ✍️ Writer Action Required');
|
|
93
93
|
lines.push('');
|
|
94
|
-
lines.push('For each new connector,
|
|
94
|
+
lines.push('For each new connector, add the `:page-commercial-names:` attribute to the frontmatter:');
|
|
95
95
|
lines.push('');
|
|
96
96
|
lines.push('```asciidoc');
|
|
97
97
|
lines.push('= Connector Name');
|
|
98
98
|
lines.push(':type: input');
|
|
99
|
-
lines.push(':commercial-names: Commercial Name, Alternative Name');
|
|
99
|
+
lines.push(':page-commercial-names: Commercial Name, Alternative Name');
|
|
100
100
|
lines.push('```');
|
|
101
101
|
lines.push('');
|
|
102
102
|
lines.push('_This helps improve discoverability and ensures proper categorization._');
|
|
103
103
|
lines.push('');
|
|
104
|
+
|
|
105
|
+
// Check if any new connectors are cloud-supported
|
|
106
|
+
if (binaryAnalysis && binaryAnalysis.comparison) {
|
|
107
|
+
const newConnectorKeys = diffData.details.newComponents.map(c => ({
|
|
108
|
+
key: `${c.type}:${c.name}`,
|
|
109
|
+
type: c.type,
|
|
110
|
+
name: c.name
|
|
111
|
+
}));
|
|
112
|
+
|
|
113
|
+
const cloudSupported = newConnectorKeys.filter(item => {
|
|
114
|
+
// Check both inCloud (OSS+Cloud) and cloudOnly (Cloud-only)
|
|
115
|
+
const inCloud = binaryAnalysis.comparison.inCloud.some(c => `${c.type}:${c.name}` === item.key);
|
|
116
|
+
const cloudOnly = binaryAnalysis.comparison.cloudOnly &&
|
|
117
|
+
binaryAnalysis.comparison.cloudOnly.some(c => `${c.type}:${c.name}` === item.key);
|
|
118
|
+
return inCloud || cloudOnly;
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
if (cloudSupported.length > 0) {
|
|
122
|
+
lines.push('### ☁️ Cloud Docs Update Required');
|
|
123
|
+
lines.push('');
|
|
124
|
+
lines.push(`**${cloudSupported.length}** new connector${cloudSupported.length !== 1 ? 's are' : ' is'} available in Redpanda Cloud.`);
|
|
125
|
+
lines.push('');
|
|
126
|
+
lines.push('**Action:** Submit a separate PR to https://github.com/redpanda-data/cloud-docs to add the connector pages using include syntax:');
|
|
127
|
+
lines.push('');
|
|
128
|
+
|
|
129
|
+
// Check if any are cloud-only (need partial syntax)
|
|
130
|
+
const cloudOnly = cloudSupported.filter(item =>
|
|
131
|
+
binaryAnalysis.comparison.cloudOnly &&
|
|
132
|
+
binaryAnalysis.comparison.cloudOnly.some(c => `${c.type}:${c.name}` === item.key)
|
|
133
|
+
);
|
|
134
|
+
const regularCloud = cloudSupported.filter(item =>
|
|
135
|
+
!binaryAnalysis.comparison.cloudOnly ||
|
|
136
|
+
!binaryAnalysis.comparison.cloudOnly.some(c => `${c.type}:${c.name}` === item.key)
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
if (regularCloud.length > 0) {
|
|
140
|
+
lines.push('**For connectors in pages:**');
|
|
141
|
+
lines.push('```asciidoc');
|
|
142
|
+
lines.push('= Connector Name');
|
|
143
|
+
lines.push('');
|
|
144
|
+
lines.push('include::redpanda-connect:components:page$type/connector-name.adoc[tag=single-source]');
|
|
145
|
+
lines.push('```');
|
|
146
|
+
lines.push('');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if (cloudOnly.length > 0) {
|
|
150
|
+
lines.push('**For cloud-only connectors (in partials):**');
|
|
151
|
+
lines.push('```asciidoc');
|
|
152
|
+
lines.push('= Connector Name');
|
|
153
|
+
lines.push('');
|
|
154
|
+
lines.push('include::redpanda-connect:components:partial$components/cloud-only/type/connector-name.adoc[tag=single-source]');
|
|
155
|
+
lines.push('```');
|
|
156
|
+
lines.push('');
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Add instruction to update cloud whats-new
|
|
160
|
+
lines.push('**Also update the cloud whats-new file:**');
|
|
161
|
+
lines.push('');
|
|
162
|
+
lines.push('Add entries for the new cloud-supported connectors to the Redpanda Cloud whats-new file in the cloud-docs repository.');
|
|
163
|
+
lines.push('');
|
|
164
|
+
}
|
|
165
|
+
}
|
|
104
166
|
}
|
|
105
167
|
|
|
106
168
|
// Breaking Changes Section
|
|
@@ -335,8 +397,9 @@ function generatePRSummary(diffData, binaryAnalysis = null, draftedConnectors =
|
|
|
335
397
|
lines.push('');
|
|
336
398
|
cloudSupportedNew.forEach(c => {
|
|
337
399
|
lines.push(`- **${c.name}** (${c.type}, ${c.status})`);
|
|
338
|
-
|
|
339
|
-
|
|
400
|
+
const desc = c.summary || c.description;
|
|
401
|
+
if (desc) {
|
|
402
|
+
const shortDesc = truncateToSentence(desc, 2);
|
|
340
403
|
lines.push(` - ${shortDesc}`);
|
|
341
404
|
}
|
|
342
405
|
});
|
|
@@ -348,8 +411,9 @@ function generatePRSummary(diffData, binaryAnalysis = null, draftedConnectors =
|
|
|
348
411
|
lines.push('');
|
|
349
412
|
selfHostedOnlyNew.forEach(c => {
|
|
350
413
|
lines.push(`- **${c.name}** (${c.type}, ${c.status})`);
|
|
351
|
-
|
|
352
|
-
|
|
414
|
+
const desc = c.summary || c.description;
|
|
415
|
+
if (desc) {
|
|
416
|
+
const shortDesc = truncateToSentence(desc, 2);
|
|
353
417
|
lines.push(` - ${shortDesc}`);
|
|
354
418
|
}
|
|
355
419
|
});
|
|
@@ -359,8 +423,9 @@ function generatePRSummary(diffData, binaryAnalysis = null, draftedConnectors =
|
|
|
359
423
|
// No cloud support info, just list all
|
|
360
424
|
diffData.details.newComponents.forEach(c => {
|
|
361
425
|
lines.push(`- **${c.name}** (${c.type}, ${c.status})`);
|
|
362
|
-
|
|
363
|
-
|
|
426
|
+
const desc = c.summary || c.description;
|
|
427
|
+
if (desc) {
|
|
428
|
+
const shortDesc = truncateToSentence(desc, 2);
|
|
364
429
|
lines.push(` - ${shortDesc}`);
|
|
365
430
|
}
|
|
366
431
|
});
|
|
@@ -250,6 +250,7 @@ function generateConnectorDiffJson(oldIndex, newIndex, opts = {}) {
|
|
|
250
250
|
result.binaryAnalysis.details = {
|
|
251
251
|
cloudSupported: ba.comparison?.inCloud?.map(c => ({ type: c.type, name: c.name, status: c.status })) || [],
|
|
252
252
|
selfHostedOnly: ba.comparison?.notInCloud?.map(c => ({ type: c.type, name: c.name, status: c.status })) || [],
|
|
253
|
+
cloudOnly: ba.comparison?.cloudOnly?.map(c => ({ type: c.type, name: c.name, status: c.status })) || [],
|
|
253
254
|
cgoOnly: ba.cgoOnly?.map(c => ({ type: c.type, name: c.name, status: c.status })) || []
|
|
254
255
|
};
|
|
255
256
|
}
|
|
@@ -148,13 +148,20 @@ function updateWhatsNew ({ dataDir, oldVersion, newVersion, binaryAnalysis }) {
|
|
|
148
148
|
const regularComponents = []
|
|
149
149
|
|
|
150
150
|
if (diff.details.newComponents && diff.details.newComponents.length) {
|
|
151
|
-
|
|
151
|
+
// Filter out cloud-only connectors - they don't go in whats-new.adoc
|
|
152
|
+
const nonCloudOnlyComponents = diff.details.newComponents.filter(comp => {
|
|
153
|
+
const isCloudOnly = diff.binaryAnalysis?.details?.cloudOnly?.some(cloudComp => {
|
|
154
|
+
return cloudComp.name === comp.name && cloudComp.type === comp.type
|
|
155
|
+
})
|
|
156
|
+
return !isCloudOnly
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
for (const comp of nonCloudOnlyComponents) {
|
|
152
160
|
if (comp.type === 'bloblang-functions' || comp.type === 'bloblang-methods') {
|
|
153
161
|
bloblangComponents.push(comp)
|
|
154
162
|
} else {
|
|
155
|
-
const isCgoOnly = binaryAnalysis?.cgoOnly?.some(cgo => {
|
|
156
|
-
|
|
157
|
-
return cgo.name === comp.name && typeSingular === comp.type
|
|
163
|
+
const isCgoOnly = diff.binaryAnalysis?.details?.cgoOnly?.some(cgo => {
|
|
164
|
+
return cgo.name === comp.name && cgo.type === comp.type
|
|
158
165
|
})
|
|
159
166
|
|
|
160
167
|
regularComponents.push({
|
|
@@ -182,8 +189,9 @@ function updateWhatsNew ({ dataDir, oldVersion, newVersion, binaryAnalysis }) {
|
|
|
182
189
|
for (const comp of comps) {
|
|
183
190
|
section += `** xref:guides:bloblang/functions.adoc#${comp.name}[\`${comp.name}\`]`
|
|
184
191
|
if (comp.status && comp.status !== 'stable') section += ` (${comp.status})`
|
|
185
|
-
|
|
186
|
-
|
|
192
|
+
const desc = comp.summary || comp.description
|
|
193
|
+
if (desc) {
|
|
194
|
+
section += `: ${capToTwoSentences(desc)}`
|
|
187
195
|
} else {
|
|
188
196
|
section += `\n+\n// TODO: Add description for ${comp.name} function`
|
|
189
197
|
}
|
|
@@ -194,8 +202,9 @@ function updateWhatsNew ({ dataDir, oldVersion, newVersion, binaryAnalysis }) {
|
|
|
194
202
|
for (const comp of comps) {
|
|
195
203
|
section += `** xref:guides:bloblang/methods.adoc#${comp.name}[\`${comp.name}\`]`
|
|
196
204
|
if (comp.status && comp.status !== 'stable') section += ` (${comp.status})`
|
|
197
|
-
|
|
198
|
-
|
|
205
|
+
const desc = comp.summary || comp.description
|
|
206
|
+
if (desc) {
|
|
207
|
+
section += `: ${capToTwoSentences(desc)}`
|
|
199
208
|
} else {
|
|
200
209
|
section += `\n+\n// TODO: Add description for ${comp.name} method`
|
|
201
210
|
}
|
|
@@ -260,7 +269,8 @@ function updateWhatsNew ({ dataDir, oldVersion, newVersion, binaryAnalysis }) {
|
|
|
260
269
|
|
|
261
270
|
for (const comp of diff.details.deprecatedComponents) {
|
|
262
271
|
const typeLabel = comp.type.charAt(0).toUpperCase() + comp.type.slice(1)
|
|
263
|
-
const
|
|
272
|
+
const descText = comp.summary || comp.description
|
|
273
|
+
const desc = descText ? capToTwoSentences(descText) : '-'
|
|
264
274
|
|
|
265
275
|
if (comp.type === 'bloblang-functions') {
|
|
266
276
|
section += `|xref:guides:bloblang/functions.adoc#${comp.name}[${comp.name}]\n`
|
|
@@ -654,6 +664,27 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
654
664
|
|
|
655
665
|
let newIndex = JSON.parse(fs.readFileSync(dataFile, 'utf8'))
|
|
656
666
|
|
|
667
|
+
// Save a clean copy of OSS data for binary analysis (before augmentation)
|
|
668
|
+
// This ensures the binary analyzer compares actual binaries, not augmented data
|
|
669
|
+
const cleanOssDataPath = path.join(dataDir, `._connect-${newVersion}-clean.json`)
|
|
670
|
+
|
|
671
|
+
// Strip augmentation fields to create clean data for comparison
|
|
672
|
+
const cleanData = JSON.parse(JSON.stringify(newIndex))
|
|
673
|
+
const connectorTypes = ['inputs', 'outputs', 'processors', 'caches', 'rate_limits', 'buffers', 'metrics', 'scanners', 'tracers']
|
|
674
|
+
|
|
675
|
+
for (const type of connectorTypes) {
|
|
676
|
+
if (Array.isArray(cleanData[type])) {
|
|
677
|
+
cleanData[type] = cleanData[type].filter(c => !c.cloudOnly) // Remove cloud-only connectors added by augmentation
|
|
678
|
+
cleanData[type].forEach(c => {
|
|
679
|
+
delete c.cloudSupported
|
|
680
|
+
delete c.requiresCgo
|
|
681
|
+
delete c.cloudOnly
|
|
682
|
+
})
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
fs.writeFileSync(cleanOssDataPath, JSON.stringify(cleanData, null, 2), 'utf8')
|
|
687
|
+
|
|
657
688
|
const versionsMatch = oldVersion && newVersion && oldVersion === newVersion
|
|
658
689
|
if (versionsMatch) {
|
|
659
690
|
console.log(`\n✓ Already at version ${newVersion}`)
|
|
@@ -740,6 +771,19 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
740
771
|
console.log('\nAnalyzing connector binaries...')
|
|
741
772
|
const { analyzeAllBinaries } = require('./connector-binary-analyzer.js')
|
|
742
773
|
|
|
774
|
+
// Always use clean OSS data for comparison
|
|
775
|
+
// Temporarily rename the file so the analyzer finds it
|
|
776
|
+
const expectedPath = path.join(dataDir, `connect-${newVersion}.json`)
|
|
777
|
+
let tempRenamed = false
|
|
778
|
+
|
|
779
|
+
if (fs.existsSync(cleanOssDataPath)) {
|
|
780
|
+
if (fs.existsSync(expectedPath)) {
|
|
781
|
+
fs.renameSync(expectedPath, path.join(dataDir, `._connect-${newVersion}-augmented.json.tmp`))
|
|
782
|
+
tempRenamed = true
|
|
783
|
+
}
|
|
784
|
+
fs.copyFileSync(cleanOssDataPath, expectedPath)
|
|
785
|
+
}
|
|
786
|
+
|
|
743
787
|
const analysisOptions = {
|
|
744
788
|
skipCloud: false,
|
|
745
789
|
skipCgo: false,
|
|
@@ -753,6 +797,13 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
753
797
|
analysisOptions
|
|
754
798
|
)
|
|
755
799
|
|
|
800
|
+
// Restore the augmented file
|
|
801
|
+
if (tempRenamed) {
|
|
802
|
+
const expectedPath = path.join(dataDir, `connect-${newVersion}.json`)
|
|
803
|
+
fs.unlinkSync(expectedPath)
|
|
804
|
+
fs.renameSync(path.join(dataDir, `._connect-${newVersion}-augmented.json.tmp`), expectedPath)
|
|
805
|
+
}
|
|
806
|
+
|
|
756
807
|
console.log('Done: Binary analysis complete:')
|
|
757
808
|
console.log(` • OSS version: ${binaryAnalysis.ossVersion}`)
|
|
758
809
|
|
|
@@ -848,10 +899,10 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
848
899
|
fs.writeFileSync(dataFile, JSON.stringify(connectorData, null, 2), 'utf8')
|
|
849
900
|
console.log(`Done: Augmented ${augmentedCount} connectors with cloud/cgo fields`)
|
|
850
901
|
if (addedCgoCount > 0) {
|
|
851
|
-
console.log(` • Added ${addedCgoCount} cgo-only
|
|
902
|
+
console.log(` • Added ${addedCgoCount} cgo-only connectors to data file`)
|
|
852
903
|
}
|
|
853
904
|
if (addedCloudOnlyCount > 0) {
|
|
854
|
-
console.log(` • Added ${addedCloudOnlyCount} cloud-only
|
|
905
|
+
console.log(` • Added ${addedCloudOnlyCount} cloud-only connectors to data file`)
|
|
855
906
|
}
|
|
856
907
|
|
|
857
908
|
// Keep only 2 most recent versions
|
|
@@ -865,6 +916,9 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
865
916
|
fs.unlinkSync(oldestPath)
|
|
866
917
|
console.log(`🧹 Deleted old version from docs-data: ${oldestFile}`)
|
|
867
918
|
}
|
|
919
|
+
|
|
920
|
+
// Reload newIndex after augmentation so diff generation uses augmented data
|
|
921
|
+
newIndex = JSON.parse(fs.readFileSync(dataFile, 'utf8'))
|
|
868
922
|
} catch (err) {
|
|
869
923
|
console.error(`Warning: Failed to augment data file: ${err.message}`)
|
|
870
924
|
}
|
|
@@ -890,8 +944,42 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
890
944
|
}
|
|
891
945
|
)
|
|
892
946
|
|
|
947
|
+
// Filter out components that already have documentation
|
|
948
|
+
const docRoots = {
|
|
949
|
+
pages: path.resolve(process.cwd(), 'modules/components/pages'),
|
|
950
|
+
partials: path.resolve(process.cwd(), 'modules/components/partials/components'),
|
|
951
|
+
cloudOnly: path.resolve(process.cwd(), 'modules/components/partials/components/cloud-only')
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
if (diffJson.details && diffJson.details.newComponents) {
|
|
955
|
+
const originalCount = diffJson.details.newComponents.length
|
|
956
|
+
diffJson.details.newComponents = diffJson.details.newComponents.filter(comp => {
|
|
957
|
+
const typePlural = comp.type.endsWith('s') ? comp.type : `${comp.type}s`
|
|
958
|
+
const relPath = path.join(typePlural, `${comp.name}.adoc`)
|
|
959
|
+
const docsExist = Object.values(docRoots).some(root =>
|
|
960
|
+
fs.existsSync(path.join(root, relPath))
|
|
961
|
+
)
|
|
962
|
+
return !docsExist
|
|
963
|
+
})
|
|
964
|
+
const filteredCount = originalCount - diffJson.details.newComponents.length
|
|
965
|
+
if (filteredCount > 0) {
|
|
966
|
+
console.log(` ℹ️ Filtered out ${filteredCount} components that already have documentation`)
|
|
967
|
+
}
|
|
968
|
+
// Update summary count
|
|
969
|
+
if (diffJson.summary) {
|
|
970
|
+
diffJson.summary.newComponents = diffJson.details.newComponents.length
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
893
974
|
// Add new cgo-only components
|
|
894
975
|
if (binaryAnalysis && binaryAnalysis.cgoOnly && binaryAnalysis.cgoOnly.length > 0) {
|
|
976
|
+
// Define roots for checking if docs already exist
|
|
977
|
+
const docRoots = {
|
|
978
|
+
pages: path.resolve(process.cwd(), 'modules/components/pages'),
|
|
979
|
+
partials: path.resolve(process.cwd(), 'modules/components/partials/components'),
|
|
980
|
+
cloudOnly: path.resolve(process.cwd(), 'modules/components/partials/components/cloud-only')
|
|
981
|
+
}
|
|
982
|
+
|
|
895
983
|
let newCgoComponents
|
|
896
984
|
|
|
897
985
|
if (oldBinaryAnalysis) {
|
|
@@ -899,20 +987,36 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
899
987
|
newCgoComponents = binaryAnalysis.cgoOnly.filter(cgoComp => {
|
|
900
988
|
const wasInOldOss = oldIndex[cgoComp.type]?.some(c => c.name === cgoComp.name)
|
|
901
989
|
const wasInOldCgo = oldCgoSet.has(`${cgoComp.type}:${cgoComp.name}`)
|
|
902
|
-
|
|
990
|
+
|
|
991
|
+
// Check if docs already exist
|
|
992
|
+
const typePlural = cgoComp.type.endsWith('s') ? cgoComp.type : `${cgoComp.type}s`
|
|
993
|
+
const relPath = path.join(typePlural, `${cgoComp.name}.adoc`)
|
|
994
|
+
const docsExist = Object.values(docRoots).some(root =>
|
|
995
|
+
fs.existsSync(path.join(root, relPath))
|
|
996
|
+
)
|
|
997
|
+
|
|
998
|
+
return !wasInOldOss && !wasInOldCgo && !docsExist
|
|
903
999
|
})
|
|
904
1000
|
} else {
|
|
905
1001
|
newCgoComponents = binaryAnalysis.cgoOnly.filter(cgoComp => {
|
|
906
1002
|
const wasInOldOss = oldIndex[cgoComp.type]?.some(c => c.name === cgoComp.name)
|
|
907
|
-
|
|
1003
|
+
|
|
1004
|
+
// Check if docs already exist
|
|
1005
|
+
const typePlural = cgoComp.type.endsWith('s') ? cgoComp.type : `${cgoComp.type}s`
|
|
1006
|
+
const relPath = path.join(typePlural, `${cgoComp.name}.adoc`)
|
|
1007
|
+
const docsExist = Object.values(docRoots).some(root =>
|
|
1008
|
+
fs.existsSync(path.join(root, relPath))
|
|
1009
|
+
)
|
|
1010
|
+
|
|
1011
|
+
return !wasInOldOss && !docsExist
|
|
908
1012
|
})
|
|
909
1013
|
if (newCgoComponents.length > 0) {
|
|
910
|
-
console.log(` ℹ️ No old binary analysis found - treating ${newCgoComponents.length} cgo
|
|
1014
|
+
console.log(` ℹ️ No old binary analysis found - treating ${newCgoComponents.length} cgo components not in old OSS data as new`)
|
|
911
1015
|
}
|
|
912
1016
|
}
|
|
913
1017
|
|
|
914
1018
|
if (newCgoComponents && newCgoComponents.length > 0) {
|
|
915
|
-
console.log(` • Found ${newCgoComponents.length} new cgo-only
|
|
1019
|
+
console.log(` • Found ${newCgoComponents.length} new cgo-only components`)
|
|
916
1020
|
newCgoComponents.forEach(cgoComp => {
|
|
917
1021
|
const typeSingular = cgoComp.type.replace(/s$/, '')
|
|
918
1022
|
diffJson.details.newComponents.push({
|
|
@@ -940,7 +1044,7 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
940
1044
|
.filter(f => f.startsWith('connect-diff-') && f.endsWith('.json') && f !== path.basename(diffPath))
|
|
941
1045
|
|
|
942
1046
|
if (oldDiffFiles.length > 0) {
|
|
943
|
-
console.log(`🧹 Cleaning up ${oldDiffFiles.length} old diff
|
|
1047
|
+
console.log(`🧹 Cleaning up ${oldDiffFiles.length} old diff files...`)
|
|
944
1048
|
oldDiffFiles.forEach(f => {
|
|
945
1049
|
const oldDiffPath = path.join(dataDir, f)
|
|
946
1050
|
fs.unlinkSync(oldDiffPath)
|
|
@@ -1011,7 +1115,8 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
1011
1115
|
|
|
1012
1116
|
const roots = {
|
|
1013
1117
|
pages: path.resolve(process.cwd(), 'modules/components/pages'),
|
|
1014
|
-
partials: path.resolve(process.cwd(), 'modules/components/partials/components')
|
|
1118
|
+
partials: path.resolve(process.cwd(), 'modules/components/partials/components'),
|
|
1119
|
+
cloudOnly: path.resolve(process.cwd(), 'modules/components/partials/components/cloud-only')
|
|
1015
1120
|
}
|
|
1016
1121
|
|
|
1017
1122
|
const allMissing = validConnectors.filter(({ name, type }) => {
|
|
@@ -190,7 +190,18 @@ function updateNavFromDrafts(draftFiles, navPath = null) {
|
|
|
190
190
|
|
|
191
191
|
console.log(`📝 Updating navigation: ${navPath}`);
|
|
192
192
|
|
|
193
|
-
|
|
193
|
+
// Filter out cloud-only connectors (they go in partials, not nav)
|
|
194
|
+
const nonCloudOnlyFiles = draftFiles.filter(draft => !draft.cloudOnly);
|
|
195
|
+
const cloudOnlyFiles = draftFiles.filter(draft => draft.cloudOnly);
|
|
196
|
+
|
|
197
|
+
if (cloudOnlyFiles.length > 0) {
|
|
198
|
+
console.log(` ℹ️ Skipping ${cloudOnlyFiles.length} cloud-only connectors (partials don't need nav entries):`);
|
|
199
|
+
cloudOnlyFiles.forEach(draft => {
|
|
200
|
+
console.log(` • ${draft.type}/${draft.name}`);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const connectors = nonCloudOnlyFiles.map(draft => ({
|
|
194
205
|
type: draft.type,
|
|
195
206
|
name: draft.name
|
|
196
207
|
}));
|