synthesisui 0.16.377 → 0.16.378
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/doctor.js +13 -1
- package/dist/doctor/scan.js +113 -1
- package/dist/install-marks.js +17 -2
- package/package.json +1 -1
package/dist/commands/doctor.js
CHANGED
|
@@ -890,7 +890,19 @@ export async function doctor(opts) {
|
|
|
890
890
|
* "not drift" era a nossa palavra para o motivo, e ela não diz o motivo. As duas razões reais
|
|
891
891
|
* cabem na linha: ou nenhum token poderia segurar aquele valor, ou ele já vem de um.
|
|
892
892
|
*/
|
|
893
|
-
|
|
893
|
+
/**
|
|
894
|
+
* E EM 05/09 ELAS VIRARAM TRÊS, senão esta linha volta a esconder metade.
|
|
895
|
+
*
|
|
896
|
+
* Os dois motivos novos não cabem em nenhum dos dois antigos: um token PODERIA segurar aquele
|
|
897
|
+
* valor, e é justamente por isso que escrevê-lo ali destrói. Uma cor dentro do e-mail que o app
|
|
898
|
+
* monta como texto, ou dentro de um hex escrito numa frase da página, não é pintada pela folha
|
|
899
|
+
* do app - `var()` não resolve num cliente de e-mail, e uma frase não é pintura nenhuma.
|
|
900
|
+
*
|
|
901
|
+
* Esta é a linha que o cliente lê SEM `--verbose`, e ela é o resumo inteiro para quem não pede
|
|
902
|
+
* detalhe. Sem a terceira metade, 61 valores no repositório dele saem da conta sob um motivo
|
|
903
|
+
* que não é o deles.
|
|
904
|
+
*/
|
|
905
|
+
console.log(body(`${plural(asideTotal, "value")} left out of the count - a token could never hold them, they already come from one, or the page never paints them` +
|
|
894
906
|
(skippedProjects.length > 0
|
|
895
907
|
? `, and ${plural(skippedProjects.length, "nested project")} that speak their own systems`
|
|
896
908
|
: "") +
|
package/dist/doctor/scan.js
CHANGED
|
@@ -269,6 +269,97 @@ function fallbackSpans(line, table) {
|
|
|
269
269
|
}
|
|
270
270
|
return out;
|
|
271
271
|
}
|
|
272
|
+
/**
|
|
273
|
+
* ONDE A CASCATA DO APP NÃO ALCANÇA - e trocar por `var()` ali APAGA a cor.
|
|
274
|
+
*
|
|
275
|
+
* O QUE ACONTECIA: `apps/web/lib/email.ts` monta o e-mail de login como TEXTO, e o `--fix` trocou
|
|
276
|
+
* `background:#6366f1` por `background:var(--color-brand-indigo)` no botão "Sign in". Aquele HTML é
|
|
277
|
+
* entregue a um cliente de e-mail, onde o `:root` do app não existe: a custom property não resolve,
|
|
278
|
+
* a declaração fica inválida, e o `background` volta para `transparent`. O botão de entrar some
|
|
279
|
+
* sobre um card quase preto - e é a PRIMEIRA tela que um usuário novo vê.
|
|
280
|
+
*
|
|
281
|
+
* É A MESMA FAMÍLIA DE `RENDERS_IMAGE`, que já recusa o arquivo que desenha para uma imagem pelo
|
|
282
|
+
* mesmo motivo declarado: "where CSS variables do not exist". Faltava a metade que sai como HTML.
|
|
283
|
+
*
|
|
284
|
+
* O SINAL É DA LINGUAGEM, NÃO DO REPOSITÓRIO: em `.ts`/`.tsx`/`.js`/`.jsx`, `style="..."` com uma
|
|
285
|
+
* declaração dentro NÃO é JSX - o React tipa `style` como objeto (`style={{}}`). Um atributo HTML
|
|
286
|
+
* escrito com aspas só existe ali dentro de uma string, isto é, marcação montada como texto: um
|
|
287
|
+
* e-mail, um PDF, um `srcdoc`, um sanitizador. Nenhum deles herda a folha do app.
|
|
288
|
+
*
|
|
289
|
+
* `.vue` e `.svelte` ficam FORA de propósito: neles `style="..."` é atributo de template real, o
|
|
290
|
+
* elemento é do app, e a cascata alcança. Recusar ali cegaria o produto para dois frameworks
|
|
291
|
+
* inteiros.
|
|
292
|
+
*
|
|
293
|
+
* MEDIDO em 05/09, em 4 escopos: `codelevel-monorepo` 7 linhas (`apps/web/lib/email.ts`, 2 delas já
|
|
294
|
+
* trocadas pelo `--fix` no repositório dele) · `frontend-hub/packages/ui` 3 linhas
|
|
295
|
+
* (`SignalUI/.../Sanitize.ts`, que remonta HTML de editor de texto) · `synthesisui-hub/apps/web`
|
|
296
|
+
* 18 linhas (`src/lib/email.ts` - o nosso próprio produto tem a forma) · `frontend-hub/apps/web-
|
|
297
|
+
* dashboard` 0. Três de quatro: a forma é geral, não é peculiaridade de um repositório.
|
|
298
|
+
*/
|
|
299
|
+
const HTML_STYLE_ATTR = /style\s*=\s*"([^"]*)"/g;
|
|
300
|
+
/** Só onde `style="..."` não pode ser um elemento do app - ver `HTML_STYLE_ATTR`. */
|
|
301
|
+
const ASSEMBLES_MARKUP = /\.(?:tsx?|jsx?|mjs|cjs)$/i;
|
|
302
|
+
function markupTextSpans(file, line) {
|
|
303
|
+
if (!ASSEMBLES_MARKUP.test(file))
|
|
304
|
+
return [];
|
|
305
|
+
const out = [];
|
|
306
|
+
for (const m of line.matchAll(HTML_STYLE_ATTR)) {
|
|
307
|
+
if (!m[1].includes(":"))
|
|
308
|
+
continue;
|
|
309
|
+
const start = (m.index ?? 0) + m[0].indexOf('"') + 1;
|
|
310
|
+
out.push([start, start + m[1].length]);
|
|
311
|
+
}
|
|
312
|
+
return out;
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* O QUE A PÁGINA DIZ NÃO É O QUE ELA PINTA - e o `--fix` reescreveu uma frase.
|
|
316
|
+
*
|
|
317
|
+
* O QUE ACONTECIA: a landing dele demonstra a própria ferramenta num terminal falso, e a frase era
|
|
318
|
+
* `#6b6b78 is already --color-ink-500`. O scanner viu um hex, o sistema nomeia aquele valor, e a
|
|
319
|
+
* troca deixou `var(--color-ink-500) is already --color-ink-500` - uma tautologia, na frase que
|
|
320
|
+
* anuncia o que o produto faz. Não foi estilo mudado: foi CONTEÚDO.
|
|
321
|
+
*
|
|
322
|
+
* A LEI JÁ EXISTIA e esta é a borda dela - `fix` muda VALOR, nunca FORMA. Um literal em posição de
|
|
323
|
+
* conteúdo não é nem valor nem forma: é texto que uma pessoa lê.
|
|
324
|
+
*
|
|
325
|
+
* A REGIÃO É DERIVADA DA MARCAÇÃO, não de nome de arquivo: entre um `>` e o `<` seguinte está o que
|
|
326
|
+
* o elemento mostra. E dentro dela o literal ainda precisa estar CRU - `{x > 1 ? "#fff" : "#000"}`
|
|
327
|
+
* põe valores numa região que se parece com conteúdo, e as aspas são o que os separa de uma frase.
|
|
328
|
+
*
|
|
329
|
+
* UMA EXPRESSÃO NÃO É UMA FRASE, e esta borda custou um achado real. `<style>{`...`}</style>` é a
|
|
330
|
+
* folha que o app injeta de verdade: a cascata ALCANÇA, `var()` resolve, e o `120ms` escrito ali é
|
|
331
|
+
* deriva como qualquer outra. Medido em `apps/web/src/components/dashboard/live-specimen.tsx`, o
|
|
332
|
+
* guard sem esta borda derrubava 24 achados para 23. O sinal é da linguagem: uma chave logo depois
|
|
333
|
+
* do `>` abre uma expressão JSX, e o que vem dentro dela é código.
|
|
334
|
+
*
|
|
335
|
+
* `<style>html,body{...}</style>` DENTRO DE UMA STRING continua sendo conteúdo - lá a chave não
|
|
336
|
+
* encosta no `>`, e o documento é outro (um `srcdoc` de iframe, medido no `frontend-hub`), onde a
|
|
337
|
+
* folha do app também não chega.
|
|
338
|
+
*
|
|
339
|
+
* MEDIDO em 05/09, em 4 escopos: `codelevel-monorepo` 1 (a frase da landing) · `frontend-hub/apps/
|
|
340
|
+
* web-dashboard` 1 (o CSS do iframe) · `synthesisui-hub/apps/web` 14, entre elas a nossa PRÓPRIA
|
|
341
|
+
* demonstração na home, `<Line tone="ok">#2563eb -> --ds-color-semantic-info</Line>` · `frontend-
|
|
342
|
+
* hub/packages/ui` 0. O preço de errar é o produto reescrevendo a página de vendas de quem o
|
|
343
|
+
* instalou - inclusive a nossa.
|
|
344
|
+
*/
|
|
345
|
+
function contentSpans(line) {
|
|
346
|
+
const out = [];
|
|
347
|
+
let open = line.indexOf(">");
|
|
348
|
+
while (open !== -1) {
|
|
349
|
+
const close = line.indexOf("<", open + 1);
|
|
350
|
+
if (close === -1)
|
|
351
|
+
break;
|
|
352
|
+
if (close > open + 1 && line[open + 1] !== "{")
|
|
353
|
+
out.push([open + 1, close]);
|
|
354
|
+
open = line.indexOf(">", close + 1);
|
|
355
|
+
}
|
|
356
|
+
return out;
|
|
357
|
+
}
|
|
358
|
+
/** Um valor entre aspas é um valor, mesmo numa região de conteúdo. */
|
|
359
|
+
function quotedAt(line, col, len) {
|
|
360
|
+
const q = /["'`]/;
|
|
361
|
+
return q.test(line[col - 1] ?? "") || q.test(line[col + len] ?? "");
|
|
362
|
+
}
|
|
272
363
|
/**
|
|
273
364
|
* The line that DEFINES a token is not a line that drifted from it.
|
|
274
365
|
*
|
|
@@ -403,6 +494,12 @@ function scanCore(file, source, table) {
|
|
|
403
494
|
// shadow) is one decision, so it is reported once.
|
|
404
495
|
const spans = fallbackSpans(line, table);
|
|
405
496
|
const inFallback = (at) => spans.some(([a, b]) => at >= a && at <= b);
|
|
497
|
+
/** Ver `markupTextSpans`: HTML montado como texto sai do alcance da folha do app. */
|
|
498
|
+
const markup = markupTextSpans(file, line);
|
|
499
|
+
const inMarkup = (at) => markup.some(([a, b]) => at >= a && at <= b);
|
|
500
|
+
/** Ver `contentSpans`: entre `>` e `<` está o que o elemento MOSTRA. */
|
|
501
|
+
const content = contentSpans(line);
|
|
502
|
+
const inContent = (at) => content.some(([a, b]) => at >= a && at <= b);
|
|
406
503
|
const seen = new Set();
|
|
407
504
|
// NOT named `at`: that is the line number in this scope, and shadowing it
|
|
408
505
|
// put column positions into the report as line numbers.
|
|
@@ -413,6 +510,14 @@ function scanCore(file, source, table) {
|
|
|
413
510
|
setAside("a token's own fallback");
|
|
414
511
|
return;
|
|
415
512
|
}
|
|
513
|
+
if (col >= 0 && inMarkup(col)) {
|
|
514
|
+
setAside("markup assembled as text, where the app's variables do not reach");
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
if (col >= 0 && inContent(col) && !quotedAt(line, col, literal.length)) {
|
|
518
|
+
setAside("text the page shows, not a value it paints");
|
|
519
|
+
return;
|
|
520
|
+
}
|
|
416
521
|
const key = `${kind}:${literal}`;
|
|
417
522
|
if (seen.has(key))
|
|
418
523
|
return;
|
|
@@ -475,7 +580,14 @@ function scanCore(file, source, table) {
|
|
|
475
580
|
// A stack already reading from the system is the point, not a problem.
|
|
476
581
|
if (stack.startsWith("var("))
|
|
477
582
|
continue;
|
|
478
|
-
|
|
583
|
+
/**
|
|
584
|
+
* A COLUNA VIAJA AQUI TAMBÉM - sem ela os guards por posição são cegos para uma família.
|
|
585
|
+
*
|
|
586
|
+
* `font` era o único `push` sem coluna, então um `font-family` dentro de um `style="..."` de
|
|
587
|
+
* e-mail passava pelos dois guards novos e pelo de fallback. Um valor não deixa de estar fora
|
|
588
|
+
* do alcance da folha por ser uma pilha de fontes.
|
|
589
|
+
*/
|
|
590
|
+
push("font", stack, (m.index ?? 0) + m[0].indexOf(stack));
|
|
479
591
|
}
|
|
480
592
|
for (const m of line.matchAll(MOTION_PROP)) {
|
|
481
593
|
const value = m[1];
|
package/dist/install-marks.js
CHANGED
|
@@ -242,7 +242,15 @@ export const MATERIALISER_SINCE = "0.16.370";
|
|
|
242
242
|
* `line 12 oklch(...) -> --color-mint-500`. Um hook pinado antes desta versão aconselha OUTRA
|
|
243
243
|
* coisa - nada -, que é a régua desta marca.
|
|
244
244
|
*/
|
|
245
|
-
|
|
245
|
+
/**
|
|
246
|
+
* 0.16.367 -> 0.16.378 em 05/09: o hook parava de cobrar onde o conselho DESTRÓI. Ele lê `scanSource`
|
|
247
|
+
* direto, então um hook pinado antes olha `style="background:#6366f1"` dentro do e-mail de login que
|
|
248
|
+
* o app monta como texto e manda escrever `var(--color-brand-indigo)` - no cliente de e-mail a
|
|
249
|
+
* custom property não resolve, a declaração fica inválida e o botão "Sign in" perde o fundo. E olha
|
|
250
|
+
* `#6b6b78 is already --color-ink-500` numa frase da landing e manda tokenizar TEXTO. Um hook
|
|
251
|
+
* pinado antes desta versão aconselha OUTRA coisa, que é a régua desta marca.
|
|
252
|
+
*/
|
|
253
|
+
export const CHECKER_SINCE = "0.16.378";
|
|
246
254
|
/**
|
|
247
255
|
* A ÚLTIMA VERSÃO EM QUE OS LEITORES PASSARAM A PRODUZIR UM CENSO DIFERENTE.
|
|
248
256
|
*
|
|
@@ -665,7 +673,14 @@ export const CHECKER_SINCE = "0.16.367";
|
|
|
665
673
|
* `codelevel-ui` e 23 no `frontend-hub`, e ZERO no `observed` das três populações. Um censo tirado
|
|
666
674
|
* antes disto não tem aqueles valores na régua, e só um `sync` os traz.
|
|
667
675
|
*/
|
|
668
|
-
|
|
676
|
+
/**
|
|
677
|
+
* 0.16.367 -> 0.16.378 em 05/09: o censo produzido MUDA. O `import` roda `scanSource` sobre cada
|
|
678
|
+
* arquivo e passa os relatórios por `diagnose`, então duas formas que nunca foram valor de design
|
|
679
|
+
* saem do `observed`: marcação montada como texto (o e-mail, o sanitizador de editor) e literal em
|
|
680
|
+
* posição de conteúdo. Um censo medido antes desta versão conta como deriva o que a folha do app
|
|
681
|
+
* nem alcança - e o número do cliente é a promessa.
|
|
682
|
+
*/
|
|
683
|
+
export const READER_SINCE = "0.16.378";
|
|
669
684
|
/**
|
|
670
685
|
* O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
|
|
671
686
|
*
|
package/package.json
CHANGED