@neetru/sdk 3.9.0 → 3.9.1

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 CHANGED
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.9.1] — 2026-10-26 (o build barra a CSP que deixa o App Router em branco)
11
+
12
+ > **Por que PATCH.** É conserto de defeito (bug_0d2e0087). Atenção: o `next build` de um app com App Router passa a **falhar** quando a CSP do `headers()` bloqueia os scripts inline do Next (sem nonce, sem `'strict-dynamic'` e sem `'unsafe-inline'`). Essa CSP já deixava a página em branco no ar; agora o defeito aparece no build. As funções exportadas novas (`findCspInlineScriptBlocks`, `assertNeetruCspAllowsAppRouterScripts`, `hasNextAppRouter`) só somam.
13
+
14
+ ### Corrigido
15
+
16
+ - **Deploy com sucesso e página em branco: uma CSP do `next.config` derrubava o App Router e nada no build percebia** (bug_0d2e0087c53945d4a8bc89eb6e3c379a, caso Zelo 2026-10-22). O `headers()` mandava `Content-Security-Policy: ... script-src 'self' ...`, sem `'unsafe-inline'` e sem nonce. O App Router põe `<script>` embutidos em toda página (`self.__next_f.push`, o payload do React Server Components). O navegador bloqueia esses scripts, a hidratação falha na raiz e o React desmonta a árvore. O servidor respondia 200 com o HTML inteiro, a sonda de saúde passava e o deploy ficava `success`.
17
+ - `withNeetruBuildGuard` agora embrulha o `headers()` do produto. Em app com App Router (pasta `app/` ou `src/app/`, a mesma regra do `findPagesDir` do Next), o `next build` **falha** quando alguma `Content-Security-Policy` bloqueia script embutido. A mensagem, em português, diz qual regra (`source`) e a linha a trocar (`troque: script-src 'self'` / `por: script-src 'self' 'unsafe-inline'`).
18
+ - Diretiva efetiva na ordem da CSP: `script-src-elem` → `script-src` → `default-src`. Passa com nonce, com `'strict-dynamic'` ou com `'unsafe-inline'`. `'unsafe-inline'` com hash `'sha…-'` ao lado **não** passa, porque o navegador ignora o `'unsafe-inline'` nesse caso.
19
+ - Não afeta: Pages Router puro, `Content-Security-Policy-Report-Only`, regras de `/api` e `/_next`, e produto sem `headers()` (o guard não cria a chave). Em `next dev` só avisa. `next start` lê o `routes-manifest.json` e não chama `headers()`, então nada muda em runtime.
20
+ - Regra pura exportada: `findCspInlineScriptBlocks`, `assertNeetruCspAllowsAppRouterScripts`, `hasNextAppRouter`.
21
+ - Limites: CSP montada no middleware ou em `<meta>` não passa por aqui. `'strict-dynamic'` sem nonce nenhum também bloquearia no navegador, mas passa no guard, como a proposta do bug pede (é a marca da configuração por nonce). Um `'nonce-…'` FIXO no `headers()` também passa no guard e ainda deixa a página em branco: o App Router lê o nonce do header `Content-Security-Policy` da REQUISIÇÃO (que o middleware põe), não da resposta que o `headers()` monta (conferido no `app-render.js` do Next 15.5.28). Esses casos ficam para a sonda pós-deploy do `/` (guarda 2 da proposta), que é do Core/agente e não faz parte desta mudança.
22
+
10
23
  ## [3.9.0] — 2026-10-11 (signOut deixa de falhar em silêncio)
11
24
 
12
25
  > **Por que MINOR e não PATCH.** O conteúdo é conserto de defeito, mas o tipo
package/README.md CHANGED
@@ -175,6 +175,16 @@ Grava `.next/neetru-build-manifest.json` com o `NEXT_PUBLIC_NEETRU_ENV`/`_PRODUC
175
175
 
176
176
  Só disponível via `@neetru/sdk/build-guard` (não o barrel `.`) — é o único módulo do SDK com import estático de `node:fs`/`node:path`, mantido fora do bundle universal de propósito.
177
177
 
178
+ **CSP que deixa a página em branco (não publicado ainda).** Em app com App Router (pasta `app/` ou `src/app/`), o guard embrulha o `headers()` do seu `next.config` e **falha o `next build`** se algum `Content-Security-Policy` bloquear script embutido: `script-src` (ou `script-src-elem`; sem os dois, o `default-src`) sem `'unsafe-inline'`, sem nonce e sem `'strict-dynamic'`. O App Router põe `<script>` embutidos em toda página (`self.__next_f.push`); com uma CSP dessas o navegador os bloqueia, a hidratação falha e a tela fica em branco, mesmo com o servidor respondendo 200 (caso Zelo, 2026-10-22). A mensagem de erro diz a linha a trocar:
179
+
180
+ ```
181
+ 1) headers() → source "/(.*)" → Content-Security-Policy
182
+ troque: script-src 'self'
183
+ por: script-src 'self' 'unsafe-inline'
184
+ ```
185
+
186
+ Ficam de fora: Pages Router puro, `Content-Security-Policy-Report-Only`, regras de `/api` e `/_next`, e CSP montada no middleware ou em `<meta>` (o guard só enxerga o `headers()` do `next.config`). Em `next dev` só avisa no terminal.
187
+
178
188
  ## Exemplos por namespace
179
189
 
180
190
  ### Login OIDC — Authorization Code + PKCE (3.1.3)
package/dist/ai.cjs CHANGED
@@ -82,7 +82,7 @@ function Z(t, e) {
82
82
  }
83
83
  function Q() {
84
84
  try {
85
- return "3.9.0";
85
+ return "3.9.1";
86
86
  } catch {
87
87
  return;
88
88
  }
package/dist/ai.mjs CHANGED
@@ -80,7 +80,7 @@ function Z(t, e) {
80
80
  }
81
81
  function Q() {
82
82
  try {
83
- return "3.9.0";
83
+ return "3.9.1";
84
84
  } catch {
85
85
  return;
86
86
  }
package/dist/auth.cjs CHANGED
@@ -156,7 +156,7 @@ function dr(n, e) {
156
156
  }
157
157
  function Et() {
158
158
  try {
159
- return "3.9.0";
159
+ return "3.9.1";
160
160
  } catch {
161
161
  return;
162
162
  }
package/dist/auth.mjs CHANGED
@@ -154,7 +154,7 @@ function dr(n, e) {
154
154
  }
155
155
  function Et() {
156
156
  try {
157
- return "3.9.0";
157
+ return "3.9.1";
158
158
  } catch {
159
159
  return;
160
160
  }
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var u = require('fs');
4
- var a = require('path');
3
+ var a = require('fs');
4
+ var l = require('path');
5
5
 
6
6
  function _interopNamespace(e) {
7
7
  if (e && e.__esModule) return e;
@@ -21,160 +21,264 @@ function _interopNamespace(e) {
21
21
  return Object.freeze(n);
22
22
  }
23
23
 
24
- var u__namespace = /*#__PURE__*/_interopNamespace(u);
25
24
  var a__namespace = /*#__PURE__*/_interopNamespace(a);
25
+ var l__namespace = /*#__PURE__*/_interopNamespace(l);
26
26
 
27
27
  // src/build-guard.ts
28
- var l = class extends Error {
29
- constructor(n) {
30
- super(n), this.name = "NeetruBuildGuardError";
28
+ var p = class extends Error {
29
+ constructor(t) {
30
+ super(t), this.name = "NeetruBuildGuardError";
31
31
  }
32
32
  };
33
- function p(e) {
33
+ function g(e) {
34
34
  return e == null || e.trim() === "";
35
35
  }
36
36
  function k(e) {
37
37
  if (e.builtEnv !== "prod") return;
38
- let n = [];
39
- if (p(e.oidcClientId) && n.push("NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID"), p(e.productId) && n.push("NEXT_PUBLIC_NEETRU_PRODUCT_ID"), n.length === 0) return;
40
- let t = n.length > 1;
41
- throw new l(
38
+ let t = [];
39
+ if (g(e.oidcClientId) && t.push("NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID"), g(e.productId) && t.push("NEXT_PUBLIC_NEETRU_PRODUCT_ID"), t.length === 0) return;
40
+ let n = t.length > 1;
41
+ throw new p(
42
42
  [
43
43
  "[neetru-sdk] BUILD DE PRODU\xC7\xC3O ABORTADO (withNeetruBuildGuard).",
44
44
  "",
45
- `Vari\xE1ve${t ? "is" : "l"} de ambiente obrigat\xF3ri${t ? "as" : "a"} ausente${t ? "s" : ""}/vazia${t ? "s" : ""} no build de produ\xE7\xE3o (NEXT_PUBLIC_NEETRU_ENV=prod):`,
46
- ...n.map((r) => ` \u2022 ${r}`),
45
+ `Vari\xE1ve${n ? "is" : "l"} de ambiente obrigat\xF3ri${n ? "as" : "a"} ausente${n ? "s" : ""}/vazia${n ? "s" : ""} no build de produ\xE7\xE3o (NEXT_PUBLIC_NEETRU_ENV=prod):`,
46
+ ...t.map((r) => ` \u2022 ${r}`),
47
47
  "",
48
- `Sem ${t ? "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).`,
48
+ `Sem ${n ? "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).`,
49
49
  "",
50
50
  "Como corrigir \u2014 defina no .env.production do produto (ou no ambiente do build de deploy):",
51
- ...n.map((r) => ` ${r}=<valor real vindo do cat\xE1logo do produto no Core>`),
51
+ ...t.map((r) => ` ${r}=<valor real vindo do cat\xE1logo do produto no Core>`),
52
52
  "",
53
53
  "dev/workspace N\xC3O exigem essas vari\xE1veis (usam MockAuth/sandbox) \u2014 s\xF3 o build de produ\xE7\xE3o enfor\xE7a."
54
54
  ].join(`
55
55
  `)
