flag-resizer 0.0.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 (384) hide show
  1. package/ATTRIBUTION.txt +25 -0
  2. package/CHANGELOG.md +11 -0
  3. package/LICENSE +21 -0
  4. package/LICENSE-GRAPHICS +56 -0
  5. package/README.md +340 -0
  6. package/dist/cli.d.ts +1 -0
  7. package/dist/cli.js +219 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/generator.js +950 -0
  10. package/dist/generator.js.map +1 -0
  11. package/dist/index.d.ts +451 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +2 -0
  14. package/flags/README.md +1 -0
  15. package/flags/ac.svg +1 -0
  16. package/flags/ad.svg +1 -0
  17. package/flags/ae.svg +1 -0
  18. package/flags/af.svg +1 -0
  19. package/flags/ag.svg +1 -0
  20. package/flags/ai.svg +1 -0
  21. package/flags/al.svg +1 -0
  22. package/flags/am.svg +1 -0
  23. package/flags/ao.svg +1 -0
  24. package/flags/aq.svg +1 -0
  25. package/flags/ar.svg +1 -0
  26. package/flags/as.svg +1 -0
  27. package/flags/at.svg +1 -0
  28. package/flags/au-act.svg +12 -0
  29. package/flags/au-nsw.svg +232 -0
  30. package/flags/au-nt.svg +40 -0
  31. package/flags/au-qld.svg +12 -0
  32. package/flags/au-sa.svg +31 -0
  33. package/flags/au-tas.svg +114 -0
  34. package/flags/au-vic.svg +191 -0
  35. package/flags/au-wa.svg +393 -0
  36. package/flags/au.svg +1 -0
  37. package/flags/aw.svg +1 -0
  38. package/flags/ax.svg +1 -0
  39. package/flags/az.svg +1 -0
  40. package/flags/ba.svg +1 -0
  41. package/flags/bb.svg +1 -0
  42. package/flags/bd.svg +1 -0
  43. package/flags/be.svg +1 -0
  44. package/flags/bf.svg +1 -0
  45. package/flags/bg.svg +1 -0
  46. package/flags/bh.svg +1 -0
  47. package/flags/bi.svg +1 -0
  48. package/flags/bj.svg +1 -0
  49. package/flags/bl.svg +1 -0
  50. package/flags/bm.svg +1 -0
  51. package/flags/bn.svg +1 -0
  52. package/flags/bo.svg +1 -0
  53. package/flags/bq.svg +1 -0
  54. package/flags/br.svg +1 -0
  55. package/flags/bs.svg +1 -0
  56. package/flags/bt.svg +1 -0
  57. package/flags/bv.svg +1 -0
  58. package/flags/bw.svg +1 -0
  59. package/flags/by.svg +1 -0
  60. package/flags/bz.svg +1 -0
  61. package/flags/ca-ab.svg +100 -0
  62. package/flags/ca-bc.svg +34 -0
  63. package/flags/ca-mb.svg +99 -0
  64. package/flags/ca-nb.svg +244 -0
  65. package/flags/ca-nl.svg +16 -0
  66. package/flags/ca-ns.svg +155 -0
  67. package/flags/ca-nt.svg +45 -0
  68. package/flags/ca-nu.svg +16 -0
  69. package/flags/ca-on.svg +31 -0
  70. package/flags/ca-pe.svg +748 -0
  71. package/flags/ca-qc.svg +20 -0
  72. package/flags/ca-sk.svg +91 -0
  73. package/flags/ca-yt.svg +81 -0
  74. package/flags/ca.svg +1 -0
  75. package/flags/cc.svg +1 -0
  76. package/flags/cd.svg +1 -0
  77. package/flags/cf.svg +1 -0
  78. package/flags/cg.svg +1 -0
  79. package/flags/ch.svg +1 -0
  80. package/flags/ci.svg +1 -0
  81. package/flags/ck.svg +1 -0
  82. package/flags/cl.svg +1 -0
  83. package/flags/cm.svg +1 -0
  84. package/flags/cn.svg +1 -0
  85. package/flags/co.svg +1 -0
  86. package/flags/cp.svg +1 -0
  87. package/flags/cq.svg +1 -0
  88. package/flags/cr.svg +1 -0
  89. package/flags/cu.svg +1 -0
  90. package/flags/cv.svg +1 -0
  91. package/flags/cw.svg +1 -0
  92. package/flags/cx.svg +1 -0
  93. package/flags/cy.svg +1 -0
  94. package/flags/cz.svg +1 -0
  95. package/flags/de-bb.svg +76 -0
  96. package/flags/de-be.svg +17 -0
  97. package/flags/de-bw.svg +12 -0
  98. package/flags/de-by.svg +16 -0
  99. package/flags/de-hb.svg +12 -0
  100. package/flags/de-he.svg +14 -0
  101. package/flags/de-hh.svg +40 -0
  102. package/flags/de-mv.svg +12 -0
  103. package/flags/de-ni.svg +86 -0
  104. package/flags/de-nw.svg +15 -0
  105. package/flags/de-rp.svg +292 -0
  106. package/flags/de-sh.svg +14 -0
  107. package/flags/de-sl.svg +279 -0
  108. package/flags/de-sn.svg +13 -0
  109. package/flags/de-st.svg +207 -0
  110. package/flags/de-th.svg +17 -0
  111. package/flags/de.svg +1 -0
  112. package/flags/dg.svg +1 -0
  113. package/flags/dj.svg +1 -0
  114. package/flags/dk.svg +1 -0
  115. package/flags/dm.svg +1 -0
  116. package/flags/do.svg +1 -0
  117. package/flags/dz.svg +1 -0
  118. package/flags/ea.svg +1 -0
  119. package/flags/ec.svg +1 -0
  120. package/flags/ee.svg +1 -0
  121. package/flags/eg.svg +1 -0
  122. package/flags/eh.svg +1 -0
  123. package/flags/er.svg +1 -0
  124. package/flags/es-an.svg +215 -0
  125. package/flags/es-ar.svg +66 -0
  126. package/flags/es-as.svg +19 -0
  127. package/flags/es-cb.svg +590 -0
  128. package/flags/es-ce.svg +357 -0
  129. package/flags/es-cl.svg +473 -0
  130. package/flags/es-cm.svg +457 -0
  131. package/flags/es-cn.svg +200 -0
  132. package/flags/es-ct.svg +13 -0
  133. package/flags/es-ex.svg +251 -0
  134. package/flags/es-ga.svg +205 -0
  135. package/flags/es-ib.svg +104 -0
  136. package/flags/es-mc.svg +32 -0
  137. package/flags/es-md.svg +29 -0
  138. package/flags/es-ml.svg +717 -0
  139. package/flags/es-nc.svg +775 -0
  140. package/flags/es-pv.svg +14 -0
  141. package/flags/es-ri.svg +787 -0
  142. package/flags/es-vc.svg +21 -0
  143. package/flags/es.svg +1 -0
  144. package/flags/et.svg +1 -0
  145. package/flags/eu.svg +1 -0
  146. package/flags/fi.svg +1 -0
  147. package/flags/fj.svg +1 -0
  148. package/flags/fk.svg +1 -0
  149. package/flags/fm.svg +1 -0
  150. package/flags/fo.svg +1 -0
  151. package/flags/fr.svg +1 -0
  152. package/flags/ga.svg +1 -0
  153. package/flags/gb-eng.svg +1 -0
  154. package/flags/gb-nir.svg +141 -0
  155. package/flags/gb-sct.svg +1 -0
  156. package/flags/gb-wls.svg +1 -0
  157. package/flags/gb.svg +1 -0
  158. package/flags/gd.svg +1 -0
  159. package/flags/ge.svg +1 -0
  160. package/flags/gf.svg +1 -0
  161. package/flags/gg.svg +1 -0
  162. package/flags/gh.svg +1 -0
  163. package/flags/gi.svg +1 -0
  164. package/flags/gl.svg +1 -0
  165. package/flags/gm.svg +1 -0
  166. package/flags/gn.svg +1 -0
  167. package/flags/gp.svg +1 -0
  168. package/flags/gq.svg +1 -0
  169. package/flags/gr.svg +1 -0
  170. package/flags/gs.svg +1 -0
  171. package/flags/gt.svg +1 -0
  172. package/flags/gu.svg +1 -0
  173. package/flags/gw.svg +1 -0
  174. package/flags/gy.svg +1 -0
  175. package/flags/hk.svg +1 -0
  176. package/flags/hm.svg +1 -0
  177. package/flags/hn.svg +1 -0
  178. package/flags/hr.svg +1 -0
  179. package/flags/ht.svg +1 -0
  180. package/flags/hu.svg +1 -0
  181. package/flags/ic.svg +1 -0
  182. package/flags/id.svg +1 -0
  183. package/flags/ie.svg +1 -0
  184. package/flags/il.svg +1 -0
  185. package/flags/im.svg +1 -0
  186. package/flags/in.svg +1 -0
  187. package/flags/io.svg +1 -0
  188. package/flags/iq.svg +1 -0
  189. package/flags/ir.svg +42 -0
  190. package/flags/is.svg +1 -0
  191. package/flags/it.svg +1 -0
  192. package/flags/je.svg +1 -0
  193. package/flags/jm.svg +1 -0
  194. package/flags/jo.svg +1 -0
  195. package/flags/jp.svg +1 -0
  196. package/flags/ke.svg +1 -0
  197. package/flags/kg.svg +1 -0
  198. package/flags/kh.svg +1 -0
  199. package/flags/ki.svg +1 -0
  200. package/flags/km.svg +1 -0
  201. package/flags/kn.svg +1 -0
  202. package/flags/kp.svg +1 -0
  203. package/flags/kr.svg +1 -0
  204. package/flags/kw.svg +1 -0
  205. package/flags/ky.svg +1 -0
  206. package/flags/kz.svg +1 -0
  207. package/flags/la.svg +1 -0
  208. package/flags/lb.svg +1 -0
  209. package/flags/lc.svg +1 -0
  210. package/flags/li.svg +1 -0
  211. package/flags/lk.svg +1 -0
  212. package/flags/lr.svg +1 -0
  213. package/flags/ls.svg +1 -0
  214. package/flags/lt.svg +1 -0
  215. package/flags/lu.svg +1 -0
  216. package/flags/lv.svg +1 -0
  217. package/flags/ly.svg +1 -0
  218. package/flags/ma.svg +1 -0
  219. package/flags/mc.svg +1 -0
  220. package/flags/md.svg +1 -0
  221. package/flags/me.svg +1 -0
  222. package/flags/mf.svg +1 -0
  223. package/flags/mg.svg +1 -0
  224. package/flags/mh.svg +1 -0
  225. package/flags/mk.svg +1 -0
  226. package/flags/ml.svg +1 -0
  227. package/flags/mm.svg +1 -0
  228. package/flags/mn.svg +1 -0
  229. package/flags/mo.svg +1 -0
  230. package/flags/mp.svg +1 -0
  231. package/flags/mq.svg +1 -0
  232. package/flags/mr.svg +1 -0
  233. package/flags/ms.svg +1 -0
  234. package/flags/mt.svg +1 -0
  235. package/flags/mu.svg +1 -0
  236. package/flags/mv.svg +1 -0
  237. package/flags/mw.svg +1 -0
  238. package/flags/mx.svg +1 -0
  239. package/flags/my.svg +1 -0
  240. package/flags/mz.svg +1 -0
  241. package/flags/na.svg +1 -0
  242. package/flags/nc.svg +1 -0
  243. package/flags/ne.svg +1 -0
  244. package/flags/nf.svg +1 -0
  245. package/flags/ng.svg +1 -0
  246. package/flags/ni.svg +1 -0
  247. package/flags/nl.svg +1 -0
  248. package/flags/no.svg +1 -0
  249. package/flags/np.svg +1 -0
  250. package/flags/nr.svg +1 -0
  251. package/flags/nu.svg +1 -0
  252. package/flags/nz.svg +1 -0
  253. package/flags/om.svg +1 -0
  254. package/flags/pa.svg +1 -0
  255. package/flags/pe.svg +1 -0
  256. package/flags/pf.svg +1 -0
  257. package/flags/pg.svg +1 -0
  258. package/flags/ph.svg +1 -0
  259. package/flags/pk.svg +1 -0
  260. package/flags/pl.svg +1 -0
  261. package/flags/pm.svg +1 -0
  262. package/flags/pn.svg +1 -0
  263. package/flags/pr.svg +1 -0
  264. package/flags/ps.svg +1 -0
  265. package/flags/pt.svg +1 -0
  266. package/flags/pw.svg +1 -0
  267. package/flags/py.svg +1 -0
  268. package/flags/qa.svg +1 -0
  269. package/flags/re.svg +1 -0
  270. package/flags/ro.svg +1 -0
  271. package/flags/rs.svg +1 -0
  272. package/flags/ru.svg +1 -0
  273. package/flags/rw.svg +1 -0
  274. package/flags/sa.svg +1 -0
  275. package/flags/sb.svg +1 -0
  276. package/flags/sc.svg +1 -0
  277. package/flags/sd.svg +1 -0
  278. package/flags/se.svg +1 -0
  279. package/flags/sg.svg +1 -0
  280. package/flags/sh.svg +1 -0
  281. package/flags/si.svg +1 -0
  282. package/flags/sj.svg +1 -0
  283. package/flags/sk.svg +1 -0
  284. package/flags/sl.svg +1 -0
  285. package/flags/sm.svg +1 -0
  286. package/flags/sn.svg +1 -0
  287. package/flags/so.svg +1 -0
  288. package/flags/sr.svg +1 -0
  289. package/flags/ss.svg +1 -0
  290. package/flags/st.svg +1 -0
  291. package/flags/sv.svg +1 -0
  292. package/flags/sx.svg +1 -0
  293. package/flags/sy.svg +1 -0
  294. package/flags/sz.svg +1 -0
  295. package/flags/ta.svg +1 -0
  296. package/flags/tc.svg +1 -0
  297. package/flags/td.svg +1 -0
  298. package/flags/tf.svg +1 -0
  299. package/flags/tg.svg +1 -0
  300. package/flags/th.svg +1 -0
  301. package/flags/tj.svg +1 -0
  302. package/flags/tk.svg +1 -0
  303. package/flags/tl.svg +1 -0
  304. package/flags/tm.svg +1 -0
  305. package/flags/tn.svg +1 -0
  306. package/flags/to.svg +1 -0
  307. package/flags/tr.svg +1 -0
  308. package/flags/tt.svg +1 -0
  309. package/flags/tv.svg +1 -0
  310. package/flags/tw.svg +1 -0
  311. package/flags/tz.svg +1 -0
  312. package/flags/ua.svg +1 -0
  313. package/flags/ug.svg +1 -0
  314. package/flags/um.svg +1 -0
  315. package/flags/un.svg +1 -0
  316. package/flags/us-ak.svg +12 -0
  317. package/flags/us-al.svg +12 -0
  318. package/flags/us-ar.svg +12 -0
  319. package/flags/us-az.svg +12 -0
  320. package/flags/us-ca.svg +12 -0
  321. package/flags/us-co.svg +12 -0
  322. package/flags/us-ct.svg +12 -0
  323. package/flags/us-de.svg +12 -0
  324. package/flags/us-fl.svg +12 -0
  325. package/flags/us-ga.svg +12 -0
  326. package/flags/us-hi.svg +12 -0
  327. package/flags/us-ia.svg +12 -0
  328. package/flags/us-id.svg +12 -0
  329. package/flags/us-il.svg +12 -0
  330. package/flags/us-in.svg +12 -0
  331. package/flags/us-ks.svg +12 -0
  332. package/flags/us-ky.svg +12 -0
  333. package/flags/us-la.svg +12 -0
  334. package/flags/us-ma.svg +12 -0
  335. package/flags/us-md.svg +12 -0
  336. package/flags/us-me.svg +12 -0
  337. package/flags/us-mi.svg +12 -0
  338. package/flags/us-mn.svg +12 -0
  339. package/flags/us-mo.svg +12 -0
  340. package/flags/us-ms.svg +12 -0
  341. package/flags/us-mt.svg +12 -0
  342. package/flags/us-nc.svg +12 -0
  343. package/flags/us-nd.svg +12 -0
  344. package/flags/us-ne.svg +12 -0
  345. package/flags/us-nh.svg +12 -0
  346. package/flags/us-nj.svg +12 -0
  347. package/flags/us-nm.svg +12 -0
  348. package/flags/us-nv.svg +12 -0
  349. package/flags/us-ny.svg +12 -0
  350. package/flags/us-oh.svg +12 -0
  351. package/flags/us-ok.svg +12 -0
  352. package/flags/us-or.svg +12 -0
  353. package/flags/us-pa.svg +12 -0
  354. package/flags/us-ri.svg +12 -0
  355. package/flags/us-sc.svg +12 -0
  356. package/flags/us-sd.svg +12 -0
  357. package/flags/us-tn.svg +12 -0
  358. package/flags/us-tx.svg +12 -0
  359. package/flags/us-ut.svg +12 -0
  360. package/flags/us-va.svg +12 -0
  361. package/flags/us-vt.svg +12 -0
  362. package/flags/us-wa.svg +12 -0
  363. package/flags/us-wi.svg +12 -0
  364. package/flags/us-wv.svg +12 -0
  365. package/flags/us-wy.svg +12 -0
  366. package/flags/us.svg +1 -0
  367. package/flags/uy.svg +1 -0
  368. package/flags/uz.svg +1 -0
  369. package/flags/va.svg +1 -0
  370. package/flags/vc.svg +1 -0
  371. package/flags/ve.svg +1 -0
  372. package/flags/vg.svg +1 -0
  373. package/flags/vi.svg +1 -0
  374. package/flags/vn.svg +1 -0
  375. package/flags/vu.svg +1 -0
  376. package/flags/wf.svg +1 -0
  377. package/flags/ws.svg +1 -0
  378. package/flags/xk.svg +1 -0
  379. package/flags/ye.svg +1 -0
  380. package/flags/yt.svg +1 -0
  381. package/flags/za.svg +1 -0
  382. package/flags/zm.svg +1 -0
  383. package/flags/zw.svg +1 -0
  384. package/package.json +113 -0
