create-dashral 0.2.2 → 0.2.3

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 (3) hide show
  1. package/README.md +1 -1
  2. package/index.mjs +57 -9
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -35,7 +35,7 @@ The theme customizer's **Copy setup command** in the [live demo](https://demo.da
35
35
  | Option | |
36
36
  | --- | --- |
37
37
  | `--monorepo` | Keep Dashral's whole repository (`apps/`, `packages/`) and history instead, so `pnpm dashral update` can bring in later releases, pages too ([Getting updates](https://github.com/hasralgana/dashral#getting-updates)) |
38
- | `--pro` | Start from Dashral Pro (your GitHub account needs access to it; monorepo for now) |
38
+ | `--pro` | Start from Dashral Pro, as the monorepo, so `pnpm dashral update` brings in new apps and their database migrations. It's a private repository: accept the invitation GitHub emailed you, then let Git sign in to GitHub once with `gh auth login` (or use `--from` with SSH) |
39
39
  | `--release v1.2.0` | An earlier release instead of the newest |
40
40
  | `--from <url>` | Clone another repository, e.g. a fork, or Pro over SSH |
41
41
  | `--no-install` | Skip `pnpm install` |
package/index.mjs CHANGED
@@ -30,7 +30,8 @@ const help = `Usage: npx create-dashral [folder] [options]
30
30
  Options of create-dashral:
31
31
  --monorepo Keep the whole repository (apps/, packages/) and its history, to bring in later releases
32
32
  with \`pnpm dashral update\`
33
- --pro Start from Dashral Pro (your GitHub account needs access to the repository; monorepo for now)
33
+ --pro Start from Dashral Pro: its private repository, as the monorepo, so \`pnpm dashral update\` brings
34
+ in new apps and their database migrations (Git needs to sign in to GitHub: see below)
34
35
  --release v1.2.0 An earlier release instead of the newest
35
36
  --from <url> Clone another repository (a fork, or Pro over SSH: git@github.com:dashral-ui/dashral-pro.git)
36
37
  --no-install Set up only; run \`pnpm install\` yourself
@@ -40,6 +41,9 @@ Every other option goes to \`pnpm dashral init\`:
40
41
  --name "Your App" --primary --light --dark --card --radius --font --yes
41
42
  Pro: --apps all|crm,kanban,… --samples keep|remove
42
43
 
44
+ Dashral Pro: accept the repository invitation GitHub emailed you, then let Git sign in to GitHub once, with the
45
+ GitHub CLI (\`gh auth login\`) or over SSH (\`--from git@github.com:dashral-ui/dashral-pro.git\`).
46
+
43
47
  The theme customizer's "Copy setup command" at https://demo.dashral.com writes these flags for you.
44
48
  Docs: https://dashral.com/docs/installation`
45
49
 
@@ -79,20 +83,28 @@ function fail(message) {
79
83
  exit(1)
80
84
  }
81
85
 
86
+ // Git never stops to ask for a username and password in the terminal (GitHub doesn't take passwords anyway): a
87
+ // credential helper that's set up (the GitHub CLI, Git Credential Manager, the macOS keychain) still signs in, and
88
+ // without one Git fails at once, so we can say what to do.
89
+ const gitEnv = { GIT_TERMINAL_PROMPT: "0" }
90
+
82
91
  /** Runs a command in the terminal (its output and questions shown as they come); its exit code, or null. */
83
92
  function run(command, args, cwd, quiet = false) {
84
93
  // Windows runs pnpm through a .cmd shim, which needs a shell. DASHRAL_CREATE: init leaves the next steps to us.
85
- const env = { ...process.env, DASHRAL_CREATE: "1" }
94
+ const env = { ...process.env, ...gitEnv, DASHRAL_CREATE: "1" }
86
95
  const result = spawnSync(command, args, { cwd, env, stdio: quiet ? "ignore" : "inherit", shell: platform === "win32" })
87
96
  return result.error ? null : result.status
88
97
  }
89
98
 
