@redpanda-data/docs-extensions-and-macros 5.55.0 → 5.56.0

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 (53) hide show
  1. package/bin/doc-tools.js +315 -7
  2. package/cli-utils/docs-links-to-xrefs.js +174 -0
  3. package/cli-utils/generated-marker.js +43 -0
  4. package/cli-utils/helm-commented-values.js +37 -3
  5. package/extension-utils/llms-utils.js +6 -2
  6. package/extension-utils/metadata-candidates.js +304 -0
  7. package/extension-utils/metadata-check.js +174 -0
  8. package/extension-utils/metadata-suggest.js +573 -0
  9. package/extension-utils/taxonomy-categories.js +106 -0
  10. package/extension-utils/taxonomy.js +566 -0
  11. package/extensions/REFERENCE.adoc +90 -4
  12. package/extensions/algolia-indexer/generate-index.js +13 -1
  13. package/extensions/algolia-indexer/index.js +4 -2
  14. package/extensions/convert-sitemap-to-markdown.js +47 -12
  15. package/extensions/convert-to-markdown.js +176 -0
  16. package/extensions/generate-fields-only-pages.js +14 -0
  17. package/extensions/modify-connect-tag-playbook.js +2 -2
  18. package/extensions/url-to-xref.js +92 -22
  19. package/extensions/validate-attributes.js +10 -1
  20. package/package.json +2 -1
  21. package/tools/check-metadata/index.js +523 -0
  22. package/tools/cloud-regions/cloud-regions-table-adoc.hbs +1 -2
  23. package/tools/cloud-regions/cloud-regions-table-md.hbs +2 -2
  24. package/tools/cloud-regions/render-cloud-regions.js +3 -0
  25. package/tools/dispatch-graph/check-dispatch-graph.js +790 -0
  26. package/tools/dispatch-graph/classify-runs.js +128 -0
  27. package/tools/dispatch-graph/parse-workflows.js +499 -0
  28. package/tools/enterprise-features/detect-gating-changes.js +393 -0
  29. package/tools/enterprise-features/verify.js +2 -1
  30. package/tools/gen-rpk-ascii.py +7 -1
  31. package/tools/lint-strings/fixtures/connect/lint_connect.go +8 -0
  32. package/tools/lint-strings/fixtures/crd/lint_types.go +4 -1
  33. package/tools/lint-strings/fixtures/rpk-pr461/delete.base.go +42 -0
  34. package/tools/lint-strings/fixtures/rpk-pr461/delete.head.go +45 -0
  35. package/tools/lint-strings/fixtures/rpk-pr461/reviewer-comments.json +1 -0
  36. package/tools/lint-strings/index.js +133 -3
  37. package/tools/lint-strings/rules/verbatim-asciidoc.js +166 -1
  38. package/tools/lint-strings/surfaces/connect.js +72 -12
  39. package/tools/lint-strings/surfaces/crd.js +10 -6
  40. package/tools/metrics/metrics.py +11 -0
  41. package/tools/property-extractor/generate-handlebars-docs.js +9 -1
  42. package/tools/property-extractor/helpers/applyPropertyLinks.js +35 -0
  43. package/tools/redpanda-connect/generate-rpcn-connector-docs.js +29 -8
  44. package/tools/redpanda-connect/rpcn-connector-docs-handler.js +19 -24
  45. package/tools/redpanda-connect/templates/bloblang-function.hbs +1 -1
  46. package/tools/redpanda-connect/templates/descriptions-partials.hbs +1 -1
  47. package/tools/redpanda-connect/templates/examples-partials.hbs +1 -1
  48. package/tools/redpanda-connect/templates/fields-partials.hbs +2 -2
  49. package/tools/redpanda-connect/templates/metadata-partials.hbs +1 -1
  50. package/tools/rpk-docs/generate-rpk-docs.js +2 -0
  51. package/tools/rpk-docs/generate-x-env-partial.js +7 -4
  52. package/tools/rpk-docs/helpers/index.js +4 -1
  53. package/tools/rpk-docs/templates/command.hbs +1 -1
@@ -17,6 +17,9 @@ Object.entries(helpers).forEach(([name, fn]) => {
17
17
  }
18
18
  handlebars.registerHelper(name, fn);
19
19
  });
