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,97 @@
|
|
|
1
|
+
import type { Context } from "../context";
|
|
2
|
+
import { Folder } from "../fs";
|
|
3
|
+
import { Resource } from "../resource";
|
|
4
|
+
/**
|
|
5
|
+
* Properties for initializing Shadcn UI
|
|
6
|
+
*/
|
|
7
|
+
export interface ShadcnUIProps {
|
|
8
|
+
/**
|
|
9
|
+
* The working directory where Shadcn UI should be installed
|
|
10
|
+
*/
|
|
11
|
+
cwd: string;
|
|
12
|
+
/**
|
|
13
|
+
* The base color to use
|
|
14
|
+
* @default "neutral"
|
|
15
|
+
*/
|
|
16
|
+
baseColor?: "neutral" | "gray" | "zinc" | "stone" | "slate";
|
|
17
|
+
/**
|
|
18
|
+
* Use default configuration
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
defaults?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Force overwrite of existing configuration
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
force?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Mute output
|
|
29
|
+
* @default false
|
|
30
|
+
*/
|
|
31
|
+
silent?: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Use the src directory when creating a new project
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
srcDir?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Use css variables for theming
|
|
39
|
+
* @default true
|
|
40
|
+
*/
|
|
41
|
+
cssVariables?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The components to add
|
|
44
|
+
*/
|
|
45
|
+
components?: string[];
|
|
46
|
+
/**
|
|
47
|
+
* Whether tailwind is already installed and configured.
|
|
48
|
+
* Shadcn UI requires Tailwind CSS to be installed and configured.
|
|
49
|
+
* @default false
|
|
50
|
+
*/
|
|
51
|
+
tailwind?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Whether react is already installed
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
react?: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Shadcn UI resource
|
|
60
|
+
*/
|
|
61
|
+
export interface ShadcnUI extends ShadcnUIProps, Resource<"project::ShadcnUI"> {
|
|
62
|
+
/**
|
|
63
|
+
* The working directory where Shadcn UI is installed
|
|
64
|
+
*/
|
|
65
|
+
cwd: string;
|
|
66
|
+
/**
|
|
67
|
+
* The ui directory
|
|
68
|
+
*/
|
|
69
|
+
ui: Folder;
|
|
70
|
+
/**
|
|
71
|
+
* The lib directory
|
|
72
|
+
*/
|
|
73
|
+
lib: Folder;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Initializes Shadcn UI in a project directory
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* // Initialize Shadcn UI with default settings
|
|
80
|
+
* const shadcn = await ShadcnUI("my-shadcn", {
|
|
81
|
+
* cwd: "my-project",
|
|
82
|
+
* tailwind: true, // Tailwind must be installed separately
|
|
83
|
+
* react: true // React must be installed separately
|
|
84
|
+
* });
|
|
85
|
+
*
|
|
86
|
+
* @example
|
|
87
|
+
* // Initialize Shadcn UI with custom settings and components
|
|
88
|
+
* const shadcn = await ShadcnUI("custom-shadcn", {
|
|
89
|
+
* cwd: "my-project",
|
|
90
|
+
* baseColor: "zinc",
|
|
91
|
+
* force: true,
|
|
92
|
+
* components: ["button", "card", "input"],
|
|
93
|
+
* tailwind: true, // Tailwind must be installed separately
|
|
94
|
+
* react: true // React must be installed separately
|
|
95
|
+
* });
|
|
96
|
+
*/
|
|
97
|
+
export declare const ShadcnUI: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<ShadcnUI>, id: string, props: ShadcnUIProps) => Promise<ShadcnUI>);
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { promisify } from "util";
|
|
4
|
+
import { Folder, StaticJsonFile } from "../fs";
|
|
5
|
+
import { StaticTypeScriptFile } from "../fs/static-typescript-file";
|
|
6
|
+
import { Resource } from "../resource";
|
|
7
|
+
import { ShadcnComponent } from "./shadcn-component";
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
/**
|
|
10
|
+
* Initializes Shadcn UI in a project directory
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Initialize Shadcn UI with default settings
|
|
14
|
+
* const shadcn = await ShadcnUI("my-shadcn", {
|
|
15
|
+
* cwd: "my-project",
|
|
16
|
+
* tailwind: true, // Tailwind must be installed separately
|
|
17
|
+
* react: true // React must be installed separately
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* // Initialize Shadcn UI with custom settings and components
|
|
22
|
+
* const shadcn = await ShadcnUI("custom-shadcn", {
|
|
23
|
+
* cwd: "my-project",
|
|
24
|
+
* baseColor: "zinc",
|
|
25
|
+
* force: true,
|
|
26
|
+
* components: ["button", "card", "input"],
|
|
27
|
+
* tailwind: true, // Tailwind must be installed separately
|
|
28
|
+
* react: true // React must be installed separately
|
|
29
|
+
* });
|
|
30
|
+
*/
|
|
31
|
+
export const ShadcnUI = Resource("project::ShadcnUI", async function (id, props) {
|
|
32
|
+
if (this.phase === "delete") {
|
|
33
|
+
// For a delete phase, we don't perform any action
|
|
34
|
+
// as removing Shadcn UI would require removing many files
|
|
35
|
+
// which could be destructive to the project
|
|
36
|
+
console.log("Note: ShadcnUI delete phase does not remove installed components");
|
|
37
|
+
return this.destroy();
|
|
38
|
+
}
|
|
39
|
+
// Setup execAsync with the correct cwd
|
|
40
|
+
const exec = (command) => execAsync(command, { cwd: props.cwd });
|
|
41
|
+
// Ensure React is installed if not already
|
|
42
|
+
if (!props.react) {
|
|
43
|
+
await exec(`bun add react react-dom`);
|
|
44
|
+
}
|
|
45
|
+
// Install shadcn dependencies
|
|
46
|
+
await exec(`bun add -D @types/node`);
|
|
47
|
+
// Create components.json directly instead of running shadcn init
|
|
48
|
+
await StaticJsonFile(path.join(props.cwd, "components.json"), {
|
|
49
|
+
$schema: "https://ui.shadcn.com/schema.json",
|
|
50
|
+
style: props.cssVariables !== false ? "default" : "new-york",
|
|
51
|
+
tsx: true,
|
|
52
|
+
rsc: false,
|
|
53
|
+
tailwind: {
|
|
54
|
+
config: "tailwind.config.js",
|
|
55
|
+
css: props.srcDir !== false
|
|
56
|
+
? "src/styles/globals.css"
|
|
57
|
+
: "styles/globals.css",
|
|
58
|
+
baseColor: props.baseColor || "neutral",
|
|
59
|
+
cssVariables: props.cssVariables !== false,
|
|
60
|
+
},
|
|
61
|
+
aliases: {
|
|
62
|
+
components: props.srcDir !== false ? "@/components" : "./components",
|
|
63
|
+
utils: props.srcDir !== false ? "@/lib/utils" : "./lib/utils",
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
// Ensure ui components directory exists
|
|
67
|
+
const ui = await Folder(path.join(props.cwd, props.srcDir !== false ? "src" : "", "components", "ui"));
|
|
68
|
+
// Create lib directory
|
|
69
|
+
const libPath = path.join(props.cwd, props.srcDir !== false ? "src" : "", "lib");
|
|
70
|
+
const lib = await Folder(libPath);
|
|
71
|
+
// Create utils.ts file
|
|
72
|
+
const utilsContent = `
|
|
73
|
+
import { type ClassValue, clsx } from "clsx";
|
|
74
|
+
import { twMerge } from "tailwind-merge";
|
|
75
|
+
|
|
76
|
+
export function cn(...inputs: ClassValue[]) {
|
|
77
|
+
return twMerge(clsx(inputs));
|
|
78
|
+
}
|
|
79
|
+
`;
|
|
80
|
+
await StaticTypeScriptFile(path.join(libPath, "utils.ts"), utilsContent);
|
|
81
|
+
// Install clsx and tailwind-merge
|
|
82
|
+
await exec(`bun add clsx tailwind-merge`);
|
|
83
|
+
// Install requested components
|
|
84
|
+
if (props.components && props.components.length > 0) {
|
|
85
|
+
for (const componentName of props.components) {
|
|
86
|
+
await ShadcnComponent(`shadcn-component-${componentName}`, {
|
|
87
|
+
name: componentName,
|
|
88
|
+
cwd: props.cwd,
|
|
89
|
+
force: props.force,
|
|
90
|
+
silent: props.silent,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return this({
|
|
95
|
+
...props,
|
|
96
|
+
ui,
|
|
97
|
+
lib,
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { Context } from "../context";
|
|
2
|
+
import { Resource } from "../resource";
|
|
3
|
+
/**
|
|
4
|
+
* Framework types supported by the Tailwind resource
|
|
5
|
+
*/
|
|
6
|
+
export type TailwindFramework = "vite" | "astro" | "next" | "standalone";
|
|
7
|
+
/**
|
|
8
|
+
* Properties for Tailwind configuration
|
|
9
|
+
*/
|
|
10
|
+
export interface TailwindConfigProps {
|
|
11
|
+
/**
|
|
12
|
+
* The working directory where Tailwind should be installed
|
|
13
|
+
*/
|
|
14
|
+
cwd: string;
|
|
15
|
+
/**
|
|
16
|
+
* The framework being used (determines which dependencies to install)
|
|
17
|
+
* @default "standalone"
|
|
18
|
+
*/
|
|
19
|
+
framework?: TailwindFramework;
|
|
20
|
+
/**
|
|
21
|
+
* The path to the CSS file where Tailwind directives should be added
|
|
22
|
+
* If not provided, a new file will be created at src/styles/base.css
|
|
23
|
+
*/
|
|
24
|
+
cssPath?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Custom additional packages to install with Tailwind
|
|
27
|
+
*/
|
|
28
|
+
additionalPackages?: string[];
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Tailwind configuration resource
|
|
32
|
+
*/
|
|
33
|
+
export interface TailwindConfig extends TailwindConfigProps, Resource<"config::TailwindConfig"> {
|
|
34
|
+
/**
|
|
35
|
+
* The working directory where Tailwind is installed
|
|
36
|
+
*/
|
|
37
|
+
cwd: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Installs and configures Tailwind CSS for a project
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* // Install Tailwind for a Vite project
|
|
44
|
+
* const tailwind = await TailwindConfig("vite-tailwind", {
|
|
45
|
+
* cwd: "my-vite-app",
|
|
46
|
+
* framework: "vite"
|
|
47
|
+
* });
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* // Install Tailwind for an Astro project
|
|
51
|
+
* const tailwind = await TailwindConfig("astro-tailwind", {
|
|
52
|
+
* cwd: "my-astro-app",
|
|
53
|
+
* framework: "astro"
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* // Install Tailwind as standalone with a custom CSS path
|
|
58
|
+
* const tailwind = await TailwindConfig("custom-tailwind", {
|
|
59
|
+
* cwd: "my-project",
|
|
60
|
+
* cssPath: "src/css/main.css",
|
|
61
|
+
* additionalPackages: ["@tailwindcss/typography", "@tailwindcss/forms"]
|
|
62
|
+
* });
|
|
63
|
+
*/
|
|
64
|
+
export declare const TailwindConfig: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<TailwindConfig>, id: string, props: TailwindConfigProps) => Promise<TailwindConfig>);
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { exec } from "child_process";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { promisify } from "util";
|
|
4
|
+
import { Folder, StaticTextFile } from "../fs";
|
|
5
|
+
import { Resource } from "../resource";
|
|
6
|
+
const execAsync = promisify(exec);
|
|
7
|
+
/**
|
|
8
|
+
* Installs and configures Tailwind CSS for a project
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // Install Tailwind for a Vite project
|
|
12
|
+
* const tailwind = await TailwindConfig("vite-tailwind", {
|
|
13
|
+
* cwd: "my-vite-app",
|
|
14
|
+
* framework: "vite"
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* // Install Tailwind for an Astro project
|
|
19
|
+
* const tailwind = await TailwindConfig("astro-tailwind", {
|
|
20
|
+
* cwd: "my-astro-app",
|
|
21
|
+
* framework: "astro"
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* // Install Tailwind as standalone with a custom CSS path
|
|
26
|
+
* const tailwind = await TailwindConfig("custom-tailwind", {
|
|
27
|
+
* cwd: "my-project",
|
|
28
|
+
* cssPath: "src/css/main.css",
|
|
29
|
+
* additionalPackages: ["@tailwindcss/typography", "@tailwindcss/forms"]
|
|
30
|
+
* });
|
|
31
|
+
*/
|
|
32
|
+
export const TailwindConfig = Resource("config::TailwindConfig", async function (id, props) {
|
|
33
|
+
if (this.phase === "delete") {
|
|
34
|
+
// Nothing to clean up specifically for Tailwind
|
|
35
|
+
return this.destroy();
|
|
36
|
+
}
|
|
37
|
+
const framework = props.framework || "standalone";
|
|
38
|
+
// Setup execAsync with the correct cwd
|
|
39
|
+
const exec = (command) => execAsync(command, { cwd: props.cwd });
|
|
40
|
+
// Install Tailwind and framework-specific dependencies
|
|
41
|
+
await installTailwindDependencies(framework);
|
|
42
|
+
// Create CSS file with Tailwind directives
|
|
43
|
+
await createTailwindCssFile();
|
|
44
|
+
return this({
|
|
45
|
+
...props,
|
|
46
|
+
framework: framework,
|
|
47
|
+
});
|
|
48
|
+
/**
|
|
49
|
+
* Install Tailwind and framework-specific dependencies
|
|
50
|
+
*/
|
|
51
|
+
async function installTailwindDependencies(framework) {
|
|
52
|
+
const basePackages = ["tailwindcss", "postcss", "autoprefixer"];
|
|
53
|
+
// Add framework-specific packages
|
|
54
|
+
const frameworkPackages = getFrameworkPackages(framework);
|
|
55
|
+
// Add custom additional packages
|
|
56
|
+
const additionalPackages = props.additionalPackages || [];
|
|
57
|
+
// Combine all packages
|
|
58
|
+
const allPackages = [
|
|
59
|
+
...basePackages,
|
|
60
|
+
...frameworkPackages,
|
|
61
|
+
...additionalPackages,
|
|
62
|
+
];
|
|
63
|
+
// Install all packages
|
|
64
|
+
await exec(`bun add -D ${allPackages.join(" ")}`);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Get framework-specific packages for Tailwind
|
|
68
|
+
*/
|
|
69
|
+
function getFrameworkPackages(framework) {
|
|
70
|
+
switch (framework) {
|
|
71
|
+
case "vite":
|
|
72
|
+
return ["@tailwindcss/vite"];
|
|
73
|
+
case "astro":
|
|
74
|
+
return ["@astrojs/tailwind"];
|
|
75
|
+
case "next":
|
|
76
|
+
return [];
|
|
77
|
+
case "standalone":
|
|
78
|
+
default:
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create or update CSS file with Tailwind directives
|
|
84
|
+
*/
|
|
85
|
+
async function createTailwindCssFile() {
|
|
86
|
+
const tailwindDirectives = `@import 'tailwindcss';`;
|
|
87
|
+
// Determine CSS file path
|
|
88
|
+
const cssPath = props.cssPath || path.join(props.cwd, "src", "styles", "global.css");
|
|
89
|
+
// Create directory structure if needed
|
|
90
|
+
const cssDir = path.dirname(cssPath);
|
|
91
|
+
await Folder(path.join(id, "css-dir"), {
|
|
92
|
+
path: cssDir,
|
|
93
|
+
});
|
|
94
|
+
// Create CSS file with Tailwind directives
|
|
95
|
+
await StaticTextFile(cssPath, tailwindDirectives);
|
|
96
|
+
}
|
|
97
|
+
});
|
|
@@ -79,6 +79,11 @@ export interface ViteProjectProps {
|
|
|
79
79
|
* @default false
|
|
80
80
|
*/
|
|
81
81
|
overwrite?: boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Whether to delete the project folder during the delete phase
|
|
84
|
+
* @default true
|
|
85
|
+
*/
|
|
86
|
+
delete?: boolean;
|
|
82
87
|
}
|
|
83
88
|
export interface ViteProject extends ViteProjectProps, Resource {
|
|
84
89
|
/**
|
package/lib/{vite → web}/vite.js
RENAMED
|
@@ -1,10 +1,11 @@
|
|
|
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";
|
|
4
|
+
import { Folder, StaticJsonFile, StaticTypeScriptFile } from "../fs";
|
|
5
5
|
import { Resource } from "../resource";
|
|
6
|
-
import { ShadcnComponent } from "../shadcn/component";
|
|
7
6
|
import { rm } from "../util/rm";
|
|
7
|
+
import { ShadcnComponent } from "./shadcn-component";
|
|
8
|
+
import { TailwindConfig } from "./tailwind";
|
|
8
9
|
const execAsync = promisify(exec);
|
|
9
10
|
export const ViteProject = Resource("project::ViteProject", {
|
|
10
11
|
alwaysUpdate: true,
|
|
@@ -12,9 +13,8 @@ export const ViteProject = Resource("project::ViteProject", {
|
|
|
12
13
|
const phase = this.phase;
|
|
13
14
|
if (this.phase === "delete") {
|
|
14
15
|
try {
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
await execAsync("rm -rf " + props.name);
|
|
16
|
+
if (props.delete !== false) {
|
|
17
|
+
await execAsync(`rm -rf ${props.name}`);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
catch (error) {
|
|
@@ -45,6 +45,11 @@ export const ViteProject = Resource("project::ViteProject", {
|
|
|
45
45
|
"react()",
|
|
46
46
|
].filter((s) => typeof s === "string");
|
|
47
47
|
const cwd = path.resolve(process.cwd(), props.name);
|
|
48
|
+
// Create folder for project
|
|
49
|
+
await Folder("project-dir", {
|
|
50
|
+
path: props.name,
|
|
51
|
+
delete: props.delete,
|
|
52
|
+
});
|
|
48
53
|
const exec = (command) => execAsync(command, { cwd });
|
|
49
54
|
if (phase === "create" || props.overwrite) {
|
|
50
55
|
await removeUnnecessaryFiles();
|
|
@@ -65,8 +70,11 @@ export const ViteProject = Resource("project::ViteProject", {
|
|
|
65
70
|
await execAsync(`bun vite build`, { cwd: props.name });
|
|
66
71
|
}
|
|
67
72
|
async function installTailwind() {
|
|
68
|
-
await
|
|
69
|
-
|
|
73
|
+
await TailwindConfig(`${id}-tailwind`, {
|
|
74
|
+
cwd: props.name,
|
|
75
|
+
framework: "vite",
|
|
76
|
+
});
|
|
77
|
+
await StaticTypeScriptFile(path.join(props.name, "vite.config.ts"), `import path from "path";
|
|
70
78
|
import react from "@vitejs/plugin-react";
|
|
71
79
|
import { defineConfig } from "vite";
|
|
72
80
|
${tailwind ? "import tailwindcss from '@tailwindcss/vite';" : ""}
|
|
@@ -81,12 +89,6 @@ export default defineConfig({
|
|
|
81
89
|
},
|
|
82
90
|
},
|
|
83
91
|
});`);
|
|
84
|
-
// Add Tailwind CSS import to index.css
|
|
85
|
-
const indexCssPath = path.join(props.name, "src", "index.css");
|
|
86
|
-
const currentCss = await fs.readFile(indexCssPath, "utf-8");
|
|
87
|
-
if (!currentCss.includes('@import "tailwindcss";')) {
|
|
88
|
-
await fs.writeFile(indexCssPath, '@import "tailwindcss";\n\n' + currentCss);
|
|
89
|
-
}
|
|
90
92
|
}
|
|
91
93
|
async function installShadcn() {
|
|
92
94
|
await exec("bun add -D @types/node");
|
|
@@ -120,8 +122,12 @@ export default defineConfig({
|
|
|
120
122
|
await exec(`bun add -D @tanstack/router-plugin @tanstack/react-router-devtools`);
|
|
121
123
|
const src = path.join(props.name, "src");
|
|
122
124
|
const routes = path.join(src, "routes");
|
|
123
|
-
|
|
124
|
-
await
|
|
125
|
+
// Create routes directory
|
|
126
|
+
await Folder("routes-dir", {
|
|
127
|
+
path: routes,
|
|
128
|
+
});
|
|
129
|
+
// Create root route file
|
|
130
|
+
await StaticTypeScriptFile(path.join(routes, "__root.tsx"), `import { Link, Outlet, createRootRoute } from "@tanstack/react-router";
|
|
125
131
|
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
|
|
126
132
|
|
|
127
133
|
export const Route = createRootRoute({
|
|
@@ -142,7 +148,8 @@ export const Route = createRootRoute({
|
|
|
142
148
|
),
|
|
143
149
|
});
|
|
144
150
|
`);
|
|
145
|
-
|
|
151
|
+
// Create index route file
|
|
152
|
+
await StaticTypeScriptFile(path.join(routes, "index.tsx"), `import { createLazyFileRoute } from '@tanstack/react-router'
|
|
146
153
|
|
|
147
154
|
export const Route = createLazyFileRoute('/')({
|
|
148
155
|
component: Index,
|
|
@@ -155,7 +162,8 @@ function Index() {
|
|
|
155
162
|
</div>
|
|
156
163
|
)
|
|
157
164
|
}`);
|
|
158
|
-
|
|
165
|
+
// Create about route file
|
|
166
|
+
await StaticTypeScriptFile(path.join(routes, "about.tsx"), `import { createLazyFileRoute } from '@tanstack/react-router'
|
|
159
167
|
|
|
160
168
|
export const Route = createLazyFileRoute('/about')({
|
|
161
169
|
component: About,
|
|
@@ -164,7 +172,8 @@ export const Route = createLazyFileRoute('/about')({
|
|
|
164
172
|
function About() {
|
|
165
173
|
return <div className="p-2">Hello from About!</div>
|
|
166
174
|
}`);
|
|
167
|
-
|
|
175
|
+
// Create main.tsx
|
|
176
|
+
await StaticTypeScriptFile(path.join(src, "main.tsx"), `import { StrictMode } from 'react'
|
|
168
177
|
import ReactDOM from 'react-dom/client'
|
|
169
178
|
import { RouterProvider, createRouter } from '@tanstack/react-router'
|
|
170
179
|
import './index.css'
|
|
@@ -194,35 +203,26 @@ if (!rootElement.innerHTML) {
|
|
|
194
203
|
}`);
|
|
195
204
|
}
|
|
196
205
|
async function removeUnnecessaryFiles() {
|
|
197
|
-
await
|
|
198
|
-
|
|
199
|
-
rm(path.join(props.name, "src", "App.css")),
|
|
200
|
-
]);
|
|
206
|
+
await rm(path.join(props.name, "src", "App.tsx"));
|
|
207
|
+
await rm(path.join(props.name, "src", "App.css"));
|
|
201
208
|
}
|
|
202
209
|
async function patchTsConfig() {
|
|
203
|
-
await
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
"@/*": ["./src/*"],
|
|
212
|
-
},
|
|
213
|
-
types: ["@cloudflare/workers-types"],
|
|
214
|
-
allowImportingTsExtensions: true,
|
|
215
|
-
jsx: "react-jsx",
|
|
210
|
+
await rm(path.join(props.name, "tsconfig.app.json"));
|
|
211
|
+
await rm(path.join(props.name, "tsconfig.node.json"));
|
|
212
|
+
await StaticJsonFile(path.join(props.name, "tsconfig.json"), {
|
|
213
|
+
extends: props.extends,
|
|
214
|
+
compilerOptions: {
|
|
215
|
+
baseUrl: ".",
|
|
216
|
+
paths: {
|
|
217
|
+
"@/*": ["./src/*"],
|
|
216
218
|
},
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}, null, 2)),
|
|
225
|
-
]);
|
|
219
|
+
types: ["@cloudflare/workers-types"],
|
|
220
|
+
allowImportingTsExtensions: true,
|
|
221
|
+
jsx: "react-jsx",
|
|
222
|
+
},
|
|
223
|
+
include: ["vite/*.ts", "src/**/*.ts", "src/**/*.tsx", "src/env.d.ts"],
|
|
224
|
+
references: props.references?.map((path) => ({ path })),
|
|
225
|
+
});
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
228
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { DefaultTheme, ThemeOptions } from "vitepress";
|
|
2
|
+
export type VitePressConfigProps = {
|
|
3
|
+
cwd: string;
|
|
4
|
+
title?: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
theme?: ThemeOptions;
|
|
7
|
+
themeConfig: DefaultTheme.Config;
|
|
8
|
+
};
|
|
9
|
+
export type VitePressConfig = Awaited<ReturnType<typeof VitePressConfig>>;
|
|
10
|
+
export declare function VitePressConfig(props: VitePressConfigProps): Promise<import("../../fs").File>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { StaticTypeScriptFile } from "../../fs/static-typescript-file";
|
|
3
|
+
export function VitePressConfig(props) {
|
|
4
|
+
return StaticTypeScriptFile(path.join(props.cwd, ".vitepress", "config.mts"), `import { transformerTwoslash } from "@shikijs/vitepress-twoslash";
|
|
5
|
+
import footnotePlugin from "markdown-it-footnote";
|
|
6
|
+
import { defineConfig } from "vitepress";
|
|
7
|
+
|
|
8
|
+
// https://vitepress.dev/reference/site-config
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
title: ${JSON.stringify(props.title || "Alchemy")},
|
|
11
|
+
description: ${JSON.stringify(props.description || "Alchemy Docs")},
|
|
12
|
+
markdown: {
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
codeTransformers: [transformerTwoslash()],
|
|
15
|
+
theme: ${JSON.stringify(props.theme ?? {
|
|
16
|
+
light: "light-plus",
|
|
17
|
+
dark: "dark-plus",
|
|
18
|
+
})},
|
|
19
|
+
config: (md) => md.use(footnotePlugin),
|
|
20
|
+
},
|
|
21
|
+
// https://vitepress.dev/reference/default-theme-config
|
|
22
|
+
themeConfig: ${JSON.stringify({
|
|
23
|
+
...props.themeConfig,
|
|
24
|
+
search: props.themeConfig.search ?? { provider: "local" },
|
|
25
|
+
nav: props.themeConfig.nav ?? [{ text: "Home", link: "/" }],
|
|
26
|
+
sidebar: props.themeConfig.sidebar ?? [],
|
|
27
|
+
socialLinks: props.themeConfig.socialLinks ?? [],
|
|
28
|
+
})}
|
|
29
|
+
});
|
|
30
|
+
`);
|
|
31
|
+
}
|