@vira-ui/cli 1.0.2 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +75 -23
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -91,7 +91,7 @@ const program = new commander_1.Command();
91
91
  program
92
92
  .name("vira")
93
93
  .description("ViraJS CLI - Create projects and generate code")
94
- .version("1.0.1");
94
+ .version("1.1.1");
95
95
  const SUPPORTED_TEMPLATES = ["frontend", "fullstack", "kanban"];
96
96
  /**
97
97
  * Инициализация проекта в текущей директории
@@ -283,15 +283,6 @@ make
283
283
  await generateGoHandler(name, options.dir);
284
284
  console.log(chalk_1.default.green(`✓ handler ${name} created in ${options.dir}`));
285
285
  });
286
- make
287
- .command("model")
288
- .description("Create Go model struct")
289
- .argument("<name>", "Model name (e.g. User)")
290
- .option("-d, --dir <directory>", "Target directory", path.join("backend", "internal", "models"))
291
- .action(async (name, options) => {
292
- await generateGoModel(name, options.dir);
293
- console.log(chalk_1.default.green(`✓ model ${name} created in ${options.dir}`));
294
- });
295
286
  make
296
287
  .command("migration")
297
288
  .description("Create SQL migration (up/down)")
@@ -310,6 +301,16 @@ make
310
301
  await generateEventHandler(name, options.dir);
311
302
  console.log(chalk_1.default.green(`✓ event handler ${name} created in ${options.dir}`));
312
303
  });
304
+ make
305
+ .command("model")
306
+ .description("Create a Go model struct")
307
+ .argument("<name>", "Model name (e.g. Client)")
308
+ .option("-d, --dir <directory>", "Target directory", path.join("backend", "internal", "models"))
309
+ .option("-f, --fields <fields>", "Comma-separated field definitions (e.g. 'name:string,email:string,phone:string')")
310
+ .action(async (name, options) => {
311
+ await generateGoModel(name, options.dir, options.fields || undefined);
312
+ console.log(chalk_1.default.green(`✓ Go model ${name} created in ${options.dir}`));
313
+ });
313
314
  make
314
315
  .command("crud")
315
316
  .description("Create CRUD handlers for a resource")
@@ -1184,7 +1185,7 @@ export function ${name}Page() {
1184
1185
  /**
1185
1186
  * Генерация модели
1186
1187
  */
1187
- async function generateModel(name, dir) {
1188
+ async function generateModel(name, dir, fields) {
1188
1189
  const modelPath = path.join(process.cwd(), dir, "models", `${name}.ts`);
1189
1190
  await fs.ensureDir(path.dirname(modelPath));
1190
1191
  const modelCode = `import { defineModel } from '@vira-ui/core';
@@ -1521,21 +1522,42 @@ func ${handlerName}(w http.ResponseWriter, r *http.Request) {
1521
1522
  /**
1522
1523
  * Go model scaffold
1523
1524
  */
1524
- async function generateGoModel(name, dir) {
1525
+ async function generateGoModel(name, dir, fields) {
1525
1526
  const modelName = capitalize(name);
1526
1527
  const targetDir = path.join(process.cwd(), dir);
1527
1528
  await fs.ensureDir(targetDir);
1529
+ // Парсим поля если указаны
1530
+ let fieldsCode = "";
1531
+ if (fields) {
1532
+ const fieldList = fields.split(",").map(f => f.trim());
1533
+ fieldsCode = fieldList.map(field => {
1534
+ const [fieldName, fieldType] = field.split(":").map(s => s.trim());
1535
+ const goType = mapTypeScriptToGo(fieldType || "string");
1536
+ return ` ${capitalize(fieldName)} ${goType} \`db:"${fieldName.toLowerCase()}" json:"${fieldName.toLowerCase()}"\``;
1537
+ }).join("\n");
1538
+ // Добавляем стандартные поля если их нет
1539
+ if (!fieldList.some(f => f.toLowerCase().includes("id"))) {
1540
+ fieldsCode = ` ID string \`db:"id" json:"id"\`
1541
+ ${fieldsCode}
1542
+ CreatedAt time.Time \`db:"created_at" json:"created_at"\`
1543
+ UpdatedAt time.Time \`db:"updated_at" json:"updated_at"\``;
1544
+ }
1545
+ }
1546
+ else {
1547
+ // Дефолтные поля для типичной модели
1548
+ fieldsCode = ` ID string \`db:"id" json:"id"\`
1549
+ CreatedAt time.Time \`db:"created_at" json:"created_at"\`
1550
+ UpdatedAt time.Time \`db:"updated_at" json:"updated_at"\``;
1551
+ }
1528
1552
  const modelCode = `package models
1529
1553
 
1530
1554
  import "time"
1531
1555
 
1532
1556
  type ${modelName} struct {
1533
- ID string \`db:"id"\`
1534
- CreatedAt time.Time \`db:"created_at"\`
1535
- UpdatedAt time.Time \`db:"updated_at"\`
1557
+ ${fieldsCode}
1536
1558
  }
1537
1559
  `;
1538
- await fs.writeFile(path.join(targetDir, `${modelName}.go`), modelCode);
1560
+ await fs.writeFile(path.join(targetDir, `${modelName.toLowerCase()}.go`), modelCode);
1539
1561
  }