90
- /** A command's output, or null when it can't run. */
91
- function output(command, args) {
92
- const result = spawnSync(command, args, { encoding: "utf8", shell: platform === "win32" })
93
- return result.status === 0 ? result.stdout.trim() : null
99
+ /** A command's output (null when it fails) and what it printed as errors. */
100
+ function capture(command, args) {
101
+ const result = spawnSync(command, args, { encoding: "utf8", env: { ...process.env, ...gitEnv }, shell: platform === "win32" })
102
+ return { out: result.status === 0 ? result.stdout.trim() : null, err: `${result.stderr ?? ""}${result.error?.message ?? ""}` }
94
103
  }
95
104
 
105
+ /** A command's output, or null when it can't run. */
106
+ const output = (command, args) => capture(command, args).out
107
+
96
108
  const versionOf = (tag) => tag.slice(1).split(".").map(Number)
97
109
  const newer = (a, b) => {
98
110
  const [x, y] = [versionOf(a), versionOf(b)]
@@ -139,12 +151,35 @@ const target = resolve(folder)
139
151
  if (existsSync(target) && readdirSync(target).length) fail(`${folder} isn't empty. Pick a new folder.`)
140
152
 
141
153
  const url = own.from ?? (own.pro ? repos.pro : repos.free)
154
+ const ssh = /^(git@|ssh:\/\/)/.test(url)
155
+ const proRepo = repos.pro.replace(/\.git$/, "")
142
156
  const access = own.pro ? " Check that your GitHub account has access to Dashral Pro (accept the invitation GitHub emailed you)." : ""
143
157
 
158
+ /** Why Git couldn't reach the repository, and what to do, from what it printed. */
159
+ function unreachable(err) {
160
+ if (/could not resolve host|unable to access.*(timed out|resolve)|network is unreachable/i.test(err)) {
161
+ return `Couldn't reach GitHub. Check your internet connection and run this again.`
162
+ }
163
+ if (!own.pro) return `Couldn't reach ${url}.${err.trim() ? `\n Git said: ${err.trim().split("\n").at(-1)}` : ""}`
164
+ if (ssh) {
165
+ return `Git couldn't open Dashral Pro over SSH. Check that:
166
+ 1. You accepted the invitation: ${proRepo}/invitations
167
+ 2. Your SSH key is on that GitHub account (\`ssh -T git@github.com\` greets you by name).`
168
+ }
169
+ return `Git couldn't open Dashral Pro: it's a private repository, so Git has to sign in to GitHub as the account that has access.
170
+ 1. Accept the invitation (sent to the GitHub account you connected on Polar): ${proRepo}/invitations
171
+ 2. Let Git sign in to GitHub once. The simplest way is the GitHub CLI (https://cli.github.com):
172
+ gh auth login (choose HTTPS, and yes to authenticate Git)
173
+ Or use SSH if your key is on GitHub:
174
+ npx create-dashral ${folder} --pro --from git@github.com:dashral-ui/dashral-pro.git
175
+ 3. Run this again. Stuck? Write to hello@dashral.com.`
176
+ }
177
+
144
178
  // The release: the newest version tag, or the one --release names.
179
+ if (own.pro) console.log(`Dashral Pro is a private repository: Git signs in to GitHub as the account you connected on Polar.`)
145
180
  console.log(`Looking for the releases of ${url}…`)
146
- const listed = output("git", ["ls-remote", "--tags", "--refs", url, "v*"])
147
- if (listed === null) fail(`Couldn't reach ${url}.${access}`)
181
+ const { out: listed, err: listError } = capture("git", ["ls-remote", "--tags", "--refs", url, "v*"])
182
+ if (listed === null) fail(unreachable(listError))
148
183
  const tags = listed
149
184
  .split("\n")
150
185
  .map((line) => line.split("refs/tags/")[1])
@@ -159,7 +194,9 @@ if (!release) fail(`${url} has no releases yet.`)
159
194
 
160
195
  let flat = !own.monorepo
161
196
  if (flat && own.pro) {
162
- console.log(" Dashral Pro starts as the monorepo for now (a project of its own is coming).")
197
+ // Pro's updates are mostly its apps (new dashboards, fixes, database migrations): only the repository's history
198
+ // lets `pnpm dashral update` merge them into a project. Pro blocks for an app you already have: the shadcn CLI.
199
+ console.log(" Dashral Pro is set up as the monorepo, so `pnpm dashral update` can bring in new apps and their migrations.")
163
200
  flat = false
164
201
  }
165
202
 
@@ -196,6 +233,17 @@ Your dashboard is in ${folder}:
196
233
  } else {
197
234
  // A tag checks out without a branch: start yours, so your commits have one.
198
235
  if (run("git", ["switch", "--quiet", "-c", "main"], target) !== 0) fail("Couldn't start the main branch.")
236
+ if (own.pro && !own.install) {
237
+ // Pro's setup rebuilds the database migrations for the apps you keep, with drizzle-kit: it needs the install first.
238
+ const quote = (arg) => (/^[\w@%+=:,./-]+$/.test(arg) ? arg : `"${arg.replace(/(["\\$`])/g, "\\$1")}"`)
239
+ console.log(`
240
+ Dashral Pro is in ${folder}. Its setup needs the dependencies, so finish with:
241
+ cd ${folder}
242
+ pnpm install
243
+ pnpm dashral init${rest.length ? ` ${rest.map(quote).join(" ")}` : ""}
244
+ pnpm dev`)
245
+ exit(0)
246
+ }
199
247
  if (own.install) {
200
248
  console.log("\nInstalling the dependencies…")
201
249
  if (run("pnpm", ["install"], target) !== 0) fail(`pnpm install stopped. Fix what it says, then in ${folder}: pnpm install && pnpm dashral init`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-dashral",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Start a new Dashral admin dashboard (Next.js, React, Tailwind CSS) in one command.",
5
5
  "license": "MIT",
6
6
  "type": "module",