color-name-list 11.25.0 → 12.0.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 (40) hide show
  1. package/.vscode/tasks.json +48 -0
  2. package/README.md +5 -3
  3. package/changes.svg +3 -3
  4. package/dist/colornames.bestof.csv +24 -21
  5. package/dist/colornames.bestof.esm.js +1 -1
  6. package/dist/colornames.bestof.esm.mjs +1 -1
  7. package/dist/colornames.bestof.html +1 -1
  8. package/dist/colornames.bestof.json +1 -1
  9. package/dist/colornames.bestof.min.json +1 -1
  10. package/dist/colornames.bestof.scss +1 -1
  11. package/dist/colornames.bestof.umd.js +1 -1
  12. package/dist/colornames.bestof.xml +73 -61
  13. package/dist/colornames.bestof.yaml +57 -48
  14. package/dist/colornames.csv +49 -212
  15. package/dist/colornames.esm.js +1 -1
  16. package/dist/colornames.esm.mjs +1 -1
  17. package/dist/colornames.html +1 -1
  18. package/dist/colornames.json +1 -1
  19. package/dist/colornames.min.json +1 -1
  20. package/dist/colornames.scss +1 -1
  21. package/dist/colornames.short.csv +17 -17
  22. package/dist/colornames.short.esm.js +1 -1
  23. package/dist/colornames.short.esm.mjs +1 -1
  24. package/dist/colornames.short.html +1 -1
  25. package/dist/colornames.short.json +1 -1
  26. package/dist/colornames.short.min.json +1 -1
  27. package/dist/colornames.short.scss +1 -1
  28. package/dist/colornames.short.umd.js +1 -1
  29. package/dist/colornames.short.xml +54 -54
  30. package/dist/colornames.short.yaml +42 -42
  31. package/dist/colornames.umd.js +1 -1
  32. package/dist/colornames.xml +119 -771
  33. package/dist/colornames.yaml +96 -585
  34. package/dist/history.json +1 -1
  35. package/package.json +1 -1
  36. package/scripts/build.js +15 -2
  37. package/scripts/lib.js +55 -0
  38. package/src/colornames.csv +57 -220
  39. package/tests/duplicate-allowlist.json +12 -0
  40. package/tests/duplicates.test.js +70 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "color-name-list",
3
- "version": "11.25.0",
3
+ "version": "12.0.0",
4
4
  "description": "long list of color names",
5
5
  "main": "dist/colornames.json",
6
6
  "browser": "dist/colornames.umd.js",
package/scripts/build.js CHANGED
@@ -80,11 +80,13 @@ colorsSrc.values['name'].forEach((name) => {
80
80
  colorsSrc.values[bestOfKey].forEach((str) => {
81
81
  // check for spaces
82
82
  if (spacesValidation.test(str)) {
83
- log(`"${bestOfKey}" marker'`, str, `${str} found either a leading or trailing space (or both)`);
83
+ // Use the actual CSV key so we can resolve the offending entries (names)
84
+ log(bestOfKey, str, `${str} found either a leading or trailing space (or both)`);
84
85
  }
85
86
 
86
87
  if (!(str == 'x' || str == '')) {
87
- log(`"${bestOfKey}" marker`, str, `${str} must be a lowercase "x" character or empty`);
88
+ // Use the actual CSV key so we can resolve the offending entries (names)
89
+ log(bestOfKey, str, `${str} must be a lowercase "x" character or empty`);
88
90
  }
89
91
  });
90
92
 
@@ -383,6 +385,17 @@ function showLog() {
383
385
  totalErrors = i + 1;
384
386
  errorLevel = error.errorLevel || errorLevel;
385
387
  console.log(`${error.errorLevel ? '⛔' : '⚠'} ${error.message}`);
388
+ if (Array.isArray(error.entries) && error.entries.length) {
389
+ // Print a concise list of offending names for quick scanning
390
+ const nameList = error.entries
391
+ .map((e) => (e && e.name ? `${e.name}${e.hex ? ` (${e.hex})` : ''}` : ''))
392
+ .filter(Boolean)
393
+ .join(', ');
394
+ if (nameList) {
395
+ console.log(`Offending name(s): ${nameList}`);
396
+ }
397
+ }
398
+ // Keep the JSON dump for full context
386
399
  console.log(JSON.stringify(error.entries));
387
400
  console.log('*-------------------------*');
388
401
  });
package/scripts/lib.js CHANGED
@@ -104,3 +104,58 @@ export const objArrToString = (arr, keys, options) => {
104
104
  settings.insertAfter
105
105
  );
106
106
  };
107
+
108
+ /**
109
+ * Normalize a color name to detect near-duplicates.
110
+ * - Lowercase
111
+ * - Strip diacritics
112
+ * - Remove all non-alphanumeric characters
113
+ * Examples:
114
+ * "Snow Pink" -> "Snowpink"
115
+ * @param {string} name
116
+ * @return {string}
117
+ */
118
+ export const normalizeNameForDuplicates = (name) => {
119
+ return String(name)
120
+ .toLowerCase()
121
+ .normalize('NFD')
122
+ .replace(/[\u0300-\u036f]/g, '')
123
+ .replace(/[^a-z0-9]/g, '');
124
+ };
125
+
126
+ /**
127
+ * Given a list of items with a name and optional lineNumber, find groups of
128
+ * near-duplicate names that collapse to the same normalized key.
129
+ *
130
+ * @param {Array<{name:string, lineNumber?:number}>} items
131
+ * @returns {Array<{norm:string, entries:Array<{name:string, lineNumber?:number}>}>}
132
+ */
133
+ export const findNearDuplicateNameConflicts = (items, options = {}) => {
134
+ const { allowlist = [] } = options;
135
+
136
+ // Normalize allowlist entries so callers can provide raw names or already-normalized keys.
137
+ const allowSet = new Set(
138
+ (Array.isArray(allowlist) ? allowlist : [])
139
+ .filter((v) => typeof v === 'string' && v.trim().length)
140
+ .map((v) => normalizeNameForDuplicates(String(v)))
141
+ );
142
+
143
+ const byNorm = new Map();
144
+ for (const item of items) {
145
+ if (!item || typeof item.name !== 'string') continue;
146
+ const norm = normalizeNameForDuplicates(item.name);
147
+ if (!byNorm.has(norm)) byNorm.set(norm, []);
148
+ byNorm.get(norm).push({ name: item.name, lineNumber: item.lineNumber });
149
+ }
150
+
151
+ const conflicts = [];
152
+ for (const [norm, arr] of byNorm.entries()) {
153
+ if (allowSet.has(norm)) continue; // explicitly allowed
154
+ const uniqueNames = Array.from(new Set(arr.map((x) => x.name)));
155
+ if (uniqueNames.length > 1) {
156
+ conflicts.push({ norm, entries: arr });
157
+ }
158
+ }
159
+
160
+ return conflicts;
161
+ };