@semacode/cli 1.5.31 → 1.5.32

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 (157) hide show
  1. package/AGENTS.md +294 -0
  2. package/AGENT_CONTEXT_PACK.json +164 -0
  3. package/LICENSE +22 -0
  4. package/README.md +85 -144
  5. package/SEMA_BRIEF.curto.txt +11 -0
  6. package/SEMA_BRIEF.md +616 -0
  7. package/SEMA_BRIEF.micro.txt +9 -0
  8. package/SEMA_INDEX.json +9393 -0
  9. package/dist/billing/index.d.ts +46 -0
  10. package/dist/billing/index.js +143 -0
  11. package/dist/billing/index.js.map +1 -0
  12. package/dist/controleComercialSupabase.d.ts +7 -0
  13. package/dist/controleComercialSupabase.js +6 -0
  14. package/dist/controleComercialSupabase.js.map +1 -0
  15. package/dist/controleComercialSupabaseAdmin.d.ts +7 -0
  16. package/dist/controleComercialSupabaseAdmin.js +138 -0
  17. package/dist/controleComercialSupabaseAdmin.js.map +1 -0
  18. package/dist/controleComercialSupabaseCadastro.d.ts +4 -0
  19. package/dist/controleComercialSupabaseCadastro.js +85 -0
  20. package/dist/controleComercialSupabaseCadastro.js.map +1 -0
  21. package/dist/controleComercialSupabaseConstantes.d.ts +28 -0
  22. package/dist/controleComercialSupabaseConstantes.js +44 -0
  23. package/dist/controleComercialSupabaseConstantes.js.map +1 -0
  24. package/dist/controleComercialSupabaseConsumo.d.ts +2 -0
  25. package/dist/controleComercialSupabaseConsumo.js +77 -0
  26. package/dist/controleComercialSupabaseConsumo.js.map +1 -0
  27. package/dist/controleComercialSupabaseConta.d.ts +11 -0
  28. package/dist/controleComercialSupabaseConta.js +157 -0
  29. package/dist/controleComercialSupabaseConta.js.map +1 -0
  30. package/dist/controleComercialSupabaseProfiles.d.ts +4 -0
  31. package/dist/controleComercialSupabaseProfiles.js +55 -0
  32. package/dist/controleComercialSupabaseProfiles.js.map +1 -0
  33. package/dist/controleComercialSupabaseTipos.d.ts +3 -0
  34. package/dist/controleComercialSupabaseTipos.js +2 -0
  35. package/dist/controleComercialSupabaseTipos.js.map +1 -0
  36. package/dist/controleComercialSupabaseTiposAdmin.d.ts +152 -0
  37. package/dist/controleComercialSupabaseTiposAdmin.js +2 -0
  38. package/dist/controleComercialSupabaseTiposAdmin.js.map +1 -0
  39. package/dist/controleComercialSupabaseTiposBase.d.ts +169 -0
  40. package/dist/controleComercialSupabaseTiposBase.js +2 -0
  41. package/dist/controleComercialSupabaseTiposBase.js.map +1 -0
  42. package/dist/controleComercialSupabaseTiposConta.d.ts +220 -0
  43. package/dist/controleComercialSupabaseTiposConta.js +2 -0
  44. package/dist/controleComercialSupabaseTiposConta.js.map +1 -0
  45. package/dist/index.js +222 -46
  46. package/dist/index.js.map +1 -1
  47. package/dist/runnerValidacaoRemota.d.ts +9 -0
  48. package/dist/runnerValidacaoRemota.js +9 -0
  49. package/dist/runnerValidacaoRemota.js.map +1 -0
  50. package/dist/runnerValidacaoRemotaBateria.d.ts +10 -0
  51. package/dist/runnerValidacaoRemotaBateria.js +115 -0
  52. package/dist/runnerValidacaoRemotaBateria.js.map +1 -0
  53. package/dist/runnerValidacaoRemotaCli.d.ts +4 -0
  54. package/dist/runnerValidacaoRemotaCli.js +86 -0
  55. package/dist/runnerValidacaoRemotaCli.js.map +1 -0
  56. package/dist/runnerValidacaoRemotaComandos.d.ts +7 -0
  57. package/dist/runnerValidacaoRemotaComandos.js +123 -0
  58. package/dist/runnerValidacaoRemotaComandos.js.map +1 -0
  59. package/dist/runnerValidacaoRemotaEscopo.d.ts +4 -0
  60. package/dist/runnerValidacaoRemotaEscopo.js +79 -0
  61. package/dist/runnerValidacaoRemotaEscopo.js.map +1 -0
  62. package/dist/runnerValidacaoRemotaExecucao.d.ts +2 -0
  63. package/dist/runnerValidacaoRemotaExecucao.js +102 -0
  64. package/dist/runnerValidacaoRemotaExecucao.js.map +1 -0
  65. package/dist/runnerValidacaoRemotaRelatorio.d.ts +3 -0
  66. package/dist/runnerValidacaoRemotaRelatorio.js +93 -0
  67. package/dist/runnerValidacaoRemotaRelatorio.js.map +1 -0
  68. package/dist/runnerValidacaoRemotaServidor.d.ts +3 -0
  69. package/dist/runnerValidacaoRemotaServidor.js +157 -0
  70. package/dist/runnerValidacaoRemotaServidor.js.map +1 -0
  71. package/dist/runnerValidacaoRemotaSnapshot.d.ts +10 -0
  72. package/dist/runnerValidacaoRemotaSnapshot.js +217 -0
  73. package/dist/runnerValidacaoRemotaSnapshot.js.map +1 -0
  74. package/dist/runnerValidacaoRemotaTipos.d.ts +158 -0
  75. package/dist/runnerValidacaoRemotaTipos.js +35 -0
  76. package/dist/runnerValidacaoRemotaTipos.js.map +1 -0
  77. package/dist/runnerValidacaoRemotaUtil.d.ts +3 -0
  78. package/dist/runnerValidacaoRemotaUtil.js +18 -0
  79. package/dist/runnerValidacaoRemotaUtil.js.map +1 -0
  80. package/dist/runnerValidacaoRemotaWorkspace.d.ts +2 -0
  81. package/dist/runnerValidacaoRemotaWorkspace.js +110 -0
  82. package/dist/runnerValidacaoRemotaWorkspace.js.map +1 -0
  83. package/docs/AGENT_STARTER.md +109 -0
  84. package/docs/api.md +82 -0
  85. package/docs/cli.md +93 -0
  86. package/docs/como-ensinar-a-sema-para-ia.md +30 -0
  87. package/docs/deploy.md +45 -0
  88. package/docs/documentacao.md +88 -0
  89. package/docs/env.md +115 -0
  90. package/docs/extensao-vscode.md +42 -0
  91. package/docs/fluxo-pratico-ia-sema.md +187 -0
  92. package/docs/instalacao-e-primeiro-uso.md +48 -0
  93. package/docs/integracao-com-ia.md +24 -0
  94. package/docs/mcp.md +48 -0
  95. package/docs/pagamento-ponta-a-ponta.md +171 -0
  96. package/docs/persistencia-vendor-first.md +151 -0
  97. package/docs/prompt-base-ia-sema.md +111 -0
  98. package/docs/repositories.md +69 -0
  99. package/docs/rollback.md +24 -0
  100. package/docs/seguranca.md +126 -0
  101. package/docs/sintaxe.md +218 -0
  102. package/exemplos/profile_conversas.sema +165 -0
  103. package/llms-full.txt +35 -0
  104. package/llms.txt +18 -0
  105. package/node_modules/@sema/gerador-css/package.json +7 -14
  106. package/node_modules/@sema/gerador-dart/package.json +7 -14
  107. package/node_modules/@sema/gerador-html/package.json +7 -14
  108. package/node_modules/@sema/gerador-javascript/package.json +7 -14
  109. package/node_modules/@sema/gerador-lua/package.json +7 -14
  110. package/node_modules/@sema/gerador-python/package.json +7 -14
  111. package/node_modules/@sema/gerador-typescript/package.json +7 -14
  112. package/node_modules/@sema/nucleo/package.json +7 -10
  113. package/node_modules/@sema/padroes/package.json +7 -10
  114. package/package.json +75 -74
  115. package/exemplos/.prepack-generated +0 -1
  116. package/node_modules/@sema/gerador-css/src/index.ts +0 -605
  117. package/node_modules/@sema/gerador-css/tsconfig.json +0 -13
  118. package/node_modules/@sema/gerador-css/tsconfig.tsbuildinfo +0 -1
  119. package/node_modules/@sema/gerador-dart/src/index.ts +0 -52
  120. package/node_modules/@sema/gerador-dart/tsconfig.json +0 -13
  121. package/node_modules/@sema/gerador-dart/tsconfig.tsbuildinfo +0 -1
  122. package/node_modules/@sema/gerador-html/src/index.ts +0 -185
  123. package/node_modules/@sema/gerador-html/tsconfig.json +0 -13
  124. package/node_modules/@sema/gerador-html/tsconfig.tsbuildinfo +0 -1
  125. package/node_modules/@sema/gerador-javascript/src/index.ts +0 -461
  126. package/node_modules/@sema/gerador-javascript/tsconfig.json +0 -13
  127. package/node_modules/@sema/gerador-javascript/tsconfig.tsbuildinfo +0 -1
  128. package/node_modules/@sema/gerador-lua/src/index.ts +0 -359
  129. package/node_modules/@sema/gerador-lua/tsconfig.json +0 -13
  130. package/node_modules/@sema/gerador-lua/tsconfig.tsbuildinfo +0 -1
  131. package/node_modules/@sema/gerador-python/src/index.ts +0 -850
  132. package/node_modules/@sema/gerador-python/tsconfig.json +0 -13
  133. package/node_modules/@sema/gerador-python/tsconfig.tsbuildinfo +0 -1
  134. package/node_modules/@sema/gerador-typescript/src/index.ts +0 -876
  135. package/node_modules/@sema/gerador-typescript/tsconfig.json +0 -13
  136. package/node_modules/@sema/gerador-typescript/tsconfig.tsbuildinfo +0 -1
  137. package/node_modules/@sema/nucleo/src/ast/tipos.ts +0 -207
  138. package/node_modules/@sema/nucleo/src/diagnosticos/index.ts +0 -43
  139. package/node_modules/@sema/nucleo/src/diagnosticos/melhorador.ts +0 -130
  140. package/node_modules/@sema/nucleo/src/formatador/index.ts +0 -530
  141. package/node_modules/@sema/nucleo/src/index.ts +0 -184
  142. package/node_modules/@sema/nucleo/src/ir/conversor.ts +0 -1037
  143. package/node_modules/@sema/nucleo/src/ir/modelos.ts +0 -403
  144. package/node_modules/@sema/nucleo/src/lexer/lexer.ts +0 -166
  145. package/node_modules/@sema/nucleo/src/lexer/tokens.ts +0 -79
  146. package/node_modules/@sema/nucleo/src/parser/gramatica.ebnf +0 -41
  147. package/node_modules/@sema/nucleo/src/parser/parser.ts +0 -936
  148. package/node_modules/@sema/nucleo/src/persistencia/contratos.ts +0 -379
  149. package/node_modules/@sema/nucleo/src/semantico/analisador.ts +0 -3126
  150. package/node_modules/@sema/nucleo/src/semantico/estruturas.ts +0 -665
  151. package/node_modules/@sema/nucleo/src/semantico/seguranca.ts +0 -362
  152. package/node_modules/@sema/nucleo/src/util/arquivos.ts +0 -28
  153. package/node_modules/@sema/nucleo/tsconfig.json +0 -9
  154. package/node_modules/@sema/nucleo/tsconfig.tsbuildinfo +0 -1
  155. package/node_modules/@sema/padroes/src/index.ts +0 -382
  156. package/node_modules/@sema/padroes/tsconfig.json +0 -9
  157. package/node_modules/@sema/padroes/tsconfig.tsbuildinfo +0 -1
