create-dashral 0.1.0 → 0.2.0

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 +17 -7
  2. package/index.mjs +69 -29
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -8,9 +8,21 @@ cd my-app
8
8
  pnpm dev
9
9
  ```
10
10
 
11
- It clones Dashral's newest release into `my-app`, installs the dependencies and runs `pnpm dashral init`. That asks
12
- which template to keep (Classic, Inset or both), demo pages or a blank page, the languages, your app's name and its
13
- look. You need **Node.js 20+**, **Git** and **pnpm** (`corepack enable pnpm`).
11
+ It asks which template to keep (Classic, Inset or both), demo pages or a blank page, the languages, your app's name
12
+ and its look, then makes a Next.js project laid out like a new Next.js app, with its own Git history:
13
+
14
+ ```
15
+ my-app/
16
+ ├── app/ pages
17
+ ├── components/ the app's own components
18
+ ├── lib/ messages/ public/
19
+ ├── package.json "@dashral/ui" from npm
20
+ └── next.config.ts tsconfig.json
21
+ ```
22
+
23
+ The UI components come from [`@dashral/ui`](https://www.npmjs.com/package/@dashral/ui)
24
+ (`import { Button } from "@dashral/ui/components/button"`): `pnpm up @dashral/ui` brings in new ones and fixes. You need
25
+ **Node.js 20+**, **Git** and **pnpm** (`corepack enable pnpm`).
14
26
 
15
27
  Every answer is also a flag, so it can run without questions:
16
28
 
@@ -22,14 +34,12 @@ The theme customizer's **Copy setup command** in the [live demo](https://demo.da
22
34
 
23
35
  | Option | |
24
36
  | --- | --- |
25
- | `--pro` | Start from Dashral Pro (your GitHub account needs access to it) |
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) |
26
39
  | `--release v1.2.0` | An earlier release instead of the newest |
27
40
  | `--from <url>` | Clone another repository, e.g. a fork, or Pro over SSH |
28
41
  | `--no-install` | Skip `pnpm install` |
29
42
 
30
43
  Any other option goes to `pnpm dashral init`; `npx create-dashral --help` lists them.
31
44
 
32
- The project keeps the release's Git history, so later releases come in with `pnpm dashral update`. See
33
- [Getting updates](https://github.com/hasralgana/dashral#getting-updates).
34
-
35
45
  MIT licensed.
package/index.mjs CHANGED
@@ -1,16 +1,19 @@
1
1
  #!/usr/bin/env node
2
- // `npx create-dashral my-app`: a new dashboard from Dashral's newest release, in one command. It clones the repository
3
- // at the release's tag (with its history, so `pnpm dashral update` can merge later releases), installs the
4
- // dependencies, then runs the repository's own `pnpm dashral init` with every other flag you passed. Nothing about the
5
- // setup lives here: the release's scripts/dashral.mjs does it, so this file rarely needs a new version.
2
+ // `npx create-dashral my-app`: a new dashboard from Dashral's newest release, in one command. By default it makes a
3
+ // Next.js project of its own, like `create-next-app`: the release is cloned, `pnpm dashral init --layout flat` keeps
4
+ // only the app (the components come from npm as @dashral/ui), the project starts a Git history of its own and its
5
+ // dependencies are installed. With --monorepo it keeps the repository's layout and history instead, for
6
+ // `pnpm dashral update`. Nothing about the setup lives here: the release's scripts/dashral.mjs does it, so this file
7
+ // rarely needs a new version.
6
8
  //
7
9
  // npx create-dashral my-app
8
10
  // npx create-dashral my-app --template inset --pages blank --languages en --name "Acme" --primary indigo
11
+ // npx create-dashral my-app --monorepo (the whole repository, for pnpm dashral update)
9
12
  // npx create-dashral my-app --pro --apps crm,kanban --name "Acme" (Dashral Pro: needs your GitHub access)
10
13
 
11
14
  import { spawnSync } from "node:child_process"
12
- import { existsSync, readdirSync } from "node:fs"
13
- import { resolve } from "node:path"
15
+ import { existsSync, readdirSync, readFileSync, rmSync } from "node:fs"
16
+ import { join, resolve } from "node:path"
14
17
  import { argv, exit, platform, versions } from "node:process"
15
18
 
16
19
  const repos = {
@@ -20,14 +23,16 @@ const repos = {
20
23
 
21
24
  const help = `Usage: npx create-dashral <folder> [options]
