color-name-list 13.1.0 → 13.2.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 (41) hide show
  1. package/README.md +48 -2
  2. package/changes.svg +3 -3
  3. package/dist/colornames.bestof.csv +6 -2
  4. package/dist/colornames.bestof.esm.js +1 -1
  5. package/dist/colornames.bestof.esm.mjs +1 -1
  6. package/dist/colornames.bestof.html +1 -1
  7. package/dist/colornames.bestof.json +1 -1
  8. package/dist/colornames.bestof.min.json +1 -1
  9. package/dist/colornames.bestof.scss +1 -1
  10. package/dist/colornames.bestof.umd.js +1 -1
  11. package/dist/colornames.bestof.xml +18 -2
  12. package/dist/colornames.bestof.yaml +14 -2
  13. package/dist/colornames.csv +9 -6
  14. package/dist/colornames.esm.js +1 -1
  15. package/dist/colornames.esm.mjs +1 -1
  16. package/dist/colornames.html +1 -1
  17. package/dist/colornames.json +1 -1
  18. package/dist/colornames.min.json +1 -1
  19. package/dist/colornames.scss +1 -1
  20. package/dist/colornames.short.csv +4 -2
  21. package/dist/colornames.short.esm.js +1 -1
  22. package/dist/colornames.short.esm.mjs +1 -1
  23. package/dist/colornames.short.html +1 -1
  24. package/dist/colornames.short.json +1 -1
  25. package/dist/colornames.short.min.json +1 -1
  26. package/dist/colornames.short.scss +1 -1
  27. package/dist/colornames.short.umd.js +1 -1
  28. package/dist/colornames.short.xml +10 -2
  29. package/dist/colornames.short.yaml +8 -2
  30. package/dist/colornames.umd.js +1 -1
  31. package/dist/colornames.xml +27 -15
  32. package/dist/colornames.yaml +21 -12
  33. package/dist/history.json +1 -1
  34. package/package.json +1 -1
  35. package/scripts/lib.js +2 -1
  36. package/src/colornames.csv +9 -6
  37. package/tests/duplicates.test.js +35 -16
  38. package/tests/title-case.test.js +82 -18
  39. package/vitest.config.js +5 -0
  40. /package/tests/{formats.test.js → formats.ci.test.js} +0 -0
  41. /package/tests/{imports.test.js → imports.ci.test.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "color-name-list",
3
- "version": "13.1.0",
3
+ "version": "13.2.0",
4
4
  "description": "long list of color names",
5
5
  "main": "dist/colornames.json",
6
6
  "browser": "dist/colornames.umd.js",
package/scripts/lib.js CHANGED
@@ -160,7 +160,8 @@ export const findNearDuplicateNameConflicts = (items, options = {}) => {
160
160
  .normalize('NFD')
161
161
  .replace(/[\u0300-\u036f]/g, '');
162
162
  const tokens = base.match(/[a-z0-9]+/g) || [];
163
- const filtered = foldStopwords && stopSet && stopSet.size ? tokens.filter((t) => !stopSet.has(t)) : tokens;
163
+ const filtered =
164
+ foldStopwords && stopSet && stopSet.size ? tokens.filter((t) => !stopSet.has(t)) : tokens;
164
165
  return filtered.length ? filtered.join('') : normalizeNameForDuplicates(name);
165
166
  };
166
167
 
@@ -215,8 +215,6 @@ Afternoon Stroll,#d9c5a1,
215
215
  Afternoon Tea,#594e40,
216
216
  Agapanthus,#bbc5de,
217
217
  Agate Brown,#956a60,
218
- Agate Green,#52928d,
219
- Agate Grey,#acaa99,
220
218
  Agate Violet,#5a5b74,
221
219
  Agave,#879d99,
222
220
  Agave Frond,#5a6e6a,
@@ -1014,7 +1012,7 @@ April Sunshine,#fbe198,
1014
1012
  April Tears,#b4cbd4,
1015
1013
  April Wedding,#c5cfb1,
1016
1014
  April Winds,#d5e2e5,
1017
- Aqua,#00ffff,x
1015
+ Aqua,#0ff0fe,x
1018
1016
  Aqua Bay,#b5dfc9,
1019
1017
  Aqua Belt,#7acad0,
1020
1018
  Aqua Bloom,#96d3d8,
@@ -1923,6 +1921,7 @@ Barberry Bush,#d2c61f,
1923
1921
  Barberry Sand,#e1d4bc,
1924
1922
  Barberry Yellow,#f3bd32,
1925
1923
  Barbie Pink,#fe46a5,
1924
+ Barbiecore,#e15acb,x
1926
1925
  Barcelona Beige,#c4b39c,
1927
1926
  Barcelona Brown,#926a46,
1928
1927
  Barcelona Orange,#ff9500,
@@ -6975,7 +6974,7 @@ Cuticle Pink,#e3a49a,
6975
6974
  Cutlery Polish,#f4dda5,
6976
6975
  Cuttlefish,#7fbbc2,x
6977
6976
  Cutty Sark,#5c8173,
6978
- Cyan,#0ff0fe,x
6977
+ Cyan,#00ffff,x
6979
6978
  Cyan Azure,#4e82b4,
6980
6979
  Cyan Blue,#14a3c7,
6981
6980
  Cyan Cobalt Blue,#28589c,
@@ -7792,6 +7791,7 @@ Dig It,#8e6e57,
7792
7791
  Digger’s Gold,#a37336,
7793
7792
  Digital,#636365,
7794
7793
  Digital Garage,#b7b3a4,
7794
+ Digital Lavender,#cac0e1,x
7795
7795
  Digital Violets,#aa00ff,
7796
7796
  Digital Yellow,#ffeb7e,
7797
7797
  Dignified,#3b695f,
@@ -10683,6 +10683,7 @@ Gemini,#b4d6cb,
10683
10683
  Gemini Mustard Momento,#fca750,
10684
10684
  Gemstone Blue,#004f6d,
10685
10685
  Gemstone Green,#4b6331,
10686
+ Gen Z Yellow,#f4e386,
10686
10687
  Generic Viridian,#007f66,
10687
10688
  Genestealer Purple,#7761ab,
10688
10689
  Genetic Code,#18515d,
@@ -11519,7 +11520,7 @@ Green,#00ff00,x
11519
11520
  Green 383,#3e3d29,
11520
11521
  Green Acres,#53a144,
11521
11522
  Green Adirondack,#688878,
11522
- Green Agate,#3f6253,
11523
+ Green Agate,#52928d,
11523
11524
  Green Alabaster,#c8ccba,
11524
11525
  Green Amazons,#98a893,
11525
11526
  Green Andara,#afc1a3,
@@ -11672,6 +11673,7 @@ Green Olive,#8d8b55,x
11672
11673
  Green Olive Pit,#bdaa89,
11673
11674
  Green Onion,#c1e089,
11674
11675
  Green Onyx,#989a82,
11676
+ Green Ooze,#e1fe52,x
11675
11677
  Green Papaya,#e5ce77,
11676
11678
  Green Parakeet,#7bd5bf,
11677
11679
  Green Parlor,#cfddb9,
@@ -15186,7 +15188,6 @@ Lima Green,#b1b787,
15186
15188
  Lima Sombrio,#7aac21,
15187
15189
  Limbert Leather,#988870,
15188
15190
  Lime,#aaff32,x
15189
- Lime Acid,#afff01,
15190
15191
  Lime Blossom,#f4f2d3,
15191
15192
  Lime Bright,#f1e4b0,
15192
15193
  Lime Cake,#dae3d0,
@@ -16808,6 +16809,7 @@ Milky Yellow,#f8dd74,
16808
16809
  Mill Creek,#876e59,
16809
16810
  Millbrook,#595648,
16810
16811
  Mille-Feuille,#efc87d,x
16812
+ Millennial Grey,#7b7b7d,
16811
16813
  Millennial Pink,#f6c8c1,x
16812
16814
  Millennium Silver,#8c9595,
16813
16815
  Million Grey,#999999,x
@@ -20832,6 +20834,7 @@ Popular Beige,#d4ccc3,
20832
20834
  Porcelain,#dddcdb,x
20833
20835
  Porcelain Basin,#d9d0c4,
20834
20836
  Porcelain Blue,#95c0cb,
20837
+ Porcelain Blush,#f0dbd5,x
20835
20838
  Porcelain Crab,#e9b7a8,
20836
20839
  Porcelain Earth,#eeffbb,
20837
20840
  Porcelain Figurines,#a9998c,
@@ -13,20 +13,41 @@ describe('Duplicate-like color names', () => {
13
13
 
14
14
  // Shared stopwords for normalization across tests
15
15
  const STOPWORDS = [
16
- 'of', 'the', 'and', 'a', 'an',
17
- 'in', 'on', 'at', 'to', 'for',
18
- 'by', 'with', 'from', 'as', 'is',
19
- 'it', 'this', 'that', 'these', 'those',
20
- 'be', 'are', 'was', 'were', 'or',
16
+ 'of',
17
+ 'the',
18
+ 'and',
19
+ 'a',
20
+ 'an',
21
+ 'in',
22
+ 'on',
23
+ 'at',
24
+ 'to',
25
+ 'for',
26
+ 'by',
27
+ 'with',
28
+ 'from',
29
+ 'as',
30
+ 'is',
31
+ 'it',
32
+ 'this',
33
+ 'that',
34
+ 'these',
35
+ 'those',
36
+ 'be',
37
+ 'are',
38
+ 'was',
39
+ 'were',
40
+ 'or',
21
41
  ];
22
42
 
23
43
  // Helper: normalize a phrase similar to scripts/lib normalization but keeping token boundaries
24
- const normalize = (s) => String(s)
25
- .toLowerCase()
26
- .normalize('NFD')
27
- .replace(/[\u0300-\u036f]/g, '')
28
- .replace(/[^a-z0-9]+/g, ' ')
29
- .trim();
44
+ const normalize = (s) =>
45
+ String(s)
46
+ .toLowerCase()
47
+ .normalize('NFD')
48
+ .replace(/[\u0300-\u036f]/g, '')
49
+ .replace(/[^a-z0-9]+/g, ' ')
50
+ .trim();
30
51
 
31
52
  const tokenize = (name) => {
32
53
  const base = normalize(name);
@@ -157,7 +178,8 @@ describe('Duplicate-like color names', () => {
157
178
 
158
179
  throw new Error(
159
180
  buildFailureMessage({
160
- title: 'Found {n} duplicate-like {items} (case/accents/punctuation/stopwords-insensitive):',
181
+ title:
182
+ 'Found {n} duplicate-like {items} (case/accents/punctuation/stopwords-insensitive):',
161
183
  offenders: [...allOffendingNames],
162
184
  offenderLabel: 'name',
163
185
  details: [
@@ -218,10 +240,7 @@ describe('Duplicate-like color names', () => {
218
240
  });
219
241
 
220
242
  it('should detect names that only differ by stopwords when enabled', () => {
221
- const items = [
222
- { name: 'Heart Gold' },
223
- { name: 'Heart of Gold' },
224
- ];
243
+ const items = [{ name: 'Heart Gold' }, { name: 'Heart of Gold' }];
225
244
  const conflicts = findNearDuplicateNameConflicts(items, {
226
245
  foldStopwords: true,
227
246
  stopwords: STOPWORDS,
@@ -8,7 +8,7 @@ describe('APA Title Case Validation', () => {
8
8
  csvTestData.load();
9
9
  });
10
10
 
11
- /**
11
+ /**
12
12
  * Determine if a word should be capitalized according to APA title case rules
13
13
  * @param {string} word - The word to check
14
14
  * @param {boolean} isFirstWordOrAfterPunctuation - True if this is the first word or after punctuation
@@ -16,7 +16,12 @@ describe('APA Title Case Validation', () => {
16
16
  * @param {boolean} isLastWord - True if this is the last word in the title
17
17
  * @returns {boolean} - True if the word should be capitalized
18
18
  */
19
- function shouldBeCapitalized(word, isFirstWordOrAfterPunctuation, isAfterPunctuation, isLastWord = false) {
19
+ function shouldBeCapitalized(
20
+ word,
21
+ isFirstWordOrAfterPunctuation,
22
+ isAfterPunctuation,
23
+ isLastWord = false
24
+ ) {
20
25
  // Always capitalize first words, words after punctuation, and last words
21
26
  if (isFirstWordOrAfterPunctuation || isAfterPunctuation || isLastWord) {
22
27
  return true;
@@ -30,13 +35,44 @@ describe('APA Title Case Validation', () => {
30
35
  // Short words (3 letters or fewer) that should be lowercase (unless first, after punctuation, or last)
31
36
  const minorWords = new Set([
32
37
  // Short conjunctions
33
- 'and', 'as', 'but', 'for', 'if', 'nor', 'or', 'so', 'yet',
38
+ 'and',
39
+ 'as',
40
+ 'but',
41
+ 'for',
42
+ 'if',
43
+ 'nor',
44
+ 'or',
45
+ 'so',
46
+ 'yet',
34
47
  // Articles
35
- 'a', 'an', 'the',
48
+ 'a',
49
+ 'an',
50
+ 'the',
36
51
  // Short prepositions
37
- 'at', 'by', 'in', 'of', 'off', 'on', 'per', 'to', 'up', 'via',
52
+ 'at',
53
+ 'by',
54
+ 'in',
55
+ 'of',
56
+ 'off',
57
+ 'on',
58
+ 'per',
59
+ 'to',
60
+ 'up',
61
+ 'via',
38
62
  // for short prepositions
39
- 'de', 'la', 'le', 'les', 'un', 'une', 'du', 'des', 'et', 'ou', 'à', 'au', 'aux'
63
+ 'de',
64
+ 'la',
65
+ 'le',
66
+ 'les',
67
+ 'un',
68
+ 'une',
69
+ 'du',
70
+ 'des',
71
+ 'et',
72
+ 'ou',
73
+ 'à',
74
+ 'au',
75
+ 'aux',
40
76
  ]);
41
77
 
42
78
  return !minorWords.has(word.toLowerCase());
@@ -147,12 +183,22 @@ describe('APA Title Case Validation', () => {
147
183
 
148
184
  // Patterns that suggest Los Angeles context
149
185
  const losAngelesIndicators = [
150
- 'vibes', 'style', 'sunset', 'beach', 'hollywood', 'california', 'west coast',
151
- 'city', 'metro', 'downtown', 'freeway', 'boulevard'
186
+ 'vibes',
187
+ 'style',
188
+ 'sunset',
189
+ 'beach',
190
+ 'hollywood',
191
+ 'california',
192
+ 'west coast',
193
+ 'city',
194
+ 'metro',
195
+ 'downtown',
196
+ 'freeway',
197
+ 'boulevard',
152
198
  ];
153
199
 
154
200
  // If the name contains any LA indicators, treat "la" as Los Angeles
155
- if (losAngelesIndicators.some(indicator => lowerName.includes(indicator))) {
201
+ if (losAngelesIndicators.some((indicator) => lowerName.includes(indicator))) {
156
202
  return true;
157
203
  }
158
204
 
@@ -160,7 +206,7 @@ describe('APA Title Case Validation', () => {
160
206
  const nextWord = words[wordIndex + 2]; // +2 to skip whitespace
161
207
  if (nextWord) {
162
208
  const nonFrenchPatterns = ['vibes', 'style', 'sunset', 'beach'];
163
- if (nonFrenchPatterns.some(pattern => nextWord.toLowerCase().includes(pattern))) {
209
+ if (nonFrenchPatterns.some((pattern) => nextWord.toLowerCase().includes(pattern))) {
164
210
  return true;
165
211
  }
166
212
  }
@@ -187,8 +233,8 @@ describe('APA Title Case Validation', () => {
187
233
 
188
234
  // Check for alphanumeric patterns that should stay uppercase (like model numbers)
189
235
  // Exclude ordinal numbers (1st, 2nd, 3rd, 18th, etc.)
190
- const isAlphanumericPattern = /^[0-9]+[A-Z]+$/i.test(segment) &&
191
- !/^\d+(st|nd|rd|th)$/i.test(segment);
236
+ const isAlphanumericPattern =
237
+ /^[0-9]+[A-Z]+$/i.test(segment) && !/^\d+(st|nd|rd|th)$/i.test(segment);
192
238
 
193
239
  // Handle hyphenated words - both parts should follow title case rules
194
240
  if (segment.includes('-')) {
@@ -219,11 +265,20 @@ describe('APA Title Case Validation', () => {
219
265
 
220
266
  // Check if this is the last part of the last word in the title
221
267
  const isLastPart = partIndex === parts.length - 1;
222
- const isLastWordInTitle = i === words.length - 1 || (i === words.length - 2 && /^\s+$/.test(words[words.length - 1]));
268
+ const isLastWordInTitle =
269
+ i === words.length - 1 ||
270
+ (i === words.length - 2 && /^\s+$/.test(words[words.length - 1]));
223
271
  const isLastWord = isLastPart && isLastWordInTitle;
224
272
 
225
- const shouldCap = shouldBeCapitalized(part, isFirstWord || partIndex > 0, isAfterPunctuation, isLastWord);
226
- return shouldCap ? part.charAt(0).toUpperCase() + part.slice(1).toLowerCase() : part.toLowerCase();
273
+ const shouldCap = shouldBeCapitalized(
274
+ part,
275
+ isFirstWord || partIndex > 0,
276
+ isAfterPunctuation,
277
+ isLastWord
278
+ );
279
+ return shouldCap
280
+ ? part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()
281
+ : part.toLowerCase();
227
282
  });
228
283
  result += capitalizedParts.join('-');
229
284
  } else {
@@ -242,9 +297,18 @@ describe('APA Title Case Validation', () => {
242
297
  result += 'LA';
243
298
  } else {
244
299
  // Regular word - check if this is the last non-whitespace word
245
- const isLastWordInTitle = i === words.length - 1 || (i === words.length - 2 && /^\s+$/.test(words[words.length - 1]));
246
- const shouldCap = shouldBeCapitalized(segment, isFirstWord, isAfterPunctuation, isLastWordInTitle);
247
- result += shouldCap ? segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase() : segment.toLowerCase();
300
+ const isLastWordInTitle =
301
+ i === words.length - 1 ||
302
+ (i === words.length - 2 && /^\s+$/.test(words[words.length - 1]));
303
+ const shouldCap = shouldBeCapitalized(
304
+ segment,
305
+ isFirstWord,
306
+ isAfterPunctuation,
307
+ isLastWordInTitle
308
+ );
309
+ result += shouldCap
310
+ ? segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()
311
+ : segment.toLowerCase();
248
312
  }
249
313
  }
250
314
 
package/vitest.config.js CHANGED
@@ -1,8 +1,13 @@
1
1
  import { defineConfig } from 'vitest/config';
2
2
 
3
+ // Only run heavy/dist-dependent tests in CI
4
+ const isCI = !!process.env.CI;
5
+
3
6
  export default defineConfig({
4
7
  test: {
5
8
  include: ['tests/**/*.test.js'],
9
+ // Exclude CI-only tests locally. GitHub Actions sets CI=true, so these will run in CI.
10
+ exclude: isCI ? [] : ['tests/*.ci.test.js'],
6
11
  environment: 'node',
7
12
  },
8
13
  });
File without changes
File without changes