yaml-admin-api 0.0.77 → 0.0.79
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/package.json +1 -1
- package/src/crud/entity-api-generator.js +60 -83
package/package.json
CHANGED
|
@@ -89,12 +89,52 @@ const generateCrud = async ({ app, db, entity_name, yml_entity, yml, options })
|
|
|
89
89
|
return key
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
+
// unique 검사 함수
|
|
93
|
+
const checkUnique = async (entity, excludeId = null) => {
|
|
94
|
+
const uniqueFields = yml_entity.unique
|
|
95
|
+
if (!uniqueFields || uniqueFields.length === 0) return
|
|
96
|
+
|
|
97
|
+
const f = {}
|
|
98
|
+
for (const field of uniqueFields) {
|
|
99
|
+
f[field.name] = entity[field.name]
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// 자기 자신 제외 (update 시)
|
|
103
|
+
if (excludeId !== null) {
|
|
104
|
+
f[key_field.name] = { $ne: excludeId }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const existing = await db.collection(collection_name).findOne(f)
|
|
108
|
+
if (existing) {
|
|
109
|
+
const fieldNames = uniqueFields.map(u => {
|
|
110
|
+
const fieldDef = yml_entity.fields?.find(field => field.name === u.name)
|
|
111
|
+
return fieldDef?.label || u.name
|
|
112
|
+
}).join(', ')
|
|
113
|
+
const fieldValues = uniqueFields.map(u => entity[u.name]).join(', ')
|
|
114
|
+
throw new Error("duplicate key of [" + fieldNames + "] - [" + fieldValues + "]")
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
92
118
|
const parseValueByType = (value, field) => {
|
|
93
119
|
const { type, reference_entity, reference_match } = field
|
|
94
120
|
if(value == 'not null')
|
|
95
121
|
return { $ne: null }
|
|
96
122
|
else if(value == 'null')
|
|
97
123
|
return null
|
|
124
|
+
if(value?.startsWith('$')) {
|
|
125
|
+
const [op, val] = value.split(' ')
|
|
126
|
+
if(op == '$lte')
|
|
127
|
+
return { $lte: parseFloat(val) }
|
|
128
|
+
else if(op == '$gte')
|
|
129
|
+
return { $gte: val }
|
|
130
|
+
else if(op == '$lt')
|
|
131
|
+
return { $lt: val }
|
|
132
|
+
else if(op == '$gt')
|
|
133
|
+
return { $gt: val }
|
|
134
|
+
else
|
|
135
|
+
return value
|
|
136
|
+
}
|
|
137
|
+
|
|
98
138
|
if (type == 'boolean') {
|
|
99
139
|
if(value == 'true')
|
|
100
140
|
return true
|
|
@@ -262,9 +302,6 @@ const generateCrud = async ({ app, db, entity_name, yml_entity, yml, options })
|
|
|
262
302
|
//Custom f list End
|
|
263
303
|
|
|
264
304
|
const projection = (key_field.name == '_id' ? {} : { _id: false })
|
|
265
|
-
if(yml.debug)
|
|
266
|
-
console.log('list', entity_name, f)
|
|
267
|
-
|
|
268
305
|
let list, count;
|
|
269
306
|
let aggregate = await makeApiGenerateAggregate(db, entity_name, yml_entity, yml, options)
|
|
270
307
|
|
|
@@ -274,9 +311,12 @@ const generateCrud = async ({ app, db, entity_name, yml_entity, yml, options })
|
|
|
274
311
|
count = countResult.length > 0 ? countResult[0].count : 0
|
|
275
312
|
|
|
276
313
|
aggregate = [...aggregate, { $sort: s }, { $skip: parseInt(_start) }, { $limit: l }]
|
|
314
|
+
if(yml.debug)
|
|
315
|
+
console.log('list', entity_name, JSON.stringify(aggregate, null, 2))
|
|
277
316
|
list = await db.collection(collection_name).aggregate(aggregate).toArray()
|
|
278
|
-
} else
|
|
279
|
-
|
|
317
|
+
} else {
|
|
318
|
+
if(yml.debug)
|
|
319
|
+
console.log('list', entity_name, f)
|
|
280
320
|
count = await db.collection(collection_name).find(f).project(projection).sort(s).count()
|
|
281
321
|
list = await db.collection(collection_name).find(f).project(projection).sort(s).skip(parseInt(_start)).limit(l).toArray()
|
|
282
322
|
}
|
|
@@ -362,6 +402,9 @@ const generateCrud = async ({ app, db, entity_name, yml_entity, yml, options })
|
|
|
362
402
|
// default_filter 값을 entity에 자동 적용
|
|
363
403
|
Object.assign(entity, default_filter)
|
|
364
404
|
|
|
405
|
+
// unique 검사
|
|
406
|
+
await checkUnique(entity)
|
|
407
|
+
|
|
365
408
|
//Custom Create Start
|
|
366
409
|
|
|
367
410
|
//Custom Create End
|
|
@@ -408,6 +451,9 @@ const generateCrud = async ({ app, db, entity_name, yml_entity, yml, options })
|
|
|
408
451
|
}
|
|
409
452
|
}
|
|
410
453
|
|
|
454
|
+
// unique 검사 (자기 자신 제외)
|
|
455
|
+
await checkUnique(entity, entityId)
|
|
456
|
+
|
|
411
457
|
await db.collection(collection_name).updateOne(f, { $set: entity });
|
|
412
458
|
|
|
413
459
|
//Custom Create Tail Start
|
|
@@ -726,6 +772,15 @@ const makeApiGenerateAggregate = async (db, entity_name, yml_entity, yml, option
|
|
|
726
772
|
{ $match: { $expr: { $eq: ['$' + match, '$$local_key'] } } }
|
|
727
773
|
]
|
|
728
774
|
|
|
775
|
+
// filter 처리
|
|
776
|
+
if (Array.isArray(apiGenerateItem.filter)) {
|
|
777
|
+
let filterMatch = {}
|
|
778
|
+
apiGenerateItem.filter.forEach(f => {
|
|
779
|
+
filterMatch[f.name] = f.value
|
|
780
|
+
})
|
|
781
|
+
innerPipeline.push({ $match: filterMatch })
|
|
782
|
+
}
|
|
783
|
+
|
|
729
784
|
// single일 때 max _id로 하나만 선택 ($match 바로 다음에)
|
|
730
785
|
if(single) {
|
|
731
786
|
innerPipeline.push({ $sort: { _id: -1 } })
|
|
@@ -785,84 +840,6 @@ const makeApiGenerateAggregate = async (db, entity_name, yml_entity, yml, option
|
|
|
785
840
|
return aggregate
|
|
786
841
|
}
|
|
787
842
|
|
|
788
|
-
const makeApiGenerateFields = async (db, entity_name, yml_entity, yml, options, data_list) => {
|
|
789
|
-
const apiGenerate = yml_entity.api_generate
|
|
790
|
-
if(!apiGenerate)
|
|
791
|
-
return;
|
|
792
|
-
for(let key in apiGenerate) {
|
|
793
|
-
|
|
794
|
-
const apiGenerateItem = apiGenerate[key]
|
|
795
|
-
let { entity, field, fields, match, sort, limit, single, match_from } = apiGenerateItem
|
|
796
|
-
|
|
797
|
-
sort = sort || []
|
|
798
|
-
sort = makeMongoSortFromYml(sort)
|
|
799
|
-
limit = limit || 1000
|
|
800
|
-
|
|
801
|
-
let match_from_list = data_list.map(m=>matchPathInObject(m, match_from))
|
|
802
|
-
match_from_list = match_from_list.filter(m=>m)
|
|
803
|
-
const projection = {[match]:1}
|
|
804
|
-
|
|
805
|
-
const aggregate = [
|
|
806
|
-
{ $match: { [match]: {$in:match_from_list} } },
|
|
807
|
-
]
|
|
808
|
-
|
|
809
|
-
if(field)
|
|
810
|
-
projection[field] = 1
|
|
811
|
-
else if(fields){
|
|
812
|
-
fields.map(m=>{
|
|
813
|
-
projection[m.name] = 1
|
|
814
|
-
})
|
|
815
|
-
|
|
816
|
-
fields.map(m=>{
|
|
817
|
-
if(m.type == 'reference') {
|
|
818
|
-
let project = { _id: 0 }
|
|
819
|
-
|
|
820
|
-
if(m.field)
|
|
821
|
-
project[m.field] = 1
|
|
822
|
-
else
|
|
823
|
-
m.fields.map(f=>{
|
|
824
|
-
project[f.name] = 1
|
|
825
|
-
})
|
|
826
|
-
|
|
827
|
-
aggregate.push({ $lookup: {
|
|
828
|
-
from: m.reference_entity,
|
|
829
|
-
let: { local_key: '$'+m.reference_from },
|
|
830
|
-
pipeline: [
|
|
831
|
-
{ $match: { $expr: { $eq: ["$"+m.reference_match, "$$local_key"] } } },
|
|
832
|
-
{ $project: project }
|
|
833
|
-
],
|
|
834
|
-
as: m.name
|
|
835
|
-
} })
|
|
836
|
-
if(m.single)
|
|
837
|
-
aggregate.push({ $unwind: `$${m.name}` })
|
|
838
|
-
|
|
839
|
-
if(m.field)
|
|
840
|
-
aggregate.push({ $addFields: { [m.field]: `$${m.name}.${m.field}` } })
|
|
841
|
-
}
|
|
842
|
-
})
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
const result = await db.collection(entity)
|
|
846
|
-
.aggregate(aggregate)
|
|
847
|
-
.project(projection)
|
|
848
|
-
.toArray()
|
|
849
|
-
data_list.map(m=>{
|
|
850
|
-
let found = result.filter(f=>matchPathInObject(f, match) === matchPathInObject(m, match_from))
|
|
851
|
-
if(single) {
|
|
852
|
-
if(field)
|
|
853
|
-
m[key] = found.length > 0 ? found[0][field] : null
|
|
854
|
-
else
|
|
855
|
-
m[key] = found.length > 0 ? found[0] : null
|
|
856
|
-
} else {
|
|
857
|
-
if(field)
|
|
858
|
-
m[key] = found.map(f=>f[field])
|
|
859
|
-
else
|
|
860
|
-
m[key] = found
|
|
861
|
-
}
|
|
862
|
-
})
|
|
863
|
-
}
|
|
864
|
-
}
|
|
865
|
-
|
|
866
843
|
const generateEntityApi = async ({ app, db, entity_name, entity, yml, options }) => {
|
|
867
844
|
await generateCrud({ app, db, entity_name, yml_entity: entity, yml, options })
|
|
868
845
|
}
|