Skip to content

Commit a60774e

Browse files
authored
Merge pull request #23 from toothlessdev/22-implement-partitioning-logic-to-save-blob-to-external-storage
파티셔닝시 CanonicalOperation 을 blob object 로 리턴하도록 수정
2 parents 4ddfc4b + 35cf528 commit a60774e

9 files changed

Lines changed: 201 additions & 29 deletions

File tree

packages/patchlogr-core/src/partition/__tests__/partitionByMethod.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,80 @@ describe("partitionByMethod", () => {
8787
expect(postMethodNode?.children).toHaveLength(1);
8888
expect(postMethodNode?.children?.[0]?.key).toBe("POST /auth/login");
8989
});
90+
91+
test("hashObjects를 리턴한다", () => {
92+
const spec: CanonicalSpec = {
93+
operations: {
94+
"GET /user": {
95+
key: "GET /user",
96+
doc: { tags: ["user"] },
97+
method: "GET",
98+
path: "/user",
99+
request: { params: [] },
100+
responses: {},
101+
},
102+
"POST /user": {
103+
key: "POST /user",
104+
doc: { tags: ["user"] },
105+
method: "POST",
106+
path: "/user",
107+
request: { params: [] },
108+
responses: {},
109+
},
110+
},
111+
};
112+
113+
const result = partitionByMethod(spec);
114+
115+
expect(result.hashObjects).toBeDefined();
116+
expect(result.hashObjects).toHaveLength(2);
117+
});
118+
119+
test("리프노드에는 value가 포함되지 않는다", () => {
120+
const spec: CanonicalSpec = {
121+
operations: {
122+
"GET /user": {
123+
key: "GET /user",
124+
doc: { tags: ["user"] },
125+
method: "GET",
126+
path: "/user",
127+
request: { params: [] },
128+
responses: {},
129+
},
130+
},
131+
};
132+
133+
const result = partitionByMethod(spec);
134+
const leafNode = result.root.children?.[0]?.children?.[0];
135+
136+
expect(leafNode?.type).toBe("leaf");
137+
expect(leafNode?.hash).toBeDefined();
138+
expect(leafNode?.value).toBeUndefined();
139+
});
140+
141+
test("hashObjects에 리프노드에 대한 CanonicalOperation 이 매핑된다", () => {
142+
const operation = {
143+
key: "GET /user" as const,
144+
doc: { tags: ["user"] },
145+
method: "GET" as const,
146+
path: "/user",
147+
request: { params: [] },
148+
responses: {},
149+
};
150+
151+
const spec: CanonicalSpec = {
152+
operations: {
153+
"GET /user": operation,
154+
},
155+
};
156+
157+
const result = partitionByMethod(spec);
158+
const leafNode = result.root.children?.[0]?.children?.[0];
159+
const hashObject = result.hashObjects.find(
160+
(ho) => ho.hash === leafNode?.hash,
161+
);
162+
163+
expect(hashObject).toBeDefined();
164+
expect(hashObject?.data).toEqual(operation);
165+
});
90166
});

