@udraft/core
Version:
uDraft is a language and stack agnostic code-generation tool that simplifies full-stack development by converting a single YAML file into code for rapid development.
268 lines • 13 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 () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const Case = __importStar(require("case"));
const path = __importStar(require("path"));
const renderer_1 = require("../entities/renderer");
const queries_1 = require("../shortcuts/queries");
const attributes_1 = require("../shortcuts/attributes");
class DartClassRenderer extends renderer_1.URenderer {
constructor(options) {
super("dart@classes");
this._modelDir = "lib/models";
this._dtoDir = "lib/dtos";
this._enumDir = "lib/enums";
this._includeModuleInDir = true;
if (options === null || options === void 0 ? void 0 : options.modelDir)
this._modelDir = options.modelDir;
if (options === null || options === void 0 ? void 0 : options.dtoDir)
this._dtoDir = options.dtoDir;
if (options === null || options === void 0 ? void 0 : options.enumDir)
this._enumDir = options.enumDir;
if ((options === null || options === void 0 ? void 0 : options.includeModuleInDir) !== undefined)
this._includeModuleInDir = options.includeModuleInDir;
this._where = options === null || options === void 0 ? void 0 : options.where;
}
$isDto(model) {
var _a, _b;
const output = this.$output(model.$name());
return (_b = (_a = output === null || output === void 0 ? void 0 : output.meta) === null || _a === void 0 ? void 0 : _a.isDto) !== null && _b !== void 0 ? _b : false;
}
$resolveImport(from, model) {
const modelPath = this.$path(this.$className(model));
if (!(modelPath === null || modelPath === void 0 ? void 0 : modelPath.path))
return "";
const fromDir = path.dirname(from);
const toDir = path.dirname(modelPath.path);
const relativePath = path.relative(fromDir, toDir);
const fileName = this.$fileName(model, false);
const importPath = path.join(relativePath, fileName);
const normalizedPath = importPath.split(path.sep).join("/");
return `import '${normalizedPath}.dart';\n`;
}
$key(model) {
return this.$className(model);
}
$className(model) {
return Case.pascal(model.$name());
}
$fileName(model, extension = true) {
return `${Case.snake(model.$name())}${extension ? ".dart" : ""}`;
}
$fieldName(field) {
const nameParts = field.$name().match(/([^A-Za-z]+)(.+)/);
return nameParts
? nameParts[1] + Case.camel(nameParts[2])
: Case.camel(field.$name());
}
$fieldType(field) {
let type;
switch (field.$type()) {
case "date":
type = "DateTime";
break;
case "reference":
case "string":
type = "String";
break;
case "int":
type = "int";
break;
case "float":
type = "double";
break;
case "boolean":
type = "bool";
break;
case "nested": {
const nestedModel = (0, queries_1.$attr)(field, (0, attributes_1._ref)());
type = nestedModel ? this.$className(nestedModel) : "dynamic";
break;
}
default:
type = field.$type().toString();
}
if ((0, queries_1.$attr)(field, (0, attributes_1._array)())) {
type = `List<${type}>`;
}
if (!(0, queries_1.$attr)(field, (0, attributes_1._required)())) {
type += "?";
}
return type;
}
toDartValue(value) {
if (typeof value === "string")
return `'${value.replace(/'/g, "\\'")}'`;
if (typeof value === "number")
return value.toString();
if (typeof value === "boolean")
return value ? "true" : "false";
return JSON.stringify(value);
}
select() {
return __awaiter(this, void 0, void 0, function* () {
const models = this.$models(this._where);
const paths = [];
models.forEach((model) => {
if (paths.some((p) => p.key === this.$key(model)))
return;
const mod = (0, queries_1.$attr)(model, (0, attributes_1._rootModule)());
const isDto = !!model.$name().match(/dto$/i);
const isEnum = !!(0, queries_1.$attr)(model, (0, attributes_1._enum)());
paths.push({
key: this.$key(model),
meta: { isDto, isEnum },
path: path.join(isDto ? this._dtoDir : isEnum ? this._enumDir : this._modelDir, this._includeModuleInDir ? Case.kebab(mod ? mod.$name() : "") : "", this.$fileName(model)),
});
});
return {
paths,
models,
};
});
}
render() {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const output = [];
const models = this.$selection().models || [];
for (const model of models) {
const modelKey = this.$key(model);
const modelPath = this.$path(modelKey);
if (!modelPath)
continue;
let content = "";
const className = this.$className(model);
const enumDefinition = (0, queries_1.$attr)(model, (0, attributes_1._enum)());
if (enumDefinition) {
const entries = Object.keys(enumDefinition).map((key) => {
const entryName = Case.camel(key);
const value = enumDefinition[key];
return `${entryName}(${this.toDartValue(value)})`;
});
const firstValue = Object.values(enumDefinition)[0];
let valueType = "dynamic";
if (typeof firstValue === "string") {
valueType = "String";
}
else if (typeof firstValue === "number") {
valueType = Number.isInteger(firstValue) ? "int" : "double";
}
else if (typeof firstValue === "boolean") {
valueType = "bool";
}
content =
`enum ${className} {\n ${entries.join(",\n ")};\n\n` +
` final ${valueType} value;\n\n` +
` const ${className}(this.value);\n}`;
}
else {
const fields = model.$fields();
let imports = "";
const importedModels = [];
let fieldDeclarations = "";
const constructorParams = [];
let fromJsonParams = "";
let toJsonAssignments = "";
fields.forEach((field) => {
const fieldName = this.$fieldName(field);
const fieldType = this.$fieldType(field);
const isRequired = (0, queries_1.$attr)(field, (0, attributes_1._required)());
// Handle nested models
if (field.$type() === "nested") {
const nestedModel = (0, queries_1.$attr)(field, (0, attributes_1._ref)());
if (nestedModel) {
const nestedClassName = this.$className(nestedModel);
if (!importedModels.includes(nestedClassName)) {
imports += this.$resolveImport(modelPath.path, nestedModel);
importedModels.push(nestedClassName);
}
}
}
// Build field declaration
fieldDeclarations += ` final ${fieldType} ${fieldName};\n`;
// Build constructor parameter
constructorParams.push(` ${isRequired ? "required " : ""}this.${fieldName},`);
// Build toJson and fromJson parameter
const refModel = (0, queries_1.$attr)(field, (0, attributes_1._ref)());
const isEnum = refModel ? !!(0, queries_1.$attr)(refModel, (0, attributes_1._enum)()) : false;
if (!isEnum && field.$type() === "nested") {
if ((0, queries_1.$attr)(field, (0, attributes_1._array)())) {
fromJsonParams += ` ${fieldName}: (json['${fieldName}'] as List<dynamic>)${!isRequired ? "?" : ""}.map((item) => ${this.$className((0, queries_1.$attr)(field, (0, attributes_1._ref)()))}.fromJson(item as Map<String, dynamic>))${!isRequired ? "?" : ""}.toList(),\n`;
toJsonAssignments += ` '${fieldName}': ${fieldName}${!isRequired ? "?" : ""}.map((item) => item.toJson())${!isRequired ? "?" : ""}.toList(),\n`;
}
else {
fromJsonParams += ` ${fieldName}: ${this.$className((0, queries_1.$attr)(field, (0, attributes_1._ref)()))}.fromJson(json['${fieldName}']),\n`;
toJsonAssignments += ` '${fieldName}': ${fieldName}${!isRequired ? "?" : ""}.toJson(),\n`;
}
}
else {
fromJsonParams += ` ${fieldName}: json['${fieldName}'],\n`;
toJsonAssignments += ` '${fieldName}': ${fieldName},\n`;
}
});
const constructor = constructorParams.length
? `\n ${className}({\n${constructorParams.join("\n")}\n });`
: "";
content =
`${imports}class ${className} {\n${fieldDeclarations}${constructor}\n\n` +
` factory ${className}.fromJson(Map<String, dynamic> json) {\n` +
` return ${className}(\n${fromJsonParams} );\n` +
` }\n\n` +
` Map<String, dynamic> toJson() {\n` +
` return {\n${toJsonAssignments} };\n` +
` }\n\n}`;
}
output.push({
key: modelKey,
content,
meta: (_a = modelPath.meta) !== null && _a !== void 0 ? _a : {},
});
}
return output;
});
}
}
exports.default = DartClassRenderer;
//# sourceMappingURL=dart-class-renderer.js.map