@redpanda-data/docs-extensions-and-macros 4.4.2 → 4.6.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 (46) hide show
  1. package/README.adoc +0 -163
  2. package/bin/doc-tools.js +808 -151
  3. package/cli-utils/antora-utils.js +127 -0
  4. package/cli-utils/convert-doc-links.js +58 -0
  5. package/cli-utils/generate-cluster-docs.sh +1 -1
  6. package/cli-utils/self-managed-docs-branch.js +91 -0
  7. package/cli-utils/start-cluster.sh +12 -2
  8. package/docker-compose/25.1/bootstrap.yml +67 -0
  9. package/docker-compose/25.1/docker-compose.yml +414 -0
  10. package/docker-compose/25.1/generate-profiles.yaml +77 -0
  11. package/docker-compose/25.1/rpk-profile.yaml +24 -0
  12. package/docker-compose/25.1/transactions-schema.json +37 -0
  13. package/docker-compose/25.1/transactions.md +46 -0
  14. package/docker-compose/25.1/transform/README.adoc +73 -0
  15. package/docker-compose/25.1/transform/go.mod +5 -0
  16. package/docker-compose/25.1/transform/go.sum +2 -0
  17. package/docker-compose/25.1/transform/regex.wasm +0 -0
  18. package/docker-compose/25.1/transform/transform.go +122 -0
  19. package/docker-compose/25.1/transform/transform.yaml +33 -0
  20. package/docker-compose/bootstrap.yml +0 -12
  21. package/package.json +6 -5
  22. package/tools/fetch-from-github.js +2 -2
  23. package/tools/redpanda-connect/generate-rpcn-connector-docs.js +205 -0
  24. package/tools/redpanda-connect/helpers/advancedConfig.js +17 -0
  25. package/tools/redpanda-connect/helpers/buildConfigYaml.js +53 -0
  26. package/tools/redpanda-connect/helpers/commonConfig.js +31 -0
  27. package/tools/redpanda-connect/helpers/eq.js +10 -0
  28. package/tools/redpanda-connect/helpers/index.js +19 -0
  29. package/tools/redpanda-connect/helpers/isObject.js +1 -0
  30. package/tools/redpanda-connect/helpers/join.js +6 -0
  31. package/tools/redpanda-connect/helpers/ne.js +10 -0
  32. package/tools/redpanda-connect/helpers/or.js +4 -0
  33. package/tools/redpanda-connect/helpers/renderConnectExamples.js +37 -0
  34. package/tools/redpanda-connect/helpers/renderConnectFields.js +146 -0
  35. package/tools/redpanda-connect/helpers/renderLeafField.js +64 -0
  36. package/tools/redpanda-connect/helpers/renderObjectField.js +41 -0
  37. package/tools/redpanda-connect/helpers/renderYamlList.js +24 -0
  38. package/tools/redpanda-connect/helpers/toYaml.js +11 -0
  39. package/tools/redpanda-connect/helpers/uppercase.js +9 -0
  40. package/tools/redpanda-connect/parse-csv-connectors.js +63 -0
  41. package/tools/redpanda-connect/report-delta.js +152 -0
  42. package/tools/redpanda-connect/templates/connector.hbs +20 -0
  43. package/tools/redpanda-connect/templates/examples-partials.hbs +7 -0
  44. package/tools/redpanda-connect/templates/fields-partials.hbs +13 -0
  45. package/tools/redpanda-connect/templates/intro.hbs +35 -0
  46. package/macros/data-template.js +0 -591
