@redpanda-data/docs-extensions-and-macros 4.12.0 ā 4.12.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.
package/bin/doc-tools.js
CHANGED
|
@@ -719,6 +719,18 @@ automation
|
|
|
719
719
|
fs.unlinkSync(tmpFile);
|
|
720
720
|
dataFile = finalFile;
|
|
721
721
|
console.log(`ā
Fetched and saved: ${finalFile}`);
|
|
722
|
+
|
|
723
|
+
// Keep only 2 most recent versions in docs-data
|
|
724
|
+
const dataFiles = fs.readdirSync(dataDir)
|
|
725
|
+
.filter(f => /^connect-\d+\.\d+\.\d+\.json$/.test(f))
|
|
726
|
+
.sort();
|
|
727
|
+
|
|
728
|
+
while (dataFiles.length > 2) {
|
|
729
|
+
const oldestFile = dataFiles.shift();
|
|
730
|
+
const oldestPath = path.join(dataDir, oldestFile);
|
|
731
|
+
fs.unlinkSync(oldestPath);
|
|
732
|
+
console.log(`š§¹ Deleted old version from docs-data: ${oldestFile}`);
|
|
733
|
+
}
|
|
722
734
|
} catch (err) {
|
|
723
735
|
console.error(`ā Failed to fetch connectors: ${err.message}`);
|
|
724
736
|
process.exit(1);
|
|
@@ -845,6 +857,45 @@ automation
|
|
|
845
857
|
}
|
|
846
858
|
|
|
847
859
|
const newIndex = JSON.parse(fs.readFileSync(dataFile, 'utf8'));
|
|
860
|
+
|
|
861
|
+
// Publish merged version with overrides to modules/components/attachments
|
|
862
|
+
if (options.overrides && fs.existsSync(options.overrides)) {
|
|
863
|
+
try {
|
|
864
|
+
const { mergeOverrides, resolveReferences } = require('../tools/redpanda-connect/generate-rpcn-connector-docs.js');
|
|
865
|
+
|
|
866
|
+
// Create a copy of newIndex to merge overrides into
|
|
867
|
+
const mergedData = JSON.parse(JSON.stringify(newIndex));
|
|
868
|
+
|
|
869
|
+
// Read and apply overrides
|
|
870
|
+
const ovRaw = fs.readFileSync(options.overrides, 'utf8');
|
|
871
|
+
const ovObj = JSON.parse(ovRaw);
|
|
872
|
+
const resolvedOverrides = resolveReferences(ovObj, ovObj);
|
|
873
|
+
mergeOverrides(mergedData, resolvedOverrides);
|
|
874
|
+
|
|
875
|
+
// Publish to modules/components/attachments
|
|
876
|
+
const attachmentsRoot = path.resolve(process.cwd(), 'modules/components/attachments');
|
|
877
|
+
fs.mkdirSync(attachmentsRoot, { recursive: true });
|
|
878
|
+
|
|
879
|
+
// Delete older versions from modules/components/attachments
|
|
880
|
+
const existingFiles = fs.readdirSync(attachmentsRoot)
|
|
881
|
+
.filter(f => /^connect-\d+\.\d+\.\d+\.json$/.test(f))
|
|
882
|
+
.sort();
|
|
883
|
+
|
|
884
|
+
for (const oldFile of existingFiles) {
|
|
885
|
+
const oldFilePath = path.join(attachmentsRoot, oldFile);
|
|
886
|
+
fs.unlinkSync(oldFilePath);
|
|
887
|
+
console.log(`š§¹ Deleted old version: ${oldFile}`);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// Save merged version to modules/components/attachments
|
|
891
|
+
const destFile = path.join(attachmentsRoot, `connect-${newVersion}.json`);
|
|
892
|
+
fs.writeFileSync(destFile, JSON.stringify(mergedData, null, 2), 'utf8');
|
|
893
|
+
console.log(`ā
Published merged version to: ${path.relative(process.cwd(), destFile)}`);
|
|
894
|
+
} catch (err) {
|
|
895
|
+
console.error(`ā Failed to publish merged version: ${err.message}`);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
|
|
848
899
|
printDeltaReport(oldIndex, newIndex);
|
|
849
900
|
|
|
850
901
|
// Generate JSON diff file for whats-new.adoc
|
|
@@ -895,6 +946,93 @@ automation
|
|
|
895
946
|
|
|
896
947
|
// Optionally update whats-new.adoc
|
|
897
948
|
if (options.updateWhatsNew) {
|
|
949
|
+
// Helper function to cap description to two sentences
|
|
950
|
+
const capToTwoSentences = (description) => {
|
|
951
|
+
if (!description) return '';
|
|
952
|
+
|
|
953
|
+
// Helper to check if text contains problematic content
|
|
954
|
+
const hasProblematicContent = (text) => {
|
|
955
|
+
return /```[\s\S]*?```/.test(text) || // code blocks
|
|
956
|
+
/`[^`]+`/.test(text) || // inline code
|
|
957
|
+
/^[=#]+\s+.+$/m.test(text) || // headings
|
|
958
|
+
/\n/.test(text); // newlines
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
// Step 1: Replace common abbreviations and ellipses with placeholders
|
|
962
|
+
const abbreviations = [
|
|
963
|
+
/\bv\d+\.\d+(?:\.\d+)?/gi, // version numbers like v4.12 or v4.12.0 (must come before decimal)
|
|
964
|
+
/\d+\.\d+/g, // decimal numbers
|
|
965
|
+
/\be\.g\./gi, // e.g.
|
|
966
|
+
/\bi\.e\./gi, // i.e.
|
|
967
|
+
/\betc\./gi, // etc.
|
|
968
|
+
/\bvs\./gi, // vs.
|
|
969
|
+
/\bDr\./gi, // Dr.
|
|
970
|
+
/\bMr\./gi, // Mr.
|
|
971
|
+
/\bMs\./gi, // Ms.
|
|
972
|
+
/\bMrs\./gi, // Mrs.
|
|
973
|
+
/\bSt\./gi, // St.
|
|
974
|
+
/\bNo\./gi // No.
|
|
975
|
+
];
|
|
976
|
+
|
|
977
|
+
let normalized = description;
|
|
978
|
+
const placeholders = [];
|
|
979
|
+
|
|
980
|
+
// Replace abbreviations with placeholders
|
|
981
|
+
abbreviations.forEach((abbrevRegex, idx) => {
|
|
982
|
+
normalized = normalized.replace(abbrevRegex, (match) => {
|
|
983
|
+
const placeholder = `__ABBREV${idx}_${placeholders.length}__`;
|
|
984
|
+
placeholders.push({ placeholder, original: match });
|
|
985
|
+
return placeholder;
|
|
986
|
+
});
|
|
987
|
+
});
|
|
988
|
+
|
|
989
|
+
// Replace ellipses (three or more dots) with placeholder
|
|
990
|
+
normalized = normalized.replace(/\.{3,}/g, (match) => {
|
|
991
|
+
const placeholder = `__ELLIPSIS_${placeholders.length}__`;
|
|
992
|
+
placeholders.push({ placeholder, original: match });
|
|
993
|
+
return placeholder;
|
|
994
|
+
});
|
|
995
|
+
|
|
996
|
+
// Step 2: Split sentences using the regex
|
|
997
|
+
const sentenceRegex = /[^.!?]+[.!?]+(?:\s|$)/g;
|
|
998
|
+
const sentences = normalized.match(sentenceRegex);
|
|
999
|
+
|
|
1000
|
+
if (!sentences || sentences.length === 0) {
|
|
1001
|
+
// Restore placeholders and return original
|
|
1002
|
+
let result = normalized;
|
|
1003
|
+
placeholders.forEach(({ placeholder, original }) => {
|
|
1004
|
+
result = result.replace(placeholder, original);
|
|
1005
|
+
});
|
|
1006
|
+
return result;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
// Step 3: Determine how many sentences to include
|
|
1010
|
+
let maxSentences = 2;
|
|
1011
|
+
|
|
1012
|
+
// If we have at least 2 sentences, check if the second one has problematic content
|
|
1013
|
+
if (sentences.length >= 2) {
|
|
1014
|
+
// Restore placeholders in second sentence to check original content
|
|
1015
|
+
let secondSentence = sentences[1];
|
|
1016
|
+
placeholders.forEach(({ placeholder, original }) => {
|
|
1017
|
+
secondSentence = secondSentence.replace(new RegExp(placeholder, 'g'), original);
|
|
1018
|
+
});
|
|
1019
|
+
|
|
1020
|
+
// If second sentence has problematic content, only take first sentence
|
|
1021
|
+
if (hasProblematicContent(secondSentence)) {
|
|
1022
|
+
maxSentences = 1;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
let result = sentences.slice(0, maxSentences).join('');
|
|
1027
|
+
|
|
1028
|
+
// Step 4: Restore placeholders back to original text
|
|
1029
|
+
placeholders.forEach(({ placeholder, original }) => {
|
|
1030
|
+
result = result.replace(new RegExp(placeholder, 'g'), original);
|
|
1031
|
+
});
|
|
1032
|
+
|
|
1033
|
+
return result.trim();
|
|
1034
|
+
};
|
|
1035
|
+
|
|
898
1036
|
try {
|
|
899
1037
|
const whatsNewPath = path.join(findRepoRoot(), 'modules/get-started/pages/whats-new.adoc');
|
|
900
1038
|
if (!fs.existsSync(whatsNewPath)) {
|
|
@@ -956,7 +1094,7 @@ automation
|
|
|
956
1094
|
for (const comp of comps) {
|
|
957
1095
|
section += `** xref:components:${type}/${comp.name}.adoc[\`${comp.name}\`]`;
|
|
958
1096
|
if (comp.status) section += ` (${comp.status})`;
|
|
959
|
-
if (comp.description) section += `: ${comp.description}`;
|
|
1097
|
+
if (comp.description) section += `: ${capToTwoSentences(comp.description)}`;
|
|
960
1098
|
section += '\n';
|
|
961
1099
|
}
|
|
962
1100
|
}
|
|
@@ -977,6 +1115,60 @@ automation
|
|
|
977
1115
|
description: field.description || '',
|
|
978
1116
|
});
|
|
979
1117
|
}
|
|
1118
|
+
for (const [type, fields] of Object.entries(fieldsByType)) {
|
|
1119
|
+
section += `* ${type.charAt(0).toUpperCase() + type.slice(1)}:\n`;
|
|
1120
|
+
// Group by component name
|
|
1121
|
+
const byComp = {};
|
|
1122
|
+
for (const f of fields) {
|
|
1123
|
+
if (!byComp[f.compName]) byComp[f.compName] = [];
|
|
1124
|
+
byComp[f.compName].push(f);
|
|
1125
|
+
}
|
|
1126
|
+
for (const [comp, compFields] of Object.entries(byComp)) {
|
|
1127
|
+
section += `** xref:components:${type}/${comp}.adoc[\`${comp}\`]:`;
|
|
1128
|
+
section += '\n';
|
|
1129
|
+
for (const f of compFields) {
|
|
1130
|
+
section += `*** xref:components:${type}/${comp}.adoc#${f.field}[\`${f.field}\`]`;
|
|
1131
|
+
if (f.description) section += `: ${capToTwoSentences(f.description)}`;
|
|
1132
|
+
section += '\n';
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
// Deprecated components
|
|
1139
|
+
if (diff.details.deprecatedComponents && diff.details.deprecatedComponents.length) {
|
|
1140
|
+
section += '\n=== Deprecations\n\n';
|
|
1141
|
+
section += 'The following components are now deprecated:\n\n';
|
|
1142
|
+
// Group by type
|
|
1143
|
+
const byType = {};
|
|
1144
|
+
for (const comp of diff.details.deprecatedComponents) {
|
|
1145
|
+
if (!byType[comp.type]) byType[comp.type] = [];
|
|
1146
|
+
byType[comp.type].push(comp);
|
|
1147
|
+
}
|
|
1148
|
+
for (const [type, comps] of Object.entries(byType)) {
|
|
1149
|
+
section += `* ${type.charAt(0).toUpperCase() + type.slice(1)}:\n`;
|
|
1150
|
+
for (const comp of comps) {
|
|
1151
|
+
section += `** xref:components:${type}/${comp.name}.adoc[\`${comp.name}\`]\n`;
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
|
|
1156
|
+
// Deprecated fields
|
|
1157
|
+
if (diff.details.deprecatedFields && diff.details.deprecatedFields.length) {
|
|
1158
|
+
if (!diff.details.deprecatedComponents || diff.details.deprecatedComponents.length === 0) {
|
|
1159
|
+
section += '\n=== Deprecations\n\n';
|
|
1160
|
+
}
|
|
1161
|
+
section += '\nThe following fields are now deprecated:\n\n';
|
|
1162
|
+
// Group deprecated fields by component type
|
|
1163
|
+
const fieldsByType = {};
|
|
1164
|
+
for (const field of diff.details.deprecatedFields) {
|
|
1165
|
+
const [type, compName] = field.component.split(':');
|
|
1166
|
+
if (!fieldsByType[type]) fieldsByType[type] = [];
|
|
1167
|
+
fieldsByType[type].push({
|
|
1168
|
+
compName,
|
|
1169
|
+
field: field.field
|
|
1170
|
+
});
|
|
1171
|
+
}
|
|
980
1172
|
for (const [type, fields] of Object.entries(fieldsByType)) {
|
|
981
1173
|
section += `* ${type.charAt(0).toUpperCase() + type.slice(1)} components\n`;
|
|
982
1174
|
// Group by component name
|
|
@@ -986,23 +1178,20 @@ automation
|
|
|
986
1178
|
byComp[f.compName].push(f);
|
|
987
1179
|
}
|
|
988
1180
|
for (const [comp, compFields] of Object.entries(byComp)) {
|
|
989
|
-
section += `** xref:components:${type}/${comp}.adoc[
|
|
1181
|
+
section += `** xref:components:${type}/${comp}.adoc[\`${comp}\`]`;
|
|
990
1182
|
if (compFields.length === 1) {
|
|
991
1183
|
const f = compFields[0];
|
|
992
|
-
section += `: xref:components:${type}/${comp}.adoc#${f.field}[
|
|
993
|
-
if (f.description) section += ` - ${f.description}`;
|
|
994
|
-
section += '\n';
|
|
1184
|
+
section += `: xref:components:${type}/${comp}.adoc#${f.field}[\`${f.field}\`]\n`;
|
|
995
1185
|
} else {
|
|
996
1186
|
section += '\n';
|
|
997
1187
|
for (const f of compFields) {
|
|
998
|
-
section += `*** xref:components:${type}/${comp}.adoc#${f.field}[
|
|
999
|
-
if (f.description) section += ` - ${f.description}`;
|
|
1000
|
-
section += '\n';
|
|
1188
|
+
section += `*** xref:components:${type}/${comp}.adoc#${f.field}[\`${f.field}\`]\n`;
|
|
1001
1189
|
}
|
|
1002
1190
|
}
|
|
1003
1191
|
}
|
|
1004
1192
|
}
|
|
1005
1193
|
}
|
|
1194
|
+
|
|
1006
1195
|
let updated;
|
|
1007
1196
|
if (startIdx !== -1) {
|
|
1008
1197
|
// Replace the existing section
|
package/package.json
CHANGED
|
@@ -138,7 +138,57 @@ 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
|
-
|
|
141
|
+
child.examples.forEach(example => {
|
|
142
|
+
if (Array.isArray(example)) {
|
|
143
|
+
// Check if array contains any objects
|
|
144
|
+
const hasObjects = example.some(item => typeof item === 'object' && item !== null);
|
|
145
|
+
|
|
146
|
+
if (hasObjects) {
|
|
147
|
+
// Use block style for arrays of objects
|
|
148
|
+
block += renderYamlList(child.name, [example]);
|
|
149
|
+
} else {
|
|
150
|
+
// Use flow style for arrays of primitives: fieldName: [item1, item2, ...]
|
|
151
|
+
const items = example.map(item => {
|
|
152
|
+
if (typeof item === 'string') {
|
|
153
|
+
// Check if already quoted (starts and ends with quotes)
|
|
154
|
+
const alreadyQuoted = item.startsWith('"') && item.endsWith('"');
|
|
155
|
+
|
|
156
|
+
if (alreadyQuoted) {
|
|
157
|
+
// Already quoted, return as-is
|
|
158
|
+
return item;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Check if quoting is needed
|
|
162
|
+
const needsQuoting = item === '' ||
|
|
163
|
+
item === '*' ||
|
|
164
|
+
/^(true|false|null|yes|no|on|off)$/i.test(item) ||
|
|
165
|
+
/^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/.test(item) ||
|
|
166
|
+
/[:\[\]\{\},&>|%@`"]/.test(item) ||
|
|
167
|
+
/\s/.test(item); // any whitespace
|
|
168
|
+
|
|
169
|
+
if (needsQuoting) {
|
|
170
|
+
// Escape backslashes first, then double quotes
|
|
171
|
+
const escaped = item.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
172
|
+
return `"${escaped}"`;
|
|
173
|
+
}
|
|
174
|
+
return item;
|
|
175
|
+
}
|
|
176
|
+
// For primitives (numbers, booleans, etc.), convert to string
|
|
177
|
+
const strValue = String(item);
|
|
178
|
+
// Check if the stringified value needs quoting
|
|
179
|
+
if (/[:\[\]\{\},&>|%@`"]/.test(strValue) || /\s/.test(strValue)) {
|
|
180
|
+
const escaped = strValue.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
181
|
+
return `"${escaped}"`;
|
|
182
|
+
}
|
|
183
|
+
return strValue;
|
|
184
|
+
});
|
|
185
|
+
block += `${child.name}: [${items.join(', ')}]\n`;
|
|
186
|
+
}
|
|
187
|
+
} else {
|
|
188
|
+
// Fallback for non-array examples (shouldn't happen for array fields)
|
|
189
|
+
block += `${child.name}: ${example}\n`;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
142
192
|
} else {
|
|
143
193
|
child.examples.forEach(example => {
|
|
144
194
|
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 = {
|