@knitli/astro-docs-template 0.1.2 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@knitli/astro-docs-template",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "description": "Opinionated Astro + Starlight docs site template with Knitli branding",
5
5
  "keywords": [
6
6
  "knitli",
@@ -19,67 +19,62 @@
19
19
  "author": "Knitli Inc.",
20
20
  "type": "module",
21
21
  "exports": {
22
- ".": {
23
- "types": "./dist/index.d.ts",
24
- "import": "./dist/index.js"
25
- },
26
- "./config": {
27
- "types": "./dist/config.d.ts",
28
- "import": "./dist/config.js"
29
- }
22
+ ".": "./src/index.ts",
23
+ "./config": "./src/config.ts"
30
24
  },
31
25
  "bin": {
32
- "knitli-docs": "dist/cli.js"
26
+ "knitli-docs": "src/cli.ts"
33
27
  },
34
28
  "files": [
35
- "dist",
29
+ "src",
36
30
  "scaffolding",
37
31
  "README.md",
38
32
  "CHANGELOG.md"
39
33
  ],
40
34
  "scripts": {
41
- "build": "vite build && tsc --emitDeclarationOnly --noCheck --noEmit false",
42
- "prepublishOnly": "bun run build",
43
- "publish": "npm publish --access public",
44
- "typecheck": "bunx tsc --noEmit"
35
+ "prebuild": "bun run clean",
36
+ "build": "bun run build.ts",
37
+ "postbuild": "tsc --noCheck --emitDeclarationOnly --declaration --declarationDir dist",
38
+ "clean": "rm -rf dist",
39
+ "deploy": "bun publish --tag latest",
40
+ "prepack": "bun run build"
45
41
  },
46
42
  "dependencies": {
47
- "@astrojs/cloudflare": "catalog:astro-core",
48
- "@astrojs/markdoc": "catalog:astro-plugins",
49
- "@astrojs/mdx": "catalog:astro-core",
50
- "@astrojs/sitemap": "catalog:astro-core",
51
- "@astrojs/starlight": "catalog:astro-core",
52
- "@knitli/docs-components": "workspace:*",
53
- "@nuasite/llm-enhancements": "catalog:astro-plugins",
54
- "astro": "catalog:astro-core",
55
- "astro-cloudflare-pages-headers": "catalog:astro-plugins",
56
- "astro-d2": "catalog:astro-plugins",
57
- "astro-favicons": "catalog:astro-core",
43
+ "@astrojs/cloudflare": "^13.1.1",
44
+ "@astrojs/markdoc": "^1.0.0",
45
+ "@astrojs/mdx": "^5.0.0",
46
+ "@astrojs/sitemap": "^3.6.0",
47
+ "@astrojs/starlight": "^0.38.1",
48
+ "@knitli/docs-components": "1.3.6",
49
+ "@nuasite/llm-enhancements": "^0.18.0",
50
+ "astro": "^6.0.4",
51
+ "astro-cloudflare-pages-headers": "^1.7.7",
52
+ "astro-d2": "^0.10.0",
53
+ "astro-favicons": "3.1.6",
58
54
  "rehype-external-links": "^3.0.0",
59
- "starlight-announcement": "catalog:starlight-plugins",
60
- "starlight-changelogs": "catalog:starlight-plugins",
61
- "starlight-heading-badges": "catalog:starlight-plugins",
62
- "starlight-links-validator": "catalog:starlight-plugins",
63
- "starlight-llms-txt": "catalog:starlight-plugins",
64
- "starlight-page-actions": "catalog:starlight-plugins",
65
- "starlight-plugin-icons": "catalog:starlight-plugins",
66
- "starlight-scroll-to-top": "catalog:starlight-plugins",
67
- "starlight-sidebar-topics": "catalog:starlight-plugins",
68
- "starlight-tags": "catalog:starlight-plugins",
69
- "vite-tsconfig-paths": "catalog:dev-common"
55
+ "starlight-announcement": ">=0.1.1",
56
+ "starlight-changelogs": " >=0.1.0",
57
+ "starlight-heading-badges": ">=0.6.1",
58
+ "starlight-links-validator": ">=0.1.0",
59
+ "starlight-llms-txt": ">=0.8.0",
60
+ "starlight-page-actions": ">=0.1.0",
61
+ "starlight-plugin-icons": ">=0.1.0",
62
+ "starlight-scroll-to-top": ">=0.4.0",
63
+ "starlight-sidebar-topics": ">=0.7.1",
64
+ "starlight-tags": ">=0.4.0",
65
+ "vite-tsconfig-paths": "6.1.1"
70
66
  },
71
67
  "devDependencies": {
72
- "@astrojs/check": "catalog:dev-common",
73
- "@astrojs/compiler-rs": "catalog:astro-core",
74
- "@biomejs/biome": "catalog:dev-common",
75
- "@knitli/tsconfig": "*",
76
- "@types/node": "catalog:types",
77
- "bun": "catalog:dev-common",
78
- "lightningcss": "catalog:optimization",
79
- "sharp": "catalog:astro-core",
80
- "svgo": "catalog:optimization",
81
- "typescript": "catalog:dev-common",
82
- "vite": "catalog:dev-common"
68
+ "@astrojs/check": "^0.9.6",
69
+ "@astrojs/compiler-rs": "^0.1.4",
70
+ "@biomejs/biome": "^2.4.2",
71
+ "@knitli/tsconfig": "0.2.0",
72
+ "@types/node": "^24.0.2",
73
+ "bun": "^1.3.9",
74
+ "lightningcss": "^1.30.2",
75
+ "sharp": "^0.34.5",
76
+ "svgo": "^4.0.0",
77
+ "typescript": "^5.9.3"
83
78
  },
84
79
  "devEngines": {
85
80
  "packageManager": {
@@ -87,5 +82,11 @@
87
82
  "version": "catalog:dev-common",
88
83
  "onFail": "download"
89
84
  }
85
+ },
86
+ "publishConfig": {
87
+ "access": "public",
88
+ "provenance": false,
89
+ "registry": "https://registry.npmjs.org/",
90
+ "tag": "latest"
90
91
  }
91
92
  }
