templates-mo
Version:
Templates is a scaffolding framework that makes code generation simple, dynamic, and reusable. Generate files, parts of your app, or whole project structures—without the repetitive copy-pasting
168 lines (167 loc) • 6.59 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable @typescript-eslint/no-explicit-any */
const template_engine_1 = __importDefault(require("./template-engine"));
const dot_1 = __importDefault(require("./dot"));
const path = __importStar(require("path"));
const fs_1 = __importDefault(require("fs"));
const errors_1 = require("../errors");
const DEFAULT_OPTS = {
force: false,
useExperimentalTemplateEngine: false,
};
/**
* Extensions that should be considered as dynamic files
*/
const DYNAMIC_EXTENTION_MATCH = /\.(dot|jst|tps|def)$/i;
/**
* File
*/
class File {
/**
* Generate a File from a FileNode
*/
static fromFileNode(fileNode, options = {}) {
var _a;
return new File(
// pathFromRoot excludes the package name
path.join(path.dirname(fileNode.pathFromRoot), fileNode.name), (_a = fs_1.default.readFileSync(fileNode.path)) === null || _a === void 0 ? void 0 : _a.toString(), options);
}
/**
* Generate a File from a FileObject
*/
static from(file, content, options = {}) {
return new File(file, content, options);
}
constructor(
/**
* Full path to the file. This value will preserve the
* `.tps`, `.def`, `.jst` or `.dot`
*
* @example "./path/to/file/index.js"
* @example "./path/to/file/index.js.dot"
*/
file,
/**
* File contents
*/
contents, options = {}) {
this.file = file;
this.contents = contents;
/**
* File should be processed as a dynamic file
*/
this.isDynamic = false;
const { dir, base } = path.parse(file);
this.isDynamic = DYNAMIC_EXTENTION_MATCH.test(base);
this.location = dir;
this.name = this.isDynamic
? base.replace(DYNAMIC_EXTENTION_MATCH, '').trim()
: base;
this.options = Object.assign(Object.assign({}, DEFAULT_OPTS), options);
this.engine = this.options.useExperimentalTemplateEngine
? template_engine_1.default
: dot_1.default;
}
/**
* Get the final result of the file name for this file. If the name has any
*
* @param data - Meta data to pass to the template engine
* @param defs - defs to send to the temnplate engine
*/
fileName(data = {}, defs = {}) {
try {
return this.engine.template(this.name, null, defs)(data);
}
catch (e) {
console.log('file name error', e);
}
}
/**
* Get the file contents for this file. If file is a dynamic file then
* this will be the final result after the template engine process it.
*
* @param location - directory to render this file into
* @param data - Meta data to pass to the template engine
* @param defs - defs to send to the temnplate engine
*/
getContents(location_1) {
return __awaiter(this, arguments, void 0, function* (location, data = {}, defs = {}) {
const realData = Object.assign(Object.assign({}, data), { file: this.fileName(data, defs), dest: this.dest(location, data, defs) });
try {
return this.isDynamic
? // How could we cache this here :thinking: this is happening for every dot file
this.engine.template(this.contents, null, defs)(realData)
: this.contents;
}
catch (e) {
throw new errors_1.DotError(this.name, this.file, e.message);
}
});
}
/**
* Render this file to a specific location
*
* @param location - directory to render this file into
* @param data - Meta data to pass to the template engine
* @param defs - defs to send to the temnplate engine
*/
render(location, data, defs) {
return __awaiter(this, void 0, void 0, function* () {
const dest = this.dest(location, data, defs);
const flag = this.options.force ? 'w' : 'wx';
const contents = yield this.getContents(location, data, defs);
yield fs_1.default.promises.writeFile(dest, contents, { flag });
return dest;
});
}
_buildParentDir(newDest) {
return path.join(newDest, this.location);
}
/**
* Full destination to render this file to.
*
* @param location - directory to render this file into
* @param data - Meta data to pass to the template engine
* @param defs - defs to send to the temnplate engine
*/
dest(location, data, defs) {
return path.join(this._buildParentDir(location), this.fileName(data, defs));
}
}
exports.default = File;