packages/patchlogr-core/src/partition/__tests__/partitionByTag.test.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,80 @@ describe("partitionByTag", () => {
112112
expect(defaultTagNode?.children).toHaveLength(1);
113113
expect(defaultTagNode?.children?.[0]?.key).toBe("GET /user");
114114
});
115+
116+
test("hashObjects를 리턴한다", () => {
117+
const spec: CanonicalSpec = {
118+
operations: {
119+
"GET /user": {
120+
key: "GET /user",
121+
doc: { tags: ["user"] },
122+
method: "GET",
123+
path: "/user",
124+
request: { params: [] },
125+
responses: {},
126+
},
127+
"POST /user": {
128+
key: "POST /user",
129+
doc: { tags: ["user"] },
130+
method: "POST",
131+
path: "/user",
132+
request: { params: [] },
133+
responses: {},
134+
},
135+
},
136+
};
137+
138+
const result = partitionByTag(spec);
139+
140+
expect(result.hashObjects).toBeDefined();
141+
expect(result.hashObjects).toHaveLength(2);
142+
});
143+
144+
test("리프노드에는 value가 포함되지 않는다", () => {
145+
const spec: CanonicalSpec = {
146+
operations: {
147+
"GET /user": {
148+
key: "GET /user",
149+
doc: { tags: ["user"] },
150+
method: "GET",
151+
path: "/user",
152+
request: { params: [] },
153+
responses: {},
154+
},
155+
},
156+
};
157+
158+
const result = partitionByTag(spec);
159+
const leafNode = result.root.children?.[0]?.children?.[0];
160+
161+
expect(leafNode?.type).toBe("leaf");
162+
expect(leafNode?.hash).toBeDefined();
163+
expect(leafNode?.value).toBeUndefined();
164+
});
165+
166+
test("hashObjects에 리프노드에 대한 CanonicalOperation 이 매핑된다", () => {
167+
const operation = {
168+
key: "GET /user" as const,
169+
doc: { tags: ["user"] },
170+
method: "GET" as const,
171+
path: "/user",
172+
request: { params: [] },
173+
responses: {},
174+
};
175+
176+
const spec: CanonicalSpec = {
177+
operations: {
178+
"GET /user": operation,
179+
},
180+
};
181+
182+
const result = partitionByTag(spec);
183+
const leafNode = result.root.children?.[0]?.children?.[0];
184+
const hashObject = result.hashObjects.find(
185+
(ho) => ho.hash === leafNode?.hash,
186+
);
187+
188+
expect(hashObject).toBeDefined();
189+
expect(hashObject?.data).toEqual(operation);
190+
});
115191
});
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
export type { Hash, HashNode, PartitionedSpec } from "./partition";
1+
export type { Hash, HashNode } from "./types/hashNode";
2+
export type { PartitionedSpec } from "./types/partitionedSpec";
23

34
export { partitionByMethod } from "./partitionByMethod";
45
export { partitionByTag } from "./partitionByTag";
@@ -8,4 +9,4 @@ export {
89
createLeafNode,
910
createHashedLeaf,
1011
createHashedNode,
11-
} from "./createNode";
12+
} from "./utils/createNode";

packages/patchlogr-core/src/partition/partitionByMethod.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@ import type {
33
HTTPMethod,
44
CanonicalOperation,
55
} from "@patchlogr/types";
6-
import type { PartitionedSpec, HashNode } from "./partition";
6+
7+
import type { HashNode } from "./types/hashNode";
8+
import type { PartitionedSpec } from "./types/partitionedSpec";
9+
import type { HashObject } from "./types/hashObject";
710

