@vited/create 0.0.4 → 0.0.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ### Added
6
+
7
+ - Generate `docs/favicon.svg` for new projects without overwriting an existing favicon.
8
+
3
9
  ## 0.0.4 - 2026-10-28
4
10
 
5
11
  ### Fixed
package/README.md CHANGED
@@ -33,10 +33,20 @@ pnpm dlx @vited/create my-docs \
33
33
  --no-install
34
34
  ```
35
35
 
36
- The generated project includes `vited.config.ts`, a `docs` directory, and
37
- `docs:dev` / `docs:build` scripts. `@vited/core` provides the HTML shell, so no
38
- `index.html` is added to the project. Existing package scripts and documentation
39
- files are preserved. An existing `vited.config.ts` is not overwritten.
36
+ The generated project includes `vited.config.ts`, a `docs` directory with a
37
+ default `favicon.svg`, and `docs:dev` / `docs:build` scripts. `@vited/core`
38
+ provides the HTML shell, so no `index.html` is added to the project. Existing
39
+ package scripts and documentation files are preserved. The generated
40
+ `.gitignore` ignores the default `docs_dist` build output. The starter
41
+ documentation is English in `docs/README.md` with a Chinese translation in
42
+ `docs/README.zh.md`. An existing `vited.config.ts` is not overwritten.
40
43
  If it already exists, `vited-new.config.ts` is created or overwritten for comparison.
41
44
  When installing with pnpm, the required `@swc/core` and `esbuild` build scripts
42
45
  are approved automatically to comply with pnpm's build-script policy.
46
+
47
+ When a GitHub repository is detected from the `origin` remote or the
48
+ `repository` field in `package.json`, create adds a GitHub Pages workflow and
49
+ sets the Vite and Vited base URLs to the repository path. The workflow deploys
50
+ the `docs_dist` build output. User and organization sites named
51
+ `<owner>.github.io` use the root URL. In the repository settings,
52
+ select **Settings → Pages → Source → GitHub Actions** to enable the workflow.
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
+ type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';
1
2
  export declare const THEMES: readonly ["@vited/theme-mantine"];
2
3
  export type Theme = (typeof THEMES)[number];
3
- export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';
4
4
  export type ProjectMode = 'create' | 'init';
5
5
  export interface CreateOptions {
6
6
  directory: string;
@@ -15,4 +15,5 @@ export interface CreateResult {
15
15
  }
16
16
  export declare function resolvePackageManager(projectPath: string, environment?: NodeJS.ProcessEnv): Promise<PackageManager>;
17
17
  export declare function create({ directory, theme, packageManager, install }: CreateOptions): Promise<CreateResult>;
18
- export declare function installPackages(projectPath: string, packageManager: PackageManager): Promise<void>;
18
+ export declare function installPackages(projectPath: string, packageManager: PackageManager): Promise<void>;
19
+ export type { PackageManager };
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- export { t as THEMES, n as create, r as installPackages, i as resolvePackageManager } from "./src-BWiFwqr3.mjs";
1
+ export { t as THEMES, n as create, r as installPackages, i as resolvePackageManager } from "./src-BAeU7i-K.mjs";
@@ -1,8 +1,164 @@
1
- import { spawn } from "node:child_process";
1
+ import { execFile, spawn } from "node:child_process";
2
2
  import { mkdir, readFile, stat, writeFile } from "node:fs/promises";
3
3
  import path from "node:path";
4
4
  import process from "node:process";
5
+ import { URL } from "node:url";
6
+ import { promisify } from "node:util";
5
7
  import i18next from "i18next";
8
+ // src/github.ts
9
+ const execFileAsync = promisify(execFile);
10
+ async function getGitHubPagesSetup(projectPath, repository, packageManager) {
11
+ const githubRepository = await findGitHubRepository(projectPath, repository);
12
+ if (!githubRepository) return;
13
+ return {
14
+ base: getGitHubBaseURL(githubRepository),
15
+ workflow: makeGitHubPagesWorkflow(packageManager)
16
+ };
17
+ }
18
+ async function writeGitHubPagesWorkflow(projectPath, content) {
19
+ const workflowPath = path.join(projectPath, ".github", "workflows", "pages.yaml");
20
+ await mkdir(path.dirname(workflowPath), { recursive: true });
21
+ try {
22
+ await writeFile(workflowPath, content, { flag: "wx" });
23
+ } catch (error) {
24
+ if (!isNodeError$1(error, "EEXIST")) throw error;
25
+ }
26
+ }
27
+ async function findGitHubRepository(projectPath, repository) {
28
+ let originURL;
29
+ try {
30
+ originURL = (await execFileAsync("git", [
31
+ "remote",
32
+ "get-url",
33
+ "origin"
34
+ ], {
35
+ cwd: projectPath,
36
+ encoding: "utf8"
37
+ })).stdout.trim();
38
+ } catch (error) {
39
+ if (!isExpectedGitLookupFailure(error)) throw error;
40
+ }
41
+ return parseGitHubRepository(originURL) ?? parseGitHubRepository(getRepositoryURL(repository));
42
+ }
43
+ function isExpectedGitLookupFailure(error) {
44
+ if (isNodeError$1(error, "ENOENT")) return true;
45
+ if (!isRecord$1(error)) return false;
46
+ const code = error["code"];
47
+ return typeof code === "number" && [2, 128].includes(code);
48
+ }
49
+ function getRepositoryURL(repository) {
50
+ if (typeof repository === "string") return repository;
51
+ if (isRecord$1(repository) && typeof repository["url"] === "string") return repository["url"];
52
+ }
53
+ function parseGitHubRepository(repositoryURL) {
54
+ if (!repositoryURL) return;
55
+ const value = repositoryURL.trim().replace(/^git\+/, "");
56
+ const scpMatch = /^(?:[^@/]+@)?github\.com:([^/]+)\/([^/?#]+)$/i.exec(value);
57
+ const shorthandMatch = /^(?:github:)?([^/]+)\/([^/?#]+)$/i.exec(value);
58
+ const shorthand = scpMatch ?? shorthandMatch;
59
+ if (shorthand?.[1] && shorthand[2]) return makeGitHubRepository(shorthand[1], shorthand[2]);
60
+ let url;
61
+ try {
62
+ url = new URL(value);
63
+ } catch (error) {
64
+ if (error instanceof TypeError) return;
65
+ throw error;
66
+ }
67
+ if (url.hostname.toLowerCase() !== "github.com" || ![
68
+ "git:",
69
+ "http:",
70
+ "https:",
71
+ "ssh:"
72
+ ].includes(url.protocol)) return;
73
+ const pathSegments = url.pathname.split("/").filter(Boolean);
74
+ if (pathSegments.length !== 2) return;
75
+ const [owner, name] = pathSegments;
76
+ if (!owner || !name) return;
77
+ return makeGitHubRepository(owner, name);
78
+ }
79
+ function makeGitHubRepository(owner, name) {
80
+ return {
81
+ owner,
82
+ name: name.replace(/\.git$/i, "")
83
+ };
84
+ }
85
+ function getGitHubBaseURL(repository) {
86
+ return repository.name.toLowerCase() === `${repository.owner.toLowerCase()}.github.io` ? "/" : `/${repository.name}/`;
87
+ }
88
+ function makeGitHubPagesWorkflow(packageManager) {
89
+ const setupPackageManagerSteps = {
90
+ npm: [],
91
+ pnpm: [" - uses: pnpm/action-setup@v4"],
92
+ yarn: [" - run: corepack enable"],
93
+ bun: [" - uses: oven-sh/setup-bun@v2"]
94
+ }[packageManager];
95
+ const installSteps = {
96
+ npm: [" - run: npm install"],
97
+ pnpm: [" - run: pnpm approve-builds @swc/core esbuild", " - run: pnpm install"],
98
+ yarn: [" - run: yarn install"],
99
+ bun: [" - run: bun install"]
100
+ }[packageManager];
101
+ const buildCommand = {
102
+ npm: "npm run docs:build",
103
+ pnpm: "pnpm run docs:build",
104
+ yarn: "yarn docs:build",
105
+ bun: "bun run docs:build"
106
+ }[packageManager];
107
+ return [
108
+ "name: Deploy docs to GitHub Pages",
109
+ "",
110
+ "on:",
111
+ " push:",
112
+ " branches:",
113
+ " - main",
114
+ " - master",
115
+ " workflow_dispatch:",
116
+ "",
117
+ "permissions:",
118
+ " contents: read",
119
+ " pages: write",
120
+ "",
121
+ "concurrency:",
122
+ " group: github-pages",
123
+ " cancel-in-progress: false",
124
+ "",
125
+ "jobs:",
126
+ " build:",
127
+ " runs-on: ubuntu-latest",
128
+ " steps:",
129
+ " - uses: actions/checkout@v6",
130
+ " - uses: actions/setup-node@v6",
131
+ " with:",
132
+ " node-version: 22",
133
+ ...setupPackageManagerSteps,
134
+ " - uses: actions/configure-pages@v5",
135
+ ...installSteps,
136
+ ` - run: ${buildCommand}`,
137
+ " - uses: actions/upload-pages-artifact@v4",
138
+ " with:",
139
+ " path: ./docs_dist",
140
+ "",
141
+ " deploy:",
142
+ " environment:",
143
+ " name: github-pages",
144
+ " url: ${{ steps.deployment.outputs.page_url }}",
145
+ " runs-on: ubuntu-latest",
146
+ " needs: build",
147
+ " permissions:",
148
+ " pages: write",
149
+ " id-token: write",
150
+ " steps:",
151
+ " - id: deployment",
152
+ " uses: actions/deploy-pages@v4",
153
+ ""
154
+ ].join("\n");
155
+ }
156
+ function isNodeError$1(error, code) {
157
+ return error instanceof Error && "code" in error && error.code === code;
158
+ }
159
+ function isRecord$1(value) {
160
+ return typeof value === "object" && value === Object(value) && !Array.isArray(value);
161
+ }
6
162
  // src/i18n.ts
7
163
  const LANGUAGES = ["en", "zh"];
8
164
  const resources = {
@@ -152,12 +308,18 @@ async function create({ directory, theme, packageManager, install }) {
152
308
  const packageJsonPath = path.join(projectPath, "package.json");
153
309
  const packageJson = await readProjectPackageJson(packageJsonPath, projectPath);
154
310
  addVitedConfiguration(packageJson, projectPath, theme);
311
+ const githubPages = await getGitHubPagesSetup(projectPath, packageJson["repository"], packageManager);
312
+ const base = githubPages?.base;
155
313
  await mkdir(projectPath, { recursive: true });
314
+ await ensureGitignoreEntry(projectPath, "docs_dist");
156
315
  const docsPath = path.join(projectPath, "docs");
157
316
  await mkdir(docsPath, { recursive: true });
158
317
  await writeFile(packageJsonPath, `${JSON.stringify(packageJson, void 0, 2)}\n`);
159
- await writeFile(configPath, makeVitedConfig(packageJson, theme), { flag: overwriteConfig ? "w" : "wx" });
160
- await writeIfMissing(path.join(docsPath, "README.md"), makeReadme(packageJson));
318
+ await writeFile(configPath, makeVitedConfig(packageJson, theme, base), { flag: overwriteConfig ? "w" : "wx" });
319
+ await writeIfMissing(path.join(docsPath, "favicon.svg"), await readFile(new URL("../favicon.svg", import.meta.url), "utf8"));
320
+ await writeIfMissing(path.join(docsPath, "README.md"), makeReadme(packageJson, "en"));
321
+ await writeIfMissing(path.join(docsPath, "README.zh.md"), makeReadme(packageJson, "zh"));
322
+ if (githubPages) await writeGitHubPagesWorkflow(projectPath, githubPages.workflow);
161
323
  if (install) await installPackages(projectPath, packageManager);
162
324
  return {
163
325
  projectPath,
@@ -294,12 +456,13 @@ async function fileExists(filePath) {
294
456
  function toPackageName(value) {
295
457
  return value.toLowerCase().replaceAll(/[^a-z0-9._-]+/g, "-").replaceAll(/^-+|-+$/g, "") || "vited-docs";
296
458
  }
297
- function makeVitedConfig(packageJson, theme) {
459
+ function makeVitedConfig(packageJson, theme, base) {
298
460
  const title = typeof packageJson["name"] === "string" && packageJson["name"].length > 0 ? packageJson["name"] : "Vited documentation";
299
461
  return [
300
462
  "import { defineConfig } from '@vited/core';",
301
463
  "",
302
464
  "export default defineConfig({",
465
+ ` base: ${JSON.stringify(base ?? "/")},`,
303
466
  " docs: {",
304
467
  ` title: ${JSON.stringify(title)},`,
305
468
  ` theme: ${JSON.stringify(theme)},`,
@@ -308,8 +471,8 @@ function makeVitedConfig(packageJson, theme) {
308
471
  ""
309
472
  ].join("\n");
310
473
  }
311
- function makeReadme(packageJson) {
312
- return `# ${typeof packageJson["name"] === "string" && packageJson["name"].length > 0 ? packageJson["name"] : "Vited documentation"}\n\n${t("template.docsWelcome")}\n`;
474
+ function makeReadme(packageJson, language) {
475
+ return `# ${typeof packageJson["name"] === "string" && packageJson["name"].length > 0 ? packageJson["name"] : "Vited documentation"}\n\n${t("template.docsWelcome", { lng: language })}\n`;
313
476
  }
