@shopify/ui-extensions-server-kit 0.0.0-nightly-20250605112924

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 (260) hide show
  1. package/CHANGELOG.md +133 -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 +30 -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 +55 -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 +7 -0
  47. package/dist/state/actions/actions.es.js +44 -0
  48. package/dist/state/actions/index.d.ts +2 -0
  49. package/dist/state/actions/types.d.ts +25 -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 +181 -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.d.ts +3 -0
  189. package/node_modules/@shopify/ui-extensions-test-utils/dist/index.js +3 -0
  190. package/node_modules/@shopify/ui-extensions-test-utils/dist/render.d.ts +2 -0
  191. package/node_modules/@shopify/ui-extensions-test-utils/dist/render.js +5 -0
  192. package/node_modules/@shopify/ui-extensions-test-utils/dist/renderHook.d.ts +17 -0
  193. package/node_modules/@shopify/ui-extensions-test-utils/dist/renderHook.js +20 -0
  194. package/node_modules/@shopify/ui-extensions-test-utils/dist/withProviders.d.ts +9 -0
  195. package/node_modules/@shopify/ui-extensions-test-utils/dist/withProviders.js +7 -0
  196. package/node_modules/@shopify/ui-extensions-test-utils/package.json +40 -0
  197. package/node_modules/@shopify/ui-extensions-test-utils/project.json +39 -0
  198. package/node_modules/@types/react/LICENSE +21 -0
  199. package/node_modules/@types/react/README.md +16 -0
  200. package/node_modules/@types/react/experimental.d.ts +192 -0
  201. package/node_modules/@types/react/global.d.ts +151 -0
  202. package/node_modules/@types/react/index.d.ts +3175 -0
  203. package/node_modules/@types/react/jsx-dev-runtime.d.ts +2 -0
  204. package/node_modules/@types/react/jsx-runtime.d.ts +2 -0
  205. package/node_modules/@types/react/package.json +149 -0
  206. package/node_modules/@vitejs/plugin-react-refresh/LICENSE +21 -0
  207. package/node_modules/@vitejs/plugin-react-refresh/README.md +73 -0
  208. package/node_modules/@vitejs/plugin-react-refresh/index.d.ts +14 -0
  209. package/node_modules/@vitejs/plugin-react-refresh/index.js +239 -0
  210. package/node_modules/@vitejs/plugin-react-refresh/package.json +35 -0
  211. package/package.json +67 -0
  212. package/project.json +72 -0
  213. package/scripts/create-entry-files.ts +44 -0
  214. package/src/ExtensionServerClient/ExtensionServerClient.test.ts +730 -0
  215. package/src/ExtensionServerClient/ExtensionServerClient.ts +311 -0
  216. package/src/ExtensionServerClient/index.ts +2 -0
  217. package/src/ExtensionServerClient/types.ts +161 -0
  218. package/src/context/ExtensionServerProvider.test.tsx +173 -0
  219. package/src/context/ExtensionServerProvider.tsx +48 -0
  220. package/src/context/constants.ts +15 -0
  221. package/src/context/index.ts +3 -0
  222. package/src/context/types.ts +13 -0
  223. package/src/hooks/index.ts +5 -0
  224. package/src/hooks/useExtensionClient.ts +6 -0
  225. package/src/hooks/useExtensionServerContext.ts +4 -0
  226. package/src/hooks/useExtensionServerEvent.ts +11 -0
  227. package/src/hooks/useExtensionServerState.ts +6 -0
  228. package/src/hooks/useIsomorphicLayoutEffect.ts +6 -0
  229. package/src/i18n.test.ts +417 -0
  230. package/src/i18n.ts +208 -0
  231. package/src/index.ts +7 -0
  232. package/src/state/actions/actions.ts +43 -0
  233. package/src/state/actions/index.ts +2 -0
  234. package/src/state/actions/types.ts +37 -0
  235. package/src/state/index.ts +2 -0
  236. package/src/state/reducers/constants.ts +6 -0
  237. package/src/state/reducers/extensionServerReducer.test.ts +174 -0
  238. package/src/state/reducers/extensionServerReducer.ts +87 -0
  239. package/src/state/reducers/index.ts +3 -0
  240. package/src/state/reducers/types.ts +7 -0
  241. package/src/testing/MockExtensionServerProvider.tsx +36 -0
  242. package/src/testing/app.ts +15 -0
  243. package/src/testing/extensions.ts +70 -0
  244. package/src/testing/index.ts +3 -0
  245. package/src/types.ts +180 -0
  246. package/src/utilities/assetToString.test.ts +16 -0
  247. package/src/utilities/assetToString.ts +8 -0
  248. package/src/utilities/groupByKey.ts +3 -0
  249. package/src/utilities/index.ts +7 -0
  250. package/src/utilities/isUIExtension.ts +7 -0
  251. package/src/utilities/isValidSurface.ts +7 -0
  252. package/src/utilities/noop.ts +1 -0
  253. package/src/utilities/replaceUpdated.test.ts +26 -0
  254. package/src/utilities/replaceUpdated.ts +17 -0
  255. package/src/utilities/set.test.ts +19 -0
  256. package/src/utilities/set.ts +30 -0
  257. package/testing.d.ts +1 -0
  258. package/testing.js +1 -0
  259. package/testing.mjs +1 -0
  260. package/tests/setup.ts +6 -0
