alchemy 0.2.5 → 0.3.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.
- package/README.md +3 -3
- package/lib/ai/approve.d.ts +99 -0
- package/lib/ai/approve.js +76 -0
- package/lib/ai/astro-file.d.ts +137 -0
- package/lib/ai/astro-file.js +156 -0
- package/lib/ai/client.d.ts +7 -8
- package/lib/ai/client.js +48 -19
- package/lib/ai/css-file.d.ts +131 -0
- package/lib/ai/css-file.js +141 -0
- package/lib/ai/data.d.ts +51 -6
- package/lib/ai/data.js +58 -12
- package/lib/ai/document.d.ts +108 -24
- package/lib/ai/document.js +166 -52
- package/lib/ai/html-file.d.ts +128 -0
- package/lib/ai/html-file.js +138 -0
- package/lib/ai/index.d.ts +9 -0
- package/lib/ai/index.js +9 -0
- package/lib/ai/json-file.d.ts +160 -0
- package/lib/ai/json-file.js +187 -0
- package/lib/ai/review.d.ts +122 -0
- package/lib/ai/review.js +101 -0
- package/lib/ai/typescript-file.d.ts +139 -0
- package/lib/ai/typescript-file.js +145 -0
- package/lib/ai/vue-file.d.ts +126 -0
- package/lib/ai/vue-file.js +136 -0
- package/lib/ai/yaml-file.d.ts +169 -0
- package/lib/ai/yaml-file.js +200 -0
- package/lib/alchemy.js +17 -2
- package/lib/apply.js +1 -1
- package/lib/cloudflare/dns.d.ts +88 -0
- package/lib/cloudflare/dns.js +192 -0
- package/lib/cloudflare/generate-asset-manifest.js +1 -1
- package/lib/cloudflare/index.d.ts +2 -1
- package/lib/cloudflare/index.js +2 -1
- package/lib/cloudflare/r2-rest-state-store.d.ts +125 -0
- package/lib/cloudflare/r2-rest-state-store.js +254 -0
- package/lib/cloudflare/response.d.ts +12 -0
- package/lib/cloudflare/response.js +0 -0
- package/lib/cloudflare/static-site-router.js +16 -7
- package/lib/cloudflare/static-site.js +3 -0
- package/lib/cloudflare/upload-asset-manifest.js +4 -2
- package/lib/cloudflare/zone.d.ts +18 -0
- package/lib/cloudflare/zone.js +17 -4
- package/lib/dns/godaddy.d.ts +7 -0
- package/lib/dns/godaddy.js +21 -0
- package/lib/dns/import-dns.d.ts +82 -0
- package/lib/dns/import-dns.js +114 -0
- package/lib/dns/index.d.ts +2 -0
- package/lib/dns/index.js +2 -0
- package/lib/dns/record.d.ts +88 -0
- package/lib/dns/record.js +13 -0
- package/lib/fs/copy-file.d.ts +54 -0
- package/lib/fs/copy-file.js +63 -0
- package/lib/fs/file-system-state-store.d.ts +17 -0
- package/lib/fs/file-system-state-store.js +87 -0
- package/lib/fs/file.d.ts +13 -0
- package/lib/fs/file.js +24 -5
- package/lib/fs/folder.d.ts +10 -0
- package/lib/fs/folder.js +2 -2
- package/lib/fs/index.d.ts +10 -4
- package/lib/fs/index.js +10 -4
- package/lib/fs/static-astro-file.d.ts +34 -0
- package/lib/fs/static-astro-file.js +39 -0
- package/lib/fs/static-css-file.d.ts +24 -0
- package/lib/fs/static-css-file.js +29 -0
- package/lib/fs/static-html-file.d.ts +31 -0
- package/lib/fs/static-html-file.js +36 -0
- package/lib/fs/{json-file.d.ts → static-json-file.d.ts} +3 -3
- package/lib/fs/static-json-file.js +15 -0
- package/lib/fs/{text-file.d.ts → static-text-file.d.ts} +2 -2
- package/lib/fs/static-text-file.js +8 -0
- package/lib/fs/{typescript-file.d.ts → static-typescript-file.d.ts} +3 -3
- package/lib/fs/{typescript-file.js → static-typescript-file.js} +3 -2
- package/lib/fs/static-vue-file.d.ts +28 -0
- package/lib/fs/static-vue-file.js +33 -0
- package/lib/fs/static-yaml-file.d.ts +22 -0
- package/lib/fs/{yaml-file.js → static-yaml-file.js} +3 -2
- package/lib/internal/getting-started.d.ts +21 -0
- package/lib/internal/getting-started.js +87 -0
- package/lib/internal/index.d.ts +3 -0
- package/lib/internal/index.js +3 -0
- package/lib/internal/providers.d.ts +27 -0
- package/lib/internal/providers.js +172 -0
- package/lib/internal/tutorial.d.ts +104 -0
- package/lib/internal/tutorial.js +251 -0
- package/lib/resource.js +8 -1
- package/lib/scope.d.ts +1 -1
- package/lib/scope.js +4 -2
- package/lib/state.d.ts +1 -16
- package/lib/state.js +0 -87
- package/lib/test/bun.d.ts +11 -0
- package/lib/test/bun.js +36 -8
- package/lib/web/astro.d.ts +147 -0
- package/lib/web/astro.js +414 -0
- package/lib/{shadcn/component.js → web/shadcn-component.js} +2 -9
- package/lib/web/shadcn.d.ts +97 -0
- package/lib/web/shadcn.js +99 -0
- package/lib/web/tailwind.d.ts +64 -0
- package/lib/web/tailwind.js +97 -0
- package/lib/{vite → web}/vite.d.ts +5 -0
- package/lib/{vite → web}/vite.js +44 -44
- package/lib/web/vitepress/config.d.ts +10 -0
- package/lib/web/vitepress/config.js +31 -0
- package/lib/web/vitepress/custom-theme.d.ts +173 -0
- package/lib/web/vitepress/custom-theme.js +336 -0
- package/lib/{vitepress → web/vitepress}/dependencies.d.ts +2 -2
- package/lib/{vitepress → web/vitepress}/dependencies.js +1 -1
- package/lib/web/vitepress/home-page.d.ts +246 -0
- package/lib/web/vitepress/home-page.js +147 -0
- package/lib/{vitepress → web/vitepress}/index.d.ts +2 -0
- package/lib/{vitepress → web/vitepress}/index.js +2 -0
- package/lib/{vitepress → web/vitepress}/vitepress.d.ts +15 -12
- package/lib/{vitepress → web/vitepress}/vitepress.js +26 -44
- package/package.json +6 -2
- package/src/ai/approve.ts +163 -0
- package/src/ai/astro-file.ts +269 -0
- package/src/ai/client.ts +60 -21
- package/src/ai/css-file.ts +247 -0
- package/src/ai/data.ts +81 -19
- package/src/ai/document.ts +240 -62
- package/src/ai/html-file.ts +244 -0
- package/src/ai/index.ts +9 -0
- package/src/ai/json-file.ts +325 -0
- package/src/ai/review.ts +213 -0
- package/src/ai/typescript-file.ts +259 -0
- package/src/ai/vue-file.ts +242 -0
- package/src/ai/yaml-file.ts +328 -0
- package/src/alchemy.ts +18 -7
- package/src/apply.ts +8 -9
- package/src/cloudflare/dns.ts +344 -0
- package/src/cloudflare/generate-asset-manifest.ts +4 -4
- package/src/cloudflare/index.ts +2 -1
- package/src/cloudflare/r2-rest-state-store.ts +353 -0
- package/src/cloudflare/response.ts +9 -0
- package/src/cloudflare/static-site-router.ts +18 -8
- package/src/cloudflare/static-site.ts +11 -7
- package/src/cloudflare/upload-asset-manifest.ts +6 -4
- package/src/cloudflare/worker.ts +44 -43
- package/src/cloudflare/zone.ts +39 -23
- package/src/dns/godaddy.ts +29 -0
- package/src/dns/import-dns.ts +213 -0
- package/src/dns/index.ts +2 -0
- package/src/dns/record.ts +121 -0
- package/src/fs/copy-file.ts +115 -0
- package/src/fs/file-system-state-store.ts +109 -0
- package/src/fs/file.ts +35 -9
- package/src/fs/folder.ts +14 -2
- package/src/fs/index.ts +10 -4
- package/src/fs/static-astro-file.ts +45 -0
- package/src/fs/static-css-file.ts +35 -0
- package/src/fs/static-html-file.ts +42 -0
- package/src/fs/static-json-file.ts +34 -0
- package/src/fs/{text-file.ts → static-text-file.ts} +9 -3
- package/src/fs/{typescript-file.ts → static-typescript-file.ts} +7 -6
- package/src/fs/static-vue-file.ts +39 -0
- package/src/fs/static-yaml-file.ts +33 -0
- package/src/internal/getting-started.ts +115 -0
- package/src/internal/index.ts +3 -0
- package/src/internal/providers.ts +241 -0
- package/src/internal/tutorial.ts +392 -0
- package/src/resource.ts +10 -1
- package/src/scope.ts +5 -6
- package/src/state.ts +1 -111
- package/src/test/bun.ts +60 -10
- package/src/web/astro.ts +644 -0
- package/src/{shadcn/component.ts → web/shadcn-component.ts} +5 -13
- package/src/web/shadcn.ts +219 -0
- package/src/web/tailwind.ts +167 -0
- package/src/{vite → web}/vite.ts +54 -56
- package/src/web/vitepress/config.ts +48 -0
- package/src/web/vitepress/custom-theme.ts +514 -0
- package/src/{vitepress → web/vitepress}/dependencies.ts +2 -2
- package/src/web/vitepress/home-page.ts +375 -0
- package/src/{vitepress → web/vitepress}/index.ts +2 -0
- package/src/{vitepress → web/vitepress}/vitepress.ts +62 -72
- package/lib/cloudflare/state.d.ts +0 -82
- package/lib/cloudflare/state.js +0 -108
- package/lib/fs/json-file.js +0 -7
- package/lib/fs/text-file.js +0 -7
- package/lib/fs/yaml-file.d.ts +0 -19
- package/lib/internal/docs.d.ts +0 -5
- package/lib/internal/docs.js +0 -287
- package/lib/shadcn/index.d.ts +0 -1
- package/lib/shadcn/index.js +0 -1
- package/lib/vite/index.d.ts +0 -1
- package/lib/vite/index.js +0 -1
- package/lib/vitepress/home-page.d.ts +0 -133
- package/lib/vitepress/home-page.js +0 -11
- package/src/cloudflare/state.ts +0 -138
- package/src/fs/json-file.ts +0 -23
- package/src/fs/yaml-file.ts +0 -26
- package/src/internal/docs.ts +0 -338
- package/src/shadcn/index.ts +0 -1
- package/src/vite/index.ts +0 -1
- package/src/vitepress/home-page.ts +0 -166
- /package/lib/{shadcn/component.d.ts → web/shadcn-component.d.ts} +0 -0
- /package/src/{vitepress → web/vitepress}/index.md +0 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { promisify } from "util";
|
|
4
|
+
import type { Context } from "../context";
|
|
5
|
+
import { Folder, StaticJsonFile } from "../fs";
|
|
6
|
+
import { StaticTypeScriptFile } from "../fs/static-typescript-file";
|
|
7
|
+
import { Resource } from "../resource";
|
|
8
|
+
import { ShadcnComponent } from "./shadcn-component";
|
|
9
|
+
|
|
10
|
+
const execAsync = promisify(exec);
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Properties for initializing Shadcn UI
|
|
14
|
+
*/
|
|
15
|
+
export interface ShadcnUIProps {
|
|
16
|
+
/**
|
|
17
|
+
* The working directory where Shadcn UI should be installed
|
|
18
|
+
*/
|
|
19
|
+
cwd: string;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The base color to use
|
|
23
|
+
* @default "neutral"
|
|
24
|
+
*/
|
|
25
|
+
baseColor?: "neutral" | "gray" | "zinc" | "stone" | "slate";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Use default configuration
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
defaults?: boolean;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Force overwrite of existing configuration
|
|
35
|
+
* @default false
|
|
36
|
+
*/
|
|
37
|
+
force?: boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Mute output
|
|
41
|
+
* @default false
|
|
42
|
+
*/
|
|
43
|
+
silent?: boolean;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Use the src directory when creating a new project
|
|
47
|
+
* @default true
|
|
48
|
+
*/
|
|
49
|
+
srcDir?: boolean;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Use css variables for theming
|
|
53
|
+
* @default true
|
|
54
|
+
*/
|
|
55
|
+
cssVariables?: boolean;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The components to add
|
|
59
|
+
*/
|
|
60
|
+
components?: string[];
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Whether tailwind is already installed and configured.
|
|
64
|
+
* Shadcn UI requires Tailwind CSS to be installed and configured.
|
|
65
|
+
* @default false
|
|
66
|
+
*/
|
|
67
|
+
tailwind?: boolean;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Whether react is already installed
|
|
71
|
+
* @default false
|
|
72
|
+
*/
|
|
73
|
+
react?: boolean;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Shadcn UI resource
|
|
78
|
+
*/
|
|
79
|
+
export interface ShadcnUI extends ShadcnUIProps, Resource<"project::ShadcnUI"> {
|
|
80
|
+
/**
|
|
81
|
+
* The working directory where Shadcn UI is installed
|
|
82
|
+
*/
|
|
83
|
+
cwd: string;
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* The ui directory
|
|
87
|
+
*/
|
|
88
|
+
ui: Folder;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The lib directory
|
|
92
|
+
*/
|
|
93
|
+
lib: Folder;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Initializes Shadcn UI in a project directory
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* // Initialize Shadcn UI with default settings
|
|
101
|
+
* const shadcn = await ShadcnUI("my-shadcn", {
|
|
102
|
+
* cwd: "my-project",
|
|
103
|
+
* tailwind: true, // Tailwind must be installed separately
|
|
104
|
+
* react: true // React must be installed separately
|
|
105
|
+
* });
|
|
106
|
+
*
|
|
107
|
+
* @example
|
|
108
|
+
* // Initialize Shadcn UI with custom settings and components
|
|
109
|
+
* const shadcn = await ShadcnUI("custom-shadcn", {
|
|
110
|
+
* cwd: "my-project",
|
|
111
|
+
* baseColor: "zinc",
|
|
112
|
+
* force: true,
|
|
113
|
+
* components: ["button", "card", "input"],
|
|
114
|
+
* tailwind: true, // Tailwind must be installed separately
|
|
115
|
+
* react: true // React must be installed separately
|
|
116
|
+
* });
|
|
117
|
+
*/
|
|
118
|
+
export const ShadcnUI = Resource(
|
|
119
|
+
"project::ShadcnUI",
|
|
120
|
+
async function (
|
|
121
|
+
this: Context<ShadcnUI>,
|
|
122
|
+
id: string,
|
|
123
|
+
props: ShadcnUIProps,
|
|
124
|
+
): Promise<ShadcnUI> {
|
|
125
|
+
if (this.phase === "delete") {
|
|
126
|
+
// For a delete phase, we don't perform any action
|
|
127
|
+
// as removing Shadcn UI would require removing many files
|
|
128
|
+
// which could be destructive to the project
|
|
129
|
+
console.log(
|
|
130
|
+
"Note: ShadcnUI delete phase does not remove installed components",
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
return this.destroy();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Setup execAsync with the correct cwd
|
|
137
|
+
const exec = (command: string) => execAsync(command, { cwd: props.cwd });
|
|
138
|
+
|
|
139
|
+
// Ensure React is installed if not already
|
|
140
|
+
if (!props.react) {
|
|
141
|
+
await exec(`bun add react react-dom`);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Install shadcn dependencies
|
|
145
|
+
await exec(`bun add -D @types/node`);
|
|
146
|
+
|
|
147
|
+
// Create components.json directly instead of running shadcn init
|
|
148
|
+
await StaticJsonFile(path.join(props.cwd, "components.json"), {
|
|
149
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
150
|
+
style: props.cssVariables !== false ? "default" : "new-york",
|
|
151
|
+
tsx: true,
|
|
152
|
+
rsc: false,
|
|
153
|
+
tailwind: {
|
|
154
|
+
config: "tailwind.config.js",
|
|
155
|
+
css:
|
|
156
|
+
props.srcDir !== false
|
|
157
|
+
? "src/styles/globals.css"
|
|
158
|
+
: "styles/globals.css",
|
|
159
|
+
baseColor: props.baseColor || "neutral",
|
|
160
|
+
cssVariables: props.cssVariables !== false,
|
|
161
|
+
},
|
|
162
|
+
aliases: {
|
|
163
|
+
components: props.srcDir !== false ? "@/components" : "./components",
|
|
164
|
+
utils: props.srcDir !== false ? "@/lib/utils" : "./lib/utils",
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
// Ensure ui components directory exists
|
|
169
|
+
const ui = await Folder(
|
|
170
|
+
path.join(
|
|
171
|
+
props.cwd,
|
|
172
|
+
props.srcDir !== false ? "src" : "",
|
|
173
|
+
"components",
|
|
174
|
+
"ui",
|
|
175
|
+
),
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
// Create lib directory
|
|
179
|
+
const libPath = path.join(
|
|
180
|
+
props.cwd,
|
|
181
|
+
props.srcDir !== false ? "src" : "",
|
|
182
|
+
"lib",
|
|
183
|
+
);
|
|
184
|
+
const lib = await Folder(libPath);
|
|
185
|
+
|
|
186
|
+
// Create utils.ts file
|
|
187
|
+
const utilsContent = `
|
|
188
|
+
import { type ClassValue, clsx } from "clsx";
|
|
189
|
+
import { twMerge } from "tailwind-merge";
|
|
190
|
+
|
|
191
|
+
export function cn(...inputs: ClassValue[]) {
|
|
192
|
+
return twMerge(clsx(inputs));
|
|
193
|
+
}
|
|
194
|
+
`;
|
|
195
|
+
|
|
196
|
+
await StaticTypeScriptFile(path.join(libPath, "utils.ts"), utilsContent);
|
|
197
|
+
|
|
198
|
+
// Install clsx and tailwind-merge
|
|
199
|
+
await exec(`bun add clsx tailwind-merge`);
|
|
200
|
+
|
|
201
|
+
// Install requested components
|
|
202
|
+
if (props.components && props.components.length > 0) {
|
|
203
|
+
for (const componentName of props.components) {
|
|
204
|
+
await ShadcnComponent(`shadcn-component-${componentName}`, {
|
|
205
|
+
name: componentName,
|
|
206
|
+
cwd: props.cwd,
|
|
207
|
+
force: props.force,
|
|
208
|
+
silent: props.silent,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return this({
|
|
214
|
+
...props,
|
|
215
|
+
ui,
|
|
216
|
+
lib,
|
|
217
|
+
});
|
|
218
|
+
},
|
|
219
|
+
);
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { promisify } from "util";
|
|
4
|
+
import type { Context } from "../context";
|
|
5
|
+
import { Folder, StaticTextFile } from "../fs";
|
|
6
|
+
import { Resource } from "../resource";
|
|
7
|
+
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Framework types supported by the Tailwind resource
|
|
12
|
+
*/
|
|
13
|
+
export type TailwindFramework = "vite" | "astro" | "next" | "standalone";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Properties for Tailwind configuration
|
|
17
|
+
*/
|
|
18
|
+
export interface TailwindConfigProps {
|
|
19
|
+
/**
|
|
20
|
+
* The working directory where Tailwind should be installed
|
|
21
|
+
*/
|
|
22
|
+
cwd: string;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The framework being used (determines which dependencies to install)
|
|
26
|
+
* @default "standalone"
|
|
27
|
+
*/
|
|
28
|
+
framework?: TailwindFramework;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The path to the CSS file where Tailwind directives should be added
|
|
32
|
+
* If not provided, a new file will be created at src/styles/base.css
|
|
33
|
+
*/
|
|
34
|
+
cssPath?: string;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Custom additional packages to install with Tailwind
|
|
38
|
+
*/
|
|
39
|
+
additionalPackages?: string[];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Tailwind configuration resource
|
|
44
|
+
*/
|
|
45
|
+
export interface TailwindConfig
|
|
46
|
+
extends TailwindConfigProps,
|
|
47
|
+
Resource<"config::TailwindConfig"> {
|
|
48
|
+
/**
|
|
49
|
+
* The working directory where Tailwind is installed
|
|
50
|
+
*/
|
|
51
|
+
cwd: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Installs and configures Tailwind CSS for a project
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* // Install Tailwind for a Vite project
|
|
59
|
+
* const tailwind = await TailwindConfig("vite-tailwind", {
|
|
60
|
+
* cwd: "my-vite-app",
|
|
61
|
+
* framework: "vite"
|
|
62
|
+
* });
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* // Install Tailwind for an Astro project
|
|
66
|
+
* const tailwind = await TailwindConfig("astro-tailwind", {
|
|
67
|
+
* cwd: "my-astro-app",
|
|
68
|
+
* framework: "astro"
|
|
69
|
+
* });
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* // Install Tailwind as standalone with a custom CSS path
|
|
73
|
+
* const tailwind = await TailwindConfig("custom-tailwind", {
|
|
74
|
+
* cwd: "my-project",
|
|
75
|
+
* cssPath: "src/css/main.css",
|
|
76
|
+
* additionalPackages: ["@tailwindcss/typography", "@tailwindcss/forms"]
|
|
77
|
+
* });
|
|
78
|
+
*/
|
|
79
|
+
export const TailwindConfig = Resource(
|
|
80
|
+
"config::TailwindConfig",
|
|
81
|
+
async function (
|
|
82
|
+
this: Context<TailwindConfig>,
|
|
83
|
+
id: string,
|
|
84
|
+
props: TailwindConfigProps,
|
|
85
|
+
): Promise<TailwindConfig> {
|
|
86
|
+
if (this.phase === "delete") {
|
|
87
|
+
// Nothing to clean up specifically for Tailwind
|
|
88
|
+
return this.destroy();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const framework = props.framework || "standalone";
|
|
92
|
+
|
|
93
|
+
// Setup execAsync with the correct cwd
|
|
94
|
+
const exec = (command: string) => execAsync(command, { cwd: props.cwd });
|
|
95
|
+
|
|
96
|
+
// Install Tailwind and framework-specific dependencies
|
|
97
|
+
await installTailwindDependencies(framework);
|
|
98
|
+
|
|
99
|
+
// Create CSS file with Tailwind directives
|
|
100
|
+
await createTailwindCssFile();
|
|
101
|
+
|
|
102
|
+
return this({
|
|
103
|
+
...props,
|
|
104
|
+
framework: framework,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Install Tailwind and framework-specific dependencies
|
|
109
|
+
*/
|
|
110
|
+
async function installTailwindDependencies(framework: TailwindFramework) {
|
|
111
|
+
const basePackages = ["tailwindcss", "postcss", "autoprefixer"];
|
|
112
|
+
|
|
113
|
+
// Add framework-specific packages
|
|
114
|
+
const frameworkPackages = getFrameworkPackages(framework);
|
|
115
|
+
|
|
116
|
+
// Add custom additional packages
|
|
117
|
+
const additionalPackages = props.additionalPackages || [];
|
|
118
|
+
|
|
119
|
+
// Combine all packages
|
|
120
|
+
const allPackages = [
|
|
121
|
+
...basePackages,
|
|
122
|
+
...frameworkPackages,
|
|
123
|
+
...additionalPackages,
|
|
124
|
+
];
|
|
125
|
+
|
|
126
|
+
// Install all packages
|
|
127
|
+
await exec(`bun add -D ${allPackages.join(" ")}`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get framework-specific packages for Tailwind
|
|
132
|
+
*/
|
|
133
|
+
function getFrameworkPackages(framework: TailwindFramework): string[] {
|
|
134
|
+
switch (framework) {
|
|
135
|
+
case "vite":
|
|
136
|
+
return ["@tailwindcss/vite"];
|
|
137
|
+
case "astro":
|
|
138
|
+
return ["@astrojs/tailwind"];
|
|
139
|
+
case "next":
|
|
140
|
+
return [];
|
|
141
|
+
case "standalone":
|
|
142
|
+
default:
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Create or update CSS file with Tailwind directives
|
|
149
|
+
*/
|
|
150
|
+
async function createTailwindCssFile() {
|
|
151
|
+
const tailwindDirectives = `@import 'tailwindcss';`;
|
|
152
|
+
|
|
153
|
+
// Determine CSS file path
|
|
154
|
+
const cssPath =
|
|
155
|
+
props.cssPath || path.join(props.cwd, "src", "styles", "global.css");
|
|
156
|
+
|
|
157
|
+
// Create directory structure if needed
|
|
158
|
+
const cssDir = path.dirname(cssPath);
|
|
159
|
+
await Folder(path.join(id, "css-dir"), {
|
|
160
|
+
path: cssDir,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// Create CSS file with Tailwind directives
|
|
164
|
+
await StaticTextFile(cssPath, tailwindDirectives);
|
|
165
|
+
}
|
|
166
|
+
},
|
|
167
|
+
);
|
package/src/{vite → web}/vite.ts
RENAMED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { exec } from "child_process";
|
|
2
|
-
import fs from "fs/promises";
|
|
3
2
|
import path from "path";
|
|
4
3
|
import { promisify } from "util";
|
|
5
4
|
import type { Context } from "../context";
|
|
5
|
+
import { Folder, StaticJsonFile, StaticTypeScriptFile } from "../fs";
|
|
6
6
|
import { Resource } from "../resource";
|
|
7
|
-
import { ShadcnComponent } from "../shadcn/component";
|
|
8
7
|
import { rm } from "../util/rm";
|
|
8
|
+
import { ShadcnComponent } from "./shadcn-component";
|
|
9
|
+
import { TailwindConfig } from "./tailwind";
|
|
9
10
|
|
|
10
11
|
const execAsync = promisify(exec);
|
|
11
12
|
|
|
@@ -113,6 +114,11 @@ export interface ViteProjectProps {
|
|
|
113
114
|
* @default false
|
|
114
115
|
*/
|
|
115
116
|
overwrite?: boolean;
|
|
117
|
+
/**
|
|
118
|
+
* Whether to delete the project folder during the delete phase
|
|
119
|
+
* @default true
|
|
120
|
+
*/
|
|
121
|
+
delete?: boolean;
|
|
116
122
|
}
|
|
117
123
|
|
|
118
124
|
export interface ViteProject extends ViteProjectProps, Resource {
|
|
@@ -135,9 +141,8 @@ export const ViteProject = Resource(
|
|
|
135
141
|
const phase = this.phase;
|
|
136
142
|
if (this.phase === "delete") {
|
|
137
143
|
try {
|
|
138
|
-
if (
|
|
139
|
-
|
|
140
|
-
await execAsync("rm -rf " + props.name);
|
|
144
|
+
if (props.delete !== false) {
|
|
145
|
+
await execAsync(`rm -rf ${props.name}`);
|
|
141
146
|
}
|
|
142
147
|
} catch (error) {
|
|
143
148
|
console.error(`Error deleting project ${id}:`, error);
|
|
@@ -174,6 +179,12 @@ export const ViteProject = Resource(
|
|
|
174
179
|
|
|
175
180
|
const cwd = path.resolve(process.cwd(), props.name);
|
|
176
181
|
|
|
182
|
+
// Create folder for project
|
|
183
|
+
await Folder("project-dir", {
|
|
184
|
+
path: props.name,
|
|
185
|
+
delete: props.delete,
|
|
186
|
+
});
|
|
187
|
+
|
|
177
188
|
const exec = (command: string) => execAsync(command, { cwd });
|
|
178
189
|
|
|
179
190
|
if (phase === "create" || props.overwrite) {
|
|
@@ -202,9 +213,12 @@ export const ViteProject = Resource(
|
|
|
202
213
|
}
|
|
203
214
|
|
|
204
215
|
async function installTailwind() {
|
|
205
|
-
await
|
|
216
|
+
await TailwindConfig(`${id}-tailwind`, {
|
|
217
|
+
cwd: props.name,
|
|
218
|
+
framework: "vite",
|
|
219
|
+
});
|
|
206
220
|
|
|
207
|
-
await
|
|
221
|
+
await StaticTypeScriptFile(
|
|
208
222
|
path.join(props.name, "vite.config.ts"),
|
|
209
223
|
`import path from "path";
|
|
210
224
|
import react from "@vitejs/plugin-react";
|
|
@@ -222,16 +236,6 @@ export default defineConfig({
|
|
|
222
236
|
},
|
|
223
237
|
});`,
|
|
224
238
|
);
|
|
225
|
-
|
|
226
|
-
// Add Tailwind CSS import to index.css
|
|
227
|
-
const indexCssPath = path.join(props.name, "src", "index.css");
|
|
228
|
-
const currentCss = await fs.readFile(indexCssPath, "utf-8");
|
|
229
|
-
if (!currentCss.includes('@import "tailwindcss";')) {
|
|
230
|
-
await fs.writeFile(
|
|
231
|
-
indexCssPath,
|
|
232
|
-
'@import "tailwindcss";\n\n' + currentCss,
|
|
233
|
-
);
|
|
234
|
-
}
|
|
235
239
|
}
|
|
236
240
|
|
|
237
241
|
async function installShadcn() {
|
|
@@ -273,8 +277,14 @@ export default defineConfig({
|
|
|
273
277
|
|
|
274
278
|
const src = path.join(props.name, "src");
|
|
275
279
|
const routes = path.join(src, "routes");
|
|
276
|
-
|
|
277
|
-
|
|
280
|
+
|
|
281
|
+
// Create routes directory
|
|
282
|
+
await Folder("routes-dir", {
|
|
283
|
+
path: routes,
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Create root route file
|
|
287
|
+
await StaticTypeScriptFile(
|
|
278
288
|
path.join(routes, "__root.tsx"),
|
|
279
289
|
`import { Link, Outlet, createRootRoute } from "@tanstack/react-router";
|
|
280
290
|
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
|
@@ -299,7 +309,8 @@ export const Route = createRootRoute({
|
|
|
299
309
|
`,
|
|
300
310
|
);
|
|
301
311
|
|
|
302
|
-
|
|
312
|
+
// Create index route file
|
|
313
|
+
await StaticTypeScriptFile(
|
|
303
314
|
path.join(routes, "index.tsx"),
|
|
304
315
|
`import { createLazyFileRoute } from '@tanstack/react-router'
|
|
305
316
|
|
|
@@ -316,7 +327,8 @@ function Index() {
|
|
|
316
327
|
}`,
|
|
317
328
|
);
|
|
318
329
|
|
|
319
|
-
|
|
330
|
+
// Create about route file
|
|
331
|
+
await StaticTypeScriptFile(
|
|
320
332
|
path.join(routes, "about.tsx"),
|
|
321
333
|
`import { createLazyFileRoute } from '@tanstack/react-router'
|
|
322
334
|
|
|
@@ -329,7 +341,8 @@ function About() {
|
|
|
329
341
|
}`,
|
|
330
342
|
);
|
|
331
343
|
|
|
332
|
-
|
|
344
|
+
// Create main.tsx
|
|
345
|
+
await StaticTypeScriptFile(
|
|
333
346
|
path.join(src, "main.tsx"),
|
|
334
347
|
`import { StrictMode } from 'react'
|
|
335
348
|
import ReactDOM from 'react-dom/client'
|
|
@@ -363,43 +376,28 @@ if (!rootElement.innerHTML) {
|
|
|
363
376
|
}
|
|
364
377
|
|
|
365
378
|
async function removeUnnecessaryFiles() {
|
|
366
|
-
await
|
|
367
|
-
|
|
368
|
-
rm(path.join(props.name, "src", "App.css")),
|
|
369
|
-
]);
|
|
379
|
+
await rm(path.join(props.name, "src", "App.tsx"));
|
|
380
|
+
await rm(path.join(props.name, "src", "App.css"));
|
|
370
381
|
}
|
|
371
382
|
|
|
372
383
|
async function patchTsConfig() {
|
|
373
|
-
await
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
include: [
|
|
391
|
-
"vite/*.ts",
|
|
392
|
-
"src/**/*.ts",
|
|
393
|
-
"src/**/*.tsx",
|
|
394
|
-
"src/env.d.ts",
|
|
395
|
-
],
|
|
396
|
-
references: props.references?.map((path) => ({ path })),
|
|
397
|
-
},
|
|
398
|
-
null,
|
|
399
|
-
2,
|
|
400
|
-
),
|
|
401
|
-
),
|
|
402
|
-
]);
|
|
384
|
+
await rm(path.join(props.name, "tsconfig.app.json"));
|
|
385
|
+
await rm(path.join(props.name, "tsconfig.node.json"));
|
|
386
|
+
|
|
387
|
+
await StaticJsonFile(path.join(props.name, "tsconfig.json"), {
|
|
388
|
+
extends: props.extends,
|
|
389
|
+
compilerOptions: {
|
|
390
|
+
baseUrl: ".",
|
|
391
|
+
paths: {
|
|
392
|
+
"@/*": ["./src/*"],
|
|
393
|
+
},
|
|
394
|
+
types: ["@cloudflare/workers-types"],
|
|
395
|
+
allowImportingTsExtensions: true,
|
|
396
|
+
jsx: "react-jsx",
|
|
397
|
+
},
|
|
398
|
+
include: ["vite/*.ts", "src/**/*.ts", "src/**/*.tsx", "src/env.d.ts"],
|
|
399
|
+
references: props.references?.map((path) => ({ path })),
|
|
400
|
+
});
|
|
403
401
|
}
|
|
404
402
|
}
|
|
405
403
|
},
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import type { DefaultTheme, ThemeOptions } from "vitepress";
|
|
3
|
+
import { StaticTypeScriptFile } from "../../fs/static-typescript-file";
|
|
4
|
+
|
|
5
|
+
export type VitePressConfigProps = {
|
|
6
|
+
cwd: string;
|
|
7
|
+
title?: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
theme?: ThemeOptions;
|
|
10
|
+
themeConfig: DefaultTheme.Config;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type VitePressConfig = Awaited<ReturnType<typeof VitePressConfig>>;
|
|
14
|
+
|
|
15
|
+
export function VitePressConfig(props: VitePressConfigProps) {
|
|
16
|
+
return StaticTypeScriptFile(
|
|
17
|
+
path.join(props.cwd, ".vitepress", "config.mts"),
|
|
18
|
+
`import { transformerTwoslash } from "@shikijs/vitepress-twoslash";
|
|
19
|
+
import footnotePlugin from "markdown-it-footnote";
|
|
20
|
+
import { defineConfig } from "vitepress";
|
|
21
|
+
|
|
22
|
+
// https://vitepress.dev/reference/site-config
|
|
23
|
+
export default defineConfig({
|
|
24
|
+
title: ${JSON.stringify(props.title || "Alchemy")},
|
|
25
|
+
description: ${JSON.stringify(props.description || "Alchemy Docs")},
|
|
26
|
+
markdown: {
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
codeTransformers: [transformerTwoslash()],
|
|
29
|
+
theme: ${JSON.stringify(
|
|
30
|
+
props.theme ?? {
|
|
31
|
+
light: "light-plus",
|
|
32
|
+
dark: "dark-plus",
|
|
33
|
+
}
|
|
34
|
+
)},
|
|
35
|
+
config: (md) => md.use(footnotePlugin),
|
|
36
|
+
},
|
|
37
|
+
// https://vitepress.dev/reference/default-theme-config
|
|
38
|
+
themeConfig: ${JSON.stringify({
|
|
39
|
+
...props.themeConfig,
|
|
40
|
+
search: props.themeConfig.search ?? { provider: "local" },
|
|
41
|
+
nav: props.themeConfig.nav ?? [{ text: "Home", link: "/" }],
|
|
42
|
+
sidebar: props.themeConfig.sidebar ?? [],
|
|
43
|
+
socialLinks: props.themeConfig.socialLinks ?? [],
|
|
44
|
+
})}
|
|
45
|
+
});
|
|
46
|
+
`
|
|
47
|
+
);
|
|
48
|
+
}
|