20
+ // The provenance marker the partial templates write on their first line
21
+ const { generatedMarker } = require('../../cli-utils/generated-marker');
22
+ handlebars.registerHelper('generatedMarker', generatedMarker);
20
23
 
21
24
  // Default “main” template (connector.hbs) which invokes partials {{> intro}}, {{> fields}}, {{> examples}}
22
25
  const DEFAULT_TEMPLATE = path.resolve(__dirname, './templates/connector.hbs');
@@ -34,9 +37,12 @@ const { hasStructuralHeadings, hasMarkdownHeadings, firstHeadingDepth, escapePla
34
37
  // section is removed upstream. Kept as an AsciiDoc comment so the file renders
35
38
  // nothing while any lingering include directive still resolves cleanly.
36
39
  const STALE_METADATA_PARTIAL =
37
- '// This content is autogenerated. Do not edit manually. ' +
38
- 'The connector description no longer contains a `== Metadata` section, so this partial is intentionally empty. ' +
39
- 'You can remove the include directive that points at this file from the connector page.\n';
40
+ generatedMarker(
41
+ 'rpcn-connector-docs',
42
+ 'the component spec in redpanda-data/connect',
43
+ 'The connector description no longer contains a `== Metadata` section, so this partial is intentionally empty. ' +
44
+ 'You can remove the include directive that points at this file from the connector page.'
45
+ ) + '\n';
40
46
 
41
47
  // Banner-only content written to a description partial when the connector's
42
48
  // description is removed upstream. Same rationale as STALE_METADATA_PARTIAL:
@@ -50,12 +56,27 @@ const STALE_METADATA_PARTIAL =
50
56
  // every page that includes it, on every build, which is a build failure
51
57
  // wherever Asciidoctor warnings are treated as errors. An empty region
52
58
  // resolves to nothing and says nothing.
53
- const STALE_DESCRIPTION_PARTIAL =
54
- '// This content is autogenerated. Do not edit manually. ' +
55
- 'The connector no longer has a description, so this partial is intentionally empty. ' +
56
- 'You can remove the include directive that points at this file from the connector page.\n' +
59
+ const STALE_DESCRIPTION_REGIONS =
57
60
  '\n// tag::meta[]\n// end::meta[]\n' +
58
61
  '\n// tag::body[]\n// end::body[]\n';
62
+ const STALE_DESCRIPTION_PARTIAL =
63
+ generatedMarker(
64
+ 'rpcn-connector-docs',
65
+ 'the component spec in redpanda-data/connect',
66
+ 'The connector no longer has a description, so this partial is intentionally empty. ' +
67
+ 'You can remove the include directive that points at this file from the connector page.'
68
+ ) + '\n' + STALE_DESCRIPTION_REGIONS;
69
+ // What earlier releases wrote for the same blanked partial. The orphan sweep
70
+ // treats either as already blanked, so a partial emptied before the marker
71
+ // changed is not re-blanked and re-reported. The marker carries no version,
72
+ // so this list grows only when the wording does.
73
+ const STALE_DESCRIPTION_PARTIALS = new Set([
74
+ STALE_DESCRIPTION_PARTIAL,
75
+ '// This content is autogenerated. Do not edit manually. ' +
76
+ 'The connector no longer has a description, so this partial is intentionally empty. ' +
77
+ 'You can remove the include directive that points at this file from the connector page.\n' +
78
+ STALE_DESCRIPTION_REGIONS,
79
+ ]);
59
80
 
60
81
  // Component families with their own reference pages, keyed by the canonical
61
82
  // type directory from typeDirFor(). Other data keys -- `config`, the bloblang
@@ -932,7 +953,7 @@ async function generateRpcnConnectorDocs(options) {
932
953
  const orphanPath = path.join(typeDirPath, file);
933
954
  // Already blanked on an earlier run: leave it alone so it is not
934
955
  // re-reported forever.
935
- if (fs.readFileSync(orphanPath, 'utf8') === STALE_DESCRIPTION_PARTIAL) continue;
956
+ if (STALE_DESCRIPTION_PARTIALS.has(fs.readFileSync(orphanPath, 'utf8'))) continue;
936
957
  orphans.push({ key, orphanPath });
937
958
  }
938
959
  }
