@shopify/ui-extensions-server-kit 0.0.0-snapshot-20240814205424

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 (367) hide show
  1. package/CHANGELOG.md +127 -0
  2. package/README.md +74 -0
  3. package/dist/ExtensionServerClient/ExtensionServerClient.cjs.js +1 -0
  4. package/dist/ExtensionServerClient/ExtensionServerClient.d.ts +28 -0
  5. package/dist/ExtensionServerClient/ExtensionServerClient.es.js +133 -0
  6. package/dist/ExtensionServerClient/ExtensionServerClient.test.d.ts +1 -0
  7. package/dist/ExtensionServerClient/index.d.ts +2 -0
  8. package/dist/ExtensionServerClient/types.cjs.js +1 -0
  9. package/dist/ExtensionServerClient/types.d.ts +124 -0
  10. package/dist/ExtensionServerClient/types.es.js +4 -0
  11. package/dist/context/ExtensionServerProvider.cjs.js +1 -0
  12. package/dist/context/ExtensionServerProvider.d.ts +2 -0
  13. package/dist/context/ExtensionServerProvider.es.js +29 -0
  14. package/dist/context/ExtensionServerProvider.test.d.ts +1 -0
  15. package/dist/context/constants.cjs.js +1 -0
  16. package/dist/context/constants.d.ts +3 -0
  17. package/dist/context/constants.es.js +14 -0
  18. package/dist/context/index.d.ts +3 -0
  19. package/dist/context/types.d.ts +11 -0
  20. package/dist/hooks/index.d.ts +5 -0
  21. package/dist/hooks/useExtensionClient.cjs.js +1 -0
  22. package/dist/hooks/useExtensionClient.d.ts +1 -0
  23. package/dist/hooks/useExtensionClient.es.js +8 -0
  24. package/dist/hooks/useExtensionServerContext.cjs.js +1 -0
  25. package/dist/hooks/useExtensionServerContext.d.ts +1 -0
  26. package/dist/hooks/useExtensionServerContext.es.js +6 -0
  27. package/dist/hooks/useExtensionServerEvent.cjs.js +1 -0
  28. package/dist/hooks/useExtensionServerEvent.d.ts +1 -0
  29. package/dist/hooks/useExtensionServerEvent.es.js +9 -0
  30. package/dist/hooks/useExtensionServerState.cjs.js +1 -0
  31. package/dist/hooks/useExtensionServerState.d.ts +1 -0
  32. package/dist/hooks/useExtensionServerState.es.js +9 -0
  33. package/dist/hooks/useIsomorphicLayoutEffect.cjs.js +1 -0
  34. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +2 -0
  35. package/dist/hooks/useIsomorphicLayoutEffect.es.js +5 -0
  36. package/dist/i18n.cjs.js +1 -0
  37. package/dist/i18n.d.ts +93 -0
  38. package/dist/i18n.es.js +61 -0
  39. package/dist/i18n.test.d.ts +1 -0
  40. package/dist/index.cjs.js +1 -0
  41. package/dist/index.cjs2.js +1 -0
  42. package/dist/index.d.ts +7 -0
  43. package/dist/index.es.js +54 -0
  44. package/dist/index.es2.js +8 -0
  45. package/dist/state/actions/actions.cjs.js +1 -0
  46. package/dist/state/actions/actions.d.ts +6 -0
  47. package/dist/state/actions/actions.es.js +37 -0
  48. package/dist/state/actions/index.d.ts +2 -0
  49. package/dist/state/actions/types.d.ts +21 -0
  50. package/dist/state/index.d.ts +2 -0
  51. package/dist/state/reducers/constants.cjs.js +1 -0
  52. package/dist/state/reducers/constants.d.ts +2 -0
  53. package/dist/state/reducers/constants.es.js +7 -0
  54. package/dist/state/reducers/extensionServerReducer.cjs.js +1 -0
  55. package/dist/state/reducers/extensionServerReducer.d.ts +3 -0
  56. package/dist/state/reducers/extensionServerReducer.es.js +57 -0
  57. package/dist/state/reducers/extensionServerReducer.test.d.ts +1 -0
  58. package/dist/state/reducers/index.d.ts +3 -0
  59. package/dist/state/reducers/types.d.ts +6 -0
  60. package/dist/testing/MockExtensionServerProvider.cjs.js +1 -0
  61. package/dist/testing/MockExtensionServerProvider.d.ts +7 -0
  62. package/dist/testing/MockExtensionServerProvider.es.js +24 -0
  63. package/dist/testing/app.cjs.js +1 -0
  64. package/dist/testing/app.d.ts +2 -0
  65. package/dist/testing/app.es.js +16 -0
  66. package/dist/testing/extensions.cjs.js +1 -0
  67. package/dist/testing/extensions.d.ts +6 -0
  68. package/dist/testing/extensions.es.js +65 -0
  69. package/dist/testing/index.d.ts +3 -0
  70. package/dist/types.cjs.js +1 -0
  71. package/dist/types.d.ts +173 -0
  72. package/dist/types.es.js +4 -0
  73. package/dist/utilities/assetToString.cjs.js +1 -0
  74. package/dist/utilities/assetToString.d.ts +2 -0
  75. package/dist/utilities/assetToString.es.js +7 -0
  76. package/dist/utilities/assetToString.test.d.ts +1 -0
  77. package/dist/utilities/groupByKey.cjs.js +1 -0
  78. package/dist/utilities/groupByKey.d.ts +3 -0
  79. package/dist/utilities/groupByKey.es.js +6 -0
  80. package/dist/utilities/index.d.ts +7 -0
  81. package/dist/utilities/isUIExtension.cjs.js +1 -0
  82. package/dist/utilities/isUIExtension.d.ts +1 -0
  83. package/dist/utilities/isUIExtension.es.js +6 -0
  84. package/dist/utilities/isValidSurface.cjs.js +1 -0
  85. package/dist/utilities/isValidSurface.d.ts +2 -0
  86. package/dist/utilities/isValidSurface.es.js +7 -0
  87. package/dist/utilities/noop.cjs.js +1 -0
  88. package/dist/utilities/noop.d.ts +1 -0
  89. package/dist/utilities/noop.es.js +5 -0
  90. package/dist/utilities/replaceUpdated.cjs.js +1 -0
  91. package/dist/utilities/replaceUpdated.d.ts +1 -0
  92. package/dist/utilities/replaceUpdated.es.js +14 -0
  93. package/dist/utilities/replaceUpdated.test.d.ts +1 -0
  94. package/dist/utilities/set.cjs.js +1 -0
  95. package/dist/utilities/set.d.ts +4 -0
  96. package/dist/utilities/set.es.js +18 -0
  97. package/dist/utilities/set.test.d.ts +1 -0
  98. package/index.d.ts +1 -0
  99. package/index.js +1 -0
  100. package/index.mjs +1 -0
  101. package/node_modules/@shopify/react-testing/LICENSE.md +21 -0
  102. package/node_modules/@shopify/react-testing/README.md +711 -0
  103. package/node_modules/@shopify/react-testing/build/cjs/TestWrapper.js +52 -0
  104. package/node_modules/@shopify/react-testing/build/cjs/_virtual/_rollupPluginBabelHelpers.js +47 -0
  105. package/node_modules/@shopify/react-testing/build/cjs/compat.js +14 -0
  106. package/node_modules/@shopify/react-testing/build/cjs/destroy.js +13 -0
  107. package/node_modules/@shopify/react-testing/build/cjs/element.js +225 -0
  108. package/node_modules/@shopify/react-testing/build/cjs/index.js +21 -0
  109. package/node_modules/@shopify/react-testing/build/cjs/matchers/components.js +46 -0
  110. package/node_modules/@shopify/react-testing/build/cjs/matchers/context.js +25 -0
  111. package/node_modules/@shopify/react-testing/build/cjs/matchers/index.js +16 -0
  112. package/node_modules/@shopify/react-testing/build/cjs/matchers/props.js +38 -0
  113. package/node_modules/@shopify/react-testing/build/cjs/matchers/strings.js +42 -0
  114. package/node_modules/@shopify/react-testing/build/cjs/matchers/utilities.js +110 -0
  115. package/node_modules/@shopify/react-testing/build/cjs/mount.js +76 -0
  116. package/node_modules/@shopify/react-testing/build/cjs/root.js +284 -0
  117. package/node_modules/@shopify/react-testing/build/cjs/toReactString.js +86 -0
  118. package/node_modules/@shopify/react-testing/build/cjs/types.js +28 -0
  119. package/node_modules/@shopify/react-testing/build/esm/TestWrapper.mjs +44 -0
  120. package/node_modules/@shopify/react-testing/build/esm/_virtual/_rollupPluginBabelHelpers.mjs +42 -0
  121. package/node_modules/@shopify/react-testing/build/esm/compat.mjs +10 -0
  122. package/node_modules/@shopify/react-testing/build/esm/destroy.mjs +9 -0
  123. package/node_modules/@shopify/react-testing/build/esm/element.mjs +221 -0
  124. package/node_modules/@shopify/react-testing/build/esm/index.mjs +5 -0
  125. package/node_modules/@shopify/react-testing/build/esm/matchers/components.mjs +41 -0
  126. package/node_modules/@shopify/react-testing/build/esm/matchers/context.mjs +21 -0
  127. package/node_modules/@shopify/react-testing/build/esm/matchers/index.mjs +14 -0
  128. package/node_modules/@shopify/react-testing/build/esm/matchers/props.mjs +33 -0
  129. package/node_modules/@shopify/react-testing/build/esm/matchers/strings.mjs +37 -0
  130. package/node_modules/@shopify/react-testing/build/esm/matchers/utilities.mjs +101 -0
  131. package/node_modules/@shopify/react-testing/build/esm/mount.mjs +70 -0
  132. package/node_modules/@shopify/react-testing/build/esm/root.mjs +275 -0
  133. package/node_modules/@shopify/react-testing/build/esm/toReactString.mjs +80 -0
  134. package/node_modules/@shopify/react-testing/build/esm/types.mjs +26 -0
  135. package/node_modules/@shopify/react-testing/build/esnext/TestWrapper.esnext +44 -0
  136. package/node_modules/@shopify/react-testing/build/esnext/compat.esnext +10 -0
  137. package/node_modules/@shopify/react-testing/build/esnext/destroy.esnext +9 -0
  138. package/node_modules/@shopify/react-testing/build/esnext/element.esnext +221 -0
  139. package/node_modules/@shopify/react-testing/build/esnext/index.esnext +5 -0
  140. package/node_modules/@shopify/react-testing/build/esnext/matchers/components.esnext +41 -0
  141. package/node_modules/@shopify/react-testing/build/esnext/matchers/context.esnext +21 -0
  142. package/node_modules/@shopify/react-testing/build/esnext/matchers/index.esnext +14 -0
  143. package/node_modules/@shopify/react-testing/build/esnext/matchers/props.esnext +33 -0
  144. package/node_modules/@shopify/react-testing/build/esnext/matchers/strings.esnext +37 -0
  145. package/node_modules/@shopify/react-testing/build/esnext/matchers/utilities.esnext +99 -0
  146. package/node_modules/@shopify/react-testing/build/esnext/mount.esnext +71 -0
  147. package/node_modules/@shopify/react-testing/build/esnext/root.esnext +275 -0
  148. package/node_modules/@shopify/react-testing/build/esnext/toReactString.esnext +80 -0
  149. package/node_modules/@shopify/react-testing/build/esnext/types.esnext +26 -0
  150. package/node_modules/@shopify/react-testing/build/ts/TestWrapper.d.ts +17 -0
  151. package/node_modules/@shopify/react-testing/build/ts/TestWrapper.d.ts.map +1 -0
  152. package/node_modules/@shopify/react-testing/build/ts/compat.d.ts +3 -0
  153. package/node_modules/@shopify/react-testing/build/ts/compat.d.ts.map +1 -0
  154. package/node_modules/@shopify/react-testing/build/ts/destroy.d.ts +2 -0
  155. package/node_modules/@shopify/react-testing/build/ts/destroy.d.ts.map +1 -0
  156. package/node_modules/@shopify/react-testing/build/ts/element.d.ts +42 -0
  157. package/node_modules/@shopify/react-testing/build/ts/element.d.ts.map +1 -0
  158. package/node_modules/@shopify/react-testing/build/ts/index.d.ts +7 -0
  159. package/node_modules/@shopify/react-testing/build/ts/index.d.ts.map +1 -0
  160. package/node_modules/@shopify/react-testing/build/ts/matchers/components.d.ts +12 -0
  161. package/node_modules/@shopify/react-testing/build/ts/matchers/components.d.ts.map +1 -0
  162. package/node_modules/@shopify/react-testing/build/ts/matchers/context.d.ts +8 -0
  163. package/node_modules/@shopify/react-testing/build/ts/matchers/context.d.ts.map +1 -0
  164. package/node_modules/@shopify/react-testing/build/ts/matchers/index.d.ts +20 -0
  165. package/node_modules/@shopify/react-testing/build/ts/matchers/index.d.ts.map +1 -0
  166. package/node_modules/@shopify/react-testing/build/ts/matchers/props.d.ts +10 -0
  167. package/node_modules/@shopify/react-testing/build/ts/matchers/props.d.ts.map +1 -0
  168. package/node_modules/@shopify/react-testing/build/ts/matchers/strings.d.ts +11 -0
  169. package/node_modules/@shopify/react-testing/build/ts/matchers/strings.d.ts.map +1 -0
  170. package/node_modules/@shopify/react-testing/build/ts/matchers/utilities.d.ts +17 -0
  171. package/node_modules/@shopify/react-testing/build/ts/matchers/utilities.d.ts.map +1 -0
  172. package/node_modules/@shopify/react-testing/build/ts/mount.d.ts +39 -0
  173. package/node_modules/@shopify/react-testing/build/ts/mount.d.ts.map +1 -0
  174. package/node_modules/@shopify/react-testing/build/ts/root.d.ts +55 -0
  175. package/node_modules/@shopify/react-testing/build/ts/root.d.ts.map +1 -0
  176. package/node_modules/@shopify/react-testing/build/ts/toReactString.d.ts +5 -0
  177. package/node_modules/@shopify/react-testing/build/ts/toReactString.d.ts.map +1 -0
  178. package/node_modules/@shopify/react-testing/build/ts/types.d.ts +89 -0
  179. package/node_modules/@shopify/react-testing/build/ts/types.d.ts.map +1 -0
  180. package/node_modules/@shopify/react-testing/index.esnext +1 -0
  181. package/node_modules/@shopify/react-testing/index.js +1 -0
  182. package/node_modules/@shopify/react-testing/index.mjs +1 -0
  183. package/node_modules/@shopify/react-testing/matchers.esnext +1 -0
  184. package/node_modules/@shopify/react-testing/matchers.js +1 -0
  185. package/node_modules/@shopify/react-testing/matchers.mjs +1 -0
  186. package/node_modules/@shopify/react-testing/package.json +69 -0
  187. package/node_modules/@shopify/ui-extensions-test-utils/CHANGELOG.md +66 -0
  188. package/node_modules/@shopify/ui-extensions-test-utils/dist/index.js +3 -0
  189. package/node_modules/@shopify/ui-extensions-test-utils/dist/render.js +5 -0
  190. package/node_modules/@shopify/ui-extensions-test-utils/dist/renderHook.js +20 -0
  191. package/node_modules/@shopify/ui-extensions-test-utils/dist/withProviders.js +6 -0
  192. package/node_modules/@shopify/ui-extensions-test-utils/package.json +41 -0
  193. package/node_modules/@shopify/ui-extensions-test-utils/project.json +39 -0
  194. package/node_modules/@types/node/LICENSE +21 -0
  195. package/node_modules/@types/node/README.md +15 -0
  196. package/node_modules/@types/node/assert/strict.d.ts +8 -0
  197. package/node_modules/@types/node/assert.d.ts +985 -0
  198. package/node_modules/@types/node/async_hooks.d.ts +522 -0
  199. package/node_modules/@types/node/buffer.d.ts +2321 -0
  200. package/node_modules/@types/node/child_process.d.ts +1544 -0
  201. package/node_modules/@types/node/cluster.d.ts +432 -0
  202. package/node_modules/@types/node/console.d.ts +412 -0
  203. package/node_modules/@types/node/constants.d.ts +19 -0
  204. package/node_modules/@types/node/crypto.d.ts +4451 -0
  205. package/node_modules/@types/node/dgram.d.ts +586 -0
  206. package/node_modules/@types/node/diagnostics_channel.d.ts +192 -0
  207. package/node_modules/@types/node/dns/promises.d.ts +381 -0
  208. package/node_modules/@types/node/dns.d.ts +809 -0
  209. package/node_modules/@types/node/dom-events.d.ts +122 -0
  210. package/node_modules/@types/node/domain.d.ts +170 -0
  211. package/node_modules/@types/node/events.d.ts +803 -0
  212. package/node_modules/@types/node/fs/promises.d.ts +1205 -0
  213. package/node_modules/@types/node/fs.d.ts +4211 -0
  214. package/node_modules/@types/node/globals.d.ts +377 -0
  215. package/node_modules/@types/node/globals.global.d.ts +1 -0
  216. package/node_modules/@types/node/http.d.ts +1801 -0
  217. package/node_modules/@types/node/http2.d.ts +2386 -0
  218. package/node_modules/@types/node/https.d.ts +544 -0
  219. package/node_modules/@types/node/index.d.ts +88 -0
  220. package/node_modules/@types/node/inspector.d.ts +2739 -0
  221. package/node_modules/@types/node/module.d.ts +298 -0
  222. package/node_modules/@types/node/net.d.ts +913 -0
  223. package/node_modules/@types/node/os.d.ts +473 -0
  224. package/node_modules/@types/node/package.json +235 -0
  225. package/node_modules/@types/node/path.d.ts +191 -0
  226. package/node_modules/@types/node/perf_hooks.d.ts +626 -0
  227. package/node_modules/@types/node/process.d.ts +1531 -0
  228. package/node_modules/@types/node/punycode.d.ts +117 -0
  229. package/node_modules/@types/node/querystring.d.ts +141 -0
  230. package/node_modules/@types/node/readline/promises.d.ts +143 -0
  231. package/node_modules/@types/node/readline.d.ts +666 -0
  232. package/node_modules/@types/node/repl.d.ts +430 -0
  233. package/node_modules/@types/node/stream/consumers.d.ts +12 -0
  234. package/node_modules/@types/node/stream/promises.d.ts +83 -0
  235. package/node_modules/@types/node/stream/web.d.ts +336 -0
  236. package/node_modules/@types/node/stream.d.ts +1731 -0
  237. package/node_modules/@types/node/string_decoder.d.ts +67 -0
  238. package/node_modules/@types/node/test.d.ts +1113 -0
  239. package/node_modules/@types/node/timers/promises.d.ts +93 -0
  240. package/node_modules/@types/node/timers.d.ts +126 -0
  241. package/node_modules/@types/node/tls.d.ts +1203 -0
  242. package/node_modules/@types/node/trace_events.d.ts +171 -0
  243. package/node_modules/@types/node/ts4.8/assert/strict.d.ts +8 -0
  244. package/node_modules/@types/node/ts4.8/assert.d.ts +985 -0
  245. package/node_modules/@types/node/ts4.8/async_hooks.d.ts +522 -0
  246. package/node_modules/@types/node/ts4.8/buffer.d.ts +2321 -0
  247. package/node_modules/@types/node/ts4.8/child_process.d.ts +1544 -0
  248. package/node_modules/@types/node/ts4.8/cluster.d.ts +432 -0
  249. package/node_modules/@types/node/ts4.8/console.d.ts +412 -0
  250. package/node_modules/@types/node/ts4.8/constants.d.ts +19 -0
  251. package/node_modules/@types/node/ts4.8/crypto.d.ts +4450 -0
  252. package/node_modules/@types/node/ts4.8/dgram.d.ts +586 -0
  253. package/node_modules/@types/node/ts4.8/diagnostics_channel.d.ts +192 -0
  254. package/node_modules/@types/node/ts4.8/dns/promises.d.ts +381 -0
  255. package/node_modules/@types/node/ts4.8/dns.d.ts +809 -0
  256. package/node_modules/@types/node/ts4.8/dom-events.d.ts +122 -0
  257. package/node_modules/@types/node/ts4.8/domain.d.ts +170 -0
  258. package/node_modules/@types/node/ts4.8/events.d.ts +754 -0
  259. package/node_modules/@types/node/ts4.8/fs/promises.d.ts +1205 -0
  260. package/node_modules/@types/node/ts4.8/fs.d.ts +4211 -0
  261. package/node_modules/@types/node/ts4.8/globals.d.ts +377 -0
  262. package/node_modules/@types/node/ts4.8/globals.global.d.ts +1 -0
  263. package/node_modules/@types/node/ts4.8/http.d.ts +1801 -0
  264. package/node_modules/@types/node/ts4.8/http2.d.ts +2386 -0
  265. package/node_modules/@types/node/ts4.8/https.d.ts +544 -0
  266. package/node_modules/@types/node/ts4.8/index.d.ts +88 -0
  267. package/node_modules/@types/node/ts4.8/inspector.d.ts +2739 -0
  268. package/node_modules/@types/node/ts4.8/module.d.ts +298 -0
  269. package/node_modules/@types/node/ts4.8/net.d.ts +913 -0
  270. package/node_modules/@types/node/ts4.8/os.d.ts +473 -0
  271. package/node_modules/@types/node/ts4.8/path.d.ts +191 -0
  272. package/node_modules/@types/node/ts4.8/perf_hooks.d.ts +626 -0
  273. package/node_modules/@types/node/ts4.8/process.d.ts +1531 -0
  274. package/node_modules/@types/node/ts4.8/punycode.d.ts +117 -0
  275. package/node_modules/@types/node/ts4.8/querystring.d.ts +141 -0
  276. package/node_modules/@types/node/ts4.8/readline/promises.d.ts +143 -0
  277. package/node_modules/@types/node/ts4.8/readline.d.ts +666 -0
  278. package/node_modules/@types/node/ts4.8/repl.d.ts +430 -0
  279. package/node_modules/@types/node/ts4.8/stream/consumers.d.ts +12 -0
  280. package/node_modules/@types/node/ts4.8/stream/promises.d.ts +83 -0
  281. package/node_modules/@types/node/ts4.8/stream/web.d.ts +336 -0
  282. package/node_modules/@types/node/ts4.8/stream.d.ts +1731 -0
  283. package/node_modules/@types/node/ts4.8/string_decoder.d.ts +67 -0
  284. package/node_modules/@types/node/ts4.8/test.d.ts +1113 -0
  285. package/node_modules/@types/node/ts4.8/timers/promises.d.ts +93 -0
  286. package/node_modules/@types/node/ts4.8/timers.d.ts +126 -0
  287. package/node_modules/@types/node/ts4.8/tls.d.ts +1203 -0
  288. package/node_modules/@types/node/ts4.8/trace_events.d.ts +171 -0
  289. package/node_modules/@types/node/ts4.8/tty.d.ts +206 -0
  290. package/node_modules/@types/node/ts4.8/url.d.ts +937 -0
  291. package/node_modules/@types/node/ts4.8/util.d.ts +2075 -0
  292. package/node_modules/@types/node/ts4.8/v8.d.ts +541 -0
  293. package/node_modules/@types/node/ts4.8/vm.d.ts +667 -0
  294. package/node_modules/@types/node/ts4.8/wasi.d.ts +158 -0
  295. package/node_modules/@types/node/ts4.8/worker_threads.d.ts +692 -0
  296. package/node_modules/@types/node/ts4.8/zlib.d.ts +517 -0
  297. package/node_modules/@types/node/tty.d.ts +206 -0
  298. package/node_modules/@types/node/url.d.ts +937 -0
  299. package/node_modules/@types/node/util.d.ts +2075 -0
  300. package/node_modules/@types/node/v8.d.ts +541 -0
  301. package/node_modules/@types/node/vm.d.ts +667 -0
  302. package/node_modules/@types/node/wasi.d.ts +158 -0
  303. package/node_modules/@types/node/worker_threads.d.ts +692 -0
  304. package/node_modules/@types/node/zlib.d.ts +517 -0
  305. package/node_modules/@types/react/LICENSE +21 -0
  306. package/node_modules/@types/react/README.md +16 -0
  307. package/node_modules/@types/react/experimental.d.ts +192 -0
  308. package/node_modules/@types/react/global.d.ts +151 -0
  309. package/node_modules/@types/react/index.d.ts +3175 -0
  310. package/node_modules/@types/react/jsx-dev-runtime.d.ts +2 -0
  311. package/node_modules/@types/react/jsx-runtime.d.ts +2 -0
  312. package/node_modules/@types/react/package.json +149 -0
  313. package/node_modules/@vitejs/plugin-react-refresh/LICENSE +21 -0
  314. package/node_modules/@vitejs/plugin-react-refresh/README.md +73 -0
  315. package/node_modules/@vitejs/plugin-react-refresh/index.d.ts +14 -0
  316. package/node_modules/@vitejs/plugin-react-refresh/index.js +239 -0
  317. package/node_modules/@vitejs/plugin-react-refresh/package.json +35 -0
  318. package/package.json +64 -0
  319. package/project.json +74 -0
  320. package/scripts/create-entry-files.ts +44 -0
  321. package/src/ExtensionServerClient/ExtensionServerClient.test.ts +730 -0
  322. package/src/ExtensionServerClient/ExtensionServerClient.ts +310 -0
  323. package/src/ExtensionServerClient/index.ts +2 -0
  324. package/src/ExtensionServerClient/types.ts +159 -0
  325. package/src/context/ExtensionServerProvider.test.tsx +173 -0
  326. package/src/context/ExtensionServerProvider.tsx +46 -0
  327. package/src/context/constants.ts +15 -0
  328. package/src/context/index.ts +3 -0
  329. package/src/context/types.ts +13 -0
  330. package/src/hooks/index.ts +5 -0
  331. package/src/hooks/useExtensionClient.ts +6 -0
  332. package/src/hooks/useExtensionServerContext.ts +4 -0
  333. package/src/hooks/useExtensionServerEvent.ts +11 -0
  334. package/src/hooks/useExtensionServerState.ts +6 -0
  335. package/src/hooks/useIsomorphicLayoutEffect.ts +6 -0
  336. package/src/i18n.test.ts +417 -0
  337. package/src/i18n.ts +208 -0
  338. package/src/index.ts +7 -0
  339. package/src/state/actions/actions.ts +36 -0
  340. package/src/state/actions/index.ts +2 -0
  341. package/src/state/actions/types.ts +26 -0
  342. package/src/state/index.ts +2 -0
  343. package/src/state/reducers/constants.ts +6 -0
  344. package/src/state/reducers/extensionServerReducer.test.ts +160 -0
  345. package/src/state/reducers/extensionServerReducer.ts +87 -0
  346. package/src/state/reducers/index.ts +3 -0
  347. package/src/state/reducers/types.ts +7 -0
  348. package/src/testing/MockExtensionServerProvider.tsx +36 -0
  349. package/src/testing/app.ts +15 -0
  350. package/src/testing/extensions.ts +70 -0
  351. package/src/testing/index.ts +3 -0
  352. package/src/types.ts +177 -0
  353. package/src/utilities/assetToString.test.ts +16 -0
  354. package/src/utilities/assetToString.ts +8 -0
  355. package/src/utilities/groupByKey.ts +3 -0
  356. package/src/utilities/index.ts +7 -0
  357. package/src/utilities/isUIExtension.ts +7 -0
  358. package/src/utilities/isValidSurface.ts +7 -0
  359. package/src/utilities/noop.ts +1 -0
  360. package/src/utilities/replaceUpdated.test.ts +26 -0
  361. package/src/utilities/replaceUpdated.ts +16 -0
  362. package/src/utilities/set.test.ts +19 -0
  363. package/src/utilities/set.ts +29 -0
  364. package/testing.d.ts +1 -0
  365. package/testing.js +1 -0
  366. package/testing.mjs +1 -0
  367. package/tests/setup.ts +6 -0
