@redpanda-data/docs-extensions-and-macros 4.11.1 → 4.12.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.
Files changed (31) hide show
  1. package/bin/doc-tools.js +201 -10
  2. package/package.json +3 -1
  3. package/tools/property-extractor/COMPUTED_CONSTANTS.md +173 -0
  4. package/tools/property-extractor/Makefile +12 -1
  5. package/tools/property-extractor/README.adoc +828 -97
  6. package/tools/property-extractor/compare-properties.js +38 -13
  7. package/tools/property-extractor/constant_resolver.py +610 -0
  8. package/tools/property-extractor/file_pair.py +42 -0
  9. package/tools/property-extractor/generate-handlebars-docs.js +41 -8
  10. package/tools/property-extractor/helpers/gt.js +9 -0
  11. package/tools/property-extractor/helpers/includes.js +17 -0
  12. package/tools/property-extractor/helpers/index.js +3 -0
  13. package/tools/property-extractor/helpers/isEnterpriseEnum.js +24 -0
  14. package/tools/property-extractor/helpers/renderPropertyExample.js +6 -5
  15. package/tools/property-extractor/overrides.json +248 -0
  16. package/tools/property-extractor/parser.py +254 -32
  17. package/tools/property-extractor/property_bag.py +40 -0
  18. package/tools/property-extractor/property_extractor.py +1417 -430
  19. package/tools/property-extractor/requirements.txt +1 -0
  20. package/tools/property-extractor/templates/property-backup.hbs +161 -0
  21. package/tools/property-extractor/templates/property.hbs +104 -49
  22. package/tools/property-extractor/templates/topic-property-backup.hbs +148 -0
  23. package/tools/property-extractor/templates/topic-property.hbs +72 -34
  24. package/tools/property-extractor/tests/test_known_values.py +617 -0
  25. package/tools/property-extractor/tests/transformers_test.py +81 -6
  26. package/tools/property-extractor/topic_property_extractor.py +23 -10
  27. package/tools/property-extractor/transformers.py +2191 -369
  28. package/tools/property-extractor/type_definition_extractor.py +669 -0
  29. package/tools/redpanda-connect/helpers/renderConnectFields.js +33 -1
  30. package/tools/redpanda-connect/report-delta.js +132 -9
  31. package/tools/property-extractor/definitions.json +0 -245
