Skip to content

Commit 6426cad

Browse files
committed
init
0 parents  commit 6426cad

19 files changed

+704
-0
lines changed

.editorconfig

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
indent_size = 2
6+
indent_style = space

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
node_modules

.idea/.gitignore

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/schema-sample.iml

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.nvmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
14.16.1

README.md

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
# 배경
3+
Scheme 과 데이터가 N : N 관계에 있을때,
4+
이를 검증하는 2가지 방법에 대한 예시 프로그램을 만들어봅니다.
5+
6+
# 환경 구성
7+
```
8+
# node 14.16.1
9+
nvm use
10+
11+
npm ci
12+
13+
# Schema 파일을 특정할 수 있는 검증 방법
14+
npm run single
15+
16+
# Schema 파일을 특정할 수 없는 검증 방법
17+
npm run bulk
18+
```
19+
20+
# 정리
21+
- bulk : 모든 Schema 들을 병합하여 특정 data.json 이 valid 한지 여부만 판단할 수 있습니다.
22+
- 장점
23+
- 개별적으로 비교하지 않아도 되어 처리 시간이 단축될 수 있다.
24+
- 매핑 파일이 필요하지 않다.
25+
- 단점: 개별 Schema 들이 복잡하게 구성되어있다면 `mergeSchemes` 함수가 훨씬 복잡하게 구현되어야 한다.
26+
27+
- single: 특정 data.json 을 기준으로 일치하는 Schema 를 찾습니다.
28+
- 장점: 매핑 파일이 필요하지 않다.
29+
- 단점: 일치하지 않는 Schema 도 모두 validate 함수 호출
30+
31+
---
32+
33+
Data, Schema 모두에 ID 를 넣게 되었을때
34+
- 장점: data.json 만 보고 이 데이터가 어떤 Schema 를 따라야 하는지 알 수 있다.
35+
- 단점: data.json 의 id 와 schema.json 의 $id 를 기준으로 할것인지 아니면 다른 기준으로 할 것인지... 모호하다.
36+
37+

bulk.ts

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { resolve } from 'path'
2+
import { readdir } from 'fs/promises'
3+
import Ajv from 'ajv'
4+
import addFormats from 'ajv-formats'
5+
import { pipe, each } from '@fxts/core'
6+
import type { JSONSchema7 } from 'json-schema'
7+
8+
type KurlySchema = JSONSchema7 &
9+
Required<Pick<JSONSchema7, "$id" | "oneOf" | "definitions">>;
10+
11+
async function mergeSchemes(): Promise<KurlySchema> {
12+
const mergedSchema: KurlySchema = {
13+
$id: 'kurly',
14+
$schema: "http://json-schema.org/draft-07/schema#",
15+
definitions: {},
16+
oneOf: []
17+
}
18+
const schemaDir = resolve(__dirname, './schema')
19+
const schemaFileNames = await readdir(schemaDir)
20+
pipe(
21+
schemaFileNames,
22+
each(fileName => {
23+
const schema = require(`${schemaDir}/${fileName}`)
24+
const schemaId = schema.$id
25+
mergedSchema.definitions = {
26+
...mergedSchema.definitions,
27+
...schema.definitions,
28+
[schemaId]: schema,
29+
}
30+
mergedSchema.oneOf.push({ $ref: `#/definitions/${schemaId}` })
31+
})
32+
)
33+
return mergedSchema
34+
}
35+
36+
async function run() {
37+
const ajv = new Ajv({ strict: true })
38+
addFormats(ajv)
39+
40+
/*
41+
NOTE: 이 함수가 중요하옵니다.
42+
schema Dir 의 모든 schema 들 하나로 합칩니다.
43+
*/
44+
const mergedSchema = await mergeSchemes();
45+
46+
const validate = ajv.compile(mergedSchema)
47+
48+
// NOTE: 아래는 예시 폴더 안의 파일들을 검사합니다.
49+
const exampleDir = resolve(__dirname, './examples')
50+
const exampleFileNames = await readdir(exampleDir)
51+
52+
pipe(
53+
exampleFileNames,
54+
each(fileName => {
55+
const isValid = validate(require(`${exampleDir}/${fileName}`))
56+
console.group()
57+
console.log(`${fileName} : is ${isValid ? 'Valid' : 'In-Valid'}`)
58+
/* NOTE: Detail Logging
59+
if (!isValid && validate.errors) {
60+
pipe(
61+
validate.errors,
62+
each(error => {
63+
const { message } = error
64+
console.warn(`${fileName} : ${message}`)
65+
})
66+
)
67+
}
68+
*/
69+
console.groupEnd()
70+
})
71+
)
72+
}
73+
74+
run()
75+
76+
/*
77+
NOTE:
78+
잘 되는 것 처럼 보입니다만 하나의 문제가 있습니다.
79+
validate 함수는 boolean 만 return 하기 때문에 검증된 파일이 어떤 Schema 인지 모릅니다.
80+
(single 파일에서 처럼 개별벅으로 검사하지 않는 이상 가져올 수 있는 방법이 없는것 같아용ㅠ)
81+
*/

examples/holidayDelivery.json

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"regionCode": [
3+
"A",
4+
"R",
5+
"C",
6+
"X",
7+
"F",
8+
"M",
9+
"I",
10+
"Y",
11+
"H",
12+
"D",
13+
"B",
14+
"S",
15+
"T",
16+
"G",
17+
"Z",
18+
"W"
19+
],
20+
"ALL": {
21+
"startDate": "2022-09-09T23:00:00+09:00",
22+
"endDate": "2022-09-10T22:59:59+09:00",
23+
"description": "오늘 주문하고 <span class='emph'>월요일(9/12) 아침</span> 샛별배송 받으세요."
24+
},
25+
"AA": {
26+
"startDate": "2022-09-09T23:00:00+09:00",
27+
"endDate": "2022-09-10T22:59:59+09:00",
28+
"description": "오늘 주문하고 <span class='emph'>월요일(9/12) 아침</span> 샛별배송 받으세요."
29+
},
30+
"AB": {
31+
"startDate": "2022-09-09T23:00:00+09:00",
32+
"endDate": "2022-09-10T19:59:59+09:00",
33+
"description": "오늘 주문하고 <span class='emph'>월요일(9/12) 아침</span> 샛별배송 받으세요."
34+
},
35+
"BS": {
36+
"startDate": "2022-09-09T23:00:00+09:00",
37+
"endDate": "2022-09-10T17:59:59+09:00",
38+
"description": "오늘 주문하고 <span class='emph'>월요일(9/12) 아침</span> 샛별배송 받으세요."
39+
},
40+
"UL": {
41+
"startDate": "2022-09-09T23:00:00+09:00",
42+
"endDate": "2022-09-10T17:59:59+09:00",
43+
"description": "오늘 주문하고 <span class='emph'>월요일(9/12) 아침</span> 샛별배송 받으세요."
44+
}
45+
}

examples/other.id.valid.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"id": "other",
3+
"foo": "foo",
4+
"bar": "bar"
5+
}

examples/other.invalid.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"foo": "no-foo",
3+
"bar": "no-bar"
4+
}

examples/other.json

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"foo": "foo",
3+
"bar": "bar"
4+
}

0 commit comments

Comments
 (0)