@semacode/cli 1.5.18 → 1.5.25

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 (93) hide show
  1. package/AGENTS.md +268 -260
  2. package/LICENSE +22 -22
  3. package/README.md +144 -104
  4. package/SEMA_BRIEF.curto.txt +7 -5
  5. package/SEMA_BRIEF.md +61 -5
  6. package/SEMA_BRIEF.micro.txt +6 -4
  7. package/SEMA_INDEX.json +991 -47
  8. package/dist/controleComercialSupabase.d.ts +326 -0
  9. package/dist/controleComercialSupabase.js +310 -0
  10. package/dist/controleComercialSupabase.js.map +1 -0
  11. package/dist/docs.js +48 -20
  12. package/dist/docs.js.map +1 -1
  13. package/dist/drift.d.ts +5 -3
  14. package/dist/drift.js +123 -14
  15. package/dist/drift.js.map +1 -1
  16. package/dist/index.js +1889 -38
  17. package/dist/index.js.map +1 -1
  18. package/dist/mcpRemoto.d.ts +32 -0
  19. package/dist/mcpRemoto.js +61 -0
  20. package/dist/mcpRemoto.js.map +1 -0
  21. package/dist/projeto.js +3 -1
  22. package/dist/projeto.js.map +1 -1
  23. package/docs/AGENT_STARTER.md +103 -97
  24. package/docs/cli.md +175 -106
  25. package/docs/como-ensinar-a-sema-para-ia.md +41 -35
  26. package/docs/deploy.md +231 -43
  27. package/docs/documentacao.md +61 -36
  28. package/docs/env.md +105 -56
  29. package/docs/extensao-vscode.md +12 -4
  30. package/docs/fluxo-pratico-ia-sema.md +182 -176
  31. package/docs/instalacao-e-primeiro-uso.md +52 -30
  32. package/docs/integracao-com-ia.md +108 -101
  33. package/docs/mcp.md +292 -51
  34. package/docs/pagamento-ponta-a-ponta.md +34 -28
  35. package/docs/persistencia-vendor-first.md +11 -5
  36. package/docs/prompt-base-ia-sema.md +13 -7
  37. package/docs/rollback.md +17 -15
  38. package/docs/sintaxe.md +180 -174
  39. package/exemplos/agendamento.sema +105 -105
  40. package/exemplos/assinatura.sema +133 -133
  41. package/exemplos/auditoria.sema +89 -89
  42. package/exemplos/autenticacao.sema +125 -125
  43. package/exemplos/author_obra_comum.sema +294 -0
  44. package/exemplos/author_tema_sensivel.sema +264 -0
  45. package/exemplos/automacao.sema +107 -107
  46. package/exemplos/cadastro_usuario.sema +54 -54
  47. package/exemplos/calculadora.sema +78 -78
  48. package/exemplos/crud_simples.sema +89 -89
  49. package/exemplos/estoque.sema +127 -127
  50. package/exemplos/exportacao.sema +94 -94
  51. package/exemplos/fila.sema +130 -130
  52. package/exemplos/integracao_externa.sema +94 -94
  53. package/exemplos/multi_tenant.sema +140 -140
  54. package/exemplos/notificacao.sema +149 -149
  55. package/exemplos/operacao_estrategia.sema +633 -633
  56. package/exemplos/pagamento.sema +434 -434
  57. package/exemplos/pagamento_dominio.sema +35 -35
  58. package/exemplos/pedido.sema +255 -255
  59. package/exemplos/permissao.sema +121 -121
  60. package/exemplos/persistencia_vendor_first.sema +86 -86
  61. package/exemplos/profile_game.sema +114 -0
  62. package/exemplos/profile_legal.sema +105 -0
  63. package/exemplos/profile_ops.sema +110 -0
  64. package/exemplos/profile_research.sema +104 -0
  65. package/exemplos/profile_software.sema +123 -0
  66. package/exemplos/profile_workflow_n8n.sema +99 -0
  67. package/exemplos/relatorio.sema +93 -93
  68. package/exemplos/replica_analitica_erp.sema +160 -160
  69. package/exemplos/testes_embutidos.sema +45 -45
  70. package/exemplos/tratamento_erro.sema +157 -157
  71. package/exemplos/upload_arquivo.sema +93 -93
  72. package/exemplos/webhook.sema +94 -94
  73. package/llms-full.txt +34 -34
  74. package/llms.txt +17 -17
  75. package/node_modules/@sema/gerador-css/dist/index.js +563 -563
  76. package/node_modules/@sema/gerador-css/package.json +1 -1
  77. package/node_modules/@sema/gerador-dart/package.json +1 -1
  78. package/node_modules/@sema/gerador-html/dist/index.js +90 -90
  79. package/node_modules/@sema/gerador-html/package.json +1 -1
  80. package/node_modules/@sema/gerador-javascript/dist/index.js +92 -92
  81. package/node_modules/@sema/gerador-javascript/package.json +1 -1
  82. package/node_modules/@sema/gerador-lua/dist/index.js +53 -53
  83. package/node_modules/@sema/gerador-lua/package.json +1 -1
  84. package/node_modules/@sema/gerador-python/dist/index.js +122 -96
  85. package/node_modules/@sema/gerador-python/dist/index.js.map +1 -1
  86. package/node_modules/@sema/gerador-python/package.json +1 -1
  87. package/node_modules/@sema/gerador-typescript/dist/index.js +153 -153
  88. package/node_modules/@sema/gerador-typescript/package.json +1 -1
  89. package/node_modules/@sema/nucleo/dist/formatador/index.js +12 -4
  90. package/node_modules/@sema/nucleo/dist/formatador/index.js.map +1 -1
  91. package/node_modules/@sema/nucleo/package.json +1 -1
  92. package/node_modules/@sema/padroes/package.json +1 -1
  93. package/package.json +11 -11
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema/gerador-css",
3
- "version": "1.5.18",
3
+ "version": "1.5.25",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema/gerador-dart",
3
- "version": "1.5.18",
3
+ "version": "1.5.25",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts"
@@ -13,40 +13,40 @@ function gerarCampoInput(campo, nivel) {
13
13
  const obrigatorio = campo.modificadores.includes("required");
14
14
  const atributos = obrigatorio ? ' required' : '';
15
15
  if (tipoInput === "textarea") {
16
- return `${indent}<div class="sema-campo">
17
- ${indent} <label for="campo-${campo.nome}">${campo.nome}${obrigatorio ? ' <span class="sema-obrigatorio">*</span>' : ''}</label>
18
- ${indent} <textarea id="campo-${campo.nome}" name="${campo.nome}" data-tipo-sema="${tipo}"${atributos}></textarea>
16
+ return `${indent}<div class="sema-campo">
17
+ ${indent} <label for="campo-${campo.nome}">${campo.nome}${obrigatorio ? ' <span class="sema-obrigatorio">*</span>' : ''}</label>
18
+ ${indent} <textarea id="campo-${campo.nome}" name="${campo.nome}" data-tipo-sema="${tipo}"${atributos}></textarea>
19
19
  ${indent}</div>`;
20
20
  }
21
21
  if (tipoInput === "checkbox") {
22
- return `${indent}<div class="sema-campo sema-campo-checkbox">
23
- ${indent} <label>
24
- ${indent} <input type="checkbox" id="campo-${campo.nome}" name="${campo.nome}" data-tipo-sema="${tipo}">
25
- ${indent} <span>${campo.nome}</span>
26
- ${indent} </label>
22
+ return `${indent}<div class="sema-campo sema-campo-checkbox">
23
+ ${indent} <label>
24
+ ${indent} <input type="checkbox" id="campo-${campo.nome}" name="${campo.nome}" data-tipo-sema="${tipo}">
25
+ ${indent} <span>${campo.nome}</span>
26
+ ${indent} </label>
27
27
  ${indent}</div>`;
28
28
  }
29
- return `${indent}<div class="sema-campo">
30
- ${indent} <label for="campo-${campo.nome}">${campo.nome}${obrigatorio ? ' <span class="sema-obrigatorio">*</span>' : ''}</label>
31
- ${indent} <input type="${tipoInput}" id="campo-${campo.nome}" name="${campo.nome}" data-tipo-sema="${tipo}"${atributos}>
29
+ return `${indent}<div class="sema-campo">
30
+ ${indent} <label for="campo-${campo.nome}">${campo.nome}${obrigatorio ? ' <span class="sema-obrigatorio">*</span>' : ''}</label>
31
+ ${indent} <input type="${tipoInput}" id="campo-${campo.nome}" name="${campo.nome}" data-tipo-sema="${tipo}"${atributos}>
32
32
  ${indent}</div>`;
33
33
  }
34
34
  function gerarTabelaEntity(entity) {
35
35
  const cabecalho = entity.campos.map((campo) => ` <th>${campo.nome} <small>(${campo.tipo})</small></th>`).join("\n");
36
- return ` <section class="sema-entity" data-entity="${entity.nome}">
37
- <h3>${entity.nome}</h3>
38
- <table class="sema-tabela">
39
- <thead>
40
- <tr>
41
- ${cabecalho}
42
- </tr>
43
- </thead>
44
- <tbody>
45
- <tr>
46
- ${entity.campos.map((campo) => ` <td data-campo="${campo.nome}">—</td>`).join("\n")}
47
- </tr>
48
- </tbody>
49
- </table>
36
+ return ` <section class="sema-entity" data-entity="${entity.nome}">
37
+ <h3>${entity.nome}</h3>
38
+ <table class="sema-tabela">
39
+ <thead>
40
+ <tr>
41
+ ${cabecalho}
42
+ </tr>
43
+ </thead>
44
+ <tbody>
45
+ <tr>
46
+ ${entity.campos.map((campo) => ` <td data-campo="${campo.nome}">—</td>`).join("\n")}
47
+ </tr>
48
+ </tbody>
49
+ </table>
50
50
  </section>`;
51
51
  }
