@semacode/cli 3.0.0 → 3.8.0
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.
- package/dist/agentEntryPoints.js +78 -64
- package/dist/cliGrammar.js +5 -5
- package/dist/cliHelpTexto.js +6 -6
- package/dist/docs.part01.d.ts +4 -1
- package/dist/docs.part01.js +8 -0
- package/dist/docs.part02.js +9 -1
- package/dist/drift.part01.d.ts +8 -2
- package/dist/drift.part04.d.ts +14 -2
- package/dist/drift.part04.js +35 -2
- package/dist/drift.part05.d.ts +6 -0
- package/dist/drift.part05.js +68 -0
- package/dist/drift.part06.js +60 -3
- package/dist/drift.part09.d.ts +2 -2
- package/dist/drift.part09.js +13 -3
- package/dist/drift.part11.js +24 -3
- package/dist/drift.part14.js +4 -0
- package/dist/exemplosOficiais.d.ts +2 -1
- package/dist/exemplosOficiais.js +9 -3
- package/dist/geracaoCore.d.ts +1 -0
- package/dist/geracaoCore.js +5 -0
- package/dist/importador.part01.d.ts +1 -1
- package/dist/importador.part04.d.ts +5 -1
- package/dist/importador.part04.js +40 -2
- package/dist/importador.part06.d.ts +2 -0
- package/dist/importador.part06.js +97 -1
- package/dist/importador.part09.js +17 -2
- package/dist/index.part04.js +13 -6
- package/dist/index.part07.d.ts +8 -2
- package/dist/index.part07.js +146 -4
- package/dist/index.part08.js +3 -3
- package/dist/initCommand.d.ts +1 -0
- package/dist/initCommand.js +15 -3
- package/dist/initTemplatesBase.js +78 -78
- package/dist/projetoConfig.js +5 -0
- package/dist/projetoLegado.js +40 -0
- package/dist/tipos.d.ts +1 -1
- package/dist/typescript-http-body.js +9 -0
- package/dist/typescript-http-modelos.d.ts +1 -1
- package/dist/typescript-http-rotas.d.ts +1 -0
- package/dist/typescript-http-rotas.js +198 -0
- package/dist/typescript-http-semantica.d.ts +3 -3
- package/dist/typescript-http-semantica.js +65 -7
- package/dist/typescript-http.d.ts +1 -1
- package/dist/typescript-http.js +1 -1
- package/dist/verificacaoCache.d.ts +25 -0
- package/dist/verificacaoCache.js +80 -0
- package/docs/syntax.md +14 -0
- package/exemplos/express_crud.sema +139 -0
- package/exemplos/fastify_crud.sema +146 -0
- package/exemplos/koa_crud.sema +95 -0
- package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js +37 -38
- package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +1 -0
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.d.ts +7 -0
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js +33 -10
- package/package.json +1 -1
package/dist/drift.part05.js
CHANGED
|
@@ -120,6 +120,74 @@ export function arquivoEhRotasFlutterConsumer(relacaoArquivo, codigo) {
|
|
|
120
120
|
return /(?:^|\/)(?:lib\/)?(?:router|app_router|routes)\.dart$/i.test(relacao)
|
|
121
121
|
|| /MaterialApp(?:\.router)?\s*\(|CupertinoApp(?:\.router)?\s*\(|GoRouter\s*\(/.test(codigo ?? "");
|
|
122
122
|
}
|
|
123
|
+
export function arquivoEhBridgeSvelteKitConsumer(relacaoArquivo) {
|
|
124
|
+
const relacao = normalizarRelacaoConsumer(relacaoArquivo);
|
|
125
|
+
return /(?:^|\/)(?:src\/)?lib\/(?:sema_consumer_bridge|sema\/.+)\.(?:ts|js)$/i.test(relacao);
|
|
126
|
+
}
|
|
127
|
+
export function arquivoEhSuperficieSvelteKitConsumer(relacaoArquivo) {
|
|
128
|
+
const relacao = normalizarRelacaoConsumer(relacaoArquivo);
|
|
129
|
+
return /(?:^|\/)(?:src\/)?routes\/(?:[^/]+\/)*\+(?:page|layout|error|server)\.(?:svelte|ts|js)$/i.test(relacao);
|
|
130
|
+
}
|
|
131
|
+
export function inferirRotaSvelteKitConsumer(relacaoArquivo) {
|
|
132
|
+
const relacao = normalizarRelacaoConsumer(relacaoArquivo);
|
|
133
|
+
const segmentos = relacao.split("/");
|
|
134
|
+
const indiceSrcRoutes = segmentos.findIndex((segmento, indice) => segmento === "src" && segmentos[indice + 1] === "routes");
|
|
135
|
+
const indiceRoutes = segmentos.findIndex((segmento) => segmento === "routes");
|
|
136
|
+
const inicioRoutes = indiceSrcRoutes >= 0 ? indiceSrcRoutes + 2 : indiceRoutes >= 0 ? indiceRoutes + 1 : -1;
|
|
137
|
+
if (inicioRoutes < 0) {
|
|
138
|
+
return undefined;
|
|
139
|
+
}
|
|
140
|
+
const arquivoFinal = segmentos.at(-1) ?? "";
|
|
141
|
+
const tipoArquivo = arquivoFinal.match(/^\+(page|layout|error|server)\.(?:svelte|ts|js)$/i)?.[1]?.toLowerCase();
|
|
142
|
+
if (!tipoArquivo) {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
rota: montarRotaConsumer(segmentos.slice(inicioRoutes, -1)),
|
|
147
|
+
arquivo: relacaoArquivo,
|
|
148
|
+
tipoArquivo,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export function arquivoEhBridgeNuxtConsumer(relacaoArquivo) {
|
|
152
|
+
const relacao = normalizarRelacaoConsumer(relacaoArquivo);
|
|
153
|
+
return /(?:^|\/)(?:app\/)?composables\/(?:sema_consumer_bridge|sema\/.+)\.(?:ts|js)$/i.test(relacao);
|
|
154
|
+
}
|
|
155
|
+
export function arquivoEhSuperficieNuxtConsumer(relacaoArquivo) {
|
|
156
|
+
const relacao = normalizarRelacaoConsumer(relacaoArquivo);
|
|
157
|
+
return /^(?:app\/)?pages\/.+\.vue$/i.test(relacao)
|
|
158
|
+
|| /(?:^|\/)server\/api\/.+\.(?:get|post|put|patch|delete|head)\.(?:ts|js)$/i.test(relacao);
|
|
159
|
+
}
|
|
160
|
+
export function inferirRotaNuxtConsumer(relacaoArquivo) {
|
|
161
|
+
const relacao = normalizarRelacaoConsumer(relacaoArquivo);
|
|
162
|
+
const segmentos = relacao.split("/");
|
|
163
|
+
const indiceServer = segmentos.findIndex((segmento, indice) => segmento === "server" && segmentos[indice + 1] === "api");
|
|
164
|
+
if (indiceServer >= 0) {
|
|
165
|
+
const arquivoFinal = segmentos.at(-1) ?? "";
|
|
166
|
+
const metodo = arquivoFinal.match(/\.(get|post|put|patch|delete|head)\.(?:ts|js)$/i)?.[1]?.toUpperCase();
|
|
167
|
+
const nomeBase = arquivoFinal.replace(/\.(?:get|post|put|patch|delete|head)?\.(?:ts|js)$/i, "");
|
|
168
|
+
const caminhoAteArquivo = segmentos.slice(indiceServer + 1, -1);
|
|
169
|
+
return {
|
|
170
|
+
rota: montarRotaConsumer(nomeBase === "index" ? caminhoAteArquivo : [...caminhoAteArquivo, nomeBase]),
|
|
171
|
+
arquivo: relacaoArquivo,
|
|
172
|
+
tipoArquivo: metodo ?? "server",
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
const indicePages = segmentos.findIndex((segmento, indice) => segmento === "pages" && (indice === 0 || segmentos[indice - 1] === "app"));
|
|
176
|
+
if (indicePages < 0) {
|
|
177
|
+
return undefined;
|
|
178
|
+
}
|
|
179
|
+
const arquivoFinal = segmentos.at(-1) ?? "";
|
|
180
|
+
if (!arquivoFinal.endsWith(".vue")) {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
const nomeBase = arquivoFinal.replace(/\.vue$/i, "");
|
|
184
|
+
const caminhoAteArquivo = segmentos.slice(indicePages + 1, -1);
|
|
185
|
+
return {
|
|
186
|
+
rota: montarRotaConsumer(nomeBase === "index" ? caminhoAteArquivo : [...caminhoAteArquivo, nomeBase]),
|
|
187
|
+
arquivo: relacaoArquivo,
|
|
188
|
+
tipoArquivo: "page",
|
|
189
|
+
};
|
|
190
|
+
}
|
|
123
191
|
export function inferirRotaNextJsConsumer(relacaoArquivo) {
|
|
124
192
|
const relacao = normalizarRelacaoConsumer(relacaoArquivo);
|
|
125
193
|
const segmentos = relacao.split("/");
|
package/dist/drift.part06.js
CHANGED
|
@@ -5,7 +5,7 @@ import path from "node:path";
|
|
|
5
5
|
import ts from "typescript";
|
|
6
6
|
import { coletarSuperficiesAngularStandaloneConsumer } from "./angular-consumer-standalone.js";
|
|
7
7
|
import { extrairRotasTypeScriptHttp } from "./typescript-http.js";
|
|
8
|
-
import { arquivoEhRotasAngularConsumer, arquivoEhRotasAngularConsumerRaiz, arquivoEhRotasReactViteConsumer, arquivoEhSuperficieNextJsConsumer, arquivoEhSuperficieReactViteConsumer, extrairRotasAngularConsumer, extrairRotasReactViteConsumer, inferirRotaNextJsConsumer, inferirRotaReactViteConsumer, normalizarRelacaoConsumer, registrarAtribuicaoPrototypeTypeScript, registrarMetodosObjectAssignTypeScript } from "./drift.part05.js";
|
|
8
|
+
import { arquivoEhRotasAngularConsumer, arquivoEhRotasAngularConsumerRaiz, arquivoEhRotasReactViteConsumer, arquivoEhSuperficieNextJsConsumer, arquivoEhSuperficieNuxtConsumer, arquivoEhSuperficieReactViteConsumer, arquivoEhSuperficieSvelteKitConsumer, extrairRotasAngularConsumer, extrairRotasReactViteConsumer, inferirRotaNextJsConsumer, inferirRotaNuxtConsumer, inferirRotaReactViteConsumer, inferirRotaSvelteKitConsumer, normalizarRelacaoConsumer, registrarAtribuicaoPrototypeTypeScript, registrarMetodosObjectAssignTypeScript } from "./drift.part05.js";
|
|
9
9
|
import { caminhosSimbolicos, chaveCaminhoCanonicoDrift, deduplicarRaizesSobrepostasDrift, desembrulharExpressaoTypeScript, extrairNomeClassePrototypeTypeScript, extrairTextoLiteral, juntarCaminhoHttp, lerDecorator, listarArquivosRecursivos, registrarSimboloTypeScript, } from "./drift.part04.js";
|
|
10
10
|
import { extrairRecursosPersistenciaCodigoVivo, registrarRecursoDrift } from "./drift.part03.js";
|
|
11
11
|
export function inferirConsumerFrameworkPrincipal(fontesLegado, consumerSurfaces, consumerBridges) {
|
|
@@ -31,7 +31,14 @@ export function inferirConsumerFrameworkPrincipal(fontesLegado, consumerSurfaces
|
|
|
31
31
|
|| /(?:^|\/)(?:lib\/)?(?:router|app_router|routes|main)\.dart$/i.test(arquivo))) {
|
|
32
32
|
return "flutter-consumer";
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
if (arquivos.some((arquivo) => /(?:^|\/)(?:src\/)?routes\/(?:[^/]+\/)*\+(?:page|layout|error|server)\.(?:svelte|ts|js)$/i.test(arquivo))) {
|
|
35
|
+
return "sveltekit-consumer";
|
|
36
|
+
}
|
|
37
|
+
if (arquivos.some((arquivo) => /^(?:app\/)?pages\/.+\.vue$/i.test(arquivo)
|
|
38
|
+
|| /(?:^|\/)server\/api\/.+\.(?:get|post|put|patch|delete|head)\.(?:ts|js)$/i.test(arquivo))) {
|
|
39
|
+
return "nuxt-consumer";
|
|
40
|
+
}
|
|
41
|
+
for (const framework of ["nextjs-consumer", "react-vite-consumer", "angular-consumer", "flutter-consumer", "sveltekit-consumer", "nuxt-consumer"]) {
|
|
35
42
|
if (fontesLegado.includes(framework)) {
|
|
36
43
|
return framework;
|
|
37
44
|
}
|
|
@@ -203,8 +210,50 @@ export async function indexarTypeScript(diretorios, adaptadorLeitura) {
|
|
|
203
210
|
const consumerSurfaces = new Map();
|
|
204
211
|
const sourceFiles = new Map();
|
|
205
212
|
const arquivosProcessados = new Set();
|
|
213
|
+
const registrarSuperficieSvelteKitDrift = (relacao, arquivo) => {
|
|
214
|
+
const superficie = arquivoEhSuperficieSvelteKitConsumer(relacao)
|
|
215
|
+
? inferirRotaSvelteKitConsumer(relacao)
|
|
216
|
+
: undefined;
|
|
217
|
+
if (!superficie) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
consumerSurfaces.set(`${superficie.rota}:${arquivo}:${superficie.tipoArquivo}`, {
|
|
221
|
+
rota: superficie.rota,
|
|
222
|
+
arquivo,
|
|
223
|
+
tipoArquivo: superficie.tipoArquivo,
|
|
224
|
+
});
|
|
225
|
+
rotas.push({
|
|
226
|
+
origem: "sveltekit-consumer",
|
|
227
|
+
metodo: superficie.tipoArquivo === "server" ? "GET" : "VIEW",
|
|
228
|
+
caminho: superficie.rota,
|
|
229
|
+
arquivo,
|
|
230
|
+
simbolo: superficie.tipoArquivo,
|
|
231
|
+
});
|
|
232
|
+
};
|
|
233
|
+
const registrarSuperficieNuxtDrift = (relacao, arquivo) => {
|
|
234
|
+
const superficie = arquivoEhSuperficieNuxtConsumer(relacao)
|
|
235
|
+
? inferirRotaNuxtConsumer(relacao)
|
|
236
|
+
: undefined;
|
|
237
|
+
if (!superficie) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
consumerSurfaces.set(`${superficie.rota}:${arquivo}:${superficie.tipoArquivo}`, {
|
|
241
|
+
rota: superficie.rota,
|
|
242
|
+
arquivo,
|
|
243
|
+
tipoArquivo: superficie.tipoArquivo,
|
|
244
|
+
});
|
|
245
|
+
rotas.push({
|
|
246
|
+
origem: "nuxt-consumer",
|
|
247
|
+
metodo: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"].includes(superficie.tipoArquivo)
|
|
248
|
+
? superficie.tipoArquivo
|
|
249
|
+
: "VIEW",
|
|
250
|
+
caminho: superficie.rota,
|
|
251
|
+
arquivo,
|
|
252
|
+
simbolo: superficie.tipoArquivo,
|
|
253
|
+
});
|
|
254
|
+
};
|
|
206
255
|
for (const diretorio of deduplicarRaizesSobrepostasDrift(diretorios)) {
|
|
207
|
-
const arquivos = (await listarArquivosRecursivos(diretorio, [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"], adaptadorLeitura))
|
|
256
|
+
const arquivos = (await listarArquivosRecursivos(diretorio, [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".vue", ".svelte"], adaptadorLeitura))
|
|
208
257
|
.filter((arquivo) => !arquivo.endsWith(".d.ts")
|
|
209
258
|
&& !arquivo.endsWith(".spec.ts")
|
|
210
259
|
&& !arquivo.endsWith(".test.ts"))
|
|
@@ -228,6 +277,12 @@ export async function indexarTypeScript(diretorios, adaptadorLeitura) {
|
|
|
228
277
|
const codigo = adaptadorLeitura
|
|
229
278
|
? await adaptadorLeitura.lerTexto(arquivo)
|
|
230
279
|
: await readFile(arquivo, "utf8");
|
|
280
|
+
if (/\.(?:vue|svelte)$/i.test(arquivo)) {
|
|
281
|
+
const relacaoSuperficie = path.relative(diretorio, arquivo);
|
|
282
|
+
registrarSuperficieSvelteKitDrift(relacaoSuperficie, arquivo);
|
|
283
|
+
registrarSuperficieNuxtDrift(relacaoSuperficie, arquivo);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
231
286
|
const origemArquivo = /\.(?:js|jsx|mjs|cjs)$/i.test(arquivo) ? "js" : "ts";
|
|
232
287
|
const scriptKind = arquivo.endsWith(".tsx")
|
|
233
288
|
? ts.ScriptKind.TSX
|
|
@@ -287,6 +342,8 @@ export async function indexarTypeScript(diretorios, adaptadorLeitura) {
|
|
|
287
342
|
simbolo: superficieReact.tipoArquivo,
|
|
288
343
|
});
|
|
289
344
|
}
|
|
345
|
+
registrarSuperficieSvelteKitDrift(relacao, arquivo);
|
|
346
|
+
registrarSuperficieNuxtDrift(relacao, arquivo);
|
|
290
347
|
if (fonteDeclaraRotasReactVite(relacao, sourceFile)) {
|
|
291
348
|
for (const rotaReact of extrairRotasReactViteConsumer(relacao, codigo)) {
|
|
292
349
|
consumerSurfaces.set(`${rotaReact.rota}:${arquivo}:router`, {
|
package/dist/drift.part09.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { OpcoesDriftLegado, OrigemCodigoDrift, RecursoResolvido, RegistroPersist
|
|
|
5
5
|
import { indexarPersistenciaDetalhada } from "./drift.part08.js";
|
|
6
6
|
export declare function analisarPersistenciaReal(contexto: ContextoProjetoCarregado, mapaRecursos?: Map<string, RecursoResolvido[]>, detalhesPersistencia?: Awaited<ReturnType<typeof indexarPersistenciaDetalhada>>, opcoes?: OpcoesDriftLegado, mapaImpl?: Map<string, SimboloResolvido>): Promise<RegistroPersistenciaRealDrift[]>;
|
|
7
7
|
export declare function normalizarCaminhoRota(caminho?: string): string;
|
|
8
|
-
export declare function extrairFontesHttpTypeScript(fontesLegado: FonteLegado[]): Array<"nestjs" | "nextjs" | "firebase">;
|
|
8
|
+
export declare function extrairFontesHttpTypeScript(fontesLegado: FonteLegado[]): Array<"nestjs" | "nextjs" | "firebase" | "express" | "fastify" | "koa">;
|
|
9
9
|
export declare function extrairFontesHttpBackend(fontesLegado: FonteLegado[]): Array<"dotnet" | "java" | "go" | "rust" | "php">;
|
|
10
10
|
export declare function ultimoSegmentoSimbolico(caminho: string): string;
|
|
11
11
|
export declare function pontuarCandidatoDeclarado(candidato: SimboloResolvido, origem: OrigemCodigoDrift, caminhoDeclarado: string): SimboloCandidatoDrift | undefined;
|
|
@@ -14,7 +14,7 @@ export declare function deduplicarCandidatos(candidatos: SimboloCandidatoDrift[]
|
|
|
14
14
|
export declare function ordenarCandidatos(candidatos: SimboloCandidatoDrift[]): SimboloCandidatoDrift[];
|
|
15
15
|
export declare function sugerirCandidatosParaImpl(simbolos: SimboloResolvido[], origem: OrigemCodigoDrift, caminhoDeclarado: string): SimboloCandidatoDrift[];
|
|
16
16
|
export declare function sugerirCandidatosParaTaskSemImpl(simbolos: SimboloResolvido[], nomeTask: string): SimboloCandidatoDrift[];
|
|
17
|
-
export declare function escolherRotasEsperadas(task: IrTask, fontesLegado: FonteLegado[]): Array<"nestjs" | "fastapi" | "flask" | "nextjs" | "firebase" | "dotnet" | "java" | "go" | "rust" | "php">;
|
|
17
|
+
export declare function escolherRotasEsperadas(task: IrTask, fontesLegado: FonteLegado[]): Array<"nestjs" | "express" | "fastify" | "koa" | "fastapi" | "flask" | "nextjs" | "firebase" | "dotnet" | "java" | "go" | "rust" | "php">;
|
|
18
18
|
export declare function taskEhBridgeFirebase(task: IrTask): boolean;
|
|
19
19
|
export declare function tiposAceitosParaRecursoPersistencia(recurso: IrRecursoPersistencia): TipoRecursoDrift[];
|
|
20
20
|
export declare function nomesRecursoPersistencia(recurso: IrRecursoPersistencia): string[];
|
package/dist/drift.part09.js
CHANGED
|
@@ -80,13 +80,14 @@ export function normalizarCaminhoRota(caminho) {
|
|
|
80
80
|
if (!caminho) {
|
|
81
81
|
return "/";
|
|
82
82
|
}
|
|
83
|
-
const limpo = normalizarCaminhoFlask(caminho.trim().replace(/\s*\/\s*/g, "/"))
|
|
83
|
+
const limpo = normalizarCaminhoFlask(caminho.trim().replace(/\s*\/\s*/g, "/"))
|
|
84
|
+
.replace(/:([A-Za-z_]\w*)/g, "{$1}");
|
|
84
85
|
const comBarra = limpo.startsWith("/") ? limpo : `/${limpo}`;
|
|
85
86
|
const normalizado = comBarra.replace(/\/+/g, "/");
|
|
86
87
|
return normalizado.endsWith("/") && normalizado !== "/" ? normalizado.slice(0, -1) : normalizado;
|
|
87
88
|
}
|
|
88
89
|
export function extrairFontesHttpTypeScript(fontesLegado) {
|
|
89
|
-
return fontesLegado.filter((fonte) => fonte === "nestjs" || fonte === "nextjs" || fonte === "firebase");
|
|
90
|
+
return fontesLegado.filter((fonte) => fonte === "nestjs" || fonte === "nextjs" || fonte === "firebase" || fonte === "express" || fonte === "fastify" || fonte === "koa");
|
|
90
91
|
}
|
|
91
92
|
export function extrairFontesHttpBackend(fontesLegado) {
|
|
92
93
|
return fontesLegado.filter((fonte) => fonte === "dotnet" || fonte === "java" || fonte === "go" || fonte === "rust" || fonte === "php");
|
|
@@ -227,13 +228,22 @@ export function escolherRotasEsperadas(task, fontesLegado) {
|
|
|
227
228
|
if (fontesTs.includes("firebase") && /(apps\.worker|worker|sema_contract_bridge|health)/i.test(implTsOuJs.caminho)) {
|
|
228
229
|
esperadas.add("firebase");
|
|
229
230
|
}
|
|
231
|
+
if (/\bexpress\b|\broutes?\b|\brouter\b/i.test(implTsOuJs.caminho) && fontesTs.includes("express")) {
|
|
232
|
+
esperadas.add("express");
|
|
233
|
+
}
|
|
234
|
+
if (/\bfastify\b/i.test(implTsOuJs.caminho) && fontesTs.includes("fastify")) {
|
|
235
|
+
esperadas.add("fastify");
|
|
236
|
+
}
|
|
237
|
+
if (/\bkoa\b/i.test(implTsOuJs.caminho) && fontesTs.includes("koa")) {
|
|
238
|
+
esperadas.add("koa");
|
|
239
|
+
}
|
|
230
240
|
if (esperadas.size > 0) {
|
|
231
241
|
return [...esperadas];
|
|
232
242
|
}
|
|
233
243
|
if (fontesTs.length > 0) {
|
|
234
244
|
return fontesTs;
|
|
235
245
|
}
|
|
236
|
-
return ["nestjs", "nextjs", "firebase"];
|
|
246
|
+
return ["nestjs", "nextjs", "firebase", "express", "fastify", "koa"];
|
|
237
247
|
}
|
|
238
248
|
if (task.implementacoesExternas.some((impl) => impl.origem === "py")) {
|
|
239
249
|
const fontesPython = fontesLegado.filter((fonte) => fonte === "fastapi" || fonte === "flask");
|
package/dist/drift.part11.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// SEMA-GOVERNED: sema.governanca_ia_contexto, sema.produto.governanca_ia.drift.cache.store
|
|
2
2
|
// Descrição: integra índices calculados ou reutilizados e sempre recalcula o resultado final do drift.
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import { resolverAlvoPadrao, resolverEstruturaSaidaPadrao, resolverFrameworkPadrao } from "./projeto.js";
|
|
4
5
|
import { emitirDiagnosticosArquivosOrcamento, workspaceExigeCabecalhoCodigoGovernado, } from "./driftOrcamento.js";
|
|
5
6
|
import { definirDiretoriosIgnoradosAtivos, obterDiretoriosIgnoradosAtivos, extrairTermosEscopoDrift, resolverDiretoriosIgnoradosAtivos, resolverOpcoesDrift } from "./drift.part01.js";
|
|
6
7
|
import { construirContextoRelevanciaConsumer, filtrarConsumerSurfacesPorEscopo } from "./drift.part02.js";
|
|
7
8
|
import { inferirConsumerFrameworkPrincipal } from "./drift.part06.js";
|
|
8
|
-
import { calcularConfiancaTask, calcularRiscoOperacional, calcularScoreTask, chaveCaminhoCanonicoDrift, encontrarCandidatosFisicosImplementacaoDrift, resumirLacunasTask, resumirOperacional } from "./drift.part04.js";
|
|
9
|
+
import { calcularConfiancaTask, calcularRiscoOperacional, calcularScoreTask, carregarEvidenciaVerificacaoDrift, chaveCaminhoCanonicoDrift, encontrarCandidatosFisicosImplementacaoDrift, resumirLacunasTask, resumirOperacional } from "./drift.part04.js";
|
|
9
10
|
import { analisarPersistenciaReal, ordenarCandidatos } from "./drift.part09.js";
|
|
10
11
|
import { simboloEhBridgeConsumer } from "./drift.part05.js";
|
|
11
12
|
import { prepararIndicesDrift } from "./drift.part13.js";
|
|
@@ -275,6 +276,24 @@ export async function analisarDriftLegado(contexto, opcoes) {
|
|
|
275
276
|
bloqueiosAnalise.add("escopo_estreito_ambiguo");
|
|
276
277
|
}
|
|
277
278
|
configuracaoEscopo.bloqueios = [...bloqueiosAnalise];
|
|
279
|
+
const evidenciaPorModulo = new Map();
|
|
280
|
+
for (const item of contexto.modulosSelecionados) {
|
|
281
|
+
const nomeModulo = item.resultado.ir?.nome;
|
|
282
|
+
if (!nomeModulo) {
|
|
283
|
+
continue;
|
|
284
|
+
}
|
|
285
|
+
const frameworkVerificacao = resolverFrameworkPadrao(undefined, contexto.configCarregada);
|
|
286
|
+
const evidencia = await carregarEvidenciaVerificacaoDrift({
|
|
287
|
+
caminhoContrato: item.caminho,
|
|
288
|
+
nomeModulo,
|
|
289
|
+
alvo: resolverAlvoPadrao(undefined, contexto.configCarregada),
|
|
290
|
+
framework: frameworkVerificacao,
|
|
291
|
+
estrutura: resolverEstruturaSaidaPadrao(undefined, frameworkVerificacao, contexto.configCarregada),
|
|
292
|
+
});
|
|
293
|
+
if (evidencia) {
|
|
294
|
+
evidenciaPorModulo.set(nomeModulo, evidencia);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
278
297
|
for (const resumo of tasksResumo) {
|
|
279
298
|
const chaveTask = `${resumo.modulo}:${resumo.task}`;
|
|
280
299
|
const task = taskPorChave.get(chaveTask);
|
|
@@ -304,8 +323,10 @@ export async function analisarDriftLegado(contexto, opcoes) {
|
|
|
304
323
|
}
|
|
305
324
|
resumo.confiancaVinculo = calcularConfiancaTask(task, resumo.implsValidos, resumo.implsQuebrados, resumoVinculos.validos, resumoVinculos.quebrados);
|
|
306
325
|
resumo.riscoOperacional = calcularRiscoOperacional(task);
|
|
307
|
-
|
|
308
|
-
resumo.
|
|
326
|
+
const evidenciaVerificada = evidenciaPorModulo.get(resumo.modulo);
|
|
327
|
+
resumo.lacunas = resumirLacunasTask(task, resumo.semImplementacao, resumo.implsQuebrados, resumoVinculos.quebrados, guardrails, evidenciaVerificada);
|
|
328
|
+
resumo.scoreSemantico = calcularScoreTask(task, resumo.implsValidos, resumo.implsQuebrados, resumoVinculos.validos, resumoVinculos.quebrados, resumo.semImplementacao, evidenciaVerificada);
|
|
329
|
+
resumo.evidenciaVerificacao = evidenciaVerificada;
|
|
309
330
|
resumo.ancoragemVinculo = task.vinculos.length > 0
|
|
310
331
|
? "propria"
|
|
311
332
|
: arquivosAncoraHerdados.length > 0
|
package/dist/drift.part14.js
CHANGED
|
@@ -277,6 +277,8 @@ export function analisarModulosSelecionadosDrift(estado) {
|
|
|
277
277
|
&& rotaResolvida.origem !== "react-vite-consumer"
|
|
278
278
|
&& rotaResolvida.origem !== "angular-consumer"
|
|
279
279
|
&& rotaResolvida.origem !== "flutter-consumer"
|
|
280
|
+
&& rotaResolvida.origem !== "sveltekit-consumer"
|
|
281
|
+
&& rotaResolvida.origem !== "nuxt-consumer"
|
|
280
282
|
&& esperadas.includes(rotaResolvida.origem));
|
|
281
283
|
const combina = encontradas.some((rotaResolvida) => rotaResolvida.metodo === route.metodo
|
|
282
284
|
&& normalizarCaminhoRota(rotaResolvida.caminho) === normalizarCaminhoRota(route.caminho));
|
|
@@ -286,6 +288,7 @@ export function analisarModulosSelecionadosDrift(estado) {
|
|
|
286
288
|
route: route.nome,
|
|
287
289
|
metodo: route.metodo,
|
|
288
290
|
caminho: route.caminho,
|
|
291
|
+
frameworksEsperados: [...esperadas],
|
|
289
292
|
motivo: `Nenhuma rota publica ${route.metodo} ${route.caminho} foi encontrada no codigo legado para o framework esperado.`,
|
|
290
293
|
};
|
|
291
294
|
rotasDivergentes.push(registro);
|
|
@@ -293,6 +296,7 @@ export function analisarModulosSelecionadosDrift(estado) {
|
|
|
293
296
|
tipo: "rota_divergente",
|
|
294
297
|
modulo: ir.nome,
|
|
295
298
|
route: route.nome,
|
|
299
|
+
frameworksEsperados: [...esperadas],
|
|
296
300
|
mensagem: registro.motivo,
|
|
297
301
|
});
|
|
298
302
|
}
|
|
@@ -17,4 +17,5 @@ export interface PlanoExemplosOficiais {
|
|
|
17
17
|
}
|
|
18
18
|
export declare function localizarDiretorioExemplosOficiais(): Promise<string | undefined>;
|
|
19
19
|
export declare function planejarExemplosOficiais(): Promise<PlanoExemplosOficiais>;
|
|
20
|
-
export declare function
|
|
20
|
+
export declare function normalizarCaminhoExemplo(caminho: string): string;
|
|
21
|
+
export declare function materializarExemplosOficiais(baseProjeto?: string, preservarExistentes?: boolean, somenteCaminhos?: ReadonlySet<string>): Promise<ResultadoMaterializacaoExemplos>;
|
package/dist/exemplosOficiais.js
CHANGED
|
@@ -56,7 +56,10 @@ export async function planejarExemplosOficiais() {
|
|
|
56
56
|
arquivos,
|
|
57
57
|
};
|
|
58
58
|
}
|
|
59
|
-
export
|
|
59
|
+
export function normalizarCaminhoExemplo(caminho) {
|
|
60
|
+
return caminho.replace(/\\/g, "/");
|
|
61
|
+
}
|
|
62
|
+
export async function materializarExemplosOficiais(baseProjeto = process.cwd(), preservarExistentes = true, somenteCaminhos) {
|
|
60
63
|
const plano = await planejarExemplosOficiais();
|
|
61
64
|
const origem = plano.origem;
|
|
62
65
|
const destino = path.resolve(baseProjeto, "exemplos");
|
|
@@ -71,10 +74,13 @@ export async function materializarExemplosOficiais(baseProjeto = process.cwd(),
|
|
|
71
74
|
erro: "Diretorio de exemplos oficiais nao foi encontrado no pacote da CLI.",
|
|
72
75
|
};
|
|
73
76
|
}
|
|
77
|
+
const arquivosSelecionados = somenteCaminhos
|
|
78
|
+
? plano.arquivos.filter((arquivo) => somenteCaminhos.has(normalizarCaminhoExemplo(arquivo.caminhoRelativo)))
|
|
79
|
+
: plano.arquivos;
|
|
74
80
|
const criados = [];
|
|
75
81
|
const preservados = [];
|
|
76
|
-
await validarDestinosEscritaWorkspace(baseProjeto,
|
|
77
|
-
for (const arquivo of
|
|
82
|
+
await validarDestinosEscritaWorkspace(baseProjeto, arquivosSelecionados.map((arquivo) => arquivo.caminhoRelativo));
|
|
83
|
+
for (const arquivo of arquivosSelecionados) {
|
|
78
84
|
const resultado = await escreverArquivoWorkspaceSeguro(baseProjeto, arquivo.caminhoRelativo, await readFile(arquivo.origemArquivo, "utf8"), { sobrescrever: !preservarExistentes });
|
|
79
85
|
if (resultado.status === "preservado") {
|
|
80
86
|
preservados.push(arquivo.nome);
|
package/dist/geracaoCore.d.ts
CHANGED
package/dist/geracaoCore.js
CHANGED
|
@@ -85,6 +85,9 @@ export function normalizarFonteImportacao(valor) {
|
|
|
85
85
|
return "php";
|
|
86
86
|
}
|
|
87
87
|
if (valor === "nestjs"
|
|
88
|
+
|| valor === "express"
|
|
89
|
+
|| valor === "fastify"
|
|
90
|
+
|| valor === "koa"
|
|
88
91
|
|| valor === "fastapi"
|
|
89
92
|
|| valor === "flask"
|
|
90
93
|
|| valor === "nextjs"
|
|
@@ -92,6 +95,8 @@ export function normalizarFonteImportacao(valor) {
|
|
|
92
95
|
|| valor === "react-vite-consumer"
|
|
93
96
|
|| valor === "angular-consumer"
|
|
94
97
|
|| valor === "flutter-consumer"
|
|
98
|
+
|| valor === "sveltekit-consumer"
|
|
99
|
+
|| valor === "nuxt-consumer"
|
|
95
100
|
|| valor === "firebase"
|
|
96
101
|
|| valor === "dotnet"
|
|
97
102
|
|| valor === "java"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import { type Diagnostico } from "@sema/nucleo";
|
|
3
|
-
export type FonteImportacao = "nestjs" | "fastapi" | "flask" | "nextjs" | "nextjs-consumer" | "react-vite-consumer" | "angular-consumer" | "flutter-consumer" | "firebase" | "typescript" | "python" | "dart" | "dotnet" | "java" | "go" | "rust" | "cpp" | "php";
|
|
3
|
+
export type FonteImportacao = "nestjs" | "express" | "fastify" | "koa" | "fastapi" | "flask" | "nextjs" | "nextjs-consumer" | "react-vite-consumer" | "angular-consumer" | "flutter-consumer" | "sveltekit-consumer" | "nuxt-consumer" | "firebase" | "typescript" | "python" | "dart" | "dotnet" | "java" | "go" | "rust" | "cpp" | "php";
|
|
4
4
|
export type OrigemInteropImportada = "ts" | "py" | "dart" | "cs" | "java" | "go" | "rust" | "cpp" | "php";
|
|
5
5
|
export interface CampoImportado {
|
|
6
6
|
nome: string;
|
|
@@ -11,8 +11,12 @@ export declare function extrairTasksBridgeConsumer(baseProjeto: string, contexto
|
|
|
11
11
|
enums: EnumImportado[];
|
|
12
12
|
};
|
|
13
13
|
export declare function montarVinculosSuperficiesConsumer(superficies: SuperficieConsumerImportada[]): VinculoImportado[];
|
|
14
|
-
export declare function importarConsumerBase(diretorio: string, namespaceBase: string, descricaoFramework: string, ehBridge: (relacaoArquivo: string) => boolean, coletarSuperficies: (baseProjeto: string, arquivos: string[]) => Promise<SuperficieConsumerImportada[]
|
|
14
|
+
export declare function importarConsumerBase(diretorio: string, namespaceBase: string, descricaoFramework: string, ehBridge: (relacaoArquivo: string) => boolean, coletarSuperficies: (baseProjeto: string, arquivos: string[]) => Promise<SuperficieConsumerImportada[]>, extensoes?: readonly string[]): Promise<ModuloImportado[]>;
|
|
15
15
|
export declare function coletarSuperficiesNextJsConsumer(baseProjeto: string, arquivos: string[]): Promise<SuperficieConsumerImportada[]>;
|
|
16
|
+
export declare function coletarSuperficiesSvelteKitConsumer(baseProjeto: string, arquivos: string[]): Promise<SuperficieConsumerImportada[]>;
|
|
17
|
+
export declare function coletarSuperficiesNuxtConsumer(baseProjeto: string, arquivos: string[]): Promise<SuperficieConsumerImportada[]>;
|
|
18
|
+
export declare function importarSvelteKitConsumerBase(diretorio: string, namespaceBase: string): Promise<ModuloImportado[]>;
|
|
19
|
+
export declare function importarNuxtConsumerBase(diretorio: string, namespaceBase: string): Promise<ModuloImportado[]>;
|
|
16
20
|
export declare function coletarSuperficiesReactViteConsumer(baseProjeto: string, arquivos: string[]): Promise<SuperficieConsumerImportada[]>;
|
|
17
21
|
export declare function coletarSuperficiesAngularConsumer(baseProjeto: string, arquivos: string[]): Promise<SuperficieConsumerImportada[]>;
|
|
18
22
|
export declare function importarNextJsConsumerBase(diretorio: string, namespaceBase: string): Promise<ModuloImportado[]>;
|
|
@@ -146,9 +146,9 @@ export function montarVinculosSuperficiesConsumer(superficies) {
|
|
|
146
146
|
{ tipo: "arquivo", valor: normalizarCaminhoImportado(superficie.arquivo) },
|
|
147
147
|
]));
|
|
148
148
|
}
|
|
149
|
-
export async function importarConsumerBase(diretorio, namespaceBase, descricaoFramework, ehBridge, coletarSuperficies) {
|
|
149
|
+
export async function importarConsumerBase(diretorio, namespaceBase, descricaoFramework, ehBridge, coletarSuperficies, extensoes = [".ts", ".tsx", ".js", ".jsx"]) {
|
|
150
150
|
const escopo = resolverEscopoImportacaoFrontendConsumer(diretorio);
|
|
151
|
-
const arquivos = await listarArquivosRecursivos(escopo.baseProjeto, [
|
|
151
|
+
const arquivos = await listarArquivosRecursivos(escopo.baseProjeto, [...extensoes]);
|
|
152
152
|
const arquivosBridge = arquivos.filter((arquivo) => ehBridge(path.relative(escopo.baseProjeto, arquivo)));
|
|
153
153
|
const contextosBridge = await carregarContextosBridgeConsumer(escopo.baseProjeto, arquivosBridge);
|
|
154
154
|
const { tasks, entities, enums } = extrairTasksBridgeConsumer(escopo.baseProjeto, contextosBridge);
|
|
@@ -175,6 +175,44 @@ export async function coletarSuperficiesNextJsConsumer(baseProjeto, arquivos) {
|
|
|
175
175
|
.map((arquivo) => inferirCaminhoNextJsConsumer(path.relative(baseProjeto, arquivo)))
|
|
176
176
|
.filter((item) => Boolean(item));
|
|
177
177
|
}
|
|
178
|
+
export async function coletarSuperficiesSvelteKitConsumer(baseProjeto, arquivos) {
|
|
179
|
+
const { arquivoEhSuperficieSvelteKitConsumer, inferirRotaSvelteKitConsumer } = await import("./drift.part05.js");
|
|
180
|
+
return arquivos
|
|
181
|
+
.map((arquivo) => {
|
|
182
|
+
const relacao = path.relative(baseProjeto, arquivo);
|
|
183
|
+
if (!arquivoEhSuperficieSvelteKitConsumer(relacao)) {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
const superficie = inferirRotaSvelteKitConsumer(relacao);
|
|
187
|
+
return superficie
|
|
188
|
+
? { caminho: superficie.rota, arquivo: relacao, tipoArquivo: superficie.tipoArquivo }
|
|
189
|
+
: undefined;
|
|
190
|
+
})
|
|
191
|
+
.filter((item) => Boolean(item));
|
|
192
|
+
}
|
|
193
|
+
export async function coletarSuperficiesNuxtConsumer(baseProjeto, arquivos) {
|
|
194
|
+
const { arquivoEhSuperficieNuxtConsumer, inferirRotaNuxtConsumer } = await import("./drift.part05.js");
|
|
195
|
+
return arquivos
|
|
196
|
+
.map((arquivo) => {
|
|
197
|
+
const relacao = path.relative(baseProjeto, arquivo);
|
|
198
|
+
if (!arquivoEhSuperficieNuxtConsumer(relacao)) {
|
|
199
|
+
return undefined;
|
|
200
|
+
}
|
|
201
|
+
const superficie = inferirRotaNuxtConsumer(relacao);
|
|
202
|
+
return superficie
|
|
203
|
+
? { caminho: superficie.rota, arquivo: relacao, tipoArquivo: superficie.tipoArquivo }
|
|
204
|
+
: undefined;
|
|
205
|
+
})
|
|
206
|
+
.filter((item) => Boolean(item));
|
|
207
|
+
}
|
|
208
|
+
export async function importarSvelteKitConsumerBase(diretorio, namespaceBase) {
|
|
209
|
+
const { arquivoEhBridgeSvelteKitConsumer } = await import("./drift.part05.js");
|
|
210
|
+
return importarConsumerBase(diretorio, namespaceBase, "SvelteKit", arquivoEhBridgeSvelteKitConsumer, coletarSuperficiesSvelteKitConsumer, [".ts", ".js", ".svelte"]);
|
|
211
|
+
}
|
|
212
|
+
export async function importarNuxtConsumerBase(diretorio, namespaceBase) {
|
|
213
|
+
const { arquivoEhBridgeNuxtConsumer } = await import("./drift.part05.js");
|
|
214
|
+
return importarConsumerBase(diretorio, namespaceBase, "Nuxt", arquivoEhBridgeNuxtConsumer, coletarSuperficiesNuxtConsumer, [".ts", ".js", ".vue"]);
|
|
215
|
+
}
|
|
178
216
|
export async function coletarSuperficiesReactViteConsumer(baseProjeto, arquivos) {
|
|
179
217
|
const superficies = [];
|
|
180
218
|
for (const arquivo of arquivos) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { extrairRotasTypeScriptHttp } from "./typescript-http.js";
|
|
2
2
|
import { CampoImportado, ModuloImportado, TipoDescoberto } from "./importador.part01.js";
|
|
3
3
|
export declare function importarNestJsDeArquivo(diretorioBase: string, arquivo: string, namespaceBase: string, tiposGlobais: Map<string, TipoDescoberto>): ModuloImportado[];
|
|
4
|
+
export declare function importarExpressFastifyDeArquivo(diretorioBase: string, arquivo: string, namespaceBase: string, origemDesejada: "express" | "fastify" | "koa"): ModuloImportado[];
|
|
5
|
+
export declare function importarExpressFastifyBase(diretorio: string, namespaceBase: string, origem: "express" | "fastify" | "koa"): Promise<ModuloImportado[]>;
|
|
4
6
|
export declare function importarTypeScriptBase(diretorio: string, namespaceBase: string, modoNestjs?: boolean): Promise<ModuloImportado[]>;
|
|
5
7
|
export declare function nomeTaskParaRotaTypeScript(caminho: string, metodo: string): string;
|
|
6
8
|
export declare function camposDeParametrosRotaTypeScript(parametros: ReturnType<typeof extrairRotasTypeScriptHttp>[number]["parametros"]): CampoImportado[];
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import ts from "typescript";
|
|
6
|
-
import { extrairRotasTypeScriptHttp, inferirSemanticaHandlerTypeScriptHttp, localizarExportacaoTypeScriptHttp, } from "./typescript-http.js";
|
|
6
|
+
import { extrairRotasExpressFastify, extrairRotasTypeScriptHttp, inferirSemanticaHandlerTypeScriptHttp, localizarExportacaoTypeScriptHttp, } from "./typescript-http.js";
|
|
7
7
|
import { extrairTextoLiteral, inferirContextoPorArquivo, juntarCaminhoHttp, lerDecorator, listarArquivosRecursivos, mapearTipoPrimitivo, paraSnakeCase } from "./importador.part01.js";
|
|
8
8
|
import { deduplicarCampos, extrairChamadaServiceTs } from "./importador.part04.js";
|
|
9
9
|
import { caminhoImplTs, camposDeSemanticaTypeScriptHttp, criarEntidadesReferenciadas, descreverEfeitosPorHeuristica, expandirCamposTs, extrairErrosTs } from "./importador.part02.js";
|
|
@@ -98,6 +98,102 @@ export function importarNestJsDeArquivo(diretorioBase, arquivo, namespaceBase, t
|
|
|
98
98
|
routes: deduplicarRotas(routes),
|
|
99
99
|
}];
|
|
100
100
|
}
|
|
101
|
+
function nomearTarefaRotaChamada(metodo, caminho) {
|
|
102
|
+
const ultimoSegmento = caminho.replace(/\{[^}]+\}/g, "").split("/").filter(Boolean).pop() ?? "recurso";
|
|
103
|
+
const singular = ultimoSegmento.length > 3 && /es$/.test(ultimoSegmento)
|
|
104
|
+
? ultimoSegmento.replace(/es$/, "")
|
|
105
|
+
: ultimoSegmento.replace(/s$/, "");
|
|
106
|
+
switch (metodo) {
|
|
107
|
+
case "POST":
|
|
108
|
+
return `criar_${singular}`;
|
|
109
|
+
case "PUT":
|
|
110
|
+
case "PATCH":
|
|
111
|
+
return `atualizar_${singular}`;
|
|
112
|
+
case "DELETE":
|
|
113
|
+
return `remover_${singular}`;
|
|
114
|
+
case "GET":
|
|
115
|
+
return caminho.includes("{") ? `obter_${singular}` : `listar_${ultimoSegmento}`;
|
|
116
|
+
default:
|
|
117
|
+
return `${metodo.toLowerCase()}_${ultimoSegmento}`;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
export function importarExpressFastifyDeArquivo(diretorioBase, arquivo, namespaceBase, origemDesejada) {
|
|
121
|
+
const relacao = path.relative(diretorioBase, arquivo);
|
|
122
|
+
const codigo = ts.sys.readFile(arquivo, "utf8") ?? "";
|
|
123
|
+
const sourceFile = ts.createSourceFile(arquivo, codigo, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
124
|
+
const contextoSegmentos = inferirContextoPorArquivo(relacao);
|
|
125
|
+
const nomeModulo = [namespaceBase, ...contextoSegmentos].join(".");
|
|
126
|
+
const rotasArquivo = extrairRotasExpressFastify(sourceFile).filter((rota) => rota.origem === origemDesejada);
|
|
127
|
+
if (rotasArquivo.length === 0) {
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
const tasks = [];
|
|
131
|
+
const routes = [];
|
|
132
|
+
for (const rota of rotasArquivo) {
|
|
133
|
+
const taskNome = nomearTarefaRotaChamada(rota.metodo, rota.caminho);
|
|
134
|
+
const implSimbolo = /^[A-Za-z_]\w*$/.test(rota.simbolo) ? rota.simbolo : undefined;
|
|
135
|
+
const semantica = implSimbolo
|
|
136
|
+
? inferirSemanticaHandlerTypeScriptHttp(sourceFile, implSimbolo, true)
|
|
137
|
+
: undefined;
|
|
138
|
+
const converterCampoInferido = (campo) => ({
|
|
139
|
+
nome: campo.nome,
|
|
140
|
+
tipo: mapearTipoPrimitivo(campo.tipoTexto ?? "string") === "Vazio" ? "Texto" : mapearTipoPrimitivo(campo.tipoTexto ?? "string"),
|
|
141
|
+
obrigatorio: campo.obrigatorio,
|
|
142
|
+
});
|
|
143
|
+
const camposInferidos = deduplicarCampos([
|
|
144
|
+
...rota.parametros.map((parametro) => ({
|
|
145
|
+
nome: parametro.nome,
|
|
146
|
+
tipo: parametro.tipoSema,
|
|
147
|
+
obrigatorio: true,
|
|
148
|
+
})),
|
|
149
|
+
...(semantica?.query ?? []).map(converterCampoInferido),
|
|
150
|
+
...(semantica?.body ?? []).map(converterCampoInferido),
|
|
151
|
+
]);
|
|
152
|
+
const camposResposta = deduplicarCampos((semantica?.response ?? []).map(converterCampoInferido));
|
|
153
|
+
tasks.push({
|
|
154
|
+
nome: taskNome,
|
|
155
|
+
resumo: `Task importada automaticamente da rota ${rota.metodo} ${rota.caminho} em ${relacao}.`,
|
|
156
|
+
input: camposInferidos,
|
|
157
|
+
output: camposResposta,
|
|
158
|
+
errors: [],
|
|
159
|
+
effects: [],
|
|
160
|
+
impl: implSimbolo ? { ts: caminhoImplTs(diretorioBase, arquivo, implSimbolo) } : undefined,
|
|
161
|
+
origemArquivo: relacao,
|
|
162
|
+
origemSimbolo: rota.simbolo,
|
|
163
|
+
});
|
|
164
|
+
routes.push({
|
|
165
|
+
nome: `${taskNome}_publico`,
|
|
166
|
+
resumo: `Rota ${origemDesejada} importada automaticamente de ${relacao}.`,
|
|
167
|
+
metodo: rota.metodo,
|
|
168
|
+
caminho: rota.caminho,
|
|
169
|
+
task: taskNome,
|
|
170
|
+
input: camposInferidos,
|
|
171
|
+
output: camposResposta,
|
|
172
|
+
errors: [],
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
const { entities, enums } = criarEntidadesReferenciadas(new Map(), new Set(), new Set());
|
|
176
|
+
sincronizarRotasComTasks(routes, tasks);
|
|
177
|
+
return [{
|
|
178
|
+
nome: nomeModulo,
|
|
179
|
+
resumo: `Rascunho Sema importado de um contexto ${origemDesejada === "express" ? "Express" : origemDesejada === "koa" ? "Koa" : "Fastify"} legado em ${contextoSegmentos.join("/")}.`,
|
|
180
|
+
entities,
|
|
181
|
+
enums,
|
|
182
|
+
tasks: deduplicarTarefas(tasks),
|
|
183
|
+
routes: deduplicarRotas(routes),
|
|
184
|
+
}];
|
|
185
|
+
}
|
|
186
|
+
export async function importarExpressFastifyBase(diretorio, namespaceBase, origem) {
|
|
187
|
+
const arquivos = await listarArquivosRecursivos(diretorio, [".ts"]);
|
|
188
|
+
const uteis = arquivos.filter((arquivo) => !arquivo.endsWith(".spec.ts")
|
|
189
|
+
&& !arquivo.endsWith(".test.ts")
|
|
190
|
+
&& !arquivo.endsWith(".d.ts"));
|
|
191
|
+
const modulos = [];
|
|
192
|
+
for (const arquivo of uteis) {
|
|
193
|
+
modulos.push(...importarExpressFastifyDeArquivo(diretorio, arquivo, namespaceBase, origem));
|
|
194
|
+
}
|
|
195
|
+
return modulos;
|
|
196
|
+
}
|
|
101
197
|
export async function importarTypeScriptBase(diretorio, namespaceBase, modoNestjs = false) {
|
|
102
198
|
const arquivos = await listarArquivosRecursivos(diretorio, [".ts"]);
|
|
103
199
|
const uteis = arquivos.filter((arquivo) => !arquivo.endsWith(".spec.ts")
|
|
@@ -12,8 +12,8 @@ import { inferirContextoPorArquivo, inferirNamespaceBase, listarArquivosRecursiv
|
|
|
12
12
|
import { camposDeParametrosRotaBackend, criarCampoResultadoBackend, descreverEfeitosPorHeuristica, inferirDatabasesPorHeuristica, mapearTipoBackendParaSema } from "./importador.part02.js";
|
|
13
13
|
import { caminhoImplGenerico, importarFirebaseBase } from "./importador.part07.js";
|
|
14
14
|
import { acumularModuloImportado, criarModuloImportadoSimples, importarDartBase, importarDotnetBase, importarPythonBase, resolverArquivoRustParaSimbolo, selecionarSimbolosPreferidos } from "./importador.part08.js";
|
|
15
|
-
import { importarNextJsBase, importarTypeScriptBase } from "./importador.part06.js";
|
|
16
|
-
import { importarAngularConsumerBase, importarFlutterConsumerBase, importarNextJsConsumerBase, importarReactViteConsumerBase } from "./importador.part04.js";
|
|
15
|
+
import { importarExpressFastifyBase, importarNextJsBase, importarTypeScriptBase } from "./importador.part06.js";
|
|
16
|
+
import { importarAngularConsumerBase, importarFlutterConsumerBase, importarNextJsConsumerBase, importarReactViteConsumerBase, importarNuxtConsumerBase, importarSvelteKitConsumerBase } from "./importador.part04.js";
|
|
17
17
|
import { formatarModuloImportado, moduloParaCodigo, montarArquivoImportado } from "./importador.part05.js";
|
|
18
18
|
export async function importarJavaBase(diretorio, namespaceBase) {
|
|
19
19
|
const arquivos = (await listarArquivosRecursivos(diretorio, [".java"]))
|
|
@@ -300,6 +300,15 @@ export async function importarProjetoLegado(fonte, diretorio, namespaceBase) {
|
|
|
300
300
|
if (fonte === "nestjs") {
|
|
301
301
|
modulos = await importarTypeScriptBase(base, namespace, true);
|
|
302
302
|
}
|
|
303
|
+
else if (fonte === "express") {
|
|
304
|
+
modulos = await importarExpressFastifyBase(base, namespace, "express");
|
|
305
|
+
}
|
|
306
|
+
else if (fonte === "fastify") {
|
|
307
|
+
modulos = await importarExpressFastifyBase(base, namespace, "fastify");
|
|
308
|
+
}
|
|
309
|
+
else if (fonte === "koa") {
|
|
310
|
+
modulos = await importarExpressFastifyBase(base, namespace, "koa");
|
|
311
|
+
}
|
|
303
312
|
else if (fonte === "nextjs") {
|
|
304
313
|
modulos = await importarNextJsBase(base, namespace);
|
|
305
314
|
}
|
|
@@ -315,6 +324,12 @@ export async function importarProjetoLegado(fonte, diretorio, namespaceBase) {
|
|
|
315
324
|
else if (fonte === "flutter-consumer") {
|
|
316
325
|
modulos = await importarFlutterConsumerBase(base, namespace);
|
|
317
326
|
}
|
|
327
|
+
else if (fonte === "sveltekit-consumer") {
|
|
328
|
+
modulos = await importarSvelteKitConsumerBase(base, namespace);
|
|
329
|
+
}
|
|
330
|
+
else if (fonte === "nuxt-consumer") {
|
|
331
|
+
modulos = await importarNuxtConsumerBase(base, namespace);
|
|
332
|
+
}
|
|
318
333
|
else if (fonte === "firebase") {
|
|
319
334
|
modulos = await importarFirebaseBase(base, namespace);
|
|
320
335
|
}
|