|
47 | 47 | const data = yaml.load(fs.readFileSync(dataPath, 'utf-8'));
|
48 | 48 | const ajv = new Ajv({ allErrors: true });
|
49 | 49 | addFormats(ajv);
|
| 50 | +
|
| 51 | + ajv.addKeyword({ |
| 52 | + keyword: 'caseInsensitiveUnique', |
| 53 | + type: 'array', |
| 54 | + validate: function (schema, data) { |
| 55 | + if (!Array.isArray(data)) return false; |
| 56 | + |
| 57 | + const languagesSet = new Set(); |
| 58 | + const languagesLowercaseSet = new Set(); |
| 59 | + data.forEach((tool) => { |
| 60 | + if (tool.languages) { |
| 61 | + tool.languages.forEach((language) => { |
| 62 | + languagesSet.add(language); |
| 63 | + languagesLowercaseSet.add(language.toLowerCase()); |
| 64 | + }); |
| 65 | + } |
| 66 | + }); |
| 67 | + if (languagesSet.size !== languagesLowercaseSet.size) { |
| 68 | + console.error('Duplicate languages found'); |
| 69 | + const lowercaseMap = new Map(); |
| 70 | + languagesSet.forEach((language) => { |
| 71 | + lowercaseMap.set( |
| 72 | + language.toLowerCase(), |
| 73 | + (lowercaseMap.get(language.toLowerCase()) || 0) + 1 |
| 74 | + ); |
| 75 | + }); |
| 76 | + |
| 77 | + lowercaseMap.forEach((value, key) => { |
| 78 | + if (value > 1) { |
| 79 | + console.log('Duplicate found for:', key); |
| 80 | + } |
| 81 | + }); |
| 82 | + validate.errors = [{ |
| 83 | + keyword: 'caseInsensitiveUnique', |
| 84 | + message: 'array contains case-insensitive duplicates', |
| 85 | + params: { keyword: 'caseInsensitiveUnique' } |
| 86 | + }]; |
| 87 | + return false; |
| 88 | + } |
| 89 | + return true; |
| 90 | + } |
| 91 | + }); |
| 92 | +
|
50 | 93 | const validate = ajv.compile(schema);
|
51 | 94 | const valid = validate(data);
|
52 | 95 | if (!valid) {
|
|
0 commit comments