22
25
 
23
- Starts a new dashboard in <folder> from Dashral's newest release: clones it, installs the dependencies and runs
24
- \`pnpm dashral init\`, which asks a few questions (or reads them from the flags below).
26
+ Starts a new Next.js dashboard in <folder> from Dashral's newest release, as a project of its own (the components
27
+ come from npm as @dashral/ui), and runs \`pnpm dashral init\`, which asks a few questions (or reads the flags below).
25
28
 
26
29
  Options of create-dashral:
27
- --pro Start from Dashral Pro (your GitHub account needs access to the repository)
30
+ --monorepo Keep the whole repository (apps/, packages/) and its history, to bring in later releases
31
+ with \`pnpm dashral update\`
32
+ --pro Start from Dashral Pro (your GitHub account needs access to the repository; monorepo for now)
28
33
  --release v1.2.0 An earlier release instead of the newest
29
34
  --from <url> Clone another repository (a fork, or Pro over SSH: git@github.com:hasralgana/dashral-pro.git)
30
- --no-install Clone and set up only; run \`pnpm install\` yourself
35
+ --no-install Set up only; run \`pnpm install\` yourself
31
36
 
32
37
  Every other option goes to \`pnpm dashral init\`:
33
38
  --template classic|inset|both --pages demo|blank --languages all|en --customizer keep|remove
@@ -41,7 +46,7 @@ Docs: https://dashral.com/docs/installation`
41
46
 
42
47
  /** This script's own flags, and the rest passed to `dashral init` as they were typed. */
