@kinkai.cloud/vibecheck 0.1.2 → 0.1.4
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/cli.js +330 -35
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -14543,6 +14543,7 @@ var MAX_BYTES = 256e3;
|
|
|
14543
14543
|
var MAX_ROTULO = 80;
|
|
14544
14544
|
var MAX_ID = 64;
|
|
14545
14545
|
var MAX_CAMINHO = 180;
|
|
14546
|
+
var MAX_PACOTES = 32;
|
|
14546
14547
|
var caminho = external_exports.string().min(1).max(MAX_CAMINHO);
|
|
14547
14548
|
var noSchema = external_exports.object({
|
|
14548
14549
|
id: external_exports.string().min(1).max(MAX_ID),
|
|
@@ -14565,10 +14566,39 @@ var grafoScanSchema = external_exports.object({
|
|
|
14565
14566
|
avancado: external_exports.boolean(),
|
|
14566
14567
|
nos: external_exports.array(noSchema).max(MAX_NOS),
|
|
14567
14568
|
arestas: external_exports.array(arestaSchema).max(MAX_ARESTAS),
|
|
14568
|
-
comunidades: external_exports.array(comunidadeSchema).max(MAX_COMUNIDADES)
|
|
14569
|
+
comunidades: external_exports.array(comunidadeSchema).max(MAX_COMUNIDADES),
|
|
14570
|
+
pacotes: external_exports.array(external_exports.string().min(1).max(MAX_ROTULO)).max(MAX_PACOTES)
|
|
14569
14571
|
});
|
|
14570
14572
|
|
|
14573
|
+
// ../../packages/graph/src/dicas.ts
|
|
14574
|
+
function rotaDeArquivo(caminho2) {
|
|
14575
|
+
const normal = caminho2.replaceAll("\\", "/");
|
|
14576
|
+
const app = /(?:^|\/)app\/(.+)\/route\.(t|j)sx?$/i.exec(normal);
|
|
14577
|
+
if (app?.[1] !== void 0) {
|
|
14578
|
+
const segmentos = app[1].split("/").filter((s) => s.length > 0 && !s.startsWith("(") && !s.startsWith("@")).map((s) => s.replace(/^\[+\.\.\.(.+)\]+$/, "*").replace(/^\[+(.+)\]+$/, ":$1"));
|
|
14579
|
+
if (segmentos.length === 0) return "/api";
|
|
14580
|
+
return `/${segmentos.join("/")}`;
|
|
14581
|
+
}
|
|
14582
|
+
const pages = /(?:^|\/)pages\/api\/(.+)\.(t|j)sx?$/i.exec(normal);
|
|
14583
|
+
if (pages?.[1] !== void 0) {
|
|
14584
|
+
const semIndex = pages[1].replace(/\/index$/i, "");
|
|
14585
|
+
return `/api/${semIndex}`;
|
|
14586
|
+
}
|
|
14587
|
+
return null;
|
|
14588
|
+
}
|
|
14589
|
+
|
|
14571
14590
|
// ../../packages/graph/src/mapear.ts
|
|
14591
|
+
var ROTULO_KIND = {
|
|
14592
|
+
browser: "navegador",
|
|
14593
|
+
app: "aplica\xE7\xE3o",
|
|
14594
|
+
api: "API",
|
|
14595
|
+
db: "banco",
|
|
14596
|
+
storage: "arquivos",
|
|
14597
|
+
auth: "autentica\xE7\xE3o",
|
|
14598
|
+
ai: "IA",
|
|
14599
|
+
payments: "pagamentos",
|
|
14600
|
+
secrets: "segredos"
|
|
14601
|
+
};
|
|
14572
14602
|
var REGRAS = [
|
|
14573
14603
|
{
|
|
14574
14604
|
kind: "api",
|
|
@@ -14593,13 +14623,78 @@ function mapearKind(sinal) {
|
|
|
14593
14623
|
return "app";
|
|
14594
14624
|
}
|
|
14595
14625
|
|
|
14626
|
+
// ../../packages/graph/src/pacotes.ts
|
|
14627
|
+
var CARA_DE_CHAVE = /(sk_live_|sk_test_|rk_live_|pk_live_|pk_test_|sb_secret_|eyJ[A-Za-z0-9_-]{20,}|gsk_[A-Za-z0-9]|sk-ant-|sk-proj-|sk-or-v1-)/i;
|
|
14628
|
+
var REGRAS2 = [
|
|
14629
|
+
{ id: "next", teste: /^next(?:\/|$)/ },
|
|
14630
|
+
{ id: "react", teste: /^react(?:-dom)?(?:\/|$)/ },
|
|
14631
|
+
{ id: "vue", teste: /^vue(?:\/|$)/ },
|
|
14632
|
+
{ id: "svelte", teste: /^svelte(?:\/|$)/ },
|
|
14633
|
+
{ id: "angular", teste: /^@angular\// },
|
|
14634
|
+
{ id: "vite", teste: /^vite(?:\/|$)/ },
|
|
14635
|
+
{ id: "astro", teste: /^astro(?:\/|$)/ },
|
|
14636
|
+
{ id: "stripe", teste: /^(?:stripe|@stripe\/)/ },
|
|
14637
|
+
{ id: "supabase", teste: /^(?:@supabase\/|@supabase$)/ },
|
|
14638
|
+
{ id: "firebase", teste: /^(?:firebase|@firebase\/)/ },
|
|
14639
|
+
{ id: "clerk", teste: /^@clerk\// },
|
|
14640
|
+
{ id: "next-auth", teste: /^(?:next-auth|@auth\/)/ },
|
|
14641
|
+
{ id: "prisma", teste: /^(?:@prisma\/client|prisma)(?:\/|$)/ },
|
|
14642
|
+
{ id: "drizzle", teste: /^drizzle-orm(?:\/|$)/ },
|
|
14643
|
+
{ id: "kysely", teste: /^kysely(?:\/|$)/ },
|
|
14644
|
+
{ id: "postgres", teste: /^(?:postgres|pg|@neondatabase\/)/ },
|
|
14645
|
+
{ id: "mongodb", teste: /^(?:mongodb|mongoose)(?:\/|$)/ },
|
|
14646
|
+
{ id: "styled-components", teste: /^styled-components(?:\/|$)/ },
|
|
14647
|
+
{ id: "emotion", teste: /^@emotion\// },
|
|
14648
|
+
{ id: "tailwind", teste: /^tailwindcss(?:\/|$)/ },
|
|
14649
|
+
{ id: "openai", teste: /^openai(?:\/|$)/ },
|
|
14650
|
+
{ id: "anthropic", teste: /^@anthropic-ai\// },
|
|
14651
|
+
{ id: "langchain", teste: /^langchain(?:\/|$)/ },
|
|
14652
|
+
{ id: "trpc", teste: /^@trpc\// },
|
|
14653
|
+
{ id: "hono", teste: /^hono(?:\/|$)/ },
|
|
14654
|
+
{ id: "express", teste: /^express(?:\/|$)/ },
|
|
14655
|
+
{ id: "fastify", teste: /^fastify(?:\/|$)/ },
|
|
14656
|
+
{ id: "graphql", teste: /^(?:graphql|@apollo\/)/ },
|
|
14657
|
+
{ id: "redis", teste: /^(?:redis|ioredis)(?:\/|$)/ },
|
|
14658
|
+
{ id: "resend", teste: /^resend(?:\/|$)/ },
|
|
14659
|
+
{ id: "auth0", teste: /^(?:auth0|@auth0\/)/ },
|
|
14660
|
+
{ id: "lucia", teste: /^lucia(?:\/|$)/ },
|
|
14661
|
+
{ id: "kinde", teste: /^@kinde-oss\// }
|
|
14662
|
+
];
|
|
14663
|
+
function idDePacote(spec) {
|
|
14664
|
+
const limpo = spec.trim().replace(/^npm:/, "");
|
|
14665
|
+
if (limpo.length === 0 || limpo.startsWith(".") || limpo.startsWith("/")) return null;
|
|
14666
|
+
if (limpo.startsWith("node:") || limpo.startsWith("#")) return null;
|
|
14667
|
+
for (const regra of REGRAS2) {
|
|
14668
|
+
if (regra.teste.test(limpo)) return regra.id;
|
|
14669
|
+
}
|
|
14670
|
+
return null;
|
|
14671
|
+
}
|
|
14672
|
+
function sanitizarPacote(bruto) {
|
|
14673
|
+
const limpo = bruto.trim().slice(0, MAX_ROTULO);
|
|
14674
|
+
if (limpo.length === 0) return null;
|
|
14675
|
+
if (CARA_DE_CHAVE.test(limpo)) return null;
|
|
14676
|
+
if (!/^[@a-z0-9][a-z0-9._+/-]{0,60}$/i.test(limpo)) return null;
|
|
14677
|
+
return limpo;
|
|
14678
|
+
}
|
|
14679
|
+
function uniquePacotes(values) {
|
|
14680
|
+
const seen = /* @__PURE__ */ new Set();
|
|
14681
|
+
const out = [];
|
|
14682
|
+
for (const value of values) {
|
|
14683
|
+
if (out.length >= MAX_PACOTES) break;
|
|
14684
|
+
const limpo = sanitizarPacote(value);
|
|
14685
|
+
if (limpo === null || seen.has(limpo)) continue;
|
|
14686
|
+
seen.add(limpo);
|
|
14687
|
+
out.push(limpo);
|
|
14688
|
+
}
|
|
14689
|
+
return out;
|
|
14690
|
+
}
|
|
14691
|
+
|
|
14596
14692
|
// ../../packages/graph/src/sanitize.ts
|
|
14597
14693
|
var CAMPOS_CORPO = /* @__PURE__ */ new Set([
|
|
14598
14694
|
"content",
|
|
14599
14695
|
"snippet",
|
|
14600
14696
|
"code",
|
|
14601
14697
|
"rationale",
|
|
14602
|
-
"source",
|
|
14603
14698
|
"body",
|
|
14604
14699
|
"text",
|
|
14605
14700
|
"source_location",
|
|
@@ -14609,7 +14704,7 @@ var CAMPOS_CORPO = /* @__PURE__ */ new Set([
|
|
|
14609
14704
|
]);
|
|
14610
14705
|
var EXTENSOES_SEGREDO = /\.(env|pem|key|p12|pfx|crt|cer|p8|keystore)(?:\.|$)/i;
|
|
14611
14706
|
var SEGMENTO_PROIBIDO = /(?:^|\/)(?:\.env(?:\..+)?|id_rsa|id_ed25519|credentials|secrets?)(?:\/|$)/i;
|
|
14612
|
-
var
|
|
14707
|
+
var CARA_DE_CHAVE2 = /(sk_live_|sk_test_|rk_live_|pk_live_|pk_test_|sb_secret_|sb_publishable_|eyJ[A-Za-z0-9_-]{20,}|gsk_[A-Za-z0-9]|sk-ant-|sk-proj-|sk-or-v1-)/i;
|
|
14613
14708
|
var MAX_ROTULO_ARQUIVO = MAX_CAMINHO;
|
|
14614
14709
|
function eRecord(value) {
|
|
14615
14710
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -14631,7 +14726,7 @@ function sanitizarCaminho(bruto) {
|
|
|
14631
14726
|
function redigirRotulo(bruto) {
|
|
14632
14727
|
const limpo = bruto.trim().slice(0, MAX_ROTULO);
|
|
14633
14728
|
if (limpo.length === 0) return "n\xF3";
|
|
14634
|
-
if (
|
|
14729
|
+
if (CARA_DE_CHAVE2.test(limpo)) return "[redigido]";
|
|
14635
14730
|
return limpo;
|
|
14636
14731
|
}
|
|
14637
14732
|
function uniqueCapped(values, cap) {
|
|
@@ -14676,10 +14771,28 @@ function stripCorpo(value) {
|
|
|
14676
14771
|
const out = {};
|
|
14677
14772
|
for (const [chave, item] of Object.entries(value)) {
|
|
14678
14773
|
if (CAMPOS_CORPO.has(chave)) continue;
|
|
14774
|
+
if (chave === "source" && typeof item === "string" && (item.includes("\n") || item.length > MAX_ID)) {
|
|
14775
|
+
continue;
|
|
14776
|
+
}
|
|
14679
14777
|
out[chave] = stripCorpo(item);
|
|
14680
14778
|
}
|
|
14681
14779
|
return out;
|
|
14682
14780
|
}
|
|
14781
|
+
function primeiroExport(value) {
|
|
14782
|
+
if (typeof value === "string" && value.length > 0) {
|
|
14783
|
+
const primeiro = value.split(/[\s,]+/)[0];
|
|
14784
|
+
return primeiro !== void 0 && primeiro.length > 0 ? primeiro : null;
|
|
14785
|
+
}
|
|
14786
|
+
if (!Array.isArray(value)) return null;
|
|
14787
|
+
for (const item of value) {
|
|
14788
|
+
if (typeof item === "string" && item.length > 0) return item;
|
|
14789
|
+
if (eRecord(item)) {
|
|
14790
|
+
const nome = comoString(item["name"]) ?? comoString(item["identifier"]);
|
|
14791
|
+
if (nome !== null) return nome;
|
|
14792
|
+
}
|
|
14793
|
+
}
|
|
14794
|
+
return null;
|
|
14795
|
+
}
|
|
14683
14796
|
function nosDoDump(dump) {
|
|
14684
14797
|
const bruto = dump["nodes"] ?? dump["nos"];
|
|
14685
14798
|
const lista = Array.isArray(bruto) ? bruto : eRecord(bruto) ? Object.entries(bruto).map(
|
|
@@ -14692,7 +14805,7 @@ function nosDoDump(dump) {
|
|
|
14692
14805
|
item["arquivos"] ?? item["files"] ?? item["source_file"] ?? item["sourceFile"] ?? item["file"] ?? item["path"]
|
|
14693
14806
|
);
|
|
14694
14807
|
const rotulo = redigirRotulo(
|
|
14695
|
-
comoString(item["rotulo"]) ?? comoString(item["label"]) ?? comoString(item["name"]) ?? arquivos[0] ?? `n\xF3-${String(i)}`
|
|
14808
|
+
comoString(item["rotulo"]) ?? comoString(item["label"]) ?? comoString(item["name"]) ?? comoString(item["identifier"]) ?? comoString(item["symbol"]) ?? primeiroExport(item["exports"] ?? item["identificadores"]) ?? arquivos[0] ?? `n\xF3-${String(i)}`
|
|
14696
14809
|
);
|
|
14697
14810
|
const kindBruto = comoString(item["kind"]) ?? comoString(item["nodeKind"]);
|
|
14698
14811
|
const kind = kindBruto !== null && NODE_KINDS.includes(kindBruto) ? kindBruto : mapearKind({ rotulo, arquivos });
|
|
@@ -14753,7 +14866,7 @@ function comunidadesDoDump(dump, nos) {
|
|
|
14753
14866
|
seen.add(nodeKind);
|
|
14754
14867
|
out2.push({
|
|
14755
14868
|
nodeKind,
|
|
14756
|
-
rotulo:
|
|
14869
|
+
rotulo: ROTULO_KIND[nodeKind],
|
|
14757
14870
|
arquivos: uniqueCapped(
|
|
14758
14871
|
arquivosDe(item["arquivos"] ?? item["files"]),
|
|
14759
14872
|
MAX_ARQUIVOS_COMUNIDADE
|
|
@@ -14775,7 +14888,7 @@ function comunidadesDoDump(dump, nos) {
|
|
|
14775
14888
|
if (grupo === void 0) continue;
|
|
14776
14889
|
const arquivos = uniqueCapped(grupo.arquivos, MAX_ARQUIVOS_COMUNIDADE);
|
|
14777
14890
|
if (arquivos.length === 0 && grupo.rotulo.length === 0) continue;
|
|
14778
|
-
out.push({ nodeKind: kind, rotulo:
|
|
14891
|
+
out.push({ nodeKind: kind, rotulo: ROTULO_KIND[kind], arquivos });
|
|
14779
14892
|
if (out.length >= MAX_COMUNIDADES) break;
|
|
14780
14893
|
}
|
|
14781
14894
|
return out;
|
|
@@ -14795,6 +14908,7 @@ function sanitizarGrafo(entrada) {
|
|
|
14795
14908
|
const ids = new Set(nos.map((n) => n.id));
|
|
14796
14909
|
const arestas = arestasDoDump(limpo, ids);
|
|
14797
14910
|
const comunidades = comunidadesDoDump(limpo, nos);
|
|
14911
|
+
const pacotes = uniquePacotes(pacotesDoDump(limpo, nos));
|
|
14798
14912
|
const temArquivo = comunidades.some((c) => c.arquivos.length > 0) || nos.some((n) => n.arquivos.length > 0);
|
|
14799
14913
|
if (!temArquivo) return { ok: false, motivo: "vazio" };
|
|
14800
14914
|
const avancado = comunidades.length > 0;
|
|
@@ -14805,10 +14919,24 @@ function sanitizarGrafo(entrada) {
|
|
|
14805
14919
|
avancado,
|
|
14806
14920
|
nos,
|
|
14807
14921
|
arestas,
|
|
14808
|
-
comunidades
|
|
14922
|
+
comunidades,
|
|
14923
|
+
pacotes
|
|
14809
14924
|
}
|
|
14810
14925
|
};
|
|
14811
14926
|
}
|
|
14927
|
+
function pacotesDoDump(dump, nos) {
|
|
14928
|
+
const brutos = [];
|
|
14929
|
+
const campo = dump["pacotes"] ?? dump["packages"];
|
|
14930
|
+
if (Array.isArray(campo)) {
|
|
14931
|
+
for (const item of campo) {
|
|
14932
|
+
if (typeof item === "string") brutos.push(item);
|
|
14933
|
+
}
|
|
14934
|
+
}
|
|
14935
|
+
for (const no of nos) {
|
|
14936
|
+
if (no.id.startsWith("pkg:")) brutos.push(no.rotulo);
|
|
14937
|
+
}
|
|
14938
|
+
return brutos;
|
|
14939
|
+
}
|
|
14812
14940
|
|
|
14813
14941
|
// src/graphify.ts
|
|
14814
14942
|
import { spawn } from "child_process";
|
|
@@ -14918,6 +15046,9 @@ async function abrirBrowser(url2) {
|
|
|
14918
15046
|
if (await tentarSpawn(cmd, args)) return;
|
|
14919
15047
|
}
|
|
14920
15048
|
}
|
|
15049
|
+
function deveAbrirNavegador(opts) {
|
|
15050
|
+
return !opts.ci && !opts.noWait;
|
|
15051
|
+
}
|
|
14921
15052
|
async function detalheHttp(resposta) {
|
|
14922
15053
|
const tipo = resposta.headers.get("content-type") ?? "";
|
|
14923
15054
|
if (tipo.includes("application/json")) {
|
|
@@ -14978,16 +15109,13 @@ var IGNORAR = /* @__PURE__ */ new Set([
|
|
|
14978
15109
|
"build"
|
|
14979
15110
|
]);
|
|
14980
15111
|
var CODIGO = /\.(m?[jt]sx?)$/;
|
|
14981
|
-
var
|
|
14982
|
-
|
|
14983
|
-
|
|
14984
|
-
|
|
14985
|
-
|
|
14986
|
-
|
|
14987
|
-
|
|
14988
|
-
{ re: /\bclerk\b|next-auth/i, rotulo: "clerk" }
|
|
14989
|
-
];
|
|
14990
|
-
var IMPORT_SINAL = /from\s+['"](@supabase\/|@clerk\/|stripe|firebase|openai|@anthropic|next-auth)/i;
|
|
15112
|
+
var MAX_ARQUIVOS = 800;
|
|
15113
|
+
var MAX_NOS_WALKER = 120;
|
|
15114
|
+
var EXT = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js"];
|
|
15115
|
+
var EXPORT_RE = /export\s+(?:default\s+)?(?:async\s+)?(?:function\*?|class|const|let|var|enum)\s+([A-Za-z_$][\w$]*)/g;
|
|
15116
|
+
var EXPORT_LISTA_RE = /export\s+\{([^}]+)\}/g;
|
|
15117
|
+
var FROM_RE = /(?:from\s+|import\s*\(\s*|require\s*\(\s*)['"]([^'"]+)['"]/g;
|
|
15118
|
+
var HANDLERS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"]);
|
|
14991
15119
|
function listar(raiz, dir, acc) {
|
|
14992
15120
|
let nomes;
|
|
14993
15121
|
try {
|
|
@@ -15010,31 +15138,196 @@ function listar(raiz, dir, acc) {
|
|
|
15010
15138
|
}
|
|
15011
15139
|
if (!stat.isFile() || !CODIGO.test(nome)) continue;
|
|
15012
15140
|
acc.push(cheio);
|
|
15013
|
-
if (acc.length >=
|
|
15141
|
+
if (acc.length >= MAX_ARQUIVOS) return;
|
|
15014
15142
|
}
|
|
15015
15143
|
}
|
|
15016
|
-
function
|
|
15017
|
-
|
|
15144
|
+
function posixRel(raiz, cheio) {
|
|
15145
|
+
return relative(raiz, cheio).replaceAll("\\", "/");
|
|
15146
|
+
}
|
|
15147
|
+
function dirnamePosix(caminho2) {
|
|
15148
|
+
const i = caminho2.lastIndexOf("/");
|
|
15149
|
+
return i <= 0 ? "" : caminho2.slice(0, i);
|
|
15150
|
+
}
|
|
15151
|
+
function normalizarPosix(caminho2) {
|
|
15152
|
+
const partes = [];
|
|
15153
|
+
for (const p of caminho2.replaceAll("\\", "/").split("/")) {
|
|
15154
|
+
if (p === "" || p === ".") continue;
|
|
15155
|
+
if (p === "..") {
|
|
15156
|
+
partes.pop();
|
|
15157
|
+
continue;
|
|
15158
|
+
}
|
|
15159
|
+
partes.push(p);
|
|
15160
|
+
}
|
|
15161
|
+
return partes.join("/");
|
|
15162
|
+
}
|
|
15163
|
+
function exportsDe(conteudo) {
|
|
15164
|
+
const out = [];
|
|
15165
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15166
|
+
const push = (nome) => {
|
|
15167
|
+
if (nome.length === 0 || seen.has(nome)) return;
|
|
15168
|
+
seen.add(nome);
|
|
15169
|
+
out.push(nome);
|
|
15170
|
+
};
|
|
15171
|
+
EXPORT_RE.lastIndex = 0;
|
|
15172
|
+
let m;
|
|
15173
|
+
while ((m = EXPORT_RE.exec(conteudo)) !== null) {
|
|
15174
|
+
if (m[1] !== void 0) push(m[1]);
|
|
15175
|
+
}
|
|
15176
|
+
EXPORT_LISTA_RE.lastIndex = 0;
|
|
15177
|
+
while ((m = EXPORT_LISTA_RE.exec(conteudo)) !== null) {
|
|
15178
|
+
const lista = m[1];
|
|
15179
|
+
if (lista === void 0) continue;
|
|
15180
|
+
for (const parte of lista.split(",")) {
|
|
15181
|
+
const nome = parte.trim().split(/\s+as\s+/).at(-1)?.trim();
|
|
15182
|
+
if (nome !== void 0 && /^[A-Za-z_$][\w$]*$/.test(nome)) push(nome);
|
|
15183
|
+
}
|
|
15184
|
+
}
|
|
15185
|
+
return out;
|
|
15186
|
+
}
|
|
15187
|
+
function specsDe(conteudo) {
|
|
15188
|
+
const out = [];
|
|
15189
|
+
FROM_RE.lastIndex = 0;
|
|
15190
|
+
let m;
|
|
15191
|
+
while ((m = FROM_RE.exec(conteudo)) !== null) {
|
|
15192
|
+
if (m[1] !== void 0) out.push(m[1]);
|
|
15193
|
+
}
|
|
15194
|
+
return out;
|
|
15195
|
+
}
|
|
15196
|
+
function acharNoIndice(specPath, indice) {
|
|
15197
|
+
const n = specPath.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
15198
|
+
for (const ext of EXT) {
|
|
15199
|
+
const hit = indice.get(n + ext);
|
|
15200
|
+
if (hit !== void 0) return hit;
|
|
15201
|
+
}
|
|
15202
|
+
return null;
|
|
15203
|
+
}
|
|
15204
|
+
function resolverSpec(de, spec, indice) {
|
|
15205
|
+
if (spec.startsWith(".")) {
|
|
15206
|
+
const base = normalizarPosix(`${dirnamePosix(de)}/${spec}`);
|
|
15207
|
+
return acharNoIndice(base, indice);
|
|
15208
|
+
}
|
|
15209
|
+
const alias = spec.startsWith("@/") ? spec.slice(2) : spec.startsWith("~/") ? spec.slice(2) : null;
|
|
15210
|
+
if (alias === null) return null;
|
|
15211
|
+
for (const prefixo of ["", "src/", "app/"]) {
|
|
15212
|
+
const hit = acharNoIndice(`${prefixo}${alias}`, indice);
|
|
15213
|
+
if (hit !== null) return hit;
|
|
15214
|
+
}
|
|
15215
|
+
return null;
|
|
15216
|
+
}
|
|
15217
|
+
function rotuloDe(rel, exports) {
|
|
15218
|
+
const rota = rotaDeArquivo(rel);
|
|
15219
|
+
const handlers = exports.filter((e) => HANDLERS.has(e));
|
|
15220
|
+
if (rota !== null && handlers.length > 0) return `${handlers[0]} ${rota}`;
|
|
15221
|
+
if (rota !== null) return rota;
|
|
15222
|
+
const simbolo = exports.find((e) => !HANDLERS.has(e));
|
|
15223
|
+
if (simbolo !== void 0) return simbolo;
|
|
15224
|
+
const base = rel.split("/").at(-1)?.replace(/\.(m?[jt]sx?)$/i, "");
|
|
15225
|
+
return base !== void 0 && base.length > 0 && base !== "index" ? base : rel;
|
|
15226
|
+
}
|
|
15227
|
+
function lerArquivo(raiz, cheio) {
|
|
15228
|
+
const rel = posixRel(raiz, cheio);
|
|
15018
15229
|
let conteudo = "";
|
|
15019
15230
|
try {
|
|
15020
|
-
conteudo = readFileSync2(cheio, "utf8").slice(0,
|
|
15231
|
+
conteudo = readFileSync2(cheio, "utf8").slice(0, 12e3);
|
|
15021
15232
|
} catch {
|
|
15022
15233
|
return null;
|
|
15023
15234
|
}
|
|
15024
|
-
const
|
|
15025
|
-
|
|
15235
|
+
const exports = exportsDe(conteudo);
|
|
15236
|
+
const specs = specsDe(conteudo);
|
|
15237
|
+
return {
|
|
15238
|
+
rel,
|
|
15239
|
+
rotulo: rotuloDe(rel, exports),
|
|
15240
|
+
exports,
|
|
15241
|
+
importsRel: specs.filter((s) => s.startsWith(".") || s.startsWith("@/") || s.startsWith("~/")),
|
|
15242
|
+
importsPkg: specs
|
|
15243
|
+
};
|
|
15244
|
+
}
|
|
15245
|
+
function prioridade(info) {
|
|
15246
|
+
const kind = mapearKind({ rotulo: info.rotulo, arquivos: [info.rel] });
|
|
15247
|
+
if (kind === "api") return 0;
|
|
15248
|
+
if (kind === "payments" || kind === "auth" || kind === "db") return 1;
|
|
15249
|
+
if (kind === "storage" || kind === "secrets" || kind === "browser" || kind === "ai") return 2;
|
|
15250
|
+
if (info.importsPkg.some((s) => idDePacote(s) !== null)) return 3;
|
|
15251
|
+
return 8;
|
|
15026
15252
|
}
|
|
15027
15253
|
function extrairDoRepo(raiz) {
|
|
15028
|
-
const
|
|
15029
|
-
listar(raiz, raiz,
|
|
15030
|
-
if (
|
|
15254
|
+
const caminhos = [];
|
|
15255
|
+
listar(raiz, raiz, caminhos);
|
|
15256
|
+
if (caminhos.length === 0) return null;
|
|
15257
|
+
const infos = [];
|
|
15258
|
+
const indice = /* @__PURE__ */ new Map();
|
|
15259
|
+
for (const cheio of caminhos) {
|
|
15260
|
+
const info = lerArquivo(raiz, cheio);
|
|
15261
|
+
if (info === null) continue;
|
|
15262
|
+
infos.push(info);
|
|
15263
|
+
indice.set(info.rel, info.rel);
|
|
15264
|
+
}
|
|
15265
|
+
if (infos.length === 0) return null;
|
|
15266
|
+
const porRel = new Map(infos.map((i) => [i.rel, i]));
|
|
15267
|
+
const escolhidos = /* @__PURE__ */ new Set();
|
|
15268
|
+
const ordenados = [...infos].sort((a, b) => prioridade(a) - prioridade(b) || a.rel.localeCompare(b.rel));
|
|
15269
|
+
for (const info of ordenados) {
|
|
15270
|
+
if (prioridade(info) <= 3) escolhidos.add(info.rel);
|
|
15271
|
+
}
|
|
15272
|
+
const expandir = (saltos) => {
|
|
15273
|
+
let fronteira = [...escolhidos];
|
|
15274
|
+
for (let s = 0; s < saltos; s += 1) {
|
|
15275
|
+
const proxima = [];
|
|
15276
|
+
for (const rel of fronteira) {
|
|
15277
|
+
const info = porRel.get(rel);
|
|
15278
|
+
if (info === void 0) continue;
|
|
15279
|
+
for (const spec of info.importsRel) {
|
|
15280
|
+
const alvo = resolverSpec(rel, spec, indice);
|
|
15281
|
+
if (alvo === null || escolhidos.has(alvo)) continue;
|
|
15282
|
+
escolhidos.add(alvo);
|
|
15283
|
+
proxima.push(alvo);
|
|
15284
|
+
}
|
|
15285
|
+
}
|
|
15286
|
+
fronteira = proxima;
|
|
15287
|
+
}
|
|
15288
|
+
};
|
|
15289
|
+
expandir(2);
|
|
15290
|
+
if (escolhidos.size === 0) {
|
|
15291
|
+
for (const info of ordenados.slice(0, Math.min(24, ordenados.length))) {
|
|
15292
|
+
escolhidos.add(info.rel);
|
|
15293
|
+
}
|
|
15294
|
+
}
|
|
15295
|
+
const files = [...escolhidos].map((rel) => porRel.get(rel)).filter((i) => i !== void 0).sort((a, b) => prioridade(a) - prioridade(b) || a.rel.localeCompare(b.rel)).slice(0, MAX_NOS_WALKER);
|
|
15031
15296
|
const nodes = [];
|
|
15032
|
-
|
|
15033
|
-
|
|
15034
|
-
|
|
15297
|
+
const edges = [];
|
|
15298
|
+
const pacotes = /* @__PURE__ */ new Set();
|
|
15299
|
+
const idDe2 = /* @__PURE__ */ new Map();
|
|
15300
|
+
for (const [i, info] of files.entries()) {
|
|
15301
|
+
const id = `f${String(i)}`;
|
|
15302
|
+
idDe2.set(info.rel, id);
|
|
15303
|
+
nodes.push({
|
|
15304
|
+
id,
|
|
15305
|
+
label: info.rotulo,
|
|
15306
|
+
identifier: info.exports[0] ?? info.rotulo,
|
|
15307
|
+
source_file: info.rel
|
|
15308
|
+
});
|
|
15035
15309
|
}
|
|
15036
|
-
|
|
15037
|
-
|
|
15310
|
+
for (const info of files) {
|
|
15311
|
+
const de = idDe2.get(info.rel);
|
|
15312
|
+
if (de === void 0) continue;
|
|
15313
|
+
for (const spec of info.importsRel) {
|
|
15314
|
+
const alvo = resolverSpec(info.rel, spec, indice);
|
|
15315
|
+
const para = alvo === null ? void 0 : idDe2.get(alvo);
|
|
15316
|
+
if (para === void 0) continue;
|
|
15317
|
+
edges.push({ source: de, target: para, relation: "imports" });
|
|
15318
|
+
}
|
|
15319
|
+
for (const spec of info.importsPkg) {
|
|
15320
|
+
const pkg = idDePacote(spec);
|
|
15321
|
+
if (pkg === null) continue;
|
|
15322
|
+
pacotes.add(pkg);
|
|
15323
|
+
const pkgId = `pkg:${pkg}`;
|
|
15324
|
+
if (!nodes.some((n) => n["id"] === pkgId)) {
|
|
15325
|
+
nodes.push({ id: pkgId, label: pkg });
|
|
15326
|
+
}
|
|
15327
|
+
edges.push({ source: de, target: pkgId, relation: "imports" });
|
|
15328
|
+
}
|
|
15329
|
+
}
|
|
15330
|
+
const sanitizado = sanitizarGrafo({ nodes, edges, pacotes: [...pacotes] });
|
|
15038
15331
|
if (!sanitizado.ok || !sanitizado.grafo.avancado) return null;
|
|
15039
15332
|
return sanitizado.grafo;
|
|
15040
15333
|
}
|
|
@@ -15102,6 +15395,7 @@ async function acompanhar(liveUrl, scanId, shareToken) {
|
|
|
15102
15395
|
}
|
|
15103
15396
|
async function main(argv) {
|
|
15104
15397
|
const ci = temFlag("--ci", argv) || process.env["CI"] === "true" || process.env["VIBECHECK_TOKEN"] !== void 0 && process.env["VIBECHECK_TOKEN"].length > 0;
|
|
15398
|
+
const noWait = temFlag("--no-wait", argv);
|
|
15105
15399
|
const raiz = arg("--dir", argv) ?? process.cwd();
|
|
15106
15400
|
let url2 = arg("--url", argv) ?? argv.find((a) => a.startsWith("http")) ?? null;
|
|
15107
15401
|
let cred = lerToken();
|
|
@@ -15142,6 +15436,9 @@ async function main(argv) {
|
|
|
15142
15436
|
console.error(corpo.error ?? "n\xE3o foi poss\xEDvel abrir o scan");
|
|
15143
15437
|
return 1;
|
|
15144
15438
|
}
|
|
15439
|
+
const live = corpo.liveUrl ?? `${base}/avancado/${corpo.scanId}`;
|
|
15440
|
+
console.warn(live);
|
|
15441
|
+
if (deveAbrirNavegador({ ci, noWait })) await abrirBrowser(live);
|
|
15145
15442
|
if (avancado && grafo !== null) {
|
|
15146
15443
|
const put = await fetch(`${base}/api/cli/scan/${corpo.scanId}/graph`, {
|
|
15147
15444
|
method: "PUT",
|
|
@@ -15150,9 +15447,7 @@ async function main(argv) {
|
|
|
15150
15447
|
});
|
|
15151
15448
|
if (!put.ok) console.warn("grafo rejeitado pelo servidor \u2014 scan segue s\xF3 HTTP");
|
|
15152
15449
|
}
|
|
15153
|
-
|
|
15154
|
-
console.warn(live);
|
|
15155
|
-
if (temFlag("--no-wait", argv)) return 0;
|
|
15450
|
+
if (noWait) return 0;
|
|
15156
15451
|
return acompanhar(live, corpo.scanId, corpo.shareToken ?? "");
|
|
15157
15452
|
}
|
|
15158
15453
|
var codigo = await main(process.argv.slice(2));
|