@vtex/api 6.45.14-beta.1 → 6.45.14

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
@@ -6,6 +6,19 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ## [Unreleased]
9
+
10
+ ## [6.45.14] - 2023-02-01
11
+
12
+ ### Added
13
+
14
+ - New tests for `MineWinsConflictsResolver`.
15
+
16
+ ### Fixed
17
+
18
+ - Merged/Rebased content not being returned causing inconsistencies.
19
+ - Do not return empty content if no conflict is found.
20
+
21
+ ## [6.45.13] - 2022-12-12
9
22
  ### Changed
10
23
  - Deterministic cache for getWithBody
11
24
  - Remove socket metrics per origin
@@ -13,6 +26,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
13
26
  ## [6.45.12] - 2022-04-14
14
27
 
15
28
  ### Fixed
29
+
16
30
  - Update sensitive fields list.
17
31
  - Remove "error" field.
18
32
  - Add missing fields.
@@ -1737,3 +1751,8 @@ instead
1737
1751
  ### Changed
1738
1752
 
1739
1753
  - `HttpClient` now adds `'Accept-Encoding': 'gzip'` header by default.
1754
+
1755
+
1756
+ [Unreleased]: https://github.com/vtex/node-vtex-api/compare/v6.45.14...HEAD
1757
+ [6.45.14]: https://github.com/vtex/node-vtex-api/compare/v6.45.13...v6.45.14
1758
+ [6.45.13]: https://github.com/vtex/node-vtex-api/compare/v6.45.12...v6.45.13
@@ -68,15 +68,40 @@ class VBase extends InfraClient_1.InfraClient {
68
68
  const headers = conflictsResolver ? { 'X-Vtex-Detect-Conflicts': true } : {};
69
69
  const inflightKey = HttpClient_1.inflightURL;
70
70
  const metric = 'vbase-get-json';
71
- return this.http.getRaw(routes.File(bucket, path), { headers, inflightKey, metric, nullIfNotFound, tracing: {
71
+ return this.http
72
+ .getRaw(routes.File(bucket, path), {
73
+ headers,
74
+ inflightKey,
75
+ metric,
76
+ nullIfNotFound,
77
+ tracing: {
72
78
  requestSpanNameSuffix: metric,
73
79
  ...tracingConfig === null || tracingConfig === void 0 ? void 0 : tracingConfig.tracing,
74
- } })
80
+ },
81
+ })
75
82
  .catch(async (error) => {
76
83
  const { response } = error;
77
84
  if (response && response.status === 409 && conflictsResolver) {
78
- const conflictsMergedData = await conflictsResolver.resolve(this.context.logger);
79
- return { ...response, data: conflictsMergedData };
85
+ try {
86
+ const conflictsMergedData = await conflictsResolver.resolve(this.context.logger);
87
+ return { ...response, data: conflictsMergedData };
88
+ }
89
+ catch (resolverError) {
90
+ const typedResolverError = resolverError;
91
+ if ((typedResolverError === null || typedResolverError === void 0 ? void 0 : typedResolverError.status) === 404) {
92
+ return this.http.getRaw(routes.File(bucket, path), {
93
+ 'X-Vtex-Detect-Conflicts': false,
94
+ inflightKey,
95
+ metric,
96
+ nullIfNotFound,
97
+ tracing: {
98
+ requestSpanNameSuffix: metric,
99
+ ...tracingConfig === null || tracingConfig === void 0 ? void 0 : tracingConfig.tracing,
100
+ },
101
+ });
102
+ }
103
+ throw resolverError;
104
+ }
80
105
  }
81
106
  throw error;
82
107
  });
@@ -12,8 +12,8 @@ export declare class MineWinsConflictsResolver<T> implements ConflictsResolver<T
12
12
  private filePath;
13
13
  private comparableKeys;
14
14
  constructor(client: VBase, bucket: string, filePath: string, comparableKeys?: string[]);
15
- resolve(logger?: Logger): Promise<T>;
16
- protected mergeMineWins(base: Configuration, master: Configuration, mine: Configuration): Configuration;
15
+ resolve(logger?: Logger): Promise<any>;
16
+ protected mergeMineWins(base: Configuration, master: Configuration, mine: Configuration): Record<string, object | Record<string, object> | Record<string, object>[]> | Record<string, object>[];
17
17
  private parseConflict;
18
18
  private serializeContentByMimetype;
19
19
  private parseContentByMimetype;
@@ -11,27 +11,19 @@ class MineWinsConflictsResolver {
11
11
  this.comparableKeys = comparableKeys;
12
12
  }
13
13
  async resolve(logger) {
14
- return await this.client.getConflicts(this.bucket).then(data => {
14
+ return await this.client.getConflicts(this.bucket).then((data) => {
15
15
  const { data: conflicts } = data;
16
- const selectedConflict = conflicts.find(conflict => conflict.path === this.filePath);
16
+ const selectedConflict = conflicts.find((conflict) => conflict.path === this.filePath);
17
17
  if (!selectedConflict) {
18
- return {};
18
+ throw {
19
+ message: 'No conflict could be found.',
20
+ status: 404,
21
+ };
19
22
  }
20
23
  selectedConflict.base.parsedContent = this.parseConflict(selectedConflict.base);
21
24
  selectedConflict.master.parsedContent = this.parseConflict(selectedConflict.master);
22
25
  selectedConflict.mine.parsedContent = this.parseConflict(selectedConflict.mine);
23
26
  const resolved = this.resolveConflictMineWins(selectedConflict);
24
- if (logger) {
25
- logger.info({
26
- base: selectedConflict.base.parsedContent,
27
- bucket: this.bucket,
28
- conflictsResolution: MineWinsConflictsResolver.constructor.name,
29
- filePath: this.filePath,
30
- master: selectedConflict.master.parsedContent,
31
- mine: selectedConflict.mine.parsedContent,
32
- resolved,
33
- });
34
- }
35
27
  return resolved;
36
28
  });
37
29
  }
@@ -64,16 +56,19 @@ class MineWinsConflictsResolver {
64
56
  }
65
57
  resolveConflictMineWins(conflict) {
66
58
  if (!conflict) {
67
- return {};
59
+ throw {
60
+ message: 'No conflict could be found.',
61
+ status: 404,
62
+ };
68
63
  }
69
64
  const { base, master, mine, path } = conflict;
70
- this.mergeMineWins(base.parsedContent, master.parsedContent, mine.parsedContent);
65
+ const merged = this.mergeMineWins(base.parsedContent, master.parsedContent, mine.parsedContent);
71
66
  const mergedContent = {
72
- content: js_base64_1.Base64.encode(this.serializeContentByMimetype(mine.parsedContent, conflict.mine.mimeType)),
67
+ content: js_base64_1.Base64.encode(this.serializeContentByMimetype(merged, conflict.mine.mimeType)),
73
68
  mimeType: conflict.mine.mimeType,
74
69
  };
75
70
  this.client.resolveConflict(this.bucket, path, mergedContent);
76
- return mine.parsedContent;
71
+ return merged;
77
72
  }
78
73
  mergeMineWinsObject(base, master, mine) {
79
74
  const merged = { ...master, ...mine };
@@ -99,10 +94,10 @@ class MineWinsConflictsResolver {
99
94
  return mine;
100
95
  }
101
96
  removeMasterDeletedElements(base, master, mine) {
102
- base.forEach(baseItem => {
97
+ base.forEach((baseItem) => {
103
98
  const foundInMaster = this.isObjectInArray(baseItem, master);
104
99
  if (!foundInMaster) {
105
- const foundInMine = mine.findIndex(mineItem => ramda_1.equals(mineItem, baseItem));
100
+ const foundInMine = mine.findIndex((mineItem) => ramda_1.equals(mineItem, baseItem));
106
101
  if (foundInMine > -1) {
107
102
  mine.splice(foundInMine, 1);
108
103
  }
@@ -110,10 +105,10 @@ class MineWinsConflictsResolver {
110
105
  });
111
106
  }
112
107
  isObjectInArray(obj, array) {
113
- return array.find(item => ramda_1.equals(item, obj));
108
+ return array.find((item) => ramda_1.equals(item, obj));
114
109
  }
115
110
  appendMasterAddedElements(base, master, mine) {
116
- master.forEach(item => {
111
+ master.forEach((item) => {
117
112
  if (this.shouldAddToMine(item, base, mine)) {
118
113
  mine.push(item);
119
114
  }
@@ -0,0 +1,17 @@
1
+ export declare function getMockConflicts(path: string, base: object, mine: object, master: object): {
2
+ data: {
3
+ base: {
4
+ content: string;
5
+ mimeType: string;
6
+ };
7
+ master: {
8
+ content: string;
9
+ mimeType: string;
10
+ };
11
+ mine: {
12
+ content: string;
13
+ mimeType: string;
14
+ };
15
+ path: string;
16
+ }[];
17
+ };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function jsonToBase64(json) {
4
+ return Buffer.from(JSON.stringify(json)).toString('base64');
5
+ }
6
+ function getMockConflicts(path, base, mine, master) {
7
+ return {
8
+ data: [
9
+ {
10
+ base: {
11
+ content: jsonToBase64(base),
12
+ mimeType: 'application/json',
13
+ },
14
+ master: {
15
+ content: jsonToBase64(master),
16
+ mimeType: 'application/json',
17
+ },
18
+ mine: {
19
+ content: jsonToBase64(mine),
20
+ mimeType: 'application/json',
21
+ },
22
+ path,
23
+ },
24
+ ],
25
+ };
26
+ }
27
+ exports.getMockConflicts = getMockConflicts;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtex/api",
3
- "version": "6.45.14-beta.1",
3
+ "version": "6.45.14",
4
4
  "description": "VTEX I/O API client",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",