create-ardo 2.5.0 → 2.7.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/dist/index.js CHANGED
@@ -36,9 +36,7 @@ function createProjectStructure(root, template, options) {
36
36
  GITHUB_PAGES_BASENAME: options.githubPages ? "basename: detectGitHubBasename()," : "// basename: detectGitHubBasename(), // Uncomment for GitHub Pages",
37
37
  DESCRIPTION: options.description,
38
38
  TYPEDOC_NAV: options.typedoc ? "{ text: 'API', link: '/api-reference' }," : "",
39
- TYPEDOC_SIDEBAR: options.typedoc ? "{ text: 'API Reference', link: '/api-reference' }," : "",
40
- TYPEDOC_NAVLINK: options.typedoc ? '<NavLink to="/api-reference">API</NavLink>' : "",
41
- TYPEDOC_SIDEBARLINK: options.typedoc ? '<SidebarLink to="/api-reference">API Reference</SidebarLink>' : ""
39
+ TYPEDOC_SIDEBAR: options.typedoc ? "{ text: 'API Reference', link: '/api-reference' }," : ""
42
40
  };
43
41
  copyDir(templateDir, root, vars);
44
42
  }
@@ -93,9 +91,76 @@ function detectProjectDescription(targetDir) {
93
91
  }
94
92
  return void 0;
95
93
  }
94
+ function isArdoProject(dir) {
95
+ try {
96
+ const pkgPath = path.join(dir, "package.json");
97
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
98
+ return Boolean(pkg.dependencies?.ardo);
99
+ } catch {
100
+ return false;
101
+ }
102
+ }
103
+ function upgradeProject(root) {
104
+ const templateDir = path.join(templatesRoot, "minimal");
105
+ const cliVersion = getCliVersion();
106
+ const result = { updated: [], deleted: [], skipped: [] };
107
+ const skeletonFiles = [
108
+ "app/entry.client.tsx",
109
+ "app/entry.server.tsx",
110
+ "app/root.tsx",
111
+ "tsconfig.json"
112
+ ];
113
+ for (const file of skeletonFiles) {
114
+ const src = path.join(templateDir, file);
115
+ const dest = path.join(root, file);
116
+ if (fs.existsSync(src)) {
117
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
118
+ fs.copyFileSync(src, dest);
119
+ result.updated.push(file);
120
+ } else {
121
+ result.skipped.push(file);
122
+ }
123
+ }
124
+ const userPkgPath = path.join(root, "package.json");
125
+ const templatePkgPath = path.join(templateDir, "package.json");
126
+ const userPkg = JSON.parse(fs.readFileSync(userPkgPath, "utf-8"));
127
+ const templatePkg = JSON.parse(fs.readFileSync(templatePkgPath, "utf-8"));
128
+ if (userPkg.dependencies) {
129
+ userPkg.dependencies.ardo = `^${cliVersion}`;
130
+ }
131
+ for (const [dep, version] of Object.entries(
132
+ templatePkg.dependencies || {}
133
+ )) {
134
+ if (dep === "ardo") continue;
135
+ if (!userPkg.dependencies?.[dep]) {
136
+ userPkg.dependencies = userPkg.dependencies || {};
137
+ userPkg.dependencies[dep] = version;
138
+ }
139
+ }
140
+ for (const [dep, version] of Object.entries(
141
+ templatePkg.devDependencies || {}
142
+ )) {
143
+ userPkg.devDependencies = userPkg.devDependencies || {};
144
+ userPkg.devDependencies[dep] = version;
145
+ }
146
+ fs.writeFileSync(userPkgPath, JSON.stringify(userPkg, null, 2) + "\n");
147
+ result.updated.push("package.json");
148
+ const obsoleteFiles = ["app/vite-env.d.ts"];
149
+ for (const file of obsoleteFiles) {
150
+ const filePath = path.join(root, file);
151
+ if (fs.existsSync(filePath)) {
152
+ fs.unlinkSync(filePath);
153
+ result.deleted.push(file);
154
+ }
155
+ }
156
+ return result;
157
+ }
96
158
 
97
159
  // src/index.ts
98
160
  var defaultTargetDir = "my-docs";
