@redpanda-data/docs-extensions-and-macros 4.13.2 → 4.13.3
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 +65 -3
- package/tools/redpanda-connect/report-delta.js +1 -0
- package/tools/redpanda-connect/rpcn-connector-docs-handler.js +111 -12
- 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
|
|
@@ -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({
|
|
@@ -654,6 +661,27 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
654
661
|
|
|
655
662
|
let newIndex = JSON.parse(fs.readFileSync(dataFile, 'utf8'))
|
|
656
663
|
|
|
664
|
+
// Save a clean copy of OSS data for binary analysis (before augmentation)
|
|
665
|
+
// This ensures the binary analyzer compares actual binaries, not augmented data
|
|
666
|
+
const cleanOssDataPath = path.join(dataDir, `._connect-${newVersion}-clean.json`)
|
|
667
|
+
|
|
668
|
+
// Strip augmentation fields to create clean data for comparison
|
|
669
|
+
const cleanData = JSON.parse(JSON.stringify(newIndex))
|
|
670
|
+
const connectorTypes = ['inputs', 'outputs', 'processors', 'caches', 'rate_limits', 'buffers', 'metrics', 'scanners', 'tracers']
|
|
671
|
+
|
|
672
|
+
for (const type of connectorTypes) {
|
|
673
|
+
if (Array.isArray(cleanData[type])) {
|
|
674
|
+
cleanData[type] = cleanData[type].filter(c => !c.cloudOnly) // Remove cloud-only connectors added by augmentation
|
|
675
|
+
cleanData[type].forEach(c => {
|
|
676
|
+
delete c.cloudSupported
|
|
677
|
+
delete c.requiresCgo
|
|
678
|
+
delete c.cloudOnly
|
|
679
|
+
})
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
fs.writeFileSync(cleanOssDataPath, JSON.stringify(cleanData, null, 2), 'utf8')
|
|
684
|
+
|
|
657
685
|
const versionsMatch = oldVersion && newVersion && oldVersion === newVersion
|
|
658
686
|
if (versionsMatch) {
|
|
659
687
|
console.log(`\n✓ Already at version ${newVersion}`)
|
|
@@ -740,6 +768,19 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
740
768
|
console.log('\nAnalyzing connector binaries...')
|
|
741
769
|
const { analyzeAllBinaries } = require('./connector-binary-analyzer.js')
|
|
742
770
|
|
|
771
|
+
// Always use clean OSS data for comparison
|
|
772
|
+
// Temporarily rename the file so the analyzer finds it
|
|
773
|
+
const expectedPath = path.join(dataDir, `connect-${newVersion}.json`)
|
|
774
|
+
let tempRenamed = false
|
|
775
|
+
|
|
776
|
+
if (fs.existsSync(cleanOssDataPath)) {
|
|
777
|
+
if (fs.existsSync(expectedPath)) {
|
|
778
|
+
fs.renameSync(expectedPath, path.join(dataDir, `._connect-${newVersion}-augmented.json.tmp`))
|
|
779
|
+
tempRenamed = true
|
|
780
|
+
}
|
|
781
|
+
fs.copyFileSync(cleanOssDataPath, expectedPath)
|
|
782
|
+
}
|
|
783
|
+
|
|
743
784
|
const analysisOptions = {
|
|
744
785
|
skipCloud: false,
|
|
745
786
|
skipCgo: false,
|
|
@@ -753,6 +794,13 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
753
794
|
analysisOptions
|
|
754
795
|
)
|
|
755
796
|
|
|
797
|
+
// Restore the augmented file
|
|
798
|
+
if (tempRenamed) {
|
|
799
|
+
const expectedPath = path.join(dataDir, `connect-${newVersion}.json`)
|
|
800
|
+
fs.unlinkSync(expectedPath)
|
|
801
|
+
fs.renameSync(path.join(dataDir, `._connect-${newVersion}-augmented.json.tmp`), expectedPath)
|
|
802
|
+
}
|
|
803
|
+
|
|
756
804
|
console.log('Done: Binary analysis complete:')
|
|
757
805
|
console.log(` • OSS version: ${binaryAnalysis.ossVersion}`)
|
|
758
806
|
|
|
@@ -848,10 +896,10 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
848
896
|
fs.writeFileSync(dataFile, JSON.stringify(connectorData, null, 2), 'utf8')
|
|
849
897
|
console.log(`Done: Augmented ${augmentedCount} connectors with cloud/cgo fields`)
|
|
850
898
|
if (addedCgoCount > 0) {
|
|
851
|
-
console.log(` • Added ${addedCgoCount} cgo-only
|
|
899
|
+
console.log(` • Added ${addedCgoCount} cgo-only connectors to data file`)
|
|
852
900
|
}
|
|
853
901
|
if (addedCloudOnlyCount > 0) {
|
|
854
|
-
console.log(` • Added ${addedCloudOnlyCount} cloud-only
|
|
902
|
+
console.log(` • Added ${addedCloudOnlyCount} cloud-only connectors to data file`)
|
|
855
903
|
}
|
|
856
904
|
|
|
857
905
|
// Keep only 2 most recent versions
|
|
@@ -890,8 +938,42 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
890
938
|
}
|
|
891
939
|
)
|
|
892
940
|
|
|
941
|
+
// Filter out components that already have documentation
|
|
942
|
+
const docRoots = {
|
|
943
|
+
pages: path.resolve(process.cwd(), 'modules/components/pages'),
|
|
944
|
+
partials: path.resolve(process.cwd(), 'modules/components/partials/components'),
|
|
945
|
+
cloudOnly: path.resolve(process.cwd(), 'modules/components/partials/components/cloud-only')
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
if (diffJson.details && diffJson.details.newComponents) {
|
|
949
|
+
const originalCount = diffJson.details.newComponents.length
|
|
950
|
+
diffJson.details.newComponents = diffJson.details.newComponents.filter(comp => {
|
|
951
|
+
const typePlural = comp.type.endsWith('s') ? comp.type : `${comp.type}s`
|
|
952
|
+
const relPath = path.join(typePlural, `${comp.name}.adoc`)
|
|
953
|
+
const docsExist = Object.values(docRoots).some(root =>
|
|
954
|
+
fs.existsSync(path.join(root, relPath))
|
|
955
|
+
)
|
|
956
|
+
return !docsExist
|
|
957
|
+
})
|
|
958
|
+
const filteredCount = originalCount - diffJson.details.newComponents.length
|
|
959
|
+
if (filteredCount > 0) {
|
|
960
|
+
console.log(` ℹ️ Filtered out ${filteredCount} components that already have documentation`)
|
|
961
|
+
}
|
|
962
|
+
// Update summary count
|
|
963
|
+
if (diffJson.summary) {
|
|
964
|
+
diffJson.summary.newComponents = diffJson.details.newComponents.length
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
|
|
893
968
|
// Add new cgo-only components
|
|
894
969
|
if (binaryAnalysis && binaryAnalysis.cgoOnly && binaryAnalysis.cgoOnly.length > 0) {
|
|
970
|
+
// Define roots for checking if docs already exist
|
|
971
|
+
const docRoots = {
|
|
972
|
+
pages: path.resolve(process.cwd(), 'modules/components/pages'),
|
|
973
|
+
partials: path.resolve(process.cwd(), 'modules/components/partials/components'),
|
|
974
|
+
cloudOnly: path.resolve(process.cwd(), 'modules/components/partials/components/cloud-only')
|
|
975
|
+
}
|
|
976
|
+
|
|
895
977
|
let newCgoComponents
|
|
896
978
|
|
|
897
979
|
if (oldBinaryAnalysis) {
|
|
@@ -899,20 +981,36 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
899
981
|
newCgoComponents = binaryAnalysis.cgoOnly.filter(cgoComp => {
|
|
900
982
|
const wasInOldOss = oldIndex[cgoComp.type]?.some(c => c.name === cgoComp.name)
|
|
901
983
|
const wasInOldCgo = oldCgoSet.has(`${cgoComp.type}:${cgoComp.name}`)
|
|
902
|
-
|
|
984
|
+
|
|
985
|
+
// Check if docs already exist
|
|
986
|
+
const typePlural = cgoComp.type.endsWith('s') ? cgoComp.type : `${cgoComp.type}s`
|
|
987
|
+
const relPath = path.join(typePlural, `${cgoComp.name}.adoc`)
|
|
988
|
+
const docsExist = Object.values(docRoots).some(root =>
|
|
989
|
+
fs.existsSync(path.join(root, relPath))
|
|
990
|
+
)
|
|
991
|
+
|
|
992
|
+
return !wasInOldOss && !wasInOldCgo && !docsExist
|
|
903
993
|
})
|
|
904
994
|
} else {
|
|
905
995
|
newCgoComponents = binaryAnalysis.cgoOnly.filter(cgoComp => {
|
|
906
996
|
const wasInOldOss = oldIndex[cgoComp.type]?.some(c => c.name === cgoComp.name)
|
|
907
|
-
|
|
997
|
+
|
|
998
|
+
// Check if docs already exist
|
|
999
|
+
const typePlural = cgoComp.type.endsWith('s') ? cgoComp.type : `${cgoComp.type}s`
|
|
1000
|
+
const relPath = path.join(typePlural, `${cgoComp.name}.adoc`)
|
|
1001
|
+
const docsExist = Object.values(docRoots).some(root =>
|
|
1002
|
+
fs.existsSync(path.join(root, relPath))
|
|
1003
|
+
)
|
|
1004
|
+
|
|
1005
|
+
return !wasInOldOss && !docsExist
|
|
908
1006
|
})
|
|
909
1007
|
if (newCgoComponents.length > 0) {
|
|
910
|
-
console.log(` ℹ️ No old binary analysis found - treating ${newCgoComponents.length} cgo
|
|
1008
|
+
console.log(` ℹ️ No old binary analysis found - treating ${newCgoComponents.length} cgo components not in old OSS data as new`)
|
|
911
1009
|
}
|
|
912
1010
|
}
|
|
913
1011
|
|
|
914
1012
|
if (newCgoComponents && newCgoComponents.length > 0) {
|
|
915
|
-
console.log(` • Found ${newCgoComponents.length} new cgo-only
|
|
1013
|
+
console.log(` • Found ${newCgoComponents.length} new cgo-only components`)
|
|
916
1014
|
newCgoComponents.forEach(cgoComp => {
|
|
917
1015
|
const typeSingular = cgoComp.type.replace(/s$/, '')
|
|
918
1016
|
diffJson.details.newComponents.push({
|
|
@@ -940,7 +1038,7 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
940
1038
|
.filter(f => f.startsWith('connect-diff-') && f.endsWith('.json') && f !== path.basename(diffPath))
|
|
941
1039
|
|
|
942
1040
|
if (oldDiffFiles.length > 0) {
|
|
943
|
-
console.log(`🧹 Cleaning up ${oldDiffFiles.length} old diff
|
|
1041
|
+
console.log(`🧹 Cleaning up ${oldDiffFiles.length} old diff files...`)
|
|
944
1042
|
oldDiffFiles.forEach(f => {
|
|
945
1043
|
const oldDiffPath = path.join(dataDir, f)
|
|
946
1044
|
fs.unlinkSync(oldDiffPath)
|
|
@@ -1011,7 +1109,8 @@ async function handleRpcnConnectorDocs (options) {
|
|
|
1011
1109
|
|
|
1012
1110
|
const roots = {
|
|
1013
1111
|
pages: path.resolve(process.cwd(), 'modules/components/pages'),
|
|
1014
|
-
partials: path.resolve(process.cwd(), 'modules/components/partials/components')
|
|
1112
|
+
partials: path.resolve(process.cwd(), 'modules/components/partials/components'),
|
|
1113
|
+
cloudOnly: path.resolve(process.cwd(), 'modules/components/partials/components/cloud-only')
|
|
1015
1114
|
}
|
|
1016
1115
|
|
|
1017
1116
|
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
|
}));
|