@neetru/sdk 3.8.1 → 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.
Files changed (71) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +14 -1
  3. package/dist/ai.cjs +1 -1
  4. package/dist/ai.d.cts +1 -1
  5. package/dist/ai.d.ts +1 -1
  6. package/dist/ai.mjs +1 -1
  7. package/dist/auth.cjs +844 -803
  8. package/dist/auth.d.cts +1 -1
  9. package/dist/auth.d.ts +1 -1
  10. package/dist/auth.mjs +841 -800
  11. package/dist/build-guard.cjs +186 -82
  12. package/dist/build-guard.d.cts +53 -1
  13. package/dist/build-guard.d.ts +53 -1
  14. package/dist/build-guard.mjs +175 -74
  15. package/dist/catalog.cjs +1 -1
  16. package/dist/catalog.d.cts +1 -1
  17. package/dist/catalog.d.ts +1 -1
  18. package/dist/catalog.mjs +1 -1
  19. package/dist/checkout.cjs +62 -49
  20. package/dist/checkout.d.cts +1 -1
  21. package/dist/checkout.d.ts +1 -1
  22. package/dist/checkout.mjs +62 -49
  23. package/dist/db-react.d.cts +1 -1
  24. package/dist/db-react.d.ts +1 -1
  25. package/dist/db.cjs +200 -187
  26. package/dist/db.d.cts +1 -1
  27. package/dist/db.d.ts +1 -1
  28. package/dist/db.mjs +193 -180
  29. package/dist/entitlements.d.cts +1 -1
  30. package/dist/entitlements.d.ts +1 -1
  31. package/dist/firestore-compat.d.cts +1 -1
  32. package/dist/firestore-compat.d.ts +1 -1
  33. package/dist/index.cjs +880 -839
  34. package/dist/index.d.cts +2 -2
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.mjs +847 -806
  37. package/dist/mobile.cjs +328 -276
  38. package/dist/mobile.d.cts +12 -2
  39. package/dist/mobile.d.ts +12 -2
  40. package/dist/mobile.mjs +328 -276
  41. package/dist/mocks.cjs +5 -5
  42. package/dist/mocks.d.cts +2 -2
  43. package/dist/mocks.d.ts +2 -2
  44. package/dist/mocks.mjs +4 -4
  45. package/dist/notifications.cjs +1 -1
  46. package/dist/notifications.d.cts +1 -1
  47. package/dist/notifications.d.ts +1 -1
  48. package/dist/notifications.mjs +1 -1
  49. package/dist/react.cjs +119 -119
  50. package/dist/react.d.cts +8 -2
  51. package/dist/react.d.ts +8 -2
  52. package/dist/react.mjs +119 -119
  53. package/dist/support.cjs +1 -1
  54. package/dist/support.d.cts +1 -1
  55. package/dist/support.d.ts +1 -1
  56. package/dist/support.mjs +1 -1
  57. package/dist/telemetry.cjs +62 -49
  58. package/dist/telemetry.d.cts +1 -1
  59. package/dist/telemetry.d.ts +1 -1
  60. package/dist/telemetry.mjs +62 -49
  61. package/dist/{types-yv3EDKg2.d.cts → types-Bl_4HROd.d.cts} +62 -3
  62. package/dist/{types-BYPk_3HR.d.ts → types-Bqnsqvow.d.ts} +62 -3
  63. package/dist/usage.cjs +1 -1
  64. package/dist/usage.d.cts +1 -1
  65. package/dist/usage.d.ts +1 -1
  66. package/dist/usage.mjs +1 -1
  67. package/dist/webhooks.cjs +1 -1
  68. package/dist/webhooks.d.cts +1 -1
  69. package/dist/webhooks.d.ts +1 -1
  70. package/dist/webhooks.mjs +1 -1
  71. package/package.json +9 -1
@@ -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 };