create-flow-os 0.0.1-dev.1771667897 → 0.0.1-dev.1771668924

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.
Files changed (2) hide show
  1. package/bin/index.js +131 -33
  2. package/package.json +1 -1
package/bin/index.js CHANGED
@@ -872,10 +872,107 @@ var useDevTag = argv.includes("--dev");
872
872
  var nameArg = argv.find((a3) => !a3.startsWith("--"));
873
873
  var DIR = basename(import.meta.dir) === "dist" || basename(import.meta.dir) === "bin" ? join2(import.meta.dir, "..") : import.meta.dir;
874
874
  var REPO_ROOT = (process.env.FLOW_FRAMEWORK_ROOT ?? join2(DIR, "..", "..")).replace(/\\/g, "/");
875
- var aqua = import_picocolors3.default.cyan;
876
- var teal = (s) => import_picocolors3.default.cyan(s);
877
- var dim = import_picocolors3.default.dim;
878
- var subtle = (s) => import_picocolors3.default.dim(import_picocolors3.default.cyan(s));
875
+ var c2 = {
876
+ brand: (s) => import_picocolors3.default.bold(import_picocolors3.default.cyan(s)),
877
+ cyan: (s) => import_picocolors3.default.cyan(s),
878
+ dim: (s) => import_picocolors3.default.dim(s),
879
+ bold: (s) => import_picocolors3.default.bold(s),
880
+ muted: (s) => import_picocolors3.default.cyan(s),
881
+ bright: (s) => import_picocolors3.default.white(s)
882
+ };
883
+ var W2 = 50;
884
+ var ICON = {
885
+ full: "\u25C9",
886
+ client: "\u25C6",
887
+ server: "\u25CF",
888
+ deps: "\uD83D\uDCE6",
889
+ rocket: "\u25B6"
890
+ };
891
+ function stripAnsi(s) {
892
+ return s.replace(/\x1b\[[0-9;]*m/g, "");
893
+ }
894
+ function box(lines) {
895
+ const top = c2.dim("\u256D" + "\u2500".repeat(W2 - 2) + "\u256E");
896
+ const bottom = c2.dim("\u2570" + "\u2500".repeat(W2 - 2) + "\u256F");
897
+ const body = lines.map((l2) => {
898
+ const plain = stripAnsi(l2);
899
+ const pad = Math.max(0, W2 - 4 - plain.length);
900
+ return c2.dim("\u2502 ") + l2 + " ".repeat(pad) + c2.dim(" \u2502");
901
+ }).join(`
902
+ `);
903
+ return `
904
+ ` + top + `
905
+ ` + body + `
906
+ ` + bottom + `
907
+ `;
908
+ }
909
+ var LOCAL_URL_RE = /https?:\/\/localhost(:\d+)?(?:\/[^\s]*)?/i;
910
+ function flowBanner(url) {
911
+ const link = c2.brand(url);
912
+ return [
913
+ "",
914
+ c2.cyan(" \u256D\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256E"),
915
+ c2.cyan(" \u2502 ") + c2.bold("Flow OS") + c2.cyan(" is running \u2502"),
916
+ c2.cyan(" \u2570\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u256F"),
917
+ "",
918
+ " Open: " + link,
919
+ ""
920
+ ].join(`
921
+ `);
922
+ }
923
+ async function runDevWithBanner(cwd) {
924
+ const devProc = Bun.spawn(["bun", "run", "dev"], {
925
+ cwd,
926
+ stdout: "pipe",
927
+ stderr: "pipe",
928
+ stdio: ["inherit", "pipe", "pipe"]
929
+ });
930
+ let bannerShown = false;
931
+ const decoder = new TextDecoder;
932
+ let outBuf = "";
933
+ const drain = (stream, isErr) => {
934
+ const target = isErr ? process.stderr : process.stdout;
935
+ const reader = stream.getReader();
936
+ function read() {
937
+ return reader.read().then(({ done, value }) => {
938
+ const text = value ? decoder.decode(value, { stream: !done }) : "";
939
+ if (isErr) {
940
+ if (text)
941
+ target.write(text);
942
+ return done ? undefined : read();
943
+ }
944
+ if (text)
945
+ outBuf += text;
946
+ const lines = outBuf.split(/\r?\n/);
947
+ outBuf = done ? "" : lines.pop() ?? "";
948
+ for (const line of lines) {
949
+ const urlMatch = line.match(LOCAL_URL_RE);
950
+ if (!bannerShown && urlMatch) {
951
+ bannerShown = true;
952
+ process.stdout.write(flowBanner(urlMatch[0]));
953
+ }
954
+ target.write(line + `
955
+ `);
956
+ }
957
+ if (done && outBuf) {
958
+ const urlMatch = outBuf.match(LOCAL_URL_RE);
959
+ if (!bannerShown && urlMatch) {
960
+ bannerShown = true;
961
+ process.stdout.write(flowBanner(urlMatch[0]));
962
+ }
963
+ target.write(outBuf);
964
+ }
965
+ return done ? undefined : read();
966
+ });
967
+ }
968
+ return read();
969
+ };
970
+ await Promise.all([
971
+ drain(devProc.stdout, false),
972
+ drain(devProc.stderr, true)
973
+ ]).catch(() => {});
974
+ await devProc.exited;
975
+ }
879
976
  function optsForProfile(config, profileId) {
880
977
  return Object.entries(config.packages).filter(([, e2]) => {
881
978
  const inc = e2.includeIn ?? [];
@@ -887,20 +984,24 @@ function optsForProfile(config, profileId) {
887
984
  });
888
985
  }
889
986
  async function main() {
890
- const devBadge = useDevTag ? teal(" \xB7 dev") : "";
891
- pe(teal("\u25B8 ") + import_picocolors3.default.bold("Flow") + devBadge + `
892
- ` + dim(" Create a new application"));
987
+ const devBadge = useDevTag ? c2.brand(" \xB7 dev") : "";
988
+ const introLines = [
989
+ c2.bold("Flow") + devBadge,
990
+ "",
991
+ c2.cyan("We're creating your Flow application.")
992
+ ];
993
+ pe(box(introLines));
893
994
  const config = await Bun.file(join2(DIR, "config.json")).json();
894
995
  const hasDeps = Object.values(config.packages).every((e2) => Array.isArray(e2.deps));
895
996
  if (!hasDeps) {
896
- he(dim("Run ") + teal("bun run gen") + dim(" from create-flow first."));
997
+ he(c2.dim("Run ") + c2.brand("bun run gen") + c2.dim(" from create-flow first."));
897
998
  process.exit(1);
898
999
  }
899
1000
  const projectName = nameArg?.trim() || (yes ? "my-flow-app" : null);
900
1001
  let name = projectName;
901
1002
  if (!name && !yes) {
902
1003
  const r2 = await ae({
903
- message: subtle("Project name"),
1004
+ message: c2.muted("Project name"),
904
1005
  initialValue: "my-flow-app",
905
1006
  validate: (v3) => !v3?.trim() ? "Required" : undefined
906
1007
  });
@@ -918,11 +1019,11 @@ async function main() {
918
1019
  selected = optsFull.map(([id]) => id);
919
1020
  } else {
920
1021
  const choice = await le({
921
- message: subtle("Template"),
1022
+ message: c2.muted("Template"),
922
1023
  options: [
923
- { value: "full", label: "Full stack " + dim("(client + server)") },
924
- { value: "client", label: "Client only" },
925
- { value: "server", label: "Server only" }
1024
+ { value: "full", label: `${ICON.full} Full stack ${c2.dim("(client + server)")}` },
1025
+ { value: "client", label: `${ICON.client} Client only` },
1026
+ { value: "server", label: `${ICON.server} Server only` }
926
1027
  ]
927
1028
  });
928
1029
  if (lD(choice))
@@ -938,7 +1039,7 @@ async function main() {
938
1039
  const optionalIds = optIds.filter((id) => !defaultIds.includes(id));
939
1040
  if (optionalIds.length > 0) {
940
1041
  const r2 = await $e({
941
- message: subtle("Add-ons"),
1042
+ message: c2.muted("Add-ons"),
942
1043
  options: optionalIds.map((id) => ({ value: id, label: id })),
943
1044
  required: false
944
1045
  });
@@ -956,17 +1057,17 @@ async function main() {
956
1057
  stat(projectPath).then(() => true).catch(() => false)
957
1058
  ]);
958
1059
  if (!profileExists) {
959
- he(dim("Profile not found. Run ") + teal("bun run gen") + dim("."));
1060
+ he(c2.dim("Profile not found. Run ") + c2.brand("bun run gen") + c2.dim("."));
960
1061
  process.exit(1);
961
1062
  }
962
1063
  if (pathExists && !force) {
963
- he(dim("Folder ") + name + dim(" exists. Use ") + teal("--force") + dim("."));
1064
+ he(c2.dim("Folder ") + name + c2.dim(" exists. Use ") + c2.brand("--force") + c2.dim("."));
964
1065
  process.exit(1);
965
1066
  }
966
1067
  const isDevFromRepoPromise = useDevTag ? findPackageDir(REPO_ROOT, "@flow.os/client").then((d2) => !!d2) : Promise.resolve(false);
967
1068
  await rm(projectPathNew, { recursive: true, force: true });
968
1069
  const createSpinner = _2();
969
- createSpinner.start(teal("Creating project\u2026"));
1070
+ createSpinner.start(c2.cyan(ICON.rocket + " Creating project\u2026"));
970
1071
  await copyWithExclude(profileDir, projectPathNew, ["node_modules", ".git"]);
971
1072
  for (const id of selected) {
972
1073
  const pkgDir = join2(DIR, "packages", id);
@@ -974,7 +1075,7 @@ async function main() {
974
1075
  await copyWithExclude(pkgDir, projectPathNew, []);
975
1076
  } catch {}
976
1077
  }
977
- createSpinner.stop(teal("Project created"));
1078
+ createSpinner.stop(c2.cyan(ICON.rocket + " Project created"));
978
1079
  const extraDeps = {};
979
1080
  for (const id of selected) {
980
1081
  const deps = config.packages[id]?.deps;
@@ -1028,10 +1129,10 @@ async function main() {
1028
1129
  }
1029
1130
  if (!noInstall) {
1030
1131
  const s = _2();
1031
- s.start(teal("Installing dependencies\u2026"));
1132
+ s.start(c2.cyan(ICON.deps + " Installing dependencies\u2026"));
1032
1133
  const proc = Bun.spawn(["bun", "install"], { cwd: projectPathNew, stdout: "pipe", stderr: "pipe" });
1033
1134
  const code = await proc.exited;
1034
- s.stop(code === 0 ? teal("Dependencies installed") : "Failed");
1135
+ s.stop(code === 0 ? c2.cyan(ICON.deps + " Dependencies installed") : "Failed");
1035
1136
  if (code !== 0) {
1036
1137
  const err = await new Response(proc.stderr).text();
1037
1138
  v2.error(err || "bun install exit " + code);
@@ -1044,20 +1145,17 @@ async function main() {
1044
1145
  await rename(projectPathNew, projectPath);
1045
1146
  const startDev = !noStart && !noInstall;
1046
1147
  if (startDev) {
1047
- ge(teal(`\u25B8 Ready
1048
- `) + dim(" ") + teal(name) + dim(` is ready. Starting dev server\u2026
1049
- `));
1050
- const devProc = Bun.spawn(["bun", "run", "dev"], {
1051
- cwd: projectPath,
1052
- stdio: "inherit"
1053
- });
1054
- await devProc.exited;
1148
+ ge(c2.cyan(ICON.rocket + " Starting dev server\u2026"));
1149
+ await runDevWithBanner(projectPath);
1055
1150
  } else {
1056
- ge(teal(`\u25B8 Done
1057
- `) + dim(` Next steps:
1058
- `) + " " + teal("cd " + name) + `
1059
- ` + " " + teal("bun run dev") + `
1060
- `);
1151
+ const outroLines = [
1152
+ c2.bold("Done"),
1153
+ "",
1154
+ c2.dim("Next steps:"),
1155
+ " " + c2.brand("cd " + name),
1156
+ " " + c2.brand("bun run dev")
1157
+ ];
1158
+ ge(box(outroLines));
1061
1159
  }
1062
1160
  }
1063
1161
  main().catch((e2) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-flow-os",
3
- "version": "0.0.1-dev.1771667897",
3
+ "version": "0.0.1-dev.1771668924",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "create-flow-os": "bin/index.js"