arevdata 0.1.17

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 (289) hide show
  1. package/README.md +499 -0
  2. package/dist/arevdata.cjs +38955 -0
  3. package/dist/arevdata.cjs.map +1 -0
  4. package/dist/arevdata.js +38955 -0
  5. package/dist/arevdata.js.map +1 -0
  6. package/dist/assets/flags/LICENSE.flag-icons.txt +21 -0
  7. package/dist/assets/flags/README.md +11 -0
  8. package/dist/assets/flags/index.html +88 -0
  9. package/dist/assets/flags/overrides/xn.svg +6 -0
  10. package/dist/assets/flags/svg/ad.svg +150 -0
  11. package/dist/assets/flags/svg/ae.svg +6 -0
  12. package/dist/assets/flags/svg/af.svg +81 -0
  13. package/dist/assets/flags/svg/ag.svg +14 -0
  14. package/dist/assets/flags/svg/al.svg +5 -0
  15. package/dist/assets/flags/svg/am.svg +5 -0
  16. package/dist/assets/flags/svg/ao.svg +13 -0
  17. package/dist/assets/flags/svg/ar.svg +32 -0
  18. package/dist/assets/flags/svg/at.svg +4 -0
  19. package/dist/assets/flags/svg/au.svg +8 -0
  20. package/dist/assets/flags/svg/az.svg +8 -0
  21. package/dist/assets/flags/svg/ba.svg +12 -0
  22. package/dist/assets/flags/svg/bb.svg +6 -0
  23. package/dist/assets/flags/svg/bd.svg +4 -0
  24. package/dist/assets/flags/svg/be.svg +7 -0
  25. package/dist/assets/flags/svg/bf.svg +7 -0
  26. package/dist/assets/flags/svg/bg.svg +5 -0
  27. package/dist/assets/flags/svg/bh.svg +4 -0
  28. package/dist/assets/flags/svg/bi.svg +15 -0
  29. package/dist/assets/flags/svg/bj.svg +14 -0
  30. package/dist/assets/flags/svg/bn.svg +36 -0
  31. package/dist/assets/flags/svg/bo.svg +673 -0
  32. package/dist/assets/flags/svg/br.svg +45 -0
  33. package/dist/assets/flags/svg/bs.svg +13 -0
  34. package/dist/assets/flags/svg/bt.svg +89 -0
  35. package/dist/assets/flags/svg/bw.svg +7 -0
  36. package/dist/assets/flags/svg/by.svg +18 -0
  37. package/dist/assets/flags/svg/bz.svg +145 -0
  38. package/dist/assets/flags/svg/ca.svg +4 -0
  39. package/dist/assets/flags/svg/cd.svg +5 -0
  40. package/dist/assets/flags/svg/cf.svg +15 -0
  41. package/dist/assets/flags/svg/cg.svg +12 -0
  42. package/dist/assets/flags/svg/ch.svg +9 -0
  43. package/dist/assets/flags/svg/cl.svg +13 -0
  44. package/dist/assets/flags/svg/cm.svg +15 -0
  45. package/dist/assets/flags/svg/cn.svg +11 -0
  46. package/dist/assets/flags/svg/co.svg +7 -0
  47. package/dist/assets/flags/svg/cr.svg +7 -0
  48. package/dist/assets/flags/svg/cu.svg +13 -0
  49. package/dist/assets/flags/svg/cv.svg +13 -0
  50. package/dist/assets/flags/svg/cy.svg +6 -0
  51. package/dist/assets/flags/svg/cz.svg +5 -0
  52. package/dist/assets/flags/svg/de.svg +5 -0
  53. package/dist/assets/flags/svg/dj.svg +13 -0
  54. package/dist/assets/flags/svg/dk.svg +5 -0
  55. package/dist/assets/flags/svg/dm.svg +152 -0
  56. package/dist/assets/flags/svg/do.svg +121 -0
  57. package/dist/assets/flags/svg/dz.svg +5 -0
  58. package/dist/assets/flags/svg/ec.svg +138 -0
  59. package/dist/assets/flags/svg/ee.svg +5 -0
  60. package/dist/assets/flags/svg/eg.svg +38 -0
  61. package/dist/assets/flags/svg/er.svg +8 -0
  62. package/dist/assets/flags/svg/es.svg +544 -0
  63. package/dist/assets/flags/svg/et.svg +14 -0
  64. package/dist/assets/flags/svg/fi.svg +5 -0
  65. package/dist/assets/flags/svg/fj.svg +120 -0
  66. package/dist/assets/flags/svg/fm.svg +11 -0
  67. package/dist/assets/flags/svg/fr.svg +5 -0
  68. package/dist/assets/flags/svg/ga.svg +7 -0
  69. package/dist/assets/flags/svg/gb.svg +7 -0
  70. package/dist/assets/flags/svg/gd.svg +27 -0
  71. package/dist/assets/flags/svg/ge.svg +6 -0
  72. package/dist/assets/flags/svg/gh.svg +6 -0
  73. package/dist/assets/flags/svg/gm.svg +14 -0
  74. package/dist/assets/flags/svg/gn.svg +7 -0
  75. package/dist/assets/flags/svg/gq.svg +23 -0
  76. package/dist/assets/flags/svg/gr.svg +16 -0
  77. package/dist/assets/flags/svg/gt.svg +204 -0
  78. package/dist/assets/flags/svg/gw.svg +13 -0
  79. package/dist/assets/flags/svg/gy.svg +9 -0
  80. package/dist/assets/flags/svg/hn.svg +18 -0
  81. package/dist/assets/flags/svg/hr.svg +58 -0
  82. package/dist/assets/flags/svg/ht.svg +116 -0
  83. package/dist/assets/flags/svg/hu.svg +7 -0
  84. package/dist/assets/flags/svg/id.svg +4 -0
  85. package/dist/assets/flags/svg/ie.svg +7 -0
  86. package/dist/assets/flags/svg/il.svg +14 -0
  87. package/dist/assets/flags/svg/in.svg +25 -0
  88. package/dist/assets/flags/svg/iq.svg +10 -0
  89. package/dist/assets/flags/svg/ir.svg +219 -0
  90. package/dist/assets/flags/svg/is.svg +12 -0
  91. package/dist/assets/flags/svg/it.svg +7 -0
  92. package/dist/assets/flags/svg/jm.svg +8 -0
  93. package/dist/assets/flags/svg/jo.svg +16 -0
  94. package/dist/assets/flags/svg/jp.svg +11 -0
  95. package/dist/assets/flags/svg/ke.svg +23 -0
  96. package/dist/assets/flags/svg/kg.svg +4 -0
  97. package/dist/assets/flags/svg/kh.svg +61 -0
  98. package/dist/assets/flags/svg/ki.svg +36 -0
  99. package/dist/assets/flags/svg/km.svg +16 -0
  100. package/dist/assets/flags/svg/kn.svg +14 -0
  101. package/dist/assets/flags/svg/kp.svg +15 -0
  102. package/dist/assets/flags/svg/kr.svg +24 -0
  103. package/dist/assets/flags/svg/kw.svg +13 -0
  104. package/dist/assets/flags/svg/kz.svg +36 -0
  105. package/dist/assets/flags/svg/la.svg +12 -0
  106. package/dist/assets/flags/svg/lb.svg +15 -0
  107. package/dist/assets/flags/svg/lc.svg +8 -0
  108. package/dist/assets/flags/svg/li.svg +43 -0
  109. package/dist/assets/flags/svg/lk.svg +22 -0
  110. package/dist/assets/flags/svg/lr.svg +14 -0
  111. package/dist/assets/flags/svg/ls.svg +8 -0
  112. package/dist/assets/flags/svg/lt.svg +7 -0
  113. package/dist/assets/flags/svg/lu.svg +5 -0
  114. package/dist/assets/flags/svg/lv.svg +6 -0
  115. package/dist/assets/flags/svg/ly.svg +13 -0
  116. package/dist/assets/flags/svg/ma.svg +4 -0
  117. package/dist/assets/flags/svg/mc.svg +6 -0
  118. package/dist/assets/flags/svg/md.svg +70 -0
  119. package/dist/assets/flags/svg/me.svg +116 -0
  120. package/dist/assets/flags/svg/mg.svg +7 -0
  121. package/dist/assets/flags/svg/mh.svg +7 -0
  122. package/dist/assets/flags/svg/mk.svg +5 -0
  123. package/dist/assets/flags/svg/ml.svg +7 -0
  124. package/dist/assets/flags/svg/mm.svg +12 -0
  125. package/dist/assets/flags/svg/mn.svg +14 -0
  126. package/dist/assets/flags/svg/mr.svg +6 -0
  127. package/dist/assets/flags/svg/mt.svg +58 -0
  128. package/dist/assets/flags/svg/mu.svg +8 -0
  129. package/dist/assets/flags/svg/mv.svg +6 -0
  130. package/dist/assets/flags/svg/mw.svg +10 -0
  131. package/dist/assets/flags/svg/mx.svg +382 -0
  132. package/dist/assets/flags/svg/my.svg +26 -0
  133. package/dist/assets/flags/svg/mz.svg +21 -0
  134. package/dist/assets/flags/svg/na.svg +16 -0
  135. package/dist/assets/flags/svg/ne.svg +6 -0
  136. package/dist/assets/flags/svg/ng.svg +6 -0
  137. package/dist/assets/flags/svg/ni.svg +129 -0
  138. package/dist/assets/flags/svg/nl.svg +5 -0
  139. package/dist/assets/flags/svg/no.svg +7 -0
  140. package/dist/assets/flags/svg/np.svg +13 -0
  141. package/dist/assets/flags/svg/nr.svg +12 -0
  142. package/dist/assets/flags/svg/nz.svg +36 -0
  143. package/dist/assets/flags/svg/om.svg +115 -0
  144. package/dist/assets/flags/svg/pa.svg +14 -0
  145. package/dist/assets/flags/svg/pe.svg +4 -0
  146. package/dist/assets/flags/svg/pg.svg +9 -0
  147. package/dist/assets/flags/svg/ph.svg +6 -0
  148. package/dist/assets/flags/svg/pk.svg +15 -0
  149. package/dist/assets/flags/svg/pl.svg +6 -0
  150. package/dist/assets/flags/svg/ps.svg +6 -0
  151. package/dist/assets/flags/svg/pt.svg +57 -0
  152. package/dist/assets/flags/svg/pw.svg +11 -0
  153. package/dist/assets/flags/svg/py.svg +157 -0
  154. package/dist/assets/flags/svg/qa.svg +4 -0
  155. package/dist/assets/flags/svg/ro.svg +7 -0
  156. package/dist/assets/flags/svg/rs.svg +292 -0
  157. package/dist/assets/flags/svg/ru.svg +5 -0
  158. package/dist/assets/flags/svg/rw.svg +13 -0
  159. package/dist/assets/flags/svg/sa.svg +25 -0
  160. package/dist/assets/flags/svg/sb.svg +13 -0
  161. package/dist/assets/flags/svg/sc.svg +7 -0
  162. package/dist/assets/flags/svg/sd.svg +13 -0
  163. package/dist/assets/flags/svg/se.svg +4 -0
  164. package/dist/assets/flags/svg/sg.svg +13 -0
  165. package/dist/assets/flags/svg/si.svg +18 -0
  166. package/dist/assets/flags/svg/sk.svg +9 -0
  167. package/dist/assets/flags/svg/sl.svg +7 -0
  168. package/dist/assets/flags/svg/sm.svg +75 -0
  169. package/dist/assets/flags/svg/sn.svg +8 -0
  170. package/dist/assets/flags/svg/so.svg +11 -0
  171. package/dist/assets/flags/svg/sr.svg +6 -0
  172. package/dist/assets/flags/svg/ss.svg +8 -0
  173. package/dist/assets/flags/svg/st.svg +16 -0
  174. package/dist/assets/flags/svg/sv.svg +593 -0
  175. package/dist/assets/flags/svg/sy.svg +6 -0
  176. package/dist/assets/flags/svg/sz.svg +34 -0
  177. package/dist/assets/flags/svg/td.svg +7 -0
  178. package/dist/assets/flags/svg/tg.svg +14 -0
  179. package/dist/assets/flags/svg/th.svg +7 -0
  180. package/dist/assets/flags/svg/tj.svg +22 -0
  181. package/dist/assets/flags/svg/tl.svg +13 -0
  182. package/dist/assets/flags/svg/tm.svg +204 -0
  183. package/dist/assets/flags/svg/tn.svg +4 -0
  184. package/dist/assets/flags/svg/to.svg +10 -0
  185. package/dist/assets/flags/svg/tr.svg +8 -0
  186. package/dist/assets/flags/svg/tt.svg +5 -0
  187. package/dist/assets/flags/svg/tv.svg +9 -0
  188. package/dist/assets/flags/svg/tw.svg +34 -0
  189. package/dist/assets/flags/svg/tz.svg +13 -0
  190. package/dist/assets/flags/svg/ua.svg +6 -0
  191. package/dist/assets/flags/svg/ug.svg +30 -0
  192. package/dist/assets/flags/svg/us.svg +9 -0
  193. package/dist/assets/flags/svg/uy.svg +28 -0
  194. package/dist/assets/flags/svg/uz.svg +30 -0
  195. package/dist/assets/flags/svg/va.svg +190 -0
  196. package/dist/assets/flags/svg/vc.svg +8 -0
  197. package/dist/assets/flags/svg/ve.svg +26 -0
  198. package/dist/assets/flags/svg/vn.svg +11 -0
  199. package/dist/assets/flags/svg/vu.svg +21 -0
  200. package/dist/assets/flags/svg/ws.svg +7 -0
  201. package/dist/assets/flags/svg/xk.svg +5 -0
  202. package/dist/assets/flags/svg/xn.svg +6 -0
  203. package/dist/assets/flags/svg/ye.svg +7 -0
  204. package/dist/assets/flags/svg/za.svg +17 -0
  205. package/dist/assets/flags/svg/zm.svg +27 -0
  206. package/dist/assets/flags/svg/zw.svg +21 -0
  207. package/dist/data/languages/index.html +86 -0
  208. package/dist/docs/api-worker-plan/index.html +439 -0
  209. package/dist/docs/cities/index.html +193 -0
  210. package/dist/docs/continents-currencies/index.html +306 -0
  211. package/dist/docs/countries/index.html +274 -0
  212. package/dist/docs/country-maps/index.html +262 -0
  213. package/dist/docs/flags/index.html +300 -0
  214. package/dist/docs/geography/index.html +454 -0
  215. package/dist/docs/languages/index.html +304 -0
  216. package/dist/docs/phone-codes/index.html +152 -0
  217. package/dist/docs/states/index.html +334 -0
  218. package/dist/docs/world-map/index.html +345 -0
  219. package/dist/examples/vue-app/index.html +208 -0
  220. package/dist/index.html +784 -0
  221. package/dist/robots.txt +2 -0
  222. package/dist/style/app.css +1 -0
  223. package/dist/types/__tests__/cities.test.d.ts +1 -0
  224. package/dist/types/__tests__/continents.test.d.ts +1 -0
  225. package/dist/types/__tests__/countries.test.d.ts +1 -0
  226. package/dist/types/__tests__/countryMaps.test.d.ts +1 -0
  227. package/dist/types/__tests__/geography.test.d.ts +1 -0
  228. package/dist/types/__tests__/index.test.d.ts +1 -0
  229. package/dist/types/__tests__/phoneCodes.test.d.ts +1 -0
  230. package/dist/types/__tests__/states.test.d.ts +1 -0
  231. package/dist/types/__tests__/translations.test.d.ts +1 -0
  232. package/dist/types/api/index.d.ts +5 -0
  233. package/dist/types/api/index.test.d.ts +1 -0
  234. package/dist/types/api/query.d.ts +3 -0
  235. package/dist/types/api/response.d.ts +16 -0
  236. package/dist/types/api/router.d.ts +1 -0
  237. package/dist/types/api/routes/cities.d.ts +2 -0
  238. package/dist/types/api/routes/countries.d.ts +2 -0
  239. package/dist/types/api/routes/health.d.ts +1 -0
  240. package/dist/types/api/routes/maps.d.ts +1 -0
  241. package/dist/types/api/routes/meta.d.ts +1 -0
  242. package/dist/types/api/routes/phoneCodes.d.ts +1 -0
  243. package/dist/types/data/cities.d.ts +22 -0
  244. package/dist/types/data/continents.d.ts +9 -0
  245. package/dist/types/data/countries.d.ts +23 -0
  246. package/dist/types/data/countryMaps.d.ts +104 -0
  247. package/dist/types/data/currencies.d.ts +13 -0
  248. package/dist/types/data/flags.d.ts +37 -0
  249. package/dist/types/data/geography.d.ts +48 -0
  250. package/dist/types/data/languages/index.d.ts +2 -0
  251. package/dist/types/data/languages/language.test.d.ts +1 -0
  252. package/dist/types/data/languages/languageData.d.ts +6 -0
  253. package/dist/types/data/languages/languageFunctions.d.ts +43 -0
  254. package/dist/types/data/languages/translations/ar.d.ts +1189 -0
  255. package/dist/types/data/languages/translations/de.d.ts +1189 -0
  256. package/dist/types/data/languages/translations/es.d.ts +1189 -0
  257. package/dist/types/data/languages/translations/fr.d.ts +1189 -0
  258. package/dist/types/data/languages/translations/hi.d.ts +1189 -0
  259. package/dist/types/data/languages/translations/it.d.ts +1189 -0
  260. package/dist/types/data/languages/translations/ja.d.ts +1189 -0
  261. package/dist/types/data/languages/translations/ko.d.ts +1189 -0
  262. package/dist/types/data/languages/translations/nl.d.ts +1189 -0
  263. package/dist/types/data/languages/translations/pl.d.ts +1189 -0
  264. package/dist/types/data/languages/translations/pt.d.ts +1189 -0
  265. package/dist/types/data/languages/translations/ru.d.ts +1189 -0
  266. package/dist/types/data/languages/translations/tr.d.ts +1189 -0
  267. package/dist/types/data/languages/translations/zh.d.ts +1189 -0
  268. package/dist/types/data/phoneCodes.d.ts +16 -0
  269. package/dist/types/data/states.d.ts +18 -0
  270. package/dist/types/data/translations/ar.d.ts +1832 -0
  271. package/dist/types/data/translations/de.d.ts +2005 -0
  272. package/dist/types/data/translations/es.d.ts +1852 -0
  273. package/dist/types/data/translations/fr.d.ts +1860 -0
  274. package/dist/types/data/translations/hi.d.ts +1816 -0
  275. package/dist/types/data/translations/it.d.ts +1824 -0
  276. package/dist/types/data/translations/ja.d.ts +1833 -0
  277. package/dist/types/data/translations/ko.d.ts +1832 -0
  278. package/dist/types/data/translations/nl.d.ts +1826 -0
  279. package/dist/types/data/translations/pl.d.ts +1818 -0
  280. package/dist/types/data/translations/pt.d.ts +1829 -0
  281. package/dist/types/data/translations/ru.d.ts +1838 -0
  282. package/dist/types/data/translations/tr.d.ts +1818 -0
  283. package/dist/types/data/translations/zh.d.ts +1834 -0
  284. package/dist/types/data/translations.d.ts +73 -0
  285. package/dist/types/data/worldMap.d.ts +122 -0
  286. package/dist/types/index.d.ts +33 -0
  287. package/dist/types/types/index.d.ts +348 -0
  288. package/dist/types/utils/geo.d.ts +101 -0
  289. package/package.json +67 -0
