synthesisui 0.16.306 → 0.16.308
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/import.js +92 -2
- package/dist/doctor/components-scan.js +40 -19
- package/dist/doctor/export-census.js +111 -0
- package/dist/doctor/form-identity.js +75 -0
- package/dist/doctor/framework-palette.js +569 -0
- package/dist/doctor/style-ledger.js +27 -1
- package/dist/doctor/transcribe.js +24 -29
- package/dist/doctor/value-ledger.js +153 -0
- package/dist/doctor/variant-read.js +13 -1
- package/dist/install-marks.js +32 -2
- package/dist/workspace-css.js +84 -0
- package/package.json +1 -1
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
* data-[checked]:bg-ocean-50 → states.checked
|
|
44
44
|
*/
|
|
45
45
|
import { tokenRefFor } from "../token-ref.js";
|
|
46
|
+
import { frameworkDeclaration } from "./framework-palette.js";
|
|
46
47
|
/**
|
|
47
48
|
* Utility prefix → the property name THE DOCUMENT USES, which is camelCase.
|
|
48
49
|
*
|
|
@@ -291,33 +292,12 @@ const TAILWIND_COLOR = {
|
|
|
291
292
|
*/
|
|
292
293
|
current: "currentColor",
|
|
293
294
|
inherit: "inherit",
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
"zinc-400": "#a1a1aa",
|
|
301
|
-
"zinc-500": "#71717a",
|
|
302
|
-
"zinc-600": "#52525b",
|
|
303
|
-
"zinc-700": "#3f3f46",
|
|
304
|
-
"zinc-800": "#27272a",
|
|
305
|
-
"zinc-900": "#18181b",
|
|
306
|
-
"zinc-950": "#09090b",
|
|
307
|
-
"blue-400": "#60a5fa",
|
|
308
|
-
"blue-500": "#3b82f6",
|
|
309
|
-
"blue-600": "#2563eb",
|
|
310
|
-
"neutral-50": "#fafafa",
|
|
311
|
-
"neutral-100": "#f5f5f5",
|
|
312
|
-
"neutral-200": "#e5e5e5",
|
|
313
|
-
"neutral-300": "#d4d4d4",
|
|
314
|
-
"neutral-400": "#a3a3a3",
|
|
315
|
-
"neutral-500": "#737373",
|
|
316
|
-
"neutral-600": "#525252",
|
|
317
|
-
"neutral-700": "#404040",
|
|
318
|
-
"neutral-800": "#262626",
|
|
319
|
-
"neutral-900": "#171717",
|
|
320
|
-
"neutral-950": "#0a0a0a",
|
|
295
|
+
/**
|
|
296
|
+
* A PALETA saiu daqui em 25/08: zinc, blue e neutral (as entradas do test14) moravam nesta
|
|
297
|
+
* tabela com os hex da v3, cravados - e um projeto v4 recebia o hex antigo. A paleta inteira
|
|
298
|
+
* mora em `framework-palette.ts`, por versão maior e com o carimbo `from` que o D1 exige;
|
|
299
|
+
* aqui ficam só os KEYWORDS de CSS, que não são paleta e não têm versão.
|
|
300
|
+
*/
|
|
321
301
|
};
|
|
322
302
|
/**
|
|
323
303
|
* TYPOGRAPHY, and the reason it is here at all.
|
|
@@ -649,8 +629,12 @@ export function parseClass(cls) {
|
|
|
649
629
|
* `declared` maps a token NAME to its value, so a resolved colour can be
|
|
650
630
|
* reported in their vocabulary rather than as a hex we looked up.
|
|
651
631
|
*/
|
|
652
|
-
/**
|
|
653
|
-
|
|
632
|
+
/**
|
|
633
|
+
* A hex, a ref into their colour scale, OR a colour function - the shapes an alpha can wrap.
|
|
634
|
+
* As funções entraram com a paleta versionada (item 18): a v4 publica oklch, e sem elas
|
|
635
|
+
* `bg-emerald-500/10` resolvia a cor e PERDIA o alfa em silêncio - o scrim virava parede.
|
|
636
|
+
*/
|
|
637
|
+
const COLOUR_VALUE = /^(#[0-9a-f]{3,8}|\{color\.[^}]+\}|(?:oklch|oklab|rgba?|hsla?|lab|lch)\([^)]*\))$/i;
|
|
654
638
|
/**
|
|
655
639
|
* `#ffffff` + `50` → `color-mix(in srgb, #ffffff 50%, transparent)`.
|
|
656
640
|
*
|
|
@@ -922,6 +906,17 @@ function readUtilityCore(utility, declared) {
|
|
|
922
906
|
if (declared.has(own)) {
|
|
923
907
|
return { property: colorProp, value: refFor(rest), token: own };
|
|
924
908
|
}
|
|
909
|
+
/**
|
|
910
|
+
* A PALETA PUBLICADA DO FRAMEWORK, por versão maior e COM carimbo (item 18 + D1).
|
|
911
|
+
*
|
|
912
|
+
* Depois do token dele (o vocabulário dele sempre vence) e antes da tabela de keywords:
|
|
913
|
+
* `text-rose-700` é decisão dele sobre um valor que o Tailwind publica, e morria em silêncio
|
|
914
|
+
* - 127 valores no diagnóstico de 25/08. O `from: "framework"` é o que separa isto de
|
|
915
|
+
* inventar: a métrica sabe que não é vocabulário DELE e o self-healing pode perguntar.
|
|
916
|
+
*/
|
|
917
|
+
const published = frameworkDeclaration(colorProp, rest);
|
|
918
|
+
if (published)
|
|
919
|
+
return published;
|
|
925
920
|
const builtin = TAILWIND_COLOR[rest];
|
|
926
921
|
if (builtin)
|
|
927
922
|
return { property: colorProp, value: builtin };
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { parseClass, readUtility } from "./transcribe.js";
|
|
2
|
+
/**
|
|
3
|
+
* AS PROPRIEDADES QUE SÃO ARRANJO - a definição de "estrutura", por propriedade resolvida.
|
|
4
|
+
*
|
|
5
|
+
* O critério do dono (D4): estrutura é onde "token é impossível por definição" - não existe
|
|
6
|
+
* decisão de vocabulário em `display: flex`. Espaçamento e tamanho NÃO entram: `gap`, `padding`
|
|
7
|
+
* e `height` são decisões de escala (a métrica de Spacing & Proportion existe para elas).
|
|
8
|
+
*/
|
|
9
|
+
const STRUCTURAL_PROPERTIES = new Set([
|
|
10
|
+
"display",
|
|
11
|
+
"position",
|
|
12
|
+
"top",
|
|
13
|
+
"right",
|
|
14
|
+
"bottom",
|
|
15
|
+
"left",
|
|
16
|
+
"inset",
|
|
17
|
+
"insetInline",
|
|
18
|
+
"insetBlock",
|
|
19
|
+
"zIndex",
|
|
20
|
+
"overflow",
|
|
21
|
+
"overflowX",
|
|
22
|
+
"overflowY",
|
|
23
|
+
"flexDirection",
|
|
24
|
+
"flexWrap",
|
|
25
|
+
"alignItems",
|
|
26
|
+
"alignContent",
|
|
27
|
+
"alignSelf",
|
|
28
|
+
"justifyContent",
|
|
29
|
+
"justifyItems",
|
|
30
|
+
"justifySelf",
|
|
31
|
+
"placeItems",
|
|
32
|
+
"placeContent",
|
|
33
|
+
"order",
|
|
34
|
+
"flex",
|
|
35
|
+
"flexGrow",
|
|
36
|
+
"flexShrink",
|
|
37
|
+
"flexBasis",
|
|
38
|
+
"gridColumn",
|
|
39
|
+
"gridRow",
|
|
40
|
+
"gridTemplateColumns",
|
|
41
|
+
"gridTemplateRows",
|
|
42
|
+
"pointerEvents",
|
|
43
|
+
"userSelect",
|
|
44
|
+
"textAlign",
|
|
45
|
+
"verticalAlign",
|
|
46
|
+
"whiteSpace",
|
|
47
|
+
"objectFit",
|
|
48
|
+
"objectPosition",
|
|
49
|
+
"visibility",
|
|
50
|
+
"isolation",
|
|
51
|
+
"textOverflow",
|
|
52
|
+
"borderCollapse",
|
|
53
|
+
]);
|
|
54
|
+
/**
|
|
55
|
+
* TOKENS DE ARRANJO QUE O RESOLVEDOR NÃO DEVOLVE COMO DECLARAÇÃO - a metade utilitária da mesma
|
|
56
|
+
* definição. `w-full` e `truncate` não são decisão de vocabulário; `hidden` e `sr-only` são
|
|
57
|
+
* visibilidade. Lista CONSERVADORA de propósito: o que não estiver aqui e não resolver cai em
|
|
58
|
+
* `unread`, que é o lado certo de errar - um arranjo cobrado como lacuna custa uma linha; uma
|
|
59
|
+
* decisão de estilo escondida como "estrutura" custa a confiança na métrica.
|
|
60
|
+
*/
|
|
61
|
+
const STRUCTURAL_TOKENS = new Set([
|
|
62
|
+
/** Os valores de display crus - a mesma lista que o juiz de fragmento chama de STRUCTURE. */
|
|
63
|
+
"flex",
|
|
64
|
+
"inline-flex",
|
|
65
|
+
"grid",
|
|
66
|
+
"inline-grid",
|
|
67
|
+
"block",
|
|
68
|
+
"inline-block",
|
|
69
|
+
"inline",
|
|
70
|
+
"contents",
|
|
71
|
+
"flow-root",
|
|
72
|
+
"flex-row",
|
|
73
|
+
"flex-col",
|
|
74
|
+
"flex-row-reverse",
|
|
75
|
+
"flex-col-reverse",
|
|
76
|
+
"w-full",
|
|
77
|
+
"h-full",
|
|
78
|
+
"w-fit",
|
|
79
|
+
"h-fit",
|
|
80
|
+
"w-max",
|
|
81
|
+
"w-min",
|
|
82
|
+
"min-w-0",
|
|
83
|
+
"shrink",
|
|
84
|
+
"shrink-0",
|
|
85
|
+
"grow",
|
|
86
|
+
"grow-0",
|
|
87
|
+
"flex-1",
|
|
88
|
+
"flex-auto",
|
|
89
|
+
"flex-none",
|
|
90
|
+
"hidden",
|
|
91
|
+
"sr-only",
|
|
92
|
+
"not-sr-only",
|
|
93
|
+
"truncate",
|
|
94
|
+
"group",
|
|
95
|
+
"peer",
|
|
96
|
+
"isolate",
|
|
97
|
+
]);
|
|
98
|
+
/**
|
|
99
|
+
* O destino de UM token de classe. Exportado para o julgamento por valor e a triagem lerem a
|
|
100
|
+
* MESMA resposta - duas cópias desta decisão é como o item 11 nasceu.
|
|
101
|
+
*/
|
|
102
|
+
export function destinationOf(cls, declared) {
|
|
103
|
+
const { utility } = parseClass(cls);
|
|
104
|
+
if (STRUCTURAL_TOKENS.has(utility))
|
|
105
|
+
return "structure";
|
|
106
|
+
const read = readUtility(utility, declared);
|
|
107
|
+
if (read) {
|
|
108
|
+
return STRUCTURAL_PROPERTIES.has(read.property)
|
|
109
|
+
? "structure"
|
|
110
|
+
: "interpreted";
|
|
111
|
+
}
|
|
112
|
+
return "unread";
|
|
113
|
+
}
|
|
114
|
+
/** A conta de uma lista de tokens - a soma SEMPRE fecha com `seen`, por construção. */
|
|
115
|
+
export function accountClasses(tokens, declared) {
|
|
116
|
+
const account = {
|
|
117
|
+
seen: 0,
|
|
118
|
+
interpreted: 0,
|
|
119
|
+
structure: 0,
|
|
120
|
+
unread: 0,
|
|
121
|
+
answered: 0,
|
|
122
|
+
unknown: 0,
|
|
123
|
+
};
|
|
124
|
+
for (const cls of tokens) {
|
|
125
|
+
account.seen += 1;
|
|
126
|
+
account[destinationOf(cls, declared)] += 1;
|
|
127
|
+
}
|
|
128
|
+
return account;
|
|
129
|
+
}
|
|
130
|
+
/** Soma de contas - o total do censo é a soma das contas por componente, nunca outra medição. */
|
|
131
|
+
export function sumAccounts(accounts) {
|
|
132
|
+
const out = {
|
|
133
|
+
seen: 0,
|
|
134
|
+
interpreted: 0,
|
|
135
|
+
structure: 0,
|
|
136
|
+
unread: 0,
|
|
137
|
+
answered: 0,
|
|
138
|
+
unknown: 0,
|
|
139
|
+
};
|
|
140
|
+
for (const a of accounts) {
|
|
141
|
+
out.seen += a.seen;
|
|
142
|
+
out.interpreted += a.interpreted;
|
|
143
|
+
out.structure += a.structure;
|
|
144
|
+
out.unread += a.unread;
|
|
145
|
+
out.answered += a.answered;
|
|
146
|
+
out.unknown += a.unknown;
|
|
147
|
+
}
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
/** A invariante do item 11, como pergunta - o spec das populações a assere, o portão a exige. */
|
|
151
|
+
export function invariantHolds(a) {
|
|
152
|
+
return (a.interpreted + a.structure + a.unread + a.answered + a.unknown === a.seen);
|
|
153
|
+
}
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* position in `layers`. They agree only if the reader inserts in the order it read.
|
|
32
32
|
*/
|
|
33
33
|
import { wearGlobal, withGlobal } from "../global-wear.js";
|
|
34
|
-
import { parseClass, transcribe } from "./transcribe.js";
|
|
34
|
+
import { parseClass, readUtility, transcribe, } from "./transcribe.js";
|
|
35
35
|
/**
|
|
36
36
|
* A Tailwind modifier, mapped to the condition it IS.
|
|
37
37
|
*
|
|
@@ -1272,11 +1272,23 @@ globals) {
|
|
|
1272
1272
|
...t.base,
|
|
1273
1273
|
...t.dark,
|
|
1274
1274
|
};
|
|
1275
|
+
/**
|
|
1276
|
+
* O HÍBRIDO DO D1, no nível da camada: `classes` é a grafia DELE, verbatim (a metade de
|
|
1277
|
+
* fidelidade - o codegen devolve o que ele escreveu); `from: "framework"` quando TODA
|
|
1278
|
+
* declaração resolvida veio da paleta publicada - numa camada mista o vocabulário dele
|
|
1279
|
+
* domina e o carimbo fica ausente, que é o caminho de sempre. Ver `framework-palette.ts`.
|
|
1280
|
+
*/
|
|
1281
|
+
const reads = bare
|
|
1282
|
+
.map((utility) => readUtility(utility, declared))
|
|
1283
|
+
.filter((d) => d != null);
|
|
1284
|
+
const fromFramework = reads.length > 0 && reads.every((d) => d.from === "framework");
|
|
1275
1285
|
return {
|
|
1276
1286
|
...(layer.when ? { when: layer.when } : {}),
|
|
1277
1287
|
...(layer.at ? { at: layer.at } : {}),
|
|
1278
1288
|
...(layer.onClasses ? { onClasses: layer.onClasses } : {}),
|
|
1279
1289
|
style,
|
|
1290
|
+
classes: layer.classes,
|
|
1291
|
+
...(fromFramework ? { from: "framework" } : {}),
|
|
1280
1292
|
};
|
|
1281
1293
|
})
|
|
1282
1294
|
.filter((layer) => Object.keys(layer.style).length > 0);
|
package/dist/install-marks.js
CHANGED
|
@@ -196,7 +196,13 @@ export const MATERIALISER_SINCE = "0.16.306";
|
|
|
196
196
|
* `var(--text-caption)` - um token de tipo numa posição de raio. Medido no repositório real: 290
|
|
197
197
|
* sugestões com a categoria trocada, 66 delas graváveis por um `--fix --write`.
|
|
198
198
|
*/
|
|
199
|
-
|
|
199
|
+
/**
|
|
200
|
+
* 0.16.250 -> 0.16.308 em 25/08: o julgamento que o hook roda passa pela paleta versionada do
|
|
201
|
+
* framework (item 18). Um hook pinado antes lê o mesmo arquivo com `text-rose-700` e conta
|
|
202
|
+
* "não lido" sobre um valor que o de hoje resolve - e o número é o que a pessoa lê para decidir
|
|
203
|
+
* se adotou. O `!` de important (0.16.306) já tinha mudado a mesma contagem.
|
|
204
|
+
*/
|
|
205
|
+
export const CHECKER_SINCE = "0.16.308";
|
|
200
206
|
/**
|
|
201
207
|
* A ÚLTIMA VERSÃO EM QUE OS LEITORES PASSARAM A PRODUZIR UM CENSO DIFERENTE.
|
|
202
208
|
*
|
|
@@ -288,7 +294,31 @@ export const CHECKER_SINCE = "0.16.250";
|
|
|
288
294
|
*
|
|
289
295
|
* Um censo medido antes carrega a poluição e a perda; quem remede ganha os três de uma vez.
|
|
290
296
|
*/
|
|
291
|
-
|
|
297
|
+
/**
|
|
298
|
+
* 0.16.306 -> 0.16.307 em 25/08: o censo passa a carregar `values` - a CONTABILIDADE POR VALOR
|
|
299
|
+
* (item 11). Todo token de classe que veste um componente admitido tem um destino, e a soma fecha
|
|
300
|
+
* por construção: `interpreted + structure + unread + answered + unknown == seen`. É a
|
|
301
|
+
* reconciliação entre o ledger (que conta lugares) e a produção (que trabalha em valores) - 86%
|
|
302
|
+
* contra 50% no mesmo repositório, sem uma linha ligando os dois.
|
|
303
|
+
*
|
|
304
|
+
* Campo novo: um censo medido antes não o tem, e a tela de cobertura (D4: três colunas, estrutura
|
|
305
|
+
* visível fora da métrica) só pode ser honesta sobre quem remedir. É o que esta marca avisa.
|
|
306
|
+
*/
|
|
307
|
+
/**
|
|
308
|
+
* 0.16.307 -> 0.16.308 em 25/08 (mvp-1128), o lote 1 fechado + o começo do lote 2:
|
|
309
|
+
*
|
|
310
|
+
* item 13 o censo carrega `exports` - o denominador antes do portão, com o resíduo em linhas
|
|
311
|
+
* item 12 cada grupo não lido carrega `forms` - a unidade da pergunta de self-healing
|
|
312
|
+
* item 17 a camada vira o híbrido do D1: `classes` verbatim + `from` de procedência
|
|
313
|
+
* item 18 a paleta publicada do framework resolve por versão maior (v4 oklch, v3 hex), com
|
|
314
|
+
* carimbo - 127 valores (21%) deixam de morrer em silêncio
|
|
315
|
+
* item 19 o vocabulário do pacote workspace IMPORTADO pelo escopo entra na colheita (genérico,
|
|
316
|
+
* nunca node_modules; o escopo vence) - medido no repo real: @frontend-hub/ui doa 94
|
|
317
|
+
* variáveis, e os 223 valores (37%) que as vestiam passam a resolver como token DELE
|
|
318
|
+
*
|
|
319
|
+
* Um censo medido antes não tem nada disso; quem remede ganha os cinco.
|
|
320
|
+
*/
|
|
321
|
+
export const READER_SINCE = "0.16.308";
|
|
292
322
|
/**
|
|
293
323
|
* O QUE ESTÁ INSTALADO AQUI FICOU PARA TRÁS - e as DUAS condições que fazem isso ser verdade.
|
|
294
324
|
*
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { sep } from "node:path";
|
|
3
|
+
import { walkAll } from "./commands/doctor.js";
|
|
4
|
+
import { workspacePackages } from "./doctor/components-scan.js";
|
|
5
|
+
/**
|
|
6
|
+
* O VOCABULÁRIO QUE MORA NO PACOTE AO LADO (item 19, 25/08).
|
|
7
|
+
*
|
|
8
|
+
* A regra do Tailwind v4: só `--color-*` cria utilitário de cor. Num monorepo, essas variáveis
|
|
9
|
+
* costumam morar no PACOTE de design system - e quando o escopo medido é o app, a colheita de CSS
|
|
10
|
+
* só via a pasta apontada: o app do repositório real veste `border-lightgray-200` 213 vezes, e o
|
|
11
|
+
* `--color-lightgray-200` que cria esse utilitário mora em `packages/ui/src/styles.css`, um pacote
|
|
12
|
+
* ao lado. Resultado medido: 223 valores (37% do não-lido) morriam com o nome declarado a vinte
|
|
13
|
+
* linhas de distância do alcance do leitor.
|
|
14
|
+
*
|
|
15
|
+
* A regra é GENÉRICA por decisão do dono (25/08): qualquer pacote de WORKSPACE que o escopo
|
|
16
|
+
* importa - nunca um nome cravado, e nunca `node_modules`: o CSS de terceiro de verdade continua
|
|
17
|
+
* fora e declarado (população zero medida até hoje; quando aparecer, mede-se lá).
|
|
18
|
+
*
|
|
19
|
+
* O ESCOPO DELE SEMPRE VENCE: uma variável declarada na pasta medida nunca é sobrescrita por uma
|
|
20
|
+
* do pacote irmão - quem está mais perto do componente é a decisão mais específica.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* `from "@acme/ui"` · `import("@acme/ui/x")` · `require("@acme/ui")` · `import "@acme/ui/css"` -
|
|
24
|
+
* o último é o side-effect import, e é EXATAMENTE como uma folha de tokens entra num app.
|
|
25
|
+
*/
|
|
26
|
+
const SPECIFIER = /(?:from\s*|import\s*\(?\s*|require\s*\(\s*)["']([^"'./][^"']*)["']/g;
|
|
27
|
+
const CUSTOM_PROPERTY = /(--[a-zA-Z0-9_-]+)\s*:\s*([^;}]+)/g;
|
|
28
|
+
const SKIP_DIR = /(^|[/\\])(node_modules|dist|build|\.next|\.git|coverage)([/\\]|$)/;
|
|
29
|
+
/**
|
|
30
|
+
* Colhe as custom properties dos pacotes workspace que o ESCOPO importa.
|
|
31
|
+
*
|
|
32
|
+
* O pré-passe de especificadores relê os fontes do escopo (o laço de componentes só roda DEPOIS,
|
|
33
|
+
* e é ele que consome o `declared` que esta colheita completa) - custo medido em IO de leitura
|
|
34
|
+
* pura, centenas de ms num monorepo de mil arquivos, pago uma vez por medição.
|
|
35
|
+
*/
|
|
36
|
+
export async function harvestWorkspaceCss(scopedRoot,
|
|
37
|
+
/** Nomes já declarados pelo escopo - a trava de "o escopo dele sempre vence". */
|
|
38
|
+
scopeDeclares) {
|
|
39
|
+
const imported = new Set();
|
|
40
|
+
for await (const file of walkAll([scopedRoot])) {
|
|
41
|
+
if (!/\.(tsx|jsx|ts|mjs|cjs|vue|svelte)$/i.test(file))
|
|
42
|
+
continue;
|
|
43
|
+
if (SKIP_DIR.test(file))
|
|
44
|
+
continue;
|
|
45
|
+
const source = await readFile(file, "utf8").catch(() => "");
|
|
46
|
+
SPECIFIER.lastIndex = 0;
|
|
47
|
+
for (const m of source.matchAll(SPECIFIER))
|
|
48
|
+
imported.add(m[1]);
|
|
49
|
+
}
|
|
50
|
+
if (imported.size === 0)
|
|
51
|
+
return { packages: [], declared: new Map() };
|
|
52
|
+
const declared = new Map();
|
|
53
|
+
const packages = [];
|
|
54
|
+
for (const pkg of await workspacePackages(scopedRoot)) {
|
|
55
|
+
/**
|
|
56
|
+
* IMPORTADO PELO ESCOPO - `@acme/ui` cobre `@acme/ui/tokens`. E nunca a própria pasta
|
|
57
|
+
* medida: o CSS dela já foi colhido pelo laço de sempre, e re-colher criaria a disputa
|
|
58
|
+
* que a trava abaixo existe para impedir.
|
|
59
|
+
*/
|
|
60
|
+
const used = [...imported].some((s) => s === pkg.name || s.startsWith(`${pkg.name}/`));
|
|
61
|
+
if (!used)
|
|
62
|
+
continue;
|
|
63
|
+
if (scopedRoot === pkg.dir ||
|
|
64
|
+
scopedRoot.startsWith(pkg.dir + sep) ||
|
|
65
|
+
pkg.dir.startsWith(scopedRoot + sep))
|
|
66
|
+
continue;
|
|
67
|
+
let vars = 0;
|
|
68
|
+
for await (const file of walkAll([pkg.dir])) {
|
|
69
|
+
if (!/\.(css|scss|sass|less)$/i.test(file) || SKIP_DIR.test(file))
|
|
70
|
+
continue;
|
|
71
|
+
const body = await readFile(file, "utf8").catch(() => "");
|
|
72
|
+
CUSTOM_PROPERTY.lastIndex = 0;
|
|
73
|
+
for (const m of body.matchAll(CUSTOM_PROPERTY)) {
|
|
74
|
+
if (scopeDeclares(m[1]) || declared.has(m[1]))
|
|
75
|
+
continue;
|
|
76
|
+
declared.set(m[1], m[2].trim());
|
|
77
|
+
vars += 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (vars > 0)
|
|
81
|
+
packages.push({ name: pkg.name, vars });
|
|
82
|
+
}
|
|
83
|
+
return { packages, declared };
|
|
84
|
+
}
|
package/package.json
CHANGED