43
48
  function parseArgs(args) {
44
- const own = { pro: false, install: true, release: null, from: null, help: false }
49
+ const own = { pro: false, monorepo: false, install: true, release: null, from: null, help: false }
45
50
  const rest = []
46
51
  let folder = null
47
52
  for (let i = 0; i < args.length; i++) {
@@ -50,11 +55,13 @@ function parseArgs(args) {
50
55
  const value = () => (inline !== undefined ? inline : args[++i])
51
56
  if (arg === "-h" || key === "help") own.help = true
52
57
  else if (key === "pro") own.pro = true
58
+ else if (key === "monorepo") own.monorepo = true
53
59
  else if (key === "no-install") own.install = false
54
60
  else if (key === "release" || key === "from") {
55
61
  own[key] = value()
56
62
  if (!own[key] || own[key].startsWith("--")) fail(`--${key} needs a value.`)
57
- } else if (key === null && folder === null) folder = arg
63
+ } else if (key === "layout") fail("Use --monorepo for the repository's layout; the project is flat without it.")
64
+ else if (key === null && folder === null) folder = arg
58
65
  else rest.push(arg)
59
66
  }
60
67
  return { folder, own, rest }
@@ -68,9 +75,10 @@ function fail(message) {
68
75
  }
69
76
 
70
77
  /** Runs a command in the terminal (its output and questions shown as they come); its exit code, or null. */
71
- function run(command, args, cwd) {
72
- // Windows runs pnpm through a .cmd shim, which needs a shell.
73
- const result = spawnSync(command, args, { cwd, stdio: "inherit", shell: platform === "win32" })
78
+ function run(command, args, cwd, quiet = false) {
79
+ // Windows runs pnpm through a .cmd shim, which needs a shell. DASHRAL_CREATE: init leaves the next steps to us.
80
+ const env = { ...process.env, DASHRAL_CREATE: "1" }
81
+ const result = spawnSync(command, args, { cwd, env, stdio: quiet ? "ignore" : "inherit", shell: platform === "win32" })
74
82
  return result.error ? null : result.status
75
83
  }
76
84
 
@@ -123,23 +131,55 @@ if (own.release) {
123
131
  }
124
132
  if (!release) fail(`${url} has no releases yet.`)
125
133
 
126
- // The whole history, not a shallow copy: `pnpm dashral update` merges later releases into it.
127
- console.log(`\nCloning Dashral ${release} into ${folder}…`)
128
- if (run("git", ["clone", "--quiet", "--branch", release, url, target]) !== 0) fail(`Couldn't clone ${url}.${access}`)
129
- // A tag checks out without a branch: start yours, so your commits have one.
130
- if (run("git", ["switch", "--quiet", "-c", "main"], target) !== 0) fail("Couldn't start the main branch.")
131
-
132
- if (own.install) {
133
- console.log("\nInstalling the dependencies…")
134
- if (run("pnpm", ["install"], target) !== 0) fail(`pnpm install stopped. Fix what it says, then in ${folder}: pnpm install && pnpm dashral init`)
134
+ let flat = !own.monorepo
135
+ if (flat && own.pro) {
136
+ console.log(" Dashral Pro starts as the monorepo for now (a project of its own is coming).")
137
+ flat = false
135
138
  }
136
139
 
137
- console.log("")
138
- if (run("node", ["scripts/dashral.mjs", "init", ...rest], target) !== 0) {
139
- fail(`The setup stopped. It's a fresh clone, so you can delete ${folder} and start again, or fix what it says and run \`pnpm dashral init\` in it.`)
140
+ // Flat: the files are enough. The monorepo keeps the whole history: `pnpm dashral update` merges later releases into it.
141
+ console.log(`\nCloning Dashral ${release} into ${folder}…`)
142
+ const depth = flat ? ["--depth", "1"] : []
143
+ if (run("git", ["-c", "advice.detachedHead=false", "clone", "--quiet", ...depth, "--branch", release, url, target]) !== 0) fail(`Couldn't clone ${url}.${access}`)
144
+ if (flat && !readFileSync(join(target, "scripts/dashral.mjs"), "utf8").includes("--layout")) {
145
+ // A release from before the flat layout: set it up as the monorepo.
146
+ console.log(` ${release} predates the flat layout, so it's set up as the monorepo.`)
147
+ flat = false
148
+ rmSync(target, { recursive: true, force: true })
149
+ if (run("git", ["-c", "advice.detachedHead=false", "clone", "--quiet", "--branch", release, url, target]) !== 0) fail(`Couldn't clone ${url}.${access}`)
140
150
  }
141
-
142
- console.log(`
151
+ const restart = `It's a fresh copy, so you can delete ${folder} and start again.`
152
+
153
+ if (flat) {
154
+ // Setting up needs no dependencies: install once, in the project as it ends up.
155
+ console.log("")
156
+ if (run("node", ["scripts/dashral.mjs", "init", "--layout", "flat", ...rest], target) !== 0) fail(`The setup stopped. ${restart}`)
157
+ // The project's own history, from its first commit.
158
+ rmSync(join(target, ".git"), { recursive: true, force: true })
159
+ run("git", ["init", "--quiet", "-b", "main"], target)
160
+ if (own.install) {
161
+ console.log("\nInstalling the dependencies…")
162
+ if (run("pnpm", ["install"], target) !== 0) fail(`pnpm install stopped. Fix what it says, then run \`pnpm install\` in ${folder}.`)
163
+ }
164
+ run("git", ["add", "-A"], target, true)
165
+ const committed = run("git", ["commit", "--quiet", "-m", "Initial commit from create-dashral"], target, true) === 0
166
+ console.log(`
167
+ Your dashboard is in ${folder}:
168
+ cd ${folder}${own.install ? "" : "\n pnpm install"}
169
+ pnpm dev${committed ? "" : "\n\n(Git has no name and email here yet, so nothing was committed: commit when you're ready.)"}`)
170
+ } else {
171
+ // A tag checks out without a branch: start yours, so your commits have one.
172
+ if (run("git", ["switch", "--quiet", "-c", "main"], target) !== 0) fail("Couldn't start the main branch.")
173
+ if (own.install) {
174
+ console.log("\nInstalling the dependencies…")
175
+ if (run("pnpm", ["install"], target) !== 0) fail(`pnpm install stopped. Fix what it says, then in ${folder}: pnpm install && pnpm dashral init`)
176
+ }
177
+ console.log("")
178
+ if (run("node", ["scripts/dashral.mjs", "init", ...rest], target) !== 0) {
179
+ fail(`The setup stopped. ${restart} Or fix what it says and run \`pnpm dashral init\` in it.`)
180
+ }
181
+ console.log(`
143
182
  Your dashboard is in ${folder}:
144
183
  cd ${folder}${own.install ? "" : "\n pnpm install"}
145
184
  pnpm dev`)
185
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-dashral",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
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",