@@ -138,7 +138,39 @@ module.exports = function renderConnectFields(children, prefix = '') {
138
138
  if (child.examples && child.examples.length) {
139
139
  block += `[source,yaml]\n----\n# Examples:\n`;
140
140
  if (child.kind === 'array') {
141
- block += renderYamlList(child.name, child.examples);
141
+ // Render arrays in flow style (with brackets) instead of block style
142
+ child.examples.forEach(example => {
143
+ if (Array.isArray(example)) {
144
+ // Format as flow style: fieldName: [item1, item2, ...]
145
+ const items = example.map(item => {
146
+ if (typeof item === 'string') {
147
+ // Check if quoting is needed
148
+ const needsQuoting = item === '*' ||
149
+ /[:\[\]\{\},&>|%@`"]/.test(item) ||
150
+ /^[\s]|[\s]$/.test(item); // leading/trailing whitespace
151
+
152
+ if (needsQuoting) {
153
+ // Escape backslashes first, then double quotes
154
+ const escaped = item.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
155
+ return `"${escaped}"`;
156
+ }
157
+ return item;
158
+ }
159
+ // For non-strings, convert to string
160
+ const strValue = String(item);
161
+ // Check if the stringified value needs quoting
162
+ if (/[:\[\]\{\},&>|%@`"]/.test(strValue) || /^[\s]|[\s]$/.test(strValue)) {
163
+ const escaped = strValue.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
164
+ return `"${escaped}"`;
165
+ }
166
+ return strValue;
167
+ });
168
+ block += `${child.name}: [${items.join(', ')}]\n`;
169
+ } else {
170
+ // Fallback for non-array examples (shouldn't happen for array fields)
171
+ block += `${child.name}: ${example}\n`;
172
+ }
173
+ });
142
174
  } else {
143
175
  child.examples.forEach(example => {
144
176
  if (typeof example === 'object') {
@@ -1,3 +1,5 @@
1
+ const { execSync } = require('child_process');
2
+
1
3
  /**
2
4
  * Generate a JSON diff report between two connector index objects.
3
5
  * @param {object} oldIndex - Previous version connector index
@@ -78,6 +80,66 @@ function generateConnectorDiffJson(oldIndex, newIndex, opts = {}) {
78
80
  });
79
81
  });
80
82
 
83
+ // Newly deprecated components (exist in both versions but became deprecated)
84
+ const deprecatedComponents = [];
85
+ Object.keys(newMap).forEach(cKey => {
86
+ if (!(cKey in oldMap)) return;
87
+ const oldStatus = (oldMap[cKey].raw.status || '').toLowerCase();
88
+ const newStatus = (newMap[cKey].raw.status || '').toLowerCase();
89
+ if (oldStatus !== 'deprecated' && newStatus === 'deprecated') {
90
+ const [type, name] = cKey.split(':');
91
+ const raw = newMap[cKey].raw;
92
+ deprecatedComponents.push({
93
+ name,
94
+ type,
95
+ status: raw.status || raw.type || '',
96
+ version: raw.version || raw.introducedInVersion || '',
97
+ description: raw.description || ''
98
+ });
99
+ }
100
+ });
101
+
102
+ // Newly deprecated fields (exist in both versions but became deprecated)
103
+ const deprecatedFields = [];
104
+ Object.keys(newMap).forEach(cKey => {
105
+ if (!(cKey in oldMap)) return;
106
+ const oldFieldsArr = oldMap[cKey].fields || [];
107
+ const newFieldsArr = newMap[cKey].fields || [];
108
+
109
+ // Check fields that exist in both versions
110
+ const commonFields = oldFieldsArr.filter(f => newFieldsArr.includes(f));
111
+ commonFields.forEach(fName => {
112
+ const [type, compName] = cKey.split(':');
113
+
114
+ // Get old field object
115
+ let oldFieldObj = null;
116
+ if (type === 'config') {
117
+ oldFieldObj = (oldMap[cKey].raw.children || []).find(f => f.name === fName);
118
+ } else {
119
+ oldFieldObj = (oldMap[cKey].raw.config?.children || []).find(f => f.name === fName);
120
+ }
121
+
122
+ // Get new field object
123
+ let newFieldObj = null;
124
+ if (type === 'config') {
125
+ newFieldObj = (newMap[cKey].raw.children || []).find(f => f.name === fName);
126
+ } else {
127
+ newFieldObj = (newMap[cKey].raw.config?.children || []).find(f => f.name === fName);
128
+ }
129
+
130
+ const oldDeprecated = oldFieldObj && (oldFieldObj.is_deprecated === true || oldFieldObj.deprecated === true || (oldFieldObj.status || '').toLowerCase() === 'deprecated');
131
+ const newDeprecated = newFieldObj && (newFieldObj.is_deprecated === true || newFieldObj.deprecated === true || (newFieldObj.status || '').toLowerCase() === 'deprecated');
132
+
133
+ if (!oldDeprecated && newDeprecated) {
134
+ deprecatedFields.push({
135
+ component: cKey,
136
+ field: fName,
137
+ description: newFieldObj && newFieldObj.description
138
+ });
139
+ }
140
+ });
141
+ });
142
+
81
143
  return {
82
144
  comparison: {
83
145
  oldVersion: opts.oldVersion || '',
@@ -88,23 +150,20 @@ function generateConnectorDiffJson(oldIndex, newIndex, opts = {}) {
88
150
  newComponents: newComponents.length,
89
151
  removedComponents: removedComponents.length,
90
152
  newFields: newFields.length,
91
- removedFields: removedFields.length
153
+ removedFields: removedFields.length,
154
+ deprecatedComponents: deprecatedComponents.length,
155
+ deprecatedFields: deprecatedFields.length
92
156
  },
93
157
  details: {
94
158
  newComponents,
95
159
  removedComponents,
96
160
  newFields,
97
- removedFields
161
+ removedFields,
162
+ deprecatedComponents,
163
+ deprecatedFields
98
164
  }
99
165
  };
100
166
  }
101
- // tools/redpanda-connect/report-delta.js
102
- 'use strict';
103
-
104
- const fs = require('fs');
105
- const path = require('path');
106
- const yaml = require('yaml');
107
- const { execSync } = require('child_process');
108
167
 
109
168
  function discoverComponentKeys(obj) {
110
169
  return Object.keys(obj).filter(key => Array.isArray(obj[key]));
@@ -209,6 +268,47 @@ function printDeltaReport(oldIndex, newIndex) {
209
268
  });
210
269
  });
211
270
 
271
+ // Newly deprecated components
272
+ const deprecatedComponentKeys = [];
273
+ Object.keys(newMap).forEach(cKey => {
274
+ if (!(cKey in oldMap)) return;
275
+ const oldStatus = (oldMap[cKey].raw.status || '').toLowerCase();
276
+ const newStatus = (newMap[cKey].raw.status || '').toLowerCase();
277
+ if (oldStatus !== 'deprecated' && newStatus === 'deprecated') {
278
+ deprecatedComponentKeys.push(cKey);
279
+ }
280
+ });
281
+
282
+ // Newly deprecated fields
283
+ const deprecatedFieldsList = [];
284
+ Object.keys(newMap).forEach(cKey => {
285
+ if (!(cKey in oldMap)) return;
286
+ const oldFieldsArr = oldMap[cKey].fields || [];
287
+ const newFieldsArr = newMap[cKey].fields || [];
288
+ const commonFields = oldFieldsArr.filter(f => newFieldsArr.includes(f));
289
+
290
+ commonFields.forEach(fName => {
291
+ const [type, compName] = cKey.split(':');
292
+ let oldFieldObj = null;
293
+ if (type === 'config') {
294
+ oldFieldObj = (oldMap[cKey].raw.children || []).find(f => f.name === fName);
295
+ } else {
296
+ oldFieldObj = (oldMap[cKey].raw.config?.children || []).find(f => f.name === fName);
297
+ }
298
+ let newFieldObj = null;
299
+ if (type === 'config') {
300
+ newFieldObj = (newMap[cKey].raw.children || []).find(f => f.name === fName);
301
+ } else {
302
+ newFieldObj = (newMap[cKey].raw.config?.children || []).find(f => f.name === fName);
303
+ }
304
+ const oldDeprecated = oldFieldObj && (oldFieldObj.is_deprecated === true || oldFieldObj.deprecated === true || (oldFieldObj.status || '').toLowerCase() === 'deprecated');
305
+ const newDeprecated = newFieldObj && (newFieldObj.is_deprecated === true || newFieldObj.deprecated === true || (newFieldObj.status || '').toLowerCase() === 'deprecated');
306
+ if (!oldDeprecated && newDeprecated) {
307
+ deprecatedFieldsList.push({ component: cKey, field: fName });
308
+ }
309
+ });
310
+ });
311
+
212
312
  console.log('\n📋 RPCN Connector Delta Report\n');
213
313
 
214
314
  if (newComponentKeys.length) {
@@ -242,6 +342,29 @@ function printDeltaReport(oldIndex, newIndex) {
242
342
  } else {
243
343
  console.log('➤ No newly added fields.\n');
244
344
  }
345
+
346
+ if (deprecatedComponentKeys.length) {
347
+ console.log('➤ Newly deprecated components:');
348
+ deprecatedComponentKeys.forEach(key => {
349
+ const [type, name] = key.split(':');
350
+ const raw = newMap[key].raw;
351
+ console.log(` • ${type}/${name}`);
352
+ });
353
+ console.log('');
354
+ } else {
355
+ console.log('➤ No newly deprecated components.\n');
356
+ }
357
+
358
+ if (deprecatedFieldsList.length) {
359
+ console.log('➤ Newly deprecated fields:');
360
+ deprecatedFieldsList.forEach(entry => {
361
+ const { component, field } = entry;
362
+ console.log(` • ${component} → ${field}`);
363
+ });
364
+ console.log('');
365
+ } else {
366
+ console.log('➤ No newly deprecated fields.\n');
367
+ }
245
368
  }
246
369
 
247
370
  module.exports = {
@@ -1,245 +0,0 @@
1
- {
2
- "client_group_quota": {
3
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/config/client_group_byte_rate_quota.h#L29",
4
- "type": "object",
5
- "properties": {
6
- "group_name": {
7
- "type": "string"
8
- },
9
- "clients_prefix": {
10
- "type": "string"
11
- },
12
- "quota": {
13
- "type": "integer",
14
- "minimum": -9223372036854775808,
15
- "maximum": 9223372036854775807
16
- }
17
- }
18
- },
19
- "config::broker_authn_endpoint": {
20
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/config/broker_authn_endpoint.h#L42",
21
- "type": "object",
22
- "properties": {
23
- "name": {
24
- "type": "string"
25
- },
26
- "address": {
27
- "type": "string"
28
- },
29
- "port": {
30
- "type": "integer",
31
- "minimum": 0,
32
- "maximum": 4294967295
33
- }
34
- }
35
- },
36
- "config::endpoint_tls_config": {
37
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/config/endpoint_tls_config.h#L21",
38
- "type": "object",
39
- "properties": {
40
- "name": {
41
- "type": "string"
42
- },
43
- "config": {
44
- "$ref": "#/definitions/config::tls_config"
45
- }
46
- }
47
- },
48
- "config::tls_config": {
49
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/config/tls_config.h#L49",
50
- "type": "object",
51
- "properties": {
52
- "enabled": {
53
- "type": "boolean"
54
- },
55
- "require_client_auth": {
56
- "type": "boolean"
57
- },
58
- "key_file": {
59
- "type": "string"
60
- },
61
- "cert_file": {
62
- "type": "string"
63
- },
64
- "truststore_file": {
65
- "type": "string"
66
- }
67
- }
68
- },
69
- "tls_config": {
70
- "$ref": "#/definitions/config::tls_config"
71
- },
72
- "config::rest_authn_endpoint": {
73
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/config/rest_authn_endpoint.h#L42",
74
- "type": "object",
75
- "properties": {
76
- "name": {
77
- "type": "string"
78
- },
79
- "address": {
80
- "type": "string"
81
- },
82
- "port": {
83
- "type": "integer",
84
- "minimum": 0,
85
- "maximum": 4294967295
86
- },
87
- "authentication_method": {
88
- "$ref": "#/definitions/config::rest_authn_method"
89
- }
90
- }
91
- },
92
- "config::rest_authn_method": {
93
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/config/rest_authn_endpoint.h#L31",
94
- "enum": [
95
- "none",
96
- "http_basic"
97
- ]
98
- },
99
- "endpoint_tls_config": {
100
- "$ref": "#/definitions/config::endpoint_tls_config"
101
- },
102
- "model::broker_endpoint": {
103
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/metadata.h#L88",
104
- "type": "object",
105
- "properties": {
106
- "name": {
107
- "type": "string"
108
- },
109
- "address": {
110
- "type": "string"
111
- },
112
- "port": {
113
- "type": "integer",
114
- "minimum": 0,
115
- "maximum": 4294967295
116
- }
117
- }
118
- },
119
- "model::cleanup_policy_bitflags": {
120
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/fundamental.h#L72",
121
- "enum": [
122
- "none",
123
- "delete",
124
- "compact"
125
- ]
126
- },
127
- "model::cloud_credentials_source": {
128
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/metadata.h#L454",
129
- "enum": [
130
- "config_file",
131
- "aws_instance_metadata",
132
- "sts",
133
- "gcp_instance_metadata"
134
- ]
135
- },
136
- "model::cloud_storage_backend": {
137
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/metadata.h#L481",
138
- "enum": [
139
- "aws",
140
- "google_s3_compat",
141
- "azure",
142
- "minio",
143
- "unknown"
144
- ]
145
- },
146
- "model::cloud_storage_chunk_eviction_strategy": {
147
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/metadata.h#L524",
148
- "enum": [
149
- "eager",
150
- "capped",
151
- "predictive"
152
- ]
153
- },
154
- "model::compression": {
155
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/compression.h#L36",
156
- "enum": [
157
- "none",
158
- "gzip",
159
- "snappy",
160
- "lz4",
161
- "zstd",
162
- "producer"
163
- ]
164
- },
165
- "model::leader_balancer_mode": {
166
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/metadata.h#L504",
167
- "enum": [
168
- "greedy_balanced_shards",
169
- "random_hill_climbing"
170
- ]
171
- },
172
- "model::node_id": {
173
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/metadata.h#L36",
174
- "type": "integer",
175
- "minimum": -2147483648,
176
- "maximum": 2147483647
177
- },
178
- "model::partition_autobalancing_mode": {
179
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/metadata.h#L463",
180
- "enum": [
181
- "off",
182
- "node_add",
183
- "continuous"
184
- ]
185
- },
186
- "model::rack_id": {
187
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/metadata.h#L60",
188
- "type": "string"
189
- },
190
- "model::timestamp_type": {
191
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/model/timestamp.h#L30",
192
- "enum": [
193
- "create_time",
194
- "append_time"
195
- ]
196
- },
197
- "net::unresolved_address": {
198
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/net/unresolved_address.h#L27",
199
- "properties": {
200
- "address": {
201
- "type": "string"
202
- },
203
- "port": {
204
- "type": "integer",
205
- "minimum": 0,
206
- "maximum": 4294967295
207
- }
208
- }
209
- },
210
- "pandaproxy::schema_registry::schema_id_validation_mode": {
211
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/pandaproxy/schema_registry/schema_id_validation.h#L22",
212
- "enum": [
213
- "none",
214
- "redpanda",
215
- "compat"
216
- ]
217
- },
218
- "retention_duration_property": {
219
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/config/property.h#L878",
220
- "type": "integer",
221
- "minimum": -2147483648,
222
- "maximum": 2147483647
223
- },
224
- "seed_server": {
225
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/config/seed_server.h#L24",
226
- "type": "object",
227
- "properties": {
228
- "host": {
229
- "$ref": "#/definitions/net::unresolved_address"
230
- }
231
- }
232
- },
233
- "throughput_control_group": {
234
- "defined_in": "https://github.com/redpanda-data/redpanda/blob/dev/src/v/config/throughput_control_group.h#L36",
235
- "type": "object",
236
- "properties": {
237
- "name": {
238
- "type": "string"
239
- },
240
- "client_id": {
241
- "type": "string"
242
- }
243
- }
244
- }
245
- }