@@ -1,936 +0,0 @@
1
- import {
2
- criarDiagnostico,
3
- type Diagnostico,
4
- type IntervaloFonte,
5
- } from "../diagnosticos/index.js";
6
- import type {
7
- BlocoAst,
8
- BlocoCasoTesteAst,
9
- BlocoGenericoAst,
10
- CampoAst,
11
- EntityAst,
12
- EnumAst,
13
- FlowAst,
14
- ModuloAst,
15
- RouteAst,
16
- StateAst,
17
- TaskAst,
18
- TypeAst,
19
- UseAst,
20
- } from "../ast/tipos.js";
21
- import type { Token } from "../lexer/tokens.js";
22
-
23
- interface ResultadoParser {
24
- modulo?: ModuloAst;
25
- diagnosticos: Diagnostico[];
26
- }
27
-
28
- type PalavraBloco =
29
- | "database"
30
- | "docs"
31
- | "comments"
32
- | "table"
33
- | "view"
34
- | "query"
35
- | "transaction"
36
- | "index"
37
- | "constraint"
38
- | "relationship"
39
- | "collection"
40
- | "document"
41
- | "keyspace"
42
- | "stream"
43
- | "lock"
44
- | "retention"
45
- | "replication"
46
- | "fields"
47
- | "invariants"
48
- | "transitions"
49
- | "input"
50
- | "output"
51
- | "rules"
52
- | "effects"
53
- | "impl"
54
- | "vinculos"
55
- | "execucao"
56
- | "auth"
57
- | "authz"
58
- | "dados"
59
- | "audit"
60
- | "segredos"
61
- | "forbidden"
62
- | "guarantees"
63
- | "state"
64
- | "tests"
65
- | "error"
66
- | "flow"
67
- | "route"
68
- | "worker"
69
- | "evento"
70
- | "fila"
71
- | "cron"
72
- | "webhook"
73
- | "cache"
74
- | "storage"
75
- | "policy"
76
- | "when"
77
- | "given"
78
- | "expect";
79
-
80
- const PALAVRAS_BLOCO_NOMEADO_LIVRE = new Set<PalavraBloco>([
81
- "table",
82
- "view",
83
- "query",
84
- "transaction",
85
- "index",
86
- "constraint",
87
- "relationship",
88
- "collection",
89
- "document",
90
- "keyspace",
91
- "stream",
92
- "lock",
93
- "retention",
94
- "replication",
95
- ]);
96
-
97
- function decodificarTextoLiteral(valor: string): string {
98
- let resultado = "";
99
-
100
- for (let indice = 0; indice < valor.length; indice += 1) {
101
- const atual = valor[indice];
102
- if (atual !== "\\") {
103
- resultado += atual;
104
- continue;
105
- }
106
-
107
- const proximo = valor[indice + 1];
108
- if (!proximo) {
109
- resultado += atual;
110
- continue;
111
- }
112
-
113
- switch (proximo) {
114
- case "\"":
115
- resultado += "\"";
116
- indice += 1;
117
- break;
118
- case "\\":
119
- resultado += "\\";
120
- indice += 1;
121
- break;
122
- case "n":
123
- resultado += "\n";
124
- indice += 1;
125
- break;
126
- case "r":
127
- resultado += "\r";
128
- indice += 1;
129
- break;
130
- case "t":
131
- resultado += "\t";
132
- indice += 1;
133
- break;
134
- default:
135
- resultado += `${atual}${proximo}`;
136
- indice += 1;
137
- break;
138
- }
139
- }
140
-
141
- return resultado;
142
- }
143
-
144
- class Parser {
145
- private indice = 0;
146
- private diagnosticos: Diagnostico[] = [];
147
-
148
- public constructor(private readonly tokens: Token[]) {}
149
-
150
- public analisar(): ResultadoParser {
151
- this.ignorarRuido();
152
- const modulo = this.parseModulo();
153
- return { modulo, diagnosticos: this.diagnosticos };
154
- }
155
-
156
- private atual(): Token {
157
- return this.tokens[this.indice]!;
158
- }
159
-
160
- private anterior(): Token {
161
- return this.tokens[Math.max(0, this.indice - 1)]!;
162
- }
163
-
164
- private avancar(): Token {
165
- const token = this.atual();
166
- if (this.indice < this.tokens.length - 1) {
167
- this.indice += 1;
168
- }
169
- return token;
170
- }
171
-
172
- private ignorarRuido(): void {
173
- while (["nova_linha", "comentario"].includes(this.atual().tipo)) {
174
- this.avancar();
175
- }
176
- }
177
-
178
- private tokenNaFrente(distancia = 1): Token | undefined {
179
- return this.tokens[this.indice + distancia];
180
- }
181
-
182
- private iniciaBlocoSimples(keyword: string): boolean {
183
- if (this.atual().valor !== keyword) {
184
- return false;
185
- }
186
- return this.tokenNaFrente()?.valor === "{";
187
- }
188
-
189
- private iniciaBlocoComNomeObrigatorio(keyword: string): boolean {
190
- if (this.atual().valor !== keyword) {
191
- return false;
192
- }
193
- return this.tokenNaFrente()?.tipo === "identificador" && this.tokenNaFrente(2)?.valor === "{";
194
- }
195
-
196
- private iniciaBlocoState(): boolean {
197
- if (this.atual().valor !== "state") {
198
- return false;
199
- }
200
- return this.tokenNaFrente()?.valor === "{"
201
- || (this.tokenNaFrente()?.tipo === "identificador" && this.tokenNaFrente(2)?.valor === "{");
202
- }
203
-
204
- private iniciaSubblocoConhecido(): boolean {
205
- if (this.atual().tipo !== "palavra_chave") {
206
- return false;
207
- }
208
-
209
- if (["state"].includes(this.atual().valor)) {
210
- return this.iniciaBlocoState();
211
- }
212
-
213
- return [
214
- "docs",
215
- "comments",
216
- "fields",
217
- "invariants",
218
- "transitions",
219
- "input",
220
- "output",
221
- "rules",
222
- "effects",
223
- "impl",
224
- "vinculos",
225
- "execucao",
226
- "auth",
227
- "authz",
228
- "dados",
229
- "audit",
230
- "segredos",
231
- "forbidden",
232
- "guarantees",
233
- "tests",
234
- "error",
235
- "given",
236
- "when",
237
- "expect",
238
- ].includes(this.atual().valor) && this.iniciaBlocoSimples(this.atual().valor);
239
- }
240
-
241
- private consumirValor(valor: string, mensagem: string): Token {
242
- const token = this.atual();
243
- if (token.valor === valor) {
244
- this.avancar();
245
- return token;
246
- }
247
- this.registrarErro("PAR001", mensagem, token.intervalo, `Esperado "${valor}", recebido "${token.valor}".`);
248
- return token;
249
- }
250
-
251
- private consumirTipo(tipo: Token["tipo"], mensagem: string): Token {
252
- const token = this.atual();
253
- if (token.tipo === tipo) {
254
- this.avancar();
255
- return token;
256
- }
257
- this.registrarErro("PAR002", mensagem, token.intervalo, `Esperado token do tipo "${tipo}".`);
258
- return token;
259
- }
260
-
261
- private registrarErro(codigo: string, mensagem: string, intervalo?: IntervaloFonte, contexto?: string): void {
262
- this.diagnosticos.push(
263
- criarDiagnostico(
264
- codigo,
265
- mensagem,
266
- "erro",
267
- intervalo,
268
- "Revise a sintaxe do bloco e a ordem das declaracoes.",
269
- contexto,
270
- ),
271
- );
272
- }
273
-
274
- private parseModulo(): ModuloAst | undefined {
275
- if (this.atual().valor !== "module") {
276
- this.registrarErro("PAR003", "Arquivo .sema deve iniciar com um bloco module.", this.atual().intervalo);
277
- return undefined;
278
- }
279
-
280
- const inicio = this.avancar().intervalo.inicio;
281
- const nome = this.consumirTipo("identificador", "Era esperado o nome do modulo.").valor;
282
- this.consumirValor("{", "Era esperado abrir o corpo do modulo com {.");
283
-
284
- const uses: UseAst[] = [];
285
- let vinculos: BlocoGenericoAst | undefined;
286
- const databases: BlocoGenericoAst[] = [];
287
- const types: TypeAst[] = [];
288
- const entities: EntityAst[] = [];
289
- const enums: EnumAst[] = [];
290
- const tasks: TaskAst[] = [];
291
- const flows: FlowAst[] = [];
292
- const routes: RouteAst[] = [];
293
- const workers: BlocoGenericoAst[] = [];
294
- const eventos: BlocoGenericoAst[] = [];
295
- const filas: BlocoGenericoAst[] = [];
296
- const crons: BlocoGenericoAst[] = [];
297
- const webhooks: BlocoGenericoAst[] = [];
298
- const caches: BlocoGenericoAst[] = [];
299
- const storages: BlocoGenericoAst[] = [];
300
- const policies: BlocoGenericoAst[] = [];
301
- const states: StateAst[] = [];
302
- const extras: BlocoGenericoAst[] = [];
303
- let docs: BlocoGenericoAst | undefined;
304
- let comments: BlocoGenericoAst | undefined;
305
- let tests: BlocoGenericoAst | undefined;
306
-
307
- while (this.atual().tipo !== "fim_arquivo" && this.atual().valor !== "}") {
308
- this.ignorarRuido();
309
- const token = this.atual();
310
- if (token.valor === "}") {
311
- break;
312
- }
313
-
314
- switch (token.valor) {
315
- case "use":
316
- if (this.tokenNaFrente()?.tipo === "identificador") {
317
- uses.push(this.parseUse());
318
- break;
319
- }
320
- extras.push(this.parseBlocoGenerico("desconhecido"));
321
- break;
322
- case "docs":
323
- if (this.iniciaBlocoSimples("docs")) {
324
- docs = this.parseBlocoGenerico("docs");
325
- break;
326
- }
327
- extras.push(this.parseBlocoGenerico("desconhecido"));
328
- break;
329
- case "comments":
330
- if (this.iniciaBlocoSimples("comments")) {
331
- comments = this.parseBlocoGenerico("comments");
332
- break;
333
- }
334
- extras.push(this.parseBlocoGenerico("desconhecido"));
335
- break;
336
- case "vinculos":
337
- if (this.iniciaBlocoSimples("vinculos")) {
338
- vinculos = this.parseBlocoGenerico("vinculos");
339
- break;
340
- }
341
- extras.push(this.parseBlocoGenerico("desconhecido"));
342
- break;
343
- case "database":
344
- if (this.iniciaBlocoComNomeObrigatorio("database")) {
345
- databases.push(this.parseBlocoGenerico("database"));
346
- break;
347
- }
348
- extras.push(this.parseBlocoGenerico("desconhecido"));
349
- break;
350
- case "type":
351
- if (this.iniciaBlocoComNomeObrigatorio("type")) {
352
- types.push(this.parseType());
353
- break;
354
- }
355
- extras.push(this.parseBlocoGenerico("desconhecido"));
356
- break;
357
- case "entity":
358
- if (this.iniciaBlocoComNomeObrigatorio("entity")) {
359
- entities.push(this.parseEntity());
360
- break;
361
- }
362
- extras.push(this.parseBlocoGenerico("desconhecido"));
363
- break;
364
- case "enum":
365
- if (this.iniciaBlocoComNomeObrigatorio("enum")) {
366
- enums.push(this.parseEnum());
367
- break;
368
- }
369
- extras.push(this.parseBlocoGenerico("desconhecido"));
370
- break;
371
- case "task":
372
- if (this.iniciaBlocoComNomeObrigatorio("task")) {
373
- tasks.push(this.parseTask());
374
- break;
375
- }
376
- extras.push(this.parseBlocoGenerico("desconhecido"));
377
- break;
378
- case "flow":
379
- if (this.iniciaBlocoComNomeObrigatorio("flow")) {
380
- flows.push(this.parseFlow());
381
- break;
382
- }
383
- extras.push(this.parseBlocoGenerico("desconhecido"));
384
- break;
385
- case "route":
386
- if (this.iniciaBlocoComNomeObrigatorio("route")) {
387
- routes.push(this.parseRoute());
388
- break;
389
- }
390
- extras.push(this.parseBlocoGenerico("desconhecido"));
391
- break;
392
- case "worker":
393
- if (this.iniciaBlocoComNomeObrigatorio("worker")) {
394
- workers.push(this.parseBlocoGenerico("worker"));
395
- break;
396
- }
397
- extras.push(this.parseBlocoGenerico("desconhecido"));
398
- break;
399
- case "evento":
400
- if (this.iniciaBlocoComNomeObrigatorio("evento")) {
401
- eventos.push(this.parseBlocoGenerico("evento"));
402
- break;
403
- }
404
- extras.push(this.parseBlocoGenerico("desconhecido"));
405
- break;
406
- case "fila":
407
- if (this.iniciaBlocoComNomeObrigatorio("fila")) {
408
- filas.push(this.parseBlocoGenerico("fila"));
409
- break;
410
- }
411
- extras.push(this.parseBlocoGenerico("desconhecido"));
412
- break;
413
- case "cron":
414
- if (this.iniciaBlocoComNomeObrigatorio("cron")) {
415
- crons.push(this.parseBlocoGenerico("cron"));
416
- break;
417
- }
418
- extras.push(this.parseBlocoGenerico("desconhecido"));
419
- break;
420
- case "webhook":
421
- if (this.iniciaBlocoComNomeObrigatorio("webhook")) {
422
- webhooks.push(this.parseBlocoGenerico("webhook"));
423
- break;
424
- }
425
- extras.push(this.parseBlocoGenerico("desconhecido"));
426
- break;
427
- case "cache":
428
- if (this.iniciaBlocoComNomeObrigatorio("cache")) {
429
- caches.push(this.parseBlocoGenerico("cache"));
430
- break;
431
- }
432
- extras.push(this.parseBlocoGenerico("desconhecido"));
433
- break;
434
- case "storage":
435
- if (this.iniciaBlocoComNomeObrigatorio("storage")) {
436
- storages.push(this.parseBlocoGenerico("storage"));
437
- break;
438
- }
439
- extras.push(this.parseBlocoGenerico("desconhecido"));
440
- break;
441
- case "policy":
442
- if (this.iniciaBlocoComNomeObrigatorio("policy")) {
443
- policies.push(this.parseBlocoGenerico("policy"));
444
- break;
445
- }
446
- extras.push(this.parseBlocoGenerico("desconhecido"));
447
- break;
448
- case "state":
449
- if (this.iniciaBlocoState()) {
450
- states.push(this.parseState());
451
- break;
452
- }
453
- extras.push(this.parseBlocoGenerico("desconhecido"));
454
- break;
455
- case "tests":
456
- if (this.iniciaBlocoSimples("tests")) {
457
- tests = this.parseBlocoGenerico("tests");
458
- break;
459
- }
460
- extras.push(this.parseBlocoGenerico("desconhecido"));
461
- break;
462
- default:
463
- extras.push(this.parseBlocoGenerico("desconhecido"));
464
- break;
465
- }
466
- this.ignorarRuido();
467
- }
468
-
469
- const fim = this.consumirValor("}", "Era esperado fechar o bloco module com }.").intervalo.fim;
470
-
471
- return {
472
- tipo: "module",
473
- nome,
474
- uses,
475
- vinculos,
476
- docs,
477
- comments,
478
- databases,
479
- types,
480
- entities,
481
- enums,
482
- tasks,
483
- flows,
484
- routes,
485
- workers,
486
- eventos,
487
- filas,
488
- crons,
489
- webhooks,
490
- caches,
491
- storages,
492
- policies,
493
- states,
494
- tests,
495
- extras,
496
- intervalo: { inicio, fim },
497
- };
498
- }
499
-
500
- private parseUse(): UseAst {
501
- const inicio = this.avancar().intervalo.inicio;
502
- const primeiro = this.consumirTipo("identificador", "Era esperado o caminho do use.");
503
- let origem: UseAst["origem"] = "sema";
504
- let caminho = primeiro.valor;
505
-
506
- const origemNormalizada = normalizarOrigemUse(primeiro.valor);
507
- if (origemNormalizada && this.atual().tipo === "identificador") {
508
- origem = origemNormalizada;
509
- caminho = this.avancar().valor;
510
- }
511
-
512
- const fim = this.anterior().intervalo.fim;
513
- return { tipo: "use", origem, caminho, intervalo: { inicio, fim } };
514
- }
515
-
516
- private parseType(): TypeAst {
517
- const inicio = this.avancar().intervalo.inicio;
518
- const nome = this.consumirTipo("identificador", "Era esperado o nome do type.").valor;
519
- const corpo = this.parseBlocoComNomeOpcional("type");
520
- return { tipo: "type", nome, corpo, intervalo: { inicio, fim: corpo.intervalo?.fim ?? this.anterior().intervalo.fim } };
521
- }
522
-
523
- private parseEntity(): EntityAst {
524
- const inicio = this.avancar().intervalo.inicio;
525
- const nome = this.consumirTipo("identificador", "Era esperado o nome da entity.").valor;
526
- const corpo = this.parseBlocoComNomeOpcional("entity");
527
- return { tipo: "entity", nome, corpo, intervalo: { inicio, fim: corpo.intervalo?.fim ?? this.anterior().intervalo.fim } };
528
- }
529
-
530
- private parseEnum(): EnumAst {
531
- const inicio = this.avancar().intervalo.inicio;
532
- const nome = this.consumirTipo("identificador", "Era esperado o nome do enum.").valor;
533
- this.consumirValor("{", "Era esperado abrir o corpo do enum.");
534
- const valores: string[] = [];
535
- let docs: BlocoGenericoAst | undefined;
536
- while (this.atual().tipo !== "fim_arquivo" && this.atual().valor !== "}") {
537
- this.ignorarRuido();
538
- if (this.atual().valor === "}") {
539
- break;
540
- }
541
- if (this.atual().valor === "docs") {
542
- docs = this.parseBlocoGenerico("docs");
543
- continue;
544
- }
545
- if (["identificador", "palavra_chave"].includes(this.atual().tipo)) {
546
- valores.push(this.avancar().valor);
547
- if (this.atual().valor === ",") {
548
- this.avancar();
549
- }
550
- continue;
551
- }
552
- this.avancar();
553
- }
554
- const fim = this.consumirValor("}", "Era esperado fechar o enum.").intervalo.fim;
555
- return { tipo: "enum", nome, valores, docs, intervalo: { inicio, fim } };
556
- }
557
-
558
- private parseTask(): TaskAst {
559
- const inicio = this.avancar().intervalo.inicio;
560
- const nome = this.consumirTipo("identificador", "Era esperado o nome da task.").valor;
561
- const corpo = this.parseBlocoComNomeOpcional("task");
562
-
563
- const localizar = (palavraChave: PalavraBloco): BlocoGenericoAst | undefined =>
564
- corpo.blocos.find((bloco): bloco is BlocoGenericoAst => bloco.tipo === "bloco_generico" && bloco.palavraChave === palavraChave);
565
-
566
- return {
567
- tipo: "task",
568
- nome,
569
- corpo,
570
- input: localizar("input"),
571
- output: localizar("output"),
572
- rules: localizar("rules"),
573
- effects: localizar("effects"),
574
- impl: localizar("impl"),
575
- vinculos: localizar("vinculos"),
576
- execucao: localizar("execucao"),
577
- auth: localizar("auth"),
578
- authz: localizar("authz"),
579
- dados: localizar("dados"),
580
- audit: localizar("audit"),
581
- segredos: localizar("segredos"),
582
- forbidden: localizar("forbidden"),
583
- guarantees: localizar("guarantees"),
584
- state: localizar("state"),
585
- tests: localizar("tests"),
586
- error: localizar("error"),
587
- docs: localizar("docs"),
588
- comments: localizar("comments"),
589
- intervalo: { inicio, fim: corpo.intervalo?.fim ?? this.anterior().intervalo.fim },
590
- };
591
- }
592
-
593
- private parseFlow(): FlowAst {
594
- const inicio = this.avancar().intervalo.inicio;
595
- const nome = this.consumirTipo("identificador", "Era esperado o nome do flow.").valor;
596
- const corpo = this.parseBlocoComNomeOpcional("flow");
597
- const vinculos = corpo.blocos.find((bloco): bloco is BlocoGenericoAst => bloco.tipo === "bloco_generico" && bloco.palavraChave === "vinculos");
598
- return { tipo: "flow", nome, corpo, vinculos, intervalo: { inicio, fim: corpo.intervalo?.fim ?? this.anterior().intervalo.fim } };
599
- }
600
-
601
- private parseRoute(): RouteAst {
602
- const inicio = this.avancar().intervalo.inicio;
603
- const nome = this.consumirTipo("identificador", "Era esperado o nome da route.").valor;
604
- const corpo = this.parseBlocoComNomeOpcional("route");
605
- const vinculos = corpo.blocos.find((bloco): bloco is BlocoGenericoAst => bloco.tipo === "bloco_generico" && bloco.palavraChave === "vinculos");
606
- return { tipo: "route", nome, corpo, vinculos, intervalo: { inicio, fim: corpo.intervalo?.fim ?? this.anterior().intervalo.fim } };
607
- }
608
-
609
- private parseState(): StateAst {
610
- const inicioToken = this.avancar();
611
- let nome: string | undefined;
612
- if (this.atual().tipo === "identificador") {
613
- nome = this.avancar().valor;
614
- }
615
- this.consumirValor("{", "Era esperado abrir o bloco state.");
616
- const corpo = this.parseCorpoBloco("state", nome, inicioToken.intervalo.inicio);
617
- return {
618
- tipo: "state",
619
- nome,
620
- corpo,
621
- intervalo: { inicio: inicioToken.intervalo.inicio, fim: corpo.intervalo?.fim ?? this.anterior().intervalo.fim },
622
- };
623
- }
624
-
625
- private parseBlocoComNomeOpcional(nomeBloco: string): BlocoGenericoAst {
626
- this.consumirValor("{", `Era esperado abrir o bloco ${nomeBloco}.`);
627
- return this.parseCorpoBloco(nomeBloco as PalavraBloco | "type" | "entity" | "task" | "flow" | "route");
628
- }
629
-
630
- private parseBlocoGenerico(palavraChave: PalavraBloco | "desconhecido"): BlocoGenericoAst {
631
- const inicioToken = this.avancar();
632
- let nome: string | undefined;
633
- if (this.atual().tipo === "identificador") {
634
- nome = this.avancar().valor;
635
- }
636
- this.consumirValor("{", `Era esperado abrir o bloco ${inicioToken.valor}.`);
637
- return this.parseCorpoBloco((palavraChave === "desconhecido" ? "desconhecido" : inicioToken.valor) as BlocoGenericoAst["palavraChave"], nome, inicioToken.intervalo.inicio);
638
- }
639
-
640
- private parseBlocoNomeadoLivre(): BlocoGenericoAst {
641
- const inicioToken = this.avancar();
642
- const nome = inicioToken.valor;
643
- this.consumirValor("{", `Era esperado abrir o bloco ${nome}.`);
644
- return this.parseCorpoBloco("desconhecido", nome, inicioToken.intervalo.inicio);
645
- }
646
-
647
- private parseBlocoNomeadoComPalavraChaveLivre(): BlocoGenericoAst {
648
- const palavraChaveToken = this.avancar();
649
- const nomeToken = this.avancar();
650
- this.consumirValor("{", `Era esperado abrir o bloco ${palavraChaveToken.valor} ${nomeToken.valor}.`);
651
- return this.parseCorpoBloco(
652
- palavraChaveToken.valor as PalavraBloco,
653
- nomeToken.valor,
654
- palavraChaveToken.intervalo.inicio,
655
- );
656
- }
657
-
658
- private parseCorpoBloco(
659
- palavraChave: BlocoGenericoAst["palavraChave"],
660
- nome?: string,
661
- inicioManual?: IntervaloFonte["inicio"],
662
- ): BlocoGenericoAst {
663
- const inicio = inicioManual ?? this.anterior().intervalo.inicio;
664
- const campos: CampoAst[] = [];
665
- const linhas: BlocoGenericoAst["linhas"] = [];
666
- const blocos: BlocoAst[] = [];
667
-
668
- while (this.atual().tipo !== "fim_arquivo" && this.atual().valor !== "}") {
669
- this.ignorarRuido();
670
- if (this.atual().valor === "}") {
671
- break;
672
- }
673
-
674
- if (palavraChave === "tests" && this.atual().valor === "caso") {
675
- blocos.push(this.parseCasoTeste());
676
- continue;
677
- }
678
-
679
- if (this.iniciaSubblocoConhecido()) {
680
- blocos.push(this.parseBlocoGenerico(this.atual().valor as PalavraBloco));
681
- continue;
682
- }
683
-
684
- if (
685
- ["identificador", "palavra_chave"].includes(this.atual().tipo)
686
- && PALAVRAS_BLOCO_NOMEADO_LIVRE.has(this.atual().valor as PalavraBloco)
687
- && ["identificador", "palavra_chave"].includes(this.tokens[this.indice + 1]?.tipo ?? "")
688
- && this.tokens[this.indice + 2]?.valor === "{"
689
- ) {
690
- blocos.push(this.parseBlocoNomeadoComPalavraChaveLivre());
691
- continue;
692
- }
693
-
694
- if (["identificador", "palavra_chave"].includes(this.atual().tipo) && this.tokens[this.indice + 1]?.valor === "{") {
695
- blocos.push(this.parseBlocoNomeadoLivre());
696
- continue;
697
- }
698
-
699
- if (["identificador", "palavra_chave"].includes(this.atual().tipo) && this.tokens[this.indice + 1]?.valor === ":") {
700
- campos.push(this.parseCampo());
701
- continue;
702
- }
703
-
704
- const linha = this.parseLinhaDeclarativa();
705
- if (linha.conteudo.trim().length > 0) {
706
- linhas.push(linha);
707
- }
708
- }
709
-
710
- const fim = this.consumirValor("}", "Era esperado fechar o bloco com }.").intervalo.fim;
711
- return {
712
- tipo: "bloco_generico",
713
- palavraChave,
714
- nome,
715
- campos,
716
- linhas,
717
- blocos,
718
- intervalo: { inicio, fim },
719
- };
720
- }
721
-
722
- private parseCampo(): CampoAst {
723
- const inicio = this.atual().intervalo.inicio;
724
- const nome = this.avancar().valor;
725
- this.consumirValor(":", "Era esperado ':' depois do nome do campo.");
726
- const partes: Token[] = [];
727
- let profundidade = 0;
728
- while (this.atual().tipo !== "fim_arquivo" && this.atual().tipo !== "nova_linha" && this.atual().valor !== "}") {
729
- const proximoToken = this.tokens[this.indice + 1];
730
- const iniciaNovoCampo =
731
- profundidade === 0
732
- && partes.length > 0
733
- && ["identificador", "palavra_chave"].includes(this.atual().tipo)
734
- && proximoToken?.valor === ":";
735
-
736
- if (iniciaNovoCampo) {
737
- break;
738
- }
739
-
740
- const token = this.avancar();
741
- partes.push(token);
742
- if (["<", "[", "("].includes(token.valor)) {
743
- profundidade += 1;
744
- } else if ([">", "]", ")"].includes(token.valor)) {
745
- profundidade = Math.max(0, profundidade - 1);
746
- }
747
- }
748
- const segmentos = partes.filter((token) => token.valor.length > 0);
749
- const possuiTextoLiteral = segmentos.some((token) => token.tipo === "texto");
750
-
751
- if (possuiTextoLiteral) {
752
- const valorLiteral = segmentos.map((token) => token.tipo === "texto" ? decodificarTextoLiteral(token.valor) : token.valor).join(" ");
753
- if (this.atual().tipo === "nova_linha") {
754
- this.avancar();
755
- }
756
- return {
757
- tipo: "campo",
758
- nome,
759
- valor: valorLiteral,
760
- modificadores: [],
761
- intervalo: { inicio, fim: this.anterior().intervalo.fim },
762
- };
763
- }
764
-
765
- const tipoTokens: string[] = [];
766
- const modificadores: string[] = [];
767
- let profundidadeTipo = 0;
768
- let iniciouModificadores = false;
769
-
770
- for (const token of segmentos) {
771
- const segmento = token.valor;
772
- if (!iniciouModificadores) {
773
- if (["<", "[", "("].includes(segmento)) {
774
- profundidadeTipo += 1;
775
- tipoTokens.push(segmento);
776
- continue;
777
- }
778
- if ([">", "]", ")"].includes(segmento)) {
779
- profundidadeTipo = Math.max(0, profundidadeTipo - 1);
780
- tipoTokens.push(segmento);
781
- continue;
782
- }
783
-
784
- const pareceModificador =
785
- profundidadeTipo === 0
786
- && tipoTokens.length > 0
787
- && /^[a-z_][a-z0-9_]*$/u.test(segmento);
788
-
789
- if (pareceModificador) {
790
- iniciouModificadores = true;
791
- modificadores.push(segmento);
792
- continue;
793
- }
794
-
795
- tipoTokens.push(segmento);
796
- continue;
797
- }
798
-
799
- modificadores.push(segmento);
800
- }
801
-
802
- let valor = tipoTokens
803
- .join(" ")
804
- .replace(/\s*([<>\[\](),|?])\s*/g, "$1")
805
- .trim();
806
- if (valor.includes("/")) {
807
- valor = valor.replace(/\s*\/\s*/g, "/");
808
- }
809
- if (this.atual().tipo === "nova_linha") {
810
- this.avancar();
811
- }
812
- return {
813
- tipo: "campo",
814
- nome,
815
- valor,
816
- modificadores,
817
- intervalo: { inicio, fim: this.anterior().intervalo.fim },
818
- };
819
- }
820
-
821
- private parseLinhaDeclarativa() {
822
- const inicio = this.atual().intervalo.inicio;
823
- const partes: string[] = [];
824
- while (this.atual().tipo !== "fim_arquivo" && this.atual().tipo !== "nova_linha" && this.atual().valor !== "}") {
825
- partes.push(this.avancar().valor);
826
- }
827
- if (this.atual().tipo === "nova_linha") {
828
- this.avancar();
829
- }
830
- return {
831
- tipo: "linha_declarativa" as const,
832
- conteudo: partes.join(" ").trim(),
833
- intervalo: { inicio, fim: this.anterior().intervalo.fim },
834
- };
835
- }
836
-
837
- private parseCasoTeste(): BlocoCasoTesteAst {
838
- const inicio = this.avancar().intervalo.inicio;
839
- const nomeToken = this.atual();
840
- const nome =
841
- nomeToken.tipo === "texto"
842
- ? this.avancar().valor
843
- : this.consumirTipo("identificador", "Era esperado o nome textual do caso de teste.").valor;
844
- this.consumirValor("{", "Era esperado abrir o bloco do caso de teste.");
845
- let given: BlocoGenericoAst | undefined;
846
- let when: BlocoGenericoAst | undefined;
847
- let expect: BlocoGenericoAst | undefined;
848
- let error: BlocoGenericoAst | undefined;
849
- let docs: BlocoGenericoAst | undefined;
850
- let comments: BlocoGenericoAst | undefined;
851
-
852
- while (this.atual().tipo !== "fim_arquivo" && this.atual().valor !== "}") {
853
- this.ignorarRuido();
854
- if (this.atual().valor === "}") {
855
- break;
856
- }
857
- switch (this.atual().valor) {
858
- case "given":
859
- given = this.parseBlocoGenerico("given");
860
- break;
861
- case "when":
862
- when = this.parseBlocoGenerico("when");
863
- break;
864
- case "expect":
865
- expect = this.parseBlocoGenerico("expect");
866
- break;
867
- case "error":
868
- error = this.parseBlocoGenerico("error");
869
- break;
870
- case "docs":
871
- docs = this.parseBlocoGenerico("docs");
872
- break;
873
- case "comments":
874
- comments = this.parseBlocoGenerico("comments");
875
- break;
876
- default:
877
- this.avancar();
878
- break;
879
- }
880
- }
881
-
882
- const fim = this.consumirValor("}", "Era esperado fechar o caso de teste.").intervalo.fim;
883
- return {
884
- tipo: "caso_teste",
885
- nome,
886
- given,
887
- when,
888
- expect,
889
- error,
890
- docs,
891
- comments,
892
- intervalo: { inicio, fim },
893
- };
894
- }
895
- }
896
-
897
- function normalizarOrigemUse(valor: string): UseAst["origem"] | undefined {
898
- switch (valor.toLowerCase()) {
899
- case "sema":
900
- return "sema";
901
- case "ts":
902
- case "typescript":
903
- return "ts";
904
- case "py":
905
- case "python":
906
- return "py";
907
- case "dart":
908
- return "dart";
909
- case "lua":
910
- return "lua";
911
- case "cs":
912
- case "csharp":
913
- case "dotnet":
914
- return "cs";
915
- case "java":
916
- return "java";
917
- case "go":
918
- case "golang":
919
- return "go";
920
- case "rust":
921
- case "rs":
922
- return "rust";
923
- case "cpp":
924
- case "cxx":
925
- case "cc":
926
- case "c++":
927
- return "cpp";
928
- default:
929
- return undefined;
930
- }
931
- }
932
-
933
- export function parsear(tokens: Token[]): ResultadoParser {
934
- const parser = new Parser(tokens);
935
- return parser.analisar();
936
- }