molstar
Version:
A comprehensive macromolecular library.
178 lines (175 loc) • 6.58 kB
JavaScript
/**
* Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.generate = generate;
const string_1 = require("../../../mol-util/string");
const schema_1 = require("../../../mol-io/reader/cif/schema");
function header(name, info, moldataImportPath) {
return `/**
* Copyright (c) 2017-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* Code-generated '${name}' schema file. ${info}
*
* @author molstar/ciftools package
*/
import { Database, Column } from '${moldataImportPath}/db';
import Schema = Column.Schema;`;
}
function footer(name) {
return `
export type ${name}_Schema = typeof ${name}_Schema;
export interface ${name}_Database extends Database<${name}_Schema> {};`;
}
function getTypeShorthands(schema, fields) {
const types = new Set();
Object.keys(schema.tables).forEach(table => {
if (fields && !fields[table])
return;
const { columns } = schema.tables[table];
Object.keys(columns).forEach(columnName => {
if (fields && !fields[table][columnName])
return;
const col = schema.tables[table].columns[columnName];
if (col.type === 'enum')
types.add(col.subType);
types.add(col.type);
});
});
const shorthands = [];
types.forEach(type => {
switch (type) {
case 'str':
shorthands.push('const str = Schema.str;');
break;
case 'ustr':
shorthands.push('const ustr = Schema.ustr;');
break;
case 'lstr':
shorthands.push('const lstr = Schema.lstr;');
break;
case 'int':
shorthands.push('const int = Schema.int;');
break;
case 'float':
shorthands.push('const float = Schema.float;');
break;
case 'coord':
shorthands.push('const coord = Schema.coord;');
break;
case 'enum':
shorthands.push('const Aliased = Schema.Aliased;');
break;
case 'matrix':
shorthands.push('const Matrix = Schema.Matrix;');
break;
case 'vector':
shorthands.push('const Vector = Schema.Vector;');
break;
case 'list':
shorthands.push('const List = Schema.List;');
break;
}
});
return shorthands.join('\n');
}
function getTypeDef(c) {
switch (c.type) {
case 'str': return 'str';
case 'int': return 'int';
case 'float': return 'float';
case 'coord': return 'coord';
case 'enum':
return `Aliased<'${c.values.map(v => v.replace(/'/g, '\\\'')).join(`' | '`)}'>(${c.subType})`;
case 'matrix':
return `Matrix(${c.rows}, ${c.columns})`;
case 'vector':
return `Vector(${c.length})`;
case 'list':
if (c.subType === 'int') {
return `List('${c.separator}', x => parseInt(x, 10))`;
}
else if (c.subType === 'float' || c.subType === 'coord') {
return `List('${c.separator}', x => parseFloat(x))`;
}
else {
return `List('${c.separator}', x => x)`;
}
}
}
const reSafePropertyName = /^[a-zA-Z_$][0-9a-zA-Z_$]*$/;
function safePropertyString(name) { return name.match(reSafePropertyName) ? name : `'${name}'`; }
function doc(description, spacesCount) {
const spaces = ' '.repeat(spacesCount);
return [
`${spaces}/**`,
`${(0, string_1.indentString)(description, 1, `${spaces} * `)}`.replace(/ +\n/g, '\n'),
`${spaces} */`
].join('\n');
}
function generate(name, info, schema, fields, moldataImportPath, addAliases) {
const codeLines = [];
if (fields) {
Object.keys(fields).forEach(table => {
if (table in schema.tables) {
const schemaTable = schema.tables[table];
Object.keys(fields[table]).forEach(column => {
if (!(column in schemaTable.columns)) {
console.log(`filter field '${table}.${column}' not found in schema`);
}
});
}
else {
console.log(`filter category '${table}' not found in schema`);
}
});
}
codeLines.push(`export const ${name}_Schema = {`);
Object.keys(schema.tables).forEach(table => {
if (fields && !fields[table])
return;
const { description, columns } = schema.tables[table];
if (description)
codeLines.push(doc(description, 4));
codeLines.push(` ${safePropertyString(table)}: {`);
Object.keys(columns).forEach(columnName => {
if (fields && !fields[table][columnName])
return;
const c = columns[columnName];
const typeDef = getTypeDef(c);
if (c.description)
codeLines.push(doc(c.description, 8));
codeLines.push(` ${safePropertyString(columnName)}: ${typeDef},`);
});
codeLines.push(' },');
});
codeLines.push('};');
if (addAliases) {
codeLines.push('');
codeLines.push(`export const ${name}_Aliases = {`);
Object.keys(schema.aliases).forEach(path => {
const [table, columnName] = path.split('.');
if (fields && !fields[table])
return;
if (fields && !fields[table][columnName])
return;
const filteredAliases = new Set();
schema.aliases[path].forEach(p => {
if (!schema_1.FieldPath.equal(p, path))
filteredAliases.add(schema_1.FieldPath.canonical(p));
});
if (filteredAliases.size === 0)
return;
codeLines.push(` ${safePropertyString(path)}: [`);
filteredAliases.forEach(alias => {
codeLines.push(` '${alias}',`);
});
codeLines.push(' ],');
});
codeLines.push('};');
}
return `${header(name, info, moldataImportPath)}\n\n${getTypeShorthands(schema, fields)}\n\n${codeLines.join('\n')}\n${footer(name)}`;
}
;