@@ -0,0 +1,25 @@
1
+ Twemoji flag graphics
2
+ Copyright (c) 2018 Twitter, Inc and other contributors.
3
+ Source: https://github.com/jdecked/twemoji
4
+ License: Creative Commons Attribution 4.0 International (CC-BY-4.0)
5
+ License URI: https://creativecommons.org/licenses/by/4.0/
6
+
7
+ The PNG and WebP files generated from the Twemoji source SVGs are resized and
8
+ re-encoded versions of those graphics.
9
+
10
+ Northern Ireland flag graphic (`gb-nir`)
11
+ Copyright (c) 2013 Panayiotis Lipiridis
12
+ Source: https://github.com/lipis/flag-icons
13
+ License: MIT
14
+
15
+ Canadian, Australian, German, and Spanish subdivision flag graphics
16
+ (`ca-*`, `au-*`, `de-*`, `es-*`)
17
+ Copyright (c) 2021 AJ McKenna
18
+ Source: https://github.com/amckenna41/iso3166-flags
19
+ License: MIT
20
+
21
+ U.S. state flag graphics (`us-*`)
22
+ Source: https://flagcdn.com/
23
+ Original vector sources: https://commons.wikimedia.org/
24
+ License status: Public domain
25
+ Status reference: https://flagpedia.net/terms
package/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ ### Changelog
2
+
3
+ All notable changes to this project will be documented in this file. Dates are displayed in UTC.
4
+
5
+ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
+
7
+ #### 0.0.1
8
+
9
+ - feat(cli): cli added [`9565d56`](https://github.com/Celtian/flag-resizer/commit/9565d56a1af0f66f7bc16697533143999d5dcd30)
10
+ - feat(flags): more flags added [`0b138f0`](https://github.com/Celtian/flag-resizer/commit/0b138f0fded8e0d5846ca865c9e8d100d57f80c0)
11
+ - chore(bun): migrated to bun [`e889d1f`](https://github.com/Celtian/flag-resizer/commit/e889d1fe3b71695fa899a416544fe198d7dd1f11)
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dominik Hladík
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,56 @@
1
+ Twemoji graphics are licensed under the Creative Commons Attribution 4.0
2
+ International license (CC-BY-4.0).
3
+
4
+ Full license text:
5
+ https://creativecommons.org/licenses/by/4.0/legalcode.txt
6
+
7
+ Source:
8
+ https://github.com/jdecked/twemoji
9
+
10
+ Copyright (c) 2018 Twitter, Inc and other contributors.
11
+
12
+ U.S. state flag graphics (`us-*.svg`)
13
+
14
+ Source:
15
+ https://flagcdn.com/
16
+
17
+ Original vector sources:
18
+ https://commons.wikimedia.org/
19
+
20
+ Flagpedia identifies its flag images as public domain and available for use
21
+ without restriction:
22
+ https://flagpedia.net/terms
23
+
24
+ Canadian, Australian, German, and Spanish subdivision flag graphics
25
+ (`ca-*.svg`, `au-*.svg`, `de-*.svg`, `es-*.svg`)
26
+
27
+ Source:
28
+ https://github.com/amckenna41/iso3166-flags
29
+
30
+ Northern Ireland flag graphic (`gb-nir.svg`)
31
+
32
+ Source:
33
+ https://github.com/lipis/flag-icons
34
+
35
+ The MIT License (MIT)
36
+
37
+ Copyright (c) 2021 AJ McKenna
38
+ Copyright (c) 2013 Panayiotis Lipiridis
39
+
40
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
41
+ this software and associated documentation files (the "Software"), to deal in
42
+ the Software without restriction, including without limitation the rights to
43
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
44
+ of the Software, and to permit persons to whom the Software is furnished to do
45
+ so, subject to the following conditions:
46
+
47
+ The above copyright notice and this permission notice shall be included in all
48
+ copies or substantial portions of the Software.
49
+
50
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
56
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,340 @@
1
+ <div align="center">
2
+
3
+ # 🏁 Flag Resizer
4
+
5
+ **Generate typed, optimized PNG and WebP flag assets from bundled SVG artwork.**
6
+
7
+ [![npm version](https://img.shields.io/npm/v/flag-resizer)](https://www.npmjs.com/package/flag-resizer)
8
+ [![Test PR](https://github.com/Celtian/flag-resizer/actions/workflows/pull-request.yml/badge.svg)](https://github.com/Celtian/flag-resizer/actions/workflows/pull-request.yml)
9
+ [![License](https://img.shields.io/github/license/Celtian/flag-resizer)](LICENSE)
10
+
11
+ [npm](https://www.npmjs.com/package/flag-resizer) · [Changelog](CHANGELOG.md) · [Source](https://github.com/Celtian/flag-resizer)
12
+
13
+ </div>
14
+
15
+ `flag-resizer` converts its bundled flag artwork into application-ready image sets.
16
+ Configure one or more profiles, choose the regions, dimensions, and formats you need, and generate
17
+ a deterministic TypeScript manifest alongside the assets.
18
+
19
+ ## ✨ Why use it?
20
+
21
+ | Feature | Details |
22
+ | --------------------------------- | ---------------------------------------------------------------------------------------------- |
23
+ | 🏳️ **Bundled flags** | Includes 369 regional and subdivision flags across Twemoji, FlagCDN, and ISO 3166-2 sources. |
24
+ | 🖼️ **Optimized image sets** | Generates PNG, WebP, or both at every configured size and quality. |
25
+ | 🧩 **Typed application paths** | Produces country, size, format, dimension, and public-path constants with a typed path helper. |
26
+ | 🎯 **Reusable profiles** | Supports independent country filters, dimensions, formats, and output locations. |
27
+ | 🧹 **Safe deterministic updates** | Tracks owned files, removes stale generated output, and preserves unrelated files. |
28
+ | 🛠️ **CLI and programmatic API** | Works in package scripts or directly from TypeScript build tooling. |
29
+
30
+ ## 🚀 Quick start
31
+
32
+ Node.js 22 or newer is required.
33
+
34
+ ### 1. Install
35
+
36
+ With Bun:
37
+
38
+ ```bash
39
+ bun add --dev flag-resizer
40
+ ```
41
+
42
+ With npm:
43
+
44
+ ```bash
45
+ npm install flag-resizer --save-dev
46
+ ```
47
+
48
+ ### 2. Configure
49
+
50
+ Create `flag-resizer.config.ts` in your project:
51
+
52
+ ```ts
53
+ import { defineConfig } from 'flag-resizer';
54
+
55
+ export default defineConfig({
56
+ default: {
57
+ filter: {
58
+ type: 'whitelist',
59
+ values: ['cz', 'gb', 'us-*'],
60
+ },
61
+ sizes: [
62
+ [20, 15],
63
+ [40, 30],
64
+ [60, 45],
65
+ [80, 60],
66
+ [120, 90],
67
+ ],
68
+ quality: 100,
69
+ formats: ['png', 'webp'],
70
+ output: {
71
+ png: {
72
+ dir: 'public/flags/png',
73
+ publicPath: '/flags/png',
74
+ },
75
+ webp: {
76
+ dir: 'public/flags/webp',
77
+ publicPath: '/flags/webp',
78
+ },
79
+ ts: 'src/generated/flags.ts',
80
+ },
81
+ },
82
+ });
83
+ ```
84
+
85
+ Filter values are lowercase flag or country codes, not language codes. They can be exact codes or
86
+ patterns using `*` as a wildcard. For example, use `cz` for the Czech flag, `gb` for the British
87
+ flag, or `us-*` for all 50 U.S. subdivision flags. The `us-*` pattern does not include the national
88
+ `us` flag; add `us` separately if needed. Likewise, `ca-*` selects Canadian subdivisions, `au-*`
89
+ selects Australian subdivisions, `de-*` selects German states, `es-*` selects Spanish autonomous
90
+ communities and cities, and `*` selects every bundled flag.
91
+
92
+ Subdivision codes can also be selected individually: `gb-eng`, `gb-nir`, `gb-sct`, and `gb-wls`
93
+ for the United Kingdom; `us-ca` for California; `ca-on` for Ontario; or `au-nsw` for New South
94
+ Wales. Unknown codes, malformed patterns, and patterns that match no bundled flags fail validation.
95
+
96
+ The Northern Ireland asset is the historical Ulster Banner from
97
+ [flag-icons](https://github.com/lipis/flag-icons). Northern Ireland has no current distinct official
98
+ flag; the United Kingdom flag is its official flag.
99
+
100
+ The 50 U.S. state assets come from [FlagCDN](https://flagcdn.com/), whose flag artwork is based on
101
+ [Wikimedia Commons](https://commons.wikimedia.org/) vectors and identified as public domain in
102
+ [Flagpedia's terms](https://flagpedia.net/terms). The source artwork is normalized to the same
103
+ rounded 36×36 canvas as the bundled Twemoji flags.
104
+
105
+ The 13 Canadian, 8 Australian, 16 German, and 19 Spanish subdivision assets come from the
106
+ MIT-licensed [iso3166-flags](https://github.com/amckenna41/iso3166-flags) dataset and use current
107
+ ISO 3166-2 codes. Spain's set covers its 17 autonomous communities and 2 autonomous cities, not its
108
+ 50 provinces. Their source artwork is also normalized to the rounded 36×36 canvas.
109
+
110
+ All sizes in one profile must use the same aspect ratio. Output paths are resolved relative to the
111
+ configuration file. A `publicPath` can be a root-relative path or an absolute CDN URL.
112
+
113
+ Configuration is loaded by C12 and may use TypeScript, JavaScript, JSON, JSONC, JSON5, YAML, or TOML.
114
+
115
+ ### 3. Generate
116
+
117
+ ```bash
118
+ bunx flag-resizer
119
+ ```
120
+
121
+ ```text
122
+ ... Generating flag assets…
123
+ ✔ default · 2 flags · 20 images · 25 created · 15 ms
124
+ ```
125
+
126
+ ## 🧭 CLI reference
127
+
128
+ ```text
129
+ flag-resizer [profiles...] [options]
130
+
131
+ -c, --config <path> Use an explicit configuration file.
132
+ --concurrency <count> Maximum parallel image conversions.
133
+ --dry-run Preview changes without writing files.
134
+ --verbose Show configuration and output details.
135
+ -h, --help Display usage information.
136
+ -v, --version Display the installed version.
137
+ ```
138
+
139
+ With no profile arguments, every configured profile is generated. Pass profile names to generate
140
+ only those profiles:
141
+
142
+ ```bash
143
+ bunx flag-resizer default marketing
144
+ ```
145
+
146
+ Use an explicit config, limit parallel image conversions, or preview changes:
147
+
148
+ ```bash
149
+ bunx flag-resizer --config ./config/flags.config.ts --concurrency 4
150
+ bunx flag-resizer --dry-run
151
+ bunx flag-resizer --dry-run --verbose
152
+ ```
153
+
154
+ Interactive output stays compact and uses color when the terminal supports it. Set `NO_COLOR=1` to
155
+ disable ANSI colors or `FORCE_COLOR=1` to enable them when output is redirected.
156
+
157
+ ### 🎨 Verbose output
158
+
159
+ Add `--verbose` to show the loaded configuration, requested sizes and formats, asset output
160
+ directories, generated TypeScript file, and managed manifest. Paths inside the current project are
161
+ kept relative for readability:
162
+
163
+ ```text
164
+ ... Planning flag generation…
165
+ ✔ default · 2 flags · 8 images · 13 created · 15 ms
166
+
167
+ config flag-resizer.config.ts
168
+ sizes 20x15, 40x30
169
+ formats png, webp
170
+ png output public/flags/png
171
+ webp output public/flags/webp
172
+ typescript src/generated/flags.ts
173
+ manifest .flag-resizer/manifest.json
174
+ ```
175
+
176
+ ## 📁 Generated assets
177
+
178
+ Each format is organized into dimension directories:
179
+
180
+ ```text
181
+ public/flags/png/
182
+ ├── ATTRIBUTION.txt
183
+ ├── LICENSE-GRAPHICS
184
+ ├── 20x15/
185
+ │ ├── cz.png
186
+ │ └── gb.png
187
+ └── 40x30/
188
+ ├── cz.png
189
+ └── gb.png
190
+ ```
191
+
192
+ The CLI records only files it owns in `.flag-resizer/manifest.json`. Later runs remove stale
193
+ generated files while preserving unrelated files in the same directories.
194
+
195
+ All images are staged before existing outputs or the ownership manifest are updated. A conversion
196
+ failure therefore leaves the current assets and manifest unchanged.
197
+
198
+ ## 📝 Generated TypeScript
199
+
200
+ Each profile generates:
201
+
202
+ - `FLAGS` and its filtered `CountryCode` union.
203
+ - `FLAG_SIZES`, `FlagSize`, and `FLAG_DIMENSIONS`.
204
+ - `FLAG_FORMATS` and `FlagFormat`.
205
+ - `FLAG_PUBLIC_PATHS`.
206
+ - `getFlagPath(code, size, format)`.
207
+
208
+ ```ts
209
+ import { FLAG_DIMENSIONS, getFlagPath, type CountryCode, type FlagSize } from './generated/flags';
210
+
211
+ function flagImage(code: CountryCode, size: FlagSize) {
212
+ return {
213
+ src: getFlagPath(code, size, 'png'),
214
+ ...FLAG_DIMENSIONS[size],
215
+ };
216
+ }
217
+ ```
218
+
219
+ An Angular template can use the generated paths in a responsive picture:
220
+
221
+ ```html
222
+ <picture>
223
+ <source
224
+ type="image/webp"
225
+ [attr.srcset]="
226
+ getFlagPath(code, '20x15', 'webp') + ', ' +
227
+ getFlagPath(code, '40x30', 'webp') + ' 2x, ' +
228
+ getFlagPath(code, '60x45', 'webp') + ' 3x'
229
+ "
230
+ />
231
+ <img [src]="getFlagPath(code, '20x15', 'png')" [width]="20" [height]="15" [alt]="FLAGS[code]" />
232
+ </picture>
233
+ ```
234
+
235
+ ## 🛠️ Programmatic API
236
+
237
+ Load a discovered or explicit configuration file:
238
+
239
+ ```ts
240
+ import { generate } from 'flag-resizer';
241
+
242
+ const result = await generate({
243
+ configFile: './flag-resizer.config.ts',
244
+ profiles: ['default'],
245
+ concurrency: 4,
246
+ });
247
+ ```
248
+
249
+ Or supply inline configuration:
250
+
251
+ ```ts
252
+ import { defineConfig, generate } from 'flag-resizer';
253
+
254
+ const config = defineConfig({
255
+ icons: {
256
+ filter: { type: 'whitelist', values: ['cz', 'gb'] },
257
+ sizes: [[40, 30]],
258
+ quality: 100,
259
+ formats: ['webp'],
260
+ output: {
261
+ webp: { dir: 'public/flags', publicPath: '/flags' },
262
+ ts: 'src/generated/flags.ts',
263
+ },
264
+ },
265
+ });
266
+
267
+ await generate({ config });
268
+ ```
269
+
270
+ ## ✅ Validation
271
+
272
+ The generator rejects:
273
+
274
+ - Language codes, unknown country codes, malformed patterns, or patterns with no matches.
275
+ - Duplicate formats, sizes, or filter values.
276
+ - Dimensions that are not positive integers.
277
+ - Mixed aspect ratios within a profile.
278
+ - Missing output settings for an enabled format.
279
+ - Output collisions between profiles.
280
+
281
+ ## 🏗️ Development
282
+
283
+ Use Node.js 24 from `.nvmrc` and Bun 1.3.14 from `package.json`:
284
+
285
+ ```bash
286
+ bun ci
287
+ bun run check
288
+ ```
289
+
290
+ `bun run check` runs formatting, linting, type checks, runtime and public-API tests, the build, and
291
+ published-package validation.
292
+
293
+ Husky installs the repository hooks during `bun ci`. The pre-commit hook runs ESLint and Prettier on
294
+ staged files through lint-staged, while the commit-message hook validates Conventional Commits with
295
+ Quick Commitlint.
296
+
297
+ ## 🏷️ Releases
298
+
299
+ Run a release command from a clean working tree:
300
+
301
+ ```bash
302
+ bun run release:patch
303
+ bun run release:minor
304
+ bun run release:major
305
+ ```
306
+
307
+ Each command checks out `master`, validates the package, updates `CHANGELOG.md`, creates the release
308
+ commit and `v*` tag, then pushes the commit and tags. The tag workflow publishes `flag-resizer` to
309
+ npm and `@celtian/flag-resizer` to GitHub Packages.
310
+
311
+ Create an npm beta release with:
312
+
313
+ ```bash
314
+ bun run release:beta
315
+ ```
316
+
317
+ Beta tags publish with the npm `beta` dist-tag and are not copied to GitHub Packages. The repository
318
+ must provide the `NPM_AUTH_TOKEN` Actions secret; GitHub Packages uses the workflow's automatic
319
+ `GITHUB_TOKEN`.
320
+
321
+ ## 🤝 Contributing
322
+
323
+ Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for the development workflow and
324
+ pull-request checklist. Participation is governed by the [Code of Conduct](CODE_OF_CONDUCT.md).
325
+
326
+ ## 🔒 Security
327
+
328
+ Report suspected vulnerabilities privately according to [SECURITY.md](SECURITY.md).
329
+
330
+ ## 📄 License and attribution
331
+
332
+ Copyright &copy; 2026 [Dominik Hladík](https://github.com/Celtian).
333
+
334
+ The package code is licensed under the [MIT License](LICENSE).
335
+
336
+ The bundled graphics use source-specific terms: Twemoji is licensed under CC-BY-4.0; the Northern
337
+ Ireland, Canadian, Australian, German, and Spanish subdivision assets are MIT-licensed; and the
338
+ FlagCDN U.S. state artwork is public domain. Generated asset roots include attribution and license
339
+ notices. Keep the required notices when redistributing the graphics. See
340
+ [ATTRIBUTION.txt](ATTRIBUTION.txt) and [LICENSE-GRAPHICS](LICENSE-GRAPHICS).
package/dist/cli.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {}
package/dist/cli.js ADDED
@@ -0,0 +1,219 @@
1
+ #!/usr/bin/env node
2
+ import { r as FlagResizerError, t as generate } from "./generator.js";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { readFileSync } from "node:fs";
6
+ import { parseArgs } from "node:util";
7
+ //#region src/cli-core.ts
8
+ const PACKAGE_ROOT = fileURLToPath(new URL("../", import.meta.url));
9
+ const PACKAGE_JSON = JSON.parse(readFileSync(path.join(PACKAGE_ROOT, "package.json"), "utf8"));
10
+ const ansi = {
11
+ reset: "\x1B[0m",
12
+ red: "\x1B[31m",
13
+ green: "\x1B[32m",
14
+ yellow: "\x1B[33m",
15
+ cyan: "\x1B[36m",
16
+ brightCyan: "\x1B[96m",
17
+ dim: "\x1B[2m",
18
+ dimCyan: "\x1B[2;36m"
19
+ };
20
+ const plain = (value) => value;
21
+ function palette(enabled) {
22
+ const color = (code) => (value) => enabled ? `${code}${value}${ansi.reset}` : value;
23
+ return {
24
+ red: color(ansi.red),
25
+ green: color(ansi.green),
26
+ yellow: color(ansi.yellow),
27
+ cyan: color(ansi.cyan),
28
+ brightCyan: color(ansi.brightCyan),
29
+ dim: color(ansi.dim),
30
+ dimCyan: color(ansi.dimCyan)
31
+ };
32
+ }
33
+ function colorsEnabled(stream) {
34
+ if (process.env["NO_COLOR"] !== void 0 || process.env["FORCE_COLOR"] === "0") return false;
35
+ return stream.isTTY || Boolean(process.env["FORCE_COLOR"]);
36
+ }
37
+ function plural(value, word) {
38
+ return `${value} ${word}${value === 1 ? "" : "s"}`;
39
+ }
40
+ function help(colors) {
41
+ return `
42
+ ${colors.brightCyan("Flag Resizer")}
43
+
44
+ ${colors.yellow("Usage:")}
45
+ flag-resizer [profiles...] [options]
46
+
47
+ Generate typed PNG and WebP flag assets from flag-resizer.config.*
48
+ With no profile arguments, every configured profile is generated.
49
+
50
+ ${colors.yellow("Options:")}
51
+ ${colors.green("-c, --config <path>")} Use an explicit configuration file.
52
+ ${colors.green(" --concurrency <count>")} Maximum parallel image conversions.
53
+ ${colors.green(" --dry-run")} Preview changes without writing files.
54
+ ${colors.green(" --verbose")} Show configuration and output details.
55
+ ${colors.green("-h, --help")} Display usage information.
56
+ ${colors.green("-v, --version")} Display the installed version.
57
+ `;
58
+ }
59
+ function parseCliArguments(args) {
60
+ const parsed = parseArgs({
61
+ args: [...args],
62
+ allowPositionals: true,
63
+ strict: true,
64
+ options: {
65
+ config: {
66
+ type: "string",
67
+ short: "c"
68
+ },
69
+ concurrency: { type: "string" },
70
+ "dry-run": {
71
+ type: "boolean",
72
+ default: false
73
+ },
74
+ verbose: {
75
+ type: "boolean",
76
+ default: false
77
+ },
78
+ help: {
79
+ type: "boolean",
80
+ short: "h",
81
+ default: false
82
+ },
83
+ version: {
84
+ type: "boolean",
85
+ short: "v",
86
+ default: false
87
+ }
88
+ }
89
+ });
90
+ const values = parsed.values;
91
+ return {
92
+ positionals: parsed.positionals,
93
+ values: {
94
+ ...typeof values.config === "string" ? { config: values.config } : {},
95
+ ...typeof values.concurrency === "string" ? { concurrency: values.concurrency } : {},
96
+ dryRun: values["dry-run"],
97
+ verbose: values.verbose,
98
+ help: values.help,
99
+ version: values.version
100
+ }
101
+ };
102
+ }
103
+ function parseConcurrency(value) {
104
+ if (value === void 0) return void 0;
105
+ const parsed = Number(value);
106
+ if (!Number.isInteger(parsed) || parsed < 1) throw new FlagResizerError("--concurrency must be a positive integer.");
107
+ return parsed;
108
+ }
109
+ function formatProfileSummary(profile, durationMs, useColor = false) {
110
+ const colors = useColor ? palette(true) : {
111
+ red: plain,
112
+ green: plain,
113
+ yellow: plain,
114
+ cyan: plain,
115
+ brightCyan: plain,
116
+ dim: plain,
117
+ dimCyan: plain
118
+ };
119
+ const details = [
120
+ plural(profile.countries, "flag"),
121
+ plural(profile.images, "image"),
122
+ ...profile.created > 0 ? [colors.green(`${profile.created} created`)] : [],
123
+ ...profile.updated > 0 ? [colors.yellow(`${profile.updated} updated`)] : [],
124
+ ...profile.unchanged > 0 ? [colors.dim(`${profile.unchanged} unchanged`)] : [],
125
+ ...profile.removed > 0 ? [colors.red(`${profile.removed} removed`)] : [],
126
+ ...durationMs === void 0 ? [] : [colors.dimCyan(`${durationMs} ms`)]
127
+ ];
128
+ return `${colors.green("✔")} ${colors.cyan(profile.name)} · ${details.join(" · ")}`;
129
+ }
130
+ function formatCombinedSummary(profiles, durationMs, colors) {
131
+ const totals = profiles.reduce((current, profile) => ({
132
+ flags: current.flags + profile.countries,
133
+ images: current.images + profile.images,
134
+ files: current.files + profile.created + profile.updated + profile.unchanged
135
+ }), {
136
+ flags: 0,
137
+ images: 0,
138
+ files: 0
139
+ });
140
+ return [
141
+ `${colors.green("✔")} ${plural(profiles.length, "profile")}`,
142
+ plural(totals.flags, "flag"),
143
+ plural(totals.images, "image"),
144
+ plural(totals.files, "file"),
145
+ colors.dimCyan(`${durationMs} ms`)
146
+ ].join(" · ");
147
+ }
148
+ function displayPath(target, cwd) {
149
+ const relative = path.relative(cwd, target);
150
+ if (relative === "") return ".";
151
+ return relative.startsWith("..") ? target : relative;
152
+ }
153
+ function verboseRow(label, value, colors) {
154
+ return ` ${colors.dim(label.padEnd(12))}${value}`;
155
+ }
156
+ function formatVerboseDetails(result, cwd = process.cwd(), useColor = false) {
157
+ const colors = palette(useColor);
158
+ const rows = [];
159
+ if (result.configFile) rows.push(verboseRow("config", displayPath(result.configFile, cwd), colors));
160
+ for (const profile of result.profiles) {
161
+ rows.push(verboseRow("sizes", profile.sizes.map(([width, height]) => `${width}x${height}`).join(", "), colors), verboseRow("formats", profile.formats.join(", "), colors));
162
+ for (const format of profile.formats) {
163
+ const directory = profile.outputDirectories[format];
164
+ if (directory) rows.push(verboseRow(`${format} output`, displayPath(directory, cwd), colors));
165
+ }
166
+ rows.push(verboseRow("typescript", displayPath(profile.typeScriptFile, cwd), colors));
167
+ }
168
+ rows.push(verboseRow("manifest", displayPath(result.manifestFile, cwd), colors));
169
+ return rows.join("\n");
170
+ }
171
+ async function runCli(args) {
172
+ const stdoutColors = palette(colorsEnabled(process.stdout));
173
+ const stderrColors = palette(colorsEnabled(process.stderr));
174
+ let parsed;
175
+ try {
176
+ parsed = parseCliArguments(args);
177
+ } catch (error) {
178
+ const message = error instanceof Error ? error.message : String(error);
179
+ console.error(`${stderrColors.red("error")}: ${message}`);
180
+ return 1;
181
+ }
182
+ if (parsed.values.help) {
183
+ console.log(help(stdoutColors));
184
+ return 0;
185
+ }
186
+ if (parsed.values.version) {
187
+ console.log(`flag-resizer ${PACKAGE_JSON.version}`);
188
+ return 0;
189
+ }
190
+ try {
191
+ const concurrency = parseConcurrency(parsed.values.concurrency);
192
+ const action = parsed.values.dryRun ? "Planning flag generation…" : "Generating flag assets…";
193
+ console.error(`${stderrColors.cyan("...")} ${stderrColors.dim(action)}`);
194
+ const result = await generate({
195
+ ...parsed.values.config ? { configFile: parsed.values.config } : {},
196
+ ...parsed.positionals.length > 0 ? { profiles: parsed.positionals } : {},
197
+ ...concurrency === void 0 ? {} : { concurrency },
198
+ dryRun: parsed.values.dryRun
199
+ });
200
+ for (const profile of result.profiles) console.error(formatProfileSummary(profile, result.profiles.length === 1 ? result.durationMs : void 0, colorsEnabled(process.stderr)));
201
+ if (result.profiles.length > 1) console.error(formatCombinedSummary(result.profiles, result.durationMs, stderrColors));
202
+ if (parsed.values.verbose) {
203
+ console.error("");
204
+ console.error(formatVerboseDetails(result, process.cwd(), colorsEnabled(process.stderr)));
205
+ }
206
+ return 0;
207
+ } catch (error) {
208
+ if (error instanceof FlagResizerError) console.error(`${stderrColors.red("error")}: ${error.message}`);
209
+ else console.error(`${stderrColors.red("error")}: unexpected failure`, error);
210
+ return 1;
211
+ }
212
+ }
213
+ //#endregion
214
+ //#region src/cli.ts
215
+ process.exitCode = await runCli(process.argv.slice(2));
216
+ //#endregion
217
+ export {};
218
+
219
+ //# sourceMappingURL=cli.js.map