56
56
  );
57
57
  }
58
- var f = ["pg", "drizzle-orm"], g = "*";
59
- function E(e) {
60
- return Array.isArray(e) ? e.filter((n) => typeof n == "string") : [];
58
+ var w = [
59
+ "script-src-elem",
60
+ "script-src",
61
+ "default-src"
62
+ ], E = /^\/(?:api|_next)(?:\/|$)/, m = /^'sha(?:256|384|512)-/;
63
+ function N(e) {
64
+ let t = /* @__PURE__ */ new Map();
65
+ for (let n of e.split(";")) {
66
+ let r = n.trim().split(/\s+/).filter(Boolean);
67
+ if (r.length === 0) continue;
68
+ let o = r[0].toLowerCase();
69
+ t.has(o) || t.set(o, { raw: r.join(" "), sources: r.slice(1) });
70
+ }
71
+ return t;
72
+ }
73
+ function I(e, t) {
74
+ let n = t.filter((o) => {
75
+ let s = o.toLowerCase();
76
+ return s !== "'none'" && !m.test(s);
77
+ });
78
+ return n.some((o) => o.toLowerCase() === "'unsafe-inline'") || n.push("'unsafe-inline'"), n.length === 1 && n.unshift("'self'"), `${e === "default-src" ? "script-src" : e} ${n.join(" ")}`;
79
+ }
80
+ function C(e) {
81
+ let t = N(e), n = w.find((c) => t.has(c));
82
+ if (!n) return null;
83
+ let { raw: r, sources: o } = t.get(n), s = o.map((c) => c.toLowerCase());
84
+ if (s.some((c) => c.startsWith("'nonce-")) || s.includes("'strict-dynamic'")) return null;
85
+ let i = s.includes("'unsafe-inline'"), u = s.some((c) => m.test(c));
86
+ return i && !u ? null : {
87
+ directiveName: n,
88
+ directive: r,
89
+ suggestion: I(n, o),
90
+ unsafeInlineIgnoredByHash: i && u
91
+ };
92
+ }
93
+ function S(e) {
94
+ if (!Array.isArray(e)) return [];
95
+ let t = [];
96
+ for (let n of e) {
97
+ if (!n || typeof n != "object") continue;
98
+ let { source: r, headers: o } = n, s = typeof r == "string" ? r : "";
99
+ if (!E.test(s) && Array.isArray(o))
100
+ for (let i of o) {
101
+ if (!i || typeof i != "object") continue;
102
+ let { key: u, value: c } = i;
103
+ if (!(typeof u != "string" || typeof c != "string") && u.trim().toLowerCase() === "content-security-policy")
104
+ for (let d of c.split(",")) {
105
+ let f = C(d);
106
+ f && t.push({ source: s, headerKey: u.trim(), ...f });
107
+ }
108
+ }
109
+ }
110
+ return t;
111
+ }
112
+ function _(e) {
113
+ if (typeof e != "string" || e.trim() === "") return false;
114
+ try {
115
+ return a__namespace.existsSync(l__namespace.join(e, "app")) || a__namespace.existsSync(l__namespace.join(e, "src", "app"));
116
+ } catch {
117
+ return false;
118
+ }
119
+ }
120
+ function b(e) {
121
+ let t = S(e);
122
+ if (t.length === 0) return;
123
+ let n = [
124
+ "[neetru-sdk] BUILD ABORTADO (withNeetruBuildGuard): a Content-Security-Policy do headers() do next.config bloqueia os scripts embutidos do App Router.",
125
+ "",
126
+ "O App Router p\xF5e <script> embutidos em toda p\xE1gina (self.__next_f.push, com o payload do React Server Components). Com a CSP abaixo o navegador bloqueia esses scripts, a hidrata\xE7\xE3o falha e o React desmonta a \xE1rvore: o servidor responde 200 com o HTML certo e a tela fica EM BRANCO (incidente Zelo 2026-10-22).",
127
+ "",
128
+ `Linha${t.length > 1 ? "s" : ""} a trocar no next.config:`
129
+ ];
130
+ throw t.forEach((r, o) => {
131
+ n.push(""), n.push(`${o + 1}) headers() \u2192 source "${r.source}" \u2192 ${r.headerKey}`), r.directiveName === "default-src" ? (n.push(` a CSP n\xE3o tem script-src, ent\xE3o quem decide os scripts \xE9 o: ${r.directive}`), n.push(` acrescente: ${r.suggestion}`)) : (n.push(` troque: ${r.directive}`), n.push(` por: ${r.suggestion}`), r.unsafeInlineIgnoredByHash && n.push(" (com um hash 'sha\u2026-' na lista, o navegador ignora o 'unsafe-inline' \u2014 por isso o hash sai)"));
132
+ }), n.push(
133
+ "",
134
+ "Sem 'unsafe-inline': use nonce por requisi\xE7\xE3o \u2014 o middleware gera o nonce e manda a CSP com 'nonce-<valor>' 'strict-dynamic' (https://nextjs.org/docs/app/guides/content-security-policy). CSP com nonce ou 'strict-dynamic' passa nesta checagem."
135
+ ), new p(n.join(`
136
+ `));
137
+ }
138
+ function R(e) {
139
+ if (_(process.cwd()))
140
+ try {
141
+ b(e);
142
+ } catch (t) {
143
+ if (t instanceof p && process.env.NODE_ENV === "development") {
144
+ typeof console < "u" && console.warn(t.message);
145
+ return;
146
+ }
147
+ throw t;
148
+ }
61
149
  }
62
- function _(e, n, t) {
63
- let r = [], o = n;
150
+ var y = ["pg", "drizzle-orm"], h = "*";
151
+ function v(e) {
152
+ return Array.isArray(e) ? e.filter((t) => typeof t == "string") : [];
153
+ }
154
+ function T(e, t, n) {
155
+ let r = [], o = t;
64
156
  for (; ; ) {
65
157
  r.push(o);
66
- let i = a__namespace.dirname(o);
67
- if (i === o) break;
68
- o = i;
158
+ let s = l__namespace.dirname(o);
159
+ if (s === o) break;
160
+ o = s;
69
161
  }
70
- r.includes(t) || r.push(t);
71
- for (let i of r) {
72
- let s = a__namespace.join(i, "node_modules", e, "package.json");
162
+ r.includes(n) || r.push(n);
163
+ for (let s of r) {
164
+ let i = l__namespace.join(s, "node_modules", e, "package.json");
73
165
  try {
74
- if (u__namespace.existsSync(s)) return s;
166
+ if (a__namespace.existsSync(i)) return i;
75
167
  } catch {
76
168
  }
77
169
  }
78
170
  return null;
79
171
  }
80
- function m(e) {
172
+ function B(e) {
81
173
  if (typeof e != "string" || e.trim() === "") return [];
82
- let n = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), r = (o, i) => {
83
- if (n.has(o)) return;
84
- n.add(o);
85
- let s = _(o, i, e);
86
- if (!s) return;
174
+ let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = (o, s) => {
175
+ if (t.has(o)) return;
87
176
  t.add(o);
88
- let d;
177
+ let i = T(o, s, e);
178
+ if (!i) return;
179
+ n.add(o);
180
+ let u;
89
181
  try {
90
- d = JSON.parse(u__namespace.readFileSync(s, "utf8"));
182
+ u = JSON.parse(a__namespace.readFileSync(i, "utf8"));
91
183
  } catch {
92
184
  return;
93
185
  }
94
186
  let c = {
95
- ...d.dependencies ?? {},
96
- ...d.optionalDependencies ?? {}
97
- }, b = a__namespace.dirname(s);
98
- for (let v of Object.keys(c)) r(v, b);
187
+ ...u.dependencies ?? {},
188
+ ...u.optionalDependencies ?? {}
189
+ }, d = l__namespace.dirname(i);
190
+ for (let f of Object.keys(c)) r(f, d);
99
191
  };
100
192
  try {
101
- for (let o of f) r(o, e);
193
+ for (let o of y) r(o, e);
102
194
  } catch {
103
195
  return [];
104
196
  }
105
- return [...t].sort();
197
+ return [...n].sort();
106
198
  }
107
- function N(e) {
108
- return e.map((n) => `./node_modules/${n}/**`);
199
+ function x(e) {
200
+ return e.map((t) => `./node_modules/${t}/**`);
109
201
  }
110
- function h(e) {
111
- let n = E(e);
112
- for (let t of f)
113
- n.includes(t) || n.push(t);
114
- return n;
202
+ function A(e) {
203
+ let t = v(e);
204
+ for (let n of y)
205
+ t.includes(n) || t.push(n);
206
+ return t;
115
207
  }
116
- function I(e, n) {
117
- let t = {};
208
+ function O(e, t) {
209
+ let n = {};
118
210
  if (e && typeof e == "object" && !Array.isArray(e))
119
- for (let [o, i] of Object.entries(e))
120
- t[o] = E(i);
121
- if (n.length === 0) return t;
122
- let r = [...t[g] ?? []];
123
- for (let o of n)
211
+ for (let [o, s] of Object.entries(e))
212
+ n[o] = v(s);
213
+ if (t.length === 0) return n;
214
+ let r = [...n[h] ?? []];
215
+ for (let o of t)
124
216
  r.includes(o) || r.push(o);
125
- return t[g] = r, t;
217
+ return n[h] = r, n;
126
218
  }
127
- function T(e, n = {}) {
128
- let t = e.webpack, r = [];
219
+ function P(e, t = {}) {
220
+ let n = e.webpack, r = e.headers, o = [];
129
221
  try {
130
- r = N(m(process.cwd()));
222
+ o = x(B(process.cwd()));
131
223
  } catch {
132
- r = [];
224
+ o = [];
133
225
  }
134
226
  return {
135
227
  ...e,
136
228
  // `serverExternalPackages` é reforço (não o conserto do caso webpackIgnore);
137
229
  // o `outputFileTracingIncludes` computado é o que realmente inclui o closure.
138
- serverExternalPackages: h(e.serverExternalPackages),
139
- outputFileTracingIncludes: I(
230
+ serverExternalPackages: A(e.serverExternalPackages),
231
+ outputFileTracingIncludes: O(
140
232
  e.outputFileTracingIncludes,
141
- r
233
+ o
142
234
  ),
143
- webpack(o, i) {
144
- let s = typeof t == "function" ? t(o, i) : o;
235
+ // CSP x App Router (incidente Zelo 2026-10-22): só embrulha quando o produto
236
+ // TEM `headers()`. Sem ele não há CSP do next.config a checar, e o config
237
+ // continua sem a chave (não inventa um `headers` que o Next não pediu).
238
+ ...typeof r == "function" ? {
239
+ async headers(...s) {
240
+ let i = await r.apply(this, s);
241
+ return R(i), i;
242
+ }
243
+ } : {},
244
+ webpack(s, i) {
245
+ let u = typeof n == "function" ? n(s, i) : s;
145
246
  if (!i.dev && i.isServer) {
146
- let d = {
247
+ let c = {
147
248
  builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,
148
249
  productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,
149
250
  oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,
150
251
  builtAt: (/* @__PURE__ */ new Date()).toISOString()
151
252
  };
152
253
  try {
153
- let c = a__namespace.resolve(process.cwd(), n.outputDir ?? ".next");
154
- u__namespace.mkdirSync(c, { recursive: !0 }), u__namespace.writeFileSync(
155
- a__namespace.join(c, "neetru-build-manifest.json"),
156
- JSON.stringify(d, null, 2),
254
+ let d = l__namespace.resolve(process.cwd(), t.outputDir ?? ".next");
255
+ a__namespace.mkdirSync(d, { recursive: !0 }), a__namespace.writeFileSync(
256
+ l__namespace.join(d, "neetru-build-manifest.json"),
257
+ JSON.stringify(c, null, 2),
157
258
  "utf8"
158
259
  );
159
- } catch (c) {
260
+ } catch (d) {
160
261
  typeof console < "u" && console.warn(
161
262
  "[neetru-sdk] withNeetruBuildGuard: falha ao gravar neetru-build-manifest.json (ignorado, build segue):",
162
- c
263
+ d
163
264
  );
164
265
  }
165
- k(d);
266
+ k(c);
166
267
  }
167
- return s;
268
+ return u;
168
269
  }
169
270
  };
170
271
  }
171
272
 
172
- exports.NEETRU_SQL_SERVER_EXTERNAL_PACKAGES = f;
173
- exports.NEETRU_SQL_TRACE_INCLUDE_KEY = g;
174
- exports.NeetruBuildGuardError = l;
273
+ exports.NEETRU_SQL_SERVER_EXTERNAL_PACKAGES = y;
274
+ exports.NEETRU_SQL_TRACE_INCLUDE_KEY = h;
275
+ exports.NeetruBuildGuardError = p;
276
+ exports.assertNeetruCspAllowsAppRouterScripts = b;
175
277
  exports.assertNeetruProdBuildEnv = k;
176
- exports.mergeOutputFileTracingIncludes = I;
177
- exports.mergeServerExternalPackages = h;
178
- exports.resolveSqlRuntimeClosure = m;
179
- exports.sqlClosureToTraceGlobs = N;
180
- exports.withNeetruBuildGuard = T;
278
+ exports.findCspInlineScriptBlocks = S;
279
+ exports.hasNextAppRouter = _;
280
+ exports.mergeOutputFileTracingIncludes = O;
281
+ exports.mergeServerExternalPackages = A;
282
+ exports.resolveSqlRuntimeClosure = B;
283
+ exports.sqlClosureToTraceGlobs = x;
284
+ exports.withNeetruBuildGuard = P;
@@ -36,6 +36,57 @@ declare class NeetruBuildGuardError extends Error {
36
36
  * reprova; retorna `void` quando passa.
37
37
  */
38
38
  declare function assertNeetruProdBuildEnv(resolved: Pick<NeetruBuildManifest, 'builtEnv' | 'productId' | 'oidcClientId'>): void;
39
+ /**
40
+ * Uma regra de `headers()` do `next.config` (`{ source, headers: [{ key, value }] }`).
41
+ * Tipada frouxa de propósito: é config de produto, pode vir malformada, e quem
42
+ * valida o formato é o próprio Next logo depois. O guard só lê.
43
+ */
44
+ interface NeetruHeaderRule {
45
+ source?: unknown;
46
+ headers?: unknown;
47
+ [key: string]: unknown;
48
+ }
49
+ /** Diretivas que decidem um `<script>` embutido, na ordem de precedência da CSP. */
50
+ type InlineScriptDirectiveName = 'script-src-elem' | 'script-src' | 'default-src';
51
+ /** Uma CSP de `headers()` que bloqueia os `<script>` embutidos do App Router. */
52
+ interface NeetruCspInlineScriptBlock {
53
+ /** `source` da regra de `headers()` (ex.: `'/(.*)'`). */
54
+ source: string;
55
+ /** Nome do header como o produto escreveu (ex.: `'Content-Security-Policy'`). */
56
+ headerKey: string;
57
+ /** Diretiva efetiva para `<script>` embutido. `default-src` = a CSP não tem `script-src`. */
58
+ directiveName: InlineScriptDirectiveName;
59
+ /** A diretiva como está na CSP, espaços normalizados (ex.: `"script-src 'self'"`). */
60
+ directive: string;
61
+ /** Linha que resolve, pronta pra colar (ex.: `"script-src 'self' 'unsafe-inline'"`). */
62
+ suggestion: string;
63
+ /** `true` quando há `'unsafe-inline'`, mas um hash `'sha…-'` na lista faz o navegador ignorá-lo. */
64
+ unsafeInlineIgnoredByHash: boolean;
65
+ }
66
+ /**
67
+ * Checagem pura (sem I/O): lista cada `Content-Security-Policy` do retorno de
68
+ * `headers()` que bloqueia os `<script>` embutidos do App Router. Lista vazia =
69
+ * nada a reprovar. Nunca lança — entrada malformada é ignorada (o Next valida).
70
+ *
71
+ * - Só `Content-Security-Policy` (sem diferença de maiúscula). `…-Report-Only`
72
+ * não bloqueia nada e fica de fora.
73
+ * - Valor com vírgula = várias políticas no mesmo header; TODAS valem no
74
+ * navegador, então cada uma é checada.
75
+ * - Regras de `/api` e `/_next` ficam de fora (não servem página).
76
+ */
77
+ declare function findCspInlineScriptBlocks(rules: unknown): NeetruCspInlineScriptBlock[];
78
+ /**
79
+ * App Router presente? Mesma regra do `findPagesDir` do Next: pasta `app/` na
80
+ * raiz do projeto, ou `src/app/`. Só Pages Router → `false` (ali o Next não põe
81
+ * script EXECUTÁVEL embutido — o `__NEXT_DATA__` é `type="application/json"`).
82
+ */
83
+ declare function hasNextAppRouter(projectDir: string): boolean;
84
+ /**
85
+ * Lança `NeetruBuildGuardError` se alguma CSP de `headers()` bloquear os
86
+ * `<script>` embutidos do App Router, com a linha a trocar de cada uma. Não
87
+ * olha se o app TEM App Router — isso é do `withNeetruBuildGuard`.
88
+ */
89
+ declare function assertNeetruCspAllowsAppRouterScripts(rules: unknown): void;
39
90
  /**
40
91
  * Formato mínimo de `next.config.mjs` que o wrapper precisa entender — só
41
92
  * o suficiente pra compor a chave `webpack` sem acoplar o SDK ao pacote
@@ -49,6 +100,7 @@ type MinimalWebpackContext = {
49
100
  };
50
101
  type MinimalNextConfig = Record<string, unknown> & {
51
102
  webpack?: (config: unknown, context: MinimalWebpackContext) => unknown;
103
+ headers?: (...args: unknown[]) => unknown;
52
104
  serverExternalPackages?: string[];
53
105
  outputFileTracingIncludes?: Record<string, string[]>;
54
106
  };
@@ -114,4 +166,4 @@ declare function mergeServerExternalPackages(existing: unknown): string[];
114
166
  declare function mergeOutputFileTracingIncludes(existing: unknown, globs: readonly string[]): Record<string, string[]>;
115
167
  declare function withNeetruBuildGuard<T extends MinimalNextConfig>(nextConfig: T, options?: WithNeetruBuildGuardOptions): T;
116
168
 
117
- export { NEETRU_SQL_SERVER_EXTERNAL_PACKAGES, NEETRU_SQL_TRACE_INCLUDE_KEY, NeetruBuildGuardError, type NeetruBuildManifest, type WithNeetruBuildGuardOptions, assertNeetruProdBuildEnv, mergeOutputFileTracingIncludes, mergeServerExternalPackages, resolveSqlRuntimeClosure, sqlClosureToTraceGlobs, withNeetruBuildGuard };
169
+ export { NEETRU_SQL_SERVER_EXTERNAL_PACKAGES, NEETRU_SQL_TRACE_INCLUDE_KEY, NeetruBuildGuardError, type NeetruBuildManifest, type NeetruCspInlineScriptBlock, type NeetruHeaderRule, type WithNeetruBuildGuardOptions, assertNeetruCspAllowsAppRouterScripts, assertNeetruProdBuildEnv, findCspInlineScriptBlocks, hasNextAppRouter, mergeOutputFileTracingIncludes, mergeServerExternalPackages, resolveSqlRuntimeClosure, sqlClosureToTraceGlobs, withNeetruBuildGuard };
@@ -36,6 +36,57 @@ declare class NeetruBuildGuardError extends Error {
36
36
  * reprova; retorna `void` quando passa.
37
37
  */
38
38
  declare function assertNeetruProdBuildEnv(resolved: Pick<NeetruBuildManifest, 'builtEnv' | 'productId' | 'oidcClientId'>): void;
39
+ /**
40
+ * Uma regra de `headers()` do `next.config` (`{ source, headers: [{ key, value }] }`).
41
+ * Tipada frouxa de propósito: é config de produto, pode vir malformada, e quem
42
+ * valida o formato é o próprio Next logo depois. O guard só lê.
43
+ */
44
+ interface NeetruHeaderRule {
45
+ source?: unknown;
46
+ headers?: unknown;
47
+ [key: string]: unknown;
48
+ }
49
+ /** Diretivas que decidem um `<script>` embutido, na ordem de precedência da CSP. */
50
+ type InlineScriptDirectiveName = 'script-src-elem' | 'script-src' | 'default-src';
51
+ /** Uma CSP de `headers()` que bloqueia os `<script>` embutidos do App Router. */
52
+ interface NeetruCspInlineScriptBlock {
53
+ /** `source` da regra de `headers()` (ex.: `'/(.*)'`). */
54
+ source: string;
55
+ /** Nome do header como o produto escreveu (ex.: `'Content-Security-Policy'`). */
56
+ headerKey: string;
57
+ /** Diretiva efetiva para `<script>` embutido. `default-src` = a CSP não tem `script-src`. */
58
+ directiveName: InlineScriptDirectiveName;
59
+ /** A diretiva como está na CSP, espaços normalizados (ex.: `"script-src 'self'"`). */
60
+ directive: string;
61
+ /** Linha que resolve, pronta pra colar (ex.: `"script-src 'self' 'unsafe-inline'"`). */
62
+ suggestion: string;
63
+ /** `true` quando há `'unsafe-inline'`, mas um hash `'sha…-'` na lista faz o navegador ignorá-lo. */
64
+ unsafeInlineIgnoredByHash: boolean;
65
+ }
66
+ /**
67
+ * Checagem pura (sem I/O): lista cada `Content-Security-Policy` do retorno de
68
+ * `headers()` que bloqueia os `<script>` embutidos do App Router. Lista vazia =
69
+ * nada a reprovar. Nunca lança — entrada malformada é ignorada (o Next valida).
70
+ *
71
+ * - Só `Content-Security-Policy` (sem diferença de maiúscula). `…-Report-Only`
72
+ * não bloqueia nada e fica de fora.
73
+ * - Valor com vírgula = várias políticas no mesmo header; TODAS valem no
74
+ * navegador, então cada uma é checada.
75
+ * - Regras de `/api` e `/_next` ficam de fora (não servem página).
76
+ */
77
+ declare function findCspInlineScriptBlocks(rules: unknown): NeetruCspInlineScriptBlock[];
78
+ /**
79
+ * App Router presente? Mesma regra do `findPagesDir` do Next: pasta `app/` na
80
+ * raiz do projeto, ou `src/app/`. Só Pages Router → `false` (ali o Next não põe
81
+ * script EXECUTÁVEL embutido — o `__NEXT_DATA__` é `type="application/json"`).
82
+ */
83
+ declare function hasNextAppRouter(projectDir: string): boolean;
84
+ /**
85
+ * Lança `NeetruBuildGuardError` se alguma CSP de `headers()` bloquear os
86
+ * `<script>` embutidos do App Router, com a linha a trocar de cada uma. Não
87
+ * olha se o app TEM App Router — isso é do `withNeetruBuildGuard`.
88
+ */
89
+ declare function assertNeetruCspAllowsAppRouterScripts(rules: unknown): void;
39
90
  /**
40
91
  * Formato mínimo de `next.config.mjs` que o wrapper precisa entender — só
41
92
  * o suficiente pra compor a chave `webpack` sem acoplar o SDK ao pacote
@@ -49,6 +100,7 @@ type MinimalWebpackContext = {
49
100
  };
50
101
  type MinimalNextConfig = Record<string, unknown> & {
51
102
  webpack?: (config: unknown, context: MinimalWebpackContext) => unknown;
103
+ headers?: (...args: unknown[]) => unknown;
52
104
  serverExternalPackages?: string[];
53
105
  outputFileTracingIncludes?: Record<string, string[]>;
54
106
  };
@@ -114,4 +166,4 @@ declare function mergeServerExternalPackages(existing: unknown): string[];
114
166
  declare function mergeOutputFileTracingIncludes(existing: unknown, globs: readonly string[]): Record<string, string[]>;
115
167
  declare function withNeetruBuildGuard<T extends MinimalNextConfig>(nextConfig: T, options?: WithNeetruBuildGuardOptions): T;
116
168
 
117
- export { NEETRU_SQL_SERVER_EXTERNAL_PACKAGES, NEETRU_SQL_TRACE_INCLUDE_KEY, NeetruBuildGuardError, type NeetruBuildManifest, type WithNeetruBuildGuardOptions, assertNeetruProdBuildEnv, mergeOutputFileTracingIncludes, mergeServerExternalPackages, resolveSqlRuntimeClosure, sqlClosureToTraceGlobs, withNeetruBuildGuard };
169
+ export { NEETRU_SQL_SERVER_EXTERNAL_PACKAGES, NEETRU_SQL_TRACE_INCLUDE_KEY, NeetruBuildGuardError, type NeetruBuildManifest, type NeetruCspInlineScriptBlock, type NeetruHeaderRule, type WithNeetruBuildGuardOptions, assertNeetruCspAllowsAppRouterScripts, assertNeetruProdBuildEnv, findCspInlineScriptBlocks, hasNextAppRouter, mergeOutputFileTracingIncludes, mergeServerExternalPackages, resolveSqlRuntimeClosure, sqlClosureToTraceGlobs, withNeetruBuildGuard };
@@ -1,149 +1,250 @@
1
- import * as u from 'fs';
2
- import * as a from 'path';
1
+ import * as a from 'fs';
2
+ import * as l from 'path';
3
3
 
4
4
  // src/build-guard.ts
5
- var l = class extends Error {
6
- constructor(n) {
7
- super(n), this.name = "NeetruBuildGuardError";
5
+ var p = class extends Error {
6
+ constructor(t) {
7
+ super(t), this.name = "NeetruBuildGuardError";
8
8
  }
9
9
  };
10
- function p(e) {
10
+ function g(e) {
11
11
  return e == null || e.trim() === "";
12
12
  }
13
13
  function k(e) {
14
14
  if (e.builtEnv !== "prod") return;
15
- let n = [];
16
- if (p(e.oidcClientId) && n.push("NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID"), p(e.productId) && n.push("NEXT_PUBLIC_NEETRU_PRODUCT_ID"), n.length === 0) return;
17
- let t = n.length > 1;
18
- throw new l(
15
+ let t = [];
16
+ if (g(e.oidcClientId) && t.push("NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID"), g(e.productId) && t.push("NEXT_PUBLIC_NEETRU_PRODUCT_ID"), t.length === 0) return;
17
+ let n = t.length > 1;
18
+ throw new p(
19
19
  [
20
20
  "[neetru-sdk] BUILD DE PRODU\xC7\xC3O ABORTADO (withNeetruBuildGuard).",
21
21
  "",
22
- `Vari\xE1ve${t ? "is" : "l"} de ambiente obrigat\xF3ri${t ? "as" : "a"} ausente${t ? "s" : ""}/vazia${t ? "s" : ""} no build de produ\xE7\xE3o (NEXT_PUBLIC_NEETRU_ENV=prod):`,
23
- ...n.map((r) => ` \u2022 ${r}`),
22
+ `Vari\xE1ve${n ? "is" : "l"} de ambiente obrigat\xF3ri${n ? "as" : "a"} ausente${n ? "s" : ""}/vazia${n ? "s" : ""} no build de produ\xE7\xE3o (NEXT_PUBLIC_NEETRU_ENV=prod):`,
23
+ ...t.map((r) => ` \u2022 ${r}`),
24
24
  "",
25
- `Sem ${t ? "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).`,
25
+ `Sem ${n ? "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).`,
26
26
  "",
27
27
  "Como corrigir \u2014 defina no .env.production do produto (ou no ambiente do build de deploy):",
28
- ...n.map((r) => ` ${r}=<valor real vindo do cat\xE1logo do produto no Core>`),
28
+ ...t.map((r) => ` ${r}=<valor real vindo do cat\xE1logo do produto no Core>`),
29
29
  "",
30
30
  "dev/workspace N\xC3O exigem essas vari\xE1veis (usam MockAuth/sandbox) \u2014 s\xF3 o build de produ\xE7\xE3o enfor\xE7a."
31
31
  ].join(`
32
32
  `)
33
33
  );
34
34
  }
35
- var f = ["pg", "drizzle-orm"], g = "*";
36
- function E(e) {
37
- return Array.isArray(e) ? e.filter((n) => typeof n == "string") : [];
35
+ var w = [
36
+ "script-src-elem",
37
+ "script-src",
38
+ "default-src"
39
+ ], E = /^\/(?:api|_next)(?:\/|$)/, m = /^'sha(?:256|384|512)-/;
40
+ function N(e) {
41
+ let t = /* @__PURE__ */ new Map();
42
+ for (let n of e.split(";")) {
43
+ let r = n.trim().split(/\s+/).filter(Boolean);
44
+ if (r.length === 0) continue;
45
+ let o = r[0].toLowerCase();
46
+ t.has(o) || t.set(o, { raw: r.join(" "), sources: r.slice(1) });
47
+ }
48
+ return t;
49
+ }
50
+ function I(e, t) {
51
+ let n = t.filter((o) => {
52
+ let s = o.toLowerCase();
53
+ return s !== "'none'" && !m.test(s);
54
+ });
55
+ return n.some((o) => o.toLowerCase() === "'unsafe-inline'") || n.push("'unsafe-inline'"), n.length === 1 && n.unshift("'self'"), `${e === "default-src" ? "script-src" : e} ${n.join(" ")}`;
56
+ }
57
+ function C(e) {
58
+ let t = N(e), n = w.find((c) => t.has(c));
59
+ if (!n) return null;
60
+ let { raw: r, sources: o } = t.get(n), s = o.map((c) => c.toLowerCase());
61
+ if (s.some((c) => c.startsWith("'nonce-")) || s.includes("'strict-dynamic'")) return null;
62
+ let i = s.includes("'unsafe-inline'"), u = s.some((c) => m.test(c));
63
+ return i && !u ? null : {
64
+ directiveName: n,
65
+ directive: r,
66
+ suggestion: I(n, o),
67
+ unsafeInlineIgnoredByHash: i && u
68
+ };
69
+ }
70
+ function S(e) {
71
+ if (!Array.isArray(e)) return [];
72
+ let t = [];
73
+ for (let n of e) {
74
+ if (!n || typeof n != "object") continue;
75
+ let { source: r, headers: o } = n, s = typeof r == "string" ? r : "";
76
+ if (!E.test(s) && Array.isArray(o))
77
+ for (let i of o) {
78
+ if (!i || typeof i != "object") continue;
79
+ let { key: u, value: c } = i;
80
+ if (!(typeof u != "string" || typeof c != "string") && u.trim().toLowerCase() === "content-security-policy")
81
+ for (let d of c.split(",")) {
82
+ let f = C(d);
83
+ f && t.push({ source: s, headerKey: u.trim(), ...f });
84
+ }
85
+ }
86
+ }
87
+ return t;
88
+ }
89
+ function _(e) {
90
+ if (typeof e != "string" || e.trim() === "") return false;
91
+ try {
92
+ return a.existsSync(l.join(e, "app")) || a.existsSync(l.join(e, "src", "app"));
93
+ } catch {
94
+ return false;
95
+ }
96
+ }
97
+ function b(e) {
98
+ let t = S(e);
99
+ if (t.length === 0) return;
100
+ let n = [
101
+ "[neetru-sdk] BUILD ABORTADO (withNeetruBuildGuard): a Content-Security-Policy do headers() do next.config bloqueia os scripts embutidos do App Router.",
102
+ "",
103
+ "O App Router p\xF5e <script> embutidos em toda p\xE1gina (self.__next_f.push, com o payload do React Server Components). Com a CSP abaixo o navegador bloqueia esses scripts, a hidrata\xE7\xE3o falha e o React desmonta a \xE1rvore: o servidor responde 200 com o HTML certo e a tela fica EM BRANCO (incidente Zelo 2026-10-22).",
104
+ "",
105
+ `Linha${t.length > 1 ? "s" : ""} a trocar no next.config:`
106
+ ];
107
+ throw t.forEach((r, o) => {
108
+ n.push(""), n.push(`${o + 1}) headers() \u2192 source "${r.source}" \u2192 ${r.headerKey}`), r.directiveName === "default-src" ? (n.push(` a CSP n\xE3o tem script-src, ent\xE3o quem decide os scripts \xE9 o: ${r.directive}`), n.push(` acrescente: ${r.suggestion}`)) : (n.push(` troque: ${r.directive}`), n.push(` por: ${r.suggestion}`), r.unsafeInlineIgnoredByHash && n.push(" (com um hash 'sha\u2026-' na lista, o navegador ignora o 'unsafe-inline' \u2014 por isso o hash sai)"));
109
+ }), n.push(
110
+ "",
111
+ "Sem 'unsafe-inline': use nonce por requisi\xE7\xE3o \u2014 o middleware gera o nonce e manda a CSP com 'nonce-<valor>' 'strict-dynamic' (https://nextjs.org/docs/app/guides/content-security-policy). CSP com nonce ou 'strict-dynamic' passa nesta checagem."
112
+ ), new p(n.join(`
113
+ `));
114
+ }
115
+ function R(e) {
116
+ if (_(process.cwd()))
117
+ try {
118
+ b(e);
119
+ } catch (t) {
120
+ if (t instanceof p && process.env.NODE_ENV === "development") {
121
+ typeof console < "u" && console.warn(t.message);
122
+ return;
123
+ }
124
+ throw t;
125
+ }
38
126
  }
39
- function _(e, n, t) {
40
- let r = [], o = n;
127
+ var y = ["pg", "drizzle-orm"], h = "*";
128
+ function v(e) {
129
+ return Array.isArray(e) ? e.filter((t) => typeof t == "string") : [];
130
+ }
131
+ function T(e, t, n) {
132
+ let r = [], o = t;
41
133
  for (; ; ) {
42
134
  r.push(o);
43
- let i = a.dirname(o);
44
- if (i === o) break;
45
- o = i;
135
+ let s = l.dirname(o);
136
+ if (s === o) break;
137
+ o = s;
46
138
  }
47
- r.includes(t) || r.push(t);
48
- for (let i of r) {
49
- let s = a.join(i, "node_modules", e, "package.json");
139
+ r.includes(n) || r.push(n);
140
+ for (let s of r) {
141
+ let i = l.join(s, "node_modules", e, "package.json");
50
142
  try {
51
- if (u.existsSync(s)) return s;
143
+ if (a.existsSync(i)) return i;
52
144
  } catch {
53
145
  }
54
146
  }
55
147
  return null;
56
148
  }
57
- function m(e) {
149
+ function B(e) {
58
150
  if (typeof e != "string" || e.trim() === "") return [];
59
- let n = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set(), r = (o, i) => {
60
- if (n.has(o)) return;
61
- n.add(o);
62
- let s = _(o, i, e);
63
- if (!s) return;
151
+ let t = /* @__PURE__ */ new Set(), n = /* @__PURE__ */ new Set(), r = (o, s) => {
152
+ if (t.has(o)) return;
64
153
  t.add(o);
65
- let d;
154
+ let i = T(o, s, e);
155
+ if (!i) return;
156
+ n.add(o);
157
+ let u;
66
158
  try {
67
- d = JSON.parse(u.readFileSync(s, "utf8"));
159
+ u = JSON.parse(a.readFileSync(i, "utf8"));
68
160
  } catch {
69
161
  return;
70
162
  }
71
163
  let c = {
72
- ...d.dependencies ?? {},
73
- ...d.optionalDependencies ?? {}
74
- }, b = a.dirname(s);
75
- for (let v of Object.keys(c)) r(v, b);
164
+ ...u.dependencies ?? {},
165
+ ...u.optionalDependencies ?? {}
166
+ }, d = l.dirname(i);
167
+ for (let f of Object.keys(c)) r(f, d);
76
168
  };
77
169
  try {
78
- for (let o of f) r(o, e);
170
+ for (let o of y) r(o, e);
79
171
  } catch {
80
172
  return [];
81
173
  }
82
- return [...t].sort();
174
+ return [...n].sort();
83
175
  }
84
- function N(e) {
85
- return e.map((n) => `./node_modules/${n}/**`);
176
+ function x(e) {
177
+ return e.map((t) => `./node_modules/${t}/**`);
86
178
  }
87
- function h(e) {
88
- let n = E(e);
89
- for (let t of f)
90
- n.includes(t) || n.push(t);
91
- return n;
179
+ function A(e) {
180
+ let t = v(e);
181
+ for (let n of y)
182
+ t.includes(n) || t.push(n);
183
+ return t;
92
184
  }
93
- function I(e, n) {
94
- let t = {};
185
+ function O(e, t) {
186
+ let n = {};
95
187
  if (e && typeof e == "object" && !Array.isArray(e))
96
- for (let [o, i] of Object.entries(e))
97
- t[o] = E(i);
98
- if (n.length === 0) return t;
99
- let r = [...t[g] ?? []];
100
- for (let o of n)
188
+ for (let [o, s] of Object.entries(e))
189
+ n[o] = v(s);
190
+ if (t.length === 0) return n;
191
+ let r = [...n[h] ?? []];
192
+ for (let o of t)
101
193
  r.includes(o) || r.push(o);
102
- return t[g] = r, t;
194
+ return n[h] = r, n;
103
195
  }
104
- function T(e, n = {}) {
105
- let t = e.webpack, r = [];
196
+ function P(e, t = {}) {
197
+ let n = e.webpack, r = e.headers, o = [];
106
198
  try {
107
- r = N(m(process.cwd()));
199
+ o = x(B(process.cwd()));
108
200
  } catch {
109
- r = [];
201
+ o = [];
110
202
  }
111
203
  return {
112
204
  ...e,
113
205
  // `serverExternalPackages` é reforço (não o conserto do caso webpackIgnore);
114
206
  // o `outputFileTracingIncludes` computado é o que realmente inclui o closure.
115
- serverExternalPackages: h(e.serverExternalPackages),
116
- outputFileTracingIncludes: I(
207
+ serverExternalPackages: A(e.serverExternalPackages),
208
+ outputFileTracingIncludes: O(
117
209
  e.outputFileTracingIncludes,
118
- r
210
+ o
119
211
  ),
120
- webpack(o, i) {
121
- let s = typeof t == "function" ? t(o, i) : o;
212
+ // CSP x App Router (incidente Zelo 2026-10-22): só embrulha quando o produto
213
+ // TEM `headers()`. Sem ele não há CSP do next.config a checar, e o config
214
+ // continua sem a chave (não inventa um `headers` que o Next não pediu).
215
+ ...typeof r == "function" ? {
216
+ async headers(...s) {
217
+ let i = await r.apply(this, s);
218
+ return R(i), i;
219
+ }
220
+ } : {},
221
+ webpack(s, i) {
222
+ let u = typeof n == "function" ? n(s, i) : s;
122
223
  if (!i.dev && i.isServer) {
123
- let d = {
224
+ let c = {
124
225
  builtEnv: process.env.NEXT_PUBLIC_NEETRU_ENV ?? null,
125
226
  productId: process.env.NEXT_PUBLIC_NEETRU_PRODUCT_ID ?? null,
126
227
  oidcClientId: process.env.NEXT_PUBLIC_NEETRU_OIDC_CLIENT_ID ?? null,
127
228
  builtAt: (/* @__PURE__ */ new Date()).toISOString()
128
229
  };
129
230
  try {
130
- let c = a.resolve(process.cwd(), n.outputDir ?? ".next");
131
- u.mkdirSync(c, { recursive: !0 }), u.writeFileSync(
132
- a.join(c, "neetru-build-manifest.json"),
133
- JSON.stringify(d, null, 2),
231
+ let d = l.resolve(process.cwd(), t.outputDir ?? ".next");
232
+ a.mkdirSync(d, { recursive: !0 }), a.writeFileSync(
233
+ l.join(d, "neetru-build-manifest.json"),
234
+ JSON.stringify(c, null, 2),
134
235
  "utf8"
135
236
  );
136
- } catch (c) {
237
+ } catch (d) {
137
238
  typeof console < "u" && console.warn(
138
239
  "[neetru-sdk] withNeetruBuildGuard: falha ao gravar neetru-build-manifest.json (ignorado, build segue):",
139
- c
240
+ d
140
241
  );
141
242
  }
142
- k(d);
243
+ k(c);
143
244
  }
144
- return s;
245
+ return u;
145
246
  }
146
247
  };
147
248
  }
148
249
 
149
- export { f as NEETRU_SQL_SERVER_EXTERNAL_PACKAGES, g as NEETRU_SQL_TRACE_INCLUDE_KEY, l as NeetruBuildGuardError, k as assertNeetruProdBuildEnv, I as mergeOutputFileTracingIncludes, h as mergeServerExternalPackages, m as resolveSqlRuntimeClosure, N as sqlClosureToTraceGlobs, T as withNeetruBuildGuard };
250
+ export { y as NEETRU_SQL_SERVER_EXTERNAL_PACKAGES, h as NEETRU_SQL_TRACE_INCLUDE_KEY, p as NeetruBuildGuardError, b as assertNeetruCspAllowsAppRouterScripts, k as assertNeetruProdBuildEnv, S as findCspInlineScriptBlocks, _ as hasNextAppRouter, O as mergeOutputFileTracingIncludes, A as mergeServerExternalPackages, B as resolveSqlRuntimeClosure, x as sqlClosureToTraceGlobs, P as withNeetruBuildGuard };
package/dist/catalog.cjs CHANGED
@@ -108,7 +108,7 @@ function G(t, e) {
108
108
  }
109
109
  function M() {
110
110
  try {
111
- return "3.9.0";
111
+ return "3.9.1";
112
112
  } catch {
113
113
  return;
114
114
  }
package/dist/catalog.mjs CHANGED
@@ -106,7 +106,7 @@ function G(t, e) {
106
106
  }
107
107
  function M() {
108
108
  try {
109
- return "3.9.0";
109
+ return "3.9.1";
110
110
  } catch {
111
111
  return;
112
112
  }
package/dist/checkout.cjs CHANGED
@@ -108,7 +108,7 @@ function F(t, e) {
108
108
  }
109
109
  function M() {
110
110
  try {
111
- return "3.9.0";
111
+ return "3.9.1";
112
112
  } catch {
113
113
  return;
114
114
  }
package/dist/checkout.mjs CHANGED
@@ -106,7 +106,7 @@ function F(t, e) {
106
106
  }
107
107
  function M() {
108
108
  try {
109
- return "3.9.0";
109
+ return "3.9.1";
110
110
  } catch {
111
111
  return;
112
112
  }
package/dist/db.cjs CHANGED
@@ -152,7 +152,7 @@ function kt(r, e) {
152
152
  }
153
153
  function qe() {
154
154
  try {
155
- return "3.9.0";
155
+ return "3.9.1";
156
156
  } catch {
157
157
  return;
158
158
  }
package/dist/db.mjs CHANGED
@@ -150,7 +150,7 @@ function kt(r, e) {
150
150
  }
151
151
  function qe() {
152
152
  try {
153
- return "3.9.0";
153
+ return "3.9.1";
154
154
  } catch {
155
155
  return;
156
156
  }
package/dist/index.cjs CHANGED
@@ -156,7 +156,7 @@ function kr(n, e) {
156
156
  }
157
157
  function Ut() {
158
158
  try {
159
- return "3.9.0";
159
+ return "3.9.1";
160
160
  } catch {
161
161
  return;
162
162
  }
@@ -6927,7 +6927,7 @@ function pi(n) {
6927
6927
 
6928
6928
  // src/index.ts
6929
6929
  ve();
6930
- var Wa = "3.9.0";
6930
+ var Wa = "3.9.1";
6931
6931
 
6932
6932
  exports.DEFAULT_BASE_URL = We;
6933
6933
  exports.DEV_FIXTURE_USER = qe;
package/dist/index.d.cts CHANGED
@@ -246,6 +246,6 @@ declare function detectNonServerRuntime(): NonServerRuntime | null;
246
246
  */
247
247
 
248
248
  /** Versão do SDK — exportada explicitamente pra detecção em runtime. */
249
- declare const VERSION: "3.9.0";
249
+ declare const VERSION: "3.9.1";
250
250
 
251
251
  export { type AuthenticateProductRequestOptions, type HeadersSource, NEETRU_OIDC_ISSUER, type NonServerRuntime, type ProductRequestAuth, VERSION, type VerifiedAccessToken, type VerifyAccessTokenOptions, accessTokenErrorToHttp, authenticateProductRequest, checkCoreVersionCompat, detectNonServerRuntime, readBearerToken, readCookie, verifyAccessToken };
package/dist/index.d.ts CHANGED
@@ -246,6 +246,6 @@ declare function detectNonServerRuntime(): NonServerRuntime | null;
246
246
  */
247
247
 
248
248
  /** Versão do SDK — exportada explicitamente pra detecção em runtime. */
249
- declare const VERSION: "3.9.0";
249
+ declare const VERSION: "3.9.1";
250
250
 
251
251
  export { type AuthenticateProductRequestOptions, type HeadersSource, NEETRU_OIDC_ISSUER, type NonServerRuntime, type ProductRequestAuth, VERSION, type VerifiedAccessToken, type VerifyAccessTokenOptions, accessTokenErrorToHttp, authenticateProductRequest, checkCoreVersionCompat, detectNonServerRuntime, readBearerToken, readCookie, verifyAccessToken };
package/dist/index.mjs CHANGED
@@ -154,7 +154,7 @@ function kr(n, e) {
154
154
  }
155
155
  function Ut() {
156
156
  try {
157
- return "3.9.0";
157
+ return "3.9.1";
158
158
  } catch {
159
159
  return;
160
160
  }
@@ -6925,6 +6925,6 @@ function pi(n) {
6925
6925
 
6926
6926
  // src/index.ts
6927
6927
  ve();
6928
- var Wa = "3.9.0";
6928
+ var Wa = "3.9.1";
6929
6929
 
6930
6930
  export { We as DEFAULT_BASE_URL, qe as DEV_FIXTURE_USER, me as MockAi, de as MockAuth, Oe as MockCheckout, ut as MockDb, fe as MockEntitlements, le as MockNotifications, pe as MockSupport, ue as MockUsage, ce as MockWebhooks, ir as NEETRU_OIDC_ISSUER, Qe as NEETRU_SENTINEL_KEY, $ as NeetruAuthRequiredError, v as NeetruDbError, c as NeetruError, Wa as VERSION, pi as accessTokenErrorToHttp, ui as authenticateProductRequest, ne as checkCoreVersionCompat, dt as createAiNamespace, st as createCheckoutNamespace, rr as createNeetruClient, ot as createNeetruDb, lt as createNotificationsNamespace, at as createWebhooksNamespace, J as detectNonServerRuntime, ci as getServerNeetruClient, Xr as increment, Q as isFieldSentinel, en as isIncrementSentinel, Zt as isServerTimestampSentinel, lr as readBearerToken, dr as readCookie, Jr as serverTimestamp, ar as verifyAccessToken, Lo as verifyWebhookRequest, wn as verifyWebhookSignature };
@@ -108,7 +108,7 @@ function Y(t, e) {
108
108
  }
109
109
  function q() {
110
110
  try {
111
- return "3.9.0";
111
+ return "3.9.1";
112
112
  } catch {
113
113
  return;
114
114
  }
@@ -106,7 +106,7 @@ function Y(t, e) {
106
106
  }
107
107
  function q() {
108
108
  try {
109
- return "3.9.0";
109
+ return "3.9.1";
110
110
  } catch {
111
111
  return;
112
112
  }
package/dist/support.cjs CHANGED
@@ -112,7 +112,7 @@ function Q(e, t) {
112
112
  }
113
113
  function $() {
114
114
  try {
115
- return "3.9.0";
115
+ return "3.9.1";
116
116
  } catch {
117
117
  return;
118
118
  }
package/dist/support.mjs CHANGED
@@ -110,7 +110,7 @@ function Q(e, t) {
110
110
  }
111
111
  function $() {
112
112
  try {
113
- return "3.9.0";
113
+ return "3.9.1";
114
114
  } catch {
115
115
  return;
116
116
  }
@@ -108,7 +108,7 @@ function B(e, t) {
108
108
  }
109
109
  function P() {
110
110
  try {
111
- return "3.9.0";
111
+ return "3.9.1";
112
112
  } catch {
113
113
  return;
114
114
  }
@@ -106,7 +106,7 @@ function B(e, t) {
106
106
  }
107
107
  function P() {
108
108
  try {
109
- return "3.9.0";
109
+ return "3.9.1";
110
110
  } catch {
111
111
  return;
112
112
  }
package/dist/usage.cjs CHANGED
@@ -108,7 +108,7 @@ function V(e, t) {
108
108
  }
109
109
  function q() {
110
110
  try {
111
- return "3.9.0";
111
+ return "3.9.1";
112
112
  } catch {
113
113
  return;
114
114
  }
package/dist/usage.mjs CHANGED
@@ -106,7 +106,7 @@ function V(e, t) {
106
106
  }
107
107
  function q() {
108
108
  try {
109
- return "3.9.0";
109
+ return "3.9.1";
110
110
  } catch {
111
111
  return;
112
112
  }
package/dist/webhooks.cjs CHANGED
@@ -108,7 +108,7 @@ function X(t, e) {
108
108
  }
109
109
  function $() {
110
110
  try {
111
- return "3.9.0";
111
+ return "3.9.1";
112
112
  } catch {
113
113
  return;
114
114
  }
package/dist/webhooks.mjs CHANGED
@@ -106,7 +106,7 @@ function X(t, e) {
106
106
  }
107
107
  function $() {
108
108
  try {
109
- return "3.9.0";
109
+ return "3.9.1";
110
110
  } catch {
111
111
  return;
112
112
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neetru/sdk",
3
- "version": "3.9.0",
3
+ "version": "3.9.1",
4
4
  "description": "Neetru SDK 3.0 — biblioteca runtime universal (browser/Node/Edge) para consumir o ecossistema Neetru. Paths canonical /api/sdk/v1/*, productId obrigatório, Idempotency-Key em mutations, WebCrypto signatures, baseUrl allowlist fail-closed.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",