52
52
  function gerarFormularioTask(task) {
@@ -55,40 +55,40 @@ function gerarFormularioTask(task) {
55
55
  const erroHtml = erros.length > 0
56
56
  ? `\n <div class="sema-erros" data-task="${task.nome}">\n${erros.map(([codigo, mensagem]) => ` <div class="sema-erro" data-erro="${codigo}" hidden>${escaparHtml(mensagem)}</div>`).join("\n")}\n </div>`
57
57
  : "";
58
- return ` <section class="sema-task" data-task="${task.nome}">
59
- <h3>Task: ${task.nome}</h3>
60
- <form id="form-${normalizarNomeParaSimbolo(task.nome)}" class="sema-formulario" data-task="${task.nome}">
61
- <fieldset>
62
- <legend>Entrada</legend>
63
- ${campos}
64
- </fieldset>
65
- <button type="submit" class="sema-botao">Executar ${task.nome}</button>
66
- </form>${erroHtml}
67
- <div class="sema-saida" data-task-saida="${task.nome}" hidden>
68
- <h4>Saida</h4>
69
- ${task.output.map((campo) => ` <div class="sema-campo-saida" data-campo="${campo.nome}"><strong>${campo.nome}</strong>: <span>—</span></div>`).join("\n")}
70
- </div>
58
+ return ` <section class="sema-task" data-task="${task.nome}">
59
+ <h3>Task: ${task.nome}</h3>
60
+ <form id="form-${normalizarNomeParaSimbolo(task.nome)}" class="sema-formulario" data-task="${task.nome}">
61
+ <fieldset>
62
+ <legend>Entrada</legend>
63
+ ${campos}
64
+ </fieldset>
65
+ <button type="submit" class="sema-botao">Executar ${task.nome}</button>
66
+ </form>${erroHtml}
67
+ <div class="sema-saida" data-task-saida="${task.nome}" hidden>
68
+ <h4>Saida</h4>
69
+ ${task.output.map((campo) => ` <div class="sema-campo-saida" data-campo="${campo.nome}"><strong>${campo.nome}</strong>: <span>—</span></div>`).join("\n")}
70
+ </div>
71
71
  </section>`;
72
72
  }
73
73
  function gerarEnumSelect(enumeracao) {
74
74
  const opcoes = enumeracao.valores.map((valor) => ` <option value="${valor}">${valor}</option>`).join("\n");
75
- return ` <section class="sema-enum" data-enum="${enumeracao.nome}">
76
- <h3>Enum: ${enumeracao.nome}</h3>
77
- <select id="enum-${normalizarNomeParaSimbolo(enumeracao.nome)}" class="sema-select" data-enum="${enumeracao.nome}">
78
- <option value="">— Selecionar —</option>
79
- ${opcoes}
80
- </select>
75
+ return ` <section class="sema-enum" data-enum="${enumeracao.nome}">
76
+ <h3>Enum: ${enumeracao.nome}</h3>
77
+ <select id="enum-${normalizarNomeParaSimbolo(enumeracao.nome)}" class="sema-select" data-enum="${enumeracao.nome}">
78
+ <option value="">— Selecionar —</option>
79
+ ${opcoes}
80
+ </select>
81
81
  </section>`;
82
82
  }
83
83
  function gerarState(state) {
84
84
  const transicoes = state.transicoes.length > 0
85
85
  ? state.transicoes.map((transicao) => ` <li class="sema-transicao"><span class="sema-estado-origem">${transicao.origem}</span> → <span class="sema-estado-destino">${transicao.destino}</span></li>`).join("\n")
86
86
  : ' <li>Nenhuma transicao declarada.</li>';
87
- return ` <section class="sema-state" data-state="${state.nome ?? "anonimo"}">
88
- <h3>State${state.nome ? `: ${state.nome}` : ""}</h3>
89
- <ul class="sema-transicoes">
90
- ${transicoes}
91
- </ul>
87
+ return ` <section class="sema-state" data-state="${state.nome ?? "anonimo"}">
88
+ <h3>State${state.nome ? `: ${state.nome}` : ""}</h3>
89
+ <ul class="sema-transicoes">
90
+ ${transicoes}
91
+ </ul>
92
92
  </section>`;
93
93
  }
94
94
  function gerarFlow(flow) {
@@ -100,27 +100,27 @@ function gerarFlow(flow) {
100
100
  if (etapa.emErro) {
101
101
  destinos.push(`erro → ${etapa.emErro}`);
102
102
  }
103
- return ` <li class="sema-etapa" data-etapa="${etapa.nome}" data-task="${etapa.task ?? ""}">
104
- <strong>${etapa.nome}</strong>${etapa.task ? ` (usa ${etapa.task})` : ""}${destinos.length > 0 ? ` [${destinos.join(", ")}]` : ""}
103
+ return ` <li class="sema-etapa" data-etapa="${etapa.nome}" data-task="${etapa.task ?? ""}">
104
+ <strong>${etapa.nome}</strong>${etapa.task ? ` (usa ${etapa.task})` : ""}${destinos.length > 0 ? ` [${destinos.join(", ")}]` : ""}
105
105
  </li>`;
106
106
  }).join("\n");
