@heyo-sh/create-heyo-docs 0.1.1 → 0.2.1

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 (45) hide show
  1. package/README.md +44 -0
  2. package/dist/index.d.ts +13 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +349 -0
  5. package/dist/package-manager.d.ts +6 -0
  6. package/dist/package-manager.d.ts.map +1 -0
  7. package/dist/project-name.d.ts +3 -0
  8. package/dist/project-name.d.ts.map +1 -0
  9. package/dist/scaffold.d.ts +5 -0
  10. package/dist/scaffold.d.ts.map +1 -0
  11. package/dist/types.d.ts +19 -0
  12. package/dist/types.d.ts.map +1 -0
  13. package/dist/utils.d.ts +8 -0
  14. package/dist/utils.d.ts.map +1 -0
  15. package/package.json +5 -2
  16. package/templates/astro/content/configuration.mdx +76 -0
  17. package/templates/astro/content/deploying.mdx +57 -0
  18. package/templates/astro/content/essentials/callouts.mdx +36 -0
  19. package/templates/astro/content/essentials/code-blocks.mdx +51 -0
  20. package/templates/astro/content/essentials/lists.mdx +40 -0
  21. package/templates/astro/content/essentials/tables.mdx +37 -0
  22. package/templates/astro/content/essentials/tabs.mdx +42 -0
  23. package/templates/astro/content/essentials/text-styling.mdx +50 -0
  24. package/templates/astro/content/quickstart.mdx +60 -0
  25. package/templates/astro/heyo-docs.config.ts +24 -2
  26. package/templates/next/content/configuration.mdx +76 -0
  27. package/templates/next/content/deploying.mdx +57 -0
  28. package/templates/next/content/essentials/callouts.mdx +36 -0
  29. package/templates/next/content/essentials/code-blocks.mdx +51 -0
  30. package/templates/next/content/essentials/lists.mdx +40 -0
  31. package/templates/next/content/essentials/tables.mdx +37 -0
  32. package/templates/next/content/essentials/tabs.mdx +42 -0
  33. package/templates/next/content/essentials/text-styling.mdx +50 -0
  34. package/templates/next/content/quickstart.mdx +60 -0
  35. package/templates/next/heyo-docs.config.ts +24 -2
  36. package/templates/react-router/content/configuration.mdx +76 -0
  37. package/templates/react-router/content/deploying.mdx +57 -0
  38. package/templates/react-router/content/essentials/callouts.mdx +36 -0
  39. package/templates/react-router/content/essentials/code-blocks.mdx +51 -0
  40. package/templates/react-router/content/essentials/lists.mdx +40 -0
  41. package/templates/react-router/content/essentials/tables.mdx +37 -0
  42. package/templates/react-router/content/essentials/tabs.mdx +42 -0
  43. package/templates/react-router/content/essentials/text-styling.mdx +50 -0
  44. package/templates/react-router/content/quickstart.mdx +60 -0
  45. package/templates/react-router/heyo-docs.config.ts +24 -2
