bobflux-gen
Version:
Generator for monkey files in bobflux application.
135 lines (134 loc) • 9.97 kB
JavaScript
;
var g = require("./generator");
var nameUnifier = require("./nameUnifier");
var pu = require("./pathUtils");
var pathPlatformDependent = require("path");
var path = pathPlatformDependent.posix; // This works everythere, just use forward slashes
var defaultLibFilename = path.join(path.dirname(require.resolve("typescript").replace(/\\/g, "/")), "lib.es6.d.ts");
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = function (project, tsAnalyzer, logger, rootStateKey) {
if (rootStateKey === void 0) { rootStateKey = null; }
return {
run: function () { return runBase(false, project, tsAnalyzer, logger, rootStateKey); },
runRecurse: function () { return runBase(true, project, tsAnalyzer, logger, rootStateKey); }
};
};
function runBase(applyRecurse, project, tsAnalyzer, logger, rootStateKey) {
return new Promise(function (f, r) {
var writeCallback = function (fn, c) { return project.writeFileCallback(fn, new Buffer(c, 'utf-8')); };
g.loadSourceFiles(project, tsAnalyzer, logger)
.then(function (p) {
var rootBaseDir = path.dirname(p.stateFilePath);
var relativeDir = project.relativePath ? path.join(path.dirname(p.stateFilePath), project.relativePath) : rootBaseDir;
try {
var filePath = path.join(path.dirname(p.stateFilePath), path.basename(p.stateFilePath));
try {
writeBuilders(filePath, p.data, project.appStateName, project.relativePath, writeCallback, rootStateKey);
}
catch (e) {
logger.error('Error on cursors writing.', e);
}
}
catch (e) {
logger.error('Error on cursors writing.', e);
}
function writeBuilders(stateFilePath, data, currentStateName, relativePath, writeCallback, parentStateKey) {
var mainState = g.resolveState(data.states, currentStateName);
if (!mainState)
return;
var bobfluxPrefix = g.resolveBobfluxPrefix(mainState);
var bobfluxImport = data.sourceDeps[bobfluxPrefix];
var imports = bobfluxImport ? (_a = {}, _a[bobfluxImport.fullPath] = bobfluxImport, _a) : {};
var stateAlias = g.createUnusedAlias(g.stateImportKey, data.imports);
var buildersFilePath = pu.createBuildersFilePath(rootBaseDir, relativeDir, stateFilePath).replace(/\\/g, "/");
var rootRelativePath = pu.resolveRelatioveStateFilePath(path.dirname(buildersFilePath), path.dirname(stateFilePath));
var generatedBuilders = [];
function createFieldsContent(state, prefix) {
if (prefix === void 0) { prefix = null; }
logger.info('Fields proccessing started for: ', state.typeName);
var nexts = [];
var builderName = nameUnifier.removeIfacePrefix(state.typeName) + "Builder";
var stateTypeName = stateAlias + "." + state.typeName;
if (generatedBuilders.filter(function (g) { return g === stateTypeName; }).length > 0)
return '';
generatedBuilders.push(stateTypeName);
var content = createBuilderHeader(builderName, stateTypeName, state.typeName, stateAlias);
content += state.fields.map(function (f) {
logger.info('Field proccessing started for: ', f.name);
var key = g.composeCursorKey(prefix, f.name);
var withContent = '';
f.type.forEach(function (t) {
if (applyRecurse && g.isExternalState(t.name, data)) {
var alias = g.getExternalAlias(t.name, data, imports);
var innerFilePath = path.join(path.dirname(stateFilePath), alias.relativePath + '.ts');
var innerSourceFile = g.resolveSourceFile(p.sourceFiles, innerFilePath);
if (innerSourceFile) {
var innerRelativePath = pu.resolveRelatioveStateFilePath(path.dirname(innerSourceFile.path), path.dirname(buildersFilePath) + '/').replace(/\\/g, "/");
logger.info('Called write builders for nested state: ', innerFilePath);
writeBuilders(innerFilePath, tsAnalyzer.getSourceData(innerSourceFile, p.typeChecker), alias.sourceType, innerRelativePath, writeCallback, key);
}
}
var states = data.states.filter(function (s) { return s.typeName === t.name; });
var fieldBuilder = null;
if (states.length > 1)
throw 'Two states with same name could not be parsed. It\'s compilation error.';
logger.info('Field proccessing ended for: ', f.name);
if (states.length > 0 && !t.arguments)
nexts.push({ state: states[0], prefix: key });
if (states.length > 0 && f.type.length === 1 && !t.indexer && !t.arguments) {
var builderImport = g.isExternalState(t.name, data) ? stateAlias + "Builders." : '';
withContent = createWithForFieldAndBuilder(builderName, f.name, stateAlias + "." + t.name, nameUnifier.removeIfacePrefix(t.name) + "Builder", builderImport, t.isArray);
}
});
return withContent
? withContent
: createWithForField(builderName, f.name, g.getFullType(f.type, data, stateAlias, imports));
}).join('\n');
content += createBuilderFooter(stateTypeName, bobfluxPrefix, prefix);
content += createIsBuilder(builderName, stateTypeName);
logger.info('Fields proccessing ended for: ', state.typeName);
return content + (nexts.length > 0 ? '\n' : '') + nexts.map(function (n) { return createFieldsContent(n.state, n.prefix); }).filter(function (b) { return b; }).join('\n');
}
logger.info('Generating has been started for: ', stateFilePath);
var fieldsContent = createFieldsContent(mainState, parentStateKey);
writeCallback(buildersFilePath, g.createAutogeneratedHeader(project.version)
+ g.createFullImports(stateAlias, !relativePath
? './' + data.fileName
: path.join(rootRelativePath.replace(/\\/g, "/"), data.fileName), Object.keys(imports).map(function (key) {
return relativePath && imports[key].relativePath.startsWith('.')
? Object.assign({}, imports[key], {
relativePath: path.join(rootRelativePath.replace(/\\/g, "/"), imports[key].relativePath)
})
: imports[key];
}))
+ fieldsContent);
logger.info('Generating ended for: ', stateFilePath);
var _a;
}
f();
})
.catch(function (e) { return r(e); });
});
}
function resolveRelativePath(filePath, projectRelativePath, parentRelativePath) {
if (parentRelativePath === void 0) { parentRelativePath = './'; }
var relativePath = path.join(path.dirname(filePath), projectRelativePath);
return path.relative(relativePath, path.dirname(filePath));
}
function createBuilderHeader(builderName, stateName, stateTypeName, stateAlias) {
return "export class " + builderName + " {\n protected state: " + stateName + " = " + stateAlias + ".createDefault" + nameUnifier.removeIfacePrefix(stateTypeName) + "();\n\n";
}
function createWithForFieldAndBuilder(builderName, fieldName, fieldType, fieldBuilder, fieldBuilderPrefix, isArray) {
return isArray
? " public " + nameUnifier.getStatePrefixFromKeyPrefix('with', fieldName) + "(..." + fieldName + ": (" + fieldType + " | " + fieldBuilderPrefix + fieldBuilder + ")[]): " + builderName + " {\n this.state." + fieldName + " = " + fieldName + ".map(i => " + fieldBuilderPrefix + "is" + fieldBuilder + "(i) ? i.build() : i);\n return this;\n };\n"
: " public " + nameUnifier.getStatePrefixFromKeyPrefix('with', fieldName) + "(" + fieldName + ": " + fieldType + " | " + fieldBuilder + "): " + builderName + " {\n this.state." + fieldName + " = " + fieldBuilderPrefix + "is" + fieldBuilder + "(" + fieldName + ") ? " + fieldName + ".build() : " + fieldName + ";\n return this;\n };\n";
}
function createWithForField(builderName, fieldName, fieldType) {
return " public " + nameUnifier.getStatePrefixFromKeyPrefix('with', fieldName) + "(" + fieldName + ": " + fieldType + "): " + builderName + " {\n this.state." + fieldName + " = " + fieldName + ";\n return this;\n };\n";
}
function createBuilderFooter(stateTypeName, bobfluxPrefix, rootStateKey) {
return "\n public build(): " + stateTypeName + " {\n return this.state;\n }\n\n public buildToStore(): " + stateTypeName + " {\n " + bobfluxPrefix + ".bootstrap(" + (rootStateKey ? nameUnifier.createDomString(rootStateKey, 'this.state') : 'this.state') + ");\n return this.state;\n }\n}\n";
}
function createIsBuilder(builderName, stateTypeName) {
return "\nexport function is" + builderName + "(obj: " + stateTypeName + " | " + builderName + "): obj is " + builderName + " {\n return 'build' in obj;\n}\n";
}