@redpanda-data/docs-extensions-and-macros 3.9.1 → 3.10.1

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/README.adoc CHANGED
@@ -46,6 +46,62 @@ This section documents the Antora extensions provided by this library and how to
46
46
 
47
47
  IMPORTANT: Ensure you register each extension under the `antora.extensions` key in the playbook, not the `asciidoc.extensions` key.
48
48
 
49
+ === Add Bloblang samples to pages
50
+
51
+ The `collect-bloblang-samples` extension processes Bloblang examples from YAML files in the `examples` directory of the `redpanda-connect` component. This extension ensures that these examples are accessible as structured data for use in UI components or documentation, such as sample dropdowns in a Bloblang playground.
52
+
53
+ It validates, sorts, and attaches the processed examples as a JSON object to the Antora page attributes. The extension ensures examples have unique titles, mandatory fields (`input` and `mapping`), and are sorted in alphabetical order.
54
+
55
+ ==== Environment variables
56
+
57
+ This extension does not require any environment variables.
58
+
59
+ ==== Configuration options
60
+
61
+ To enable the extension, add it to your Antora playbook under the `antora.extensions` key. No additional configuration is required.
62
+
63
+ [,yaml]
64
+ ----
65
+ antora:
66
+ extensions:
67
+ - require: '@redpanda-data/docs-extensions-and-macros/extensions/collect-bloblang-samples'
68
+ ----
69
+
70
+ ==== Example Bloblang YAML file
71
+
72
+ The following YAML file is an example of how to define a Bloblang sample:
73
+
74
+ [,yaml]
75
+ ----
76
+ title: Hello world
77
+ input: |
78
+ {
79
+ "message": "hello world"
80
+ }
81
+ mapping: |
82
+ root.message = this.message.uppercase()
83
+ ----
84
+
85
+ ==== Sample output
86
+
87
+ The processed examples are added as JSON to the `page-bloblang-samples` attribute. For example:
88
+
89
+ [,json]
90
+ ----
91
+ {
92
+ "hello-world.yaml": {
93
+ "title": "Hello world",
94
+ "input": "{\n \"message\": \"hello world\"\n}\n",
95
+ "mapping": "root.message = this.message.uppercase()\n"
96
+ },
97
+ "array-processing.yaml": {
98
+ "title": "Array processing",
99
+ "input": "{\n \"numbers\": [1, 2, 3, 4, 5]\n}\n",
100
+ "mapping": "root.even_numbers = this.numbers.filter(n -> n % 2 == 0)"
101
+ }
102
+ }
103
+ ----
104
+
49
105
  === Add pages to root
50
106
 
51
107
  The `add-pages-to-root` extension allows you to copy files from your Antora content catalog to the root of the site during the build process. This is particularly useful for files like `llms.txt` or any custom files that need to be directly accessible at the site's root level.
