@redpanda-data/docs-extensions-and-macros 4.13.1 → 4.13.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.
Files changed (33) hide show
  1. package/bin/doc-tools-mcp.js +15 -3
  2. package/bin/doc-tools.js +767 -2088
  3. package/bin/mcp-tools/property-docs.js +18 -0
  4. package/bin/mcp-tools/rpcn-docs.js +28 -3
  5. package/cli-utils/antora-utils.js +53 -2
  6. package/cli-utils/dependencies.js +313 -0
  7. package/cli-utils/diff-utils.js +273 -0
  8. package/cli-utils/doc-tools-utils.js +54 -0
  9. package/extensions/algolia-indexer/generate-index.js +134 -102
  10. package/extensions/algolia-indexer/index.js +70 -38
  11. package/extensions/collect-bloblang-samples.js +2 -1
  12. package/extensions/generate-rp-connect-categories.js +126 -67
  13. package/extensions/generate-rp-connect-info.js +291 -137
  14. package/macros/rp-connect-components.js +34 -5
  15. package/package.json +4 -3
  16. package/tools/add-commercial-names.js +207 -0
  17. package/tools/generate-cli-docs.js +6 -2
  18. package/tools/get-console-version.js +5 -0
  19. package/tools/get-redpanda-version.js +5 -0
  20. package/tools/property-extractor/compare-properties.js +3 -3
  21. package/tools/property-extractor/generate-handlebars-docs.js +14 -14
  22. package/tools/property-extractor/generate-pr-summary.js +46 -0
  23. package/tools/property-extractor/pr-summary-formatter.js +375 -0
  24. package/tools/redpanda-connect/README.adoc +403 -38
  25. package/tools/redpanda-connect/connector-binary-analyzer.js +588 -0
  26. package/tools/redpanda-connect/generate-rpcn-connector-docs.js +97 -34
  27. package/tools/redpanda-connect/parse-csv-connectors.js +1 -1
  28. package/tools/redpanda-connect/pr-summary-formatter.js +601 -0
  29. package/tools/redpanda-connect/report-delta.js +69 -2
  30. package/tools/redpanda-connect/rpcn-connector-docs-handler.js +1180 -0
  31. package/tools/redpanda-connect/templates/connector.hbs +38 -0
  32. package/tools/redpanda-connect/templates/intro.hbs +0 -20
  33. package/tools/redpanda-connect/update-nav.js +205 -0
@@ -9,7 +9,7 @@ const helpers = require('./helpers');
9
9
  // Register each helper under handlebars, verifying that it’s a function