1540
1562
  /**
1541
1563
  * SQL migration scaffold (timestamped up/down)
@@ -1583,6 +1605,19 @@ function capitalize(value) {
1583
1605
  return value;
1584
1606
  return value.charAt(0).toUpperCase() + value.slice(1);
1585
1607
  }
1608
+ /**
1609
+ * Маппинг TypeScript типов в Go типы
1610
+ */
1611
+ function mapTypeScriptToGo(tsType) {
1612
+ const mapping = {
1613
+ "string": "string",
1614
+ "number": "int",
1615
+ "boolean": "bool",
1616
+ "Date": "time.Time",
1617
+ "date": "time.Time",
1618
+ };
1619
+ return mapping[tsType.toLowerCase()] || "string";
1620
+ }
1586
1621
  function toPascal(value) {
1587
1622
  return value
1588
1623
  .split(/[^a-zA-Z0-9]+/)
@@ -1599,6 +1634,21 @@ async function generateCRUDHandler(name, dir, modelName) {
1599
1634
  const model = modelName || capitalize(name);
1600
1635
  const targetDir = path.join(process.cwd(), dir);
1601
1636
  await fs.ensureDir(targetDir);
1637
+ // Попытка определить модуль из go.mod
1638
+ let modulePath = "your-project/backend";
1639
+ try {
1640
+ const goModPath = path.join(process.cwd(), dir, "..", "..", "go.mod");
1641
+ if (await fs.pathExists(goModPath)) {
1642
+ const goModContent = await fs.readFile(goModPath, "utf8");
1643
+ const moduleMatch = goModContent.match(/^module\\s+(.+)$/m);
1644
+ if (moduleMatch) {
1645
+ modulePath = moduleMatch[1];
1646
+ }
1647
+ }
1648
+ }
1649
+ catch (e) {
1650
+ // Игнорируем ошибки, используем дефолтный путь
1651
+ }
1602
1652
  const handlerCode = `package handlers
1603
1653
 
1604
1654
  import (
@@ -1609,6 +1659,8 @@ import (
1609
1659
  "github.com/gorilla/mux"
1610
1660
  "github.com/go-playground/validator/v10"
1611
1661
  "github.com/google/uuid"
1662
+
1663
+ "${modulePath}/internal/models"
1612
1664
  )
1613
1665
 
1614
1666
  var validate = validator.New()
@@ -1622,7 +1674,7 @@ type PaginationParams struct {
1622
1674
 
1623
1675
  // 🎯 Production-ready: List response with pagination
1624
1676
  type ${handlerName}ListResponse struct {
1625
- Items []${model} \`json:"items"\`
1677
+ Items []models.${model} \`json:"items"\`
1626
1678
  Total int \`json:"total"\`
1627
1679
  Limit int \`json:"limit"\`
1628
1680
  Offset int \`json:"offset"\`
@@ -1635,8 +1687,8 @@ type ${handlerName}Event struct {
1635
1687
  Type string \`json:"type"\` // created, updated, deleted
1636
1688
  EntityID string \`json:"entity_id"\`
1637
1689
  UserID string \`json:"user_id,omitempty"\`
1638
- OldValue *${model} \`json:"old_value,omitempty"\`
1639
- NewValue *${model} \`json:"new_value,omitempty"\`
1690
+ OldValue *models.${model} \`json:"old_value,omitempty"\`
1691
+ NewValue *models.${model} \`json:"new_value,omitempty"\`
1640
1692
  Timestamp time.Time \`json:"timestamp"\`
1641
1693
  }
1642
1694
 
@@ -1685,7 +1737,7 @@ func List${handlerName}(w http.ResponseWriter, r *http.Request) {
1685
1737
  // }
1686
1738
 
1687
1739
  response := ${handlerName}ListResponse{
1688
- Items: []${model}{},
1740
+ Items: []models.${model}{},
1689
1741
  Total: 0,
1690
1742
  Limit: limit,
1691
1743
  Offset: offset,
@@ -1719,7 +1771,7 @@ func Get${handlerName}(w http.ResponseWriter, r *http.Request) {
1719
1771
  // return
1720
1772
  // }
1721
1773
 
1722
- item := ${model}{ID: id}
1774
+ item := models.${model}{ID: id}
1723
1775
 
1724
1776
  // 🎯 Production-ready: Cache detail (TTL 5min)
1725
1777
  // redis.Set(cacheKey, item, 5*time.Minute)
@@ -1729,7 +1781,7 @@ func Get${handlerName}(w http.ResponseWriter, r *http.Request) {
1729
1781
 
1730
1782
  // Create${handlerName} handles POST /${safeName}
1731
1783
  func Create${handlerName}(w http.ResponseWriter, r *http.Request) {
1732
- var input ${model}
1784
+ var input models.${model}
1733
1785
 
1734
1786
  if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
1735
1787
  http.Error(w, "Invalid JSON", http.StatusBadRequest)
@@ -1787,7 +1839,7 @@ func Update${handlerName}(w http.ResponseWriter, r *http.Request) {
1787
1839
  vars := mux.Vars(r)
1788
1840
  id := vars["id"]
1789
1841
 
1790
- var input ${model}
1842
+ var input models.${model}
1791
1843
  if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
1792
1844
  http.Error(w, "Invalid JSON", http.StatusBadRequest)
1793
1845
  return
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vira-ui/cli",
3
- "version": "1.0.2",
3
+ "version": "1.1.1",
4
4
  "description": "CLI tool for ViraJS project generation",
5
5
  "author": "Vira Team",
6
6
  "license": "MIT",