@@ -0,0 +1,127 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const yaml = require('js-yaml');
6
+
7
+ /**
8
+ * Attempts to locate and parse `antora.yml` in the current working directory.
9
+ *
10
+ * @returns {Object|undefined} The parsed YAML as a JavaScript object, or undefined if not found or on error.
11
+ */
12
+ function loadAntoraConfig() {
13
+ const antoraPath = path.join(process.cwd(), 'antora.yml');
14
+ if (!fs.existsSync(antoraPath)) {
15
+ // No antora.yml in project root
16
+ return undefined;
17
+ }
18
+
19
+ try {
20
+ const fileContents = fs.readFileSync(antoraPath, 'utf8');
21
+ const config = yaml.load(fileContents);
22
+ if (typeof config !== 'object' || config === null) {
23
+ console.error('Warning: antora.yml parsed to a non‐object value.');
24
+ return undefined;
25
+ }
26
+ return config;
27
+ } catch (err) {
28
+ console.error(`Error reading/parsing antora.yml: ${err.message}`);
29
+ return undefined;
30
+ }
31
+ }
32
+
33
+ /**
34
+ * Safely retrieves a nested value from the Antora configuration, given a "dot path".
35
+ *
36
+ * Example usage:
37
+ * const latestVersion = getAntoraValue('asciidoc.attributes.latest-connect-version');
38
+ *
39
+ * @param {string} keyPath
40
+ * A dot-separated path into the Antora object (e.g. "asciidoc.attributes.foo").
41
+ * @returns {*}
42
+ * The value at that path, or undefined if the file is missing or the key does not exist.
43
+ */
44
+ function getAntoraValue(keyPath) {
45
+ const config = loadAntoraConfig();
46
+ if (!config) {
47
+ return undefined;
48
+ }
49
+
50
+ // Split on dots, but ignore empty segments
51
+ const segments = keyPath.split('.').filter(Boolean);
52
+ let cursor = config;
53
+
54
+ for (const seg of segments) {
55
+ if (cursor && typeof cursor === 'object' && seg in cursor) {
56
+ cursor = cursor[seg];
57
+ } else {
58
+ return undefined;
59
+ }
60
+ }
61
+ return cursor;
62
+ }
63
+
64
+ /**
65
+ * Safely sets a nested value in the Antora configuration, given a "dot path".
66
+ * If the file or path does not exist, it will create intermediate objects as needed.
67
+ * After setting the value, writes the updated YAML back to `antora.yml`.
68
+ *
69
+ * @param {string} keyPath
70
+ * A dot-separated path to set (e.g. "asciidoc.attributes.latest-connect-version").
71
+ * @param {*} newValue
72
+ * The new value to assign at that path.
73
+ * @returns {boolean}
74
+ * True if it succeeded, false otherwise.
75
+ */
76
+ function setAntoraValue(keyPath, newValue) {
77
+ const antoraPath = path.join(process.cwd(), 'antora.yml');
78
+ if (!fs.existsSync(antoraPath)) {
79
+ console.error('Cannot update antora.yml: file not found in project root.');
80
+ return false;
81
+ }
82
+
83
+ let config;
84
+ try {
85
+ const fileContents = fs.readFileSync(antoraPath, 'utf8');
86
+ config = yaml.load(fileContents) || {};
87
+ if (typeof config !== 'object' || config === null) {
88
+ config = {};
89
+ }
90
+ } catch (err) {
91
+ console.error(`Error reading/parsing antora.yml: ${err.message}`);
92
+ return false;
93
+ }
94
+
95
+ // Traverse/construct nested objects
96
+ const segments = keyPath.split('.').filter(Boolean);
97
+ let cursor = config;
98
+ for (let i = 0; i < segments.length; i++) {
99
+ const seg = segments[i];
100
+ if (i === segments.length - 1) {
101
+ // Last segment: assign
102
+ cursor[seg] = newValue;
103
+ } else {
104
+ // Intermediate: ensure object
105
+ if (!(seg in cursor) || typeof cursor[seg] !== 'object' || cursor[seg] === null) {
106
+ cursor[seg] = {};
107
+ }
108
+ cursor = cursor[seg];
109
+ }
110
+ }
111
+
112
+ // Serialize back to YAML and write
113
+ try {
114
+ const newYaml = yaml.dump(config, { lineWidth: 120 });
115
+ fs.writeFileSync(antoraPath, newYaml, 'utf8');
116
+ return true;
117
+ } catch (err) {
118
+ console.error(`Error writing antora.yml: ${err.message}`);
119
+ return false;
120
+ }
121
+ }
122
+
123
+ module.exports = {
124
+ loadAntoraConfig,
125
+ getAntoraValue,
126
+ setAntoraValue,
127
+ };
@@ -0,0 +1,58 @@
1
+ const { URL } = require('url');
2
+
3
+ /**
4
+ * Converts a docs.redpanda.com URL, optionally suffixed with a label in brackets, into an Antora xref resource ID string.
5
+ *
6
+ * If the input includes a label in square brackets (e.g., `[Label]`), the label is preserved and appended to the resulting xref.
7
+ *
8
+ * @param {string} input - A docs.redpanda.com URL, optionally followed by a label in square brackets.
9
+ * @returns {string} The corresponding Antora xref resource ID, with the label preserved if present.
10
+ *
11
+ * @throws {Error} If the input is not a valid URL or does not belong to docs.redpanda.com.
12
+ */
13
+ function urlToXref(input) {
14
+ // Peel off an optional “[label]”
15
+ let urlPart = input;
16
+ let label = '';
17
+ const mLabel = input.match(/^(.*)\[([^\]]+)\]$/);
18
+ if (mLabel) {
19
+ urlPart = mLabel[1];
20
+ label = mLabel[2];
21
+ }
22
+
23
+ //Parse & validate
24
+ let url;
25
+ try {
26
+ url = new URL(urlPart);
27
+ } catch {
28
+ throw new Error(`Invalid URL: ${input}`);
29
+ }
30
+ if (!/docs\.redpanda\.com$/.test(url.hostname)) {
31
+ throw new Error(`Not a docs.redpanda.com URL: ${input}`);
32
+ }
33
+
34
+ // Strip any leading “/docs”, “/docs/vX.Y”, “/docs/current”, “/vX.Y” or “/current”
35
+ let p = url.pathname.replace(
36
+ /^\/(?:docs(?:\/(?:v?\d+\.\d+|current))?|v?\d+\.\d+|current)\/?/,
37
+ ''
38
+ );
39
+ // Drop trailing slash
40
+ p = p.replace(/\/$/, '');
41
+ const segments = p.split('/').filter(Boolean);
42
+
43
+ // Build module + path + .adoc
44
+ let xref;
45
+ if (segments.length === 0) {
46
+ xref = 'xref:index.adoc';
47
+ } else {
48
+ const moduleName = segments.shift();
49
+ const pagePath = segments.join('/');
50
+ const fileName = (pagePath || moduleName) + '.adoc';
51
+ xref = `xref:${moduleName}:${fileName}`;
52
+ }
53
+
54
+ // Re-attach label if there was one
55
+ return label ? `${xref}[${label}]` : xref;
56
+ }
57
+
58
+ module.exports = { urlToXref };
@@ -73,7 +73,7 @@ else
73
73
  "$TAG"
