@vulcan-sql/extension-dbt
Version:
Using dbt models form VulcanSQL projects
59 lines • 2.76 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DBTTagBuilder = void 0;
const tslib_1 = require("tslib");
const core_1 = require("@vulcan-sql/core");
const fs_1 = require("fs");
const lodash_1 = require("lodash");
class DBTTagBuilder extends core_1.TagBuilder {
constructor() {
super(...arguments);
this.tags = ['dbt'];
this.models = new Map();
}
onActivate() {
var _a;
return tslib_1.__awaiter(this, void 0, void 0, function* () {
this.models.clear();
const modelFiles = ((_a = this.getConfig()) === null || _a === void 0 ? void 0 : _a.modelFiles) || [];
for (const modelFile of modelFiles) {
const content = JSON.parse(yield fs_1.promises.readFile(modelFile, 'utf-8'));
(0, lodash_1.chain)(content.nodes || [])
.toPairs()
.filter((node) => node[0].startsWith('model'))
.forEach((node) => this.loadModel(node[0], node[1]))
.value();
}
});
}
parse(parser, nodes, lexer) {
// {% dbt "model-name" %}
// consume dbt tag
const dbtToken = parser.nextToken();
const args = new nodes.NodeList(dbtToken.lineno, dbtToken.colno);
const modelNameToken = parser.nextToken();
if (modelNameToken.type !== lexer.TOKEN_STRING) {
parser.fail(`Expect model name as string, but got ${modelNameToken.type}`, modelNameToken.lineno, modelNameToken.colno);
}
const end = parser.nextToken();
if (end.type !== lexer.TOKEN_BLOCK_END) {
parser.fail(`Expect block end %}, but got ${end.type}`, end.lineno, end.colno);
}
const sql = this.models.get(modelNameToken.value);
if (!sql) {
parser.fail(`Model ${modelNameToken.value} is not found in modelFiles`, modelNameToken.lineno, modelNameToken.colno);
}
const output = new nodes.Output(dbtToken.lineno, dbtToken.colno);
output.addChild(new nodes.TemplateData(dbtToken.lineno, dbtToken.colno, sql));
return this.createAsyncExtensionNode(args, [output]);
}
loadModel(name, node) {
if (this.models.has(name))
throw Error(`Model name ${name} is unambiguous`);
// If the materialization of a table is view, table, or incremental, the "relation_name" property indicates the table name created by dbt.
// If it is an ephemeral model, the "relation_name" property is null, we should use compiled sql instead.
this.models.set(name, node.relation_name || `(${node.compiled_sql})`);
}
}
exports.DBTTagBuilder = DBTTagBuilder;
//# sourceMappingURL=dbtTagBuilder.js.map