bobflux-gen
Version:
Generator for monkey files in bobflux application.
136 lines (135 loc) • 8.57 kB
JavaScript
;
var g = require("./generator");
var nameUnifier = require("./nameUnifier");
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) {
var writeCallback = function (fn, c) { project.writeFileCallback(fn, new Buffer(c, 'utf-8')); };
function writeCursors(params, currentStateName, rootStateKey) {
var stateFilePath = params.stateFilePath;
var mainState = g.resolveState(params.data.states, currentStateName);
if (!mainState)
return;
var stateAlias = g.createUnusedAlias(g.stateImportKey, params.data.imports);
var bobfluxPrefix = g.resolveBobfluxPrefix(mainState);
logger.info('Generating has been started for: ', stateFilePath);
var bobfluxImport = params.data.sourceDeps[bobfluxPrefix];
var imports = bobfluxImport ? (_a = {}, _a[bobfluxImport.fullPath] = bobfluxImport, _a) : {};
var stateFieldCursors = createCursorsForStateFields(params, imports, rootStateKey, params.data, mainState, bobfluxPrefix, stateAlias);
writeCallback(createCursorsFilePath(stateFilePath), g.createAutogeneratedHeader(project.version)
+ g.createFullImports(stateAlias, "./" + params.data.fileName, Object.keys(imports).map(function (key) { return repairRelativePath(imports[key], stateFilePath); }))
+ createRootKey(rootStateKey, bobfluxPrefix)
+ createRootCursor(rootStateKey, bobfluxPrefix, stateAlias, mainState.typeName)
+ stateFieldCursors);
logger.info('Generating ended for: ', stateFilePath);
var _a;
}
function createCursorsForStateFields(params, topLevelImports, parentStateKey, data, state, bobfluxPrefix, stateAlias, prefix) {
if (prefix === void 0) { prefix = null; }
var nexts = [];
function queue(p) {
nexts.push(p);
p.state.heritages.forEach(function (heritageName) {
var heritage = p.data.states.find(function (s) { return s.typeName === heritageName; });
// cross-file heritage is not implemented yet
if (heritage)
nexts.push(Object.assign({}, p, { state: heritage }));
});
}
var inner = state.fields.map(function (f) {
var key = parentStateKey === null ? g.composeCursorKey(parentStateKey, prefix, f.name) : g.composeCursorKey(prefix, f.name);
if (applyRecurse) {
f.type.forEach(function (t) {
if (t.isArray || !g.isExternalState(t.name, data))
return;
var alias = g.getExternalAlias(t.name, data, topLevelImports);
var innerFilePath = path.join(path.dirname(data.filePath), alias.relativePath + '.ts');
var innerSourceFile = g.resolveSourceFile(params.sourceFiles, innerFilePath);
if (innerSourceFile) {
var innerData = tsAnalyzer.getSourceData(innerSourceFile, params.typeChecker);
var innerResolvedState = g.resolveState(innerData.states, alias.sourceType);
if (innerResolvedState)
if (g.isRouteComponentState.apply(g, innerResolvedState.heritages) && f.type.length === 1)
writeCursors({
stateFilePath: innerSourceFile.path,
data: tsAnalyzer.getSourceData(innerSourceFile, params.typeChecker),
sourceFiles: params.sourceFiles,
typeChecker: params.typeChecker
}, alias.sourceType, g.composeCursorKey(parentStateKey, key));
else
queue({ state: innerResolvedState, data: innerData, externalFileAlias: alias.prefix, prefix: key });
}
});
}
var fieldType = g.getFullType(f.type, data, stateAlias, topLevelImports);
f.type.forEach(function (t) {
if (t.isArray)
return;
var states = data.states.filter(function (s) { return s.typeName === t.name; });
if (states.length > 0 && !t.arguments /* not implemented yet*/)
queue({ state: states[0], data: data, externalFileAlias: stateAlias, prefix: key });
if (states.length > 1)
throw 'Two states with same name could not be parsed. It\'s compilation error.';
});
// if (f.type.map(t => t.name).indexOf('undefined') >= 0)
// return '';
return createFieldCursor(prefix, key, f.name, bobfluxPrefix, fieldType, parentStateKey !== null, f);
}).join('\n');
return inner + (nexts.length > 0 ? '\n' : '') + nexts.map(function (n) { return createCursorsForStateFields(params, topLevelImports, parentStateKey, n.data, n.state, bobfluxPrefix, n.externalFileAlias, n.prefix); }).filter(function (n) { return n; }).join('\n');
}
return new Promise(function (f, r) {
g.loadSourceFiles(project, tsAnalyzer, logger)
.then(function (p) {
try {
writeCursors(p, project.appStateName, rootStateKey);
}
catch (e) {
logger.error('Error on cursors writing.', e);
}
f();
})
.catch(function (e) { return r(e); });
});
}
function createRootKey(key, bobfluxPrefix) {
return "export const rootKey = " + (key ? "'" + key + "'" : bobfluxPrefix + ".rootCursor.key") + ";\n\n";
}
function createFieldCursor(prefix, key, fieldName, bobfluxPrefix, typeName, withRoot, f) {
var undefinedDef = f.type.some(function (t) { return t.name === 'undefined'; }) ? ",\n isUndefinable: true" : '';
return "export const " + (prefix === null ? fieldName : nameUnifier.getStatePrefixFromKeyPrefix(prefix, fieldName)) + "Cursor: " + bobfluxPrefix + ".ICursor<" + typeName + "> = {\n key: " + (withRoot ? "rootKey + '." + key + "'" : "'" + key + "'") + undefinedDef + "\n};\n";
}
function createArrayIndexFactoryCursor(prefix, key, fieldName, bobfluxPrefix, typeName, withRoot) {
return "\nexport const " + (prefix === null ? fieldName : nameUnifier.getStatePrefixFromKeyPrefix(prefix, fieldName)) + "IndexFactoryCursor: (index: number) => " + bobfluxPrefix + ".IIndexCursorReslut = (index: number) => {\n return {\n cursor: <" + bobfluxPrefix + ".ICursor<" + typeName + ">>{ key: " + (withRoot ? "rootKey + '." + key + ".'" : "'" + key + ".'") + " + index }\n };\n};\n";
}
function createRootCursor(key, bobfluxPrefix, stateAlias, typeName) {
return (key
? "export const rootCursor: " + bobfluxPrefix + ".ICursor<" + stateAlias + "." + typeName + "> = {\n key: rootKey\n};\n"
: "export const rootCursor: " + bobfluxPrefix + ".ICursor<" + stateAlias + "." + typeName + "> = " + bobfluxPrefix + ".rootCursor;\n") + "\nexport default rootCursor;\n\n";
}
function createCursorsFilePath(stateFilePath) {
return path.join(path.dirname(stateFilePath), path.basename(stateFilePath).replace(path.extname(stateFilePath), '')) + ".cursors.ts";
}
exports.createCursorsFilePath = createCursorsFilePath;
function repairRelativePath(imp, stateFilePath) {
if (!imp.relativePath.startsWith('.'))
return imp;
var dir = path.dirname(stateFilePath);
if (!path.isAbsolute(dir))
dir = path.join(process.cwd(), dir);
var fullPath = imp.fullPath;
if (!path.isAbsolute(fullPath))
fullPath = path.join(process.cwd(), fullPath);
var relativePath = path.relative(dir, fullPath);
if (!relativePath.startsWith('.'))
relativePath = "." + path.sep + relativePath;
return Object.assign({}, imp, { relativePath: relativePath });
}