create-flow-os 0.0.47-dev.1772045775 → 0.0.47
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/package.json +2 -2
- package/src/init/index.ts +5 -4
- package/src/init/lib.ts +2 -22
- package/src/init/scaffold.ts +16 -164
- package/src/init/ui.ts +12 -16
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-flow-os",
|
|
3
|
-
"version": "0.0.47
|
|
3
|
+
"version": "0.0.47",
|
|
4
4
|
"license": "PolyForm-Shield-1.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@flow-os/client": "
|
|
7
|
+
"@flow-os/client": "^0.0.47"
|
|
8
8
|
},
|
|
9
9
|
"bin": {
|
|
10
10
|
"create-flow-os": "./src/index.ts"
|
package/src/init/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
+
// Clear subito per nascondere resolving/installing di Bun
|
|
3
|
+
process.stdout.write("\x1b[2J\x1b[H");
|
|
2
4
|
|
|
3
5
|
import * as readline from "readline";
|
|
4
6
|
import { join, dirname } from "path";
|
|
5
7
|
import { fileURLToPath } from "url";
|
|
6
8
|
import { libsWithConfig, toShortName, toPkgName } from "./lib";
|
|
7
|
-
import { initLib, fetchFlowPackageVersions
|
|
9
|
+
import { initLib, fetchFlowPackageVersions } from "./scaffold";
|
|
8
10
|
import { bannerBox, withLoading, colors } from "./ui";
|
|
9
11
|
|
|
10
12
|
const { V, V_LIGHT, Y, E, R, B } = colors;
|
|
@@ -14,8 +16,7 @@ const { V, V_LIGHT, Y, E, R, B } = colors;
|
|
|
14
16
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
15
17
|
const cwd = process.cwd();
|
|
16
18
|
const cliRoot = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
17
|
-
const
|
|
18
|
-
const available = libsWithConfig(cliRoot, flowOsRepoRoot).map(toShortName);
|
|
19
|
+
const available = libsWithConfig(cliRoot).map(toShortName);
|
|
19
20
|
|
|
20
21
|
let libs = [...new Set(process.argv.slice(3))];
|
|
21
22
|
|
|
@@ -42,7 +43,7 @@ if (!toInit.length) {
|
|
|
42
43
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
43
44
|
const pkgNames = toInit.map(toPkgName);
|
|
44
45
|
await withLoading(async (onStep) => {
|
|
45
|
-
const versions =
|
|
46
|
+
const versions = await fetchFlowPackageVersions(pkgNames);
|
|
46
47
|
await initLib(toInit, cwd, versions, onStep);
|
|
47
48
|
});
|
|
48
49
|
|
package/src/init/lib.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, readFileSync
|
|
1
|
+
import { existsSync, readFileSync } from "fs";
|
|
2
2
|
import { join, dirname } from "path";
|
|
3
3
|
import { fileURLToPath } from "url";
|
|
4
4
|
|
|
@@ -21,27 +21,7 @@ export function flowDeps(root: string): string[] {
|
|
|
21
21
|
return Object.keys(deps).filter((k) => k.startsWith(FLOW_PREFIX));
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
function scanPackagesDir(packagesDir: string): string[] {
|
|
26
|
-
const found: string[] = [];
|
|
27
|
-
try {
|
|
28
|
-
for (const name of readdirSync(packagesDir, { withFileTypes: true })) {
|
|
29
|
-
if (!name.isDirectory()) continue;
|
|
30
|
-
const pkgPath = join(packagesDir, name.name, "package.json");
|
|
31
|
-
if (!existsSync(pkgPath)) continue;
|
|
32
|
-
try {
|
|
33
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8")) as { name?: string };
|
|
34
|
-
if (pkg?.name?.startsWith(FLOW_PREFIX)) found.push(pkg.name);
|
|
35
|
-
} catch {}
|
|
36
|
-
}
|
|
37
|
-
} catch {}
|
|
38
|
-
return found;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function libsWithConfig(cliRoot: string, flowOsRepoRoot?: string | null): string[] {
|
|
42
|
-
const packagesDir = flowOsRepoRoot ? join(flowOsRepoRoot, "packages") : join(cliRoot, "..");
|
|
43
|
-
const fromScan = scanPackagesDir(packagesDir);
|
|
44
|
-
if (fromScan.length > 0) return fromScan;
|
|
24
|
+
export function libsWithConfig(cliRoot: string): string[] {
|
|
45
25
|
const pkg = JSON.parse(readFileSync(join(cliRoot, "package.json"), "utf-8"));
|
|
46
26
|
const deps = Object.keys(pkg.dependencies ?? {}).filter((k) => k.startsWith(FLOW_PREFIX));
|
|
47
27
|
return deps.filter((name) => existsSync(join(pkgRoot(name), "config")));
|
package/src/init/scaffold.ts
CHANGED
|
@@ -79,29 +79,6 @@ function isCreateFlowOsDev(): boolean {
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
/** Trova la root del repo flow-os salendo da cwd (contiene packages/client) */
|
|
83
|
-
export function findFlowOsRepoRoot(cwd: string): string | null {
|
|
84
|
-
let d = cwd;
|
|
85
|
-
while (true) {
|
|
86
|
-
const pkgClient = join(d, "packages", "client", "package.json");
|
|
87
|
-
if (existsSync(pkgClient)) {
|
|
88
|
-
try {
|
|
89
|
-
const pkg = JSON.parse(readFileSync(pkgClient, "utf-8")) as { name?: string };
|
|
90
|
-
if (pkg?.name === "@flow-os/client") return d;
|
|
91
|
-
} catch {}
|
|
92
|
-
}
|
|
93
|
-
const parent = dirname(d);
|
|
94
|
-
if (parent === d) break;
|
|
95
|
-
d = parent;
|
|
96
|
-
}
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/** True se usare workspace:* (cwd dentro repo flow-os) */
|
|
101
|
-
export function shouldUseWorkspace(cwd: string): boolean {
|
|
102
|
-
return !!findFlowOsRepoRoot(cwd);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
82
|
/** Recupera versione di un pacchetto @flow-os/* dal registry npm (con cache 5 min) */
|
|
106
83
|
async function fetchFlowPackageVersion(pkgName: string): Promise<string | undefined> {
|
|
107
84
|
const tag = isCreateFlowOsDev() ? "dev" : "latest";
|
|
@@ -192,19 +169,12 @@ async function fetchConfigFromNpm(
|
|
|
192
169
|
/** Sostituisce workspace:* e 0.0.1 con versione concreta (workspace va bene solo dentro flow-os) */
|
|
193
170
|
function resolveFlowDeps(
|
|
194
171
|
deps: Record<string, string> | undefined,
|
|
195
|
-
|
|
196
|
-
versionsFromNpm: Map<string, string
|
|
197
|
-
useWorkspace: boolean
|
|
172
|
+
configDir: string,
|
|
173
|
+
versionsFromNpm: Map<string, string>
|
|
198
174
|
): Record<string, string> {
|
|
199
175
|
if (!deps) return {};
|
|
200
176
|
const resolved = { ...deps };
|
|
201
|
-
|
|
202
|
-
for (const k of Object.keys(resolved)) {
|
|
203
|
-
if (k.startsWith("@flow-os/")) resolved[k] = "workspace:*";
|
|
204
|
-
}
|
|
205
|
-
return resolved;
|
|
206
|
-
}
|
|
207
|
-
const ownerPkgPath = join(pkgRootDir, "package.json");
|
|
177
|
+
const ownerPkgPath = join(configDir, "..", "package.json");
|
|
208
178
|
let ownerVersion: string | undefined;
|
|
209
179
|
if (existsSync(ownerPkgPath)) {
|
|
210
180
|
try {
|
|
@@ -235,7 +205,7 @@ function resolveFlowDeps(
|
|
|
235
205
|
return resolved;
|
|
236
206
|
}
|
|
237
207
|
|
|
238
|
-
function mergePkg(configDir: string, cwd: string, versionsFromNpm: Map<string, string
|
|
208
|
+
function mergePkg(configDir: string, cwd: string, versionsFromNpm: Map<string, string>): void {
|
|
239
209
|
const configPkg = join(configDir, "package.json");
|
|
240
210
|
if (!existsSync(configPkg)) return;
|
|
241
211
|
const targetPath = join(cwd, "package.json");
|
|
@@ -245,77 +215,14 @@ function mergePkg(configDir: string, cwd: string, versionsFromNpm: Map<string, s
|
|
|
245
215
|
: { ...config, name: basename(cwd) || "flow-app" };
|
|
246
216
|
target.dependencies = { ...target.dependencies, ...config.dependencies };
|
|
247
217
|
target.devDependencies = { ...target.devDependencies, ...config.devDependencies };
|
|
248
|
-
const
|
|
249
|
-
for (const [k, v] of Object.entries(resolveFlowDeps(config.dependencies, pkgRootDir, versionsFromNpm, useWorkspace)))
|
|
218
|
+
for (const [k, v] of Object.entries(resolveFlowDeps(config.dependencies, configDir, versionsFromNpm)))
|
|
250
219
|
target.dependencies[k] = v;
|
|
251
|
-
for (const [k, v] of Object.entries(resolveFlowDeps(config.devDependencies,
|
|
220
|
+
for (const [k, v] of Object.entries(resolveFlowDeps(config.devDependencies, configDir, versionsFromNpm)))
|
|
252
221
|
target.devDependencies[k] = v;
|
|
253
222
|
target.scripts = { ...target.scripts, ...config.scripts };
|
|
254
223
|
writeFileSync(targetPath, JSON.stringify(target, null, 2));
|
|
255
224
|
}
|
|
256
225
|
|
|
257
|
-
type FlowOsInit = { dependencies?: Record<string, string>; devDependencies?: Record<string, string>; scripts?: Record<string, string>; name?: string; version?: string; type?: string };
|
|
258
|
-
|
|
259
|
-
/** Merge da flow-os-init: root package.json (se in repo) oppure package (npm) */
|
|
260
|
-
function mergeFlowOsInit(
|
|
261
|
-
packageRoot: string,
|
|
262
|
-
pkgName: string,
|
|
263
|
-
cwd: string,
|
|
264
|
-
versionsFromNpm: Map<string, string>,
|
|
265
|
-
useWorkspace: boolean,
|
|
266
|
-
flowOsRepoRoot: string | null
|
|
267
|
-
): void {
|
|
268
|
-
let init: FlowOsInit | undefined;
|
|
269
|
-
if (flowOsRepoRoot) {
|
|
270
|
-
const rootPkgPath = join(flowOsRepoRoot, "package.json");
|
|
271
|
-
if (existsSync(rootPkgPath)) {
|
|
272
|
-
try {
|
|
273
|
-
const rootPkg = JSON.parse(readFileSync(rootPkgPath, "utf-8")) as { "flow-os-init"?: Record<string, FlowOsInit> };
|
|
274
|
-
init = rootPkg["flow-os-init"]?.[pkgName];
|
|
275
|
-
} catch {}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
if (!init) {
|
|
279
|
-
const pkgPath = join(packageRoot, "package.json");
|
|
280
|
-
if (!existsSync(pkgPath)) return;
|
|
281
|
-
try {
|
|
282
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8")) as { "flow-os-init"?: FlowOsInit };
|
|
283
|
-
init = pkg["flow-os-init"];
|
|
284
|
-
} catch {
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
if (!init) return;
|
|
289
|
-
const targetPath = join(cwd, "package.json");
|
|
290
|
-
const target = existsSync(targetPath)
|
|
291
|
-
? JSON.parse(readFileSync(targetPath, "utf-8"))
|
|
292
|
-
: { name: init.name ?? (basename(cwd) || "flow-app"), version: init.version ?? "0.0.1", type: init.type ?? "module" };
|
|
293
|
-
target.dependencies = { ...target.dependencies, ...init.dependencies };
|
|
294
|
-
target.devDependencies = { ...target.devDependencies, ...init.devDependencies };
|
|
295
|
-
for (const [k, v] of Object.entries(resolveFlowDeps(init.dependencies, packageRoot, versionsFromNpm, useWorkspace)))
|
|
296
|
-
target.dependencies[k] = v;
|
|
297
|
-
for (const [k, v] of Object.entries(resolveFlowDeps(init.devDependencies, packageRoot, versionsFromNpm, useWorkspace)))
|
|
298
|
-
target.devDependencies[k] = v;
|
|
299
|
-
target.scripts = { ...target.scripts, ...init.scripts };
|
|
300
|
-
writeFileSync(targetPath, JSON.stringify(target, null, 2));
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
/** Aggiunge dipendenza per pacchetti senza config (solo install) */
|
|
304
|
-
function addDependencyForPackage(
|
|
305
|
-
pkgName: string,
|
|
306
|
-
cwd: string,
|
|
307
|
-
versionsFromNpm: Map<string, string>,
|
|
308
|
-
useWorkspace: boolean
|
|
309
|
-
): void {
|
|
310
|
-
const targetPath = join(cwd, "package.json");
|
|
311
|
-
if (!existsSync(targetPath)) return;
|
|
312
|
-
const target = JSON.parse(readFileSync(targetPath, "utf-8"));
|
|
313
|
-
target.dependencies = target.dependencies ?? {};
|
|
314
|
-
const spec = useWorkspace ? "workspace:*" : (versionsFromNpm.get(pkgName) ? `^${versionsFromNpm.get(pkgName)}` : undefined);
|
|
315
|
-
if (spec) target.dependencies[pkgName] = spec;
|
|
316
|
-
writeFileSync(targetPath, JSON.stringify(target, null, 2));
|
|
317
|
-
}
|
|
318
|
-
|
|
319
226
|
/** Assicura che versions abbia le versioni per pkgNames (fetch lazy) */
|
|
320
227
|
async function ensureVersions(versions: Map<string, string>, pkgNames: string[]): Promise<void> {
|
|
321
228
|
const missing = pkgNames.filter((n) => !versions.has(n));
|
|
@@ -344,17 +251,12 @@ async function collectAllTemplates(
|
|
|
344
251
|
done: Set<string>,
|
|
345
252
|
order: string[],
|
|
346
253
|
versionsFromNpm: Map<string, string>,
|
|
347
|
-
tmpDirs: string[]
|
|
348
|
-
flowOsRepoRoot: string | null
|
|
254
|
+
tmpDirs: string[]
|
|
349
255
|
): Promise<void> {
|
|
350
256
|
for (const lib of libs) {
|
|
351
257
|
const pkgName = toPkgName(lib);
|
|
352
258
|
if (done.has(pkgName)) continue;
|
|
353
259
|
|
|
354
|
-
const shortName = toShortName(pkgName);
|
|
355
|
-
const localFromRepo = flowOsRepoRoot ? join(flowOsRepoRoot, "packages", shortName) : "";
|
|
356
|
-
const localConfigFromRepo = localFromRepo ? join(localFromRepo, "config") : "";
|
|
357
|
-
|
|
358
260
|
let root: string;
|
|
359
261
|
let configDir: string;
|
|
360
262
|
try {
|
|
@@ -364,22 +266,12 @@ async function collectAllTemplates(
|
|
|
364
266
|
root = "";
|
|
365
267
|
configDir = "";
|
|
366
268
|
}
|
|
367
|
-
const hasLocalFromRepo = !!localConfigFromRepo && existsSync(localConfigFromRepo);
|
|
368
269
|
const hasLocal = existsSync(configDir);
|
|
369
270
|
|
|
370
271
|
let pkgFiles: Map<string, string>;
|
|
371
272
|
let configDirForPkg: string;
|
|
372
|
-
const useLocalRepo = hasLocalFromRepo && flowOsRepoRoot;
|
|
373
273
|
const npmVer = versionsFromNpm.get(pkgName);
|
|
374
|
-
|
|
375
|
-
if (useLocalRepo) {
|
|
376
|
-
configDirForPkg = localConfigFromRepo;
|
|
377
|
-
pkgFiles = collectConfigFiles(configDirForPkg);
|
|
378
|
-
const subDeps = flowDepsFromPkg(join(configDirForPkg, ".."));
|
|
379
|
-
for (const sub of subDeps) {
|
|
380
|
-
await collectAllTemplates([toShortName(sub)], combined, done, order, versionsFromNpm, tmpDirs, flowOsRepoRoot);
|
|
381
|
-
}
|
|
382
|
-
} else if (npmVer) {
|
|
274
|
+
if (npmVer) {
|
|
383
275
|
const fetched = await fetchConfigFromNpm(pkgName, npmVer, tmpDirs);
|
|
384
276
|
if (fetched) {
|
|
385
277
|
pkgFiles = fetched.files;
|
|
@@ -387,13 +279,13 @@ async function collectAllTemplates(
|
|
|
387
279
|
const subDeps = flowDepsFromPkg(join(configDirForPkg, ".."));
|
|
388
280
|
await ensureVersions(versionsFromNpm, subDeps);
|
|
389
281
|
for (const sub of subDeps) {
|
|
390
|
-
await collectAllTemplates([toShortName(sub)], combined, done, order, versionsFromNpm, tmpDirs
|
|
282
|
+
await collectAllTemplates([toShortName(sub)], combined, done, order, versionsFromNpm, tmpDirs);
|
|
391
283
|
}
|
|
392
284
|
} else if (hasLocal) {
|
|
393
285
|
const subDeps = flowDeps(root);
|
|
394
286
|
await ensureVersions(versionsFromNpm, subDeps);
|
|
395
287
|
for (const sub of subDeps) {
|
|
396
|
-
await collectAllTemplates([toShortName(sub)], combined, done, order, versionsFromNpm, tmpDirs
|
|
288
|
+
await collectAllTemplates([toShortName(sub)], combined, done, order, versionsFromNpm, tmpDirs);
|
|
397
289
|
}
|
|
398
290
|
pkgFiles = collectConfigFiles(configDir);
|
|
399
291
|
configDirForPkg = configDir;
|
|
@@ -404,7 +296,7 @@ async function collectAllTemplates(
|
|
|
404
296
|
const subDeps = flowDeps(root);
|
|
405
297
|
await ensureVersions(versionsFromNpm, subDeps);
|
|
406
298
|
for (const sub of subDeps) {
|
|
407
|
-
await collectAllTemplates([toShortName(sub)], combined, done, order, versionsFromNpm, tmpDirs
|
|
299
|
+
await collectAllTemplates([toShortName(sub)], combined, done, order, versionsFromNpm, tmpDirs);
|
|
408
300
|
}
|
|
409
301
|
pkgFiles = collectConfigFiles(configDir);
|
|
410
302
|
configDirForPkg = configDir;
|
|
@@ -427,68 +319,28 @@ export async function initLib(
|
|
|
427
319
|
onProgress?: (step: InitProgressStep) => void
|
|
428
320
|
): Promise<void> {
|
|
429
321
|
const pkgNames = libs.map(toPkgName);
|
|
430
|
-
const flowOsRepoRoot = findFlowOsRepoRoot(cwd);
|
|
431
|
-
const useWorkspace = !!flowOsRepoRoot;
|
|
432
322
|
const versions = versionsFromNpm ?? new Map<string, string>();
|
|
433
323
|
|
|
434
324
|
onProgress?.("fetch");
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
for (const [k, v] of fetched) versions.set(k, v);
|
|
438
|
-
}
|
|
325
|
+
const fetched = await fetchFlowPackageVersions(pkgNames);
|
|
326
|
+
for (const [k, v] of fetched) versions.set(k, v);
|
|
439
327
|
|
|
440
328
|
onProgress?.("templates");
|
|
441
329
|
const combined = new Map<string, string>();
|
|
442
330
|
const done = new Set<string>();
|
|
443
331
|
const order: string[] = [];
|
|
444
332
|
const tmpDirs: string[] = [];
|
|
445
|
-
await collectAllTemplates(libs, combined, done, order, versions, tmpDirs
|
|
446
|
-
|
|
447
|
-
for (const configDir of order) {
|
|
448
|
-
const packageRoot = join(configDir, "..");
|
|
449
|
-
const pkgName = (() => {
|
|
450
|
-
try {
|
|
451
|
-
const p = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf-8")) as { name?: string };
|
|
452
|
-
return p?.name ?? "";
|
|
453
|
-
} catch {
|
|
454
|
-
return "";
|
|
455
|
-
}
|
|
456
|
-
})();
|
|
457
|
-
if (existsSync(join(configDir, "package.json"))) {
|
|
458
|
-
mergePkg(configDir, cwd, versions, useWorkspace);
|
|
459
|
-
} else {
|
|
460
|
-
mergeFlowOsInit(packageRoot, pkgName, cwd, versions, useWorkspace, flowOsRepoRoot);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
333
|
+
await collectAllTemplates(libs, combined, done, order, versions, tmpDirs);
|
|
463
334
|
|
|
464
|
-
const targetPath = join(cwd, "package.json");
|
|
465
|
-
if (!existsSync(targetPath)) {
|
|
466
|
-
writeFileSync(
|
|
467
|
-
targetPath,
|
|
468
|
-
JSON.stringify({ name: basename(cwd) || "flow-app", version: "0.0.1", private: true, type: "module" }, null, 2)
|
|
469
|
-
);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
const toAdd = new Set<string>(pkgNames);
|
|
473
335
|
for (const configDir of order) {
|
|
474
|
-
|
|
475
|
-
for (const peer of flowDepsFromPkg(packageRoot)) toAdd.add(peer);
|
|
476
|
-
}
|
|
477
|
-
for (const pkgName of pkgNames) {
|
|
478
|
-
const packageRoot = flowOsRepoRoot ? join(flowOsRepoRoot, "packages", toShortName(pkgName)) : (() => { try { return pkgRoot(pkgName); } catch { return ""; } })();
|
|
479
|
-
if (packageRoot) for (const peer of flowDepsFromPkg(packageRoot)) toAdd.add(peer);
|
|
480
|
-
}
|
|
481
|
-
await ensureVersions(versions, [...toAdd]);
|
|
482
|
-
for (const pkgName of toAdd) {
|
|
483
|
-
addDependencyForPackage(pkgName, cwd, versions, useWorkspace);
|
|
336
|
+
mergePkg(configDir, cwd, versions);
|
|
484
337
|
}
|
|
485
338
|
|
|
486
339
|
onProgress?.("write");
|
|
487
340
|
await writeMergedWithUser(combined, cwd, (path, conflicts) => resolveConflicts(conflicts, path));
|
|
488
341
|
|
|
489
342
|
onProgress?.("install");
|
|
490
|
-
const
|
|
491
|
-
const proc = Bun.spawn(["bun", "install"], { cwd: installCwd, stdout: "pipe", stderr: "pipe" });
|
|
343
|
+
const proc = Bun.spawn(["bun", "install"], { cwd, stdout: "inherit", stderr: "inherit" });
|
|
492
344
|
const exitCode = await proc.exited;
|
|
493
345
|
if (exitCode !== 0) {
|
|
494
346
|
throw new Error(`bun install exited with code ${exitCode}`);
|
package/src/init/ui.ts
CHANGED
|
@@ -9,7 +9,6 @@ const E = "\x1b[91m";
|
|
|
9
9
|
const R = "\x1b[0m";
|
|
10
10
|
const B = "\x1b[1m";
|
|
11
11
|
const DIM = "\x1b[2m";
|
|
12
|
-
const W = "\x1b[97m"; // bianco (solo per headerLogo)
|
|
13
12
|
|
|
14
13
|
const FRAMES = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏";
|
|
15
14
|
|
|
@@ -26,24 +25,19 @@ export function bannerBox(title: string, lines: string[], color: string, w = 50)
|
|
|
26
25
|
const c = color;
|
|
27
26
|
const inner = " " + c + B + title + R + " ";
|
|
28
27
|
const innerLen = stripAnsi(inner).length;
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
const emptyLine = c + "│" + R + " " + " ".repeat(innerW - 2) + c + "│" + R;
|
|
35
|
-
const bodyLines = lines.map((l) => c + "│" + R + " " + pad(l, innerW - 2) + c + "│" + R);
|
|
36
|
-
return "\n" + top + "\n" + emptyLine + "\n" + bodyLines.join("\n") + "\n" + bottom + "\n";
|
|
28
|
+
const half = Math.max(0, Math.floor((w - 2 - innerLen) / 2));
|
|
29
|
+
const top = c + "╭" + "─".repeat(half) + inner + "─".repeat(w - 2 - half - innerLen) + "╮" + R;
|
|
30
|
+
const bottom = c + "╰" + "─".repeat(w - 2) + "╯" + R;
|
|
31
|
+
const bodyLines = lines.map((l) => c + "│" + R + " " + pad(l, w - 2) + c + "│" + R);
|
|
32
|
+
return "\n" + top + "\n" + bodyLines.join("\n") + "\n" + bottom + "\n";
|
|
37
33
|
}
|
|
38
34
|
|
|
39
|
-
export function box(lines: string[], color: string, w =
|
|
35
|
+
export function box(lines: string[], color: string, w = 52): string {
|
|
40
36
|
const c = color;
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
const body = lines.map((l) => c + "│" + R + " " + pad(l, innerW - 2) + c + "│" + R).join("\n");
|
|
46
|
-
return "\n" + top + "\n" + emptyLine + "\n" + body + "\n" + bottom + "\n";
|
|
37
|
+
const top = c + "╭" + "─".repeat(w) + "╮" + R;
|
|
38
|
+
const bottom = c + "╰" + "─".repeat(w) + "╯" + R;
|
|
39
|
+
const body = lines.map((l) => c + "│" + R + " " + pad(l, w - 2) + c + "│" + R).join("\n");
|
|
40
|
+
return "\n" + top + "\n" + body + "\n" + bottom + "\n";
|
|
47
41
|
}
|
|
48
42
|
|
|
49
43
|
import type { InitProgressStep } from "./scaffold";
|
|
@@ -93,6 +87,8 @@ export async function withLoading<T>(
|
|
|
93
87
|
}
|
|
94
88
|
}
|
|
95
89
|
|
|
90
|
+
const W = "\x1b[97m"; // bianco
|
|
91
|
+
|
|
96
92
|
export const colors = { V, V_LIGHT, Y, E, R, B, DIM, W };
|
|
97
93
|
|
|
98
94
|
/** Icona layers: 3 quadrati arrotondati sovrapposti, vista isometrica con shading ▓▒░ */
|