@@ -0,0 +1,15 @@
1
+ import {ExtensionServerClient} from '../ExtensionServerClient'
2
+ import {INITIAL_STATE} from '../state'
3
+ import {noop} from '../utilities'
4
+ import {createContext} from 'react'
5
+
6
+ import type {ExtensionServerContext} from './types'
7
+
8
+ export const DEFAULT_VALUE: ExtensionServerContext = {
9
+ connect: noop,
10
+ dispatch: noop,
11
+ state: INITIAL_STATE,
12
+ client: new ExtensionServerClient(),
13
+ }
14
+
15
+ export const extensionServerContext = createContext<ExtensionServerContext>(DEFAULT_VALUE)
@@ -0,0 +1,3 @@
1
+ export * from './ExtensionServerProvider'
2
+ export * from './constants'
3
+ export * from './types'
@@ -0,0 +1,13 @@
1
+ import type {ExtensionServerState, ExtensionServerActions} from '../state'
2
+
3
+ export interface ExtensionServerContext {
4
+ client: ExtensionServer.Client
5
+ state: ExtensionServerState
6
+ connect(options?: ExtensionServer.Options): void
7
+ dispatch(action: ExtensionServerActions): void
8
+ }
9
+
10
+ export interface ExtensionServerProviderProps {
11
+ children?: React.ReactNode
12
+ options: ExtensionServer.Options
13
+ }
@@ -0,0 +1,5 @@
1
+ export * from './useExtensionClient'
2
+ export * from './useExtensionServerContext'
3
+ export * from './useExtensionServerEvent'
4
+ export * from './useExtensionServerState'
5
+ export * from './useIsomorphicLayoutEffect'
@@ -0,0 +1,6 @@
1
+ import {useExtensionServerContext} from './useExtensionServerContext'
2
+
3
+ export function useExtensionClient() {
4
+ const {client} = useExtensionServerContext()
5
+ return client
6
+ }
@@ -0,0 +1,4 @@
1
+ import {extensionServerContext} from '../context'
2
+ import {useContext} from 'react'
3
+
4
+ export const useExtensionServerContext = () => useContext(extensionServerContext)
@@ -0,0 +1,11 @@
1
+ import {useExtensionServerContext} from './useExtensionServerContext'
2
+ import {useIsomorphicLayoutEffect} from './useIsomorphicLayoutEffect'
3
+
4
+ export function useExtensionServerEvent<TEvent extends keyof ExtensionServer.InboundEvents>(
5
+ event: TEvent,
6
+ listener: ExtensionServer.EventListener<TEvent>,
7
+ ): void {
8
+ const {client} = useExtensionServerContext()
9
+
10
+ useIsomorphicLayoutEffect(() => client.on(event, listener), [client, event, listener])
11
+ }
@@ -0,0 +1,6 @@
1
+ import {extensionServerReducer, INITIAL_STATE} from '../state'
2
+ import {useReducer} from 'react'
3
+
4
+ export function useExtensionServerState() {
5
+ return useReducer(extensionServerReducer, INITIAL_STATE)
6
+ }
@@ -0,0 +1,6 @@
1
+ import {useEffect, useLayoutEffect} from 'react'
2
+
3
+ const isSSR =
4
+ typeof window === 'undefined' || !window.navigator || /ServerSideRendering|^Deno\//.test(window.navigator.userAgent)
5
+
6
+ export const useIsomorphicLayoutEffect = isSSR ? useEffect : useLayoutEffect
@@ -0,0 +1,417 @@
1
+ import {flattenDevExtensionTranslations, resolveDevExtensionLocale, getFlattenedLocalization} from './i18n'
2
+
3
+ /**
4
+ * These tests were adapted from https://github.com/Shopify/checkout-web/blob/master/app/utilities/development-mode/tests/i18n-utilities.test.tsx
5
+ * */
6
+
7
+ describe('resolveDevExtensionLocale()', () => {
8
+ test('returns the user locale if it is provided as a supported locale', () => {
9
+ const userLocale = 'fr-FR'
10
+
11
+ const localization = {
12
+ defaultLocale: 'en',
13
+ lastUpdated: Date.now(),
14
+ translations: {
15
+ en: {
16
+ greetings: {
17
+ hello: 'Hello',
18
+ },
19
+ },
20
+ de: {
21
+ greetings: {
22
+ hello: 'Hallo',
23
+ },
24
+ },
25
+ 'fr-FR': {
26
+ greetings: {
27
+ hello: 'Bonjour',
28
+ },
29
+ },
30
+ },
31
+ }
32
+
33
+ const extensionLocale = resolveDevExtensionLocale(localization, {user: userLocale})
34
+
35
+ expect(extensionLocale).toBe(userLocale)
36
+ })
37
+
38
+ test('returns the non-regional user locale if there is no exact match with user locale', async () => {
39
+ const userLocale = 'de-DE'
40
+
41
+ const localization = {
42
+ defaultLocale: 'en',
43
+ lastUpdated: Date.now(),
44
+ translations: {
45
+ en: {
46
+ greetings: {
47
+ hello: 'Hello',
48
+ },
49
+ },
50
+ de: {
51
+ greetings: {
52
+ hello: 'Hallo',
53
+ },
54
+ },
55
+ 'fr-FR': {
56
+ greetings: {
57
+ hello: 'Bonjour',
58
+ },
59
+ },
60
+ },
61
+ }
62
+
63
+ const extensionLocale = resolveDevExtensionLocale(localization, {user: userLocale})
64
+
65
+ expect(extensionLocale).toBe(userLocale.split('-')[0])
66
+ })
67
+
68
+ test("returns the shop locale if it is provided as a supported locale and there isn't a match for the user locale", () => {
69
+ const shopLocale = 'fr-FR'
70
+ const userLocale = 'de-DE'
71
+
72
+ const localization = {
73
+ defaultLocale: 'en',
74
+ lastUpdated: Date.now(),
75
+ translations: {
76
+ en: {
77
+ greetings: {
78
+ hello: 'Hello',
79
+ },
80
+ },
81
+ 'fr-FR': {
82
+ greetings: {
83
+ hello: 'Bonjour',
84
+ },
85
+ },
86
+ },
87
+ }
88
+
89
+ const extensionLocale = resolveDevExtensionLocale(localization, {user: userLocale, shop: shopLocale})
90
+
91
+ expect(extensionLocale).toBe(shopLocale)
92
+ })
93
+
94
+ test("returns the non-regional shop locale if it is provided as a supported locale and there isn't a match for the user locale", async () => {
95
+ const userLocale = 'ja-JP'
96
+ const shopLocale = 'de-DE'
97
+
98
+ const localization = {
99
+ defaultLocale: 'en',
100
+ lastUpdated: Date.now(),
101
+ translations: {
102
+ en: {
103
+ greetings: {
104
+ hello: 'Hello',
105
+ },
106
+ },
107
+ de: {
108
+ greetings: {
109
+ hello: 'Hallo',
110
+ },
111
+ },
112
+ },
113
+ }
114
+
115
+ const extensionLocale = resolveDevExtensionLocale(localization, {user: userLocale, shop: shopLocale})
116
+
117
+ expect(extensionLocale).toBe(shopLocale.split('-')[0])
118
+ })
119
+
120
+ test('returns the default translation locale when no full or partial match can be for neither user nor shop locale made', async () => {
121
+ const userLocale = 'en-US'
122
+ const shopLocale = 'ja'
123
+ const defaultLocale = 'fi'
124
+
125
+ const localization = {
126
+ defaultLocale,
127
+ lastUpdated: Date.now(),
128
+ translations: {
129
+ 'en-CA': {
130
+ greetings: {
131
+ hello: 'Hello',
132
+ },
133
+ },
134
+ de: {
135
+ greetings: {
136
+ hello: 'Hallo',
137
+ },
138
+ },
139
+ fi: {
140
+ greetings: {
141
+ hello: 'Hei',
142
+ },
143
+ },
144
+ },
145
+ }
146
+
147
+ const extensionLocale = resolveDevExtensionLocale(localization, {user: userLocale, shop: shopLocale})
148
+
149
+ expect(extensionLocale).toBe(defaultLocale)
150
+ })
151
+ })
152
+
153
+ describe('flattenDevExtensionTranslations()', () => {
154
+ test('returns flattened translation keys using a single locale', () => {
155
+ const resolvedLocale = 'en'
156
+
157
+ const localization = {
158
+ defaultLocale: 'en',
159
+ lastUpdated: Date.now(),
160
+ translations: {
161
+ en: {
162
+ greetings: {
163
+ hello: 'Hello',
164
+ },
165
+ },
166
+ },
167
+ }
168
+
169
+ const flattenedTranslations = flattenDevExtensionTranslations(localization, resolvedLocale)
170
+
171
+ expect(flattenedTranslations).toStrictEqual({
172
+ 'greetings.hello': 'Hello',
173
+ })
174
+ })
175
+
176
+ test('returns flattened and merged translations with fallbacks for missing keys from the default locale', () => {
177
+ const resolvedLocale = 'en-GB'
178
+
179
+ const localization = {
180
+ defaultLocale: 'en',
181
+ lastUpdated: Date.now(),
182
+ translations: {
183
+ en: {
184
+ greetings: {
185
+ hello: 'Hello',
186
+ goodbye: 'Goodbye',
187
+ },
188
+ },
189
+ 'en-GB': {
190
+ greetings: {
191
+ hello: 'Hello, UK',
192
+ },
193
+ },
194
+ fr: {
195
+ greetings: {
196
+ hello: 'Bonjour',
197
+ },
198
+ },
199
+ },
200
+ }
201
+
202
+ const flattenedTranslations = flattenDevExtensionTranslations(localization, resolvedLocale)
203
+
204
+ expect(flattenedTranslations).toStrictEqual({
205
+ 'greetings.hello': 'Hello, UK',
206
+ 'greetings.goodbye': 'Goodbye',
207
+ })
208
+ })
209
+
210
+ test('returns flattened and merged translations based on exact match for locale translation', () => {
211
+ const resolvedLocale = 'fr-CA'
212
+
213
+ const localization = {
214
+ defaultLocale: 'en',
215
+ lastUpdated: Date.now(),
216
+ translations: {
217
+ en: {
218
+ greetings: {
219
+ hello: 'Hello',
220
+ goodbye: 'Goodbye',
221
+ },
222
+ },
223
+ fr: {
224
+ greetings: {
225
+ hello: 'Bonjour',
226
+ goodbye: 'Au revoir',
227
+ },
228
+ },
229
+ 'fr-CA': {
230
+ greetings: {
231
+ hello: 'Bonjour, Canada',
232
+ goodbye: 'Au revoir, Canada',
233
+ },
234
+ },
235
+ },
236
+ }
237
+
238
+ const flattenedTranslations = flattenDevExtensionTranslations(localization, resolvedLocale)
239
+
240
+ expect(flattenedTranslations).toStrictEqual({
241
+ 'greetings.hello': 'Bonjour, Canada',
242
+ 'greetings.goodbye': 'Au revoir, Canada',
243
+ })
244
+ })
245
+
246
+ test('returns flattened and merged translations based on non-regional match for locale translation', () => {
247
+ const resolvedLocale = 'fr-CA'
248
+
249
+ const localization = {
250
+ defaultLocale: 'en',
251
+ lastUpdated: Date.now(),
252
+ translations: {
253
+ en: {
254
+ greetings: {
255
+ hello: 'Hello',
256
+ goodbye: 'Goodbye',
257
+ sorry: 'Sorry',
258
+ },
259
+ },
260
+ fr: {
261
+ greetings: {
262
+ hello: 'Bonjour',
263
+ goodbye: 'Au revoir',
264
+ sorry: 'Désolé',
265
+ },
266
+ },
267
+ },
268
+ }
269
+
270
+ const flattenedTranslations = flattenDevExtensionTranslations(localization, resolvedLocale)
271
+
272
+ expect(flattenedTranslations).toStrictEqual({
273
+ 'greetings.hello': 'Bonjour',
274
+ 'greetings.goodbye': 'Au revoir',
275
+ 'greetings.sorry': 'Désolé',
276
+ })
277
+ })
278
+
279
+ test('returns the flattened default locale where no locale match is possible (full or non-regional)', () => {
280
+ const resolvedLocale = 'de'
281
+
282
+ const localization = {
283
+ defaultLocale: 'en',
284
+ lastUpdated: Date.now(),
285
+ translations: {
286
+ en: {
287
+ greetings: {
288
+ hello: 'Hello',
289
+ goodbye: 'Goodbye',
290
+ sorry: 'Sorry',
291
+ },
292
+ },
293
+ fr: {
294
+ greetings: {
295
+ hello: 'Bonjour',
296
+ goodbye: 'Au revoir',
297
+ sorry: 'Désolé',
298
+ },
299
+ },
300
+ 'de-DE': {
301
+ greetings: {
302
+ hello: 'Hallo',
303
+ goodbye: 'Auf Wiedersehen',
304
+ sorry: ' Entschuldigung',
305
+ },
306
+ },
307
+ },
308
+ }
309
+
310
+ const flattenedTranslations = flattenDevExtensionTranslations(localization, resolvedLocale)
311
+
312
+ expect(flattenedTranslations).toStrictEqual({
313
+ 'greetings.hello': 'Hello',
314
+ 'greetings.goodbye': 'Goodbye',
315
+ 'greetings.sorry': 'Sorry',
316
+ })
317
+ })
318
+
319
+ test('returns flattened translations with pluralizations', () => {
320
+ const resolvedLocale = 'en'
321
+
322
+ const localization = {
323
+ defaultLocale: 'en',
324
+ lastUpdated: Date.now(),
325
+ translations: {
326
+ en: {
327
+ pluralExample: {
328
+ one: 'You have {{count}} apple',
329
+ other: 'You have {{count}} apples',
330
+ },
331
+ example: {
332
+ of: {
333
+ nestedTranslation: 'This is a nested translation only in the default locale',
334
+ anotherNestedTranslation: 'This is another nested translation defined in the default locale',
335
+ },
336
+ },
337
+ },
338
+ },
339
+ }
340
+
341
+ const flattenedTranslations = flattenDevExtensionTranslations(localization, resolvedLocale)
342
+
343
+ expect(flattenedTranslations).toStrictEqual({
344
+ 'pluralExample.one': 'You have {{count}} apple',
345
+ 'pluralExample.other': 'You have {{count}} apples',
346
+ 'example.of.nestedTranslation': 'This is a nested translation only in the default locale',
347
+ 'example.of.anotherNestedTranslation': 'This is another nested translation defined in the default locale',
348
+ })
349
+ })
350
+ })
351
+
352
+ describe('getFlattenedLocalization()', () => {
353
+ test('returns flattened translations string and resolved extension locale when locales options are provided', () => {
354
+ const userLocale = 'en'
355
+
356
+ const localization = {
357
+ defaultLocale: 'en',
358
+ lastUpdated: Date.now(),
359
+ translations: {
360
+ en: {
361
+ greetings: {
362
+ hello: 'Hello',
363
+ },
364
+ },
365
+ },
366
+ }
367
+
368
+ const flattenedLocalization = getFlattenedLocalization(localization, {user: userLocale})
369
+
370
+ expect(flattenedLocalization).toStrictEqual({
371
+ extensionLocale: userLocale,
372
+ translations: '{"greetings.hello":"Hello"}',
373
+ lastUpdated: localization.lastUpdated,
374
+ })
375
+ })
376
+
377
+ test('return undefined when locales options are not provided', () => {
378
+ const userLocale = 'en'
379
+
380
+ const localization = {
381
+ defaultLocale: 'en',
382
+ lastUpdated: Date.now(),
383
+ translations: {
384
+ en: {
385
+ greetings: {
386
+ hello: 'Hello',
387
+ },
388
+ },
389
+ },
390
+ }
391
+
392
+ const flattenedLocalization = getFlattenedLocalization(localization)
393
+
394
+ expect(flattenedLocalization).toBeUndefined()
395
+ })
396
+
397
+ test('return undefined when localization is null', () => {
398
+ const userLocale = 'en'
399
+ const flattenedLocalization = getFlattenedLocalization(null, {user: userLocale})
400
+
401
+ expect(flattenedLocalization).toBeUndefined()
402
+ })
403
+
404
+ test('return flattened localization if localization is already flattened', () => {
405
+ const userLocale = 'en'
406
+
407
+ const localization = {
408
+ extensionLocale: userLocale,
409
+ lastUpdated: Date.now(),
410
+ translations: '{"greetings.hello":"Hello"}',
411
+ }
412
+
413
+ const flattenedLocalization = getFlattenedLocalization(localization, {user: userLocale})
414
+
415
+ expect(flattenedLocalization).toStrictEqual(localization)
416
+ })
417
+ })
package/src/i18n.ts ADDED
@@ -0,0 +1,208 @@
1
+ /**
2
+ * These translation utilities were adapted from https://github.com/Shopify/checkout-web/blob/master/app/utilities/development-mode/i18n-utilities.tsx
3
+ * */
4
+
5
+ type Translation = string | {[key: string]: Translation}
6
+
7
+ export interface Localization {
8
+ defaultLocale: string
9
+ translations: {[key: string]: {[key: string]: Translation}}
10
+ lastUpdated: number
11
+ }
12
+
13
+ export interface FlattenedLocalization {
14
+ extensionLocale: string
15
+ translations: string
16
+ lastUpdated: number
17
+ }
18
+
19
+ export interface LocalesOptions {
20
+ user: string
21
+ shop?: string
22
+ }
23
+
24
+ export interface TranslationDictionary {
25
+ [key: string]: string | TranslationDictionary
26
+ }
27
+
28
+ /**
29
+ * This is a flattened dictionary of extension translations for the active locale.
30
+ *
31
+ * Here are some examples for the 'en' locale.
32
+ *
33
+ * Nested keys are dot separated. Consider this translation definition:
34
+ *
35
+ * ```
36
+ * {
37
+ * "greetings": {
38
+ * "hello": "Hello {{user}}"
39
+ * }
40
+ * }
41
+ * ```
42
+ *
43
+ * It would be represented in this flattened dictionary as:
44
+ * ```
45
+ * {
46
+ * "greetings.hello": "Hello {{user}}"
47
+ * }
48
+ * ```
49
+ * Pluralized translations will also be flattened. Consider this definition:
50
+ * ```
51
+ * {
52
+ * "loyaltyPointsRemaining": {
53
+ * "one": "You have {{count}} loyalty point",
54
+ * "other": "You have {{count}} loyalty points",
55
+ * }
56
+ * }
57
+ * ```
58
+ * It would be represented in this flattened dictionary as:
59
+ * ```
60
+ * {
61
+ * "loyaltyPointsRemaining.one": "You have {{count}} loyalty point",
62
+ * "loyaltyPointsRemaining.other": "You have {{count}} loyalty points",
63
+ * }
64
+ * ```
65
+ */
66
+ export interface ExtensionTranslationMap {
67
+ [key: string]: string
68
+ }
69
+
70
+ export const TRANSLATED_KEYS = ['localization', 'name', 'description']
71
+ /**
72
+ * From a nested dictionary like the following :
73
+ *
74
+ * ```typescript
75
+ * const dictionary = {
76
+ * Foo: {
77
+ * Bar: {
78
+ * fooBar: 'something'
79
+ * }
80
+ * }
81
+ * }
82
+ *
83
+ * Returns a map containing this pair : {'Foo.Bar.fooBar': 'something'}
84
+ * ```
85
+ */
86
+ export function dictionaryToFlatMap(dictionary: TranslationDictionary) {
87
+ const map = new Map<string, string>()
88
+
89
+ traverseDictionary(dictionary, (key, value) => map.set(key, value))
90
+
91
+ return map
92
+ }
93
+
94
+ function traverseDictionary(
95
+ dictionary: TranslationDictionary,
96
+ callback: (key: string, value: string) => void,
97
+ keyPrefix?: string,
98
+ ) {
99
+ Object.keys(dictionary).forEach((key: string) => {
100
+ const value = dictionary[key]
101
+ const translationKey = keyPrefix ? `${keyPrefix}.${key}` : key
102
+
103
+ if (value == null) {
104
+ return
105
+ }
106
+
107
+ if (typeof value === 'string') {
108
+ // eslint-disable-next-line node/callback-return
109
+ callback(translationKey, value)
110
+ } else {
111
+ traverseDictionary(value, callback, translationKey)
112
+ }
113
+ })
114
+ }
115
+
116
+ export function flattenDevExtensionTranslations(localization: Localization, locale: string): ExtensionTranslationMap {
117
+ const defaultTranslations = getFlatMap(localization.translations[localization.defaultLocale])
118
+
119
+ const nonRegionalLocale = getNonRegionalLocale(locale)
120
+ const nonRegionalTranslations = getFlatMap(localization.translations[nonRegionalLocale])
121
+
122
+ const userLocaleTranslations = getFlatMap(localization.translations[locale])
123
+
124
+ return convertMapToExtensionTranslationMap(
125
+ new Map([...defaultTranslations, ...nonRegionalTranslations, ...userLocaleTranslations]),
126
+ )
127
+ }
128
+
129
+ function getFlatMap(translationDictionary: TranslationDictionary | undefined) {
130
+ if (translationDictionary) {
131
+ return dictionaryToFlatMap(translationDictionary)
132
+ }
133
+ return new Map<string, string>()
134
+ }
135
+
136
+ export function resolveDevExtensionLocale(
137
+ localization: Localization,
138
+ locales: {
139
+ user: string
140
+ shop?: string
141
+ },
142
+ ): string {
143
+ const extensionLocales = new Set(Object.keys(localization.translations))
144
+
145
+ // 0. If no translations, use the user's locale
146
+ if (extensionLocales.size === 0) return locales.user
147
+
148
+ // 1. Attempt to match the user's locale exactly
149
+ if (extensionLocales.has(locales.user)) return locales.user
150
+
151
+ // 2. Attempt to match the non-regional part of the user's locale (i.e. 'fr-CA' becomes 'fr')
152
+ const nonRegionalUserLocale = getNonRegionalLocale(locales.user)
153
+ if (extensionLocales.has(nonRegionalUserLocale)) return nonRegionalUserLocale
154
+
155
+ // 3. Attempt to match the shop's default locale exactly
156
+ if (locales.shop && extensionLocales.has(locales.shop)) return locales.shop
157
+
158
+ // 4. Attempt to match the non-regional part of the shop's default locale (i.e. 'fr-CA' becomes 'fr')
159
+ const nonRegionalShopLocale = locales.shop && getNonRegionalLocale(locales.shop)
160
+ if (nonRegionalShopLocale && extensionLocales.has(nonRegionalShopLocale)) return nonRegionalShopLocale
161
+
162
+ // 5. Finally, return the default locale as a fallback
163
+ return localization.defaultLocale
164
+ }
165
+
166
+ function convertMapToExtensionTranslationMap(map: Map<string, string>): ExtensionTranslationMap {
167
+ const extTransMap: ExtensionTranslationMap = {}
168
+ for (const [key, value] of map) {
169
+ extTransMap[key] = value
170
+ }
171
+ return extTransMap
172
+ }
173
+
174
+ function getNonRegionalLocale(locale: string): string {
175
+ return locale.split('-')[0]
176
+ }
177
+
178
+ export function getFlattenedLocalization(
179
+ localization?: FlattenedLocalization | Localization | null,
180
+ locales?: LocalesOptions,
181
+ ) {
182
+ if (!localization || !locales) {
183
+ return
184
+ }
185
+
186
+ if (isFlattenedTranslations(localization)) {
187
+ return localization
188
+ }
189
+
190
+ const extensionLocale = resolveDevExtensionLocale(localization, locales)
191
+ const translations = JSON.stringify(flattenDevExtensionTranslations(localization, extensionLocale))
192
+
193
+ const flattenedLocalization: FlattenedLocalization = {
194
+ extensionLocale,
195
+ translations,
196
+ lastUpdated: localization.lastUpdated,
197
+ }
198
+ return flattenedLocalization
199
+ }
200
+
201
+ export function isFlattenedTranslations(
202
+ localization: Localization | FlattenedLocalization,
203
+ ): localization is FlattenedLocalization {
204
+ return (
205
+ typeof localization.translations === 'string' &&
206
+ Object.prototype.hasOwnProperty.call(localization, 'extensionLocale')
207
+ )
208
+ }