107
- return ` <section class="sema-flow" data-flow="${flow.nome}">
108
- <h3>Flow: ${flow.nome}</h3>
109
- <ol class="sema-etapas">
110
- ${etapas || ' <li>Nenhuma etapa estruturada.</li>'}
111
- </ol>
107
+ return ` <section class="sema-flow" data-flow="${flow.nome}">
108
+ <h3>Flow: ${flow.nome}</h3>
109
+ <ol class="sema-etapas">
110
+ ${etapas || ' <li>Nenhuma etapa estruturada.</li>'}
111
+ </ol>
112
112
  </section>`;
113
113
  }
114
114
  function gerarRoute(route) {
115
- return ` <section class="sema-route" data-route="${route.nome}">
116
- <h3>Route: ${route.nome}</h3>
117
- <div class="sema-route-detalhe">
118
- <span class="sema-route-metodo">${route.metodo ?? "POST"}</span>
119
- <code class="sema-route-caminho">${route.caminho ?? "/"}</code>
120
- ${route.task ? `<span class="sema-route-task">→ ${route.task}</span>` : ""}
121
- </div>
122
- ${route.inputPublico.length > 0 ? `<details class="sema-route-io"><summary>Input publico</summary><ul>${route.inputPublico.map((campo) => `<li>${campo.nome}: ${campo.tipo}${campo.modificadores.includes("required") ? " (obrigatorio)" : ""}</li>`).join("")}</ul></details>` : ""}
123
- ${route.outputPublico.length > 0 ? `<details class="sema-route-io"><summary>Output publico</summary><ul>${route.outputPublico.map((campo) => `<li>${campo.nome}: ${campo.tipo}</li>`).join("")}</ul></details>` : ""}
115
+ return ` <section class="sema-route" data-route="${route.nome}">
116
+ <h3>Route: ${route.nome}</h3>
117
+ <div class="sema-route-detalhe">
118
+ <span class="sema-route-metodo">${route.metodo ?? "POST"}</span>
119
+ <code class="sema-route-caminho">${route.caminho ?? "/"}</code>
120
+ ${route.task ? `<span class="sema-route-task">→ ${route.task}</span>` : ""}
121
+ </div>
122
+ ${route.inputPublico.length > 0 ? `<details class="sema-route-io"><summary>Input publico</summary><ul>${route.inputPublico.map((campo) => `<li>${campo.nome}: ${campo.tipo}${campo.modificadores.includes("required") ? " (obrigatorio)" : ""}</li>`).join("")}</ul></details>` : ""}
123
+ ${route.outputPublico.length > 0 ? `<details class="sema-route-io"><summary>Output publico</summary><ul>${route.outputPublico.map((campo) => `<li>${campo.nome}: ${campo.tipo}</li>`).join("")}</ul></details>` : ""}
124
124
  </section>`;