@@ -0,0 +1,275 @@
1
+ import React from 'react';
2
+ import { render, unmountComponentAtNode } from 'react-dom';
3
+ import { act } from 'react-dom/test-utils';
4
+ import { TestWrapper } from './TestWrapper.mjs';
5
+ import { Element } from './element.mjs';
6
+ import { getInternals } from './compat.mjs';
7
+ import { Tag } from './types.mjs';
8
+
9
+ const {
10
+ findCurrentFiberUsingSlowPath
11
+ } = require('react-reconciler/reflection');
12
+
13
+ const connected = new Set();
14
+ class Root {
15
+ get props() {
16
+ return this.withRoot(root => root.props);
17
+ }
18
+
19
+ get isDOM() {
20
+ return this.withRoot(root => root.isDOM);
21
+ }
22
+
23
+ get type() {
24
+ return this.withRoot(root => root.type);
25
+ }
26
+
27
+ get instance() {
28
+ return this.withRoot(root => root.instance);
29
+ }
30
+
31
+ get children() {
32
+ return this.withRoot(root => root.children);
33
+ }
34
+
35
+ get descendants() {
36
+ return this.withRoot(root => root.descendants);
37
+ }
38
+
39
+ get domNodes() {
40
+ return this.withRoot(root => root.domNodes);
41
+ }
42
+
43
+ get domNode() {
44
+ return this.withRoot(root => root.domNode);
45
+ }
46
+
47
+ get mounted() {
48
+ return this.wrapper != null;
49
+ }
50
+
51
+ constructor(tree, {
52
+ render = defaultRender,
53
+ resolveRoot = defaultResolveRoot
54
+ } = {}) {
55
+ this.tree = tree;
56
+ this.wrapper = null;
57
+ this.element = document.createElement('div');
58
+ this.root = null;
59
+ this.acting = false;
60
+ this.render = void 0;
61
+ this.resolveRoot = void 0;
62
+ this.render = render;
63
+ this.resolveRoot = resolveRoot;
64
+ this.mount();
65
+ }
66
+
67
+ act(action, {
68
+ update = true
69
+ } = {}) {
70
+ const updateWrapper = update ? this.update.bind(this) : noop;
71
+ let result;
72
+
73
+ if (this.acting) {
74
+ return action();
75
+ }
76
+
77
+ this.acting = true;
78
+
79
+ const afterResolve = () => {
80
+ updateWrapper();
81
+ this.acting = false;
82
+ return result;
83
+ };
84
+
85
+ const promise = act(() => {
86
+ result = action(); // This condition checks the returned value is an actual Promise and returns it
87
+ // to React’s `act()` call, otherwise we just want to return `undefined`
88
+
89
+ if (isPromise(result)) {
90
+ return result;
91
+ }
92
+
93
+ return undefined;
94
+ });
95
+
96
+ if (isPromise(result)) {
97
+ updateWrapper();
98
+ return Promise.resolve(promise).then(afterResolve);
99
+ }
100
+
101
+ return afterResolve();
102
+ }
103
+
104
+ html() {
105
+ return this.withRoot(root => root.html());
106
+ }
107
+
108
+ text() {
109
+ return this.withRoot(root => root.text());
110
+ }
111
+
112
+ is(type) {
113
+ return this.withRoot(root => root.is(type));
114
+ }
115
+
116
+ prop(key) {
117
+ return this.withRoot(root => root.prop(key));
118
+ }
119
+
120
+ data(key) {
121
+ return this.withRoot(root => root.data(key));
122
+ }
123
+
124
+ find(type, props) {
125
+ return this.withRoot(root => root.find(type, props));
126
+ }
127
+
128
+ findAll(type, props) {
129
+ return this.withRoot(root => root.findAll(type, props));
130
+ }
131
+
132
+ findWhere(predicate) {
133
+ return this.withRoot(root => root.findWhere(predicate));
134
+ }
135
+
136
+ findAllWhere(predicate) {
137
+ return this.withRoot(root => root.findAllWhere(predicate));
138
+ }
139
+
140
+ trigger(prop, ...args) {
141
+ return this.withRoot(root => root.trigger(prop, ...args));
142
+ }
143
+
144
+ triggerKeypath(keypath, ...args) {
145
+ return this.withRoot(root => root.triggerKeypath(keypath, ...args));
146
+ }
147
+
148
+ mount() {
149
+ if (this.mounted) {
150
+ throw new Error('Attempted to mount a node that was already mounted');
151
+ }
152
+
153
+ if (this.element.parentNode == null) {
154
+ document.body.appendChild(this.element);
155
+ connected.add(this);
156
+ }
157
+
158
+ this.act(() => {
159
+ render( /*#__PURE__*/React.createElement(TestWrapper, {
160
+ render: this.render,
161
+ ref: wrapper => {
162
+ this.wrapper = wrapper;
163
+ }
164
+ }, this.tree), this.element);
165
+ });
166
+ }
167
+
168
+ unmount() {
169
+ if (!this.mounted) {
170
+ throw new Error('You attempted to unmount a node that was already unmounted');
171
+ }
172
+
173
+ this.ensureRoot();
174
+ this.act(() => unmountComponentAtNode(this.element));
175
+ }
176
+
177
+ destroy() {
178
+ const {
179
+ element,
180
+ mounted
181
+ } = this;
182
+
183
+ if (mounted) {
184
+ this.unmount();
185
+ }
186
+
187
+ element.remove();
188
+ connected.delete(this);
189
+ }
190
+
191
+ setProps(props) {
192
+ this.ensureRoot();
193
+ this.act(() => this.wrapper.setProps(props));
194
+ }
195
+
196
+ forceUpdate() {
197
+ this.ensureRoot();
198
+ this.act(() => this.wrapper.forceUpdate());
199
+ }
200
+
201
+ debug(options) {
202
+ this.ensureRoot();
203
+ return this.root.debug(options);
204
+ }
205
+
206
+ toString() {
207
+ return this.withRoot(root => root.toString());
208
+ }
209
+
210
+ update() {
211
+ if (this.wrapper == null) {
212
+ this.root = null;
213
+ } else {
214
+ const rootFiber = getInternals(this.wrapper.rootRef);
215
+ const topElement = fiberToElement(findCurrentFiberUsingSlowPath(rootFiber), this);
216
+ this.root = this.resolveRoot(topElement);
217
+ }
218
+ }
219
+
220
+ ensureRoot() {
221
+ if (this.wrapper == null || this.root == null) {
222
+ throw new Error('Attempted to operate on a mounted tree, but the component is no longer mounted');
223
+ }
224
+ }
225
+
226
+ withRoot(withRoot) {
227
+ this.ensureRoot();
228
+ return withRoot(this.root);
229
+ }
230
+
231
+ }
232
+
233
+ function defaultResolveRoot(element) {
234
+ return element.children[0];
235
+ }
236
+
237
+ function defaultRender(element) {
238
+ return element;
239
+ }
240
+
241
+ function fiberToElement(node, root) {
242
+ if (node.tag === Tag.HostText) {
243
+ return node.memoizedProps;
244
+ }
245
+
246
+ const props = node.memoizedProps;
247
+ const children = childrenToTree(node.child, root);
248
+ return new Element({
249
+ tag: node.tag,
250
+ type: node.type,
251
+ props,
252
+ instance: node.stateNode
253
+ }, children, root);
254
+ }
255
+
256
+ function childrenToTree(fiber, root) {
257
+ let currentFiber = fiber;
258
+ const children = [];
259
+
260
+ while (currentFiber != null) {
261
+ const result = fiberToElement(currentFiber, root);
262
+ children.push(result);
263
+ currentFiber = currentFiber.sibling;
264
+ }
265
+
266
+ return children;
267
+ }
268
+
269
+ function isPromise(promise) {
270
+ return promise != null && typeof promise === 'object' && 'then' in promise;
271
+ }
272
+
273
+ function noop() {}
274
+
275
+ export { Root, connected };
@@ -0,0 +1,80 @@
1
+ import { stringify } from 'jest-matcher-utils';
2
+
3
+ function toReactString(node, options = {}, level = 0) {
4
+ // if this is an array node then print all children at the current level
5
+ if (!node.type && node.children.length > 0) {
6
+ return node.children.map(child => toReactString(child, options, level)).join('\n');
7
+ }
8
+
9
+ const name = nodeName(node);
10
+ const indent = ' '.repeat(level);
11
+ const props = Object.keys(node.props) // we always filter out children no matter what, but unless allProps option
12
+ // is present we will also filter out insigificant props
13
+ .filter(key => options.allProps ? key !== 'children' : !/^(children|className)$|^(aria|data)-/.test(key)).reduce((list, key) => {
14
+ if (!key) {
15
+ return list;
16
+ }
17
+
18
+ const value = node.props[key];
19
+
20
+ if (value === undefined && !options.allProps) {
21
+ return list;
22
+ }
23
+
24
+ list.push(toPropString(key, value, options.verbosity));
25
+ return list;
26
+ }, []);
27
+ const hasChildren = node.children.length > 0 && !['svg'].includes(name);
28
+ const open = `${indent}<${name}${props.length > 0 ? ` ${props.join(' ')}` : ''}${hasChildren ? '>' : ' />'}`;
29
+
30
+ if (!hasChildren) {
31
+ return open;
32
+ }
33
+
34
+ const close = `${indent}</${name}>`;
35
+
36
+ if (options.depth != null && level >= options.depth) {
37
+ return [open, `${indent} {/* <${node.children.length} child${node.children.length === 1 ? '' : 'ren'}... /> */}`, close].join('\n');
38
+ }
39
+
40
+ return [open, ...node.children.map(child => toReactString(child, options, level + 1)), close].join('\n');
41
+ }
42
+ function toPropString(key, value, verbosity = 1) {
43
+ if (value === undefined) {
44
+ return `${key}={undefined}`;
45
+ }
46
+
47
+ if (value === null) {
48
+ return `${key}={null}`;
49
+ }
50
+
51
+ if (typeof value === 'string') {
52
+ return `${key}="${value}"`;
53
+ }
54
+
55
+ if (typeof value === 'boolean' && value) {
56
+ return value ? `${key}` : `${key}={false}`;
57
+ }
58
+
59
+ if (value instanceof Array) {
60
+ return `${key}={${stringify(value, verbosity + 1)}}`;
61
+ }
62
+
63
+ return `${key}={${stringify(value, verbosity)}}`;
64
+ }
65
+ function nodeName({
66
+ type
67
+ }) {
68
+ if (type && typeof type === 'object' && '_context' in type) {
69
+ const context = type._context;
70
+ return `${context.displayName || 'Context'}.${type === context.Provider ? 'Provider' : 'Consumer'}`;
71
+ }
72
+
73
+ if (type == null) {
74
+ return 'Node';
75
+ }
76
+
77
+ return typeof type === 'string' ? type : type.displayName || type.name || 'Component';
78
+ }
79
+
80
+ export { nodeName, toPropString, toReactString };
@@ -0,0 +1,26 @@
1
+ // https://github.com/facebook/react/blob/master/packages/shared/ReactWorkTag.js
2
+ let Tag;
3
+
4
+ (function (Tag) {
5
+ Tag[Tag["FunctionComponent"] = 0] = "FunctionComponent";
6
+ Tag[Tag["ClassComponent"] = 1] = "ClassComponent";
7
+ Tag[Tag["IndeterminateComponent"] = 2] = "IndeterminateComponent";
8
+ Tag[Tag["HostRoot"] = 3] = "HostRoot";
9
+ Tag[Tag["HostPortal"] = 4] = "HostPortal";
10
+ Tag[Tag["HostComponent"] = 5] = "HostComponent";
11
+ Tag[Tag["HostText"] = 6] = "HostText";
12
+ Tag[Tag["Fragment"] = 7] = "Fragment";
13
+ Tag[Tag["Mode"] = 8] = "Mode";
14
+ Tag[Tag["ContextConsumer"] = 9] = "ContextConsumer";
15
+ Tag[Tag["ContextProvider"] = 10] = "ContextProvider";
16
+ Tag[Tag["ForwardRef"] = 11] = "ForwardRef";
17
+ Tag[Tag["Profiler"] = 12] = "Profiler";
18
+ Tag[Tag["SuspenseComponent"] = 13] = "SuspenseComponent";
19
+ Tag[Tag["MemoComponent"] = 14] = "MemoComponent";
20
+ Tag[Tag["SimpleMemoComponent"] = 15] = "SimpleMemoComponent";
21
+ Tag[Tag["LazyComponent"] = 16] = "LazyComponent";
22
+ Tag[Tag["IncompleteClassComponent"] = 17] = "IncompleteClassComponent";
23
+ Tag[Tag["DehydratedSuspenseComponent"] = 18] = "DehydratedSuspenseComponent";
24
+ })(Tag || (Tag = {}));
25
+
26
+ export { Tag };
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+
3
+ class TestWrapper extends React.Component {
4
+ constructor(...args) {
5
+ super(...args);
6
+ this.state = {};
7
+ this.rootRef = null;
8
+
9
+ this.setRef = ref => {
10
+ this.rootRef = ref;
11
+ };
12
+ }
13
+
14
+ // eslint-disable-next-line @shopify/react-prefer-private-members
15
+ setProps(props) {
16
+ this.setState({
17
+ props
18
+ });
19
+ }
20
+
21
+ render() {
22
+ const {
23
+ props
24
+ } = this.state;
25
+ const {
26
+ children,
27
+ render
28
+ } = this.props;
29
+ const rootElement = props ? /*#__PURE__*/React.cloneElement(children, props) : children;
30
+ return render( /*#__PURE__*/React.createElement(TestInnerWrapper, {
31
+ ref: this.setRef
32
+ }, rootElement));
33
+ }
34
+
35
+ }
36
+
37
+ class TestInnerWrapper extends React.Component {
38
+ render() {
39
+ return this.props.children;
40
+ }
41
+
42
+ }
43
+
44
+ export { TestWrapper };
@@ -0,0 +1,10 @@
1
+ function getInternals(instance) {
2
+ // In React 17+ _reactInternalFiber was renamed to _reactInternals. As such we need to handle both APIs to maintain support.
3
+ if ('_reactInternalFiber' in instance) {
4
+ return instance._reactInternalFiber;
5
+ }
6
+
7
+ return instance._reactInternals;
8
+ }
9
+
10
+ export { getInternals };
@@ -0,0 +1,9 @@
1
+ import { connected } from './root.esnext';
2
+
3
+ function destroyAll() {
4
+ for (const wrapper of [...connected]) {
5
+ wrapper.destroy();
6
+ }
7
+ }
8
+
9
+ export { destroyAll };
@@ -0,0 +1,221 @@
1
+ import { toReactString, nodeName } from './toReactString.esnext';
2
+ import { Tag } from './types.esnext';
3
+
4
+ class Element {
5
+ get props() {
6
+ return this.tree.props;
7
+ }
8
+
9
+ get type() {
10
+ return this.tree.type;
11
+ }
12
+
13
+ get isDOM() {
14
+ return this.tree.tag === Tag.HostComponent;
15
+ }
16
+
17
+ get instance() {
18
+ return this.tree.instance;
19
+ }
20
+
21
+ get children() {
22
+ return this.elementChildren;
23
+ }
24
+
25
+ get elementDescendants() {
26
+ if (!this.descendantsCache) {
27
+ this.descendantsCache = getDescendants(this);
28
+ }
29
+
30
+ return this.descendantsCache;
31
+ }
32
+
33
+ get elementChildren() {
34
+ if (!this.elementChildrenCache) {
35
+ this.elementChildrenCache = this.allChildren.filter(element => typeof element !== 'string');
36
+ }
37
+
38
+ return this.elementChildrenCache;
39
+ }
40
+
41
+ get descendants() {
42
+ return this.elementDescendants;
43
+ }
44
+
45
+ get domNodes() {
46
+ if (this.isDOM) {
47
+ return [this.instance];
48
+ }
49
+
50
+ return this.elementChildren.filter(element => element.isDOM).map(element => element.instance);
51
+ }
52
+
53
+ get domNode() {
54
+ const {
55
+ domNodes
56
+ } = this;
57
+
58
+ if (domNodes.length > 1) {
59
+ throw new Error('You can’t call getDOMNode() on an element that returns multiple HTML elements. Call getDOMNodes() to retrieve all of the elements instead.');
60
+ }
61
+
62
+ return domNodes[0] || null;
63
+ }
64
+
65
+ constructor(tree, allChildren, root) {
66
+ this.tree = tree;
67
+ this.allChildren = allChildren;
68
+ this.root = root;
69
+ this.descendantsCache = null;
70
+ this.elementChildrenCache = null;
71
+ }
72
+
73
+ data(key) {
74
+ return this.props[key.startsWith('data-') ? key : `data-${key}`];
75
+ }
76
+
77
+ prop(key) {
78
+ return this.props[key];
79
+ }
80
+
81
+ text() {
82
+ const {
83
+ instance,
84
+ allChildren,
85
+ tree: {
86
+ tag
87
+ }
88
+ } = this;
89
+
90
+ if (tag === Tag.HostPortal) {
91
+ return '';
92
+ }
93
+
94
+ if (instance instanceof HTMLElement) {
95
+ return instance.textContent || '';
96
+ }
97
+
98
+ return allChildren.reduce((text, child) => text + (typeof child === 'string' ? child : child.text()), '');
99
+ }
100
+
101
+ html() {
102
+ const {
103
+ instance,
104
+ allChildren,
105
+ tree: {
106
+ tag
107
+ }
108
+ } = this;
109
+
110
+ if (tag === Tag.HostPortal) {
111
+ return '';
112
+ }
113
+
114
+ if (instance instanceof HTMLElement) {
115
+ return instance.outerHTML;
116
+ }
117
+
118
+ return allChildren.reduce((text, child) => text + (typeof child === 'string' ? child : child.html()), '');
119
+ }
120
+
121
+ is(type) {
122
+ return isMatchingType(this.type, type);
123
+ }
124
+
125
+ find(type, props) {
126
+ return this.elementDescendants.find(element => isMatchingType(element.type, type) && (props == null || equalSubset(props, element.props))) || null;
127
+ }
128
+
129
+ findAll(type, props) {
130
+ return this.elementDescendants.filter(element => isMatchingType(element.type, type) && (props == null || equalSubset(props, element.props)));
131
+ }
132
+
133
+ findWhere(predicate) {
134
+ return this.elementDescendants.find(element => predicate(element)) || null;
135
+ }
136
+
137
+ findAllWhere(predicate) {
138
+ return this.elementDescendants.filter(element => predicate(element));
139
+ }
140
+
141
+ trigger(prop, ...args) {
142
+ return this.root.act(() => {
143
+ const propValue = this.props[prop];
144
+
145
+ if (propValue == null) {
146
+ throw new Error(`Attempted to call prop ${prop} but it was not defined.`);
147
+ }
148
+
149
+ return propValue(...args);
150
+ });
151
+ }
152
+
153
+ triggerKeypath(keypath, ...args) {
154
+ return this.root.act(() => {
155
+ const {
156
+ props
157
+ } = this;
158
+ const parts = keypath.split(/[.[\]]/g).filter(Boolean);
159
+ let currentProp = props;
160
+ const currentKeypath = [];
161
+
162
+ for (const part of parts) {
163
+ if (currentProp == null || typeof currentProp !== 'object') {
164
+ throw new Error(`Attempted to access field keypath '${currentKeypath.join('.')}', but it was not an object.`);
165
+ }
166
+
167
+ currentProp = currentProp[part];
168
+ currentKeypath.push(part);
169
+ }
170
+
171
+ if (typeof currentProp !== 'function') {
172
+ throw new Error(`Value at keypath '${keypath}' is not a function.`);
173
+ }
174
+
175
+ return currentProp(...args);
176
+ });
177
+ }
178
+
179
+ debug(options) {
180
+ return toReactString(this, options);
181
+ }
182
+
183
+ toString() {
184
+ return `<${nodeName(this)} />`;
185
+ }
186
+
187
+ }
188
+
189
+ function isMatchingType(type, test) {
190
+ if (type === test) {
191
+ return true;
192
+ }
193
+
194
+ if (test == null) {
195
+ return false;
196
+ }
197
+
198
+ return test.type != null && isMatchingType(type, test.type);
199
+ }
200
+
201
+ function equalSubset(subset, full) {
202
+ return Object.keys(subset).every(key => key in full && full[key] === subset[key]);
203
+ }
204
+
205
+ function getDescendants(element) {
206
+ const descendants = []; // eslint-disable-next-line @typescript-eslint/prefer-for-of
207
+
208
+ for (let i = 0; i < element.allChildren.length; i++) {
209
+ const child = element.allChildren[i];
210
+
211
+ if (typeof child !== 'string') {
212
+ descendants.push(child); // eslint-disable-next-line prefer-spread
213
+
214
+ descendants.push.apply(descendants, child.elementDescendants);
215
+ }
216
+ }
217
+
218
+ return descendants;
219
+ }
220
+
221
+ export { Element };
@@ -0,0 +1,5 @@
1
+ export { Root } from './root.esnext';
2
+ export { Element } from './element.esnext';
3
+ export { CustomRoot, createMount, mount } from './mount.esnext';
4
+ export { destroyAll } from './destroy.esnext';
5
+ export { nodeName, toPropString, toReactString } from './toReactString.esnext';