811
import { createSHA256Hash } from "../utils/createHash";
912
import stableStringify from "fast-json-stable-stringify";
@@ -15,6 +18,7 @@ export function partitionByMethod(
1518
HTTPMethod,
1619
Array<{ key: string; operation: CanonicalOperation }>
1720
>();
21+
const hashObjects: HashObject<CanonicalOperation>[] = [];
1822

1923
Object.entries(spec.operations).forEach(([key, operation]) => {
2024
if (!methodGroups.has(operation.method)) {
@@ -30,12 +34,15 @@ export function partitionByMethod(
3034

3135
methodGroups.forEach((operations, method) => {
3236
const operationLeaves: HashNode<string, CanonicalOperation>[] =
33-
operations.map(({ key, operation }) => ({
34-
type: "leaf",
35-
key,
36-
hash: createSHA256Hash(stableStringify(operation)),
37-
value: operation,
38-
}));
37+
operations.map(({ key, operation }) => {
38+
const hash = createSHA256Hash(stableStringify(operation));
39+
hashObjects.push({ hash, data: operation });
40+
return {
41+
type: "leaf" as const,
42+
key,
43+
hash,
44+
};
45+
});
3946

4047
const methodHash = createSHA256Hash(
4148
stableStringify(operationLeaves.map((leaf) => leaf.hash)),
@@ -66,5 +73,6 @@ export function partitionByMethod(
6673
...spec.info,
6774
...spec.security,
6875
},
76+
hashObjects,
6977
};
7078
}

packages/patchlogr-core/src/partition/partitionByTag.ts

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import type {
2-
CanonicalSpec,
3-
CanonicalOperation,
4-
OperationKey,
5-
} from "@patchlogr/types";
6-
import type { PartitionedSpec, HashNode } from "./partition";
1+
import type { CanonicalSpec, CanonicalOperation } from "@patchlogr/types";
2+
3+
import type { PartitionedSpec } from "./types/partitionedSpec";
4+
import type { HashNode } from "./types/hashNode";
5+
import type { HashObject } from "./types/hashObject";
76

87
import { createSHA256Hash } from "../utils/createHash";
98
import stableStringify from "fast-json-stable-stringify";
@@ -17,6 +16,7 @@ export function partitionByTag(
1716
string,
1817
Array<{ key: string; operation: CanonicalOperation }>
1918
>();
19+
const hashObjects: HashObject<CanonicalOperation>[] = [];
2020

2121
Object.entries(spec.operations).forEach(([key, operation]) => {
2222
const tag = operation.doc?.tags?.[0] || DEFAULT_TAG;
@@ -25,7 +25,7 @@ export function partitionByTag(
2525
tagGroups.set(tag, []);
2626
}
2727
tagGroups.get(tag)?.push({
28-
key: key as OperationKey,
28+
key: key,
2929
operation,
3030
});
3131
});
@@ -34,12 +34,15 @@ export function partitionByTag(
3434

3535
tagGroups.forEach((operations, tag) => {
3636
const operationLeaves: HashNode<string, CanonicalOperation>[] =
37-
operations.map(({ key, operation }) => ({
38-
type: "leaf",
39-
key,
40-
hash: createSHA256Hash(stableStringify(operation)),
41-
value: operation,
42-
}));
37+
operations.map(({ key, operation }) => {
38+
const hash = createSHA256Hash(stableStringify(operation));
39+
hashObjects.push({ hash, data: operation });
40+
return {
41+
type: "leaf",
42+
key,
43+
hash,
44+
};
45+
});
4346

4447
const tagHash = createSHA256Hash(
4548
stableStringify(operationLeaves.map((leaf) => leaf.hash)),
@@ -70,5 +73,6 @@ export function partitionByTag(
7073
...spec.info,
7174
...spec.security,
7275
},
76+
hashObjects,
7377
};
7478
}

packages/patchlogr-core/src/partition/partition.ts renamed to packages/patchlogr-core/src/partition/types/hashNode.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,3 @@ export type HashNode<K = string, V = unknown> = {
77
children?: HashNode<K, V>[];
88
value?: V;
99
};
10-
11-
export type PartitionedSpec<K = string, V = unknown> = {
12-
root: HashNode<K, V>;
13-
metadata: Record<string, unknown>;
14-
};
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export type HashObject<T> = {
2+
hash: string;
3+
data: T;
4+
};
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { HashNode } from "./hashNode";
2+
import type { HashObject } from "./hashObject";
3+
4+
export type PartitionedSpec<K = string, V = unknown> = {
5+
root: HashNode<K, V>;
6+
metadata: Record<string, unknown>;
7+
hashObjects: HashObject<V>[];
8+
};

packages/patchlogr-core/src/partition/createNode.ts renamed to packages/patchlogr-core/src/partition/utils/createNode.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import type { HashNode } from "./partition";
2-
import { createSHA256Hash } from "../utils/createHash";
1+
import type { HashNode } from "../types/hashNode";
2+
import { createSHA256Hash } from "../../utils/createHash";
33
import stableStringify from "fast-json-stable-stringify";
44

55
export function createNode<K, V>(

0 commit comments

Comments
 (0)