@stackpress/idea-parser
Version:
Parses ideas to AST and readable JSON.
209 lines (208 loc) • 8.7 kB
JavaScript
;
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;
;