|
@@ -1,6 +1,6 @@
|
|
|
|
|
|
// import dic from './dic'
|
|
|
-import { Field, Category } from '../schema'
|
|
|
+import { Field, Block, Category } from '../schema'
|
|
|
import * as Data from '../data-model'
|
|
|
|
|
|
const pooledStr = Field.pooledStr()
|
|
@@ -8,7 +8,7 @@ const str = Field.str()
|
|
|
const int = Field.int()
|
|
|
const float = Field.float()
|
|
|
|
|
|
-function getFieldType (type: string) {
|
|
|
+export function getFieldType (type: string) {
|
|
|
switch (type) {
|
|
|
case 'code':
|
|
|
case 'ucode':
|
|
@@ -63,38 +63,102 @@ function getFieldType (type: string) {
|
|
|
return str
|
|
|
}
|
|
|
|
|
|
+type SafeFrameCategories = { [category: string]: Data.SafeFrame }
|
|
|
+type SafeFrameLinks = { [k: string]: string }
|
|
|
+
|
|
|
+interface SafeFrameData {
|
|
|
+ categories: SafeFrameCategories
|
|
|
+ links: SafeFrameLinks
|
|
|
+}
|
|
|
+
|
|
|
+// get field from given or linked category
|
|
|
+function getField ( category: string, field: string, d: Data.SafeFrame, ctx: SafeFrameData): Data.Field|undefined {
|
|
|
+ const { categories, links } = ctx
|
|
|
+
|
|
|
+ const cat = d.categories[category]
|
|
|
+ if (cat) {
|
|
|
+ return cat.getField(field)
|
|
|
+ } else {
|
|
|
+ if (d.header in links) {
|
|
|
+ return getField(category, field, categories[links[d.header]], ctx)
|
|
|
+ } else {
|
|
|
+ // console.log(`no links found for '${d.header}'`)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// function getEnums (d: Data.SafeFrame, ctx: SafeFrameData): string[]|undefined {
|
|
|
+// const value = getField('_item_enumeration', 'value', d, ctx)
|
|
|
+// if (value) {
|
|
|
+// const enums: string[] = []
|
|
|
+// for (let i = 0; i < value.rowCount; ++i) {
|
|
|
+// enums.push(value.str(i))
|
|
|
+// // console.log(value.str(i))
|
|
|
+// }
|
|
|
+// return enums
|
|
|
+// } else {
|
|
|
+// // console.log(`item_enumeration.value not found for '${d.header}'`)
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+function getCode (d: Data.SafeFrame, ctx: SafeFrameData): string|undefined {
|
|
|
+ const code = getField('_item_type', 'code', d, ctx)
|
|
|
+ if (code) {
|
|
|
+ let c = code.str(0)
|
|
|
+ // if (c === 'ucode') {
|
|
|
+ // const enums = getEnums(d, ctx)
|
|
|
+ // if (enums) c += `: ${enums.join('|')}`
|
|
|
+ // }
|
|
|
+ return c
|
|
|
+ } else {
|
|
|
+ console.log(`item_type.code not found for '${d.header}'`)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
export function getSchema (dic: Data.Block) { // todo Block needs to be specialized with safe frames as well
|
|
|
- const schema: { [category: string]: Category.Schema } = {}
|
|
|
+ const schema: Block.Schema = {} // { [category: string]: Category.Schema } = {}
|
|
|
|
|
|
+ const categories: SafeFrameCategories = {}
|
|
|
+ const links: SafeFrameLinks = {}
|
|
|
dic.saveFrames.forEach(d => {
|
|
|
- if (d.header[0] !== '_') {
|
|
|
- schema[d.header] = {}
|
|
|
- } else {
|
|
|
- const categoryName = d.header.substring(1, d.header.indexOf('.'))
|
|
|
- const itemName = d.header.substring(d.header.indexOf('.') + 1)
|
|
|
- let fields
|
|
|
- if (categoryName in schema) {
|
|
|
- fields = schema[categoryName]
|
|
|
- } else {
|
|
|
- fields = {}
|
|
|
- schema[categoryName] = fields
|
|
|
- }
|
|
|
- // console.log(util.inspect(d.categories, {showHidden: false, depth: 1}))
|
|
|
- const item_type = d.categories['_item_type']
|
|
|
- if (item_type) {
|
|
|
- const code = item_type.getField('code')
|
|
|
- if (code) {
|
|
|
- fields[itemName] = getFieldType(code.str(0))
|
|
|
- } else {
|
|
|
- console.log(`item_type.code not found for '${d.header}'`)
|
|
|
+ if (d.header[0] !== '_') return
|
|
|
+ categories[d.header] = d
|
|
|
+ const item_linked = d.categories['_item_linked']
|
|
|
+ if (item_linked) {
|
|
|
+ const child_name = item_linked.getField('child_name')
|
|
|
+ const parent_name = item_linked.getField('parent_name')
|
|
|
+ if (child_name && parent_name) {
|
|
|
+ for (let i = 0; i < item_linked.rowCount; ++i) {
|
|
|
+ const childName = child_name.str(i)
|
|
|
+ const parentName = parent_name.str(i)
|
|
|
+ if (childName in links && links[childName] !== parentName) {
|
|
|
+ console.log(`${childName} linked to ${links[childName]}, ignoring link to ${parentName}`)
|
|
|
+ }
|
|
|
+ links[childName] = parentName
|
|
|
}
|
|
|
- } else {
|
|
|
- // TODO check for _item_linked.parent_name and use its type
|
|
|
- console.log(`item_type not found for '${d.header}'`)
|
|
|
}
|
|
|
+ }
|
|
|
+ })
|
|
|
|
|
|
+ Object.keys(categories).forEach(fullName => {
|
|
|
+ const d = categories[fullName]
|
|
|
+ const categoryName = d.header.substring(1, d.header.indexOf('.'))
|
|
|
+ const itemName = d.header.substring(d.header.indexOf('.') + 1)
|
|
|
+ let fields
|
|
|
+ if (categoryName in schema) {
|
|
|
+ fields = schema[categoryName]
|
|
|
+ } else {
|
|
|
+ fields = {}
|
|
|
+ schema[categoryName] = fields
|
|
|
+ }
|
|
|
+
|
|
|
+ const code = getCode(d, { categories, links })
|
|
|
+ if (code) {
|
|
|
+ fields[itemName] = getFieldType(code)
|
|
|
+ } else {
|
|
|
+ console.log(`could not determine code for '${d.header}'`)
|
|
|
}
|
|
|
})
|
|
|
|
|
|
- return schema
|
|
|
+ return schema as Block.Instance<any>
|
|
|
}
|