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.
- package/README.md +17 -7
- package/index.mjs +69 -29
- 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
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
| `--
|
|
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.
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
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
|
|
24
|
-
\`pnpm dashral init\`, which asks a few questions (or reads
|
|
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
|
-
--
|
|
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
|
|
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 ===
|
|
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
|
|
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
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
-
|
|
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
|
+
}
|