@@ -0,0 +1,78 @@
1
+ const yaml = require('js-yaml');
2
+
3
+ module.exports.register = function () {
4
+ const logger = this.getLogger('collect-bloblang-samples');
5
+
6
+ this.on('contentClassified', ({ contentCatalog }) => {
7
+ const collectExamples = (examples, componentName) => {
8
+ const bloblangSamples = [];
9
+ const seenTitles = new Set();
10
+
11
+ examples
12
+ .filter((example) => example.src.relative.startsWith('playground/')) // Only include files in the 'bloblang' subdirectory
13
+ .forEach((example) => {
14
+ try {
15
+ const content = example.contents.toString('utf8');
16
+ const parsedContent = yaml.load(content);
17
+
18
+ if (!parsedContent.title) {
19
+ logger.warn(`Skipping example '${example.src.basename}' in '${componentName}': Missing title.`);
20
+ return;
21
+ }
22
+
23
+ if (seenTitles.has(parsedContent.title)) {
24
+ logger.warn(
25
+ `Duplicate title found: '${parsedContent.title}' in '${example.src.basename}' (${componentName}). Skipping.`
26
+ );
27
+ return;
28
+ }
29
+
30
+ if (!parsedContent.input || !parsedContent.mapping) {
31
+ logger.warn(
32
+ `Skipping example '${example.src.basename}' in '${componentName}': Missing input or mapping.`
33
+ );
34
+ return;
35
+ }
36
+
37
+ logger.info(`Loaded example: ${example.src.basename} with title: '${parsedContent.title}'`);
38
+ seenTitles.add(parsedContent.title);
39
+
40
+ bloblangSamples.push({ filename: example.src.basename, ...parsedContent });
41
+ } catch (error) {
42
+ logger.error(`Error processing example '${example.src.basename}' in '${componentName}':`, error);
43
+ }
44
+ });
45
+
46
+ bloblangSamples.sort((a, b) => a.title.localeCompare(b.title));
47
+
48
+ return bloblangSamples.reduce((acc, sample) => {
49
+ acc[sample.filename] = sample;
50
+ return acc;
51
+ }, {});
52
+ };
53
+
54
+ // Fetch examples from both components
55
+ const examples = contentCatalog.findBy({ component: 'redpanda-connect', family: 'example' });
56
+ const previewExamples = contentCatalog.findBy({ component: 'preview', family: 'example' });
57
+
58
+ if (!examples.length) logger.warn(`No examples found in the 'redpanda-connect' component.`);
59
+
60
+ // Get components
61
+ const connect = contentCatalog.getComponents().find((c) => c.name === 'redpanda-connect');
62
+ const preview = contentCatalog.getComponents().find((c) => c.name === 'preview');
63
+
64
+ if (connect) {
65
+ const connectSamples = collectExamples(examples, 'redpanda-connect');
66
+ connect.latest.asciidoc.attributes['page-bloblang-samples'] = JSON.stringify(connectSamples);
67
+ logger.debug(`Bloblang samples added to 'redpanda-connect': ${JSON.stringify(connectSamples, null, 2)}`);
68
+ } else {
69
+ logger.warn(`Component 'redpanda-connect' not found.`);
70
+ }
71
+
72
+ if (preview) {
73
+ const previewSamples = collectExamples(previewExamples, 'preview');
74
+ preview.latest.asciidoc.attributes['page-bloblang-samples'] = JSON.stringify(previewSamples);
75
+ logger.debug(`Bloblang samples added to 'preview': ${JSON.stringify(previewSamples, null, 2)}`);
76
+ }
77
+ });
78
+ };
@@ -704,7 +704,7 @@ module.exports.register = function (registry, context) {
704
704
  const requiresEnterprise = componentRows.some(row => row.is_licensed.toLowerCase() === 'yes');
705
705
  if (requiresEnterprise) {
706
706
  enterpriseLicenseInfo = `
707
- <p><strong>License</strong>: This component requires an <a href="https://redpanda.com/compare-platform-editions" target="_blank">Enterprise license</a>. To upgrade, contact <a href="https://redpanda.com/try-redpanda?section=enterprise-trial" target="_blank" rel="noopener">Redpanda sales</a>.</p>`;
707
+ <p><strong>License</strong>: This component requires an <a href="https://docs.redpanda.com/redpanda-connect/get-started/licensing/" target="_blank">Enterprise license</a>. To upgrade, go to the <a href="https://www.redpanda.com/upgrade" target="_blank" rel="noopener">Redpanda website</a>.</p>`;
708
708
  }
709
709
  }
710
710
  const isCloudSupported = componentRows.some(row => row.is_cloud_supported === 'y');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redpanda-data/docs-extensions-and-macros",
3
- "version": "3.9.1",
3
+ "version": "3.10.1",
4
4
  "description": "Antora extensions and macros developed for Redpanda documentation.",
5
5
  "keywords": [
6
6
  "antora",
@@ -31,6 +31,7 @@
31
31
  },
32
32
  "./extensions/replace-attributes-in-attachments": "./extensions/replace-attributes-in-attachments.js",
33
33
  "./extensions/add-pages-to-root": "./extensions/add-pages-to-root.js",
34
+ "./extensions/collect-bloblang-samples": "./extensions/collect-bloblang-samples.js",
34
35
  "./extensions/generate-rp-connect-categories": "./extensions/generate-rp-connect-categories.js",
35
36
  "./extensions/generate-rp-connect-info": "./extensions/generate-rp-connect-info.js",
36
37
  "./extensions/add-global-attributes": "./extensions/add-global-attributes.js",