@@ -30,11 +30,9 @@ function capToTwoSentences (description) {
30
30
  }
31
31
 
32
32
  const abbreviations = [
33
- /https?:\/\/[^\s]+?(?=[.!?](?:\s|$)|\s|$)/gi, // Protect URLs from being split by sentence detection (non-greedy, preserve trailing punctuation)
34
- /\bxref:[^\s[\]]+\[[^\]]*\]/g, // Protect Antora xref macros (e.g. xref:components:processors/try.adoc[`try`]) whose targets contain periods
35
- /\b[\w/-]+\.(?:adoc|md|ya?ml|json|html)\b/gi, // Protect bare doc/config filenames (try.adoc, config.yaml) from splitting
36
- /\bv\d+\.\d+(?:\.\d+)?/gi,
37
- /\d+\.\d+/g,
33
+ // A period inside a token (a URL, an xref target, a filename, a version
34
+ // or a decimal) has no whitespace after it, so it never ends a sentence.
35
+ // Only abbreviations that are followed by a space need protecting.
38
36
  /\be\.g\./gi,
39
37
  /\bi\.e\./gi,
40
38
  /\betc\./gi,
@@ -79,21 +77,12 @@ function capToTwoSentences (description) {
79
77
  return placeholder
80
78
  })
81
79
 
