@semacode/cli 1.5.53 → 1.5.55
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/README.md +1 -0
- package/dist/agentEntryPoints.js +3 -3
- package/dist/drift.part01.d.ts +2 -2
- package/dist/drift.part03.js +1 -1
- package/dist/drift.part04.js +1 -1
- package/dist/drift.part07.d.ts +5 -0
- package/dist/drift.part07.js +43 -1
- package/dist/drift.part08.js +1 -1
- package/dist/drift.part09.d.ts +2 -2
- package/dist/drift.part09.js +5 -1
- package/dist/drift.part12.js +1 -1
- package/dist/drift.part13.js +6 -1
- package/dist/geracaoCore.js +53 -2
- package/dist/iaPrompts.d.ts +1 -1
- package/dist/iaPrompts.js +3 -3
- package/dist/importador.part01.d.ts +2 -2
- package/dist/importador.part05.js +10 -0
- package/dist/importador.part08.js +5 -3
- package/dist/importador.part09.d.ts +1 -0
- package/dist/importador.part09.js +65 -0
- package/dist/index.part01.js +4 -4
- package/dist/index.part06.js +1 -1
- package/dist/index.part08.js +1 -1
- package/dist/initTemplatesBase.js +1 -1
- package/dist/php-http.d.ts +24 -0
- package/dist/php-http.js +252 -0
- package/dist/projetoBusca.js +1 -0
- package/dist/projetoConfig.js +3 -2
- package/dist/projetoLegado.js +11 -0
- package/dist/tipos.d.ts +1 -1
- package/docs/ai-workflow.md +1 -1
- package/docs/commands.md +2 -2
- package/docs/syntax.md +3 -2
- package/node_modules/@sema/gerador-php/dist/index.d.ts +3 -0
- package/node_modules/@sema/gerador-php/dist/index.js +538 -0
- package/node_modules/@sema/gerador-php/dist/index.js.map +1 -0
- package/node_modules/@sema/gerador-php/package.json +7 -0
- package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +1 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js +4 -0
- package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.part02.d.ts +1 -1
- package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +3 -3
- package/node_modules/@sema/nucleo/dist/parser/parser.declaracoes.js +2 -0
- package/node_modules/@sema/nucleo/dist/parser/parser.declaracoes.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.d.ts +2 -2
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js +3 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js.map +1 -1
- package/node_modules/@sema/padroes/dist/index.d.ts +2 -1
- package/node_modules/@sema/padroes/dist/index.js +31 -0
- package/node_modules/@sema/padroes/dist/index.js.map +1 -1
- package/package.json +12 -10
package/dist/index.part06.js
CHANGED
|
@@ -206,7 +206,7 @@ export async function comandoAjudaIa() {
|
|
|
206
206
|
"Use `sema docs-impacto --intencao <acao>` para ler ou criar docs obrigatorias antes de agir.",
|
|
207
207
|
"Use `sema finalizar-mudanca --intencao <acao>` para bloquear conclusao sem leitura documental comprovada.",
|
|
208
208
|
"Use `sema contexto-ia <arquivo.sema>` para gerar AST, IR, drift, `briefing.json` e `briefing.min.json`.",
|
|
209
|
-
"Use `sema compilar <arquivo-ou-pasta> --alvo <typescript|python|dart|lua|javascript|html|css> --saida <diretorio>` quando a tarefa pedir codigo derivado.",
|
|
209
|
+
"Use `sema compilar <arquivo-ou-pasta> --alvo <typescript|python|php|dart|lua|javascript|html|css> --saida <diretorio>` quando a tarefa pedir codigo derivado.",
|
|
210
210
|
]));
|
|
211
211
|
console.log("");
|
|
212
212
|
console.log(renderizarSecaoAscii("Regras praticas", [
|
package/dist/index.part08.js
CHANGED
|
@@ -121,7 +121,7 @@ export async function principal() {
|
|
|
121
121
|
{
|
|
122
122
|
const fonte = normalizarFonteImportacao(posicionais[0]);
|
|
123
123
|
if (!fonte || !posicionais[1]) {
|
|
124
|
-
console.error("Uso: sema importar <nestjs|fastapi|flask|nextjs|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer|firebase|dotnet|java|go|rust|cpp|typescript|python|dart> <diretorio> [--saida <diretorio>] [--namespace <base>] [--json]");
|
|
124
|
+
console.error("Uso: sema importar <nestjs|fastapi|flask|nextjs|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer|firebase|dotnet|java|go|rust|cpp|php|typescript|python|dart> <diretorio> [--saida <diretorio>] [--namespace <base>] [--json]");
|
|
125
125
|
codigoSaida = 1;
|
|
126
126
|
break;
|
|
127
127
|
}
|
|
@@ -118,7 +118,7 @@ export function arquivosTemplateIniciar(template) {
|
|
|
118
118
|
?? [
|
|
119
119
|
{
|
|
120
120
|
caminhoRelativo: "sema.config.json",
|
|
121
|
-
conteudo: "{\n \"origens\": [\"./contratos\"],\n \"saida\": \"./generated\",\n \"alvos\": [\"typescript\", \"javascript\", \"python\", \"dart\", \"lua\", \"html\", \"css\"],\n \"alvoPadrao\": \"typescript\",\n \"estruturaSaida\": \"modulos\",\n \"framework\": \"base\",\n \"modoEstrito\": true,\n \"diretoriosSaidaPorAlvo\": {\n \"typescript\": \"./generated/typescript\",\n \"javascript\": \"./generated/javascript\",\n \"python\": \"./generated/python\",\n \"dart\": \"./generated/dart\",\n \"lua\": \"./generated/lua\",\n \"html\": \"./generated/html\",\n \"css\": \"./generated/css\"\n },\n \"convencoesGeracaoPorProjeto\": \"base\"\n}\n",
|
|
121
|
+
conteudo: "{\n \"origens\": [\"./contratos\"],\n \"saida\": \"./generated\",\n \"alvos\": [\"typescript\", \"javascript\", \"python\", \"php\", \"dart\", \"lua\", \"html\", \"css\"],\n \"alvoPadrao\": \"typescript\",\n \"estruturaSaida\": \"modulos\",\n \"framework\": \"base\",\n \"modoEstrito\": true,\n \"diretoriosSaidaPorAlvo\": {\n \"typescript\": \"./generated/typescript\",\n \"javascript\": \"./generated/javascript\",\n \"python\": \"./generated/python\",\n \"php\": \"./generated/php\",\n \"dart\": \"./generated/dart\",\n \"lua\": \"./generated/lua\",\n \"html\": \"./generated/html\",\n \"css\": \"./generated/css\"\n },\n \"convencoesGeracaoPorProjeto\": \"base\"\n}\n",
|
|
122
122
|
},
|
|
123
123
|
...arquivosBase,
|
|
124
124
|
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export interface ParametroRotaPhp {
|
|
2
|
+
nome: string;
|
|
3
|
+
tipoSema: "Texto" | "Inteiro" | "Decimal" | "Id";
|
|
4
|
+
}
|
|
5
|
+
export interface SimboloPhpExtraido {
|
|
6
|
+
simbolo: string;
|
|
7
|
+
aliases?: string[];
|
|
8
|
+
retorno?: string;
|
|
9
|
+
parametros: Array<{
|
|
10
|
+
nome: string;
|
|
11
|
+
tipoTexto?: string;
|
|
12
|
+
obrigatorio: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
export interface RotaPhpExtraida {
|
|
16
|
+
origem: "php";
|
|
17
|
+
metodo: string;
|
|
18
|
+
caminho: string;
|
|
19
|
+
simbolo: string;
|
|
20
|
+
parametros: ParametroRotaPhp[];
|
|
21
|
+
retorno?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function extrairSimbolosPhp(codigo: string): SimboloPhpExtraido[];
|
|
24
|
+
export declare function extrairRotasPhp(codigo: string): RotaPhpExtraida[];
|
package/dist/php-http.js
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
// SEMA-GOVERNED: sema.governanca_ia_contexto
|
|
2
|
+
// Descricao: extracao PHP para drift/importacao; consulte contratos/sema/governanca_ia_contexto.sema antes de editar.
|
|
3
|
+
const METODOS_HTTP = new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
4
|
+
function contarChar(texto, alvo) {
|
|
5
|
+
return [...texto].filter((char) => char === alvo).length;
|
|
6
|
+
}
|
|
7
|
+
function limparStringPhp(valor) {
|
|
8
|
+
const limpo = (valor ?? "").trim();
|
|
9
|
+
if (!limpo) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
if ((limpo.startsWith("\"") && limpo.endsWith("\"")) || (limpo.startsWith("'") && limpo.endsWith("'"))) {
|
|
13
|
+
return limpo.slice(1, -1);
|
|
14
|
+
}
|
|
15
|
+
return limpo;
|
|
16
|
+
}
|
|
17
|
+
function normalizarCaminhoPhp(caminho) {
|
|
18
|
+
const limpo = caminho
|
|
19
|
+
.trim()
|
|
20
|
+
.replace(/^\/+|\/+$/g, "")
|
|
21
|
+
.replace(/:([A-Za-z_]\w*)/g, "{$1}")
|
|
22
|
+
.replace(/\{([^}:?]+)\??(?::[^}]+)?\}/g, "{$1}");
|
|
23
|
+
return `/${limpo}`.replace(/\/+/g, "/");
|
|
24
|
+
}
|
|
25
|
+
function juntarCaminhoPhp(base, sufixo) {
|
|
26
|
+
const partes = [base, sufixo]
|
|
27
|
+
.map((parte) => (parte ?? "").trim())
|
|
28
|
+
.filter(Boolean)
|
|
29
|
+
.map((parte) => parte.replace(/^\/+|\/+$/g, ""));
|
|
30
|
+
return normalizarCaminhoPhp(partes.join("/"));
|
|
31
|
+
}
|
|
32
|
+
function mapearTipoPhp(tipo) {
|
|
33
|
+
const normalizado = (tipo ?? "").toLowerCase().replace(/^[?\\]+/, "");
|
|
34
|
+
if (/^(int|integer)$/.test(normalizado)) {
|
|
35
|
+
return "Inteiro";
|
|
36
|
+
}
|
|
37
|
+
if (/^(float|double|decimal)$/.test(normalizado)) {
|
|
38
|
+
return "Decimal";
|
|
39
|
+
}
|
|
40
|
+
if (/uuid|id$/.test(normalizado)) {
|
|
41
|
+
return "Id";
|
|
42
|
+
}
|
|
43
|
+
return "Texto";
|
|
44
|
+
}
|
|
45
|
+
function extrairParametrosPhp(assinatura) {
|
|
46
|
+
return assinatura.split(",").map((parametroBruto) => {
|
|
47
|
+
const parametro = parametroBruto.trim();
|
|
48
|
+
if (!parametro) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const semPadrao = parametro.split("=")[0]?.trim() ?? parametro;
|
|
52
|
+
const nome = semPadrao.match(/\$([A-Za-z_]\w*)/)?.[1];
|
|
53
|
+
if (!nome) {
|
|
54
|
+
return undefined;
|
|
55
|
+
}
|
|
56
|
+
const tipoTexto = semPadrao
|
|
57
|
+
.slice(0, semPadrao.indexOf(`$${nome}`))
|
|
58
|
+
.replace(/\b(?:public|protected|private|readonly|static)\b/g, "")
|
|
59
|
+
.replace(/[&.]{1,3}/g, "")
|
|
60
|
+
.trim() || undefined;
|
|
61
|
+
return {
|
|
62
|
+
nome,
|
|
63
|
+
tipoTexto,
|
|
64
|
+
obrigatorio: !parametro.includes("=") && !tipoTexto?.startsWith("?"),
|
|
65
|
+
};
|
|
66
|
+
}).filter((item) => Boolean(item));
|
|
67
|
+
}
|
|
68
|
+
function extrairParametrosRotaPhp(caminho, assinatura) {
|
|
69
|
+
const assinaturaMap = new Map();
|
|
70
|
+
for (const parametro of extrairParametrosPhp(assinatura)) {
|
|
71
|
+
assinaturaMap.set(parametro.nome, parametro.tipoTexto ?? "");
|
|
72
|
+
}
|
|
73
|
+
return [...normalizarCaminhoPhp(caminho).matchAll(/\{([^}]+)\}/g)].map((match) => {
|
|
74
|
+
const nome = match[1];
|
|
75
|
+
return {
|
|
76
|
+
nome,
|
|
77
|
+
tipoSema: mapearTipoPhp(assinaturaMap.get(nome)),
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function removerComentariosBloco(codigo) {
|
|
82
|
+
return codigo.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
83
|
+
}
|
|
84
|
+
function extrairAtributoRoutePhp(linha) {
|
|
85
|
+
const match = linha.match(/#\[\s*Route\s*\(([\s\S]+)\)\s*\]/i);
|
|
86
|
+
if (!match) {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
const corpo = match[1];
|
|
90
|
+
const caminho = limparStringPhp(corpo.match(/(?:path\s*:\s*)?(['"][^'"]+['"])/i)?.[1]);
|
|
91
|
+
if (!caminho) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
const metodos = [...corpo.matchAll(/['"](GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)['"]/gi)]
|
|
95
|
+
.map((item) => item[1].toUpperCase())
|
|
96
|
+
.filter((metodo) => METODOS_HTTP.has(metodo));
|
|
97
|
+
return {
|
|
98
|
+
caminho,
|
|
99
|
+
metodos: metodos.length > 0 ? [...new Set(metodos)] : ["GET"],
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function extrairTargetLaravel(bloco) {
|
|
103
|
+
const arrayController = bloco.match(/([A-Za-z_][\\A-Za-z0-9_]*)::class\s*,\s*['"]([A-Za-z_]\w*)['"]/);
|
|
104
|
+
if (arrayController) {
|
|
105
|
+
const classe = arrayController[1].split("\\").at(-1);
|
|
106
|
+
return `${classe}.${arrayController[2]}`;
|
|
107
|
+
}
|
|
108
|
+
const stringController = bloco.match(/['"]([A-Za-z_][\\A-Za-z0-9_]*)@([A-Za-z_]\w*)['"]/);
|
|
109
|
+
if (stringController) {
|
|
110
|
+
const classe = stringController[1].split("\\").at(-1);
|
|
111
|
+
return `${classe}.${stringController[2]}`;
|
|
112
|
+
}
|
|
113
|
+
const invokable = bloco.match(/([A-Za-z_][\\A-Za-z0-9_]*)::class/);
|
|
114
|
+
if (invokable) {
|
|
115
|
+
const classe = invokable[1].split("\\").at(-1);
|
|
116
|
+
return `${classe}.__invoke`;
|
|
117
|
+
}
|
|
118
|
+
const closure = bloco.match(/function\s*\(/);
|
|
119
|
+
if (closure) {
|
|
120
|
+
return "closure";
|
|
121
|
+
}
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
function assinaturaFuncaoPhp(linha) {
|
|
125
|
+
return linha.match(/^(?:(?:public|protected|private|static|final|abstract|readonly)\s+)*function\s+&?\s*([A-Za-z_]\w*)\s*\(([^)]*)\)\s*(?::\s*([?\\A-Za-z_][\\A-Za-z0-9_|?]*))?/);
|
|
126
|
+
}
|
|
127
|
+
function namespaceParaCaminhoPhp(namespace) {
|
|
128
|
+
const limpo = namespace?.trim().replace(/\\+/g, ".");
|
|
129
|
+
return limpo || undefined;
|
|
130
|
+
}
|
|
131
|
+
function variantesNamespacePhp(namespace, classe, metodo) {
|
|
132
|
+
const base = namespaceParaCaminhoPhp(namespace);
|
|
133
|
+
if (!base) {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
const caminho = `${base}.${classe}.${metodo}`;
|
|
137
|
+
const partes = caminho.split(".");
|
|
138
|
+
const primeiroMinusculo = partes.length > 0
|
|
139
|
+
? [partes[0].toLowerCase(), ...partes.slice(1)].join(".")
|
|
140
|
+
: caminho;
|
|
141
|
+
return [...new Set([caminho, primeiroMinusculo])];
|
|
142
|
+
}
|
|
143
|
+
export function extrairSimbolosPhp(codigo) {
|
|
144
|
+
const simbolos = new Map();
|
|
145
|
+
const linhas = removerComentariosBloco(codigo).split(/\r?\n/);
|
|
146
|
+
const pilhaClasses = [];
|
|
147
|
+
let profundidade = 0;
|
|
148
|
+
let namespaceAtual;
|
|
149
|
+
for (const linhaOriginal of linhas) {
|
|
150
|
+
const linha = linhaOriginal.trim();
|
|
151
|
+
if (!linha || linha.startsWith("//") || linha.startsWith("#")) {
|
|
152
|
+
profundidade += contarChar(linhaOriginal, "{") - contarChar(linhaOriginal, "}");
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
const namespace = linha.match(/^namespace\s+([^;{]+)\s*[;{]/);
|
|
156
|
+
if (namespace) {
|
|
157
|
+
namespaceAtual = namespace[1].trim();
|
|
158
|
+
}
|
|
159
|
+
const classe = linha.match(/\b(?:class|trait)\s+([A-Za-z_]\w*)/);
|
|
160
|
+
const classeSemChaveNaLinha = Boolean(classe && !linhaOriginal.includes("{"));
|
|
161
|
+
if (classe) {
|
|
162
|
+
pilhaClasses.push({ nome: classe[1], profundidade: profundidade + 1 });
|
|
163
|
+
}
|
|
164
|
+
const funcao = assinaturaFuncaoPhp(linha);
|
|
165
|
+
if (funcao) {
|
|
166
|
+
const nome = funcao[1];
|
|
167
|
+
if (!["__construct", "__destruct"].includes(nome)) {
|
|
168
|
+
const classeAtual = pilhaClasses[pilhaClasses.length - 1];
|
|
169
|
+
const simbolo = classeAtual ? `${classeAtual.nome}.${nome}` : nome;
|
|
170
|
+
simbolos.set(simbolo, {
|
|
171
|
+
simbolo,
|
|
172
|
+
aliases: classeAtual ? variantesNamespacePhp(namespaceAtual, classeAtual.nome, nome) : [],
|
|
173
|
+
retorno: funcao[3]?.trim(),
|
|
174
|
+
parametros: extrairParametrosPhp(funcao[2] ?? ""),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
profundidade += contarChar(linhaOriginal, "{") - contarChar(linhaOriginal, "}");
|
|
179
|
+
while (!classeSemChaveNaLinha && pilhaClasses.length > 0 && profundidade < pilhaClasses[pilhaClasses.length - 1].profundidade) {
|
|
180
|
+
pilhaClasses.pop();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return [...simbolos.values()];
|
|
184
|
+
}
|
|
185
|
+
export function extrairRotasPhp(codigo) {
|
|
186
|
+
const rotas = new Map();
|
|
187
|
+
const texto = removerComentariosBloco(codigo);
|
|
188
|
+
for (const match of texto.matchAll(/\b(?:Route::|\$?[A-Za-z_]\w*->)(get|post|put|patch|delete|head|options)\s*\(\s*(['"][^'"]+['"])\s*,\s*([\s\S]*?)\)\s*;/gi)) {
|
|
189
|
+
const metodo = match[1].toUpperCase();
|
|
190
|
+
if (!METODOS_HTTP.has(metodo)) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
const caminho = normalizarCaminhoPhp(limparStringPhp(match[2]) ?? "/");
|
|
194
|
+
const simbolo = extrairTargetLaravel(match[3] ?? "") ?? metodo.toLowerCase();
|
|
195
|
+
rotas.set(`${metodo}:${caminho}:${simbolo}`, {
|
|
196
|
+
origem: "php",
|
|
197
|
+
metodo,
|
|
198
|
+
caminho,
|
|
199
|
+
simbolo,
|
|
200
|
+
parametros: extrairParametrosRotaPhp(caminho, ""),
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
const linhas = texto.split(/\r?\n/);
|
|
204
|
+
const pilhaClasses = [];
|
|
205
|
+
let atributoPendente;
|
|
206
|
+
let profundidade = 0;
|
|
207
|
+
for (const linhaOriginal of linhas) {
|
|
208
|
+
const linha = linhaOriginal.trim();
|
|
209
|
+
const atributo = extrairAtributoRoutePhp(linha);
|
|
210
|
+
if (atributo) {
|
|
211
|
+
atributoPendente = atributo;
|
|
212
|
+
continue;
|
|
213
|
+
}
|
|
214
|
+
const classe = linha.match(/\b(?:class|trait)\s+([A-Za-z_]\w*)/);
|
|
215
|
+
const classeSemChaveNaLinha = Boolean(classe && !linhaOriginal.includes("{"));
|
|
216
|
+
if (classe) {
|
|
217
|
+
pilhaClasses.push({
|
|
218
|
+
nome: classe[1],
|
|
219
|
+
profundidade: profundidade + 1,
|
|
220
|
+
rotaBase: atributoPendente?.caminho,
|
|
221
|
+
});
|
|
222
|
+
atributoPendente = undefined;
|
|
223
|
+
}
|
|
224
|
+
const funcao = assinaturaFuncaoPhp(linha);
|
|
225
|
+
if (funcao && atributoPendente) {
|
|
226
|
+
const classeAtual = pilhaClasses[pilhaClasses.length - 1];
|
|
227
|
+
const nome = funcao[1];
|
|
228
|
+
const simbolo = classeAtual ? `${classeAtual.nome}.${nome}` : nome;
|
|
229
|
+
const caminho = juntarCaminhoPhp(classeAtual?.rotaBase, atributoPendente.caminho);
|
|
230
|
+
for (const metodo of atributoPendente.metodos) {
|
|
231
|
+
rotas.set(`${metodo}:${caminho}:${simbolo}`, {
|
|
232
|
+
origem: "php",
|
|
233
|
+
metodo,
|
|
234
|
+
caminho,
|
|
235
|
+
simbolo,
|
|
236
|
+
parametros: extrairParametrosRotaPhp(caminho, funcao[2] ?? ""),
|
|
237
|
+
retorno: funcao[3]?.trim(),
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
atributoPendente = undefined;
|
|
241
|
+
}
|
|
242
|
+
else if (funcao) {
|
|
243
|
+
atributoPendente = undefined;
|
|
244
|
+
}
|
|
245
|
+
profundidade += contarChar(linhaOriginal, "{") - contarChar(linhaOriginal, "}");
|
|
246
|
+
while (!classeSemChaveNaLinha && pilhaClasses.length > 0 && profundidade < pilhaClasses[pilhaClasses.length - 1].profundidade) {
|
|
247
|
+
pilhaClasses.pop();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return [...rotas.values()];
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=php-http.js.map
|
package/dist/projetoBusca.js
CHANGED
package/dist/projetoConfig.js
CHANGED
|
@@ -52,7 +52,7 @@ export function normalizarFrameworkGeracao(valor) {
|
|
|
52
52
|
return "base";
|
|
53
53
|
}
|
|
54
54
|
export function normalizarAlvo(valor) {
|
|
55
|
-
if (valor === "typescript" || valor === "python" || valor === "dart" || valor === "lua" || valor === "javascript" || valor === "html" || valor === "css") {
|
|
55
|
+
if (valor === "typescript" || valor === "python" || valor === "dart" || valor === "lua" || valor === "javascript" || valor === "html" || valor === "css" || valor === "php") {
|
|
56
56
|
return valor;
|
|
57
57
|
}
|
|
58
58
|
if (valor === "js") {
|
|
@@ -85,7 +85,8 @@ export function normalizarFonteLegado(valor) {
|
|
|
85
85
|
|| valor === "java"
|
|
86
86
|
|| valor === "go"
|
|
87
87
|
|| valor === "rust"
|
|
88
|
-
|| valor === "cpp"
|
|
88
|
+
|| valor === "cpp"
|
|
89
|
+
|| valor === "php") {
|
|
89
90
|
return valor;
|
|
90
91
|
}
|
|
91
92
|
return undefined;
|
package/dist/projetoLegado.js
CHANGED
|
@@ -45,6 +45,8 @@ export async function inferirFontesLegado(diretoriosCodigo, baseProjeto, configC
|
|
|
45
45
|
const arquivosRust = await listarArquivosRecursivosLimitado(diretorio, [".rs"], 5, 20);
|
|
46
46
|
const arquivosCppBrutos = await listarArquivosRecursivosLimitado(diretorio, [".cpp", ".cc", ".cxx", ".hpp", ".h"], 5, 30);
|
|
47
47
|
const arquivosCpp = arquivosCppBrutos.filter((arquivo) => !/(^|[\\/])(windows|linux|macos|runner|flutter|ephemeral|build|vendor)([\\/]|$)/i.test(arquivo));
|
|
48
|
+
const arquivosPhp = (await listarArquivosRecursivosLimitado(diretorio, [".php"], 5, 30))
|
|
49
|
+
.filter((arquivo) => !/(^|[\\/])(vendor|storage|bootstrap[\\/]cache|cache|tests?)([\\/]|$)/i.test(arquivo));
|
|
48
50
|
if (arquivosTs.length > 0) {
|
|
49
51
|
encontrados.add("typescript");
|
|
50
52
|
}
|
|
@@ -176,6 +178,15 @@ export async function inferirFontesLegado(diretoriosCodigo, baseProjeto, configC
|
|
|
176
178
|
if (arquivosCpp.length > 0) {
|
|
177
179
|
encontrados.add("cpp");
|
|
178
180
|
}
|
|
181
|
+
if (arquivosPhp.length > 0) {
|
|
182
|
+
encontrados.add("php");
|
|
183
|
+
const composer = await procurarArquivosPorNome(diretorio, ["composer.json"], 4);
|
|
184
|
+
const amostrasPhp = await Promise.all(arquivosPhp.slice(0, 8).map((arquivo) => lerConteudoSeExistir(arquivo)));
|
|
185
|
+
if (composer.length > 0
|
|
186
|
+
|| amostrasPhp.some((texto) => /Route::(?:get|post|put|patch|delete)|#\[\s*Route\s*\(|namespace\s+App\\|use\s+Illuminate\\|use\s+Symfony\\/i.test(texto ?? ""))) {
|
|
187
|
+
encontrados.add("php");
|
|
188
|
+
}
|
|
189
|
+
}
|
|
179
190
|
}
|
|
180
191
|
return [...encontrados].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
181
192
|
}
|
package/dist/tipos.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export type EstruturaSaida = "flat" | "modulos" | "backend";
|
|
2
|
-
export type FonteLegado = "nestjs" | "fastapi" | "flask" | "nextjs" | "nextjs-consumer" | "react-vite-consumer" | "angular-consumer" | "flutter-consumer" | "firebase" | "typescript" | "javascript" | "python" | "dart" | "lua" | "dotnet" | "java" | "go" | "rust" | "cpp";
|
|
2
|
+
export type FonteLegado = "nestjs" | "fastapi" | "flask" | "nextjs" | "nextjs-consumer" | "react-vite-consumer" | "angular-consumer" | "flutter-consumer" | "firebase" | "typescript" | "javascript" | "python" | "dart" | "lua" | "dotnet" | "java" | "go" | "rust" | "cpp" | "php";
|
|
3
3
|
export type ModoAdocao = "incremental";
|
package/docs/ai-workflow.md
CHANGED
|
@@ -35,7 +35,7 @@ If the delivery includes code derived from a contract, run `sema compilar`.
|
|
|
35
35
|
sema compilar contratos/orders.sema --alvo javascript --saida ./generated/javascript
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
Replace `javascript` with `typescript`, `python`, `dart`, `lua`, `html`, or `css` when appropriate.
|
|
38
|
+
Replace `javascript` with `typescript`, `python`, `php`, `dart`, `lua`, `html`, or `css` when appropriate.
|
|
39
39
|
|
|
40
40
|
## Fail Closed
|
|
41
41
|
|
package/docs/commands.md
CHANGED
|
@@ -36,7 +36,7 @@ Honest closure: treat drift JSON as the source of truth. `sucesso:false`, `vincu
|
|
|
36
36
|
|
|
37
37
|
## Sema Code
|
|
38
38
|
|
|
39
|
-
- `sema compilar <arquivo-ou-pasta> --alvo <typescript|python|dart|lua|javascript|html|css> --saida <diretorio>`: generates starter/support artifacts from the contract.
|
|
39
|
+
- `sema compilar <arquivo-ou-pasta> --alvo <typescript|python|php|dart|lua|javascript|html|css> --saida <diretorio>`: generates starter/support artifacts from the contract.
|
|
40
40
|
- `sema testar <arquivo.sema> --alvo <alvo> --saida <diretorio-temporario>`: generates and runs local tests when the target supports it.
|
|
41
41
|
- `sema importar <fonte> <diretorio> --saida <diretorio> --json`: imports a legacy project into initial contracts.
|
|
42
42
|
- `sema renomear-semantico <arquivo-ou-pasta> --de <nome> --para <nome> --json`: helps rename symbols semantically.
|
|
@@ -49,7 +49,7 @@ Ready UI rule: if the task generates an app, site, dashboard, form, or static HT
|
|
|
49
49
|
|
|
50
50
|
## Canonical Syntax Lists
|
|
51
51
|
|
|
52
|
-
- Origins for `use` and `impl`: `ts/typescript`, `js/javascript`, `py/python`, `dart`, `lua`, `cs/dotnet`, `java`, `go`, `rust`, `cpp`.
|
|
52
|
+
- Origins for `use` and `impl`: `ts/typescript`, `js/javascript`, `py/python`, `dart`, `lua`, `cs/dotnet`, `java`, `go`, `rust`, `cpp`, `php`.
|
|
53
53
|
- Frequent `effects` categories: `persistencia`, `consulta`, `evento`, `auditoria`, `db.write`, `queue.publish`, `fs.write`, `network.egress`, `secret.read`, `shell.exec`.
|
|
54
54
|
- Accepted `audit.motivo` values: `obrigatorio`, `opcional`, `dispensado`.
|
|
55
55
|
|
package/docs/syntax.md
CHANGED
|
@@ -74,6 +74,7 @@ Use these origins before inventing a new one:
|
|
|
74
74
|
- `go`
|
|
75
75
|
- `rust`
|
|
76
76
|
- `cpp`
|
|
77
|
+
- `php`
|
|
77
78
|
|
|
78
79
|
Examples:
|
|
79
80
|
|
|
@@ -104,13 +105,13 @@ impl {
|
|
|
104
105
|
|
|
105
106
|
## JavaScript Is Supported
|
|
106
107
|
|
|
107
|
-
The CLI supports JavaScript generation:
|
|
108
|
+
The CLI supports JavaScript and PHP generation:
|
|
108
109
|
|
|
109
110
|
```bash
|
|
110
111
|
sema compilar contratos/orders.sema --alvo javascript --saida ./generated/javascript
|
|
111
112
|
```
|
|
112
113
|
|
|
113
|
-
The project can also generate TypeScript, Python, Dart, Lua, HTML, and CSS when those targets are enabled in `sema.config.json`.
|
|
114
|
+
The project can also generate TypeScript, Python, PHP, Dart, Lua, HTML, and CSS when those targets are enabled in `sema.config.json`.
|
|
114
115
|
|
|
115
116
|
## Support Files
|
|
116
117
|
|