314
477
  async function writeIfMissing(filePath, content) {
315
478
  try {
@@ -318,4 +481,20 @@ async function writeIfMissing(filePath, content) {
318
481
  if (!isNodeError(error, "EEXIST")) throw error;
319
482
  }
320
483
  }
484
+ async function ensureGitignoreEntry(projectPath, entry) {
485
+ const gitignorePath = path.join(projectPath, ".gitignore");
486
+ let contents;
487
+ try {
488
+ contents = await readFile(gitignorePath, "utf8");
489
+ } catch (error) {
490
+ if (!isNodeError(error, "ENOENT")) throw error;
491
+ contents = "";
492
+ }
493
+ if (contents.split(/\r?\n/).some((line) => {
494
+ return line.trim().replaceAll(/^\/+|\/+$/g, "") === entry;
495
+ })) return;
496
+ const lineEnding = contents.includes("\r\n") ? "\r\n" : "\n";
497
+ const separator = contents.length > 0 && !contents.endsWith("\n") ? lineEnding : "";
498
+ await writeFile(gitignorePath, `${contents}${separator}${entry}${lineEnding}`);
499
+ }
321
500
  export { LANGUAGES as a, t as c, resolvePackageManager as i, create as n, isLanguage as o, installPackages as r, setLanguage as s, THEMES as t };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as LANGUAGES, c as t, i as resolvePackageManager, n as create, o as isLanguage, s as setLanguage, t as THEMES } from "./src-BWiFwqr3.mjs";