161
+ var onCancel = () => {
162
+ throw new Error(red("\u2716") + " Operation cancelled");
163
+ };
99
164
  async function main() {
100
165
  console.log();
101
166
  console.log(` ${cyan("\u25C6")} ${green("create-ardo")}`);
@@ -103,11 +168,10 @@ async function main() {
103
168
  const argTargetDir = process.argv[2];
104
169
  const argTemplate = process.argv[3];
105
170
  let targetDir = argTargetDir || defaultTargetDir;
106
- let template = argTemplate;
107
- const response = await prompts(
108
- [
171
+ if (!argTargetDir) {
172
+ const { projectName } = await prompts(
109
173
  {
110
- type: argTargetDir ? null : "text",
174
+ type: "text",
111
175
  name: "projectName",
112
176
  message: reset("Project name:"),
113
177
  initial: defaultTargetDir,
@@ -118,13 +182,55 @@ async function main() {
118
182
  if (!/^[a-z0-9-]+$/.test(name))
119
183
  return "Project name may only contain lowercase letters, digits, and hyphens";
120
184
  return true;
121
- },
122
- onState: (state) => {
123
- targetDir = formatTargetDir(state.value) || defaultTargetDir;
124
185
  }
125
186
  },
187
+ { onCancel }
188
+ );
189
+ targetDir = formatTargetDir(projectName) || defaultTargetDir;
190
+ }
191
+ const root = path2.join(process.cwd(), targetDir);
192
+ if (fs2.existsSync(root) && !isEmpty(root) && isArdoProject(root)) {
193
+ const cliVersion = getCliVersion();
194
+ const { action } = await prompts(
195
+ {
196
+ type: "select",
197
+ name: "action",
198
+ message: `Existing Ardo project detected. Upgrade to v${cliVersion}?`,
199
+ choices: [
200
+ { title: "Upgrade framework files", value: "upgrade" },
201
+ { title: "Cancel", value: "cancel" }
202
+ ]
203
+ },
204
+ { onCancel }
205
+ );
206
+ if (action === "cancel") {
207
+ throw new Error(red("\u2716") + " Operation cancelled");
208
+ }
209
+ console.log();
210
+ console.log(` ${cyan("Upgrading project in")} ${root}...`);
211
+ console.log();
212
+ const result = upgradeProject(root);
213
+ for (const file of result.updated) {
214
+ console.log(` ${green("\u25CF")} ${file}`);
215
+ }
216
+ for (const file of result.deleted) {
217
+ console.log(` ${yellow("\u25CF")} ${file} ${dim("(removed)")}`);
218
+ }
219
+ for (const file of result.skipped) {
220
+ console.log(` ${dim("\u25CB")} ${file} ${dim("(not found, skipped)")}`);
221
+ }
222
+ console.log();
223
+ console.log(` ${green("Done!")} Now run:`);
224
+ console.log();
225
+ console.log(` ${blue("pnpm install")}`);
226
+ console.log();
227
+ return;
228
+ }
229
+ let template = argTemplate;
230
+ const response = await prompts(
231
+ [
126
232
  {
127
- type: () => !fs2.existsSync(targetDir) || isEmpty(targetDir) ? null : "select",
233
+ type: () => !fs2.existsSync(root) || isEmpty(root) ? null : "select",
128
234
  name: "overwrite",
129
235
  message: () => `${targetDir === "." ? "Current directory" : `Target directory "${targetDir}"`} is not empty. How would you like to proceed?`,
130
236
  choices: [
@@ -188,15 +294,10 @@ async function main() {
188
294
  ]
189
295
  }
190
296
  ],
191
- {
192
- onCancel: () => {
193
- throw new Error(red("\u2716") + " Operation cancelled");
194
- }
195
- }
297
+ { onCancel }
196
298
  );
197
299
  const { overwrite, template: templateChoice, siteTitle, docType, githubPages } = response;
198
300
  template = templateChoice || template || "minimal";
199
- const root = path2.join(process.cwd(), targetDir);
200
301
  if (overwrite === "yes") {
201
302
  emptyDir(root);
202
303
  } else if (!fs2.existsSync(root)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-ardo",
3
- "version": "2.5.0",
3
+ "version": "2.7.0",
4
4
  "description": "Scaffolding tool for Ardo documentation projects",
5
5
  "type": "module",
6
6
  "bin": {
@@ -24,7 +24,7 @@
24
24
  "url": "https://github.com/sebastian-software/ardo.git",
25
25
  "directory": "packages/create-ardo"
26
26
  },
27
- "homepage": "https://sebastian-software.github.io/ardo/",
27
+ "homepage": "https://ardo-docs.dev",
28
28
  "bugs": {
29
29
  "url": "https://github.com/sebastian-software/ardo/issues"
30
30
  },
@@ -1,84 +1,15 @@
1
- import { Links, Meta, Outlet, Scripts, ScrollRestoration, useLocation } from "react-router"
2
- import {
3
- Layout as ArdoLayout,
4
- Header,
5
- Nav,
6
- NavLink,
7
- Sidebar,
8
- SidebarGroup,
9
- SidebarLink,
10
- Footer,
11
- } from "ardo/ui"
12
- import { PressProvider } from "ardo/runtime"
1
+ import { RootLayout, ArdoRoot } from "ardo/ui"
13
2
  import config from "virtual:ardo/config"
14
3
  import sidebar from "virtual:ardo/sidebar"
4
+ import type { MetaFunction } from "react-router"
15
5
  import "ardo/ui/styles.css"
16
6
 
7
+ export const meta: MetaFunction = () => [{ title: config.title }]
8
+
17
9
  export function Layout({ children }: { children: React.ReactNode }) {
18
- return (
19
- <html lang="en" suppressHydrationWarning>
20
- <head>
21
- <meta charSet="utf-8" />
22
- <meta name="viewport" content="width=device-width, initial-scale=1" />
23
- <Meta />
24
- <Links />
25
- </head>
26
- <body suppressHydrationWarning>
27
- {children}
28
- <ScrollRestoration />
29
- <Scripts />
30
- </body>
31
- </html>
32
- )
10
+ return <RootLayout>{children}</RootLayout>
33
11
  }
34
12
 
35
13
  export default function Root() {
36
- const location = useLocation()
37
- const isHomePage = location.pathname === "/"
38
-
39
- return (
40
- <PressProvider config={config} sidebar={sidebar}>
41
- <ArdoLayout
42
- className={isHomePage ? "ardo-layout ardo-home" : "ardo-layout"}
43
- header={
44
- <Header
45
- title="{{SITE_TITLE}}"
46
- nav={
47
- <Nav>
48
- <NavLink to="/guide/getting-started">Guide</NavLink>
49
- {{TYPEDOC_NAVLINK}}
50
- </Nav>
51
- }
52
- />
53
- }
54
- sidebar={
55
- isHomePage ? undefined : (
56
- <Sidebar>
57
- <SidebarGroup title="Guide">
58
- <SidebarLink to="/guide/getting-started">Getting Started</SidebarLink>
59
- </SidebarGroup>
60
- {{TYPEDOC_SIDEBARLINK}}
61
- </Sidebar>
62
- )
63
- }
64
- footer={
65
- <Footer
66
- message={[
67
- config.project?.homepage
68
- ? `<a href="${config.project.homepage}">${config.title}</a>`
69
- : config.title,
70
- "Built with <a href='https://github.com/sebastian-software/ardo'>Ardo</a>",
71
- ].join(" &middot; ")}
72
- copyright={
73
- config.project?.author
74
- ? `Copyright &copy; ${new Date().getFullYear()} ${config.project.author}`
75
- : undefined
76
- }
77
- />
78
- }
79
- >
80
- <Outlet />
81
- </ArdoLayout>
82
- </PressProvider>
83
- )
14
+ return <ArdoRoot config={config} sidebar={sidebar} />
84
15
  }
@@ -34,5 +34,5 @@ Edit `vite.config.ts` to customize your site:
34
34
 
35
35
  ## Learn More
36
36
 
37
- - [Ardo Documentation](https://sebastian-software.github.io/ardo/)
37
+ - [Ardo Documentation](https://ardo-docs.dev)
38
38
  - [GitHub Repository](https://github.com/sebastian-software/ardo)
@@ -1,5 +1,10 @@
1
1
  import { Hero, Features } from "ardo/ui"
2
2
  import { Zap, Sparkles, Palette, ArrowRight, Github } from "ardo/icons"
3
+ import type { MetaFunction } from "react-router"
4
+
5
+ export const meta: MetaFunction = () => [
6
+ { title: "{{SITE_TITLE}}" },
7
+ ]
3
8
 
4
9
  export default function HomePage() {
5
10
  return (
@@ -11,7 +11,8 @@
11
11
  "esModuleInterop": true,
12
12
  "skipLibCheck": true,
13
13
  "forceConsistentCasingInFileNames": true,
14
- "jsx": "react-jsx"
14
+ "jsx": "react-jsx",
15
+ "types": ["vite/client", "ardo/virtual"]
15
16
  },
16
17
  "include": ["app/**/*", "*.ts", "*.config.ts"],
17
18
  "exclude": ["node_modules", "build"]
@@ -28,7 +28,7 @@ export default defineConfig({
28
28
  ],
29
29
 
30
30
  footer: {
31
- message: 'Built with Ardo',
31
+ message: 'Released under the MIT License.',
32
32
  },
33
33
 
34
34
  search: {
@@ -1,13 +0,0 @@
1
- /// <reference types="vite/client" />
2
-
3
- declare module "virtual:ardo/config" {
4
- import type { PressConfig } from "ardo"
5
- const config: PressConfig
6
- export default config
7
- }
8
-
9
- declare module "virtual:ardo/sidebar" {
10
- import type { SidebarItem } from "ardo"
11
- const sidebar: SidebarItem[]
12
- export default sidebar
13
- }