10
10
  Object.entries(helpers).forEach(([name, fn]) => {
11
11
  if (typeof fn !== 'function') {
12
- console.error(`❌ Helper "${name}" is not a function`);
12
+ console.error(`Error: Helper "${name}" is not a function`);
13
13
  process.exit(1);
14
14
  }
15
15
  handlebars.registerHelper(name, fn);
@@ -242,7 +242,9 @@ async function generateRpcnConnectorDocs(options) {
242
242
  templateFields,
243
243
  templateExamples,
244
244
  templateBloblang,
245
- writeFullDrafts
245
+ writeFullDrafts,
246
+ cgoOnly = [], // Array of cgo-only connectors from cgo binary inspection
247
+ cloudOnly = [] // Array of cloud-only connectors from cloud binary inspection
246
248
  } = options;
247
249
 
248
250
  // Read connector index (JSON or YAML)
@@ -252,6 +254,26 @@ async function generateRpcnConnectorDocs(options) {
252
254
  // Mark beta fields/components before overrides
253
255
  markBeta(dataObj);
254
256
 
257
+ // Build a Set of cgo-only connector keys for fast lookup
258
+ const cgoOnlySet = new Set();
259
+ if (Array.isArray(cgoOnly)) {
260
+ cgoOnly.forEach(connector => {
261
+ if (connector.type && connector.name) {
262
+ cgoOnlySet.add(`${connector.type}:${connector.name}`);
263
+ }
264
+ });
265
+ }
266
+
267
+ // Build a Set of cloud-only connector keys for fast lookup
268
+ const cloudOnlySet = new Set();
269
+ if (Array.isArray(cloudOnly)) {
270
+ cloudOnly.forEach(connector => {
271
+ if (connector.type && connector.name) {
272
+ cloudOnlySet.add(`${connector.type}:${connector.name}`);
273
+ }
274
+ });
275
+ }
276
+
255
277
  // Apply overrides if provided
256
278
  if (overrides && fs.existsSync(overrides)) {
257
279
  const ovRaw = fs.readFileSync(overrides, 'utf8');
@@ -295,21 +317,26 @@ async function generateRpcnConnectorDocs(options) {
295
317
  const examplesTemplatePath = templateExamples || null;
296
318
 
297
319
  // Register partials
298
- if (!writeFullDrafts) {
299
- if (fieldsTemplatePath) {
300
- registerPartial('fields', fieldsTemplatePath);
301
- }
302
- if (examplesTemplatePath) {
303
- registerPartial('examples', examplesTemplatePath);
304
- }
305
- } else {
320
+ // Always register fields and examples partials (needed for rendering partials even in draft mode)
321
+ if (fieldsTemplatePath) {
322
+ registerPartial('fields', fieldsTemplatePath);
323
+ }
324
+ if (examplesTemplatePath) {
325
+ registerPartial('examples', examplesTemplatePath);
326
+ }
327
+
328
+ // In draft mode, also register the intro partial
329
+ if (writeFullDrafts && templateIntro) {
306
330
  registerPartial('intro', templateIntro);
307
331
  }
308
332
 
309
333
  const outputRoot = path.resolve(process.cwd(), 'modules/components/partials');
310
334
  const fieldsOutRoot = path.join(outputRoot, 'fields');
311
335
  const examplesOutRoot = path.join(outputRoot, 'examples');
312
- const draftsRoot = path.join(outputRoot, 'drafts');
336
+ // Drafts go to pages/, not partials/
337
+ const componentsRoot = writeFullDrafts
338
+ ? path.resolve(process.cwd(), 'modules/components/pages')
339
+ : path.join(outputRoot, 'components');
313
340
  const configExamplesRoot = path.resolve(process.cwd(), 'modules/components/examples');
314
341
 
315
342
  if (!writeFullDrafts) {
@@ -329,30 +356,33 @@ async function generateRpcnConnectorDocs(options) {
329
356
  if (!item.name) continue;
330
357
  const name = item.name;
331
358
 
332
- if (!writeFullDrafts) {
333
- // Render fields using the registered fields partial
334
- const fieldsOut = handlebars
335
- .compile('{{> fields children=config.children}}')(item);
359
+ // Always generate field and example partials (needed for both standalone and draft modes)
360
+ // Render fields using the registered "fields" partial
361
+ const fieldsOut = handlebars
362
+ .compile('{{> fields children=config.children}}')(item);
336
363
 
337
- // Render examples only if an examples template was provided
338
- let examplesOut = '';
339
- if (examplesTemplatePath) {
340
- examplesOut = handlebars
341
- .compile('{{> examples examples=examples}}')(item);
342
- }
364
+ // Render examples only if an examples template was provided
365
+ let examplesOut = '';
366
+ if (examplesTemplatePath) {
367
+ examplesOut = handlebars
368
+ .compile('{{> examples examples=examples}}')(item);
369
+ }
343
370
 
344
- if (fieldsOut.trim()) {
345
- const fPath = path.join(fieldsOutRoot, type, `${name}.adoc`);
346
- fs.mkdirSync(path.dirname(fPath), { recursive: true });
347
- fs.writeFileSync(fPath, fieldsOut);
371
+ if (fieldsOut.trim()) {
372
+ const fPath = path.join(fieldsOutRoot, type, `${name}.adoc`);
373
+ fs.mkdirSync(path.dirname(fPath), { recursive: true });
374
+ fs.writeFileSync(fPath, fieldsOut);
375
+ if (!writeFullDrafts) {
348
376
  partialsWritten++;
349
377
  partialFiles.push(path.relative(process.cwd(), fPath));
350
378
  }
379
+ }
351
380
 
352
- if (examplesOut.trim() && type !== 'bloblang-functions' && type !== 'bloblang-methods') {
353
- const ePath = path.join(examplesOutRoot, type, `${name}.adoc`);
354
- fs.mkdirSync(path.dirname(ePath), { recursive: true });
355
- fs.writeFileSync(ePath, examplesOut);
381
+ if (examplesOut.trim() && type !== 'bloblang-functions' && type !== 'bloblang-methods') {
382
+ const ePath = path.join(examplesOutRoot, type, `${name}.adoc`);
383
+ fs.mkdirSync(path.dirname(ePath), { recursive: true });
384
+ fs.writeFileSync(ePath, examplesOut);
385
+ if (!writeFullDrafts) {
356
386
  partialsWritten++;
357
387
  partialFiles.push(path.relative(process.cwd(), ePath));
358
388
  }
@@ -363,6 +393,24 @@ async function generateRpcnConnectorDocs(options) {
363
393
  console.log(`Skipping draft for deprecated component: ${type}/${name}`);
364
394
  continue;
365
395
  }
396
+
397
+ // Check if this connector is cgo-only or cloud-only and mark it
398
+ const connectorKey = `${type}:${name}`;
399
+ const isCloudOnly = cloudOnlySet.has(connectorKey);
400
+ const isCgoOnly = cgoOnlySet.has(connectorKey);
401
+
402
+ if (isCgoOnly) {
403
+ item.requiresCgo = true;
404
+ // tigerbeetle_cdc also requires idempotency
405
+ if (name === 'tigerbeetle_cdc') {
406
+ item.requiresIdempotency = true;
407
+ }
408
+ }
409
+
410
+ if (isCloudOnly) {
411
+ item.cloudOnly = true;
412
+ }
413
+
366
414
  let content;
367
415
  try {
368
416
  content = compiledTemplate(item);
@@ -370,15 +418,30 @@ async function generateRpcnConnectorDocs(options) {
370
418
  throw new Error(`Template render failed for component "${name}": ${err.message}`);
371
419
  }
372
420
 
373
- const draftSubdir = name === 'gateway'
374
- ? path.join(draftsRoot, 'cloud-only')
375
- : draftsRoot;
421
+ // Determine output location based on availability
422
+ let destFile;
423
+ const typeDir = type.endsWith('s') ? type : `${type}s`;
424
+
425
+ if (isCloudOnly) {
426
+ // Cloud-only connectors go to partials/components/cloud-only/{type}s/{name}.adoc
427
+ const cloudOnlyRoot = path.resolve(process.cwd(), 'modules/components/partials/components/cloud-only');
428
+ destFile = path.join(cloudOnlyRoot, typeDir, `${name}.adoc`);
429
+ } else {
430
+ // Regular connectors go to pages/{type}s/{name}.adoc
431
+ destFile = path.join(componentsRoot, typeDir, `${name}.adoc`);
432
+ }
376
433
 
377
- const destFile = path.join(draftSubdir, `${name}.adoc`);
378
434
  fs.mkdirSync(path.dirname(destFile), { recursive: true });
379
435
  fs.writeFileSync(destFile, content, 'utf8');
380
436
  draftsWritten++;
381
- draftFiles.push(path.relative(process.cwd(), destFile));
437
+ draftFiles.push({
438
+ path: path.relative(process.cwd(), destFile),
439
+ name: name,
440
+ type: type,
441
+ status: item.status || 'stable',
442
+ requiresCgo: item.requiresCgo || false,
443
+ cloudOnly: item.cloudOnly || false
444
+ });
382
445
  }
383
446
  }
384
447
  }
@@ -53,7 +53,7 @@ async function parseCSVConnectors(localCsvPath, logger) {
53
53
  })
54
54
  .filter(Boolean);
55
55
 
56
- logger.info(`✅ Parsed ${cleaned.length} connector records.`);
56
+ logger.info(`Done: Parsed ${cleaned.length} connector records.`);
57
57
  return cleaned;
58
58
  } catch (err) {
59
59
  throw new Error(`CSV parsing failed: ${err.message}`);