UNPKG

@stackpress/idea-parser

Version:

Parses ideas to AST and readable JSON.

209 lines (208 loc) 8.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Exception_js_1 = __importDefault(require("./Exception.js")); class Compiler { static array(token, references = false) { return token.elements.map(element => this.data(element, references)); } static data(token, references = false) { if (token.type === 'ObjectExpression') { return this.object(token, references); } else if (token.type === 'ArrayExpression') { return this.array(token, references); } else if (token.type === 'Literal') { return this.literal(token); } else if (token.type === 'Identifier') { return this.identifier(token, references); } throw Exception_js_1.default.for('Invalid data token type'); } static enum(token) { var _a, _b; if (token.kind !== 'enum') { throw Exception_js_1.default.for('Invalid Enum'); } const name = (_b = (_a = token.declarations) === null || _a === void 0 ? void 0 : _a[0].id) === null || _b === void 0 ? void 0 : _b.name; const options = {}; token.declarations[0].init.properties.forEach(property => { options[property.key.name] = property.value.value; }); return [name, options]; } static final(token) { const schema = this.schema(token, true); delete schema.use; delete schema.prop; return schema; } static identifier(token, references = false) { if (references && token.name in references) { return references[token.name]; } else if (references === false) { return '${' + token.name + '}'; } throw Exception_js_1.default.for(`Unknown reference ${token.name}`); } static literal(token) { return token.value; } static model(token, references = false) { var _a; const name = (_a = token.declarations[0].id) === null || _a === void 0 ? void 0 : _a.name; const mutable = token.mutable !== false; const value = {}; token.declarations[0].init.properties.forEach(property => { value[property.key.name] = this.data(property.value, references); }); if (typeof value.columns !== 'object') { throw Exception_js_1.default.for('Expecting a columns property'); } const columns = []; for (const name in value.columns) { const column = value.columns[name]; column.name = name; if (typeof column.type === 'string') { column.required = !column.type.endsWith('?'); column.type = column.type.replace(/\?$/, ''); column.multiple = column.type.endsWith('[]'); column.type = column.type.replace(/\[\]$/, ''); } columns.push(Object.assign({ type: column.type, name: column.name, required: column.required, multiple: column.multiple, attributes: column.attributes }, column)); } value.columns = columns; return [name, Object.assign({ name, mutable }, value)]; } static object(token, references = false) { return Object.fromEntries(token.properties.map(property => [ property.key.name, this.data(property.value, references) ])); } static plugin(token) { var _a, _b; if (token.kind !== 'plugin') { throw Exception_js_1.default.for('Invalid Plugin'); } const name = (_b = (_a = token.declarations) === null || _a === void 0 ? void 0 : _a[0].id) === null || _b === void 0 ? void 0 : _b.name; const value = {}; token.declarations[0].init.properties.forEach(property => { value[property.key.name] = this.data(property.value); }); return [name, value]; } static prop(token, references = false) { if (token.kind !== 'prop') { throw Exception_js_1.default.for('Invalid Prop'); } const name = token.declarations[0].id.name; const value = {}; token.declarations[0].init.properties.forEach(property => { value[property.key.name] = this.data(property.value, references); }); return [name, value]; } static schema(token, finalize = false) { if (token.kind !== 'schema') { throw Exception_js_1.default.for('Invalid Schema'); } const schema = {}; const references = {}; const uses = token.body.filter(token => token.type === 'ImportDeclaration'); uses.forEach(use => { schema.use = schema.use || []; schema.use.push(this.use(use)); }); const declarations = token.body; declarations.filter(declaration => declaration.kind).forEach(declaration => { if (declaration.kind === 'enum') { schema.enum = schema.enum || {}; const [key, value] = this.enum(declaration); schema.enum[key] = value; if (references[key]) { throw Exception_js_1.default.for('Duplicate %s', key); } references[key] = value; } else if (declaration.kind === 'prop') { schema.prop = schema.prop || {}; const [key, value] = this.prop(declaration, finalize ? references : false); schema.prop[key] = value; if (references[key]) { throw Exception_js_1.default.for('Duplicate %s', key); } references[key] = value; } else if (declaration.kind === 'type') { schema.type = schema.type || {}; const [key, value] = this.type(declaration, finalize ? references : false); schema.type[key] = value; if (references[key]) { throw Exception_js_1.default.for('Duplicate %s', key); } references[key] = value; } else if (declaration.kind === 'model') { schema.model = schema.model || {}; const [key, value] = this.model(declaration, finalize ? references : false); schema.model[key] = value; if (references[key]) { throw Exception_js_1.default.for('Duplicate %s', key); } references[key] = value; } else if (declaration.kind === 'plugin') { schema.plugin = schema.plugin || {}; const [key, value] = this.plugin(declaration); schema.plugin[key] = value; if (references[key]) { throw Exception_js_1.default.for('Duplicate %s', key); } references[key] = value; } }); return schema; } static type(token, references = false) { if (token.kind !== 'type') { throw Exception_js_1.default.for('Invalid Type'); } const name = token.declarations[0].id.name; const mutable = token.mutable !== false; const value = {}; token.declarations[0].init.properties.forEach(property => { value[property.key.name] = this.data(property.value, references); }); if (typeof value.columns !== 'object') { throw Exception_js_1.default.for('Expecting a columns property'); } const columns = []; for (const name in value.columns) { const column = value.columns[name]; column.name = name; if (typeof column.type === 'string') { column.required = !column.type.endsWith('?'); column.type = column.type.replace(/\?$/, ''); column.multiple = column.type.endsWith('[]'); column.type = column.type.replace(/\[\]$/, ''); } columns.push(Object.assign({ type: column.type, name: column.name, required: column.required, multiple: column.multiple, attributes: column.attributes }, column)); } value.columns = columns; return [name, Object.assign({ name, mutable }, value)]; } static use(token) { if (token.type !== 'ImportDeclaration') { throw Exception_js_1.default.for('Invalid Import'); } return token.source.value; } } exports.default = Compiler; ;