@@ -0,0 +1,439 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta name="viewport" content="width=device-width, initial-scale=1">
5
+ <meta name="type" content="content">
6
+ <title>arev API Worker Plan</title>
7
+ <link href="/style/app.css" rel="stylesheet" type="text/css">
8
+ </head>
9
+ <body class="page--api-worker-plan">
10
+ <div class="page-container">
11
+ <header class="header">
12
+ <div class="header__container">
13
+ </div>
14
+ </header>
15
+ <main class="main">
16
+ <section class="section">
17
+ <div class="container">
18
+ <div class="content"><h1 id="arev-api-worker-plan" tabindex="-1">arev API Worker Plan</h1>
19
+ <h2 id="goal" tabindex="-1">Goal</h2>
20
+ <p>Expose the full <code>arev</code> library through a simple REST API deployed as a Cloudflare Worker, while keeping this package as the single source of truth for all data and business logic.</p>
21
+ <p>Planned public domains:</p>
22
+ <ul>
23
+ <li>Docs: <code>https://arevdata.com</code></li>
24
+ <li>API: <code>https://api.arevdata.com</code></li>
25
+ </ul>
26
+ <p>The HTTP layer should be thin. Data definitions and lookup logic must stay in the library and be reused directly by the Worker routes.</p>
27
+ <h2 id="core-principles" tabindex="-1">Core Principles</h2>
28
+ <ol>
29
+ <li>The library stays primary.</li>
30
+ <li>The API is an adapter over exported data and functions.</li>
31
+ <li>Route behavior should mirror library behavior as closely as possible.</li>
32
+ <li>Response formats should be predictable and cache-friendly.</li>
33
+ <li>The first version should optimize for clarity, not maximum route compression.</li>
34
+ </ol>
35
+ <h2 id="recommended-package-shape" tabindex="-1">Recommended Package Shape</h2>
36
+ <p>Keep everything in this package for now, but separate the library and Worker entrypoints clearly.</p>
37
+ <p>Suggested structure:</p>
38
+ <pre class="language-text"><code class="language-text">src/
39
+ index.ts
40
+ api/
41
+ index.ts
42
+ router.ts
43
+ response.ts
44
+ query.ts
45
+ errors.ts
46
+ routes/
47
+ countries.ts
48
+ cities.ts
49
+ states.ts
50
+ continents.ts
51
+ currencies.ts
52
+ phoneCodes.ts
53
+ geography.ts
54
+ flags.ts
55
+ languages.ts
56
+ translations.ts
57
+ maps.ts
58
+ health.ts
59
+ </code></pre>
60
+ <p>This preserves <code>src/index.ts</code> for library consumers and gives Cloudflare a dedicated Worker entrypoint at <code>src/api/index.ts</code>.</p>
61
+ <h2 id="worker-runtime-choice" tabindex="-1">Worker Runtime Choice</h2>
62
+ <p>Use a plain Cloudflare Worker with a small internal router instead of adding a heavy framework.</p>
63
+ <p>Why:</p>
64
+ <ul>
65
+ <li>The API surface is data-heavy and logic-light.</li>
66
+ <li>Native <code>Request</code> and <code>Response</code> are enough.</li>
67
+ <li>It avoids coupling the package to a larger framework before the route model stabilizes.</li>
68
+ <li>Testability stays simple.</li>
69
+ </ul>
70
+ <p>If route volume becomes hard to maintain, adding <code>hono</code> later is reasonable, but it is not required for the first version.</p>
71
+ <h2 id="api-design" tabindex="-1">API Design</h2>
72
+ <p>Use resource-oriented routes for data collections and resource-specific routes for direct lookups.</p>
73
+ <h3 id="base-routes" tabindex="-1">Base routes</h3>
74
+ <pre class="language-text"><code class="language-text">GET /health
75
+ GET /meta
76
+ </code></pre>
77
+ <p><code>/meta</code> should return supported locales, available resources, version, and maybe counts for major datasets.</p>
78
+ <h3 id="countries" tabindex="-1">Countries</h3>
79
+ <pre class="language-text"><code class="language-text">GET /countries
80
+ GET /countries/:alpha2
81
+ GET /countries/:alpha2/flag
82
+ GET /countries/:alpha2/geography
83
+ GET /countries/:alpha2/cities
84
+ GET /countries/:alpha2/states
85
+ GET /countries/:alpha2/currency
86
+ GET /countries/:alpha2/languages
87
+ GET /countries/:alpha2/neighbors
88
+ </code></pre>
89
+ <p>Query params:</p>
90
+ <ul>
91
+ <li><code>lang=en</code></li>
92
+ <li><code>recognized=true|false</code></li>
93
+ <li><code>continent=Europe</code></li>
94
+ </ul>
95
+ <h3 id="cities" tabindex="-1">Cities</h3>
96
+ <pre class="language-text"><code class="language-text">GET /cities
97
+ GET /cities/search?q=amst
98
+ GET /cities/capital/:alpha2
99
+ </code></pre>
100
+ <p>Query params:</p>
101
+ <ul>
102
+ <li><code>country=NL</code></li>
103
+ <li><code>limit=50</code></li>
104
+ <li><code>sort=population</code></li>
105
+ <li><code>lang=en</code></li>
106
+ </ul>
107
+ <h3 id="states" tabindex="-1">States</h3>
108
+ <pre class="language-text"><code class="language-text">GET /states
109
+ GET /states/:country/:code
110
+ </code></pre>
111
+ <p>Query params:</p>
112
+ <ul>
113
+ <li><code>country=US</code></li>
114
+ <li><code>type=province</code></li>
115
+ </ul>
116
+ <h3 id="continents" tabindex="-1">Continents</h3>
117
+ <pre class="language-text"><code class="language-text">GET /continents
118
+ GET /continents/:code
119
+ GET /continents/:code/countries
120
+ </code></pre>
121
+ <h3 id="currencies" tabindex="-1">Currencies</h3>
122
+ <pre class="language-text"><code class="language-text">GET /currencies
123
+ GET /currencies/:code
124
+ GET /currencies/by-country/:alpha2
125
+ </code></pre>
126
+ <p>Query params:</p>
127
+ <ul>
128
+ <li><code>lang=en</code></li>
129
+ </ul>
130
+ <h3 id="phone-codes" tabindex="-1">Phone Codes</h3>
131
+ <pre class="language-text"><code class="language-text">GET /phone-codes
132
+ GET /phone-codes/:code
133
+ GET /phone-codes/by-country/:alpha2
134
+ </code></pre>
135
+ <p><code>/phone-codes/:code</code> should accept <code>+31</code> and <code>31</code>.</p>
136
+ <h3 id="geography" tabindex="-1">Geography</h3>
137
+ <pre class="language-text"><code class="language-text">GET /geography
138
+ GET /geography/:alpha2
139
+ GET /geography/climate/:climate
140
+ GET /geography/landlocked
141
+ GET /geography/border/:alpha2/:alpha2B
142
+ GET /geography/distance/:alpha2/:alpha2B
143
+ GET /geography/direction/:alpha2/:alpha2B
144
+ GET /geography/hints/:guess/:target
145
+ </code></pre>
146
+ <h3 id="flags" tabindex="-1">Flags</h3>
147
+ <pre class="language-text"><code class="language-text">GET /flags
148
+ GET /flags/:alpha2
149
+ GET /flags/:alpha2/similar
150
+ GET /flags/color/:color
151
+ GET /flags/:alpha2/svg
152
+ GET /flags/:alpha2/png?width=320
153
+ </code></pre>
154
+ <p>For <code>/svg</code> and <code>/png</code>, first version should return JSON with upstream URLs, not proxy binary assets.</p>
155
+ <h3 id="languages" tabindex="-1">Languages</h3>
156
+ <pre class="language-text"><code class="language-text">GET /languages
157
+ GET /languages/:code
158
+ GET /languages/:code/variants
159
+ GET /languages/:code/countries
160
+ GET /languages/by-country/:alpha2
161
+ GET /languages/search?q=engl
162
+ </code></pre>
163
+ <p>Query params:</p>
164
+ <ul>
165
+ <li><code>locale=en</code></li>
166
+ <li><code>includeVariants=true|false</code></li>
167
+ <li><code>minSpeakers=50000000</code></li>
168
+ </ul>
169
+ <h3 id="translations" tabindex="-1">Translations</h3>
170
+ <pre class="language-text"><code class="language-text">GET /translations/languages
171
+ GET /translations/:lang
172
+ </code></pre>
173
+ <p>This is useful for clients that want the translation maps directly.</p>
174
+ <h3 id="maps" tabindex="-1">Maps</h3>
175
+ <pre class="language-text"><code class="language-text">GET /maps/world
176
+ GET /maps/world/countries
177
+ GET /maps/world/countries/:code
178
+ GET /maps/countries/:alpha2/svg
179
+ GET /maps/countries/:alpha3/subdivisions
180
+ </code></pre>
181
+ <p>For <code>/maps/world</code>, support query params that map to existing helpers where practical:</p>
182
+ <ul>
183
+ <li><code>highlight=NL,BE,DE</code></li>
184
+ <li><code>stroke=#ffffff</code></li>
185
+ <li><code>fill=#d9d9d9</code></li>
186
+ <li><code>background=transparent</code></li>
187
+ </ul>
188
+ <p>Important: the first version should avoid exposing every rendering option if it makes validation messy. Start with a small safe subset.</p>
189
+ <h2 id="response-model" tabindex="-1">Response Model</h2>
190
+ <p>Use plain JSON consistently.</p>
191
+ <p>Success:</p>
192
+ <pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
193
+ <span class="token property">"data"</span><span class="token operator">:</span> <span class="token punctuation">{</span><span class="token punctuation">}</span>
194
+ <span class="token punctuation">}</span>
195
+ </code></pre>
196
+ <p>Collection responses:</p>
197
+ <pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
198
+ <span class="token property">"data"</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token punctuation">,</span>
199
+ <span class="token property">"meta"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
200
+ <span class="token property">"count"</span><span class="token operator">:</span> <span class="token number">0</span>
201
+ <span class="token punctuation">}</span>
202
+ <span class="token punctuation">}</span>
203
+ </code></pre>
204
+ <p>Errors:</p>
205
+ <pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
206
+ <span class="token property">"error"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
207
+ <span class="token property">"code"</span><span class="token operator">:</span> <span class="token string">"not_found"</span><span class="token punctuation">,</span>
208
+ <span class="token property">"message"</span><span class="token operator">:</span> <span class="token string">"Country not found"</span>
209
+ <span class="token punctuation">}</span>
210
+ <span class="token punctuation">}</span>
211
+ </code></pre>
212
+ <p>Recommended status codes:</p>
213
+ <ul>
214
+ <li><code>200</code> for success</li>
215
+ <li><code>400</code> for invalid query/path input</li>
216
+ <li><code>404</code> for unknown resource</li>
217
+ <li><code>405</code> for unsupported method</li>
218
+ <li><code>500</code> for unexpected runtime failures</li>
219
+ </ul>
220
+ <h2 id="mapping-strategy" tabindex="-1">Mapping Strategy</h2>
221
+ <p>The Worker should call the existing exports directly.</p>
222
+ <p>Examples:</p>
223
+ <ul>
224
+ <li><code>GET /countries/:alpha2</code> -&gt; <code>getCountryByCode(alpha2, lang)</code></li>
225
+ <li><code>GET /cities/search?q=tok</code> -&gt; <code>searchCities(q, lang)</code></li>
226
+ <li><code>GET /languages/search?q=engl</code> -&gt; <code>searchLanguages(q, { includeVariants, locale, minSpeakers })</code></li>
227
+ <li><code>GET /geography/hints/:guess/:target</code> -&gt; <code>getGeoHints(guess, target)</code></li>
228
+ </ul>
229
+ <p>This is the critical design rule: do not reimplement lookup logic in the route handlers.</p>
230
+ <h2 id="validation-and-query-parsing" tabindex="-1">Validation and Query Parsing</h2>
231
+ <p>Add small helpers for:</p>
232
+ <ul>
233
+ <li>boolean parsing</li>
234
+ <li>number parsing</li>
235
+ <li>comma-separated list parsing</li>
236
+ <li>enum validation</li>
237
+ <li>alpha-2 and alpha-3 normalization</li>
238
+ </ul>
239
+ <p>Examples:</p>
240
+ <ul>
241
+ <li><code>parseBoolean(&quot;true&quot;)</code></li>
242
+ <li><code>parseInteger(&quot;50&quot;)</code></li>
243
+ <li><code>parseCsv(&quot;NL,BE,DE&quot;)</code></li>
244
+ <li><code>normalizeCountryCode(&quot;nl&quot;) -&gt; &quot;NL&quot;</code></li>
245
+ </ul>
246
+ <p>Centralizing this keeps handlers small and consistent.</p>
247
+ <h2 id="bundle-size-and-performance" tabindex="-1">Bundle Size and Performance</h2>
248
+ <p>This matters because the Worker will include large static datasets.</p>
249
+ <p>The main risks are:</p>
250
+ <ol>
251
+ <li>Large Worker bundle size.</li>
252
+ <li>Cold starts caused by parsing large modules.</li>
253
+ <li>Duplicating imports between library and API entrypoints.</li>
254
+ </ol>
255
+ <p>Recommended mitigations:</p>
256
+ <ol>
257
+ <li>Reuse the existing data files and avoid copying or transforming them at runtime.</li>
258
+ <li>Keep route modules thin and import only what each route needs.</li>
259
+ <li>Measure final Worker bundle size before expanding the API surface further.</li>
260
+ <li>Consider splitting especially heavy features later if Cloudflare size limits become a problem.</li>
261
+ </ol>
262
+ <p>The language dataset looks like the biggest likely pressure point.</p>
263
+ <p>If needed later, there are two fallback options:</p>
264
+ <ol>
265
+ <li>Put the large datasets into KV/R2 or static assets and load them through the Worker.</li>
266
+ <li>Split the deployment into multiple Workers by domain area.</li>
267
+ </ol>
268
+ <p>I would not start there. First measure the simple in-package Worker.</p>
269
+ <h2 id="caching" tabindex="-1">Caching</h2>
270
+ <p>Most endpoints are static and should be aggressively cacheable.</p>
271
+ <p>Recommended headers:</p>
272
+ <ul>
273
+ <li><code>Cache-Control: public, max-age=3600, s-maxage=86400</code></li>
274
+ </ul>
275
+ <p>Potentially longer for immutable data:</p>
276
+ <ul>
277
+ <li><code>Cache-Control: public, max-age=86400, s-maxage=604800</code></li>
278
+ </ul>
279
+ <p>For endpoints driven only by static data, Cloudflare cache should work very well.</p>
280
+ <h2 id="testing-strategy" tabindex="-1">Testing Strategy</h2>
281
+ <p>Add API-focused tests next to the Worker code.</p>
282
+ <p>Suggested test areas:</p>
283
+ <ol>
284
+ <li>Route success cases.</li>
285
+ <li>Input validation failures.</li>
286
+ <li>Not-found behavior.</li>
287
+ <li>Query-param handling.</li>
288
+ <li>Response shape consistency.</li>
289
+ </ol>
290
+ <p>Suggested files:</p>
291
+ <pre class="language-text"><code class="language-text">src/api/routes/countries.test.ts
292
+ src/api/routes/languages.test.ts
293
+ src/api/routes/geography.test.ts
294
+ src/api/router.test.ts
295
+ </code></pre>
296
+ <p>Use the Worker <code>fetch()</code> handler directly in tests.</p>
297
+ <h2 id="build-and-deployment" tabindex="-1">Build and Deployment</h2>
298
+ <p>Add Cloudflare-specific files later:</p>
299
+ <pre class="language-text"><code class="language-text">wrangler.jsonc
300
+ </code></pre>
301
+ <p>Suggested scripts:</p>
302
+ <pre class="language-json"><code class="language-json"><span class="token punctuation">{</span>
303
+ <span class="token property">"build:api"</span><span class="token operator">:</span> <span class="token string">"tsc -p tsconfig.json"</span><span class="token punctuation">,</span>
304
+ <span class="token property">"dev:api"</span><span class="token operator">:</span> <span class="token string">"wrangler dev src/api/index.ts"</span><span class="token punctuation">,</span>
305
+ <span class="token property">"deploy:api"</span><span class="token operator">:</span> <span class="token string">"wrangler deploy src/api/index.ts"</span>
306
+ <span class="token punctuation">}</span>
307
+ </code></pre>
308
+ <p>The exact build command may change depending on whether Wrangler handles bundling directly. The important part is to keep the library build and Worker deployment concerns separate.</p>
309
+ <h2 id="recommended-implementation-order" tabindex="-1">Recommended Implementation Order</h2>
310
+ <h3 id="phase-1%3A-minimal-worker-skeleton" tabindex="-1">Phase 1: Minimal Worker skeleton</h3>
311
+ <ul>
312
+ <li>Add <code>src/api/index.ts</code></li>
313
+ <li>Add a tiny router</li>
314
+ <li>Add <code>json()</code> and <code>error()</code> response helpers</li>
315
+ <li>Add <code>/health</code> and <code>/meta</code></li>
316
+ </ul>
317
+ <h3 id="phase-2%3A-core-read-only-resources" tabindex="-1">Phase 2: Core read-only resources</h3>
318
+ <ul>
319
+ <li><code>countries</code></li>
320
+ <li><code>cities</code></li>
321
+ <li><code>states</code></li>
322
+ <li><code>continents</code></li>
323
+ <li><code>currencies</code></li>
324
+ <li><code>phone-codes</code></li>
325
+ </ul>
326
+ <h3 id="phase-3%3A-function-backed-routes" tabindex="-1">Phase 3: Function-backed routes</h3>
327
+ <ul>
328
+ <li><code>languages</code></li>
329
+ <li><code>geography</code></li>
330
+ <li><code>flags</code></li>
331
+ <li><code>maps</code></li>
332
+ </ul>
333
+ <h3 id="phase-4%3A-hardening" tabindex="-1">Phase 4: Hardening</h3>
334
+ <ul>
335
+ <li>cache headers</li>
336
+ <li>route tests</li>
337
+ <li>not-found and validation consistency</li>
338
+ <li>README API docs</li>
339
+ <li>Wrangler config and deployment workflow</li>
340
+ </ul>
341
+ <h2 id="important-decisions-to-make-early" tabindex="-1">Important Decisions To Make Early</h2>
342
+ <ol>
343
+ <li>Should all collection endpoints support pagination, or should the first version always return the full dataset?</li>
344
+ <li>Should map endpoints return JSON metadata only, or raw SVG text where relevant?</li>
345
+ <li>Do we want to expose translated responses through <code>lang</code>, <code>locale</code>, or both depending on domain?</li>
346
+ <li>Do we want one Worker for everything, or do we keep the option open to split later by domain?</li>
347
+ </ol>
348
+ <p>My recommendation for v1:</p>
349
+ <ol>
350
+ <li>No pagination unless an endpoint is clearly large or search-based.</li>
351
+ <li>Return raw SVG only for explicit SVG endpoints.</li>
352
+ <li>Use <code>lang</code> for translated data and <code>locale</code> only where the library already uses locale semantics for language names.</li>
353
+ <li>Start with one Worker.</li>
354
+ </ol>
355
+ <h2 id="risks" tabindex="-1">Risks</h2>
356
+ <ol>
357
+ <li>The Worker bundle may become too large once languages and maps are included.</li>
358
+ <li>Route sprawl can get messy if handlers are not grouped by domain from the start.</li>
359
+ <li>If route behavior diverges from library behavior, the API will become a second source of truth.</li>
360
+ <li>Some existing library helpers return plain values or strings, while the API needs normalized JSON envelopes.</li>
361
+ </ol>
362
+ <h2 id="recommendation" tabindex="-1">Recommendation</h2>
363
+ <p>Build this as a thin Cloudflare Worker adapter inside the same package, with the library unchanged as the underlying source of truth.</p>
364
+ <p>Do not start by trying to expose every single function through generic RPC-like routes. A clear REST surface over the current domain groups will be easier to understand, cache, test, and document.</p>
365
+
366
+ </div>
367
+ </div>
368
+ </section>
369
+ </main>
370
+ </div>
371
+ <footer class="footer">
372
+ <div class="footer__container">
373
+ <div class="footer__controls">
374
+ <div class="footer__control"><span class="footer__label">Theme</span>
375
+ <button class="color-mode-toggle" type="button" data-color-mode-toggle aria-label="Toggle color mode"><span class="color-mode-toggle__value"></span></button>
376
+ </div>
377
+ </div>
378
+ </div>
379
+ </footer>
380
+ </body>
381
+ <script>const isDarkMode = window.matchMedia("prefers-color-scheme: dark").matches;
382
+ let localMode = isDarkMode ? "dark" : "light";
383
+
384
+ const updateColorModeToggle = () => {
385
+ const toggle = document.querySelector("[data-color-mode-toggle]");
386
+ if (!toggle) return;
387
+
388
+ const value = toggle.querySelector(".color-mode-toggle__value");
389
+ if (!value) return;
390
+
391
+ value.textContent = localMode === "dark" ? "Dark" : "Light";
392
+ };
393
+
394
+ const initColorMode = () => {
395
+ localMode = localStorage.getItem("colorMode");
396
+ setCurrentMode(localMode ? localMode : isDarkMode ? "dark" : "light");
397
+ };
398
+
399
+ const setCurrentMode = (mode) => {
400
+ localMode = mode;
401
+ localStorage.setItem("colorMode", localMode);
402
+ document.body.setAttribute("color-mode", mode);
403
+ updateColorModeToggle();
404
+ };
405
+
406
+ const switchMode = () => {
407
+ if (localMode == "dark") setCurrentMode("light");
408
+ else setCurrentMode("dark");
409
+ };
410
+
411
+ const bindColorModeToggle = () => {
412
+ const toggle = document.querySelector("[data-color-mode-toggle]");
413
+ if (!toggle) return;
414
+
415
+ toggle.addEventListener("click", () => {
416
+ switchMode();
417
+ });
418
+ };
419
+
420
+ initColorMode();
421
+ bindColorModeToggle();
422
+ const container = document.querySelector(".container").querySelectorAll("*");
423
+
424
+ container.forEach((el) => {
425
+ const text = el.innerText;
426
+ if (el.innerHTML == el.textContent)
427
+ if (text) {
428
+ const matches = text.match(/#[a-fA-F0-9]{6}|#[a-fA-F0-9]{3}/i);
429
+ if (matches) {
430
+ el.innerHTML = el.innerHTML.replace(
431
+ matches[0],
432
+ `<span class="color-preview" style="--color-preview:${matches[0]}">${matches[0]}</span>`
433
+ );
434
+ }
435
+ }
436
+ });
437
+
438
+ </script>
439
+ </html>