UNPKG

@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
"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