125
125
  }
126
126
  export function gerarHtml(modulo) {
@@ -132,31 +132,31 @@ export function gerarHtml(modulo) {
132
132
  const tasks = modulo.tasks.map(gerarFormularioTask).join("\n\n");
133
133
  const flows = modulo.flows.map(gerarFlow).join("\n\n");
134
134
  const routes = modulo.routes.map(gerarRoute).join("\n\n");
135
- const html = `<!DOCTYPE html>
136
- <html lang="pt-BR">
137
- <head>
138
- <meta charset="UTF-8">
139
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
140
- <meta name="description" content="Contrato Sema: ${escaparHtml(modulo.nome)}">
141
- <title>${escaparHtml(titulo)} — Sema</title>
142
- <link rel="stylesheet" href="${nomeBase}.css">
143
- </head>
144
- <body>
145
- <header class="sema-header">
146
- <h1>${escaparHtml(titulo)}</h1>
147
- <p class="sema-subtitulo">Contrato gerado automaticamente pela Sema.</p>
148
- </header>
149
-
150
- <main class="sema-main">
151
- ${entidades ? ` <!-- Entities -->\n${entidades}\n\n` : ""}${enums ? ` <!-- Enums -->\n${enums}\n\n` : ""}${states ? ` <!-- States -->\n${states}\n\n` : ""}${tasks ? ` <!-- Tasks -->\n${tasks}\n\n` : ""}${flows ? ` <!-- Flows -->\n${flows}\n\n` : ""}${routes ? ` <!-- Routes -->\n${routes}\n\n` : ""} </main>
152
-
153
- <footer class="sema-footer">
154
- <p>Modulo: <code>${escaparHtml(modulo.nome)}</code> | Gerado pela Sema</p>
155
- </footer>
156
-
157
- <script src="${nomeBase}.js" type="module"></script>
158
- </body>
159
- </html>
135
+ const html = `<!DOCTYPE html>
136
+ <html lang="pt-BR">
137
+ <head>
138
+ <meta charset="UTF-8">
139
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
140
+ <meta name="description" content="Contrato Sema: ${escaparHtml(modulo.nome)}">
141
+ <title>${escaparHtml(titulo)} — Sema</title>
142
+ <link rel="stylesheet" href="${nomeBase}.css">
143
+ </head>
144
+ <body>
145
+ <header class="sema-header">
146
+ <h1>${escaparHtml(titulo)}</h1>
147
+ <p class="sema-subtitulo">Contrato gerado automaticamente pela Sema.</p>
148
+ </header>
149
+
150
+ <main class="sema-main">
151
+ ${entidades ? ` <!-- Entities -->\n${entidades}\n\n` : ""}${enums ? ` <!-- Enums -->\n${enums}\n\n` : ""}${states ? ` <!-- States -->\n${states}\n\n` : ""}${tasks ? ` <!-- Tasks -->\n${tasks}\n\n` : ""}${flows ? ` <!-- Flows -->\n${flows}\n\n` : ""}${routes ? ` <!-- Routes -->\n${routes}\n\n` : ""} </main>
152
+
153
+ <footer class="sema-footer">
154
+ <p>Modulo: <code>${escaparHtml(modulo.nome)}</code> | Gerado pela Sema</p>
155
+ </footer>
156
+
157
+ <script src="${nomeBase}.js" type="module"></script>
158
+ </body>
159
+ </html>
160
160
  `;
161
161
  return [{ caminhoRelativo: `${nomeBase}.html`, conteudo: html }];
162
162
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema/gerador-html",
3
- "version": "1.5.18",
3
+ "version": "1.5.25",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts"
@@ -218,15 +218,15 @@ function gerarMetadadosTask(task) {
218
218
  const implementacoes = task.implementacoesExternas.length === 0
219
219
  ? "[]"
220
220
  : `[\n${task.implementacoesExternas.map((impl) => ` { origem: "${impl.origem}", caminho: "${impl.caminho}", resolucaoImpl: "${impl.resolucaoImpl ?? impl.caminho}", statusImpl: "${impl.statusImpl ?? "nao_verificado"}" },`).join("\n")}\n]`;
221
- return `export const contrato_${normalizarNomeParaSimbolo(task.nome)} = {
222
- nome: "${task.nome}",
223
- input: ${gerarLiteralCampos(task.input)},
224
- output: ${gerarLiteralCampos(task.output)},
225
- effects: ${efeitos},
226
- impl: ${implementacoes},
227
- errors: ${gerarLiteralErros(task.errors)},
228
- guarantees: ${JSON.stringify(task.guarantees, null, 2)},
229
- };
221
+ return `export const contrato_${normalizarNomeParaSimbolo(task.nome)} = {
222
+ nome: "${task.nome}",
223
+ input: ${gerarLiteralCampos(task.input)},
224
+ output: ${gerarLiteralCampos(task.output)},
225
+ effects: ${efeitos},
226
+ impl: ${implementacoes},
227
+ errors: ${gerarLiteralErros(task.errors)},
228
+ guarantees: ${JSON.stringify(task.guarantees, null, 2)},
229
+ };
230
230
  `;
231
231
  }
232
232
  function gerarTask(task) {
@@ -248,46 +248,46 @@ function gerarTask(task) {
248
248
  tipoErro: caso.error?.campos.find((campo) => campo.nome === "tipo")?.tipo ?? caso.error?.campos[0]?.tipo,
249
249
  }))