74
74
  fi
75
75
 
76
- echo "✅ Redpanda cluster docs generated successfully!"
76
+ echo "✅ $MODE docs generated successfully!"
77
77
 
78
78
  # Tear down the cluster
79
79
  cd "$SCRIPT_DIR"/../docker-compose
@@ -0,0 +1,91 @@
1
+ const https = require('https');
2
+ const yaml = require('js-yaml');
3
+ const { spawnSync } = require('child_process');
4
+
5
+ /**
6
+ * Retrieves the current Self-Managed documentation version from the remote antora.yml file.
7
+ *
8
+ * @returns {Promise<string>} Resolves with the version string (e.g., "25.1").
9
+ *
10
+ * @throws {Error} If the antora.yml file cannot be fetched, parsed, or if the version field is missing.
11
+ */
12
+ function fetchRemoteAntoraVersion() {
13
+ const url = 'https://raw.githubusercontent.com/redpanda-data/docs/main/antora.yml'
14
+ return new Promise((resolve, reject) => {
15
+ https.get(url, res => {
16
+ if (res.statusCode !== 200) {
17
+ return reject(new Error(`Failed to fetch antora.yml: ${res.statusCode}`))
18
+ }
19
+ let body = ''
20
+ res.on('data', chunk => (body += chunk))
21
+ res.on('end', () => {
22
+ try {
23
+ const cfg = yaml.load(body)
24
+ if (cfg.version == null) {
25
+ throw new Error('version field missing')
26
+ }
27
+ const version = String(cfg.version).trim()
28
+ resolve(version)
29
+ } catch (err) {
30
+ reject(err)
31
+ }
32
+ })
33
+ }).on('error', reject)
34
+ })
35
+ }
36
+
37
+ /**
38
+ * Determines the appropriate documentation branch for a given operator tag based on the remote Antora version.
39
+ *
40
+ * Normalizes the input tag, extracts the major.minor version, and applies version-specific logic to select the correct branch. Verifies that the chosen branch exists in the remote repository.
41
+ *
42
+ * @param {string} operatorTag - The operator tag to evaluate (e.g., "operator/v25.1.2" or "v25.1.2").
43
+ * @returns {Promise<string>} The name of the documentation branch to use.
44
+ *
45
+ * @throws {Error} If the tag cannot be parsed or if the determined branch does not exist in the remote repository.
46
+ */
47
+ async function determineDocsBranch(operatorTag) {
48
+ // Strip any "operator/" prefix
49
+ const TAG = operatorTag.replace(/^(?:operator|release)\//, '')
50
+ // Pull in the remote Antora version
51
+ const ANTORA = await fetchRemoteAntoraVersion()
52
+ // Extract v<major>.<minor>
53
+ const mm = TAG.match(/^v(\d+\.\d+)/)
54
+ const filtered = mm ? `v${mm[1]}` : null
55
+
56
+ if (!filtered) {
57
+ throw new Error(`Could not parse major.minor from ${TAG}`)
58
+ }
59
+ // We started versioning the operator in line with Redpanda core versions. But when v2.4.x was the latest version, the docs were still on 25.1 and v25.1.x of the operator was still in beta. So we need to handle this special case.
60
+ let branch
61
+ if (filtered === 'v2.4') {
62
+ if (ANTORA === '25.1') {
63
+ branch = 'main'
64
+ } else {
65
+ branch = 'v/24.3'
66
+ }
67
+ // For all other versions use the v<major>.<minor> branch unless it is the current version, in which case we use 'main'.
68
+ } else if (filtered === `v${ANTORA}`) {
69
+ branch = 'main'
70
+ } else {
71
+ branch = `v/${filtered.slice(1)}`
72
+ }
73
+
74
+ // Verify branch exists
75
+ const repo = 'https://github.com/redpanda-data/docs.git'
76
+ const ref = `refs/heads/${branch}`
77
+ const ok = spawnSync('git', ['ls-remote', '--exit-code', '--heads', repo, ref], {
78
+ stdio: 'ignore'
79
+ }).status === 0
80
+
81
+ if (!ok) {
82
+ throw new Error(`Docs branch ${branch} not found in ${repo}`)
83
+ }
84
+
85
+ return branch
86
+ }
87
+
88
+ module.exports = {
89
+ fetchRemoteAntoraVersion,
90
+ determineDocsBranch
91
+ }
@@ -20,12 +20,22 @@ if [[ "$TAG" != "latest" ]]; then
20
20
  MAJOR_MINOR="$(echo "$TAG" | sed -E 's/^v?([0-9]+\.[0-9]+).*$/\1/')"
21
21
  fi
22
22
 
23
+ # Conditionally override quickstart dir for >= 25.1
24
+ if [[ "$MAJOR_MINOR" =~ ^([0-9]+)\.([0-9]+)$ ]]; then
25
+ major="${BASH_REMATCH[1]}"
26
+ minor="${BASH_REMATCH[2]}"
27
+
28
+ if (( major > 25 )) || (( major == 25 && minor >= 1 )); then
29
+ QUICKSTART_DIR="$PACKAGE_ROOT/docker-compose/25.1"
30
+ fi
31
+ fi
32
+
23
33
  # Fetch quickstart into package root if needed
24
34
  if [[ ! -d "$QUICKSTART_DIR" ]]; then
25
35
  echo "📥 Fetching Redpanda quickstart for ${MAJOR_MINOR}…"
26
36
  if [[ "$TAG" == "latest" ]]; then
27
- curl -sSLf --retry 3 https://docs.redpanda.com/redpanda-quickstart.tar.gz \
28
- | tar -C "$PACKAGE_ROOT" -xzf -
37
+ curl -sSLf --retry 3 https://docs.redpanda.com/redpanda-quickstart.tar.gz \
38
+ | tar -C "$PACKAGE_ROOT" -xzf -
29
39
  else
30
40
  curl -sSLf --retry 3 "https://docs.redpanda.com/${MAJOR_MINOR}-redpanda-quickstart.tar.gz" \
31
41
  | tar -C "$PACKAGE_ROOT" -xzf -
@@ -0,0 +1,67 @@
1
+ # =================================================================
2
+ # This file defines initial cluster properties for a Redpanda cluster.
3
+ # Some of these settings are intended for quickstart development and evaluation
4
+ # and are not suitable for production environments.
5
+ #
6
+ # For more information on bootstrap files, see:
7
+ # https://docs.redpanda.com/current/deploy/deployment-option/self-hosted/manual/production/production-deployment/#configure-a-bootstrap-file
8
+ # =================================================================
9
+
10
+ #
11
+ # Enable SASL authentication for the Kafka and Admin APIs.
12
+ # https://docs.redpanda.com/current/reference/properties/cluster-properties/#admin_api_require_auth
13
+ admin_api_require_auth: true
14
+ # At least one superuser is required to be able to create other SASL users
15
+ # https://docs.redpanda.com/current/reference/properties/cluster-properties/#superusers
16
+ superusers:
17
+ - superuser
18
+ # https://docs.redpanda.com/current/reference/properties/cluster-properties/#enable_sasl
19
+ enable_sasl: true
20
+ # Allow topics to be created on first access.
21
+ # https://docs.redpanda.com/current/reference/properties/cluster-properties/#auto_create_topics_enabled
22
+ auto_create_topics_enabled: true
23
+ # Enable data transforms.
24
+ # https://docs.redpanda.com/current/develop/data-transforms/how-transforms-work/
25
+ data_transforms_enabled: true
26
+ # Enable audit logging (enterprise feature).
27
+ # https://docs.redpanda.com/current/manage/audit-logging/
28
+ audit_enabled: true
29
+ # Enable Tiered Storage (enterprise feature).
30
+ # https://docs.redpanda.com/current/manage/tiered-storage/
31
+ cloud_storage_enabled: true
32
+ cloud_storage_region: local
33
+ cloud_storage_access_key: minio
34
+ cloud_storage_secret_key: redpandaTieredStorage7
35
+ cloud_storage_api_endpoint: minio
36
+ cloud_storage_api_endpoint_port: 9000
37
+ cloud_storage_disable_tls: true
38
+ cloud_storage_bucket: redpanda
39
+ cloud_storage_enable_remote_write: true
40
+ cloud_storage_enable_remote_read: true
41
+ # Forces segments to be uploaded to Tiered Storage faster for the purposes of the quickstart
42
+ # https://docs.redpanda.com/current/reference/properties/object-storage-properties/#cloud_storage_segment_max_upload_interval_sec
43
+ cloud_storage_segment_max_upload_interval_sec: 60
44
+ # Continuous Data Balancing (enterprise feature) continuously monitors your node and rack availability and disk usage. This enables self-healing clusters that dynamically balance partitions, ensuring smooth operations and optimal cluster performance.
45
+ # https://docs.redpanda.com/current/manage/cluster-maintenance/continuous-data-balancing/
46
+ partition_autobalancing_mode: continuous
47
+ # Enable Redpanda to collect consumer group metrics.
48
+ # https://docs.redpanda.com/current/reference/properties/cluster-properties/#enable_consumer_group_metrics
49
+ enable_consumer_group_metrics:
50
+ - "group"
51
+ - "partition"
52
+ - "consumer_lag"
53
+ # Lower the interval for the autogeneration of consumer group metrics.
54
+ # https://docs.redpanda.com/current/reference/properties/cluster-properties/#consumer_group_lag_collection_interval_sec
55
+ consumer_group_lag_collection_interval_sec: 60
56
+ # Enable Redpanda to collect host metrics.
57
+ # https://docs.redpanda.com/current/reference/properties/cluster-properties/#enable_host_metrics
58
+ enable_host_metrics: true
59
+ # Enable for Iceberg metrics
60
+ iceberg_enabled: true
61
+ # Set up Iceberg REST catalog configuration
62
+ iceberg_catalog_type: rest
63
+ iceberg_rest_catalog_endpoint: http://catalog:8181
64
+ # Credentials are required, but the catalog ignores them
65
+ iceberg_rest_catalog_client_id: catalog
66
+ iceberg_rest_catalog_client_secret: catalog123
67
+ iceberg_catalog_commit_interval_ms: 5000