create-flow-os 0.0.13 → 0.0.16-dev.1772014900
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/.dockerignore +5 -0
- package/.vscode/settings.json +6 -0
- package/Dockerfile +14 -0
- package/config/flow.ts +3 -0
- package/index.html +13 -0
- package/package.json +9 -4
- package/src/index.ts +5 -5
- package/src/init/index.ts +22 -9
- package/src/init/lib.ts +3 -3
- package/src/init/scaffold.ts +74 -13
- package/tsconfig.json +15 -0
package/.dockerignore
ADDED
package/Dockerfile
ADDED
package/config/flow.ts
ADDED
package/index.html
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="it">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8"/>
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
6
|
+
<title>Flow</title>
|
|
7
|
+
<style>html,body{margin:0;padding:0;min-height:100vh}#app{min-height:100vh;box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}</style>
|
|
8
|
+
</head>
|
|
9
|
+
<body>
|
|
10
|
+
<div id="app"></div>
|
|
11
|
+
<script type="module">document.getElementById('app').innerHTML='<h1>Flow</h1><p>Dev server ready.</p>';</script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-flow-os",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.16-dev.1772014900",
|
|
4
4
|
"license": "PolyForm-Shield-1.0.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@flow-os/client": "0.0.11"
|
|
7
|
+
"@flow-os/client": "^0.0.11"
|
|
8
8
|
},
|
|
9
9
|
"bin": {
|
|
10
10
|
"create-flow-os": "./src/index.ts"
|
|
11
11
|
},
|
|
12
12
|
"scripts": {
|
|
13
|
-
"create": "bun run src/create/index.ts"
|
|
13
|
+
"create": "bun run src/create/index.ts",
|
|
14
|
+
"dev": "flow-os dev",
|
|
15
|
+
"build": "flow-os build",
|
|
16
|
+
"start": "bun run server/start.ts"
|
|
14
17
|
},
|
|
15
18
|
"devDependencies": {
|
|
16
|
-
"
|
|
19
|
+
"@types/node": "^25.3.0",
|
|
20
|
+
"bun-types": "^1.3.9",
|
|
21
|
+
"vite": ">=7.3.0"
|
|
17
22
|
}
|
|
18
23
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
// create flow-os [nome]
|
|
4
|
-
// create flow-os
|
|
3
|
+
// create flow-os [nome] → create/
|
|
4
|
+
// create flow-os i [lib] → init (i = init)
|
|
5
5
|
|
|
6
6
|
const subcommand = process.argv[2];
|
|
7
7
|
|
|
8
|
-
if (subcommand === "init") {
|
|
9
|
-
await import("./init/index
|
|
8
|
+
if (subcommand === "init" || subcommand === "i") {
|
|
9
|
+
await import("./init/index");
|
|
10
10
|
} else {
|
|
11
|
-
await import("./create/index
|
|
11
|
+
await import("./create/index");
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
export {};
|
package/src/init/index.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
3
|
+
import * as readline from "readline";
|
|
4
|
+
import { join, dirname } from "path";
|
|
5
|
+
import { fileURLToPath } from "url";
|
|
5
6
|
import { libsWithConfig, toShortName } from "./lib";
|
|
6
|
-
import { initLib } from "./scaffold";
|
|
7
|
+
import { initLib, fetchFlowClientVersion } from "./scaffold";
|
|
7
8
|
|
|
8
9
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
9
|
-
// Usage: bun create flow-os
|
|
10
|
+
// Usage: bun create flow-os i [lib...] | bun create flow-os i (prompt interattivo)
|
|
10
11
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
11
12
|
|
|
12
13
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
13
14
|
// ANSI: violet (ok), yellow (unrecognized), red (error/failure)
|
|
14
|
-
// 38;5;226 = golden yellow (più vivo di 93)
|
|
15
15
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
16
16
|
const V = "\x1b[95m";
|
|
17
17
|
const Y = "\x1b[38;5;226m";
|
|
@@ -35,12 +35,24 @@ const box = (lines: string[], color: string, w = 52) => {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
38
|
-
// Args: libs
|
|
38
|
+
// Args: libs da argv o prompt interattivo
|
|
39
39
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
40
|
-
const libs = [...new Set(process.argv.slice(3))];
|
|
41
40
|
const cwd = process.cwd();
|
|
42
41
|
const cliRoot = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
43
42
|
const available = libsWithConfig(cliRoot).map(toShortName);
|
|
43
|
+
|
|
44
|
+
let libs = [...new Set(process.argv.slice(3))];
|
|
45
|
+
|
|
46
|
+
if (!libs.length && available.length) {
|
|
47
|
+
console.log(box([B + "Packages disponibili:" + R, ...available.map((l) => V + "◆" + R + " " + l)], V));
|
|
48
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
49
|
+
const answer = await new Promise<string>((resolve) =>
|
|
50
|
+
rl.question(V + "Seleziona (spazio o virgola): " + R, resolve)
|
|
51
|
+
);
|
|
52
|
+
rl.close();
|
|
53
|
+
libs = answer.split(/[\s,]+/).map((s) => s.trim()).filter(Boolean);
|
|
54
|
+
}
|
|
55
|
+
|
|
44
56
|
const toInit = libs.filter((l) => available.includes(l));
|
|
45
57
|
const skipped = libs.filter((l) => !available.includes(l));
|
|
46
58
|
|
|
@@ -50,10 +62,11 @@ if (!toInit.length) {
|
|
|
50
62
|
}
|
|
51
63
|
|
|
52
64
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
53
|
-
// Execute: init libs, poi output box
|
|
65
|
+
// Execute: fetch versione client da npm (latest/dev), init libs, poi output box
|
|
54
66
|
// ───────────────────────────────────────────────────────────────────────────────
|
|
67
|
+
const clientVersion = await fetchFlowClientVersion();
|
|
55
68
|
const done = new Set<string>();
|
|
56
|
-
for (const lib of toInit) initLib(lib, cwd, done);
|
|
69
|
+
for (const lib of toInit) initLib(lib, cwd, done, clientVersion);
|
|
57
70
|
|
|
58
71
|
const iconOk = V + "◆" + R;
|
|
59
72
|
const iconUnrec = Y + "?" + R;
|
package/src/init/lib.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "
|
|
2
|
-
import { join, dirname } from "
|
|
3
|
-
import { fileURLToPath } from "
|
|
1
|
+
import { existsSync, readFileSync } from "fs";
|
|
2
|
+
import { join, dirname } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
4
|
|
|
5
5
|
const FLOW_PREFIX = "@flow-os/";
|
|
6
6
|
|
package/src/init/scaffold.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { existsSync, cpSync, readFileSync, writeFileSync, readdirSync } from "
|
|
2
|
-
import { join, basename } from "
|
|
3
|
-
import {
|
|
1
|
+
import { existsSync, cpSync, readFileSync, writeFileSync, readdirSync } from "fs";
|
|
2
|
+
import { join, basename, dirname } from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import { pkgRoot, flowDeps, toPkgName, toShortName } from "./lib";
|
|
4
5
|
|
|
5
6
|
const SKIP = new Set(["node_modules", ".git", ".vite", "package.json"]);
|
|
7
|
+
const NPM_REGISTRY = "https://registry.npmjs.org";
|
|
6
8
|
|
|
7
9
|
function copyConfig(configDir: string, cwd: string): void {
|
|
8
10
|
for (const e of readdirSync(configDir, { withFileTypes: true })) {
|
|
@@ -11,23 +13,80 @@ function copyConfig(configDir: string, cwd: string): void {
|
|
|
11
13
|
}
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
/**
|
|
15
|
-
function
|
|
16
|
+
/** Indica se create-flow-os è in modalità dev (flow-os@dev) */
|
|
17
|
+
function isCreateFlowOsDev(): boolean {
|
|
18
|
+
try {
|
|
19
|
+
const cliRoot = join(dirname(fileURLToPath(import.meta.url)), "..", "..");
|
|
20
|
+
const pkg = JSON.parse(readFileSync(join(cliRoot, "package.json"), "utf-8")) as { dependencies?: Record<string, string> };
|
|
21
|
+
const v = pkg.dependencies?.["@flow-os/client"];
|
|
22
|
+
return !!v?.includes("dev");
|
|
23
|
+
} catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** Recupera la versione di @flow-os/client dal registry npm in tempo reale (latest o dev) */
|
|
29
|
+
export async function fetchFlowClientVersion(): Promise<string | undefined> {
|
|
30
|
+
const tag = isCreateFlowOsDev() ? "dev" : "latest";
|
|
31
|
+
try {
|
|
32
|
+
const res = await fetch(`${NPM_REGISTRY}/@flow-os/client`);
|
|
33
|
+
if (!res.ok) return undefined;
|
|
34
|
+
const data = (await res.json()) as { "dist-tags"?: Record<string, string> };
|
|
35
|
+
const version = data["dist-tags"]?.[tag] ?? data["dist-tags"]?.["latest"];
|
|
36
|
+
return version;
|
|
37
|
+
} catch {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Sostituisce workspace:* e 0.0.1 con versione concreta (workspace va bene solo dentro flow-os) */
|
|
43
|
+
function resolveFlowDeps(
|
|
44
|
+
deps: Record<string, string> | undefined,
|
|
45
|
+
configDir: string,
|
|
46
|
+
clientVersionFromNpm: string | undefined
|
|
47
|
+
): Record<string, string> {
|
|
16
48
|
if (!deps) return {};
|
|
17
49
|
const resolved = { ...deps };
|
|
50
|
+
const ownerPkgPath = join(configDir, "..", "package.json");
|
|
51
|
+
let ownerVersion: string | undefined;
|
|
52
|
+
if (existsSync(ownerPkgPath)) {
|
|
53
|
+
try {
|
|
54
|
+
ownerVersion = (JSON.parse(readFileSync(ownerPkgPath, "utf-8")) as { version?: string }).version;
|
|
55
|
+
} catch {}
|
|
56
|
+
}
|
|
57
|
+
const isDevSpec = isCreateFlowOsDev();
|
|
18
58
|
for (const k of Object.keys(resolved)) {
|
|
19
|
-
if (k.startsWith("@flow-os/")
|
|
59
|
+
if (!k.startsWith("@flow-os/")) continue;
|
|
60
|
+
const v = resolved[k];
|
|
61
|
+
if (v !== "workspace:*" && v !== "0.0.1" && k !== "@flow-os/client") continue;
|
|
62
|
+
let spec: string | undefined;
|
|
63
|
+
if (k === "@flow-os/client") {
|
|
64
|
+
if (clientVersionFromNpm) {
|
|
65
|
+
spec = isDevSpec ? "dev" : `^${clientVersionFromNpm}`;
|
|
66
|
+
} else if (isDevSpec) {
|
|
67
|
+
spec = "dev";
|
|
68
|
+
} else {
|
|
69
|
+
try {
|
|
70
|
+
const root = pkgRoot(k);
|
|
71
|
+
const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf-8")) as { version?: string };
|
|
72
|
+
if (pkg.version) spec = `^${pkg.version}`;
|
|
73
|
+
} catch {}
|
|
74
|
+
if (!spec && ownerVersion) spec = `^${ownerVersion}`;
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
20
77
|
try {
|
|
21
78
|
const root = pkgRoot(k);
|
|
22
79
|
const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf-8")) as { version?: string };
|
|
23
|
-
if (pkg.version)
|
|
80
|
+
if (pkg.version) spec = `^${pkg.version}`;
|
|
24
81
|
} catch {}
|
|
82
|
+
if (!spec && ownerVersion) spec = `^${ownerVersion}`;
|
|
25
83
|
}
|
|
84
|
+
if (spec) resolved[k] = spec;
|
|
26
85
|
}
|
|
27
86
|
return resolved;
|
|
28
87
|
}
|
|
29
88
|
|
|
30
|
-
function mergePkg(configDir: string, cwd: string): void {
|
|
89
|
+
function mergePkg(configDir: string, cwd: string, clientVersionFromNpm: string | undefined): void {
|
|
31
90
|
const configPkg = join(configDir, "package.json");
|
|
32
91
|
if (!existsSync(configPkg)) return;
|
|
33
92
|
const targetPath = join(cwd, "package.json");
|
|
@@ -37,13 +96,15 @@ function mergePkg(configDir: string, cwd: string): void {
|
|
|
37
96
|
: { ...config, name: basename(cwd) || "flow-app" };
|
|
38
97
|
target.dependencies = { ...target.dependencies, ...config.dependencies };
|
|
39
98
|
target.devDependencies = { ...target.devDependencies, ...config.devDependencies };
|
|
40
|
-
for (const [k, v] of Object.entries(resolveFlowDeps(config.dependencies)))
|
|
41
|
-
|
|
99
|
+
for (const [k, v] of Object.entries(resolveFlowDeps(config.dependencies, configDir, clientVersionFromNpm)))
|
|
100
|
+
target.dependencies[k] = v;
|
|
101
|
+
for (const [k, v] of Object.entries(resolveFlowDeps(config.devDependencies, configDir, clientVersionFromNpm)))
|
|
102
|
+
target.devDependencies[k] = v;
|
|
42
103
|
target.scripts = { ...target.scripts, ...config.scripts };
|
|
43
104
|
writeFileSync(targetPath, JSON.stringify(target, null, 2));
|
|
44
105
|
}
|
|
45
106
|
|
|
46
|
-
export function initLib(lib: string, cwd: string, done: Set<string
|
|
107
|
+
export function initLib(lib: string, cwd: string, done: Set<string>, clientVersionFromNpm?: string): void {
|
|
47
108
|
const pkgName = toPkgName(lib);
|
|
48
109
|
if (done.has(pkgName)) return;
|
|
49
110
|
|
|
@@ -52,10 +113,10 @@ export function initLib(lib: string, cwd: string, done: Set<string>): void {
|
|
|
52
113
|
if (!existsSync(configDir)) return;
|
|
53
114
|
|
|
54
115
|
for (const sub of flowDeps(root)) {
|
|
55
|
-
initLib(toShortName(sub), cwd, done);
|
|
116
|
+
initLib(toShortName(sub), cwd, done, clientVersionFromNpm);
|
|
56
117
|
}
|
|
57
118
|
|
|
58
119
|
copyConfig(configDir, cwd);
|
|
59
|
-
mergePkg(configDir, cwd);
|
|
120
|
+
mergePkg(configDir, cwd, clientVersionFromNpm);
|
|
60
121
|
done.add(pkgName);
|
|
61
122
|
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"types": ["bun-types", "node"],
|
|
4
|
+
"target": "ESNext",
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"strict": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"noEmit": true,
|
|
10
|
+
"esModuleInterop": true,
|
|
11
|
+
"isolatedModules": true
|
|
12
|
+
},
|
|
13
|
+
"include": ["src/**/*.ts"],
|
|
14
|
+
"exclude": ["node_modules"]
|
|
15
|
+
}
|