250
250
  .filter((caso) => caso.tipoErro);
251
- return `
252
- ${gerarJsdocTypedef(`${task.nome}Entrada`, task.input)}
253
- ${gerarJsdocTypedef(`${task.nome}Saida`, task.output)}
254
- ${erros.map(([nomeErro, mensagem]) => `export class ${task.nome}_${nomeErro}Erro extends Error {
255
- constructor() {
256
- super(${JSON.stringify(mensagem)});
257
- this.name = "${task.nome}_${nomeErro}Erro";
258
- this.codigo = "${nomeErro}";
259
- }
260
- }
261
- `).join("\n")}
262
- ${gerarMetadadosTask(task)}
263
-
264
- /**
265
- * Valida a entrada para ${task.nome}.
266
- * @param {${task.nome}Entrada} entrada
267
- * @returns {void}
268
- */
269
- export function validar_${nomeSimbolo}(entrada) {
270
- ${gerarValidacoes(task)}
271
- }
272
-
273
- ${gerarFuncaoGarantias(task)}
274
-
275
- /**
276
- * Executa a task ${task.nome}.
277
- * @param {${task.nome}Entrada} entrada
278
- * @returns {Promise<${task.nome}Saida>}
279
- */
280
- export async function executar_${nomeSimbolo}(entrada) {
281
- validar_${nomeSimbolo}(entrada);
282
- ${cenariosErro.map((caso) => ` if (JSON.stringify(entrada) === JSON.stringify(${caso.entrada})) throw new ${task.nome}_${caso.tipoErro}Erro();`).join("\n")}
283
- ${task.stateContract ? ` // Vinculo de estado: ${task.stateContract.nomeEstado ?? "nao_definido"}\n // Transicoes declaradas pela task: ${task.stateContract.transicoes.map((transicao) => `${transicao.origem}->${transicao.destino}`).join(", ") || "nenhuma"}` : ""}
284
- ${task.implementacoesExternas.length > 0 ? ` // Implementacoes externas vinculadas:\n${task.implementacoesExternas.map((impl) => ` // - ${impl.origem}: ${impl.caminho} [${impl.statusImpl ?? "nao_verificado"}]`).join("\n")}` : ""}
285
- // Efeitos declarados:
286
- ${task.efeitosEstruturados.map((efeito) => ` // - categoria=${efeito.categoria} alvo=${efeito.alvo}${efeito.detalhe ? ` detalhe=${efeito.detalhe}` : ""}${efeito.criticidade ? ` criticidade=${efeito.criticidade}` : ""}`).join("\n") || task.effects.map((efeito) => ` // - ${efeito}`).join("\n") || " // - Nenhum efeito declarado."}
287
- ${gerarPreparacaoSaida(task)}
288
- verificar_garantias_${nomeSimbolo}(saida);
289
- return saida;
290
- }
251
+ return `
252
+ ${gerarJsdocTypedef(`${task.nome}Entrada`, task.input)}
253
+ ${gerarJsdocTypedef(`${task.nome}Saida`, task.output)}
254
+ ${erros.map(([nomeErro, mensagem]) => `export class ${task.nome}_${nomeErro}Erro extends Error {
255
+ constructor() {
256
+ super(${JSON.stringify(mensagem)});
257
+ this.name = "${task.nome}_${nomeErro}Erro";
258
+ this.codigo = "${nomeErro}";
259
+ }
260
+ }
261
+ `).join("\n")}
262
+ ${gerarMetadadosTask(task)}
263
+
264
+ /**
265
+ * Valida a entrada para ${task.nome}.
266
+ * @param {${task.nome}Entrada} entrada
267
+ * @returns {void}
268
+ */
269
+ export function validar_${nomeSimbolo}(entrada) {
270
+ ${gerarValidacoes(task)}
271
+ }
272
+
273
+ ${gerarFuncaoGarantias(task)}
274
+
275
+ /**
276
+ * Executa a task ${task.nome}.
277
+ * @param {${task.nome}Entrada} entrada
278
+ * @returns {Promise<${task.nome}Saida>}
279
+ */
280
+ export async function executar_${nomeSimbolo}(entrada) {
281
+ validar_${nomeSimbolo}(entrada);
282
+ ${cenariosErro.map((caso) => ` if (JSON.stringify(entrada) === JSON.stringify(${caso.entrada})) throw new ${task.nome}_${caso.tipoErro}Erro();`).join("\n")}
283
+ ${task.stateContract ? ` // Vinculo de estado: ${task.stateContract.nomeEstado ?? "nao_definido"}\n // Transicoes declaradas pela task: ${task.stateContract.transicoes.map((transicao) => `${transicao.origem}->${transicao.destino}`).join(", ") || "nenhuma"}` : ""}
284
+ ${task.implementacoesExternas.length > 0 ? ` // Implementacoes externas vinculadas:\n${task.implementacoesExternas.map((impl) => ` // - ${impl.origem}: ${impl.caminho} [${impl.statusImpl ?? "nao_verificado"}]`).join("\n")}` : ""}
285
+ // Efeitos declarados:
286
+ ${task.efeitosEstruturados.map((efeito) => ` // - categoria=${efeito.categoria} alvo=${efeito.alvo}${efeito.detalhe ? ` detalhe=${efeito.detalhe}` : ""}${efeito.criticidade ? ` criticidade=${efeito.criticidade}` : ""}`).join("\n") || task.effects.map((efeito) => ` // - ${efeito}`).join("\n") || " // - Nenhum efeito declarado."}
287
+ ${gerarPreparacaoSaida(task)}
288
+ verificar_garantias_${nomeSimbolo}(saida);
289
+ return saida;
290
+ }
291
291
  `;
292
292
  }
293
293
  function gerarRotas(modulo) {
@@ -305,38 +305,38 @@ function gerarRotas(modulo) {
305
305
  const efeitosPublicos = route.efeitosPublicos.length === 0
306
306
  ? "[]"
307
307
  : `[\n${route.efeitosPublicos.map((efeito) => ` { categoria: "${efeito.categoria}", alvo: "${efeito.alvo}"${efeito.detalhe ? `, detalhe: ${JSON.stringify(efeito.detalhe)}` : ""}${efeito.criticidade ? `, criticidade: "${efeito.criticidade}"` : ""} },`).join("\n")}\n]`;
308
- return `
309
- ${gerarJsdocTypedef(`${route.nome}EntradaPublica`, route.inputPublico)}
310
- ${gerarJsdocTypedef(`${route.nome}SaidaPublica`, route.outputPublico)}
311
-
312
- export const contrato_publico_${nomeSimboloRoute} = {
313
- nome: "${route.nome}",
314
- metodo: ${JSON.stringify(route.metodo ?? null)},
315
- caminho: ${JSON.stringify(route.caminho ?? null)},
316
- task: ${JSON.stringify(route.task ?? null)},
317
- input: ${gerarLiteralCampos(route.inputPublico)},
318
- output: ${gerarLiteralCampos(route.outputPublico)},
319
- effects: ${efeitosPublicos},
320
- guarantees: ${JSON.stringify(route.garantiasPublicasMinimas, null, 2)},
321
- };
322
-
323
- /**
324
- * Adaptador publico para a rota ${route.nome}.
325
- * @param {${route.nome}EntradaPublica} requisicao
326
- * @returns {Promise<{sucesso: boolean, dados?: ${route.nome}SaidaPublica, erro?: {codigo: string, mensagem: string}}>}
327
- */
328
- export async function adaptar_${nomeSimboloRoute}(requisicao) {
329
- try {
330
- const saida = await executar_${nomeSimboloTask}(requisicao);
331
- return {
332
- sucesso: true,
333
- dados: {${route.outputPublico.map((campo) => `\n ${campo.nome}: saida.${campo.nome},`).join("")}
334
- },
335
- };
336
- } catch (erro) {
337
- throw erro;
338
- }
339
- }
308
+ return `
309
+ ${gerarJsdocTypedef(`${route.nome}EntradaPublica`, route.inputPublico)}
310
+ ${gerarJsdocTypedef(`${route.nome}SaidaPublica`, route.outputPublico)}
311
+
312
+ export const contrato_publico_${nomeSimboloRoute} = {
313
+ nome: "${route.nome}",
314
+ metodo: ${JSON.stringify(route.metodo ?? null)},
315
+ caminho: ${JSON.stringify(route.caminho ?? null)},
316
+ task: ${JSON.stringify(route.task ?? null)},
317
+ input: ${gerarLiteralCampos(route.inputPublico)},
318
+ output: ${gerarLiteralCampos(route.outputPublico)},
319
+ effects: ${efeitosPublicos},
320
+ guarantees: ${JSON.stringify(route.garantiasPublicasMinimas, null, 2)},
321
+ };
322
+
323
+ /**
324
+ * Adaptador publico para a rota ${route.nome}.
325
+ * @param {${route.nome}EntradaPublica} requisicao
326
+ * @returns {Promise<{sucesso: boolean, dados?: ${route.nome}SaidaPublica, erro?: {codigo: string, mensagem: string}}>}
327
+ */
328
+ export async function adaptar_${nomeSimboloRoute}(requisicao) {
329
+ try {
330
+ const saida = await executar_${nomeSimboloTask}(requisicao);
331
+ return {
332
+ sucesso: true,
333
+ dados: {${route.outputPublico.map((campo) => `\n ${campo.nome}: saida.${campo.nome},`).join("")}
334
+ },
335
+ };
336
+ } catch (erro) {
337
+ throw erro;
338
+ }
339
+ }
340
340
  `;
