@neetru/sdk 3.4.0 → 3.4.2
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/CHANGELOG.md +31 -0
- package/dist/ai.d.cts +1 -1
- package/dist/ai.d.ts +1 -1
- package/dist/auth.cjs +230 -38
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/auth.mjs +230 -38
- package/dist/auth.mjs.map +1 -1
- package/dist/build-guard.cjs +41 -6
- package/dist/build-guard.cjs.map +1 -1
- package/dist/build-guard.d.cts +24 -1
- package/dist/build-guard.d.ts +24 -1
- package/dist/build-guard.mjs +40 -7
- package/dist/build-guard.mjs.map +1 -1
- package/dist/catalog.d.cts +1 -1
- package/dist/catalog.d.ts +1 -1
- package/dist/checkout.d.cts +1 -1
- package/dist/checkout.d.ts +1 -1
- package/dist/db-react.d.cts +1 -1
- package/dist/db-react.d.ts +1 -1
- package/dist/db.cjs +230 -38
- package/dist/db.cjs.map +1 -1
- package/dist/db.d.cts +1 -1
- package/dist/db.d.ts +1 -1
- package/dist/db.mjs +230 -38
- package/dist/db.mjs.map +1 -1
- package/dist/entitlements.d.cts +1 -1
- package/dist/entitlements.d.ts +1 -1
- package/dist/firestore-compat.d.cts +1 -1
- package/dist/firestore-compat.d.ts +1 -1
- package/dist/index.cjs +231 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +231 -39
- package/dist/index.mjs.map +1 -1
- package/dist/mocks.d.cts +1 -1
- package/dist/mocks.d.ts +1 -1
- package/dist/notifications.d.cts +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/react.cjs +593 -31
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +97 -2
- package/dist/react.d.ts +97 -2
- package/dist/react.mjs +590 -31
- package/dist/react.mjs.map +1 -1
- package/dist/support.d.cts +1 -1
- package/dist/support.d.ts +1 -1
- package/dist/telemetry.d.cts +1 -1
- package/dist/telemetry.d.ts +1 -1
- package/dist/{types-DdJyqBy-.d.ts → types-BlOLDMR0.d.ts} +79 -6
- package/dist/{types-BoFSCHF_.d.cts → types-D-QdG502.d.cts} +79 -6
- package/dist/usage.d.cts +1 -1
- package/dist/usage.d.ts +1 -1
- package/dist/webhooks.d.cts +1 -1
- package/dist/webhooks.d.ts +1 -1
- package/package.json +1 -1
package/dist/build-guard.cjs
CHANGED
|
@@ -25,6 +25,38 @@ var fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
|
25
25
|
var path__namespace = /*#__PURE__*/_interopNamespace(path);
|
|
26
26
|
|
|
27
27
|
// src/build-guard.ts
|
|
28
|
+
var NeetruBuildGuardError = class extends Error {
|
|
29
|
+
constructor(message) {
|
|
30
|
+
super(message);
|
|
31
|
+
this.name = "NeetruBuildGuardError";
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
function isBlankEnvValue(v) {
|
|
35
|
+
return v == null || v.trim() === "";
|
|
36
|
+
}
|
|
37
|
+
function assertNeetruProdBuildEnv(resolved) {
|
|
38
|
+
if (resolved.builtEnv !== "prod") return;
|
|
39
|
+
const missing = [];
|
|
40
|
+
if (isBlankEnvValue(resolved.oidcClientId)) missing.push("NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID");
|
|
41
|
+
if (isBlankEnvValue(resolved.productId)) missing.push("NEXT_PUBLIC_NEETRU_PRODUCT_ID");
|
|
42
|
+
if (missing.length === 0) return;
|
|
43
|
+
const plural = missing.length > 1;
|
|
44
|
+
throw new NeetruBuildGuardError(
|
|
45
|
+
[
|
|
46
|
+
"[neetru-sdk] BUILD DE PRODU\xC7\xC3O ABORTADO (withNeetruBuildGuard).",
|
|
47
|
+
"",
|
|
48
|
+
`Vari\xE1ve${plural ? "is" : "l"} de ambiente obrigat\xF3ri${plural ? "as" : "a"} ausente${plural ? "s" : ""}/vazia${plural ? "s" : ""} no build de produ\xE7\xE3o (NEXT_PUBLIC_NEETRU_ENV=prod):`,
|
|
49
|
+
...missing.map((v) => ` \u2022 ${v}`),
|
|
50
|
+
"",
|
|
51
|
+
`Sem ${plural ? "essas vari\xE1veis" : "essa vari\xE1vel"} o SDK n\xE3o consegue montar o client_id do login OIDC \u2014 o bot\xE3o "Entrar com Neetru" (NeetruLoginButton) N\xC3O redireciona e o login do produto quebra EM SIL\xCANCIO em produ\xE7\xE3o (incidente gestovendas 2026-09-06: workspace recriado perdeu a env var e shippou um build de prod com o client_id vazio).`,
|
|
52
|
+
"",
|
|
53
|
+
"Como corrigir \u2014 defina no .env.production do produto (ou no ambiente do build de deploy):",
|
|
54
|
+
...missing.map((v) => ` ${v}=<valor real vindo do cat\xE1logo do produto no Core>`),
|
|
55
|
+
"",
|
|
56
|
+
"dev/workspace N\xC3O exigem essas vari\xE1veis (usam MockAuth/sandbox) \u2014 s\xF3 o build de produ\xE7\xE3o enfor\xE7a."
|
|
57
|
+
].join("\n")
|
|
58
|
+
);
|
|
59
|
+
}
|
|
28
60
|
function withNeetruBuildGuard(nextConfig, options = {}) {
|
|
29
61
|
const prevWebpack = nextConfig.webpack;
|
|
30
62
|
return {
|
|
@@ -32,15 +64,15 @@ function withNeetruBuildGuard(nextConfig, options = {}) {
|
|
|
32
64
|
webpack(config, context) {
|
|
33
65
|
const result = typeof prevWebpack === "function" ? prevWebpack(config, context) : config;
|
|
34
66
|
if (!context.dev && context.isServer) {
|
|
67
|
+
const manifest = {
|
|
68
|
+
builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,
|
|
69
|
+
productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,
|
|
70
|
+
oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,
|
|
71
|
+
builtAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
72
|
+
};
|
|
35
73
|
try {
|
|
36
74
|
const outDir = path__namespace.resolve(process.cwd(), options.outputDir ?? ".next");
|
|
37
75
|
fs__namespace.mkdirSync(outDir, { recursive: true });
|
|
38
|
-
const manifest = {
|
|
39
|
-
builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,
|
|
40
|
-
productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,
|
|
41
|
-
oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,
|
|
42
|
-
builtAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
43
|
-
};
|
|
44
76
|
fs__namespace.writeFileSync(
|
|
45
77
|
path__namespace.join(outDir, "neetru-build-manifest.json"),
|
|
46
78
|
JSON.stringify(manifest, null, 2),
|
|
@@ -54,12 +86,15 @@ function withNeetruBuildGuard(nextConfig, options = {}) {
|
|
|
54
86
|
);
|
|
55
87
|
}
|
|
56
88
|
}
|
|
89
|
+
assertNeetruProdBuildEnv(manifest);
|
|
57
90
|
}
|
|
58
91
|
return result;
|
|
59
92
|
}
|
|
60
93
|
};
|
|
61
94
|
}
|
|
62
95
|
|
|
96
|
+
exports.NeetruBuildGuardError = NeetruBuildGuardError;
|
|
97
|
+
exports.assertNeetruProdBuildEnv = assertNeetruProdBuildEnv;
|
|
63
98
|
exports.withNeetruBuildGuard = withNeetruBuildGuard;
|
|
64
99
|
//# sourceMappingURL=build-guard.cjs.map
|
|
65
100
|
//# sourceMappingURL=build-guard.cjs.map
|
package/dist/build-guard.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/build-guard.ts"],"names":["path","fs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAwFO,SAAS,oBAAA,CACd,UAAA,EACA,OAAA,GAAuC,EAAC,EACrC;AACH,EAAA,MAAM,cAAc,UAAA,CAAW,OAAA;AAE/B,EAAA,OAAO;AAAA,IACL,GAAG,UAAA;AAAA,IACH,OAAA,CAAQ,QAAiB,OAAA,EAAyC;AAChE,MAAA,MAAM,SAAS,OAAO,WAAA,KAAgB,aAAa,WAAA,CAAY,MAAA,EAAQ,OAAO,CAAA,GAAI,MAAA;AAKlF,MAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,IAAO,OAAA,CAAQ,QAAA,EAAU;AACpC,QAAA,IAAI;AACF,UAAA,MAAM,SAAcA,eAAA,CAAA,OAAA,CAAQ,OAAA,CAAQ,KAAI,EAAG,OAAA,CAAQ,aAAa,OAAO,CAAA;AACvE,UAAGC,aAAA,CAAA,SAAA,CAAU,MAAA,EAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AACxC,UAAA,MAAM,QAAA,GAAgC;AAAA,YACpC,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,sBAAA,IAA0B,IAAA;AAAA,YAChD,SAAA,EAAW,OAAA,CAAQ,GAAA,CAAI,6BAAA,IAAiC,IAAA;AAAA,YACxD,YAAA,EAAc,OAAA,CAAQ,GAAA,CAAI,iCAAA,IAAqC,IAAA;AAAA,YAC/D,OAAA,EAAA,iBAAS,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,WAClC;AACA,UAAGA,aAAA,CAAA,aAAA;AAAA,YACID,eAAA,CAAA,IAAA,CAAK,QAAQ,4BAA4B,CAAA;AAAA,YAC9C,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAA;AAAA,YAChC;AAAA,WACF;AAAA,QACF,SAAS,GAAA,EAAK;AAMZ,UAAA,IAAI,OAAO,YAAY,WAAA,EAAa;AAClC,YAAA,OAAA,CAAQ,IAAA;AAAA,cACN,wGAAA;AAAA,cACA;AAAA,aACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,GACF;AACF","file":"build-guard.cjs","sourcesContent":["/**\r\n * `withNeetruBuildGuard` — wrapper de `next.config.mjs` que grava\r\n * `.next/neetru-build-manifest.json` ao final do build com os valores\r\n * `NEXT_PUBLIC_NEETRU_*` que realmente foram resolvidos pelo Next.js.\r\n *\r\n * Existe pra fechar um bug de precedência de env do Next.js (incidente\r\n * 2026-07-22, pdv-agiliza): `.env.local` (fica no disco do dev) vence\r\n * `.env.production` durante `next build` pra qualquer chave em comum —\r\n * então um build \"de prod\" podia compilar com `NEXT_PUBLIC_NEETRU_ENV=dev`\r\n * sem nenhum aviso, ativando `MockAuth` no bundle do browser em produção\r\n * (o botão \"Entrar com Neetru\" não fazia nada, porque `MockAuth.signIn()`\r\n * só finge um login em memória — nunca navega pro IdP real).\r\n *\r\n * O manifesto não inspeciona o JS compilado (minificação/webpack\r\n * `DefinePlugin` tornam isso frágil — o nome da chave some, só sobra o\r\n * literal). Em vez disso grava, em texto puro, o que o processo Node do\r\n * build efetivamente tinha em `process.env` no momento da compilação\r\n * server-side — reflete fielmente a resolução real do Next.js/dotenv,\r\n * incluindo qualquer override via spawn-env (`@neetru/cli` injeta\r\n * `NEXT_PUBLIC_NEETRU_ENV` assim desde a v2.26.2). `neetru build` lê este\r\n * arquivo depois do build e recusa empacotar o tarball se o valor não\r\n * bater com o ambiente esperado do deploy.\r\n *\r\n * Uso, em `next.config.mjs`:\r\n * ```js\r\n * import { withNeetruBuildGuard } from '@neetru/sdk/build-guard';\r\n * export default withNeetruBuildGuard({ ...nextConfig });\r\n * ```\r\n *\r\n * Subpath dedicado (`@neetru/sdk/build-guard`, não o barrel `.`) de\r\n * propósito: este arquivo é o único no SDK que importa `node:fs`/`node:path`\r\n * estaticamente. O entry `.` promete rodar em browser/Node/Edge sem Node\r\n * builtins — reexportar o guard ali vazaria essa dependência pro bundle\r\n * universal (achado real da revisão: `esbuild --platform=browser` falha com\r\n * \"Could not resolve fs/path\" se o guard entra no barrel principal).\r\n *\r\n * IMPORTANTE — isto NÃO é uma checagem universal de \"o env está certo\": o\r\n * guard grava literalmente as 3 env vars `NEXT_PUBLIC_NEETRU_ENV` /\r\n * `_PRODUCT_ID` / `_OIDC_CLIENT_ID`, que são a convenção recomendada de\r\n * bootstrap Next.js do ecossistema Neetru (o que `neetru-pdvagiliza` e\r\n * outros produtos usam em `src/lib/neetru/client.ts` pra montar\r\n * `createNeetruClient({env, productId, oidcClientId})`) — **não** é o mesmo\r\n * que o fallback interno `NEETRU_ENV`/`globalThis.NEETRU_ENV` que\r\n * `resolveEnv()` (`src/auth.ts`) usa quando NENHUM `env` é passado\r\n * explicitamente pro client. Se o seu produto bootstrap o client de outra\r\n * forma (nome de env var diferente, ou sem prefixo `NEXT_PUBLIC_`, ou\r\n * hardcoded), este guard não detecta drift pra esse caso — ele só confirma\r\n * que a convenção documentada acima foi respeitada.\r\n *\r\n * Composável com qualquer wrapper que já use a chave `webpack` do config\r\n * (ex: `next-pwa`) — a função `webpack` anterior, se houver, é chamada\r\n * primeiro e o retorno dela é repassado adiante sem alteração.\r\n */\r\nimport * as fs from 'node:fs';\r\nimport * as path from 'node:path';\r\n\r\n/** Formato do `.next/neetru-build-manifest.json`. */\r\nexport interface NeetruBuildManifest {\r\n /** `NEXT_PUBLIC_NEETRU_ENV` resolvido no momento do build (`dev|workspace|prod`), ou `null` se ausente. */\r\n builtEnv: string | null;\r\n /** `NEXT_PUBLIC_NEETRU_PRODUCT_ID` resolvido, ou `null`. */\r\n productId: string | null;\r\n /** `NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` resolvido, ou `null`. */\r\n oidcClientId: string | null;\r\n /** ISO timestamp de quando o manifesto foi gravado. */\r\n builtAt: string;\r\n}\r\n\r\nexport interface WithNeetruBuildGuardOptions {\r\n /** Diretório de saída do Next (default `.next`, relativo ao cwd do build). */\r\n outputDir?: string;\r\n}\r\n\r\n/**\r\n * Formato mínimo de `next.config.mjs` que o wrapper precisa entender — só\r\n * o suficiente pra compor a chave `webpack` sem acoplar o SDK ao pacote\r\n * `next` como dependência de tipos.\r\n */\r\ntype MinimalWebpackContext = {\r\n buildId: string;\r\n dev: boolean;\r\n isServer: boolean;\r\n [key: string]: unknown;\r\n};\r\ntype MinimalNextConfig = Record<string, unknown> & {\r\n webpack?: (config: unknown, context: MinimalWebpackContext) => unknown;\r\n};\r\n\r\nexport function withNeetruBuildGuard<T extends MinimalNextConfig>(\r\n nextConfig: T,\r\n options: WithNeetruBuildGuardOptions = {},\r\n): T {\r\n const prevWebpack = nextConfig.webpack;\r\n\r\n return {\r\n ...nextConfig,\r\n webpack(config: unknown, context: MinimalWebpackContext): unknown {\r\n const result = typeof prevWebpack === 'function' ? prevWebpack(config, context) : config;\r\n\r\n // Grava só na passada server (roda 1x por build, diferente da passada\r\n // client que pode rodar múltiplas vezes) e só fora de `next dev` —\r\n // `next build` é sempre produção de artefato de deploy.\r\n if (!context.dev && context.isServer) {\r\n try {\r\n const outDir = path.resolve(process.cwd(), options.outputDir ?? '.next');\r\n fs.mkdirSync(outDir, { recursive: true });\r\n const manifest: NeetruBuildManifest = {\r\n builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,\r\n productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,\r\n oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,\r\n builtAt: new Date().toISOString(),\r\n };\r\n fs.writeFileSync(\r\n path.join(outDir, 'neetru-build-manifest.json'),\r\n JSON.stringify(manifest, null, 2),\r\n 'utf8',\r\n );\r\n } catch (err) {\r\n // Best-effort — o guard nunca pode quebrar o build do produto,\r\n // mas uma falha de escrita silenciosa aqui esconderia o problema\r\n // (achado da revisão: sem log, ninguém percebe que o manifesto não\r\n // foi gravado e `neetru build` trata \"manifesto ausente\" como\r\n // aviso, não bloqueio — visibilidade aqui é a única forma de notar).\r\n if (typeof console !== 'undefined') {\r\n console.warn(\r\n '[neetru-sdk] withNeetruBuildGuard: falha ao gravar neetru-build-manifest.json (ignorado, build segue):',\r\n err,\r\n );\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n },\r\n } as T;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/build-guard.ts"],"names":["path","fs"],"mappings":"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","file":"build-guard.cjs","sourcesContent":["/**\r\n * `withNeetruBuildGuard` — wrapper de `next.config.mjs` que grava\r\n * `.next/neetru-build-manifest.json` ao final do build com os valores\r\n * `NEXT_PUBLIC_NEETRU_*` que realmente foram resolvidos pelo Next.js.\r\n *\r\n * Existe pra fechar um bug de precedência de env do Next.js (incidente\r\n * 2026-07-22, pdv-agiliza): `.env.local` (fica no disco do dev) vence\r\n * `.env.production` durante `next build` pra qualquer chave em comum —\r\n * então um build \"de prod\" podia compilar com `NEXT_PUBLIC_NEETRU_ENV=dev`\r\n * sem nenhum aviso, ativando `MockAuth` no bundle do browser em produção\r\n * (o botão \"Entrar com Neetru\" não fazia nada, porque `MockAuth.signIn()`\r\n * só finge um login em memória — nunca navega pro IdP real).\r\n *\r\n * O manifesto não inspeciona o JS compilado (minificação/webpack\r\n * `DefinePlugin` tornam isso frágil — o nome da chave some, só sobra o\r\n * literal). Em vez disso grava, em texto puro, o que o processo Node do\r\n * build efetivamente tinha em `process.env` no momento da compilação\r\n * server-side — reflete fielmente a resolução real do Next.js/dotenv,\r\n * incluindo qualquer override via spawn-env (`@neetru/cli` injeta\r\n * `NEXT_PUBLIC_NEETRU_ENV` assim desde a v2.26.2). `neetru build` lê este\r\n * arquivo depois do build e recusa empacotar o tarball se o valor não\r\n * bater com o ambiente esperado do deploy.\r\n *\r\n * Uso, em `next.config.mjs`:\r\n * ```js\r\n * import { withNeetruBuildGuard } from '@neetru/sdk/build-guard';\r\n * export default withNeetruBuildGuard({ ...nextConfig });\r\n * ```\r\n *\r\n * Subpath dedicado (`@neetru/sdk/build-guard`, não o barrel `.`) de\r\n * propósito: este arquivo é o único no SDK que importa `node:fs`/`node:path`\r\n * estaticamente. O entry `.` promete rodar em browser/Node/Edge sem Node\r\n * builtins — reexportar o guard ali vazaria essa dependência pro bundle\r\n * universal (achado real da revisão: `esbuild --platform=browser` falha com\r\n * \"Could not resolve fs/path\" se o guard entra no barrel principal).\r\n *\r\n * IMPORTANTE — isto NÃO é uma checagem universal de \"o env está certo\": o\r\n * guard grava literalmente as 3 env vars `NEXT_PUBLIC_NEETRU_ENV` /\r\n * `_PRODUCT_ID` / `_OIDC_CLIENT_ID`, que são a convenção recomendada de\r\n * bootstrap Next.js do ecossistema Neetru (o que `neetru-pdvagiliza` e\r\n * outros produtos usam em `src/lib/neetru/client.ts` pra montar\r\n * `createNeetruClient({env, productId, oidcClientId})`) — **não** é o mesmo\r\n * que o fallback interno `NEETRU_ENV`/`globalThis.NEETRU_ENV` que\r\n * `resolveEnv()` (`src/auth.ts`) usa quando NENHUM `env` é passado\r\n * explicitamente pro client. Se o seu produto bootstrap o client de outra\r\n * forma (nome de env var diferente, ou sem prefixo `NEXT_PUBLIC_`, ou\r\n * hardcoded), este guard não detecta drift pra esse caso — ele só confirma\r\n * que a convenção documentada acima foi respeitada.\r\n *\r\n * FAIL-LOUD em produção (incidente gestovendas 2026-09-06): além de gravar o\r\n * manifesto, quando o env-alvo resolvido é **prod** o guard FALHA o build\r\n * (`throw NeetruBuildGuardError` → `next build` sai com código ≠ 0) se\r\n * `NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` ou `NEXT_PUBLIC_NEETRU_PRODUCT_ID`\r\n * estiver ausente/vazio. Sem esse par o SDK não monta o `client_id` do login\r\n * OIDC — o `NeetruLoginButton` não redireciona e o login quebra EM SILÊNCIO\r\n * em produção (foi exatamente o que aconteceu quando a recriação do workspace\r\n * do gestovendas perdeu a env var e shippou um build de prod com o client_id\r\n * vazio). `dev`/`workspace` NÃO exigem o par (usam MockAuth/sandbox) — só prod\r\n * enforça, pra nunca quebrar build local. A checagem de valor pura vive em\r\n * `assertNeetruProdBuildEnv` (exportada, testável sem rodar webpack).\r\n *\r\n * Composável com qualquer wrapper que já use a chave `webpack` do config\r\n * (ex: `next-pwa`) — a função `webpack` anterior, se houver, é chamada\r\n * primeiro e o retorno dela é repassado adiante sem alteração.\r\n */\r\nimport * as fs from 'node:fs';\r\nimport * as path from 'node:path';\r\n\r\n/** Formato do `.next/neetru-build-manifest.json`. */\r\nexport interface NeetruBuildManifest {\r\n /** `NEXT_PUBLIC_NEETRU_ENV` resolvido no momento do build (`dev|workspace|prod`), ou `null` se ausente. */\r\n builtEnv: string | null;\r\n /** `NEXT_PUBLIC_NEETRU_PRODUCT_ID` resolvido, ou `null`. */\r\n productId: string | null;\r\n /** `NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` resolvido, ou `null`. */\r\n oidcClientId: string | null;\r\n /** ISO timestamp de quando o manifesto foi gravado. */\r\n builtAt: string;\r\n}\r\n\r\nexport interface WithNeetruBuildGuardOptions {\r\n /** Diretório de saída do Next (default `.next`, relativo ao cwd do build). */\r\n outputDir?: string;\r\n}\r\n\r\n/**\r\n * Erro lançado pelo guard quando um build de PRODUÇÃO está sem uma env var\r\n * obrigatória (OIDC client_id / productId). Classe dedicada pra o caller\r\n * poder distinguir \"guard reprovou de propósito\" de uma falha genérica de\r\n * build. Lançar dentro da função `webpack` do `next.config` faz o\r\n * `next build` sair com código ≠ 0 (fail-loud) — que é justamente o objetivo.\r\n */\r\nexport class NeetruBuildGuardError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'NeetruBuildGuardError';\r\n }\r\n}\r\n\r\n/** `''`/whitespace/`null`/`undefined` contam como \"ausente\". */\r\nfunction isBlankEnvValue(v: string | null | undefined): boolean {\r\n return v == null || v.trim() === '';\r\n}\r\n\r\n/**\r\n * Checagem pura (sem I/O, sem webpack) que decide se um build DEVE falhar por\r\n * env var obrigatória faltando. Exportada pra ser testável isoladamente e pra\r\n * o CLI poder reusar a mesma regra se quiser.\r\n *\r\n * Regra: SÓ o env-alvo `prod` exige o par OIDC completo\r\n * (`NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` + `NEXT_PUBLIC_NEETRU_PRODUCT_ID`).\r\n * `dev`/`workspace`/qualquer outro valor (ou ausência) NÃO enforçam — usam\r\n * MockAuth/sandbox e não montam o client OIDC real, então não podem quebrar\r\n * build local. Lança `NeetruBuildGuardError` com mensagem acionável quando\r\n * reprova; retorna `void` quando passa.\r\n */\r\nexport function assertNeetruProdBuildEnv(\r\n resolved: Pick<NeetruBuildManifest, 'builtEnv' | 'productId' | 'oidcClientId'>,\r\n): void {\r\n // Só produção monta o client_id OIDC real. dev/workspace seguem permissivos.\r\n if (resolved.builtEnv !== 'prod') return;\r\n\r\n const missing: string[] = [];\r\n if (isBlankEnvValue(resolved.oidcClientId)) missing.push('NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID');\r\n if (isBlankEnvValue(resolved.productId)) missing.push('NEXT_PUBLIC_NEETRU_PRODUCT_ID');\r\n if (missing.length === 0) return;\r\n\r\n const plural = missing.length > 1;\r\n throw new NeetruBuildGuardError(\r\n [\r\n '[neetru-sdk] BUILD DE PRODUÇÃO ABORTADO (withNeetruBuildGuard).',\r\n '',\r\n `Variáve${plural ? 'is' : 'l'} de ambiente obrigatóri${plural ? 'as' : 'a'} ausente${plural ? 's' : ''}/vazia${plural ? 's' : ''} no build de produção (NEXT_PUBLIC_NEETRU_ENV=prod):`,\r\n ...missing.map((v) => ` • ${v}`),\r\n '',\r\n `Sem ${plural ? 'essas variáveis' : 'essa variável'} o SDK não consegue montar o client_id do login OIDC — o botão \"Entrar com Neetru\" (NeetruLoginButton) NÃO redireciona e o login do produto quebra EM SILÊNCIO em produção (incidente gestovendas 2026-09-06: workspace recriado perdeu a env var e shippou um build de prod com o client_id vazio).`,\r\n '',\r\n 'Como corrigir — defina no .env.production do produto (ou no ambiente do build de deploy):',\r\n ...missing.map((v) => ` ${v}=<valor real vindo do catálogo do produto no Core>`),\r\n '',\r\n 'dev/workspace NÃO exigem essas variáveis (usam MockAuth/sandbox) — só o build de produção enforça.',\r\n ].join('\\n'),\r\n );\r\n}\r\n\r\n/**\r\n * Formato mínimo de `next.config.mjs` que o wrapper precisa entender — só\r\n * o suficiente pra compor a chave `webpack` sem acoplar o SDK ao pacote\r\n * `next` como dependência de tipos.\r\n */\r\ntype MinimalWebpackContext = {\r\n buildId: string;\r\n dev: boolean;\r\n isServer: boolean;\r\n [key: string]: unknown;\r\n};\r\ntype MinimalNextConfig = Record<string, unknown> & {\r\n webpack?: (config: unknown, context: MinimalWebpackContext) => unknown;\r\n};\r\n\r\nexport function withNeetruBuildGuard<T extends MinimalNextConfig>(\r\n nextConfig: T,\r\n options: WithNeetruBuildGuardOptions = {},\r\n): T {\r\n const prevWebpack = nextConfig.webpack;\r\n\r\n return {\r\n ...nextConfig,\r\n webpack(config: unknown, context: MinimalWebpackContext): unknown {\r\n const result = typeof prevWebpack === 'function' ? prevWebpack(config, context) : config;\r\n\r\n // Grava só na passada server (roda 1x por build, diferente da passada\r\n // client que pode rodar múltiplas vezes) e só fora de `next dev` —\r\n // `next build` é sempre produção de artefato de deploy.\r\n if (!context.dev && context.isServer) {\r\n const manifest: NeetruBuildManifest = {\r\n builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,\r\n productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,\r\n oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,\r\n builtAt: new Date().toISOString(),\r\n };\r\n\r\n try {\r\n const outDir = path.resolve(process.cwd(), options.outputDir ?? '.next');\r\n fs.mkdirSync(outDir, { recursive: true });\r\n fs.writeFileSync(\r\n path.join(outDir, 'neetru-build-manifest.json'),\r\n JSON.stringify(manifest, null, 2),\r\n 'utf8',\r\n );\r\n } catch (err) {\r\n // Best-effort — a FALHA DE ESCRITA do manifesto nunca pode quebrar o\r\n // build do produto, mas uma falha silenciosa aqui esconderia o\r\n // problema (achado da revisão: sem log, ninguém percebe que o\r\n // manifesto não foi gravado e `neetru build` trata \"manifesto\r\n // ausente\" como aviso, não bloqueio — visibilidade aqui é a única\r\n // forma de notar).\r\n if (typeof console !== 'undefined') {\r\n console.warn(\r\n '[neetru-sdk] withNeetruBuildGuard: falha ao gravar neetru-build-manifest.json (ignorado, build segue):',\r\n err,\r\n );\r\n }\r\n }\r\n\r\n // FAIL-LOUD (incidente gestovendas 2026-09-06): DEPOIS de gravar o\r\n // manifesto (best-effort) e FORA do try/catch acima — este throw é\r\n // DE PROPÓSITO e DEVE escapar pra falhar o `next build` (exit ≠ 0)\r\n // quando um build de produção está sem o client_id/productId do OIDC.\r\n // Só prod enforça; dev/workspace passam direto (ver\r\n // assertNeetruProdBuildEnv).\r\n assertNeetruProdBuildEnv(manifest);\r\n }\r\n\r\n return result;\r\n },\r\n } as T;\r\n}\r\n"]}
|
package/dist/build-guard.d.cts
CHANGED
|
@@ -13,6 +13,29 @@ interface WithNeetruBuildGuardOptions {
|
|
|
13
13
|
/** Diretório de saída do Next (default `.next`, relativo ao cwd do build). */
|
|
14
14
|
outputDir?: string;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Erro lançado pelo guard quando um build de PRODUÇÃO está sem uma env var
|
|
18
|
+
* obrigatória (OIDC client_id / productId). Classe dedicada pra o caller
|
|
19
|
+
* poder distinguir "guard reprovou de propósito" de uma falha genérica de
|
|
20
|
+
* build. Lançar dentro da função `webpack` do `next.config` faz o
|
|
21
|
+
* `next build` sair com código ≠ 0 (fail-loud) — que é justamente o objetivo.
|
|
22
|
+
*/
|
|
23
|
+
declare class NeetruBuildGuardError extends Error {
|
|
24
|
+
constructor(message: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Checagem pura (sem I/O, sem webpack) que decide se um build DEVE falhar por
|
|
28
|
+
* env var obrigatória faltando. Exportada pra ser testável isoladamente e pra
|
|
29
|
+
* o CLI poder reusar a mesma regra se quiser.
|
|
30
|
+
*
|
|
31
|
+
* Regra: SÓ o env-alvo `prod` exige o par OIDC completo
|
|
32
|
+
* (`NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` + `NEXT_PUBLIC_NEETRU_PRODUCT_ID`).
|
|
33
|
+
* `dev`/`workspace`/qualquer outro valor (ou ausência) NÃO enforçam — usam
|
|
34
|
+
* MockAuth/sandbox e não montam o client OIDC real, então não podem quebrar
|
|
35
|
+
* build local. Lança `NeetruBuildGuardError` com mensagem acionável quando
|
|
36
|
+
* reprova; retorna `void` quando passa.
|
|
37
|
+
*/
|
|
38
|
+
declare function assertNeetruProdBuildEnv(resolved: Pick<NeetruBuildManifest, 'builtEnv' | 'productId' | 'oidcClientId'>): void;
|
|
16
39
|
/**
|
|
17
40
|
* Formato mínimo de `next.config.mjs` que o wrapper precisa entender — só
|
|
18
41
|
* o suficiente pra compor a chave `webpack` sem acoplar o SDK ao pacote
|
|
@@ -29,4 +52,4 @@ type MinimalNextConfig = Record<string, unknown> & {
|
|
|
29
52
|
};
|
|
30
53
|
declare function withNeetruBuildGuard<T extends MinimalNextConfig>(nextConfig: T, options?: WithNeetruBuildGuardOptions): T;
|
|
31
54
|
|
|
32
|
-
export { type NeetruBuildManifest, type WithNeetruBuildGuardOptions, withNeetruBuildGuard };
|
|
55
|
+
export { NeetruBuildGuardError, type NeetruBuildManifest, type WithNeetruBuildGuardOptions, assertNeetruProdBuildEnv, withNeetruBuildGuard };
|
package/dist/build-guard.d.ts
CHANGED
|
@@ -13,6 +13,29 @@ interface WithNeetruBuildGuardOptions {
|
|
|
13
13
|
/** Diretório de saída do Next (default `.next`, relativo ao cwd do build). */
|
|
14
14
|
outputDir?: string;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Erro lançado pelo guard quando um build de PRODUÇÃO está sem uma env var
|
|
18
|
+
* obrigatória (OIDC client_id / productId). Classe dedicada pra o caller
|
|
19
|
+
* poder distinguir "guard reprovou de propósito" de uma falha genérica de
|
|
20
|
+
* build. Lançar dentro da função `webpack` do `next.config` faz o
|
|
21
|
+
* `next build` sair com código ≠ 0 (fail-loud) — que é justamente o objetivo.
|
|
22
|
+
*/
|
|
23
|
+
declare class NeetruBuildGuardError extends Error {
|
|
24
|
+
constructor(message: string);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Checagem pura (sem I/O, sem webpack) que decide se um build DEVE falhar por
|
|
28
|
+
* env var obrigatória faltando. Exportada pra ser testável isoladamente e pra
|
|
29
|
+
* o CLI poder reusar a mesma regra se quiser.
|
|
30
|
+
*
|
|
31
|
+
* Regra: SÓ o env-alvo `prod` exige o par OIDC completo
|
|
32
|
+
* (`NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` + `NEXT_PUBLIC_NEETRU_PRODUCT_ID`).
|
|
33
|
+
* `dev`/`workspace`/qualquer outro valor (ou ausência) NÃO enforçam — usam
|
|
34
|
+
* MockAuth/sandbox e não montam o client OIDC real, então não podem quebrar
|
|
35
|
+
* build local. Lança `NeetruBuildGuardError` com mensagem acionável quando
|
|
36
|
+
* reprova; retorna `void` quando passa.
|
|
37
|
+
*/
|
|
38
|
+
declare function assertNeetruProdBuildEnv(resolved: Pick<NeetruBuildManifest, 'builtEnv' | 'productId' | 'oidcClientId'>): void;
|
|
16
39
|
/**
|
|
17
40
|
* Formato mínimo de `next.config.mjs` que o wrapper precisa entender — só
|
|
18
41
|
* o suficiente pra compor a chave `webpack` sem acoplar o SDK ao pacote
|
|
@@ -29,4 +52,4 @@ type MinimalNextConfig = Record<string, unknown> & {
|
|
|
29
52
|
};
|
|
30
53
|
declare function withNeetruBuildGuard<T extends MinimalNextConfig>(nextConfig: T, options?: WithNeetruBuildGuardOptions): T;
|
|
31
54
|
|
|
32
|
-
export { type NeetruBuildManifest, type WithNeetruBuildGuardOptions, withNeetruBuildGuard };
|
|
55
|
+
export { NeetruBuildGuardError, type NeetruBuildManifest, type WithNeetruBuildGuardOptions, assertNeetruProdBuildEnv, withNeetruBuildGuard };
|
package/dist/build-guard.mjs
CHANGED
|
@@ -2,6 +2,38 @@ import * as fs from 'fs';
|
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
|
|
4
4
|
// src/build-guard.ts
|
|
5
|
+
var NeetruBuildGuardError = class extends Error {
|
|
6
|
+
constructor(message) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = "NeetruBuildGuardError";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
function isBlankEnvValue(v) {
|
|
12
|
+
return v == null || v.trim() === "";
|
|
13
|
+
}
|
|
14
|
+
function assertNeetruProdBuildEnv(resolved) {
|
|
15
|
+
if (resolved.builtEnv !== "prod") return;
|
|
16
|
+
const missing = [];
|
|
17
|
+
if (isBlankEnvValue(resolved.oidcClientId)) missing.push("NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID");
|
|
18
|
+
if (isBlankEnvValue(resolved.productId)) missing.push("NEXT_PUBLIC_NEETRU_PRODUCT_ID");
|
|
19
|
+
if (missing.length === 0) return;
|
|
20
|
+
const plural = missing.length > 1;
|
|
21
|
+
throw new NeetruBuildGuardError(
|
|
22
|
+
[
|
|
23
|
+
"[neetru-sdk] BUILD DE PRODU\xC7\xC3O ABORTADO (withNeetruBuildGuard).",
|
|
24
|
+
"",
|
|
25
|
+
`Vari\xE1ve${plural ? "is" : "l"} de ambiente obrigat\xF3ri${plural ? "as" : "a"} ausente${plural ? "s" : ""}/vazia${plural ? "s" : ""} no build de produ\xE7\xE3o (NEXT_PUBLIC_NEETRU_ENV=prod):`,
|
|
26
|
+
...missing.map((v) => ` \u2022 ${v}`),
|
|
27
|
+
"",
|
|
28
|
+
`Sem ${plural ? "essas vari\xE1veis" : "essa vari\xE1vel"} o SDK n\xE3o consegue montar o client_id do login OIDC \u2014 o bot\xE3o "Entrar com Neetru" (NeetruLoginButton) N\xC3O redireciona e o login do produto quebra EM SIL\xCANCIO em produ\xE7\xE3o (incidente gestovendas 2026-09-06: workspace recriado perdeu a env var e shippou um build de prod com o client_id vazio).`,
|
|
29
|
+
"",
|
|
30
|
+
"Como corrigir \u2014 defina no .env.production do produto (ou no ambiente do build de deploy):",
|
|
31
|
+
...missing.map((v) => ` ${v}=<valor real vindo do cat\xE1logo do produto no Core>`),
|
|
32
|
+
"",
|
|
33
|
+
"dev/workspace N\xC3O exigem essas vari\xE1veis (usam MockAuth/sandbox) \u2014 s\xF3 o build de produ\xE7\xE3o enfor\xE7a."
|
|
34
|
+
].join("\n")
|
|
35
|
+
);
|
|
36
|
+
}
|
|
5
37
|
function withNeetruBuildGuard(nextConfig, options = {}) {
|
|
6
38
|
const prevWebpack = nextConfig.webpack;
|
|
7
39
|
return {
|
|
@@ -9,15 +41,15 @@ function withNeetruBuildGuard(nextConfig, options = {}) {
|
|
|
9
41
|
webpack(config, context) {
|
|
10
42
|
const result = typeof prevWebpack === "function" ? prevWebpack(config, context) : config;
|
|
11
43
|
if (!context.dev && context.isServer) {
|
|
44
|
+
const manifest = {
|
|
45
|
+
builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,
|
|
46
|
+
productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,
|
|
47
|
+
oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,
|
|
48
|
+
builtAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
49
|
+
};
|
|
12
50
|
try {
|
|
13
51
|
const outDir = path.resolve(process.cwd(), options.outputDir ?? ".next");
|
|
14
52
|
fs.mkdirSync(outDir, { recursive: true });
|
|
15
|
-
const manifest = {
|
|
16
|
-
builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,
|
|
17
|
-
productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,
|
|
18
|
-
oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,
|
|
19
|
-
builtAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
20
|
-
};
|
|
21
53
|
fs.writeFileSync(
|
|
22
54
|
path.join(outDir, "neetru-build-manifest.json"),
|
|
23
55
|
JSON.stringify(manifest, null, 2),
|
|
@@ -31,12 +63,13 @@ function withNeetruBuildGuard(nextConfig, options = {}) {
|
|
|
31
63
|
);
|
|
32
64
|
}
|
|
33
65
|
}
|
|
66
|
+
assertNeetruProdBuildEnv(manifest);
|
|
34
67
|
}
|
|
35
68
|
return result;
|
|
36
69
|
}
|
|
37
70
|
};
|
|
38
71
|
}
|
|
39
72
|
|
|
40
|
-
export { withNeetruBuildGuard };
|
|
73
|
+
export { NeetruBuildGuardError, assertNeetruProdBuildEnv, withNeetruBuildGuard };
|
|
41
74
|
//# sourceMappingURL=build-guard.mjs.map
|
|
42
75
|
//# sourceMappingURL=build-guard.mjs.map
|
package/dist/build-guard.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/build-guard.ts"],"names":[],"mappings":";;;;AAwFO,SAAS,oBAAA,CACd,UAAA,EACA,OAAA,GAAuC,EAAC,EACrC;AACH,EAAA,MAAM,cAAc,UAAA,CAAW,OAAA;AAE/B,EAAA,OAAO;AAAA,IACL,GAAG,UAAA;AAAA,IACH,OAAA,CAAQ,QAAiB,OAAA,EAAyC;AAChE,MAAA,MAAM,SAAS,OAAO,WAAA,KAAgB,aAAa,WAAA,CAAY,MAAA,EAAQ,OAAO,CAAA,GAAI,MAAA;AAKlF,MAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,IAAO,OAAA,CAAQ,QAAA,EAAU;AACpC,QAAA,IAAI;AACF,UAAA,MAAM,SAAc,IAAA,CAAA,OAAA,CAAQ,OAAA,CAAQ,KAAI,EAAG,OAAA,CAAQ,aAAa,OAAO,CAAA;AACvE,UAAG,EAAA,CAAA,SAAA,CAAU,MAAA,EAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AACxC,UAAA,MAAM,QAAA,GAAgC;AAAA,YACpC,QAAA,EAAU,OAAA,CAAQ,GAAA,CAAI,sBAAA,IAA0B,IAAA;AAAA,YAChD,SAAA,EAAW,OAAA,CAAQ,GAAA,CAAI,6BAAA,IAAiC,IAAA;AAAA,YACxD,YAAA,EAAc,OAAA,CAAQ,GAAA,CAAI,iCAAA,IAAqC,IAAA;AAAA,YAC/D,OAAA,EAAA,iBAAS,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,WAClC;AACA,UAAG,EAAA,CAAA,aAAA;AAAA,YACI,IAAA,CAAA,IAAA,CAAK,QAAQ,4BAA4B,CAAA;AAAA,YAC9C,IAAA,CAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAA;AAAA,YAChC;AAAA,WACF;AAAA,QACF,SAAS,GAAA,EAAK;AAMZ,UAAA,IAAI,OAAO,YAAY,WAAA,EAAa;AAClC,YAAA,OAAA,CAAQ,IAAA;AAAA,cACN,wGAAA;AAAA,cACA;AAAA,aACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAEA,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,GACF;AACF","file":"build-guard.mjs","sourcesContent":["/**\r\n * `withNeetruBuildGuard` — wrapper de `next.config.mjs` que grava\r\n * `.next/neetru-build-manifest.json` ao final do build com os valores\r\n * `NEXT_PUBLIC_NEETRU_*` que realmente foram resolvidos pelo Next.js.\r\n *\r\n * Existe pra fechar um bug de precedência de env do Next.js (incidente\r\n * 2026-07-22, pdv-agiliza): `.env.local` (fica no disco do dev) vence\r\n * `.env.production` durante `next build` pra qualquer chave em comum —\r\n * então um build \"de prod\" podia compilar com `NEXT_PUBLIC_NEETRU_ENV=dev`\r\n * sem nenhum aviso, ativando `MockAuth` no bundle do browser em produção\r\n * (o botão \"Entrar com Neetru\" não fazia nada, porque `MockAuth.signIn()`\r\n * só finge um login em memória — nunca navega pro IdP real).\r\n *\r\n * O manifesto não inspeciona o JS compilado (minificação/webpack\r\n * `DefinePlugin` tornam isso frágil — o nome da chave some, só sobra o\r\n * literal). Em vez disso grava, em texto puro, o que o processo Node do\r\n * build efetivamente tinha em `process.env` no momento da compilação\r\n * server-side — reflete fielmente a resolução real do Next.js/dotenv,\r\n * incluindo qualquer override via spawn-env (`@neetru/cli` injeta\r\n * `NEXT_PUBLIC_NEETRU_ENV` assim desde a v2.26.2). `neetru build` lê este\r\n * arquivo depois do build e recusa empacotar o tarball se o valor não\r\n * bater com o ambiente esperado do deploy.\r\n *\r\n * Uso, em `next.config.mjs`:\r\n * ```js\r\n * import { withNeetruBuildGuard } from '@neetru/sdk/build-guard';\r\n * export default withNeetruBuildGuard({ ...nextConfig });\r\n * ```\r\n *\r\n * Subpath dedicado (`@neetru/sdk/build-guard`, não o barrel `.`) de\r\n * propósito: este arquivo é o único no SDK que importa `node:fs`/`node:path`\r\n * estaticamente. O entry `.` promete rodar em browser/Node/Edge sem Node\r\n * builtins — reexportar o guard ali vazaria essa dependência pro bundle\r\n * universal (achado real da revisão: `esbuild --platform=browser` falha com\r\n * \"Could not resolve fs/path\" se o guard entra no barrel principal).\r\n *\r\n * IMPORTANTE — isto NÃO é uma checagem universal de \"o env está certo\": o\r\n * guard grava literalmente as 3 env vars `NEXT_PUBLIC_NEETRU_ENV` /\r\n * `_PRODUCT_ID` / `_OIDC_CLIENT_ID`, que são a convenção recomendada de\r\n * bootstrap Next.js do ecossistema Neetru (o que `neetru-pdvagiliza` e\r\n * outros produtos usam em `src/lib/neetru/client.ts` pra montar\r\n * `createNeetruClient({env, productId, oidcClientId})`) — **não** é o mesmo\r\n * que o fallback interno `NEETRU_ENV`/`globalThis.NEETRU_ENV` que\r\n * `resolveEnv()` (`src/auth.ts`) usa quando NENHUM `env` é passado\r\n * explicitamente pro client. Se o seu produto bootstrap o client de outra\r\n * forma (nome de env var diferente, ou sem prefixo `NEXT_PUBLIC_`, ou\r\n * hardcoded), este guard não detecta drift pra esse caso — ele só confirma\r\n * que a convenção documentada acima foi respeitada.\r\n *\r\n * Composável com qualquer wrapper que já use a chave `webpack` do config\r\n * (ex: `next-pwa`) — a função `webpack` anterior, se houver, é chamada\r\n * primeiro e o retorno dela é repassado adiante sem alteração.\r\n */\r\nimport * as fs from 'node:fs';\r\nimport * as path from 'node:path';\r\n\r\n/** Formato do `.next/neetru-build-manifest.json`. */\r\nexport interface NeetruBuildManifest {\r\n /** `NEXT_PUBLIC_NEETRU_ENV` resolvido no momento do build (`dev|workspace|prod`), ou `null` se ausente. */\r\n builtEnv: string | null;\r\n /** `NEXT_PUBLIC_NEETRU_PRODUCT_ID` resolvido, ou `null`. */\r\n productId: string | null;\r\n /** `NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` resolvido, ou `null`. */\r\n oidcClientId: string | null;\r\n /** ISO timestamp de quando o manifesto foi gravado. */\r\n builtAt: string;\r\n}\r\n\r\nexport interface WithNeetruBuildGuardOptions {\r\n /** Diretório de saída do Next (default `.next`, relativo ao cwd do build). */\r\n outputDir?: string;\r\n}\r\n\r\n/**\r\n * Formato mínimo de `next.config.mjs` que o wrapper precisa entender — só\r\n * o suficiente pra compor a chave `webpack` sem acoplar o SDK ao pacote\r\n * `next` como dependência de tipos.\r\n */\r\ntype MinimalWebpackContext = {\r\n buildId: string;\r\n dev: boolean;\r\n isServer: boolean;\r\n [key: string]: unknown;\r\n};\r\ntype MinimalNextConfig = Record<string, unknown> & {\r\n webpack?: (config: unknown, context: MinimalWebpackContext) => unknown;\r\n};\r\n\r\nexport function withNeetruBuildGuard<T extends MinimalNextConfig>(\r\n nextConfig: T,\r\n options: WithNeetruBuildGuardOptions = {},\r\n): T {\r\n const prevWebpack = nextConfig.webpack;\r\n\r\n return {\r\n ...nextConfig,\r\n webpack(config: unknown, context: MinimalWebpackContext): unknown {\r\n const result = typeof prevWebpack === 'function' ? prevWebpack(config, context) : config;\r\n\r\n // Grava só na passada server (roda 1x por build, diferente da passada\r\n // client que pode rodar múltiplas vezes) e só fora de `next dev` —\r\n // `next build` é sempre produção de artefato de deploy.\r\n if (!context.dev && context.isServer) {\r\n try {\r\n const outDir = path.resolve(process.cwd(), options.outputDir ?? '.next');\r\n fs.mkdirSync(outDir, { recursive: true });\r\n const manifest: NeetruBuildManifest = {\r\n builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,\r\n productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,\r\n oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,\r\n builtAt: new Date().toISOString(),\r\n };\r\n fs.writeFileSync(\r\n path.join(outDir, 'neetru-build-manifest.json'),\r\n JSON.stringify(manifest, null, 2),\r\n 'utf8',\r\n );\r\n } catch (err) {\r\n // Best-effort — o guard nunca pode quebrar o build do produto,\r\n // mas uma falha de escrita silenciosa aqui esconderia o problema\r\n // (achado da revisão: sem log, ninguém percebe que o manifesto não\r\n // foi gravado e `neetru build` trata \"manifesto ausente\" como\r\n // aviso, não bloqueio — visibilidade aqui é a única forma de notar).\r\n if (typeof console !== 'undefined') {\r\n console.warn(\r\n '[neetru-sdk] withNeetruBuildGuard: falha ao gravar neetru-build-manifest.json (ignorado, build segue):',\r\n err,\r\n );\r\n }\r\n }\r\n }\r\n\r\n return result;\r\n },\r\n } as T;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/build-guard.ts"],"names":[],"mappings":"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","file":"build-guard.mjs","sourcesContent":["/**\r\n * `withNeetruBuildGuard` — wrapper de `next.config.mjs` que grava\r\n * `.next/neetru-build-manifest.json` ao final do build com os valores\r\n * `NEXT_PUBLIC_NEETRU_*` que realmente foram resolvidos pelo Next.js.\r\n *\r\n * Existe pra fechar um bug de precedência de env do Next.js (incidente\r\n * 2026-07-22, pdv-agiliza): `.env.local` (fica no disco do dev) vence\r\n * `.env.production` durante `next build` pra qualquer chave em comum —\r\n * então um build \"de prod\" podia compilar com `NEXT_PUBLIC_NEETRU_ENV=dev`\r\n * sem nenhum aviso, ativando `MockAuth` no bundle do browser em produção\r\n * (o botão \"Entrar com Neetru\" não fazia nada, porque `MockAuth.signIn()`\r\n * só finge um login em memória — nunca navega pro IdP real).\r\n *\r\n * O manifesto não inspeciona o JS compilado (minificação/webpack\r\n * `DefinePlugin` tornam isso frágil — o nome da chave some, só sobra o\r\n * literal). Em vez disso grava, em texto puro, o que o processo Node do\r\n * build efetivamente tinha em `process.env` no momento da compilação\r\n * server-side — reflete fielmente a resolução real do Next.js/dotenv,\r\n * incluindo qualquer override via spawn-env (`@neetru/cli` injeta\r\n * `NEXT_PUBLIC_NEETRU_ENV` assim desde a v2.26.2). `neetru build` lê este\r\n * arquivo depois do build e recusa empacotar o tarball se o valor não\r\n * bater com o ambiente esperado do deploy.\r\n *\r\n * Uso, em `next.config.mjs`:\r\n * ```js\r\n * import { withNeetruBuildGuard } from '@neetru/sdk/build-guard';\r\n * export default withNeetruBuildGuard({ ...nextConfig });\r\n * ```\r\n *\r\n * Subpath dedicado (`@neetru/sdk/build-guard`, não o barrel `.`) de\r\n * propósito: este arquivo é o único no SDK que importa `node:fs`/`node:path`\r\n * estaticamente. O entry `.` promete rodar em browser/Node/Edge sem Node\r\n * builtins — reexportar o guard ali vazaria essa dependência pro bundle\r\n * universal (achado real da revisão: `esbuild --platform=browser` falha com\r\n * \"Could not resolve fs/path\" se o guard entra no barrel principal).\r\n *\r\n * IMPORTANTE — isto NÃO é uma checagem universal de \"o env está certo\": o\r\n * guard grava literalmente as 3 env vars `NEXT_PUBLIC_NEETRU_ENV` /\r\n * `_PRODUCT_ID` / `_OIDC_CLIENT_ID`, que são a convenção recomendada de\r\n * bootstrap Next.js do ecossistema Neetru (o que `neetru-pdvagiliza` e\r\n * outros produtos usam em `src/lib/neetru/client.ts` pra montar\r\n * `createNeetruClient({env, productId, oidcClientId})`) — **não** é o mesmo\r\n * que o fallback interno `NEETRU_ENV`/`globalThis.NEETRU_ENV` que\r\n * `resolveEnv()` (`src/auth.ts`) usa quando NENHUM `env` é passado\r\n * explicitamente pro client. Se o seu produto bootstrap o client de outra\r\n * forma (nome de env var diferente, ou sem prefixo `NEXT_PUBLIC_`, ou\r\n * hardcoded), este guard não detecta drift pra esse caso — ele só confirma\r\n * que a convenção documentada acima foi respeitada.\r\n *\r\n * FAIL-LOUD em produção (incidente gestovendas 2026-09-06): além de gravar o\r\n * manifesto, quando o env-alvo resolvido é **prod** o guard FALHA o build\r\n * (`throw NeetruBuildGuardError` → `next build` sai com código ≠ 0) se\r\n * `NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` ou `NEXT_PUBLIC_NEETRU_PRODUCT_ID`\r\n * estiver ausente/vazio. Sem esse par o SDK não monta o `client_id` do login\r\n * OIDC — o `NeetruLoginButton` não redireciona e o login quebra EM SILÊNCIO\r\n * em produção (foi exatamente o que aconteceu quando a recriação do workspace\r\n * do gestovendas perdeu a env var e shippou um build de prod com o client_id\r\n * vazio). `dev`/`workspace` NÃO exigem o par (usam MockAuth/sandbox) — só prod\r\n * enforça, pra nunca quebrar build local. A checagem de valor pura vive em\r\n * `assertNeetruProdBuildEnv` (exportada, testável sem rodar webpack).\r\n *\r\n * Composável com qualquer wrapper que já use a chave `webpack` do config\r\n * (ex: `next-pwa`) — a função `webpack` anterior, se houver, é chamada\r\n * primeiro e o retorno dela é repassado adiante sem alteração.\r\n */\r\nimport * as fs from 'node:fs';\r\nimport * as path from 'node:path';\r\n\r\n/** Formato do `.next/neetru-build-manifest.json`. */\r\nexport interface NeetruBuildManifest {\r\n /** `NEXT_PUBLIC_NEETRU_ENV` resolvido no momento do build (`dev|workspace|prod`), ou `null` se ausente. */\r\n builtEnv: string | null;\r\n /** `NEXT_PUBLIC_NEETRU_PRODUCT_ID` resolvido, ou `null`. */\r\n productId: string | null;\r\n /** `NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` resolvido, ou `null`. */\r\n oidcClientId: string | null;\r\n /** ISO timestamp de quando o manifesto foi gravado. */\r\n builtAt: string;\r\n}\r\n\r\nexport interface WithNeetruBuildGuardOptions {\r\n /** Diretório de saída do Next (default `.next`, relativo ao cwd do build). */\r\n outputDir?: string;\r\n}\r\n\r\n/**\r\n * Erro lançado pelo guard quando um build de PRODUÇÃO está sem uma env var\r\n * obrigatória (OIDC client_id / productId). Classe dedicada pra o caller\r\n * poder distinguir \"guard reprovou de propósito\" de uma falha genérica de\r\n * build. Lançar dentro da função `webpack` do `next.config` faz o\r\n * `next build` sair com código ≠ 0 (fail-loud) — que é justamente o objetivo.\r\n */\r\nexport class NeetruBuildGuardError extends Error {\r\n constructor(message: string) {\r\n super(message);\r\n this.name = 'NeetruBuildGuardError';\r\n }\r\n}\r\n\r\n/** `''`/whitespace/`null`/`undefined` contam como \"ausente\". */\r\nfunction isBlankEnvValue(v: string | null | undefined): boolean {\r\n return v == null || v.trim() === '';\r\n}\r\n\r\n/**\r\n * Checagem pura (sem I/O, sem webpack) que decide se um build DEVE falhar por\r\n * env var obrigatória faltando. Exportada pra ser testável isoladamente e pra\r\n * o CLI poder reusar a mesma regra se quiser.\r\n *\r\n * Regra: SÓ o env-alvo `prod` exige o par OIDC completo\r\n * (`NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID` + `NEXT_PUBLIC_NEETRU_PRODUCT_ID`).\r\n * `dev`/`workspace`/qualquer outro valor (ou ausência) NÃO enforçam — usam\r\n * MockAuth/sandbox e não montam o client OIDC real, então não podem quebrar\r\n * build local. Lança `NeetruBuildGuardError` com mensagem acionável quando\r\n * reprova; retorna `void` quando passa.\r\n */\r\nexport function assertNeetruProdBuildEnv(\r\n resolved: Pick<NeetruBuildManifest, 'builtEnv' | 'productId' | 'oidcClientId'>,\r\n): void {\r\n // Só produção monta o client_id OIDC real. dev/workspace seguem permissivos.\r\n if (resolved.builtEnv !== 'prod') return;\r\n\r\n const missing: string[] = [];\r\n if (isBlankEnvValue(resolved.oidcClientId)) missing.push('NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID');\r\n if (isBlankEnvValue(resolved.productId)) missing.push('NEXT_PUBLIC_NEETRU_PRODUCT_ID');\r\n if (missing.length === 0) return;\r\n\r\n const plural = missing.length > 1;\r\n throw new NeetruBuildGuardError(\r\n [\r\n '[neetru-sdk] BUILD DE PRODUÇÃO ABORTADO (withNeetruBuildGuard).',\r\n '',\r\n `Variáve${plural ? 'is' : 'l'} de ambiente obrigatóri${plural ? 'as' : 'a'} ausente${plural ? 's' : ''}/vazia${plural ? 's' : ''} no build de produção (NEXT_PUBLIC_NEETRU_ENV=prod):`,\r\n ...missing.map((v) => ` • ${v}`),\r\n '',\r\n `Sem ${plural ? 'essas variáveis' : 'essa variável'} o SDK não consegue montar o client_id do login OIDC — o botão \"Entrar com Neetru\" (NeetruLoginButton) NÃO redireciona e o login do produto quebra EM SILÊNCIO em produção (incidente gestovendas 2026-09-06: workspace recriado perdeu a env var e shippou um build de prod com o client_id vazio).`,\r\n '',\r\n 'Como corrigir — defina no .env.production do produto (ou no ambiente do build de deploy):',\r\n ...missing.map((v) => ` ${v}=<valor real vindo do catálogo do produto no Core>`),\r\n '',\r\n 'dev/workspace NÃO exigem essas variáveis (usam MockAuth/sandbox) — só o build de produção enforça.',\r\n ].join('\\n'),\r\n );\r\n}\r\n\r\n/**\r\n * Formato mínimo de `next.config.mjs` que o wrapper precisa entender — só\r\n * o suficiente pra compor a chave `webpack` sem acoplar o SDK ao pacote\r\n * `next` como dependência de tipos.\r\n */\r\ntype MinimalWebpackContext = {\r\n buildId: string;\r\n dev: boolean;\r\n isServer: boolean;\r\n [key: string]: unknown;\r\n};\r\ntype MinimalNextConfig = Record<string, unknown> & {\r\n webpack?: (config: unknown, context: MinimalWebpackContext) => unknown;\r\n};\r\n\r\nexport function withNeetruBuildGuard<T extends MinimalNextConfig>(\r\n nextConfig: T,\r\n options: WithNeetruBuildGuardOptions = {},\r\n): T {\r\n const prevWebpack = nextConfig.webpack;\r\n\r\n return {\r\n ...nextConfig,\r\n webpack(config: unknown, context: MinimalWebpackContext): unknown {\r\n const result = typeof prevWebpack === 'function' ? prevWebpack(config, context) : config;\r\n\r\n // Grava só na passada server (roda 1x por build, diferente da passada\r\n // client que pode rodar múltiplas vezes) e só fora de `next dev` —\r\n // `next build` é sempre produção de artefato de deploy.\r\n if (!context.dev && context.isServer) {\r\n const manifest: NeetruBuildManifest = {\r\n builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,\r\n productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,\r\n oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,\r\n builtAt: new Date().toISOString(),\r\n };\r\n\r\n try {\r\n const outDir = path.resolve(process.cwd(), options.outputDir ?? '.next');\r\n fs.mkdirSync(outDir, { recursive: true });\r\n fs.writeFileSync(\r\n path.join(outDir, 'neetru-build-manifest.json'),\r\n JSON.stringify(manifest, null, 2),\r\n 'utf8',\r\n );\r\n } catch (err) {\r\n // Best-effort — a FALHA DE ESCRITA do manifesto nunca pode quebrar o\r\n // build do produto, mas uma falha silenciosa aqui esconderia o\r\n // problema (achado da revisão: sem log, ninguém percebe que o\r\n // manifesto não foi gravado e `neetru build` trata \"manifesto\r\n // ausente\" como aviso, não bloqueio — visibilidade aqui é a única\r\n // forma de notar).\r\n if (typeof console !== 'undefined') {\r\n console.warn(\r\n '[neetru-sdk] withNeetruBuildGuard: falha ao gravar neetru-build-manifest.json (ignorado, build segue):',\r\n err,\r\n );\r\n }\r\n }\r\n\r\n // FAIL-LOUD (incidente gestovendas 2026-09-06): DEPOIS de gravar o\r\n // manifesto (best-effort) e FORA do try/catch acima — este throw é\r\n // DE PROPÓSITO e DEVE escapar pra falhar o `next build` (exit ≠ 0)\r\n // quando um build de produção está sem o client_id/productId do OIDC.\r\n // Só prod enforça; dev/workspace passam direto (ver\r\n // assertNeetruProdBuildEnv).\r\n assertNeetruProdBuildEnv(manifest);\r\n }\r\n\r\n return result;\r\n },\r\n } as T;\r\n}\r\n"]}
|
package/dist/catalog.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ag as ResolvedConfig, C as CatalogListOptions, n as CatalogListResponse, a8 as Product } from './types-
|
|
1
|
+
import { ag as ResolvedConfig, C as CatalogListOptions, n as CatalogListResponse, a8 as Product } from './types-D-QdG502.cjs';
|
|
2
2
|
import 'drizzle-orm/node-postgres';
|
|
3
3
|
import './errors.cjs';
|
|
4
4
|
|
package/dist/catalog.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ag as ResolvedConfig, C as CatalogListOptions, n as CatalogListResponse, a8 as Product } from './types-
|
|
1
|
+
import { ag as ResolvedConfig, C as CatalogListOptions, n as CatalogListResponse, a8 as Product } from './types-BlOLDMR0.js';
|
|
2
2
|
import 'drizzle-orm/node-postgres';
|
|
3
3
|
import './errors.js';
|
|
4
4
|
|
package/dist/checkout.d.cts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { o as CheckoutAuthOpts, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, S as MockCheckout,
|
|
1
|
+
export { o as CheckoutAuthOpts, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, S as MockCheckout, aK as createCheckoutNamespace } from './types-D-QdG502.cjs';
|
|
2
2
|
import 'drizzle-orm/node-postgres';
|
|
3
3
|
import './errors.cjs';
|
package/dist/checkout.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { o as CheckoutAuthOpts, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, S as MockCheckout,
|
|
1
|
+
export { o as CheckoutAuthOpts, p as CheckoutIntentInfo, q as CheckoutIntentStatus, r as CheckoutNamespace, s as CheckoutStartInput, t as CheckoutStartResult, u as CheckoutTenantType, S as MockCheckout, aK as createCheckoutNamespace } from './types-BlOLDMR0.js';
|
|
2
2
|
import 'drizzle-orm/node-postgres';
|
|
3
3
|
import './errors.js';
|
package/dist/db-react.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { aq as SyncState, av as Unsubscribe, F as DbDoc, W as NeetruClient, E as DbCollectionRef, K as DbQuery } from './types-D-QdG502.cjs';
|
|
2
2
|
import 'drizzle-orm/node-postgres';
|
|
3
3
|
import './errors.cjs';
|
|
4
4
|
|
package/dist/db-react.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { aq as SyncState, av as Unsubscribe, F as DbDoc, W as NeetruClient, E as DbCollectionRef, K as DbQuery } from './types-BlOLDMR0.js';
|
|
2
2
|
import 'drizzle-orm/node-postgres';
|
|
3
3
|
import './errors.js';
|
|
4
4
|
|