@labdigital/commercetools-mock 2.20.0 → 2.20.2
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/dist/index.cjs +37 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -5
- package/dist/index.d.ts +8 -5
- package/dist/index.js +37 -11
- package/dist/index.js.map +1 -1
- package/package.json +4 -5
- package/src/repositories/abstract.ts +23 -9
- package/src/repositories/category/index.test.ts +92 -0
- package/src/repositories/category/index.ts +43 -2
- package/src/repositories/extension.ts +4 -1
- package/src/repositories/project.ts +2 -2
- package/src/services/category.test.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@labdigital/commercetools-mock",
|
|
3
|
-
"version": "2.20.
|
|
3
|
+
"version": "2.20.2",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Michael van Tellingen",
|
|
6
6
|
"type": "module",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@types/uuid": "^9.0.8",
|
|
50
50
|
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
|
51
51
|
"@typescript-eslint/parser": "^7.0.2",
|
|
52
|
-
"@vitest/coverage-v8": "^1.
|
|
52
|
+
"@vitest/coverage-v8": "^1.5.0",
|
|
53
53
|
"esbuild": "^0.20.1",
|
|
54
54
|
"eslint": "^8.57.0",
|
|
55
55
|
"eslint-plugin-sort-class-members": "^1.20.0",
|
|
@@ -65,12 +65,11 @@
|
|
|
65
65
|
"tslib": "^2.6.2",
|
|
66
66
|
"tsup": "^8.0.2",
|
|
67
67
|
"typescript": "^5.3.3",
|
|
68
|
-
"vitest": "^1.
|
|
68
|
+
"vitest": "^1.5.0"
|
|
69
69
|
},
|
|
70
|
-
"packageManager": "pnpm@8.6.5",
|
|
71
70
|
"engines": {
|
|
72
71
|
"node": ">=18",
|
|
73
|
-
"pnpm": ">=
|
|
72
|
+
"pnpm": ">=9.0.2"
|
|
74
73
|
},
|
|
75
74
|
"publishConfig": {
|
|
76
75
|
"access": "public"
|
|
@@ -53,7 +53,7 @@ export abstract class AbstractRepository<R extends BaseResource | Project> {
|
|
|
53
53
|
resource: R,
|
|
54
54
|
): void;
|
|
55
55
|
|
|
56
|
-
abstract postProcessResource(resource: any): any;
|
|
56
|
+
abstract postProcessResource(context: RepositoryContext, resource: any): any;
|
|
57
57
|
|
|
58
58
|
processUpdateActions(
|
|
59
59
|
context: RepositoryContext,
|
|
@@ -78,7 +78,7 @@ export abstract class AbstractRepository<R extends BaseResource | Project> {
|
|
|
78
78
|
this.saveUpdate(context, version, updatedResource);
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
const result = this.postProcessResource(updatedResource);
|
|
81
|
+
const result = this.postProcessResource(context, updatedResource);
|
|
82
82
|
if (!result) {
|
|
83
83
|
throw new Error("invalid post process action");
|
|
84
84
|
}
|
|
@@ -113,7 +113,9 @@ export abstract class AbstractResourceRepository<
|
|
|
113
113
|
id,
|
|
114
114
|
params,
|
|
115
115
|
);
|
|
116
|
-
return resource
|
|
116
|
+
return resource
|
|
117
|
+
? this.postProcessResource(context, resource, params)
|
|
118
|
+
: null;
|
|
117
119
|
}
|
|
118
120
|
|
|
119
121
|
get(
|
|
@@ -127,7 +129,9 @@ export abstract class AbstractResourceRepository<
|
|
|
127
129
|
id,
|
|
128
130
|
params,
|
|
129
131
|
);
|
|
130
|
-
return resource
|
|
132
|
+
return resource
|
|
133
|
+
? this.postProcessResource(context, resource, params)
|
|
134
|
+
: null;
|
|
131
135
|
}
|
|
132
136
|
|
|
133
137
|
getByKey(
|
|
@@ -141,10 +145,16 @@ export abstract class AbstractResourceRepository<
|
|
|
141
145
|
key,
|
|
142
146
|
params,
|
|
143
147
|
);
|
|
144
|
-
return resource
|
|
148
|
+
return resource
|
|
149
|
+
? this.postProcessResource(context, resource, params)
|
|
150
|
+
: null;
|
|
145
151
|
}
|
|
146
152
|
|
|
147
|
-
postProcessResource(
|
|
153
|
+
postProcessResource(
|
|
154
|
+
context: RepositoryContext,
|
|
155
|
+
resource: ResourceMap[T],
|
|
156
|
+
params?: GetParams,
|
|
157
|
+
): ResourceMap[T] {
|
|
148
158
|
return resource;
|
|
149
159
|
}
|
|
150
160
|
|
|
@@ -153,9 +163,13 @@ export abstract class AbstractResourceRepository<
|
|
|
153
163
|
...params,
|
|
154
164
|
});
|
|
155
165
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
166
|
+
const data = result.results.map((r) =>
|
|
167
|
+
this.postProcessResource(context, r as ResourceMap[T]),
|
|
168
|
+
);
|
|
169
|
+
return {
|
|
170
|
+
...result,
|
|
171
|
+
results: data,
|
|
172
|
+
};
|
|
159
173
|
}
|
|
160
174
|
|
|
161
175
|
saveNew(
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import { InMemoryStorage } from "~src/storage";
|
|
3
|
+
import { CategoryRepository } from "./index";
|
|
4
|
+
|
|
5
|
+
describe("Order repository", () => {
|
|
6
|
+
const storage = new InMemoryStorage();
|
|
7
|
+
const repository = new CategoryRepository(storage);
|
|
8
|
+
|
|
9
|
+
test("valid ancestors", async () => {
|
|
10
|
+
const root = repository.create(
|
|
11
|
+
{ projectKey: "dummy" },
|
|
12
|
+
{
|
|
13
|
+
key: "root",
|
|
14
|
+
slug: {
|
|
15
|
+
en: "root",
|
|
16
|
+
},
|
|
17
|
+
name: {
|
|
18
|
+
en: "root",
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
const level1 = repository.create(
|
|
24
|
+
{ projectKey: "dummy" },
|
|
25
|
+
{
|
|
26
|
+
key: "level-1",
|
|
27
|
+
slug: {
|
|
28
|
+
en: "level-1",
|
|
29
|
+
},
|
|
30
|
+
name: {
|
|
31
|
+
en: "level-1",
|
|
32
|
+
},
|
|
33
|
+
parent: {
|
|
34
|
+
id: root.id,
|
|
35
|
+
typeId: "category",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const level2 = repository.create(
|
|
41
|
+
{ projectKey: "dummy" },
|
|
42
|
+
{
|
|
43
|
+
key: "level-2",
|
|
44
|
+
slug: {
|
|
45
|
+
en: "level-2",
|
|
46
|
+
},
|
|
47
|
+
name: {
|
|
48
|
+
en: "level-2",
|
|
49
|
+
},
|
|
50
|
+
parent: {
|
|
51
|
+
id: level1.id,
|
|
52
|
+
typeId: "category",
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
const level3 = repository.create(
|
|
58
|
+
{ projectKey: "dummy" },
|
|
59
|
+
{
|
|
60
|
+
key: "level-3",
|
|
61
|
+
slug: {
|
|
62
|
+
en: "level-3",
|
|
63
|
+
},
|
|
64
|
+
name: {
|
|
65
|
+
en: "level-3",
|
|
66
|
+
},
|
|
67
|
+
parent: {
|
|
68
|
+
id: level2.id,
|
|
69
|
+
typeId: "category",
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const result = repository.get({ projectKey: "dummy" }, level3.id);
|
|
75
|
+
expect(result?.ancestors).toHaveLength(3);
|
|
76
|
+
expect(result?.ancestors).toEqual([
|
|
77
|
+
{ id: level2.id, typeId: "category" },
|
|
78
|
+
{ id: level1.id, typeId: "category" },
|
|
79
|
+
{ id: root.id, typeId: "category" },
|
|
80
|
+
]);
|
|
81
|
+
|
|
82
|
+
const expandResult = repository.get({ projectKey: "dummy" }, level3.id, {
|
|
83
|
+
expand: ["ancestors[*]"],
|
|
84
|
+
});
|
|
85
|
+
expect(expandResult?.ancestors).toHaveLength(3);
|
|
86
|
+
expect(expandResult?.ancestors).toEqual([
|
|
87
|
+
{ id: level2.id, typeId: "category", obj: level2 },
|
|
88
|
+
{ id: level1.id, typeId: "category", obj: level1 },
|
|
89
|
+
{ id: root.id, typeId: "category", obj: root },
|
|
90
|
+
]);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
@@ -1,9 +1,16 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Category,
|
|
3
|
+
CategoryDraft,
|
|
4
|
+
CategoryReference,
|
|
5
|
+
} from "@commercetools/platform-sdk";
|
|
2
6
|
import { v4 as uuidv4 } from "uuid";
|
|
3
7
|
import { getBaseResourceProperties } from "~src/helpers";
|
|
8
|
+
import { parseExpandClause } from "~src/lib/expandParser";
|
|
4
9
|
import { AbstractStorage } from "~src/storage/abstract";
|
|
10
|
+
import { Writable } from "~src/types";
|
|
5
11
|
import {
|
|
6
12
|
AbstractResourceRepository,
|
|
13
|
+
GetParams,
|
|
7
14
|
type RepositoryContext,
|
|
8
15
|
} from "../abstract";
|
|
9
16
|
import { createCustomFields } from "../helpers";
|
|
@@ -26,7 +33,7 @@ export class CategoryRepository extends AbstractResourceRepository<"category"> {
|
|
|
26
33
|
parent: draft.parent
|
|
27
34
|
? { typeId: "category", id: draft.parent.id! }
|
|
28
35
|
: undefined,
|
|
29
|
-
ancestors: [], //
|
|
36
|
+
ancestors: [], // Resolved at runtime
|
|
30
37
|
assets:
|
|
31
38
|
draft.assets?.map((d) => ({
|
|
32
39
|
id: uuidv4(),
|
|
@@ -49,4 +56,38 @@ export class CategoryRepository extends AbstractResourceRepository<"category"> {
|
|
|
49
56
|
};
|
|
50
57
|
return this.saveNew(context, resource);
|
|
51
58
|
}
|
|
59
|
+
|
|
60
|
+
postProcessResource(
|
|
61
|
+
context: RepositoryContext,
|
|
62
|
+
resource: Writable<Category>,
|
|
63
|
+
params?: GetParams,
|
|
64
|
+
): Category {
|
|
65
|
+
let node: Category = resource;
|
|
66
|
+
const ancestors: CategoryReference[] = [];
|
|
67
|
+
|
|
68
|
+
// TODO: The expand clause here is a hack, the current expand architecture
|
|
69
|
+
// is not able to handle the case for 'dynamic' fields like ancestors which
|
|
70
|
+
// are resolved at runtime. We should do the expand resolution post query
|
|
71
|
+
// execution for all resources
|
|
72
|
+
|
|
73
|
+
const expandClauses = params?.expand?.map(parseExpandClause) ?? [];
|
|
74
|
+
const addExpand = expandClauses?.find(
|
|
75
|
+
(c) => c.element === "ancestors" && c.index === "*",
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
while (node.parent) {
|
|
79
|
+
node = this._storage.getByResourceIdentifier<"category">(
|
|
80
|
+
context.projectKey,
|
|
81
|
+
node.parent,
|
|
82
|
+
);
|
|
83
|
+
ancestors.push({
|
|
84
|
+
typeId: "category",
|
|
85
|
+
id: node.id,
|
|
86
|
+
obj: addExpand ? node : undefined,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
resource.ancestors = ancestors;
|
|
91
|
+
return resource;
|
|
92
|
+
}
|
|
52
93
|
}
|
|
@@ -35,7 +35,10 @@ export class ExtensionRepository extends AbstractResourceRepository<"extension">
|
|
|
35
35
|
return this.saveNew(context, resource);
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
postProcessResource(
|
|
38
|
+
postProcessResource(
|
|
39
|
+
context: RepositoryContext,
|
|
40
|
+
resource: Extension,
|
|
41
|
+
): Extension {
|
|
39
42
|
if (resource) {
|
|
40
43
|
const extension = resource as Extension;
|
|
41
44
|
if (
|
|
@@ -31,10 +31,10 @@ export class ProjectRepository extends AbstractRepository<Project> {
|
|
|
31
31
|
|
|
32
32
|
get(context: RepositoryContext): Project | null {
|
|
33
33
|
const resource = this._storage.getProject(context.projectKey);
|
|
34
|
-
return this.postProcessResource(resource);
|
|
34
|
+
return this.postProcessResource(context, resource);
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
postProcessResource(resource: Project): Project {
|
|
37
|
+
postProcessResource(context: RepositoryContext, resource: Project): Project {
|
|
38
38
|
if (resource) {
|
|
39
39
|
return maskSecretValue(resource, "externalOAuth.authorizationHeader");
|
|
40
40
|
}
|
|
@@ -144,6 +144,8 @@ describe("categories changeParent", () => {
|
|
|
144
144
|
typeId: "category",
|
|
145
145
|
id: category1?.id,
|
|
146
146
|
});
|
|
147
|
+
expect(changeNameResponse.body.ancestors).toHaveLength(1);
|
|
148
|
+
expect(changeNameResponse.body.ancestors[0].id).toEqual(category1?.id);
|
|
147
149
|
});
|
|
148
150
|
});
|
|
149
151
|
|