@@ -5,12 +5,11 @@
5
5
  "type": "module",
6
6
  "scripts": {
7
7
  "astro": "bunx astro",
8
- "prepare": "test -f ./node_modules/bun/install.js && node ./node_modules/bun/install.js || true",
9
-
10
8
  "prebuild": "bunx wrangler types; bunx astro sync",
11
9
  "build": "bunx astro build",
12
10
  "deploy": "bun run build && bunx wrangler deploy",
13
11
  "dev": "bunx astro dev",
12
+ "prepare": "test -f ./node_modules/bun/install.js && node ./node_modules/bun/install.js || true",
14
13
  "preview": "bunx astro preview",
15
14
  "wrangler": "bunx wrangler"
16
15
  },
@@ -1,25 +1,54 @@
1
1
  #!/usr/bin/env bun
2
- import { stdout, stdin } from 'node:process';
3
- import { createInterface } from 'node:readline/promises';
4
- import { PIECES, PIECE_NAMES, addPieces, initDocsTemplate } from './index.js';
5
2
 
6
- function parseArgs(argv) {
7
- const flags = {};
8
- const positional = [];
3
+ // SPDX-FileCopyrightText: 2026 Knitli Inc.
4
+ //
5
+ // SPDX-License-Identifier: Apache-2.0
6
+
7
+ import { stdin, stdout } from "node:process";
8
+ import { createInterface } from "node:readline/promises";
9
+ import {
10
+ addPieces,
11
+ type InitOptions,
12
+ initDocsTemplate,
13
+ PIECE_NAMES,
14
+ PIECES,
15
+ type PieceName,
16
+ } from "./index";
17
+
18
+ // ── Arg parsing ──
19
+
20
+ function parseArgs(argv: string[]) {
21
+ const flags: Record<string, string> = {};
22
+ const positional: string[] = [];
23
+
9
24
  for (let i = 0; i < argv.length; i++) {
10
25
  const arg = argv[i];
26
+ if (arg === undefined) {
27
+ continue;
28
+ }
29
+
11
30
  if (arg === "--help" || arg === "-h") {
12
31
  flags.help = "true";
13
32
  } else if (arg === "--force" || arg === "-f") {
14
33
  flags.force = "true";
15
- } else if (arg.startsWith("--") && i + 1 < argv.length) {
16
- flags[arg.slice(2)] = argv[++i];
34
+ } else if (arg.startsWith("--")) {
35
+ const nextArg = argv[i + 1];
36
+ if (nextArg !== undefined) {
37
+ flags[arg.slice(2)] = nextArg;
38
+ i++;
39
+ } else {
40
+ positional.push(arg);
41
+ }
17
42
  } else {
18
43
  positional.push(arg);
19
44
  }
20
45
  }
46
+
21
47
  return { flags, positional };
22
48
  }
49
+
50
+ // ── Help text ──
51
+
23
52
  const HELP = `knitli-docs — scaffold and manage Knitli docs sites
24
53
 
25
54
  Usage:
@@ -28,7 +57,9 @@ Usage:
28
57
  knitli-docs list Show available pieces
29
58
 
30
59
  Pieces:
31
- ${Object.entries(PIECES).map(([name, { description }]) => ` ${name.padEnd(18)} ${description}`).join("\n")}
60
+ ${Object.entries(PIECES)
61
+ .map(([name, { description }]) => ` ${name.padEnd(18)} ${description}`)
62
+ .join("\n")}
32
63
 
33
64
  Options:
34
65
  --app-name <name> Product name (e.g. "Recoco")
@@ -39,37 +70,57 @@ Options:
39
70
  --force, -f Overwrite existing files
40
71
  --help, -h Show this help
41
72
  `;
42
- async function getOptions(flags) {
73
+
74
+ // ── Interactive prompts ──
75
+
76
+ async function getOptions(flags: Record<string, string>): Promise<InitOptions> {
43
77
  const rl = createInterface({ input: stdin, output: stdout });
44
- const ask = async (question, defaultValue) => {
78
+
79
+ const ask = async (
80
+ question: string,
81
+ defaultValue?: string,
82
+ ): Promise<string> => {
45
83
  const suffix = defaultValue ? ` [${defaultValue}]` : "";
46
84
  const answer = await rl.question(`${question}${suffix}: `);
47
85
  return answer.trim() || defaultValue || "";
48
86
  };
87
+
49
88
  try {
50
- const appName = flags["app-name"] || await ask("Product name (e.g. Recoco)");
89
+ const appName =
90
+ flags["app-name"] || (await ask("Product name (e.g. Recoco)"));
51
91
  if (!appName) {
52
92
  console.error("Error: product name is required");
53
93
  process.exit(1);
54
94
  }
55
- const name = flags.name || await ask(
56
- "npm package name",
57
- `@knitli-site/${appName.toLowerCase()}-docs`
58
- );
59
- const description = flags.description || await ask("Short description");
60
- const workerName = flags["worker-name"] || await ask("Worker name", `${appName.toLowerCase()}-docs`);
95
+
96
+ const name =
97
+ flags.name ||
98
+ (await ask(
99
+ "npm package name",
100
+ `@knitli-site/${appName.toLowerCase()}-docs`,
101
+ ));
102
+ const description = flags.description || (await ask("Short description"));
103
+ const workerName =
104
+ flags["worker-name"] ||
105
+ (await ask("Worker name", `${appName.toLowerCase()}-docs`));
106
+
61
107
  return { appName, name, description, workerName };
62
108
  } finally {
63
109
  rl.close();
64
110
  }
65
111
  }
112
+
113
+ // ── Commands ──
114
+
66
115
  async function main() {
67
116
  const { flags, positional } = parseArgs(process.argv.slice(2));
68
117
  const command = positional[0];
118
+
69
119
  if (flags.help || !command) {
70
120
  console.log(HELP);
71
121
  process.exit(0);
72
122
  }
123
+
73
124
  switch (command) {
74
125
  case "list": {
75
126
  console.log("\nAvailable pieces:\n");
@@ -82,55 +133,54 @@ async function main() {
82
133
  console.log();
83
134
  break;
84
135
  }
136
+
85
137
  case "init": {
86
138
  const dir = flags.dir || positional[1] || ".";
87
139
  const options = await getOptions(flags);
88
- console.log(`
89
- Scaffolding into ${dir} ...
90
- `);
140
+ console.log(`\nScaffolding into ${dir} ...\n`);
91
141
  const created = initDocsTemplate(dir, options);
92
- console.log(`
93
- Done — ${created.length} files created`);
142
+ console.log(`\nDone — ${created.length} files created`);
94
143
  break;
95
144
  }
145
+
96
146
  case "add": {
97
147
  const pieces = positional.slice(1).filter((p) => !p.startsWith("-"));
98
148
  if (pieces.length === 0) {
99
149
  console.error(
100
- "Error: specify at least one piece. Run 'knitli-docs list' to see options."
150
+ "Error: specify at least one piece. Run 'knitli-docs list' to see options.",
101
151
  );
102
152
  process.exit(1);
103
153
  }
154
+
104
155
  const invalid = pieces.filter(
105
- (p) => !PIECE_NAMES.includes(p)
156
+ (p) => !PIECE_NAMES.includes(p as PieceName),
106
157
  );
107
158
  if (invalid.length > 0) {
108
159
  console.error(`Error: unknown piece(s): ${invalid.join(", ")}`);
109
160
  console.error(`Available: ${PIECE_NAMES.join(", ")}`);
110
161
  process.exit(1);
111
162
  }
163
+
112
164
  const dir = flags.dir || ".";
113
165
  const options = await getOptions(flags);
114
- console.log(`
115
- Adding ${pieces.join(", ")} to ${dir} ...
116
- `);
166
+ console.log(`\nAdding ${pieces.join(", ")} to ${dir} ...\n`);
117
167
  const created = addPieces(dir, {
118
168
  ...options,
119
- pieces,
120
- force: flags.force === "true"
169
+ pieces: pieces as PieceName[],
170
+ force: flags.force === "true",
121
171
  });
122
- console.log(`
123
- Done — ${created.length} files created`);
172
+ console.log(`\nDone — ${created.length} files created`);
124
173
  break;
125
174
  }
175
+
126
176
  default: {
127
- console.error(`Unknown command: ${command}
128
- `);
177
+ console.error(`Unknown command: ${command}\n`);
129
178
  console.log(HELP);
130
179
  process.exit(1);
131
180
  }
132
181
  }
133
182
  }
183
+
134
184
  main().catch((err) => {
135
185
  console.error(err.message);
136
186
  process.exit(1);