341
341
  }).join("\n");
342
342
  }
@@ -364,20 +364,20 @@ function gerarTestes(modulo) {
364
364
  const entrada = converterBlocoTesteParaJs(caso.given, tiposEntrada);
365
365
  const tipoErro = caso.error?.campos.find((campo) => campo.nome === "tipo")?.tipo ?? caso.error?.campos[0]?.tipo;
366
366
  if (tipoErro) {
367
- linhas.push(`
368
- test("${task.nome} :: ${caso.nome}", async () => {
369
- const entrada = ${entrada};
370
- await assert.rejects(() => ${nomeFuncao}(entrada), ${task.nome}_${tipoErro}Erro);
371
- });
367
+ linhas.push(`
368
+ test("${task.nome} :: ${caso.nome}", async () => {
369
+ const entrada = ${entrada};
370
+ await assert.rejects(() => ${nomeFuncao}(entrada), ${task.nome}_${tipoErro}Erro);
371
+ });
372
372
  `);
373
373
  continue;
374
374
  }
375
- linhas.push(`
376
- test("${task.nome} :: ${caso.nome}", async () => {
377
- const entrada = ${entrada};
378
- const resultado = await ${nomeFuncao}(entrada);
379
- assert.ok(resultado !== undefined);
380
- });
375
+ linhas.push(`
376
+ test("${task.nome} :: ${caso.nome}", async () => {
377
+ const entrada = ${entrada};
378
+ const resultado = await ${nomeFuncao}(entrada);
379
+ assert.ok(resultado !== undefined);
380
+ });
381
381
  `);
382
382
  }
383
383
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema/gerador-javascript",
3
- "version": "1.5.18",
3
+ "version": "1.5.25",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts"
@@ -228,42 +228,42 @@ function gerarTestesLua(modulo, arquivoModulo) {
228
228
  const funcoes = testes.map(({ task, caso, indice }) => {
229
229
  const nomeTeste = `test_${normalizarNomeParaSimbolo(task.nome)}_${indice + 1}`;
230
230
  const tiposDeclarados = gerarTabelaTiposDeclarados(task);
231
- return `local function ${nomeTeste}()
232
- local entrada = ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}
233
- local saida = modulo.executar_${normalizarNomeParaSimbolo(task.nome)}(entrada)
234
- if ${caso.expect.campos.some((campo) => campo.nome === "sucesso" && campo.tipo === "falso") ? "saida ~= nil" : "saida == nil"} then
235
- error("Caso ${caso.nome} nao respeitou expectativa basica de execucao.")
236
- end
231
+ return `local function ${nomeTeste}()
232
+ local entrada = ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}
233
+ local saida = modulo.executar_${normalizarNomeParaSimbolo(task.nome)}(entrada)
234
+ if ${caso.expect.campos.some((campo) => campo.nome === "sucesso" && campo.tipo === "falso") ? "saida ~= nil" : "saida == nil"} then
235
+ error("Caso ${caso.nome} nao respeitou expectativa basica de execucao.")
236
+ end
237
237
  end`;
238
238
  });
239
239
  const lista = testes.map(({ task, caso, indice }) => `{ nome = ${JSON.stringify(caso.nome)}, fn = test_${normalizarNomeParaSimbolo(task.nome)}_${indice + 1} }`).join(",\n ");
240
- return `local origem = debug.getinfo(1, "S").source:sub(2)
241
- local base = origem:match("^(.*[/\\\\])") or "./"
242
- local modulo = assert(loadfile(base .. ${JSON.stringify(nomeArquivo)}))()
243
-
244
- ${funcoes.join("\n\n")}
245
-
246
- local testes = {
247
- ${lista}
248
- }
249
-
250
- for _, teste in ipairs(testes) do
251
- io.write("test ", teste.nome, "\\n")
252
- teste.fn()
253
- end
254
-
255
- io.write("ok ", tostring(#testes), " testes\\n")
240
+ return `local origem = debug.getinfo(1, "S").source:sub(2)
241
+ local base = origem:match("^(.*[/\\\\])") or "./"
242
+ local modulo = assert(loadfile(base .. ${JSON.stringify(nomeArquivo)}))()
243
+
244
+ ${funcoes.join("\n\n")}
245
+
246
+ local testes = {
247
+ ${lista}
248
+ }
249
+
250
+ for _, teste in ipairs(testes) do
251
+ io.write("test ", teste.nome, "\\n")
252
+ teste.fn()
253
+ end
254
+
255
+ io.write("ok ", tostring(#testes), " testes\\n")
256
256
  `;
257
257
  }
258
258
  function gerarMetadadosTask(task) {
259
259
  const efeitos = task.efeitosEstruturados.map((efeito) => `${efeito.categoria}:${efeito.alvo}`).join(", ") || "nenhum";
260
260
  const impl = task.implementacoesExternas.map((item) => `${item.origem}:${item.caminho}[${item.statusImpl ?? "nao_verificado"}]`).join(", ") || "nenhuma";
261
- return `M.contrato_${normalizarNomeParaSimbolo(task.nome)} = {
262
- nome = ${JSON.stringify(task.nome)},
263
- input = ${gerarTabelaCampos(task.input)},
264
- output = ${gerarTabelaCampos(task.output)},
265
- effects = ${JSON.stringify(efeitos)},
266
- impl = ${JSON.stringify(impl)}
261
+ return `M.contrato_${normalizarNomeParaSimbolo(task.nome)} = {
262
+ nome = ${JSON.stringify(task.nome)},
263
+ input = ${gerarTabelaCampos(task.input)},
264
+ output = ${gerarTabelaCampos(task.output)},
265
+ effects = ${JSON.stringify(efeitos)},
266
+ impl = ${JSON.stringify(impl)}
267
267
  }`;
268
268
  }
269
269
  function gerarFuncoesTask(task) {
@@ -271,15 +271,15 @@ function gerarFuncoesTask(task) {
271
271
  const validacoes = gerarValidacoes(task);
272
272
  const garantias = gerarGarantias(task);
273
273
  const preparacaoSaida = gerarPreparacaoSaida(task);
274
- return `${gerarMetadadosTask(task)}
275
-
276
- ${garantias}
277
-
278
- function M.executar_${simbolo}(entrada)
279
- entrada = entrada or {}
280
- ${validacoes ? `${validacoes}\n` : ""}${preparacaoSaida}
281
- verificar_garantias_${simbolo}(saida)
282
- return saida
274
+ return `${gerarMetadadosTask(task)}
275
+
276
+ ${garantias}
277
+
278
+ function M.executar_${simbolo}(entrada)
279
+ entrada = entrada or {}
280
+ ${validacoes ? `${validacoes}\n` : ""}${preparacaoSaida}
281
+ verificar_garantias_${simbolo}(saida)
282
+ return saida
283
283
  end`;
284
284
  }
285
285
  export function gerarLua(modulo) {
@@ -293,22 +293,22 @@ export function gerarLua(modulo) {
293
293
  const tasks = modulo.tasks.map((task) => gerarFuncoesTask(task)).join("\n\n");
294
294
  const flows = modulo.flows.map((flow) => `-- Flow ${flow.nome}: etapas=${flow.etapasEstruturadas.length} tasks=${flow.tasksReferenciadas.join(", ") || "nenhuma"}`).join("\n");
295
295
  const routes = modulo.routes.map((route) => `-- Route ${route.nome}: metodo=${route.metodo ?? "nao_definido"} caminho=${route.caminho ?? "nao_definido"} task=${route.task ?? "nao_definida"}`).join("\n");
296
- const codigo = `-- Arquivo gerado automaticamente pela Sema.
297
- -- Modulo de origem: ${modulo.nome}
298
- ${interops ? `${interops}\n` : ""}${tiposExternos ? `${tiposExternos}\n\n` : ""}local M = {}
299
-
300
- local function contem(lista, valor)
301
- for _, item in ipairs(lista) do
302
- if item == valor then
303
- return true
304
- end
305
- end
306
- return false
307
- end
308
-
309
- ${tipos ? `${tipos}\n\n` : ""}${entidades ? `${entidades}\n\n` : ""}${enums ? `${enums}\n\n` : ""}${tasks}${flows ? `\n\n${flows}` : ""}${routes ? `\n${routes}` : ""}
310
-
311
- return M
296
+ const codigo = `-- Arquivo gerado automaticamente pela Sema.
297
+ -- Modulo de origem: ${modulo.nome}
298
+ ${interops ? `${interops}\n` : ""}${tiposExternos ? `${tiposExternos}\n\n` : ""}local M = {}
299
+
300
+ local function contem(lista, valor)
301
+ for _, item in ipairs(lista) do
302
+ if item == valor then
303
+ return true
304
+ end
305
+ end
306
+ return false
307
+ end
308
+
309
+ ${tipos ? `${tipos}\n\n` : ""}${entidades ? `${entidades}\n\n` : ""}${enums ? `${enums}\n\n` : ""}${tasks}${flows ? `\n\n${flows}` : ""}${routes ? `\n${routes}` : ""}
310
+
311
+ return M
312
312
  `;
313
313
  const caminhoModulo = estrutura.contextoRelativo
314
314
  ? path.join(estrutura.contextoRelativo, `${estrutura.nomeArquivo}.lua`)
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema/gerador-lua",
3
- "version": "1.5.18",
3
+ "version": "1.5.25",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts"