rescript-relay 1.0.0-beta.7 → 1.0.0-beta.8

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.
package/CHANGELOG.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # master
2
2
 
3
- # 1.0.0-beta.7
3
+ # 1.0.0-beta.8
4
4
 
5
5
  _[Here's a commit showing a project being upgraded to this version](https://github.com/zth/rescript-relay/commit/5831c2f1f0f13eedc1cb60468c32fd32b2dc01d3)_
6
6
 
@@ -24,11 +24,19 @@ You can go ahead and remove these packages, that are no longer needed, as the co
24
24
  - There's no longer any need to manually select `__typename` on interfaces and unions for RescriptRelay's sake, unless you actually want to use it yourself.
25
25
  - We now support the `@required` directive from Relay, which is a new directive that lets you force non-nullability for nullable fields on the client side. You can then choose to throw an error if null values are encountered, or let the null value bubble up. Docs are coming soon.
26
26
  - The errors reported by the compiler is now quite a lot better.
27
+ - Full support for `reanalyze` as all false positive dead code results from generated code are now suppressed.
28
+ - Bindings for `requiredFieldLogger` for logging when missing fields are encountered (kudos [Emilios1995](https://github.com/Emilios1995)).
29
+ - Improved utils for [dealing with enums](https://rescript-relay-documentation.vercel.app/docs/enums).
27
30
 
28
31
  ## Beta fix changelog
29
32
 
30
33
  ### unreleased
31
34
 
35
+ ### beta.8
36
+
37
+ - More fixes for conversion instructions in variables and input objects.
38
+ - Project now works in `"type": "module"` mode in `package.json` (kudos [cometkim](https://github.com/cometkim))
39
+
32
40
  ### beta.7
33
41
 
34
42
  - Full support for `reanalyze` as all false positive dead code results from generated code are now suppressed.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rescript-relay",
3
- "version": "1.0.0-beta.7",
3
+ "version": "1.0.0-beta.8",
4
4
  "main": "src/RescriptRelay.res",
5
5
  "license": "MIT",
6
6
  "author": "Gabriel Nordeborn",
@@ -19,6 +19,14 @@
19
19
  "reasonml",
20
20
  "rescript"
21
21
  ],
22
+ "exports": {
23
+ "./src/utils": {
24
+ "require": "./src/utils.js",
25
+ "import": "./src/utils.mjs"
26
+ },
27
+ "./src/*": "./src/*",
28
+ "./package.json": "./package.json"
29
+ },
22
30
  "bin": {
23
31
  "rescript-relay-compiler": "compiler.js",
24
32
  "rescript-relay-cli": "cli/cli.js"
Binary file
Binary file
Binary file
package/src/utils.mjs ADDED
@@ -0,0 +1,339 @@
1
+ function getNewObj(maybeNewObj, currentObj) {
2
+ return maybeNewObj || Object.assign({}, currentObj);
3
+ }
4
+
5
+ function getPathName(path) {
6
+ return path.join("_");
7
+ }
8
+
9
+ function makeNewPath(currentPath, newKeys) {
10
+ return [].concat(currentPath, newKeys);
11
+ }
12
+
13
+ /**
14
+ * Runs on each object in the tree and follows the provided instructions
15
+ * to apply transforms etc.
16
+ */
17
+ function traverse(
18
+ fullInstructionMap,
19
+ currentPath,
20
+ currentObj,
21
+ instructionMap,
22
+ converters,
23
+ nullableValue,
24
+ instructionPaths,
25
+ addFragmentOnRoot
26
+ ) {
27
+ // We lazily set up a new object for each "level", as we don't want to mutate
28
+ // what comes back from the Relay store, and nor do we want to create new
29
+ // objects unless we need to. And we only need to when we need to change
30
+ // something.
31
+ var newObj;
32
+
33
+ if (addFragmentOnRoot) {
34
+ newObj = getNewObj(newObj, currentObj);
35
+ newObj.fragmentRefs = Object.assign({}, newObj);
36
+ }
37
+
38
+ for (var key in currentObj) {
39
+ var isUnion = false;
40
+ var originalValue = currentObj[key];
41
+
42
+ // Instructions are stored by the path in the object where they apply
43
+ var thisPath = makeNewPath(currentPath, [key]);
44
+ var path = getPathName(thisPath);
45
+
46
+ var instructions = instructionMap[path] || {};
47
+
48
+ if (currentObj[key] == null) {
49
+ newObj = getNewObj(newObj, currentObj);
50
+ newObj[key] = nullableValue;
51
+ continue;
52
+ }
53
+
54
+ var shouldConvertRootObj =
55
+ typeof instructions["r"] === "string" &&
56
+ fullInstructionMap[instructions["r"]];
57
+
58
+ var shouldAddFragmentFn = instructions["f"] === "";
59
+
60
+ var shouldConvertEnum =
61
+ typeof instructions["e"] === "string" && !!converters[instructions["e"]];
62
+
63
+ var shouldConvertCustomField =
64
+ typeof instructions["c"] === "string" && !!converters[instructions["c"]];
65
+
66
+ var shouldConvertUnion =
67
+ typeof instructions["u"] === "string" && !!converters[instructions["u"]];
68
+
69
+ var isTopLevelNodeField = typeof instructions["tnf"] === "string";
70
+
71
+ /**
72
+ * Handle arrays
73
+ */
74
+ if (Array.isArray(currentObj[key])) {
75
+ newObj = getNewObj(newObj, currentObj);
76
+ newObj[key] = currentObj[key].map(function (v) {
77
+ if (v == null) {
78
+ return nullableValue;
79
+ }
80
+
81
+ if (shouldConvertRootObj) {
82
+ return traverser(
83
+ v,
84
+ fullInstructionMap,
85
+ converters,
86
+ nullableValue,
87
+ instructions["r"]
88
+ );
89
+ }
90
+
91
+ if (shouldConvertEnum) {
92
+ return converters[instructions["e"]](v);
93
+ }
94
+
95
+ if (shouldConvertCustomField) {
96
+ return converters[instructions["c"]](v);
97
+ }
98
+
99
+ if (
100
+ shouldConvertUnion &&
101
+ typeof v === "object" &&
102
+ typeof v.__typename === "string"
103
+ ) {
104
+ isUnion = true;
105
+
106
+ var newPath = makeNewPath(currentPath, [key, v.__typename]);
107
+
108
+ var unionRootHasFragment =
109
+ (instructionMap[getPathName(newPath)] || {}).f === "";
110
+
111
+ var traversedValue = traverse(
112
+ fullInstructionMap,
113
+ newPath,
114
+ v,
115
+ instructionMap,
116
+ converters,
117
+ nullableValue,
118
+ instructionPaths,
119
+ unionRootHasFragment
120
+ );
121
+
122
+ return converters[instructions["u"]](traversedValue);
123
+ }
124
+
125
+ if (shouldAddFragmentFn && typeof v === "object") {
126
+ var objWithFragmentFn = Object.assign({}, v);
127
+ objWithFragmentFn.fragmentRefs = Object.assign({}, objWithFragmentFn);
128
+ return objWithFragmentFn;
129
+ }
130
+
131
+ return v;
132
+ });
133
+ } else {
134
+ /**
135
+ * Handle normal values.
136
+ */
137
+ var v = currentObj[key];
138
+
139
+ if (shouldConvertRootObj) {
140
+ newObj = getNewObj(newObj, currentObj);
141
+ newObj[key] = traverser(
142
+ v,
143
+ fullInstructionMap,
144
+ converters,
145
+ nullableValue,
146
+ instructions["r"]
147
+ );
148
+ }
149
+
150
+ if (isTopLevelNodeField) {
151
+ if (
152
+ v == null ||
153
+ !v.hasOwnProperty("__typename") ||
154
+ v.__typename !== instructions["tnf"]
155
+ ) {
156
+ newObj = getNewObj(newObj, currentObj);
157
+ newObj[key] = nullableValue;
158
+ }
159
+ }
160
+
161
+ if (shouldConvertEnum) {
162
+ newObj = getNewObj(newObj, currentObj);
163
+ newObj[key] = converters[instructions["e"]](v);
164
+ }
165
+
166
+ if (shouldConvertCustomField) {
167
+ newObj = getNewObj(newObj, currentObj);
168
+ newObj[key] = converters[instructions["c"]](v);
169
+ }
170
+
171
+ if (
172
+ shouldConvertUnion &&
173
+ v != null &&
174
+ typeof v === "object" &&
175
+ typeof v.__typename === "string"
176
+ ) {
177
+ isUnion = true;
178
+
179
+ var newPath = makeNewPath(currentPath, [key, v.__typename]);
180
+
181
+ var unionRootHasFragment =
182
+ (instructionMap[getPathName(newPath)] || {}).f === "";
183
+
184
+ var traversedValue = traverse(
185
+ fullInstructionMap,
186
+ newPath,
187
+ v,
188
+ instructionMap,
189
+ converters,
190
+ nullableValue,
191
+ instructionPaths,
192
+ unionRootHasFragment
193
+ );
194
+
195
+ newObj = getNewObj(newObj, currentObj);
196
+ newObj[key] = converters[instructions["u"]](traversedValue);
197
+ }
198
+
199
+ if (shouldAddFragmentFn && typeof v === "object") {
200
+ newObj = getNewObj(newObj, currentObj);
201
+ var objWithFragmentFn = Object.assign({}, v);
202
+ objWithFragmentFn.fragmentRefs = Object.assign({}, objWithFragmentFn);
203
+ newObj[key] = objWithFragmentFn;
204
+ }
205
+ }
206
+
207
+ if (originalValue != null && !isUnion) {
208
+ var nextObj = (newObj && newObj[key]) || currentObj[key];
209
+
210
+ if (typeof nextObj === "object" && !Array.isArray(originalValue)) {
211
+ var traversedObj = traverse(
212
+ fullInstructionMap,
213
+ thisPath,
214
+ nextObj,
215
+ instructionMap,
216
+ converters,
217
+ nullableValue,
218
+ instructionPaths
219
+ );
220
+
221
+ if (traversedObj !== nextObj) {
222
+ newObj = getNewObj(newObj, currentObj);
223
+ newObj[key] = traversedObj;
224
+ }
225
+ } else if (Array.isArray(originalValue)) {
226
+ newObj = getNewObj(newObj, currentObj);
227
+ newObj[key] = nextObj.map(function (o) {
228
+ if (typeof o === "object" && o != null) {
229
+ return traverse(
230
+ fullInstructionMap,
231
+ thisPath,
232
+ o,
233
+ instructionMap,
234
+ converters,
235
+ nullableValue,
236
+ instructionPaths
237
+ );
238
+ } else if (o == null) {
239
+ return nullableValue;
240
+ } else {
241
+ return o;
242
+ }
243
+ });
244
+ }
245
+ }
246
+ }
247
+
248
+ return newObj || currentObj;
249
+ }
250
+
251
+ /**
252
+ * This function takes an object (snapshot from the Relay store) and applies a
253
+ * set of conversions deeply on the object (instructions coming from "converters"-prop).
254
+ * It converts nullable values either to null or undefined, and it wraps/unwraps enums
255
+ * and unions.
256
+ *
257
+ * It preserves structural integrity where possible, and return new objects where properties
258
+ * have been modified.
259
+ */
260
+ function traverser(
261
+ root,
262
+ instructionMaps_,
263
+ theConverters,
264
+ nullableValue,
265
+ rootObjectKey
266
+ ) {
267
+ if (!root) {
268
+ return nullableValue;
269
+ }
270
+
271
+ var instructionMaps = instructionMaps_ || {};
272
+ var instructionMap = instructionMaps[rootObjectKey || "__root"] || {};
273
+
274
+ var converters = theConverters == null ? {} : theConverters;
275
+ var instructionPaths = Object.keys(instructionMap);
276
+
277
+ // We'll add the fragmentRefs reference to the root if needed here.
278
+ var fragmentsOnRoot = (instructionMap[""] || {}).f === "";
279
+ var unionRootConverter = converters[(instructionMap[""] || {}).u];
280
+
281
+ if (Array.isArray(root)) {
282
+ return root.map(function (v) {
283
+ if (v == null) {
284
+ return nullableValue;
285
+ }
286
+
287
+ var n = [];
288
+
289
+ // Since a root level union is treated as a "new root level", we'll need
290
+ // to do a separate check here of whether there's a fragment on the root
291
+ // we need to account for, or not.
292
+ if (unionRootConverter != null) {
293
+ n = [v.__typename];
294
+ fragmentsOnRoot = (instructionMap[v.__typename] || {}).f === "";
295
+ }
296
+
297
+ var traversedObj = traverse(
298
+ instructionMaps,
299
+ n,
300
+ v,
301
+ instructionMap,
302
+ converters,
303
+ nullableValue,
304
+ instructionPaths,
305
+ fragmentsOnRoot
306
+ );
307
+
308
+ return unionRootConverter != null
309
+ ? unionRootConverter(traversedObj)
310
+ : traversedObj;
311
+ });
312
+ }
313
+
314
+ var newObj = Object.assign({}, root);
315
+
316
+ var n = [];
317
+
318
+ // Same as in the union array check above - if there's a fragment in the new
319
+ // root created by the union, we need to account for that separately here.
320
+ if (unionRootConverter != null) {
321
+ n = [newObj.__typename];
322
+ fragmentsOnRoot = (instructionMap[newObj.__typename] || {}).f === "";
323
+ }
324
+
325
+ var v = traverse(
326
+ instructionMaps,
327
+ n,
328
+ newObj,
329
+ instructionMap,
330
+ converters,
331
+ nullableValue,
332
+ instructionPaths,
333
+ fragmentsOnRoot
334
+ );
335
+
336
+ return unionRootConverter != null ? unionRootConverter(v) : v;
337
+ }
338
+
339
+ export { traverser };