firebase-bolt-compiler
Version:
Compiles Firebase Bolt files to TypeScript, Flow, & more
124 lines • 4.11 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
class TypeScriptGenerator {
constructor(schemas, paths) {
this.atomicTypes = {
Any: "any",
Boolean: "boolean",
Number: "number",
Null: "void",
Object: "Object",
String: "string"
};
this.schemas = schemas;
this.paths = paths;
_.forEach(schemas, (schema, name) => {
const type = schema.derivedFrom;
if (type.name && this.derivesFromAtomic(type)) {
this.atomicTypes[name] = this.serializeTypeName(type.name);
}
});
}
generate() {
// const paths = this.paths.map(path => this.serializePath(path)).join("\n\n") + "\n\n";
const types = _.map(this.schemas, (schema, name) => this.serializeSchema(name, schema))
.join("\n\n")
.trim();
// return paths + types;
return types;
}
serializePath(path) {
const methodName = _.camelCase(`get ${path.template.parts[0].label}`);
const params = path.template.parts
.map(part => part.variable ? `${part.variable}: string` : "")
.filter(part => part !== "")
.join(", ");
return `export function ${methodName}(${params}) {
return \`${path.template.parts.map(p => p.variable ? `\${${p.variable}}` : p.label).join("/")}\`;
}`;
}
serializeTypeName(name) {
return this.atomicTypes[name] || name;
}
/* tslint:disable:no-use-before-declare */
serialize(type) {
if (type.params) {
return this.serializeGenericType(type);
}
else if (type.types) {
return this.serializeUnionType(type);
}
else {
return this.serializeSimpleType(type);
}
}
/* tslint:enable:no-use-before-declare */
serializeSimpleType(type) {
return this.serializeTypeName(type.name);
}
serializeUnionType(type) {
return type.types.map(t => this.serialize(t)).filter(t => t !== "void").join(" | ");
}
serializeGenericType(type) {
return type.name === "Map"
?
`{ [key: string]: ${this.serialize(type.params[1])} }`
:
this.serializeGenericTypeRef(type);
}
serializeGenericTypeRef(type) {
const typeName = this.serializeTypeName(type.name);
const params = type.params.map(param => this.serialize(param)).join(", ");
return `${typeName}<${params}>`;
}
serializeRef(type) {
if (type.params) {
return this.serializeGenericTypeRef(type);
}
else if (type.types) {
throw new Error();
}
else {
return type.name;
}
}
derivesFromMap(type) {
return type.name === "Map";
}
derivesFromAtomic(type) {
return this.atomicTypes[type.name] !== undefined && type.name !== "Object";
}
derives(schema) {
const type = this.serializeRef(schema.derivedFrom);
if (type !== "Object") {
return `extends ${type} `;
}
else {
return ``;
}
}
isNullable(type) {
const union = type;
if (union.types) {
const isNullable = _.some(union.types, (t) => t.name === "Null");
return isNullable ? "?" : "";
}
return "";
}
serializeSchema(name, schema) {
if (this.derivesFromMap(schema.derivedFrom)) {
return `export type ${name} = ${this.serializeGenericType(schema.derivedFrom)};`;
}
else if (!this.derivesFromAtomic(schema.derivedFrom)) {
return `export interface ${name} ${this.derives(schema)}{
${_.map(schema.properties, (prop, propName) => ` ${propName}${this.isNullable(prop)}: ${this.serialize(prop)};`).join("\n")}
}`;
}
else {
return "";
}
}
}
exports.default = TypeScriptGenerator;
//# sourceMappingURL=TypeScriptGenerator.js.map