2
+ import { a as LANGUAGES, c as t, i as resolvePackageManager, n as create, o as isLanguage, s as setLanguage, t as THEMES } from "./src-BAeU7i-K.mjs";
3
3
  import process from "node:process";
4
4
  import console from "node:console";
5
5
  import { Command, Option } from "commander";
package/favicon.svg ADDED
@@ -0,0 +1,20 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
2
+ <defs>
3
+ <linearGradient id="bolt" x1="30" y1="14" x2="95" y2="107" gradientUnits="userSpaceOnUse">
4
+ <stop stop-color="#ffe76b" />
5
+ <stop offset=".38" stop-color="#ff9a43" />
6
+ <stop offset=".72" stop-color="#d94fe8" />
7
+ <stop offset="1" stop-color="#6657f5" />
8
+ </linearGradient>
9
+ <clipPath id="shape">
10
+ <path d="M75 8 29 62h27l-9 58 53-70H73L94 8H75Z" />
11
+ </clipPath>
12
+ </defs>
13
+ <path d="M75 8 29 62h27l-9 58 53-70H73L94 8H75Z" fill="url(#bolt)" />
14
+ <g clip-path="url(#shape)">
15
+ <path d="M22 18h61L56 62H22Z" fill="#fff1a1" opacity=".58" />
16
+ <path d="m56 62 17-14h28l-53 72 9-58Z" fill="#654ce1" opacity=".5" />
17
+ <path d="m73 8 21 0-21 42H55Z" fill="#fff" opacity=".18" />
18
+ <path d="m56 62 17-14-26 72 9-58Z" fill="#ff6b5b" opacity=".45" />
19
+ </g>
20
+ </svg>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vited/create",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "Create and initialize Vited documentation projects",
5
5
  "keywords": [
6
6
  "cli",
@@ -27,6 +27,7 @@
27
27
  },
28
28
  "files": [
29
29
  "dist",
30
+ "favicon.svg",
30
31
  "CHANGELOG.md",
31
32
  "LICENSE",
32
33
  "README.md"
@@ -46,7 +47,6 @@
46
47
  "i18next": "^26.5.11"
47
48
  },
48
49
  "devDependencies": {
49
- "@guoyunhe/editorconfig": "^0.3.0",
50
50
  "@guoyunhe/oxfmt-config": "^1.1.0",
51
51
  "@tsconfig/node20": "^20.1.2",
52
52
  "@tsconfig/strictest": "^2.0.2",