@knitli/astro-docs-template 0.1.1 → 0.1.2
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/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/{src/cli.ts → dist/cli.js} +34 -76
- package/dist/config.d.ts +59 -0
- package/dist/config.d.ts.map +1 -0
- package/{src/config.ts → dist/config.js} +163 -249
- package/dist/index.d.ts +69 -0
- package/dist/index.d.ts.map +1 -0
- package/{src/index.ts → dist/index.js} +41 -127
- package/package.json +14 -7
- package/scaffolding/package.json +3 -1
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
|
@@ -1,43 +1,25 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import { createInterface } from "node:readline/promises";
|
|
7
|
-
import { stdin, stdout } from "node:process";
|
|
8
|
-
import {
|
|
9
|
-
addPieces,
|
|
10
|
-
initDocsTemplate,
|
|
11
|
-
PIECES,
|
|
12
|
-
PIECE_NAMES,
|
|
13
|
-
type InitOptions,
|
|
14
|
-
type PieceName,
|
|
15
|
-
} from "./index.js";
|
|
16
|
-
|
|
17
|
-
// ── Arg parsing ──
|
|
18
|
-
|
|
19
|
-
function parseArgs(argv: string[]) {
|
|
20
|
-
const flags: Record<string, string> = {};
|
|
21
|
-
const positional: string[] = [];
|
|
2
|
+
import { stdout, stdin } from 'node:process';
|
|
3
|
+
import { createInterface } from 'node:readline/promises';
|
|
4
|
+
import { PIECES, PIECE_NAMES, addPieces, initDocsTemplate } from './index.js';
|
|
22
5
|
|
|
6
|
+
function parseArgs(argv) {
|
|
7
|
+
const flags = {};
|
|
8
|
+
const positional = [];
|
|
23
9
|
for (let i = 0; i < argv.length; i++) {
|
|
24
|
-
const arg = argv[i]
|
|
10
|
+
const arg = argv[i];
|
|
25
11
|
if (arg === "--help" || arg === "-h") {
|
|
26
12
|
flags.help = "true";
|
|
27
13
|
} else if (arg === "--force" || arg === "-f") {
|
|
28
14
|
flags.force = "true";
|
|
29
15
|
} else if (arg.startsWith("--") && i + 1 < argv.length) {
|
|
30
|
-
flags[arg.slice(2)] = argv[++i]
|
|
16
|
+
flags[arg.slice(2)] = argv[++i];
|
|
31
17
|
} else {
|
|
32
18
|
positional.push(arg);
|
|
33
19
|
}
|
|
34
20
|
}
|
|
35
|
-
|
|
36
21
|
return { flags, positional };
|
|
37
22
|
}
|
|
38
|
-
|
|
39
|
-
// ── Help text ──
|
|
40
|
-
|
|
41
23
|
const HELP = `knitli-docs — scaffold and manage Knitli docs sites
|
|
42
24
|
|
|
43
25
|
Usage:
|
|
@@ -46,9 +28,7 @@ Usage:
|
|
|
46
28
|
knitli-docs list Show available pieces
|
|
47
29
|
|
|
48
30
|
Pieces:
|
|
49
|
-
${Object.entries(PIECES)
|
|
50
|
-
.map(([name, { description }]) => ` ${name.padEnd(18)} ${description}`)
|
|
51
|
-
.join("\n")}
|
|
31
|
+
${Object.entries(PIECES).map(([name, { description }]) => ` ${name.padEnd(18)} ${description}`).join("\n")}
|
|
52
32
|
|
|
53
33
|
Options:
|
|
54
34
|
--app-name <name> Product name (e.g. "Recoco")
|
|
@@ -59,60 +39,37 @@ Options:
|
|
|
59
39
|
--force, -f Overwrite existing files
|
|
60
40
|
--help, -h Show this help
|
|
61
41
|
`;
|
|
62
|
-
|
|
63
|
-
// ── Interactive prompts ──
|
|
64
|
-
|
|
65
|
-
async function getOptions(
|
|
66
|
-
flags: Record<string, string>,
|
|
67
|
-
): Promise<InitOptions> {
|
|
42
|
+
async function getOptions(flags) {
|
|
68
43
|
const rl = createInterface({ input: stdin, output: stdout });
|
|
69
|
-
|
|
70
|
-
const ask = async (
|
|
71
|
-
question: string,
|
|
72
|
-
defaultValue?: string,
|
|
73
|
-
): Promise<string> => {
|
|
44
|
+
const ask = async (question, defaultValue) => {
|
|
74
45
|
const suffix = defaultValue ? ` [${defaultValue}]` : "";
|
|
75
46
|
const answer = await rl.question(`${question}${suffix}: `);
|
|
76
47
|
return answer.trim() || defaultValue || "";
|
|
77
48
|
};
|
|
78
|
-
|
|
79
49
|
try {
|
|
80
|
-
const appName =
|
|
81
|
-
flags["app-name"] || (await ask("Product name (e.g. Recoco)"));
|
|
50
|
+
const appName = flags["app-name"] || await ask("Product name (e.g. Recoco)");
|
|
82
51
|
if (!appName) {
|
|
83
52
|
console.error("Error: product name is required");
|
|
84
53
|
process.exit(1);
|
|
85
54
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
));
|
|
93
|
-
const description =
|
|
94
|
-
flags.description || (await ask("Short description"));
|
|
95
|
-
const workerName =
|
|
96
|
-
flags["worker-name"] ||
|
|
97
|
-
(await ask("Worker name", `${appName.toLowerCase()}-docs`));
|
|
98
|
-
|
|
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`);
|
|
99
61
|
return { appName, name, description, workerName };
|
|
100
62
|
} finally {
|
|
101
63
|
rl.close();
|
|
102
64
|
}
|
|
103
65
|
}
|
|
104
|
-
|
|
105
|
-
// ── Commands ──
|
|
106
|
-
|
|
107
66
|
async function main() {
|
|
108
67
|
const { flags, positional } = parseArgs(process.argv.slice(2));
|
|
109
68
|
const command = positional[0];
|
|
110
|
-
|
|
111
69
|
if (flags.help || !command) {
|
|
112
70
|
console.log(HELP);
|
|
113
71
|
process.exit(0);
|
|
114
72
|
}
|
|
115
|
-
|
|
116
73
|
switch (command) {
|
|
117
74
|
case "list": {
|
|
118
75
|
console.log("\nAvailable pieces:\n");
|
|
@@ -125,54 +82,55 @@ async function main() {
|
|
|
125
82
|
console.log();
|
|
126
83
|
break;
|
|
127
84
|
}
|
|
128
|
-
|
|
129
85
|
case "init": {
|
|
130
86
|
const dir = flags.dir || positional[1] || ".";
|
|
131
87
|
const options = await getOptions(flags);
|
|
132
|
-
console.log(
|
|
88
|
+
console.log(`
|
|
89
|
+
Scaffolding into ${dir} ...
|
|
90
|
+
`);
|
|
133
91
|
const created = initDocsTemplate(dir, options);
|
|
134
|
-
console.log(
|
|
92
|
+
console.log(`
|
|
93
|
+
Done — ${created.length} files created`);
|
|
135
94
|
break;
|
|
136
95
|
}
|
|
137
|
-
|
|
138
96
|
case "add": {
|
|
139
97
|
const pieces = positional.slice(1).filter((p) => !p.startsWith("-"));
|
|
140
98
|
if (pieces.length === 0) {
|
|
141
99
|
console.error(
|
|
142
|
-
"Error: specify at least one piece. Run 'knitli-docs list' to see options."
|
|
100
|
+
"Error: specify at least one piece. Run 'knitli-docs list' to see options."
|
|
143
101
|
);
|
|
144
102
|
process.exit(1);
|
|
145
103
|
}
|
|
146
|
-
|
|
147
104
|
const invalid = pieces.filter(
|
|
148
|
-
(p) => !PIECE_NAMES.includes(p
|
|
105
|
+
(p) => !PIECE_NAMES.includes(p)
|
|
149
106
|
);
|
|
150
107
|
if (invalid.length > 0) {
|
|
151
108
|
console.error(`Error: unknown piece(s): ${invalid.join(", ")}`);
|
|
152
109
|
console.error(`Available: ${PIECE_NAMES.join(", ")}`);
|
|
153
110
|
process.exit(1);
|
|
154
111
|
}
|
|
155
|
-
|
|
156
112
|
const dir = flags.dir || ".";
|
|
157
113
|
const options = await getOptions(flags);
|
|
158
|
-
console.log(
|
|
114
|
+
console.log(`
|
|
115
|
+
Adding ${pieces.join(", ")} to ${dir} ...
|
|
116
|
+
`);
|
|
159
117
|
const created = addPieces(dir, {
|
|
160
118
|
...options,
|
|
161
|
-
pieces
|
|
162
|
-
force: flags.force === "true"
|
|
119
|
+
pieces,
|
|
120
|
+
force: flags.force === "true"
|
|
163
121
|
});
|
|
164
|
-
console.log(
|
|
122
|
+
console.log(`
|
|
123
|
+
Done — ${created.length} files created`);
|
|
165
124
|
break;
|
|
166
125
|
}
|
|
167
|
-
|
|
168
126
|
default: {
|
|
169
|
-
console.error(`Unknown command: ${command}
|
|
127
|
+
console.error(`Unknown command: ${command}
|
|
128
|
+
`);
|
|
170
129
|
console.log(HELP);
|
|
171
130
|
process.exit(1);
|
|
172
131
|
}
|
|
173
132
|
}
|
|
174
133
|
}
|
|
175
|
-
|
|
176
134
|
main().catch((err) => {
|
|
177
135
|
console.error(err.message);
|
|
178
136
|
process.exit(1);
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { OutgoingHttpHeaders } from "node:http2";
|
|
2
|
+
type defaultIntegration = "sitemap" | "astroD2" | "markdoc" | "mdx" | "favicons" | "cloudflare-pages-headers";
|
|
3
|
+
export declare const headlineLogoDark: string, headlineLogoLight: string, variables: string, docsStyle: string, faviconIco: string, faviconSvg: string;
|
|
4
|
+
declare const shikiCfg: {
|
|
5
|
+
themes: {
|
|
6
|
+
light: "catppuccin-latte";
|
|
7
|
+
dark: "catppuccin-mocha";
|
|
8
|
+
};
|
|
9
|
+
bundledLangs: string[];
|
|
10
|
+
langAlias: {
|
|
11
|
+
js: string;
|
|
12
|
+
md: string;
|
|
13
|
+
py: string;
|
|
14
|
+
rs: string;
|
|
15
|
+
sh: string;
|
|
16
|
+
yml: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
declare const imgDomains: {
|
|
20
|
+
protocol: string;
|
|
21
|
+
hostname: string;
|
|
22
|
+
}[];
|
|
23
|
+
export interface DocsTemplateOptions {
|
|
24
|
+
appName: string;
|
|
25
|
+
description: string;
|
|
26
|
+
llmConfig: {
|
|
27
|
+
llmDescription: string;
|
|
28
|
+
promotePatterns: string[];
|
|
29
|
+
demotePatterns: string[];
|
|
30
|
+
};
|
|
31
|
+
rootDir: string;
|
|
32
|
+
shikiConfig?: typeof shikiCfg;
|
|
33
|
+
logoDark?: string;
|
|
34
|
+
logoLight?: string;
|
|
35
|
+
imageDomains?: typeof imgDomains;
|
|
36
|
+
is_codeweaver?: boolean;
|
|
37
|
+
sitemapFilter?: (page: string) => boolean;
|
|
38
|
+
linkValidationConfig?: Record<string, unknown>;
|
|
39
|
+
sidebarConfig?: {
|
|
40
|
+
label: string;
|
|
41
|
+
autogenerate: {
|
|
42
|
+
directory: string;
|
|
43
|
+
};
|
|
44
|
+
}[];
|
|
45
|
+
unwantedPlugins?: string[];
|
|
46
|
+
pluginConfigs?: Record<string, any>;
|
|
47
|
+
unwantedIntegrations?: defaultIntegration[];
|
|
48
|
+
integrationConfigs?: Record<string, any>;
|
|
49
|
+
headersConfig?: OutgoingHttpHeaders;
|
|
50
|
+
}
|
|
51
|
+
export type IntegrationOptions = Pick<DocsTemplateOptions, "appName" | "sitemapFilter" | "integrationConfigs"> & {
|
|
52
|
+
unwantedIntegrations?: defaultIntegration[];
|
|
53
|
+
};
|
|
54
|
+
export type PluginOptions = Pick<DocsTemplateOptions, "appName" | "llmConfig" | "pluginConfigs"> & {
|
|
55
|
+
unwantedPlugins?: string[];
|
|
56
|
+
};
|
|
57
|
+
export default function createConfig(options: DocsTemplateOptions): import("astro").AstroUserConfig<never, never, never>;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AA6BtD,KAAK,kBAAkB,GACnB,SAAS,GACT,SAAS,GACT,SAAS,GACT,KAAK,GACL,UAAU,GACV,0BAA0B,CAAC;AAQ/B,eAAO,MACL,gBAAgB,UAChB,iBAAiB,UACjB,SAAS,UACT,SAAS,UACT,UAAU,UACV,UAAU,QACE,CAAC;AAEf,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;CAyBb,CAAC;AAEF,QAAA,MAAM,UAAU;;;GAMf,CAAC;AA8DF,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE;QACT,cAAc,EAAE,MAAM,CAAC;QACvB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,cAAc,EAAE,MAAM,EAAE,CAAC;KAC1B,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,QAAQ,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,UAAU,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC1C,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE;QACd,KAAK,EAAE,MAAM,CAAC;QACd,YAAY,EAAE;YAAE,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;KACrC,EAAE,CAAC;IACJ,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,oBAAoB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAE5C,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACzC,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACrC;AAED,MAAM,MAAM,kBAAkB,GAAG,IAAI,CACnC,mBAAmB,EACnB,SAAS,GAAG,eAAe,GAAG,oBAAoB,CACnD,GAAG;IAAE,oBAAoB,CAAC,EAAE,kBAAkB,EAAE,CAAA;CAAE,CAAC;AA+DpD,MAAM,MAAM,aAAa,GAAG,IAAI,CAC9B,mBAAmB,EACnB,SAAS,GAAG,WAAW,GAAG,eAAe,CAC1C,GAAG;IAAE,eAAe,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAoEnC,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,OAAO,EAAE,mBAAmB,wDAuOhE"}
|
|
@@ -1,65 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import cloudflare from '@astrojs/cloudflare';
|
|
2
|
+
import markdoc from '@astrojs/markdoc';
|
|
3
|
+
import mdx from '@astrojs/mdx';
|
|
4
|
+
import sitemap from '@astrojs/sitemap';
|
|
5
|
+
import starlight from '@astrojs/starlight';
|
|
6
|
+
import { DocsAssets } from '@knitli/docs-components';
|
|
7
|
+
import llmEnhancements from '@nuasite/llm-enhancements';
|
|
8
|
+
import { fontProviders, defineConfig } from 'astro/config';
|
|
9
|
+
import cloudflarePagesHeaders from 'astro-cloudflare-pages-headers';
|
|
10
|
+
import astroD2 from 'astro-d2';
|
|
11
|
+
import favicons from 'astro-favicons';
|
|
12
|
+
import rehypeExternalLinks from 'rehype-external-links';
|
|
13
|
+
import starlightAnnouncement from 'starlight-announcement';
|
|
14
|
+
import starlightChangelogs from 'starlight-changelogs';
|
|
15
|
+
import starlightHeadingBadges from 'starlight-heading-badges';
|
|
16
|
+
import starlightLinksValidator from 'starlight-links-validator';
|
|
17
|
+
import starlightLlmsText from 'starlight-llms-txt';
|
|
18
|
+
import starlightPageActions from 'starlight-page-actions';
|
|
19
|
+
import { starlightIconsIntegration, starlightIconsPlugin } from 'starlight-plugin-icons';
|
|
20
|
+
import starlightScrollToTop from 'starlight-scroll-to-top';
|
|
21
|
+
import starlightSidebarTopics from 'starlight-sidebar-topics';
|
|
22
|
+
import starlightTags from 'starlight-tags';
|
|
23
|
+
import { searchForWorkspaceRoot } from 'vite';
|
|
24
|
+
import viteTsconfigPaths from 'vite-tsconfig-paths';
|
|
4
25
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import type { OutgoingHttpHeaders } from "node:http2";
|
|
8
|
-
import cloudflare from "@astrojs/cloudflare";
|
|
9
|
-
import markdoc from "@astrojs/markdoc";
|
|
10
|
-
import mdx from "@astrojs/mdx";
|
|
11
|
-
import sitemap from "@astrojs/sitemap";
|
|
12
|
-
import starlight from "@astrojs/starlight";
|
|
13
|
-
import { DocsAssets } from "@knitli/docs-components";
|
|
14
|
-
import llmEnhancements from "@nuasite/llm-enhancements";
|
|
15
|
-
import { defineConfig, fontProviders } from "astro/config";
|
|
16
|
-
import cloudflarePagesHeaders from "astro-cloudflare-pages-headers";
|
|
17
|
-
import astroD2 from "astro-d2";
|
|
18
|
-
import favicons from "astro-favicons";
|
|
19
|
-
import rehypeExternalLinks from "rehype-external-links";
|
|
20
|
-
import starlightAnnouncement from "starlight-announcement";
|
|
21
|
-
import starlightChangelogs from "starlight-changelogs";
|
|
22
|
-
import starlightHeadingBadges from "starlight-heading-badges";
|
|
23
|
-
import starlightLinksValidator from "starlight-links-validator";
|
|
24
|
-
import starlightLlmsText from "starlight-llms-txt";
|
|
25
|
-
import starlightPageActions from "starlight-page-actions";
|
|
26
|
-
import {
|
|
27
|
-
starlightIconsIntegration,
|
|
28
|
-
starlightIconsPlugin,
|
|
29
|
-
} from "starlight-plugin-icons";
|
|
30
|
-
import starlightScrollToTop from "starlight-scroll-to-top";
|
|
31
|
-
import starlightSidebarTopics from "starlight-sidebar-topics";
|
|
32
|
-
import starlightTags from "starlight-tags";
|
|
33
|
-
import { searchForWorkspaceRoot } from "vite";
|
|
34
|
-
import viteTsconfigPaths from "vite-tsconfig-paths";
|
|
35
|
-
|
|
36
|
-
type defaultIntegration =
|
|
37
|
-
| "sitemap"
|
|
38
|
-
| "astroD2"
|
|
39
|
-
| "markdoc"
|
|
40
|
-
| "mdx"
|
|
41
|
-
| "favicons"
|
|
42
|
-
| "cloudflare-pages-headers";
|
|
43
|
-
|
|
44
|
-
function nonNullable<T>(value: T): value is NonNullable<T> {
|
|
26
|
+
function nonNullable(value) {
|
|
45
27
|
return value != null;
|
|
46
28
|
}
|
|
47
|
-
|
|
48
|
-
// ── Defaults (defined before interface so `typeof` references work) ──
|
|
49
|
-
|
|
50
|
-
export const {
|
|
29
|
+
const {
|
|
51
30
|
headlineLogoDark,
|
|
52
31
|
headlineLogoLight,
|
|
53
32
|
variables,
|
|
54
33
|
docsStyle,
|
|
55
34
|
faviconIco,
|
|
56
|
-
faviconSvg
|
|
35
|
+
faviconSvg
|
|
57
36
|
} = DocsAssets;
|
|
58
|
-
|
|
59
37
|
const shikiCfg = {
|
|
60
38
|
themes: {
|
|
61
|
-
light: "catppuccin-latte"
|
|
62
|
-
dark: "catppuccin-mocha"
|
|
39
|
+
light: "catppuccin-latte",
|
|
40
|
+
dark: "catppuccin-mocha"
|
|
63
41
|
},
|
|
64
42
|
bundledLangs: [
|
|
65
43
|
"ansi",
|
|
@@ -71,7 +49,7 @@ const shikiCfg = {
|
|
|
71
49
|
"rust",
|
|
72
50
|
"toml",
|
|
73
51
|
"typescript",
|
|
74
|
-
"yaml"
|
|
52
|
+
"yaml"
|
|
75
53
|
],
|
|
76
54
|
langAlias: {
|
|
77
55
|
js: "typescript",
|
|
@@ -79,64 +57,61 @@ const shikiCfg = {
|
|
|
79
57
|
py: "python",
|
|
80
58
|
rs: "rust",
|
|
81
59
|
sh: "bash",
|
|
82
|
-
yml: "yaml"
|
|
83
|
-
}
|
|
60
|
+
yml: "yaml"
|
|
61
|
+
}
|
|
84
62
|
};
|
|
85
|
-
|
|
86
63
|
const imgDomains = [
|
|
87
64
|
{ protocol: "https", hostname: "ui-avatars.com" },
|
|
88
65
|
{ protocol: "https", hostname: "knitli.com" },
|
|
89
66
|
{ protocol: "https", hostname: "*.knitli.com" },
|
|
90
67
|
{ protocol: "https", hostname: "*.githubusercontent.com" },
|
|
91
|
-
{ protocol: "https", hostname: "*.cloudflare.com" }
|
|
68
|
+
{ protocol: "https", hostname: "*.cloudflare.com" }
|
|
92
69
|
];
|
|
93
|
-
|
|
94
70
|
const defaultFontConfig = [
|
|
95
71
|
{
|
|
96
72
|
provider: fontProviders.google(),
|
|
97
73
|
name: "DM Mono",
|
|
98
74
|
cssVariable: "--font-sans",
|
|
99
|
-
weights: [400, 500, 700]
|
|
100
|
-
styles: ["normal", "italic"]
|
|
101
|
-
subsets: ["latin"]
|
|
102
|
-
formats: ["woff2"]
|
|
75
|
+
weights: [400, 500, 700],
|
|
76
|
+
styles: ["normal", "italic"],
|
|
77
|
+
subsets: ["latin"],
|
|
78
|
+
formats: ["woff2"],
|
|
103
79
|
fallbacks: [
|
|
104
80
|
"Roboto Mono",
|
|
105
81
|
"Menlo",
|
|
106
82
|
"Consolas",
|
|
107
83
|
"DejaVu Sans Mono",
|
|
108
|
-
"monospace"
|
|
109
|
-
]
|
|
84
|
+
"monospace"
|
|
85
|
+
]
|
|
110
86
|
},
|
|
111
87
|
{
|
|
112
88
|
provider: fontProviders.google(),
|
|
113
89
|
name: "JetBrains Mono",
|
|
114
90
|
cssVariable: "--font-mono",
|
|
115
|
-
weights: [400, 500, 700]
|
|
116
|
-
styles: ["normal", "italic"]
|
|
117
|
-
subsets: ["latin"]
|
|
118
|
-
formats: ["woff2"]
|
|
91
|
+
weights: [400, 500, 700],
|
|
92
|
+
styles: ["normal", "italic"],
|
|
93
|
+
subsets: ["latin"],
|
|
94
|
+
formats: ["woff2"],
|
|
119
95
|
fallbacks: [
|
|
120
96
|
"DM Mono",
|
|
121
97
|
"Roboto Mono",
|
|
122
98
|
"Menlo",
|
|
123
99
|
"Consolas",
|
|
124
100
|
"DejaVu Sans Mono",
|
|
125
|
-
"monospace"
|
|
126
|
-
]
|
|
127
|
-
}
|
|
101
|
+
"monospace"
|
|
102
|
+
]
|
|
103
|
+
}
|
|
128
104
|
];
|
|
129
|
-
|
|
130
105
|
const codeweaverFontConfig = [
|
|
131
106
|
{ ...defaultFontConfig[1], cssVariable: "--font-sans" },
|
|
132
107
|
{
|
|
133
108
|
provider: fontProviders.google(),
|
|
134
109
|
name: "IBM Plex Mono",
|
|
135
110
|
cssVariable: "--font-mono",
|
|
136
|
-
weights: [400, 500, 700]
|
|
137
|
-
styles: ["normal", "italic"]
|
|
138
|
-
subsets: ["latin"]
|
|
139
|
-
formats: ["woff2"]
|
|
111
|
+
weights: [400, 500, 700],
|
|
112
|
+
styles: ["normal", "italic"],
|
|
113
|
+
subsets: ["latin"],
|
|
114
|
+
formats: ["woff2"],
|
|
140
115
|
fallbacks: [
|
|
141
116
|
"JetBrains Mono",
|
|
142
117
|
"DM Mono",
|
|
@@ -144,53 +119,16 @@ const codeweaverFontConfig = [
|
|
|
144
119
|
"Menlo",
|
|
145
120
|
"Consolas",
|
|
146
121
|
"DejaVu Sans Mono",
|
|
147
|
-
"monospace"
|
|
148
|
-
]
|
|
149
|
-
}
|
|
122
|
+
"monospace"
|
|
123
|
+
]
|
|
124
|
+
}
|
|
150
125
|
];
|
|
151
|
-
|
|
152
|
-
// ── Public interface ──
|
|
153
|
-
|
|
154
|
-
export interface DocsTemplateOptions {
|
|
155
|
-
appName: string;
|
|
156
|
-
description: string;
|
|
157
|
-
llmConfig: {
|
|
158
|
-
llmDescription: string;
|
|
159
|
-
promotePatterns: string[];
|
|
160
|
-
demotePatterns: string[];
|
|
161
|
-
};
|
|
162
|
-
rootDir: string;
|
|
163
|
-
shikiConfig?: typeof shikiCfg;
|
|
164
|
-
logoDark?: string;
|
|
165
|
-
logoLight?: string;
|
|
166
|
-
imageDomains?: typeof imgDomains;
|
|
167
|
-
is_codeweaver?: boolean;
|
|
168
|
-
sitemapFilter?: (page: string) => boolean;
|
|
169
|
-
linkValidationConfig?: Record<string, unknown>;
|
|
170
|
-
sidebarConfig?: {
|
|
171
|
-
label: string;
|
|
172
|
-
autogenerate: { directory: string };
|
|
173
|
-
}[];
|
|
174
|
-
unwantedPlugins?: string[];
|
|
175
|
-
// biome-ignore lint/suspicious/noExplicitAny: plugin configs are opaque pass-throughs
|
|
176
|
-
pluginConfigs?: Record<string, any>;
|
|
177
|
-
unwantedIntegrations?: defaultIntegration[];
|
|
178
|
-
// biome-ignore lint/suspicious/noExplicitAny: integration configs are opaque pass-throughs
|
|
179
|
-
integrationConfigs?: Record<string, any>;
|
|
180
|
-
headersConfig?: OutgoingHttpHeaders;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
export type IntegrationOptions = Pick<
|
|
184
|
-
DocsTemplateOptions,
|
|
185
|
-
"appName" | "sitemapFilter" | "integrationConfigs"
|
|
186
|
-
> & { unwantedIntegrations?: defaultIntegration[] };
|
|
187
|
-
|
|
188
|
-
const getIntegrations = (options: IntegrationOptions) => {
|
|
126
|
+
const getIntegrations = (options) => {
|
|
189
127
|
const {
|
|
190
128
|
appName,
|
|
191
129
|
sitemapFilter,
|
|
192
130
|
integrationConfigs,
|
|
193
|
-
unwantedIntegrations = []
|
|
131
|
+
unwantedIntegrations = []
|
|
194
132
|
} = options;
|
|
195
133
|
const defaultIntegrations = [
|
|
196
134
|
astroD2({ skipGeneration: true }),
|
|
@@ -201,57 +139,45 @@ const getIntegrations = (options: IntegrationOptions) => {
|
|
|
201
139
|
name: `${appName} Docs by Knitli`,
|
|
202
140
|
short_name: `${appName} Docs`,
|
|
203
141
|
input: {
|
|
204
|
-
favicons: [faviconSvg]
|
|
205
|
-
}
|
|
142
|
+
favicons: [faviconSvg]
|
|
143
|
+
}
|
|
206
144
|
}),
|
|
207
145
|
cloudflarePagesHeaders({}),
|
|
208
146
|
sitemap({
|
|
209
147
|
filter: sitemapFilter || ((page) => !/\^\/(?!cdn-cgi\/)/.test(page)),
|
|
210
148
|
changefreq: "weekly",
|
|
211
149
|
priority: 0.4,
|
|
212
|
-
lastmod: new Date(),
|
|
150
|
+
lastmod: /* @__PURE__ */ new Date(),
|
|
213
151
|
namespaces: {
|
|
214
152
|
image: false,
|
|
215
|
-
video: false
|
|
216
|
-
}
|
|
217
|
-
})
|
|
153
|
+
video: false
|
|
154
|
+
}
|
|
155
|
+
})
|
|
218
156
|
];
|
|
219
|
-
|
|
220
157
|
const filtered = defaultIntegrations.filter((integration) => {
|
|
221
158
|
const name = integration?.name;
|
|
222
|
-
return !name || !unwantedIntegrations.includes(name
|
|
159
|
+
return !name || !unwantedIntegrations.includes(name);
|
|
223
160
|
});
|
|
224
|
-
|
|
225
161
|
if (!integrationConfigs) return filtered;
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}
|
|
243
|
-
})
|
|
244
|
-
.filter(nonNullable);
|
|
245
|
-
|
|
162
|
+
const overrides = Object.entries(integrationConfigs).map(([integrationName, config]) => {
|
|
163
|
+
switch (integrationName) {
|
|
164
|
+
case "astroD2":
|
|
165
|
+
return astroD2(config);
|
|
166
|
+
case "markdoc":
|
|
167
|
+
return markdoc(config);
|
|
168
|
+
case "mdx":
|
|
169
|
+
return mdx(config);
|
|
170
|
+
case "favicons":
|
|
171
|
+
return favicons(config);
|
|
172
|
+
case "sitemap":
|
|
173
|
+
return sitemap(config);
|
|
174
|
+
default:
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
}).filter(nonNullable);
|
|
246
178
|
return [...filtered, ...overrides];
|
|
247
179
|
};
|
|
248
|
-
|
|
249
|
-
export type PluginOptions = Pick<
|
|
250
|
-
DocsTemplateOptions,
|
|
251
|
-
"appName" | "llmConfig" | "pluginConfigs"
|
|
252
|
-
> & { unwantedPlugins?: string[] };
|
|
253
|
-
|
|
254
|
-
const get_plugins = (options: PluginOptions) => {
|
|
180
|
+
const get_plugins = (options) => {
|
|
255
181
|
const { appName, llmConfig, pluginConfigs, unwantedPlugins = [] } = options;
|
|
256
182
|
const defaultPlugins = [
|
|
257
183
|
starlightAnnouncement(),
|
|
@@ -263,12 +189,10 @@ const get_plugins = (options: PluginOptions) => {
|
|
|
263
189
|
starlightPageActions({
|
|
264
190
|
baseUrl: `https://docs.knitli.com/${appName.toLowerCase()}`,
|
|
265
191
|
actions: { claude: true, chatgpt: true, markdown: true },
|
|
266
|
-
share: true
|
|
192
|
+
share: true
|
|
267
193
|
}),
|
|
268
194
|
starlightTags({ onInlineTagsNotFound: "warn" }),
|
|
269
|
-
pluginConfigs?.starlightSidebarTopics
|
|
270
|
-
? starlightSidebarTopics(pluginConfigs.starlightSidebarTopics)
|
|
271
|
-
: null,
|
|
195
|
+
pluginConfigs?.starlightSidebarTopics ? starlightSidebarTopics(pluginConfigs.starlightSidebarTopics) : null,
|
|
272
196
|
starlightScrollToTop({ showOnHomepage: false }),
|
|
273
197
|
// We need to configure starlight-tags with a tags.yml.
|
|
274
198
|
//starlightTags(),
|
|
@@ -280,44 +204,35 @@ const get_plugins = (options: PluginOptions) => {
|
|
|
280
204
|
minify: {
|
|
281
205
|
whitespace: true,
|
|
282
206
|
note: true,
|
|
283
|
-
details: true
|
|
284
|
-
},
|
|
285
|
-
}),
|
|
286
|
-
];
|
|
287
|
-
|
|
288
|
-
const filtered = defaultPlugins
|
|
289
|
-
.filter(nonNullable)
|
|
290
|
-
.filter((plugin) => !unwantedPlugins.includes(plugin.name));
|
|
291
|
-
|
|
292
|
-
if (!pluginConfigs) return filtered;
|
|
293
|
-
|
|
294
|
-
const overrides = Object.entries(pluginConfigs)
|
|
295
|
-
.map(([pluginName, config]) => {
|
|
296
|
-
switch (pluginName) {
|
|
297
|
-
case "starlightAnnouncement":
|
|
298
|
-
return starlightAnnouncement(config);
|
|
299
|
-
case "starlightIconsIntegration":
|
|
300
|
-
return starlightIconsIntegration(config);
|
|
301
|
-
case "starlightIconsPlugin":
|
|
302
|
-
return starlightIconsPlugin(config);
|
|
303
|
-
case "starlightLinksValidator":
|
|
304
|
-
return starlightLinksValidator(config);
|
|
305
|
-
case "starlightPageActions":
|
|
306
|
-
return starlightPageActions(config);
|
|
307
|
-
case "starlightTags":
|
|
308
|
-
return starlightTags(config);
|
|
309
|
-
case "starlightScrollToTop":
|
|
310
|
-
return starlightScrollToTop(config);
|
|
311
|
-
default:
|
|
312
|
-
return null;
|
|
207
|
+
details: true
|
|
313
208
|
}
|
|
314
209
|
})
|
|
315
|
-
|
|
316
|
-
|
|
210
|
+
];
|
|
211
|
+
const filtered = defaultPlugins.filter(nonNullable).filter((plugin) => !unwantedPlugins.includes(plugin.name));
|
|
212
|
+
if (!pluginConfigs) return filtered;
|
|
213
|
+
const overrides = Object.entries(pluginConfigs).map(([pluginName, config]) => {
|
|
214
|
+
switch (pluginName) {
|
|
215
|
+
case "starlightAnnouncement":
|
|
216
|
+
return starlightAnnouncement(config);
|
|
217
|
+
case "starlightIconsIntegration":
|
|
218
|
+
return starlightIconsIntegration(config);
|
|
219
|
+
case "starlightIconsPlugin":
|
|
220
|
+
return starlightIconsPlugin(config);
|
|
221
|
+
case "starlightLinksValidator":
|
|
222
|
+
return starlightLinksValidator(config);
|
|
223
|
+
case "starlightPageActions":
|
|
224
|
+
return starlightPageActions(config);
|
|
225
|
+
case "starlightTags":
|
|
226
|
+
return starlightTags(config);
|
|
227
|
+
case "starlightScrollToTop":
|
|
228
|
+
return starlightScrollToTop(config);
|
|
229
|
+
default:
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
}).filter(nonNullable);
|
|
317
233
|
return [...filtered, ...overrides];
|
|
318
234
|
};
|
|
319
|
-
|
|
320
|
-
export default function createConfig(options: DocsTemplateOptions) {
|
|
235
|
+
function createConfig(options) {
|
|
321
236
|
const {
|
|
322
237
|
appName,
|
|
323
238
|
description,
|
|
@@ -334,59 +249,57 @@ export default function createConfig(options: DocsTemplateOptions) {
|
|
|
334
249
|
integrationConfigs,
|
|
335
250
|
unwantedIntegrations,
|
|
336
251
|
unwantedPlugins,
|
|
337
|
-
headersConfig
|
|
252
|
+
headersConfig
|
|
338
253
|
} = options;
|
|
339
|
-
|
|
340
|
-
// https://astro.build/config
|
|
341
254
|
return defineConfig({
|
|
342
255
|
site: "https://docs.knitli.com",
|
|
343
256
|
base: `/${appName.toLowerCase()}/`,
|
|
344
257
|
adapter: cloudflare({
|
|
345
258
|
prerenderEnvironment: "workerd",
|
|
346
259
|
experimental: {
|
|
347
|
-
headersAndRedirectsDevModeSupport: true
|
|
260
|
+
headersAndRedirectsDevModeSupport: true
|
|
348
261
|
},
|
|
349
262
|
configPath: `${rootDir}/wrangler.jsonc`,
|
|
350
|
-
imageService: "compile"
|
|
263
|
+
imageService: "compile"
|
|
351
264
|
}),
|
|
352
265
|
// Image optimization
|
|
353
266
|
image: {
|
|
354
267
|
service: {
|
|
355
|
-
entrypoint: "astro/assets/services/sharp"
|
|
268
|
+
entrypoint: "astro/assets/services/sharp"
|
|
356
269
|
},
|
|
357
270
|
responsiveStyles: true,
|
|
358
271
|
layout: "constrained",
|
|
359
|
-
remotePatterns: imageDomains
|
|
272
|
+
remotePatterns: imageDomains
|
|
360
273
|
},
|
|
361
274
|
compressHTML: true,
|
|
362
275
|
// biome-ignore lint/suspicious/noExplicitAny: Astro's FontFamily generic inference doesn't match spread patterns
|
|
363
|
-
fonts:
|
|
276
|
+
fonts: is_codeweaver ? codeweaverFontConfig : defaultFontConfig,
|
|
364
277
|
// Build optimizations
|
|
365
278
|
build: {
|
|
366
279
|
inlineStylesheets: "auto",
|
|
367
|
-
assets: "_astro"
|
|
280
|
+
assets: "_astro"
|
|
368
281
|
},
|
|
369
282
|
markdown: {
|
|
370
283
|
shikiConfig: Object.fromEntries(
|
|
371
|
-
Object.entries(shikiConfig).filter(([key]) => key !== "bundledLangs")
|
|
284
|
+
Object.entries(shikiConfig).filter(([key]) => key !== "bundledLangs")
|
|
372
285
|
),
|
|
373
286
|
rehypePlugins: [
|
|
374
287
|
rehypeExternalLinks({
|
|
375
288
|
content: { type: "text", value: " ↗" },
|
|
376
|
-
rel: ["nofollow"]
|
|
377
|
-
})
|
|
378
|
-
]
|
|
289
|
+
rel: ["nofollow"]
|
|
290
|
+
})
|
|
291
|
+
]
|
|
379
292
|
},
|
|
380
293
|
server: {
|
|
381
|
-
headers: headersConfig
|
|
294
|
+
headers: headersConfig
|
|
382
295
|
},
|
|
383
296
|
trailingSlash: "always",
|
|
384
297
|
// Vite configuration for better bundling
|
|
385
298
|
vite: {
|
|
386
299
|
server: {
|
|
387
300
|
fs: {
|
|
388
|
-
allow: [searchForWorkspaceRoot(rootDir)]
|
|
389
|
-
}
|
|
301
|
+
allow: [searchForWorkspaceRoot(rootDir)]
|
|
302
|
+
}
|
|
390
303
|
},
|
|
391
304
|
assetsInclude: [
|
|
392
305
|
"src/*.webp",
|
|
@@ -394,11 +307,11 @@ export default function createConfig(options: DocsTemplateOptions) {
|
|
|
394
307
|
"src/*.jpg",
|
|
395
308
|
"src/*.jpeg",
|
|
396
309
|
"src/*.svg",
|
|
397
|
-
"src/*.avif"
|
|
310
|
+
"src/*.avif"
|
|
398
311
|
],
|
|
399
312
|
plugins: [viteTsconfigPaths({ loose: true })],
|
|
400
313
|
define: {
|
|
401
|
-
"import.meta.env.PUBLIC_DOCS_PRODUCT": JSON.stringify(appName)
|
|
314
|
+
"import.meta.env.PUBLIC_DOCS_PRODUCT": JSON.stringify(appName)
|
|
402
315
|
},
|
|
403
316
|
build: {
|
|
404
317
|
cssMinify: "lightningcss",
|
|
@@ -411,7 +324,7 @@ export default function createConfig(options: DocsTemplateOptions) {
|
|
|
411
324
|
dir: `${rootDir}/dist/_astro/`,
|
|
412
325
|
compact: true,
|
|
413
326
|
interop: "esModule",
|
|
414
|
-
experimentalMinChunkSize:
|
|
327
|
+
experimentalMinChunkSize: 1e4,
|
|
415
328
|
banner: `
|
|
416
329
|
/* SPDX-FileCopyrightText: 2026 Knitli Inc.
|
|
417
330
|
* SPDX-License-Identifier: MIT OR Apache-2.0
|
|
@@ -423,22 +336,22 @@ export default function createConfig(options: DocsTemplateOptions) {
|
|
|
423
336
|
arrowFunctions: true,
|
|
424
337
|
constBindings: true,
|
|
425
338
|
objectShorthand: true,
|
|
426
|
-
symbols: true
|
|
339
|
+
symbols: true
|
|
427
340
|
},
|
|
428
341
|
entryFileNames: "assets/[name]-[hash].js",
|
|
429
342
|
chunkFileNames: "assets/[name]-[hash].js",
|
|
430
|
-
assetFileNames: "assets/[name]-[hash][extname]"
|
|
343
|
+
assetFileNames: "assets/[name]-[hash][extname]"
|
|
431
344
|
},
|
|
432
|
-
treeshake: "smallest"
|
|
345
|
+
treeshake: "smallest"
|
|
433
346
|
},
|
|
434
|
-
ssr: false
|
|
347
|
+
ssr: false
|
|
435
348
|
},
|
|
436
349
|
css: {
|
|
437
|
-
lightningcss: {}
|
|
438
|
-
}
|
|
350
|
+
lightningcss: {}
|
|
351
|
+
}
|
|
439
352
|
},
|
|
440
353
|
prefetch: {
|
|
441
|
-
defaultStrategy: "viewport"
|
|
354
|
+
defaultStrategy: "viewport"
|
|
442
355
|
},
|
|
443
356
|
prerenderConflictBehavior: "warn",
|
|
444
357
|
experimental: {
|
|
@@ -447,7 +360,7 @@ export default function createConfig(options: DocsTemplateOptions) {
|
|
|
447
360
|
contentIntellisense: true,
|
|
448
361
|
queuedRendering: {
|
|
449
362
|
contentCache: true,
|
|
450
|
-
enabled: true
|
|
363
|
+
enabled: true
|
|
451
364
|
},
|
|
452
365
|
rustCompiler: true,
|
|
453
366
|
svgo: {
|
|
@@ -456,14 +369,13 @@ export default function createConfig(options: DocsTemplateOptions) {
|
|
|
456
369
|
name: "preset-default",
|
|
457
370
|
params: {
|
|
458
371
|
overrides: {
|
|
459
|
-
removeMetadata: false
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
]
|
|
464
|
-
}
|
|
372
|
+
removeMetadata: false
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
]
|
|
377
|
+
}
|
|
465
378
|
},
|
|
466
|
-
|
|
467
379
|
// Static site generation for Cloudflare
|
|
468
380
|
output: "static",
|
|
469
381
|
integrations: [
|
|
@@ -471,20 +383,20 @@ export default function createConfig(options: DocsTemplateOptions) {
|
|
|
471
383
|
appName,
|
|
472
384
|
sitemapFilter,
|
|
473
385
|
integrationConfigs,
|
|
474
|
-
unwantedIntegrations
|
|
386
|
+
unwantedIntegrations
|
|
475
387
|
}),
|
|
476
388
|
starlight({
|
|
477
389
|
title: `${appName} Docs`,
|
|
478
390
|
pagefind: true,
|
|
479
|
-
description
|
|
391
|
+
description,
|
|
480
392
|
logo: {
|
|
481
393
|
dark: logoDark,
|
|
482
394
|
light: logoLight,
|
|
483
395
|
alt: is_codeweaver ? "CodeWeaver Logo" : "Knitli Logo",
|
|
484
|
-
replacesTitle: true
|
|
396
|
+
replacesTitle: true
|
|
485
397
|
},
|
|
486
398
|
editLink: {
|
|
487
|
-
baseUrl: `https://github.com/knitli/${appName.toLowerCase()}/edit/main/docs-site/src
|
|
399
|
+
baseUrl: `https://github.com/knitli/${appName.toLowerCase()}/edit/main/docs-site/src`
|
|
488
400
|
},
|
|
489
401
|
expressiveCode: {
|
|
490
402
|
useStarlightDarkModeSwitch: true,
|
|
@@ -492,27 +404,27 @@ export default function createConfig(options: DocsTemplateOptions) {
|
|
|
492
404
|
removeUnusedThemes: true,
|
|
493
405
|
shiki: {
|
|
494
406
|
...Object.fromEntries(
|
|
495
|
-
Object.entries(shikiConfig).filter(([key]) => key !== "themes")
|
|
496
|
-
)
|
|
497
|
-
}
|
|
407
|
+
Object.entries(shikiConfig).filter(([key]) => key !== "themes")
|
|
408
|
+
)
|
|
409
|
+
}
|
|
498
410
|
},
|
|
499
411
|
plugins: get_plugins({
|
|
500
412
|
appName,
|
|
501
413
|
llmConfig,
|
|
502
414
|
pluginConfigs,
|
|
503
|
-
unwantedPlugins
|
|
415
|
+
unwantedPlugins
|
|
504
416
|
// biome-ignore lint/suspicious/noExplicitAny: Starlight plugin types are complex Zod inferences
|
|
505
|
-
})
|
|
417
|
+
}),
|
|
506
418
|
social: [
|
|
507
419
|
{
|
|
508
420
|
icon: "github",
|
|
509
421
|
label: "GitHub",
|
|
510
|
-
href: `https://github.com/knitli/${appName.toLowerCase()}
|
|
511
|
-
}
|
|
422
|
+
href: `https://github.com/knitli/${appName.toLowerCase()}`
|
|
423
|
+
}
|
|
512
424
|
],
|
|
513
425
|
components: {
|
|
514
426
|
Footer: "@knitli/docs-components/Footer.astro",
|
|
515
|
-
PageFrame: "@knitli/docs-components/PageFrame.astro"
|
|
427
|
+
PageFrame: "@knitli/docs-components/PageFrame.astro"
|
|
516
428
|
},
|
|
517
429
|
customCss: [variables, docsStyle, `${rootDir}/src/styles/custom.css`],
|
|
518
430
|
head: [
|
|
@@ -520,32 +432,34 @@ export default function createConfig(options: DocsTemplateOptions) {
|
|
|
520
432
|
tag: "meta",
|
|
521
433
|
attrs: {
|
|
522
434
|
property: "og:image",
|
|
523
|
-
content: `https://docs.knitli.com/${appName.toLowerCase()}/og-image.png
|
|
524
|
-
}
|
|
435
|
+
content: `https://docs.knitli.com/${appName.toLowerCase()}/og-image.png`
|
|
436
|
+
}
|
|
525
437
|
},
|
|
526
438
|
{
|
|
527
439
|
tag: "meta",
|
|
528
440
|
attrs: {
|
|
529
441
|
property: "twitter:card",
|
|
530
|
-
content: "summary_large_image"
|
|
531
|
-
}
|
|
532
|
-
}
|
|
442
|
+
content: "summary_large_image"
|
|
443
|
+
}
|
|
444
|
+
}
|
|
533
445
|
],
|
|
534
446
|
sidebar: sidebarConfig || [
|
|
535
447
|
{
|
|
536
448
|
label: "Guides",
|
|
537
|
-
autogenerate: { directory: "guides" }
|
|
449
|
+
autogenerate: { directory: "guides" }
|
|
538
450
|
},
|
|
539
451
|
{
|
|
540
452
|
label: "Examples",
|
|
541
|
-
autogenerate: { directory: "examples" }
|
|
453
|
+
autogenerate: { directory: "examples" }
|
|
542
454
|
},
|
|
543
455
|
{
|
|
544
456
|
label: "Reference",
|
|
545
|
-
autogenerate: { directory: "reference" }
|
|
546
|
-
}
|
|
547
|
-
]
|
|
548
|
-
})
|
|
549
|
-
]
|
|
457
|
+
autogenerate: { directory: "reference" }
|
|
458
|
+
}
|
|
459
|
+
]
|
|
460
|
+
})
|
|
461
|
+
]
|
|
550
462
|
});
|
|
551
463
|
}
|
|
464
|
+
|
|
465
|
+
export { createConfig as default, docsStyle, faviconIco, faviconSvg, headlineLogoDark, headlineLogoLight, variables };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export { type DocsTemplateOptions, default as createConfig } from "./config.js";
|
|
2
|
+
export interface InitOptions {
|
|
3
|
+
/** Display name for the product (e.g. "Recoco", "CodeWeaver") */
|
|
4
|
+
appName: string;
|
|
5
|
+
/** npm package name (e.g. "@knitli-site/recoco-docs") */
|
|
6
|
+
name: string;
|
|
7
|
+
/** Short product description */
|
|
8
|
+
description: string;
|
|
9
|
+
/** Cloudflare Worker name (e.g. "recoco-docs") */
|
|
10
|
+
workerName?: string;
|
|
11
|
+
/** Whether this is a CodeWeaver-branded site */
|
|
12
|
+
is_codeweaver?: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface AddPiecesOptions extends InitOptions {
|
|
15
|
+
pieces: PieceName[];
|
|
16
|
+
/** Overwrite existing files (default: false — skips with a warning) */
|
|
17
|
+
force?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const PIECES: {
|
|
20
|
+
readonly config: {
|
|
21
|
+
readonly description: "Astro config using createConfig()";
|
|
22
|
+
readonly paths: readonly ["astro.config.ts"];
|
|
23
|
+
};
|
|
24
|
+
readonly wrangler: {
|
|
25
|
+
readonly description: "Cloudflare Worker deployment config";
|
|
26
|
+
readonly paths: readonly ["wrangler.jsonc"];
|
|
27
|
+
};
|
|
28
|
+
readonly tsconfig: {
|
|
29
|
+
readonly description: "TypeScript config extending shared base";
|
|
30
|
+
readonly paths: readonly ["tsconfig.json"];
|
|
31
|
+
};
|
|
32
|
+
readonly content: {
|
|
33
|
+
readonly description: "Content collections, env types, and tags";
|
|
34
|
+
readonly paths: readonly ["src/content.config.ts", "src/env.d.ts", "tags.yml"];
|
|
35
|
+
};
|
|
36
|
+
readonly mise: {
|
|
37
|
+
readonly description: "mise dev tasks (build, deploy, clean, etc.)";
|
|
38
|
+
readonly paths: readonly ["mise.toml"];
|
|
39
|
+
};
|
|
40
|
+
readonly styles: {
|
|
41
|
+
readonly description: "Custom CSS hook for site-specific styles";
|
|
42
|
+
readonly paths: readonly ["src/styles/custom.css"];
|
|
43
|
+
};
|
|
44
|
+
readonly deps: {
|
|
45
|
+
readonly description: "package.json with template dependencies";
|
|
46
|
+
readonly paths: readonly ["package.json"];
|
|
47
|
+
};
|
|
48
|
+
readonly "starter-content": {
|
|
49
|
+
readonly description: "Example documentation pages";
|
|
50
|
+
readonly paths: readonly ["src/content/docs"];
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export type PieceName = keyof typeof PIECES;
|
|
54
|
+
export declare const PIECE_NAMES: PieceName[];
|
|
55
|
+
/**
|
|
56
|
+
* Initialize a new Knitli docs site from the template scaffolding.
|
|
57
|
+
*
|
|
58
|
+
* Copies all files from the scaffolding directory to the target path,
|
|
59
|
+
* applying placeholder substitution to text files.
|
|
60
|
+
*/
|
|
61
|
+
export declare function initDocsTemplate(targetPath: string, options: InitOptions): string[];
|
|
62
|
+
/**
|
|
63
|
+
* Add specific pieces from the template scaffolding to an existing project.
|
|
64
|
+
*
|
|
65
|
+
* Unlike initDocsTemplate, this only copies the files belonging to the
|
|
66
|
+
* requested pieces and skips existing files unless force is set.
|
|
67
|
+
*/
|
|
68
|
+
export declare function addPieces(targetPath: string, options: AddPiecesOptions): string[];
|
|
69
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,KAAK,mBAAmB,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AAOhF,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAID,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCT,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,MAAM,CAAC;AAC5C,eAAO,MAAM,WAAW,EAA0B,SAAS,EAAE,CAAC;AAyF9D;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,WAAW,GACnB,MAAM,EAAE,CAWV;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,gBAAgB,GACxB,MAAM,EAAE,CAyCV"}
|
|
@@ -1,89 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
readdirSync,
|
|
10
|
-
readFileSync,
|
|
11
|
-
statSync,
|
|
12
|
-
writeFileSync,
|
|
13
|
-
} from "node:fs";
|
|
14
|
-
import { dirname, join, resolve } from "node:path";
|
|
15
|
-
import { fileURLToPath } from "node:url";
|
|
16
|
-
|
|
17
|
-
export { type DocsTemplateOptions, default as createConfig } from "./config.js";
|
|
18
|
-
|
|
19
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
|
-
const SCAFFOLDING_DIR = resolve(__dirname, "../scaffolding");
|
|
21
|
-
|
|
22
|
-
// ── Options ──
|
|
23
|
-
|
|
24
|
-
export interface InitOptions {
|
|
25
|
-
/** Display name for the product (e.g. "Recoco", "CodeWeaver") */
|
|
26
|
-
appName: string;
|
|
27
|
-
/** npm package name (e.g. "@knitli-site/recoco-docs") */
|
|
28
|
-
name: string;
|
|
29
|
-
/** Short product description */
|
|
30
|
-
description: string;
|
|
31
|
-
/** Cloudflare Worker name (e.g. "recoco-docs") */
|
|
32
|
-
workerName?: string;
|
|
33
|
-
/** Whether this is a CodeWeaver-branded site */
|
|
34
|
-
is_codeweaver?: boolean;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface AddPiecesOptions extends InitOptions {
|
|
38
|
-
pieces: PieceName[];
|
|
39
|
-
/** Overwrite existing files (default: false — skips with a warning) */
|
|
40
|
-
force?: boolean;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ── Piece definitions ──
|
|
44
|
-
|
|
45
|
-
export const PIECES = {
|
|
1
|
+
import { existsSync, statSync, mkdirSync, readdirSync, readFileSync, writeFileSync, cpSync } from 'node:fs';
|
|
2
|
+
import { dirname, resolve, join } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
export { default as createConfig } from './config.js';
|
|
5
|
+
|
|
6
|
+
const __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
const SCAFFOLDING_DIR = resolve(__dirname$1, "../scaffolding");
|
|
8
|
+
const PIECES = {
|
|
46
9
|
config: {
|
|
47
10
|
description: "Astro config using createConfig()",
|
|
48
|
-
paths: ["astro.config.ts"]
|
|
11
|
+
paths: ["astro.config.ts"]
|
|
49
12
|
},
|
|
50
13
|
wrangler: {
|
|
51
14
|
description: "Cloudflare Worker deployment config",
|
|
52
|
-
paths: ["wrangler.jsonc"]
|
|
15
|
+
paths: ["wrangler.jsonc"]
|
|
53
16
|
},
|
|
54
17
|
tsconfig: {
|
|
55
18
|
description: "TypeScript config extending shared base",
|
|
56
|
-
paths: ["tsconfig.json"]
|
|
19
|
+
paths: ["tsconfig.json"]
|
|
57
20
|
},
|
|
58
21
|
content: {
|
|
59
22
|
description: "Content collections, env types, and tags",
|
|
60
|
-
paths: ["src/content.config.ts", "src/env.d.ts", "tags.yml"]
|
|
23
|
+
paths: ["src/content.config.ts", "src/env.d.ts", "tags.yml"]
|
|
61
24
|
},
|
|
62
25
|
mise: {
|
|
63
26
|
description: "mise dev tasks (build, deploy, clean, etc.)",
|
|
64
|
-
paths: ["mise.toml"]
|
|
27
|
+
paths: ["mise.toml"]
|
|
65
28
|
},
|
|
66
29
|
styles: {
|
|
67
30
|
description: "Custom CSS hook for site-specific styles",
|
|
68
|
-
paths: ["src/styles/custom.css"]
|
|
31
|
+
paths: ["src/styles/custom.css"]
|
|
69
32
|
},
|
|
70
33
|
deps: {
|
|
71
34
|
description: "package.json with template dependencies",
|
|
72
|
-
paths: ["package.json"]
|
|
35
|
+
paths: ["package.json"]
|
|
73
36
|
},
|
|
74
37
|
"starter-content": {
|
|
75
38
|
description: "Example documentation pages",
|
|
76
|
-
paths: ["src/content/docs"]
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
export const PIECE_NAMES = Object.keys(PIECES) as PieceName[];
|
|
82
|
-
|
|
83
|
-
// ── Shared helpers ──
|
|
84
|
-
|
|
85
|
-
/** File extensions that should have placeholder substitution applied */
|
|
86
|
-
const TEXT_EXTENSIONS = new Set([
|
|
39
|
+
paths: ["src/content/docs"]
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const PIECE_NAMES = Object.keys(PIECES);
|
|
43
|
+
const TEXT_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
87
44
|
".ts",
|
|
88
45
|
".js",
|
|
89
46
|
".mjs",
|
|
@@ -96,42 +53,28 @@ const TEXT_EXTENSIONS = new Set([
|
|
|
96
53
|
".css",
|
|
97
54
|
".html",
|
|
98
55
|
".astro",
|
|
99
|
-
".toml"
|
|
56
|
+
".toml"
|
|
100
57
|
]);
|
|
101
|
-
|
|
102
|
-
function isTextFile(filePath: string): boolean {
|
|
58
|
+
function isTextFile(filePath) {
|
|
103
59
|
return TEXT_EXTENSIONS.has(filePath.slice(filePath.lastIndexOf(".")));
|
|
104
60
|
}
|
|
105
|
-
|
|
106
|
-
function buildReplacements(options: InitOptions): Record<string, string> {
|
|
61
|
+
function buildReplacements(options) {
|
|
107
62
|
return {
|
|
108
63
|
"{{appName}}": options.appName,
|
|
109
64
|
"{{appNameLower}}": options.appName.toLowerCase(),
|
|
110
65
|
"{{name}}": options.name,
|
|
111
66
|
"{{description}}": options.description,
|
|
112
|
-
"{{workerName}}":
|
|
113
|
-
options.workerName ?? `${options.appName.toLowerCase()}-docs`,
|
|
67
|
+
"{{workerName}}": options.workerName ?? `${options.appName.toLowerCase()}-docs`
|
|
114
68
|
};
|
|
115
69
|
}
|
|
116
|
-
|
|
117
|
-
function applyReplacements(
|
|
118
|
-
content: string,
|
|
119
|
-
replacements: Record<string, string>,
|
|
120
|
-
): string {
|
|
70
|
+
function applyReplacements(content, replacements) {
|
|
121
71
|
let result = content;
|
|
122
72
|
for (const [placeholder, value] of Object.entries(replacements)) {
|
|
123
73
|
result = result.replaceAll(placeholder, value);
|
|
124
74
|
}
|
|
125
75
|
return result;
|
|
126
76
|
}
|
|
127
|
-
|
|
128
|
-
function copyFile(
|
|
129
|
-
srcPath: string,
|
|
130
|
-
destPath: string,
|
|
131
|
-
replacements: Record<string, string>,
|
|
132
|
-
created: string[],
|
|
133
|
-
force?: boolean,
|
|
134
|
-
): void {
|
|
77
|
+
function copyFile(srcPath, destPath, replacements, created, force) {
|
|
135
78
|
if (!force && existsSync(destPath)) {
|
|
136
79
|
console.log(` skip ${destPath} (exists, use --force to overwrite)`);
|
|
137
80
|
return;
|
|
@@ -145,14 +88,7 @@ function copyFile(
|
|
|
145
88
|
}
|
|
146
89
|
created.push(destPath);
|
|
147
90
|
}
|
|
148
|
-
|
|
149
|
-
function copyDirRecursive(
|
|
150
|
-
srcDir: string,
|
|
151
|
-
destDir: string,
|
|
152
|
-
replacements: Record<string, string>,
|
|
153
|
-
created: string[],
|
|
154
|
-
force?: boolean,
|
|
155
|
-
): void {
|
|
91
|
+
function copyDirRecursive(srcDir, destDir, replacements, created, force) {
|
|
156
92
|
mkdirSync(destDir, { recursive: true });
|
|
157
93
|
for (const entry of readdirSync(srcDir)) {
|
|
158
94
|
const srcPath = join(srcDir, entry);
|
|
@@ -164,73 +100,51 @@ function copyDirRecursive(
|
|
|
164
100
|
}
|
|
165
101
|
}
|
|
166
102
|
}
|
|
167
|
-
|
|
168
|
-
// ── Public API ──
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Initialize a new Knitli docs site from the template scaffolding.
|
|
172
|
-
*
|
|
173
|
-
* Copies all files from the scaffolding directory to the target path,
|
|
174
|
-
* applying placeholder substitution to text files.
|
|
175
|
-
*/
|
|
176
|
-
export function initDocsTemplate(
|
|
177
|
-
targetPath: string,
|
|
178
|
-
options: InitOptions,
|
|
179
|
-
): string[] {
|
|
103
|
+
function initDocsTemplate(targetPath, options) {
|
|
180
104
|
const target = resolve(targetPath);
|
|
181
105
|
const replacements = buildReplacements(options);
|
|
182
|
-
const created
|
|
183
|
-
|
|
106
|
+
const created = [];
|
|
184
107
|
if (!existsSync(SCAFFOLDING_DIR)) {
|
|
185
108
|
throw new Error(`Scaffolding directory not found at ${SCAFFOLDING_DIR}`);
|
|
186
109
|
}
|
|
187
|
-
|
|
188
110
|
copyDirRecursive(SCAFFOLDING_DIR, target, replacements, created, true);
|
|
189
111
|
return created;
|
|
190
112
|
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Add specific pieces from the template scaffolding to an existing project.
|
|
194
|
-
*
|
|
195
|
-
* Unlike initDocsTemplate, this only copies the files belonging to the
|
|
196
|
-
* requested pieces and skips existing files unless force is set.
|
|
197
|
-
*/
|
|
198
|
-
export function addPieces(
|
|
199
|
-
targetPath: string,
|
|
200
|
-
options: AddPiecesOptions,
|
|
201
|
-
): string[] {
|
|
113
|
+
function addPieces(targetPath, options) {
|
|
202
114
|
const target = resolve(targetPath);
|
|
203
115
|
const replacements = buildReplacements(options);
|
|
204
|
-
const created
|
|
205
|
-
|
|
116
|
+
const created = [];
|
|
206
117
|
if (!existsSync(SCAFFOLDING_DIR)) {
|
|
207
118
|
throw new Error(`Scaffolding directory not found at ${SCAFFOLDING_DIR}`);
|
|
208
119
|
}
|
|
209
|
-
|
|
210
120
|
for (const piece of options.pieces) {
|
|
211
121
|
const pieceDef = PIECES[piece];
|
|
212
122
|
if (!pieceDef) {
|
|
213
123
|
throw new Error(
|
|
214
|
-
`Unknown piece: ${piece}. Available: ${PIECE_NAMES.join(", ")}
|
|
124
|
+
`Unknown piece: ${piece}. Available: ${PIECE_NAMES.join(", ")}`
|
|
215
125
|
);
|
|
216
126
|
}
|
|
217
|
-
|
|
218
127
|
for (const relPath of pieceDef.paths) {
|
|
219
128
|
const srcPath = join(SCAFFOLDING_DIR, relPath);
|
|
220
129
|
const destPath = join(target, relPath);
|
|
221
|
-
|
|
222
130
|
if (!existsSync(srcPath)) {
|
|
223
131
|
console.warn(` warn: ${relPath} not found in scaffolding, skipping`);
|
|
224
132
|
continue;
|
|
225
133
|
}
|
|
226
|
-
|
|
227
134
|
if (statSync(srcPath).isDirectory()) {
|
|
228
|
-
copyDirRecursive(
|
|
135
|
+
copyDirRecursive(
|
|
136
|
+
srcPath,
|
|
137
|
+
destPath,
|
|
138
|
+
replacements,
|
|
139
|
+
created,
|
|
140
|
+
options.force
|
|
141
|
+
);
|
|
229
142
|
} else {
|
|
230
143
|
copyFile(srcPath, destPath, replacements, created, options.force);
|
|
231
144
|
}
|
|
232
145
|
}
|
|
233
146
|
}
|
|
234
|
-
|
|
235
147
|
return created;
|
|
236
148
|
}
|
|
149
|
+
|
|
150
|
+
export { PIECES, PIECE_NAMES, addPieces, initDocsTemplate };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knitli/astro-docs-template",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Opinionated Astro + Starlight docs site template with Knitli branding",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"knitli",
|
|
@@ -19,20 +19,26 @@
|
|
|
19
19
|
"author": "Knitli Inc.",
|
|
20
20
|
"type": "module",
|
|
21
21
|
"exports": {
|
|
22
|
-
".":
|
|
23
|
-
|
|
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
|
+
}
|
|
24
30
|
},
|
|
25
31
|
"bin": {
|
|
26
|
-
"knitli-docs": "
|
|
32
|
+
"knitli-docs": "dist/cli.js"
|
|
27
33
|
},
|
|
28
34
|
"files": [
|
|
29
|
-
"
|
|
35
|
+
"dist",
|
|
30
36
|
"scaffolding",
|
|
31
37
|
"README.md",
|
|
32
38
|
"CHANGELOG.md"
|
|
33
39
|
],
|
|
34
40
|
"scripts": {
|
|
35
|
-
"build": "
|
|
41
|
+
"build": "vite build && tsc --emitDeclarationOnly --noCheck --noEmit false",
|
|
36
42
|
"prepublishOnly": "bun run build",
|
|
37
43
|
"publish": "npm publish --access public",
|
|
38
44
|
"typecheck": "bunx tsc --noEmit"
|
|
@@ -72,7 +78,8 @@
|
|
|
72
78
|
"lightningcss": "catalog:optimization",
|
|
73
79
|
"sharp": "catalog:astro-core",
|
|
74
80
|
"svgo": "catalog:optimization",
|
|
75
|
-
"typescript": "catalog:dev-common"
|
|
81
|
+
"typescript": "catalog:dev-common",
|
|
82
|
+
"vite": "catalog:dev-common"
|
|
76
83
|
},
|
|
77
84
|
"devEngines": {
|
|
78
85
|
"packageManager": {
|
package/scaffolding/package.json
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"astro": "bunx astro",
|
|
8
|
-
"
|
|
8
|
+
"prepare": "test -f ./node_modules/bun/install.js && node ./node_modules/bun/install.js || true",
|
|
9
|
+
|
|
10
|
+
"prebuild": "bunx wrangler types; bunx astro sync",
|
|
9
11
|
"build": "bunx astro build",
|
|
10
12
|
"deploy": "bun run build && bunx wrangler deploy",
|
|
11
13
|
"dev": "bunx astro dev",
|