synthesisui 0.16.293 → 0.16.294
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/component.js +41 -7
- package/dist/index.js +8 -0
- package/package.json +1 -1
|
@@ -34,6 +34,22 @@ async function writeCn(root, compDir, slug) {
|
|
|
34
34
|
/** Slugs/names are kebab-case by contract; reject anything else before it ever
|
|
35
35
|
* reaches a filesystem path (defense-in-depth against `../` traversal). */
|
|
36
36
|
const SAFE_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
37
|
+
/**
|
|
38
|
+
* O NOME QUE O ARQUIVO VAI TER - o do blueprint, ou o que ele pediu.
|
|
39
|
+
*
|
|
40
|
+
* Puro e exportado porque é a decisão, e ela precisa ser provada sem rede nem disco. O nome vem da
|
|
41
|
+
* linha de comando e termina dentro de um `join`, então a validação é defesa em profundidade e não
|
|
42
|
+
* capricho: `--as ../escape` não pode chegar ao sistema de arquivos.
|
|
43
|
+
*/
|
|
44
|
+
export function localName(blueprint, asked) {
|
|
45
|
+
const wanted = asked?.trim();
|
|
46
|
+
if (!wanted)
|
|
47
|
+
return blueprint;
|
|
48
|
+
if (!SAFE_NAME.test(wanted)) {
|
|
49
|
+
throw new RegistryError(`Invalid --as "${wanted}" - use kebab-case, like \`--as my-${blueprint}\`.`);
|
|
50
|
+
}
|
|
51
|
+
return wanted;
|
|
52
|
+
}
|
|
37
53
|
/**
|
|
38
54
|
* Brings ONE component from a design system into the project (granular "bring
|
|
39
55
|
* specific", INS-18 fatia 3):
|
|
@@ -172,7 +188,15 @@ export async function component(slug, name, opts) {
|
|
|
172
188
|
console.log(body("Nothing of yours was touched. Which name it takes is your call, not ours."));
|
|
173
189
|
return;
|
|
174
190
|
}
|
|
175
|
-
|
|
191
|
+
/**
|
|
192
|
+
* O NOME QUE O ARQUIVO VAI TER - ver `localName`.
|
|
193
|
+
*
|
|
194
|
+
* `--as` é o que permite ele VER o que um blueprint produz num repositório que já tem o
|
|
195
|
+
* componente. O CSS não muda de nome: a receita é a do blueprint, e as classes dela são
|
|
196
|
+
* `.ds-<blueprint>` - o componente novo veste o mesmo desenho, com o nome dele no arquivo.
|
|
197
|
+
*/
|
|
198
|
+
const local = localName(res.name, opts.as);
|
|
199
|
+
const compDir = join(root, config.componentsDir, local);
|
|
176
200
|
await mkdir(compDir, { recursive: true });
|
|
177
201
|
let filenames;
|
|
178
202
|
if (wantInteractive) {
|
|
@@ -180,10 +204,10 @@ export async function component(slug, name, opts) {
|
|
|
180
204
|
// it wears (.css) + the barrel. Ignores the css|tailwind flavor - the
|
|
181
205
|
// template drives itself off the .ds-* classes.
|
|
182
206
|
const tsx = interactiveTemplate(res.name);
|
|
183
|
-
await writeFile(join(compDir, `${
|
|
184
|
-
await writeFile(join(compDir, `${
|
|
185
|
-
await writeFile(join(compDir, "index.ts"), `export * from "./${
|
|
186
|
-
filenames = [`${
|
|
207
|
+
await writeFile(join(compDir, `${local}.tsx`), tsx, "utf8");
|
|
208
|
+
await writeFile(join(compDir, `${local}.css`), `${css}\n`, "utf8");
|
|
209
|
+
await writeFile(join(compDir, "index.ts"), `export * from "./${local}";\n`, "utf8");
|
|
210
|
+
filenames = [`${local}.tsx`, `${local}.css`, "index.ts"];
|
|
187
211
|
}
|
|
188
212
|
else {
|
|
189
213
|
const files = generateComponentFiles(slug, res.name, res.recipe, css, res.version, config.styles, await reactMajorOf(root),
|
|
@@ -195,7 +219,17 @@ export async function component(slug, name, opts) {
|
|
|
195
219
|
* it, so the TSX and the stylesheet in the same folder agree by
|
|
196
220
|
* construction. Falling back to disk keeps an older registry working.
|
|
197
221
|
*/
|
|
198
|
-
res.classNames ?? (await readInstalledConvention(root, slug)),
|
|
222
|
+
res.classNames ?? (await readInstalledConvention(root, slug)),
|
|
223
|
+
/**
|
|
224
|
+
* O NOME LOCAL, e o codegen já sabia fazer isto - ver `localName` em
|
|
225
|
+
* `component-codegen.ts`: *"A project that already exports `Button` should not have to give
|
|
226
|
+
* the name up to install ours"*. A capacidade existia e nenhuma flag a alcançava, então a
|
|
227
|
+
* recusa oferecia `--as` e o comando ignorava.
|
|
228
|
+
*
|
|
229
|
+
* O ARQUIVO e o EXPORT levam o nome dele; a CLASSE continua sendo a do blueprint. Um
|
|
230
|
+
* `<CardPreview>` vestindo `.ds-card` está estilizado certo e não faz sombra em nada dele.
|
|
231
|
+
*/
|
|
232
|
+
local, await readInstalledScheme(root, slug));
|
|
199
233
|
/**
|
|
200
234
|
* AS DECLARAÇÕES DO ARQUIVO DELE QUE O INTERPRETADOR NÃO LEU - ver `unread-for-component.ts`.
|
|
201
235
|
*
|
|
@@ -217,7 +251,7 @@ export async function component(slug, name, opts) {
|
|
|
217
251
|
filenames = files.map((f) => f.filename);
|
|
218
252
|
}
|
|
219
253
|
const flavor = wantInteractive ? "interactive" : `styles: ${config.styles}`;
|
|
220
|
-
console.log(`✓ ${config.componentsDir}/${
|
|
254
|
+
console.log(`✓ ${config.componentsDir}/${local}/ → ${filenames.join(", ")} (${flavor})${local === res.name ? "" : ` - the "${res.name}" blueprint, under your name`}`);
|
|
221
255
|
}
|
|
222
256
|
else if (opts.interactive && !hasInteractiveTemplate(res.name)) {
|
|
223
257
|
console.log(` note: no interactive template for "${res.name}" - materialized the standard shell.`);
|
package/dist/index.js
CHANGED
|
@@ -522,6 +522,14 @@ async function main() {
|
|
|
522
522
|
version,
|
|
523
523
|
artifactsOnly: flags["artifacts-only"] === true,
|
|
524
524
|
interactive: flags.interactive === true,
|
|
525
|
+
/**
|
|
526
|
+
* O NOME LOCAL - ver `localName` em `component.ts`.
|
|
527
|
+
*
|
|
528
|
+
* A recusa por nome ocupado já oferecia `--as`, e a flag não era lida: quem seguia a
|
|
529
|
+
* instrução da tela recebia o arquivo com o nome de sempre.
|
|
530
|
+
*/
|
|
531
|
+
...(typeof flags.as === "string" ? { as: flags.as } : {}),
|
|
532
|
+
...(flags.force === true ? { force: true } : {}),
|
|
525
533
|
});
|
|
526
534
|
break;
|
|
527
535
|
}
|
package/package.json
CHANGED