package/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Create Heyo Docs
2
+
3
+ Create a standalone, production-ready documentation site with Heyo Docs. Choose React Router, Next.js, or Astro, plus a built-in theme and deployment target.
4
+
5
+ ## Create a project
6
+
7
+ Run the creator without arguments to choose the project directory, framework,
8
+ deployment target, theme, and package manager interactively. It prints the
9
+ appropriate `cd` and development-server commands when it finishes.
10
+
11
+ ```bash
12
+ # pnpm
13
+ pnpm create @heyo-sh/heyo-docs
14
+
15
+ # npm
16
+ npm create @heyo-sh/heyo-docs@latest
17
+
18
+ # Yarn
19
+ yarn dlx @heyo-sh/create-heyo-docs
20
+
21
+ # Bun
22
+ bun create @heyo-sh/heyo-docs
23
+ ```
24
+
25
+ The creator works with pnpm, npm, Yarn, and Bun.
26
+
27
+ ## Options
28
+
29
+ Passing options makes the creator non-interactive; include a project-directory
30
+ argument when using them in automation.
31
+
32
+ | Option | Values |
33
+ | ------------------- | ------------------------------- |
34
+ | `--template` | `react-router`, `next`, `astro` |
35
+ | `--theme` | `grain`, `shade`, `moss` |
36
+ | `--deployment` | `cloudflare`, `vercel`, `later` |
37
+ | `--package-manager` | `bun`, `pnpm`, `npm`, `yarn` |
38
+ | `--no-install` | Skip dependency installation |
39
+
40
+ Read the [full documentation](https://docs.heyo.sh) for configuration, content, components, framework integrations, and deployment.
41
+
42
+ ## License
43
+
44
+ [MIT](https://github.com/heyo-sh/heyo-docs/blob/main/LICENSE)
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import type { CreateOptions } from "./types";
3
+ export { detectPackageManager, packageManagerField, packageManagerRunCommand, } from "./package-manager";
4
+ export { scaffoldProject } from "./scaffold";
5
+ export { mergePackageJson, replacePlaceholders } from "./utils";
6
+ export type * from "./types";
7
+ export declare function run(argv?: string[]): Promise<void>;
8
+ export declare function parseArguments(argv: string[]): {
9
+ options: CreateOptions;
10
+ interactive: boolean;
11
+ showHelp: boolean;
12
+ };
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAChE,mBAAmB,SAAS,CAAC;AAqD7B,wBAAsB,GAAG,CAAC,IAAI,WAAwB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBrE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAC9C,OAAO,EAAE,aAAa,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAsDA"}
package/dist/index.js ADDED
@@ -0,0 +1,349 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { realpathSync } from "node:fs";
5
+ import { fileURLToPath } from "node:url";
6
+ import * as p from "@clack/prompts";
7
+
8
+ // src/package-manager.ts
9
+ import { spawnSync } from "node:child_process";
10
+ var FALLBACK_VERSIONS = {
11
+ bun: "1.3.1",
12
+ pnpm: "10.17.0",
13
+ npm: "11.6.0",
14
+ yarn: "4.9.4"
15
+ };
16
+ function detectPackageManager(userAgent = process.env.npm_config_user_agent ?? "") {
17
+ const match = userAgent.match(/(?:^|\s)(bun|pnpm|npm|yarn)\/([^\s]+)/);
18
+ if (!match)
19
+ return { name: "npm" };
20
+ return { name: match[1], version: match[2] };
21
+ }
22
+ function packageManagerField(manager, detected = detectPackageManager()) {
23
+ if (manager === detected.name && detected.version)
24
+ return `${manager}@${detected.version}`;
25
+ const executable = manager === "yarn" ? "yarn" : manager;
26
+ try {
27
+ const result = spawnSync(executable, ["--version"], {
28
+ encoding: "utf8"
29
+ });
30
+ const version = result.stdout?.trim();
31
+ if (result.status === 0 && version && /^\d+(?:\.\d+)+/.test(version))
32
+ return `${manager}@${version}`;
33
+ } catch {}
34
+ return `${manager}@${FALLBACK_VERSIONS[manager]}`;
35
+ }
36
+ function packageManagerInstallCommand(manager) {
37
+ return manager === "yarn" ? ["yarn"] : [manager, "install"];
38
+ }
39
+ function packageManagerRunCommand(manager, script) {
40
+ if (manager === "npm")
41
+ return `npm run ${script}`;
42
+ if (manager === "yarn")
43
+ return `yarn ${script}`;
44
+ return `${manager} run ${script}`;
45
+ }
46
+
47
+ // src/project-name.ts
48
+ var PROJECT_NAME_PATTERN = /^[a-z0-9][a-z0-9-]*$/i;
49
+ function projectNameError(value) {
50
+ if (!value.trim())
51
+ return "Enter a project name.";
52
+ if (!PROJECT_NAME_PATTERN.test(value))
53
+ return "Use letters, numbers and hyphens only.";
54
+ }
55
+ function assertProjectName(value) {
56
+ const error = projectNameError(value);
57
+ if (error)
58
+ throw new Error(error);
59
+ return value.trim();
60
+ }
61
+
62
+ // src/scaffold.ts
63
+ import { spawn } from "node:child_process";
64
+ import { existsSync } from "node:fs";
65
+ import { mkdir as mkdir2, readdir as readdir2 } from "node:fs/promises";
66
+ import { join as join2, resolve } from "node:path";
67
+
68
+ // src/utils.ts
69
+ import {
70
+ cp,
71
+ mkdir,
72
+ readFile,
73
+ readdir,
74
+ rm,
75
+ stat,
76
+ writeFile
77
+ } from "node:fs/promises";
78
+ import { dirname, join } from "node:path";
79
+ function replacePlaceholders(source, values) {
80
+ return source.replace(/\{\{([A-Z0-9_]+)\}\}/g, (placeholder, key) => values[key] ?? placeholder);
81
+ }
82
+ function mergePackageJson(base, overlay) {
83
+ const merged = { ...base };
84
+ for (const [key, value] of Object.entries(overlay)) {
85
+ const current = merged[key];
86
+ if (isRecord(current) && isRecord(value))
87
+ merged[key] = mergePackageJson(current, value);
88
+ else
89
+ merged[key] = value;
90
+ }
91
+ return merged;
92
+ }
93
+ async function copyTemplate(source, destination, placeholders) {
94
+ await cp(source, destination, { recursive: true, force: true });
95
+ await replacePlaceholdersAtPath(destination, placeholders);
96
+ }
97
+ async function replacePlaceholdersAtPath(path, values) {
98
+ if (!(await stat(path)).isDirectory()) {
99
+ const contents = await readFile(path, "utf8");
100
+ await writeFile(path, replacePlaceholders(contents, values));
101
+ return;
102
+ }
103
+ const entries = await readdir(path, { withFileTypes: true });
104
+ await Promise.all(entries.map((entry) => replacePlaceholdersAtPath(join(path, entry.name), values)));
105
+ }
106
+ async function writeJson(path, data) {
107
+ await mkdir(dirname(path), { recursive: true });
108
+ await writeFile(path, `${JSON.stringify(data, null, 2)}
109
+ `);
110
+ }
111
+ async function readJson(path) {
112
+ return JSON.parse(await readFile(path, "utf8"));
113
+ }
114
+ function isRecord(value) {
115
+ return typeof value === "object" && value !== null && !Array.isArray(value);
116
+ }
117
+
118
+ // src/scaffold.ts
119
+ var packageRoot = resolve(import.meta.dirname, "..");
120
+ async function scaffoldProject(options) {
121
+ const cwd = options.cwd ?? process.cwd();
122
+ const projectName = assertProjectName(options.projectName);
123
+ const projectPath = resolve(cwd, projectName);
124
+ if (existsSync(projectPath))
125
+ throw new Error(`Directory already exists: ${projectPath}`);
126
+ const placeholders = {
127
+ PROJECT_NAME: projectName,
128
+ HEYO_DOCS_VERSION: options.heyoDocsVersion ?? "0.1.0",
129
+ PACKAGE_MANAGER: packageManagerField(options.packageManager),
130
+ THEME: options.theme
131
+ };
132
+ const templatePath = join2(packageRoot, "templates", options.template);
133
+ const deploymentPath = join2(packageRoot, "deployments", options.deployment, options.template);
134
+ await mkdir2(projectPath, { recursive: true });
135
+ await copyTemplate(templatePath, projectPath, placeholders);
136
+ const basePackage = await readJson(join2(projectPath, "package.json"));
137
+ const overlayPackage = options.deployment === "later" ? {} : await readJson(join2(deploymentPath, "package.json"));
138
+ if (options.deployment !== "later") {
139
+ await copyOverlay(deploymentPath, projectPath, placeholders);
140
+ }
141
+ await writeJson(join2(projectPath, "package.json"), mergePackageJson(basePackage, overlayPackage));
142
+ if (options.install)
143
+ await installDependencies(projectPath, options.packageManager);
144
+ return { projectPath };
145
+ }
146
+ async function copyOverlay(source, destination, placeholders) {
147
+ const entries = await readdir2(source, { withFileTypes: true });
148
+ await Promise.all(entries.filter((entry) => entry.name !== "package.json").map(async (entry) => {
149
+ const sourcePath = join2(source, entry.name);
150
+ const destinationPath = join2(destination, entry.name);
151
+ return copyTemplate(sourcePath, destinationPath, placeholders);
152
+ }));
153
+ }
154
+ async function installDependencies(projectPath, packageManager) {
155
+ const command = packageManagerInstallCommand(packageManager);
156
+ const [executable, ...arguments_] = command;
157
+ await new Promise((resolveInstall, rejectInstall) => {
158
+ const child = spawn(executable, arguments_, {
159
+ cwd: projectPath,
160
+ stdio: "inherit"
161
+ });
162
+ child.once("error", rejectInstall);
163
+ child.once("close", (exitCode) => {
164
+ if (exitCode === 0)
165
+ return resolveInstall();
166
+ rejectInstall(new Error(`Dependency installation failed with ${command.join(" ")}.`));
167
+ });
168
+ });
169
+ }
170
+
171
+ // src/index.ts
172
+ var USAGE = "Usage: create-heyo-docs [project-name] [--template react-router|next|astro] [--deployment cloudflare|vercel|later] [--theme grain|shade|moss] [--package-manager bun|pnpm|npm|yarn] [--no-install]";
173
+ var TEMPLATE_OPTIONS = [
174
+ { value: "react-router", label: "React Router" },
175
+ { value: "next", label: "Next.js" },
176
+ { value: "astro", label: "Astro" }
177
+ ];
178
+ var DEPLOYMENT_OPTIONS = [
179
+ { value: "cloudflare", label: "Cloudflare" },
180
+ { value: "vercel", label: "Vercel" },
181
+ { value: "later", label: "Configure later" }
182
+ ];
183
+ var THEME_OPTIONS = [
184
+ { value: "grain", label: "Grain" },
185
+ { value: "shade", label: "Shade" },
186
+ { value: "moss", label: "Moss" },
187
+ {
188
+ value: "dripper",
189
+ label: "Dripper — Soon",
190
+ hint: "Unavailable in this MVP"
191
+ },
192
+ {
193
+ value: "fixed-gear",
194
+ label: "Fixed Gear — Soon",
195
+ hint: "Unavailable in this MVP"
196
+ }
197
+ ];
198
+ var PACKAGE_MANAGER_OPTIONS = [
199
+ { value: "bun", label: "bun" },
200
+ { value: "pnpm", label: "pnpm" },
201
+ { value: "npm", label: "npm" },
202
+ { value: "yarn", label: "yarn" }
203
+ ];
204
+ if (isMainModule()) {
205
+ run(process.argv.slice(2)).catch((error) => {
206
+ p.log.error(error instanceof Error ? error.message : String(error));
207
+ process.exitCode = 1;
208
+ });
209
+ }
210
+ function isMainModule() {
211
+ const entryPoint = process.argv[1];
212
+ if (!entryPoint)
213
+ return false;
214
+ try {
215
+ return realpathSync(entryPoint) === fileURLToPath(import.meta.url);
216
+ } catch {
217
+ return false;
218
+ }
219
+ }
220
+ async function run(argv = process.argv.slice(2)) {
221
+ const parsed = parseArguments(argv);
222
+ if (parsed.showHelp) {
223
+ p.note(USAGE, "@heyo-sh/create-heyo-docs");
224
+ return;
225
+ }
226
+ const options = parsed.interactive ? await askQuestions(parsed.options) : parsed.options;
227
+ const spinner2 = p.spinner();
228
+ spinner2.start("Creating your Heyo Docs project");
229
+ try {
230
+ await scaffoldProject(options);
231
+ } catch (error) {
232
+ spinner2.stop("Unable to create your documentation project");
233
+ throw error;
234
+ }
235
+ spinner2.stop("Your documentation project is ready");
236
+ const install = options.install ? "" : `
237
+ ${options.packageManager} install`;
238
+ p.note(`cd ${options.projectName}${install}
239
+ ${packageManagerRunCommand(options.packageManager, "dev")}`, "Next steps");
240
+ p.outro("Happy documenting.");
241
+ }
242
+ function parseArguments(argv) {
243
+ const detected = detectPackageManager();
244
+ const options = {
245
+ projectName: "",
246
+ template: "react-router",
247
+ deployment: "later",
248
+ theme: "grain",
249
+ packageManager: detected.name,
250
+ install: true
251
+ };
252
+ let explicit = false;
253
+ let showHelp = false;
254
+ for (let index = 0;index < argv.length; index += 1) {
255
+ const value = argv[index];
256
+ if (!value.startsWith("-")) {
257
+ options.projectName ||= value;
258
+ continue;
259
+ }
260
+ explicit = true;
261
+ if (value === "--template") {
262
+ options.template = readEnum(argv[++index], ["react-router", "next", "astro"], "template");
263
+ } else if (value === "--deployment") {
264
+ options.deployment = readEnum(argv[++index], ["cloudflare", "vercel", "later"], "deployment");
265
+ } else if (value === "--theme") {
266
+ options.theme = readEnum(argv[++index], ["grain", "shade", "moss"], "theme");
267
+ } else if (value === "--package-manager") {
268
+ options.packageManager = readEnum(argv[++index], ["bun", "pnpm", "npm", "yarn"], "package manager");
269
+ } else if (value === "--no-install") {
270
+ options.install = false;
271
+ } else if (value === "--install") {
272
+ options.install = true;
273
+ } else if (value === "--help" || value === "-h") {
274
+ showHelp = true;
275
+ } else {
276
+ throw new Error(`Unknown option: ${value}`);
277
+ }
278
+ }
279
+ return { options, interactive: !explicit && !options.projectName, showHelp };
280
+ }
281
+ async function askQuestions(defaults) {
282
+ p.intro("Create Heyo Docs");
283
+ const projectName = await p.text({
284
+ message: "Project name",
285
+ placeholder: "my-docs",
286
+ defaultValue: "my-docs",
287
+ validate: projectNameError
288
+ });
289
+ if (p.isCancel(projectName))
290
+ cancelCreation();
291
+ const template = await selectAvailable("Template", TEMPLATE_OPTIONS, [
292
+ "react-router",
293
+ "next",
294
+ "astro"
295
+ ]);
296
+ const deployment = await selectAvailable("Deployment", DEPLOYMENT_OPTIONS, ["cloudflare", "vercel", "later"], defaults.deployment);
297
+ const theme = await selectAvailable("Theme", THEME_OPTIONS, [
298
+ "grain",
299
+ "shade",
300
+ "moss"
301
+ ]);
302
+ const packageManager = await selectAvailable("Package manager", PACKAGE_MANAGER_OPTIONS, ["bun", "pnpm", "npm", "yarn"], defaults.packageManager);
303
+ const install = await p.confirm({
304
+ message: "Install dependencies?",
305
+ initialValue: true
306
+ });
307
+ if (p.isCancel(install))
308
+ cancelCreation();
309
+ return {
310
+ projectName,
311
+ template,
312
+ deployment,
313
+ theme,
314
+ packageManager,
315
+ install
316
+ };
317
+ }
318
+ async function selectAvailable(message, options, available, initialValue) {
319
+ for (;; ) {
320
+ const answer = await p.select({ message, options, initialValue });
321
+ if (p.isCancel(answer))
322
+ cancelCreation();
323
+ if (isOneOf(answer, available))
324
+ return answer;
325
+ p.log.warn("That option is planned but not available in this MVP.");
326
+ }
327
+ }
328
+ function isOneOf(value, values) {
329
+ return values.some((candidate) => candidate === value);
330
+ }
331
+ function cancelCreation() {
332
+ p.cancel("Creation cancelled.");
333
+ process.exit(0);
334
+ }
335
+ function readEnum(value, allowed, label) {
336
+ if (value && isOneOf(value, allowed))
337
+ return value;
338
+ throw new Error(`Use one of ${allowed.join(", ")} for ${label}.`);
339
+ }
340
+ export {
341
+ scaffoldProject,
342
+ run,
343
+ replacePlaceholders,
344
+ parseArguments,
345
+ packageManagerRunCommand,
346
+ packageManagerField,
347
+ mergePackageJson,
348
+ detectPackageManager
349
+ };
@@ -0,0 +1,6 @@
1
+ import type { DetectedPackageManager, PackageManager } from "./types";
2
+ export declare function detectPackageManager(userAgent?: string): DetectedPackageManager;
3
+ export declare function packageManagerField(manager: PackageManager, detected?: DetectedPackageManager): string;
4
+ export declare function packageManagerInstallCommand(manager: PackageManager): string[];
5
+ export declare function packageManagerRunCommand(manager: PackageManager, script: string): string;
6
+ //# sourceMappingURL=package-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../src/package-manager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAStE,wBAAgB,oBAAoB,CAClC,SAAS,SAA0C,GAClD,sBAAsB,CAIxB;AAED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,cAAc,EACvB,QAAQ,yBAAyB,GAChC,MAAM,CAeR;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,cAAc,GACtB,MAAM,EAAE,CAEV;AAED,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,cAAc,EACvB,MAAM,EAAE,MAAM,GACb,MAAM,CAIR"}
@@ -0,0 +1,3 @@
1
+ export declare function projectNameError(value: string): string | undefined;
2
+ export declare function assertProjectName(value: string): string;
3
+ //# sourceMappingURL=project-name.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-name.d.ts","sourceRoot":"","sources":["../src/project-name.ts"],"names":[],"mappings":"AAEA,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIlE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIvD"}
@@ -0,0 +1,5 @@
1
+ import type { CreateOptions } from "./types";
2
+ export declare function scaffoldProject(options: CreateOptions): Promise<{
3
+ projectPath: string;
4
+ }>;
5
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAK7C,wBAAsB,eAAe,CACnC,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA0ClC"}
@@ -0,0 +1,19 @@
1
+ export type Template = "react-router" | "next" | "astro";
2
+ export type Deployment = "cloudflare" | "vercel" | "later";
3
+ export type Theme = "grain" | "shade" | "moss";
4
+ export type PackageManager = "bun" | "pnpm" | "npm" | "yarn";
5
+ export interface CreateOptions {
6
+ projectName: string;
7
+ template: Template;
8
+ deployment: Deployment;
9
+ theme: Theme;
10
+ packageManager: PackageManager;
11
+ install: boolean;
12
+ cwd?: string;
13
+ heyoDocsVersion?: string;
14
+ }
15
+ export interface DetectedPackageManager {
16
+ name: PackageManager;
17
+ version?: string;
18
+ }
19
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,cAAc,GAAG,MAAM,GAAG,OAAO,CAAC;AACzD,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,QAAQ,GAAG,OAAO,CAAC;AAC3D,MAAM,MAAM,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;AAC/C,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,UAAU,CAAC;IACvB,KAAK,EAAE,KAAK,CAAC;IACb,cAAc,EAAE,cAAc,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,8 @@
1
+ export declare function replacePlaceholders(source: string, values: Record<string, string>): string;
2
+ export declare function mergePackageJson<T extends Record<string, unknown>>(base: T, overlay: Record<string, unknown>): T;
3
+ export declare function copyTemplate(source: string, destination: string, placeholders: Record<string, string>): Promise<void>;
4
+ export declare function replacePlaceholdersInDirectory(directory: string, values: Record<string, string>): Promise<void>;
5
+ export declare function writeJson(path: string, data: unknown): Promise<void>;
6
+ export declare function readJson<T>(path: string): Promise<T>;
7
+ export declare function emptyDirectory(path: string): Promise<void>;
8
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAWA,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,MAAM,CAKR;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChE,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,CAAC,CASH;AAED,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACnC,OAAO,CAAC,IAAI,CAAC,CAGf;AAED,wBAAsB,8BAA8B,CAClD,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC7B,OAAO,CAAC,IAAI,CAAC,CAOf;AAoBD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAG1E;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAE1D;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEhE"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heyo-sh/create-heyo-docs",
3
- "version": "0.1.1",
3
+ "version": "0.2.1",
4
4
  "description": "Create a standalone Heyo Docs documentation project.",
5
5
  "homepage": "https://heyo.sh",
6
6
  "repository": {
@@ -12,6 +12,9 @@
12
12
  },
13
13
  "license": "MIT",
14
14
  "type": "module",
15
+ "engines": {
16
+ "node": ">=20.11.0"
17
+ },
15
18
  "bin": {
16
19
  "create-heyo-docs": "./dist/index.js"
17
20
  },
@@ -28,7 +31,7 @@
28
31
  },
29
32
  "scripts": {
30
33
  "dev": "bun run build --watch",
31
- "build": "bun build src/index.ts --outdir dist --target bun --external @clack/prompts && bun run build:types",
34
+ "build": "bun build src/index.ts --outdir dist --target node --external @clack/prompts && bun run build:types",
32
35
  "build:types": "tsc -p tsconfig.build.json",
33
36
  "typecheck": "tsc -p tsconfig.json",
34
37
  "test": "bun test"
@@ -0,0 +1,76 @@
1
+ ---
2
+ title: Basic Configuration
3
+ description: Set the identity, content source, and sidebar structure for a Heyo Docs site.
4
+ ---
5
+
6
+ # Basic Configuration
7
+
8
+ `heyo-docs.config.ts` is the single source of truth for a Heyo Docs site.
9
+ The framework integration and the documentation UI read the same validated
10
+ object, so a change to navigation or metadata does not need to be repeated in
11
+ multiple places.
12
+
13
+ ## Start with the site model
14
+
15
+ The generated project already includes a working configuration. Update the
16
+ identity fields first, then point `content` at the directory that contains
17
+ your MDX files.
18
+
19
+ <CodeBlock language="ts" title="heyo-docs.config.ts" showLineNumbers>
20
+ {`import { heyoDocs } from "@heyo-sh/heyo-docs";
21
+
22
+ export default heyoDocs({
23
+ title: "{{PROJECT_NAME}}",
24
+ description: "Guides and reference for {{PROJECT_NAME}}.",
25
+ content: "./content",
26
+ theme: "grain",
27
+ mode: "system",
28
+ branding: { name: "{{PROJECT_NAME}}" },
29
+ });`}
30
+ </CodeBlock>
31
+
32
+ Set `siteUrl` to the final public origin before publishing. It is used for
33
+ canonical URLs, social metadata, the sitemap, RSS, and AI-facing discovery
34
+ files.
35
+
36
+ ## Organize the sidebar
37
+
38
+ Use `groups` to define the order readers see. A group contains named sections
39
+ and their MDX page references; a reference is relative to `content` and does
40
+ not include the `.mdx` extension.
41
+
42
+ <CodeBlock language="ts" title="heyo-docs.config.ts">
43
+ {`groups: [
44
+ {
45
+ group: "Documentation",
46
+ icon: "globe",
47
+ sections: [
48
+ {
49
+ section: "Get Started",
50
+ icon: "lightbulb",
51
+ pages: ["quickstart", "configuration"],
52
+ },
53
+ {
54
+ section: "Essentials",
55
+ icon: "book",
56
+ pages: ["essentials/text-styling", "essentials/code-blocks"],
57
+ },
58
+ ],
59
+ },
60
+ ],`}
61
+ </CodeBlock>
62
+
63
+ The order is meaningful: it controls the sidebar and the previous/next links at
64
+ the end of each article. Use a page object with `title` and `src` when a
65
+ sidebar entry should point to a page outside the local documentation.
66
+
67
+ ## Verify the result
68
+
69
+ Run the project's typecheck and build commands after changing configuration.
70
+ They resolve each configured MDX page and report missing paths or malformed
71
+ navigation before the site is deployed.
72
+
73
+ <Callout type="info" title="Keep page metadata close to the page">
74
+ Put a page's <code>title</code> and <code>description</code> in its MDX
75
+ frontmatter. Keep shared site settings in <code>heyo-docs.config.ts</code>.
76
+ </Callout>
@@ -0,0 +1,57 @@
1
+ ---
2
+ title: Deploying
3
+ description: Build and publish your Heyo Docs site with the deployment target chosen during setup.
4
+ ---
5
+
6
+ # Deploying
7
+
8
+ A Heyo Docs site is built as part of the framework application. The creator asks
9
+ for a deployment target when the project is created and adds the corresponding
10
+ configuration, so the same MDX content, navigation, search, and metadata are
11
+ used locally and in production.
12
+
13
+ ## Choose the target during setup
14
+
15
+ Select Vercel or Cloudflare when running the creator if you already know where
16
+ the site will live. The generated project includes the adapter and deployment
17
+ configuration required by that platform. You can also choose to configure
18
+ deployment later and keep the starter focused on local development.
19
+
20
+ ## Build before publishing
21
+
22
+ Run the production build on your machine before creating a deployment. It
23
+ resolves every configured page, validates the navigation tree, and generates
24
+ the sitemap, RSS feed, robots file, and AI-facing documentation endpoints.
25
+
26
+ <CodeBlock language="bash" title="Terminal">
27
+ {"bun run build"}
28
+ </CodeBlock>
29
+
30
+ Use the equivalent `npm run build`, `pnpm build`, or `yarn build` command
31
+ when the project uses a different package manager.
32
+
33
+ <Callout type="tip" title="Set the canonical URL">
34
+ Add the final public origin as <code>siteUrl</code> in
35
+ <code>heyo-docs.config.ts</code> before the first production release. It keeps
36
+ canonical links, social metadata, and generated discovery files consistent.
37
+ </Callout>
38
+
39
+ ## Publish the project
40
+
41
+ For a generated Vercel or Cloudflare project, connect the repository in the
42
+ provider dashboard or run the deployment script included by the selected setup.
43
+ The provider builds the application with the same command you verified locally.
44
+
45
+ <Steps>
46
+ <Step title="Push the documentation source">
47
+ Commit the MDX content and <code>heyo-docs.config.ts</code> together so the
48
+ deployed navigation matches the reviewed pages.
49
+ </Step>
50
+ <Step title="Create a preview">
51
+ Review the provider's preview URL for layout, links, search, and metadata.
52
+ </Step>
53
+ <Step title="Promote the production build">
54
+ Publish once the preview is correct and the configured <code>siteUrl</code>
55
+ matches the public domain.
56
+ </Step>
57
+ </Steps>
@@ -0,0 +1,36 @@
1
+ ---
2
+ title: Callouts
3
+ description: Highlight prerequisites, tips, warnings, and successful outcomes.
4
+ ---
5
+
6
+ # Callouts
7
+
8
+ Use `Callout` when an important note should stand apart from the surrounding
9
+ prose. It works well for a prerequisite, a preferred approach, a warning, or a
10
+ successful result.
11
+
12
+ ## Choose the right emphasis
13
+
14
+ Use `note` or `info` for context, `tip` for a recommended approach, and
15
+ `check` for a completed outcome. Reserve `warning` and `danger` for cases
16
+ where missing the message has a real consequence.
17
+
18
+ <Callout type="tip" title="Keep examples focused">
19
+ Show one idea at a time so readers can apply it quickly.
20
+ </Callout>
21
+
22
+ <Callout type="warning" title="Preview before publishing">
23
+ Run the production build locally after changing navigation or MDX.
24
+ </Callout>
25
+
26
+ ## Add richer guidance
27
+
28
+ Pass the message as children when it needs Markdown or another MDX component.
29
+
30
+ <Callout type="info" title="Configuration and content work together">
31
+ Navigation belongs in <code>heyo-docs.config.ts</code>; page titles and
32
+ descriptions belong in the page frontmatter.
33
+ </Callout>
34
+
35
+ Keep each callout focused on one decision. A long sequence of status messages is
36
+ usually clearer as regular sections or a numbered procedure.