82
- const sentenceRegex = /[^.!?]+[.!?]+(?:\s|$)/g
83
-
84
- // An unprotected mid-token period (`fetch.max.partition.bytes`) stops a
85
- // match, and the regex then resumes after it, so the text before that
86
- // period never belongs to any match. Merge each such gap into the sentence
87
- // that follows it rather than silently discarding it, otherwise the second
88
- // "sentence" can be a tail such as "bytes`.". Text after the last match
89
- // (an unterminated colon lead-in, for example) is still dropped.
90
- let sentences = null
91
- let lastEnd = 0
92
- for (const m of normalized.matchAll(sentenceRegex)) {
93
- if (!sentences) sentences = []
94
- sentences.push(normalized.slice(lastEnd, m.index) + m[0])
95
- lastEnd = m.index + m[0].length
96
- }
80
+ // A sentence ends at punctuation, optionally followed by a closing quote,
81
+ // parenthesis or bracket, then whitespace or the end of the text. Matching
82
+ // lazily up to that boundary keeps a period inside a token, such as the
83
+ // dotted name partition.assignment.strategy, in its sentence. Text after the
84
+ // last match (an unterminated colon lead-in, for example) is dropped.
85
+ const sentences = normalized.match(/[\s\S]+?[.!?]+["')\]`]*(?:\s|$)/g)
97
86
 
98
87
  if (!sentences || sentences.length === 0) {
99
88
  let result = normalized
@@ -644,7 +633,8 @@ function buildFieldsTable (fields, capFn, opts = {}) {
644
633
  })
645
634
  }
646
635
 
647
- const desc = info.description ? capFn(info.description) : '// TODO: Add description'
636
+ // A | in the description would end the cell and shift the row.
637
+ const desc = info.description ? capFn(info.description).replace(/\|/g, '\\|') : '// TODO: Add description'
648
638
 
649
639
  section += `|${fieldName}\n`
650
640
  section += `|${desc}\n`
@@ -687,18 +677,23 @@ function buildChangedDefaultsTable (changedDefaults, capFn) {
687
677
  for (const [, info] of Object.entries(byFieldAndDefaults)) {
688
678
  // Values render as literal inline code, so interpolations like
689
679
  // ${!uuid_v4()} and characters like * or _ show as typed.
680
+ // Values render as literal inline code through pass:c, which, unlike
681
+ // `+...+`, also keeps values with ++ or with spaces at either end. Strings
682
+ // that are empty, start or end with whitespace, or contain a newline show
683
+ // as JSON, so " " and "\n" read as the values they are.
690
684
  const formatDefault = (val) => {
691
685
  if (val === undefined || val === null) return 'none'
692
686
  let text
693
- if (typeof val === 'string') text = val === '' ? '""' : val
687
+ if (typeof val === 'string') text = (val === '' || /^\s|\s$|\n/.test(val)) ? JSON.stringify(val) : val
694
688
  else if (typeof val === 'number' || typeof val === 'boolean') text = String(val)
695
689
  else text = JSON.stringify(val)
696
- return `\`+${text.replace(/\|/g, '\\|')}+\``
690
+ return `\`pass:c[${text.replace(/\]/g, '\\]').replace(/\|/g, '\\|')}]\``
697
691
  }
698
692
 
699
693
  const oldVal = formatDefault(info.oldDefault)
700
694
  const newVal = formatDefault(info.newDefault)
701
- const desc = info.description ? capFn(info.description) : '// TODO: Add description'
695
+ // A | in the description would end the cell and shift the row.
696
+ const desc = info.description ? capFn(info.description).replace(/\|/g, '\\|') : '// TODO: Add description'
702
697
 
703
698
  const byType = {}
704
699
  for (const comp of info.components) {
@@ -1,4 +1,4 @@
1
- // This content is autogenerated. Do not edit manually. To override descriptions, use the doc-tools CLI with the --overrides option: https://redpandadata.atlassian.net/wiki/spaces/DOC/pages/1247543314/Generate+reference+docs+for+Redpanda+Connect
1
+ {{{generatedMarker "rpcn-connector-docs" "the Bloblang spec in redpanda-data/connect or redpanda-data/benthos" "This file is a doc-tools preview. The published partials are generated in redpanda-data/connect by `task docs`, and their first line names the file that registers the function or method. To change the text, edit the spec in that file."}}}
2
2
 
3
3
  = {{name}}
4
4
  {{#if signature}}
@@ -1,5 +1,5 @@
1
1
  {{#if (or summary description version)}}
2
- // This content is autogenerated. Do not edit manually. The summary and description come from the connector's definition in the Connect source. To change them, update the connector upstream, or use the doc-tools CLI with the --overrides option: https://redpandadata.atlassian.net/wiki/spaces/DOC/pages/1247543314/Generate+reference+docs+for+Redpanda+Connect
2
+ {{{generatedMarker "rpcn-connector-docs" "the component spec in redpanda-data/connect or redpanda-data/benthos" "The summary and description come from the component spec. This file is a doc-tools preview. The published partials are generated in redpanda-data/connect by `task docs`, and their first line names the file that registers the component. To change the text, edit the component spec in that file."}}}
3
3
  //
4
4
  // Pages consume this partial in two places so both stay fresh:
5
5
  // header: include::...[tag=meta] (sets :description: for search snippets and meta tags)
@@ -1,5 +1,5 @@
1
1
  {{#with examples}}
2
- // This content is autogenerated. Do not edit manually. To override descriptions, use the doc-tools CLI with the --overrides option: https://redpandadata.atlassian.net/wiki/spaces/DOC/pages/1247543314/Generate+reference+docs+for+Redpanda+Connect
2
+ {{{generatedMarker "rpcn-connector-docs" "the component spec in redpanda-data/connect or redpanda-data/benthos" "This file is a doc-tools preview. The published partials are generated in redpanda-data/connect by `task docs`, and their first line names the file that registers the component. To change the text, edit the component spec in that file."}}}
3
3
 
4
4
  == Examples
5
5
 
@@ -1,11 +1,11 @@
1
1
  {{#if this.config.children}}
2
- // This content is autogenerated. Do not edit manually. To override descriptions, use the doc-tools CLI with the --overrides option: https://redpandadata.atlassian.net/wiki/spaces/DOC/pages/1247543314/Generate+reference+docs+for+Redpanda+Connect
2
+ {{{generatedMarker "rpcn-connector-docs" "the component spec in redpanda-data/connect or redpanda-data/benthos" "This file is a doc-tools preview. The published partials are generated in redpanda-data/connect by `task docs`, and their first line names the file that registers the component. To change the text, edit the component spec in that file."}}}
3
3
 
4
4
  == Fields
5
5
 
6
6
  {{{renderConnectFields this.config.children}}}
7
7
  {{else if this.children}}
8
- // This content is autogenerated. Do not edit manually. To override descriptions, use the doc-tools CLI with the --overrides option: https://redpandadata.atlassian.net/wiki/spaces/DOC/pages/1247543314/Generate+reference+docs+for+Redpanda+Connect
8
+ {{{generatedMarker "rpcn-connector-docs" "the component spec in redpanda-data/connect or redpanda-data/benthos" "This file is a doc-tools preview. The published partials are generated in redpanda-data/connect by `task docs`, and their first line names the file that registers the component. To change the text, edit the component spec in that file."}}}
9
9
 
10
10
  == Fields
11
11
 
@@ -1,5 +1,5 @@
1
1
  {{#if (renderConnectMetadata description)}}
2
- // This content is autogenerated. Do not edit manually. Metadata fields come from the connector's description in the Connect source. To change them, update the connector description upstream, or use the doc-tools CLI with the --overrides option: https://redpandadata.atlassian.net/wiki/spaces/DOC/pages/1247543314/Generate+reference+docs+for+Redpanda+Connect
2
+ {{{generatedMarker "rpcn-connector-docs" "the component spec in redpanda-data/connect or redpanda-data/benthos" "Metadata fields come from the `== Metadata` section of the component description. This file is a doc-tools preview. The published partials are generated in redpanda-data/connect by `task docs`, and their first line names the file that registers the component. To change the text, edit the component spec in that file."}}}
3
3
 
4
4
  {{{renderConnectMetadata description}}}
5
5
  {{/if}}
@@ -11,6 +11,8 @@ Object.entries(helpers).forEach(([name, fn]) => {
11
11
  handlebars.registerHelper(name, fn)
12
12
  }
13
13
  })
14
+ // The provenance marker command.hbs writes under the page header
15
+ handlebars.registerHelper('generatedMarker', require('../../cli-utils/generated-marker').generatedMarker)
14
16
 
15
17
  // Template paths
16
18
  const TEMPLATES_DIR = path.resolve(__dirname, './templates')
@@ -28,17 +28,20 @@ const fs = require('fs')
28
28
  const os = require('os')
29
29
  const path = require('path')
30
30
  const { spawnSync } = require('child_process')
31
+ const { generatedMarker } = require('../../cli-utils/generated-marker')
31
32
 
32
33
  // A healthy rpk exposes ~30 -X options. Refuse to overwrite the partial
33
34
  // with a suspiciously small table (for example, if -X list output ever
34
35
  // changes format and only partially parses).
35
36
  const MIN_OPTIONS = 20
36
37
 
38
+ // The shared marker, so convert-to-markdown reports the partial as generated.
37
39
  const GENERATED_BANNER = `// tag::generated[]
38
- // Generated from rpk's own -X option data. Do not edit manually:
39
- // regenerate with doc-tools generate rpk-docs (which rewrites this
40
- // file alongside the rpk command pages) or, for a targeted refresh,
41
- // doc-tools generate rpk-env-partial.
40
+ ${generatedMarker(
41
+ 'rpk-env-partial',
42
+ "rpk's own -X option data (rpk --print-tree)",
43
+ 'Regenerate with doc-tools generate rpk-docs, which rewrites this file alongside the rpk command pages, or, for a targeted refresh, doc-tools generate rpk-env-partial.'
44
+ )}
42
45
  `
43
46
 
44
47
  /**
@@ -426,7 +426,10 @@ function wrapDescriptionPassthrough(str) {
426
426
  if (!str) return ''
427
427
  // Check if contains backticks (inline code) or other formatting markers
428
428
  if (/`/.test(str)) {
429
- return `pass:q[${str}]`
429
+ // pass:q[] skips special-character substitution, so a placeholder such as
430
+ // <agent> would reach the HTML raw and be dropped as an unknown tag.
431
+ const escaped = str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')
432
+ return `pass:q[${escaped}]`
430
433
  }
431
434
  return str
432
435
  }
@@ -22,7 +22,7 @@
22
22
  :page-deprecated: true
23
23
  {{/if}}
24
24
 
25
- // This content is autogenerated. Do not edit manually. To customize content, see the writer's guide: https://github.com/redpanda-data/docs/blob/main/docs-data/RPK_OVERRIDES_GUIDE.adoc
25
+ {{{generatedMarker "rpk-docs" "the rpk command help in redpanda-data/streaming-enterprise" "To customize content, see the writer's guide: https://github.com/redpanda-data/docs/blob/main/docs-data/RPK_OVERRIDES_GUIDE.adoc"}}}
26
26
  {{#each pageAttributes}}
27
27
  :{{@key}}: {{this}}
28
28
  {{/each}}