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
package/src/cloudflare/state.ts
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import type { KVNamespace } from "@cloudflare/workers-types";
|
|
2
|
-
import type { State, StateStore } from "../state";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Options for CloudflareStateStore
|
|
6
|
-
*/
|
|
7
|
-
export interface CloudflareStateStoreOptions {
|
|
8
|
-
/**
|
|
9
|
-
* The prefix to use for keys in the KV namespace
|
|
10
|
-
* This allows multiple state stores to use the same KV namespace
|
|
11
|
-
*/
|
|
12
|
-
prefix?: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* State store implementation using Cloudflare KV Namespace
|
|
17
|
-
*/
|
|
18
|
-
export class CloudflareStateStore implements StateStore {
|
|
19
|
-
private namespace: KVNamespace;
|
|
20
|
-
private prefix: string;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Create a new CloudflareStateStore
|
|
24
|
-
*
|
|
25
|
-
* @param namespace The KV namespace to use for storing state
|
|
26
|
-
* @param options Options for the state store
|
|
27
|
-
*/
|
|
28
|
-
constructor(
|
|
29
|
-
namespace: KVNamespace,
|
|
30
|
-
options: CloudflareStateStoreOptions = {},
|
|
31
|
-
) {
|
|
32
|
-
this.namespace = namespace;
|
|
33
|
-
this.prefix = options.prefix || "alchemy-state:";
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* No initialization needed for KV namespaces as they are pre-provisioned
|
|
38
|
-
*/
|
|
39
|
-
async init(): Promise<void> {
|
|
40
|
-
// KV namespaces are pre-provisioned in Cloudflare, so no initialization is needed
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* KV namespaces cannot be deleted programmatically
|
|
45
|
-
*/
|
|
46
|
-
async deinit(): Promise<void> {
|
|
47
|
-
// KV namespaces can only be deleted through the Cloudflare dashboard or API
|
|
48
|
-
// We cannot delete the namespace itself here
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* List all resources in the state store
|
|
53
|
-
*/
|
|
54
|
-
async list(): Promise<string[]> {
|
|
55
|
-
const list = await this.namespace.list({ prefix: this.prefix });
|
|
56
|
-
return list.keys.map((key) => key.name.slice(this.prefix.length));
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Count the number of items in the state store
|
|
61
|
-
*/
|
|
62
|
-
async count(): Promise<number> {
|
|
63
|
-
const list = await this.namespace.list({ prefix: this.prefix });
|
|
64
|
-
return list.keys.length;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Get a state by key
|
|
69
|
-
*
|
|
70
|
-
* @param key The key to look up
|
|
71
|
-
* @returns The state or undefined if not found
|
|
72
|
-
*/
|
|
73
|
-
async get(key: string): Promise<State | undefined> {
|
|
74
|
-
const data = await this.namespace.get(this.getNamespacedKey(key), "json");
|
|
75
|
-
return data as State | undefined;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Get multiple states by their keys
|
|
80
|
-
*
|
|
81
|
-
* @param ids Array of keys to fetch
|
|
82
|
-
* @returns Record mapping keys to their states
|
|
83
|
-
*/
|
|
84
|
-
async getBatch(ids: string[]): Promise<Record<string, State>> {
|
|
85
|
-
const result: Record<string, State> = {};
|
|
86
|
-
|
|
87
|
-
// KV doesn't have a native batch get operation, so we need to make multiple requests
|
|
88
|
-
// We could optimize this with Promise.all for parallel fetching
|
|
89
|
-
const promises = ids.map(async (id) => {
|
|
90
|
-
const state = await this.get(id);
|
|
91
|
-
if (state) {
|
|
92
|
-
result[id] = state;
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
await Promise.all(promises);
|
|
97
|
-
return result;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Get all states in the store
|
|
102
|
-
*
|
|
103
|
-
* @returns Record mapping all keys to their states
|
|
104
|
-
*/
|
|
105
|
-
async all(): Promise<Record<string, State>> {
|
|
106
|
-
const keys = await this.list();
|
|
107
|
-
return this.getBatch(keys);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Set a state for a key
|
|
112
|
-
*
|
|
113
|
-
* @param key The key to set
|
|
114
|
-
* @param value The state to store
|
|
115
|
-
*/
|
|
116
|
-
async set(key: string, value: State): Promise<void> {
|
|
117
|
-
await this.namespace.put(this.getNamespacedKey(key), JSON.stringify(value));
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Delete a state by key
|
|
122
|
-
*
|
|
123
|
-
* @param key The key to delete
|
|
124
|
-
*/
|
|
125
|
-
async delete(key: string): Promise<void> {
|
|
126
|
-
await this.namespace.delete(this.getNamespacedKey(key));
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
* Get the namespaced key for storage
|
|
131
|
-
*
|
|
132
|
-
* @param key The original key
|
|
133
|
-
* @returns The key with prefix for use in the KV namespace
|
|
134
|
-
*/
|
|
135
|
-
private getNamespacedKey(key: string): string {
|
|
136
|
-
return `${this.prefix}${key}`;
|
|
137
|
-
}
|
|
138
|
-
}
|
package/src/fs/json-file.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { File } from "./file";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Creates a JSON file with formatted content
|
|
5
|
-
*
|
|
6
|
-
* @example
|
|
7
|
-
* // Create a JSON configuration file
|
|
8
|
-
* const config = await JsonFile("config.json", {
|
|
9
|
-
* api: {
|
|
10
|
-
* endpoint: "https://api.example.com",
|
|
11
|
-
* version: "v1"
|
|
12
|
-
* },
|
|
13
|
-
* features: ["auth", "logging"]
|
|
14
|
-
* });
|
|
15
|
-
*/
|
|
16
|
-
export type JsonFile = File;
|
|
17
|
-
|
|
18
|
-
export function JsonFile(id: string, content: any): Promise<JsonFile> {
|
|
19
|
-
return File(id, {
|
|
20
|
-
path: id,
|
|
21
|
-
content: JSON.stringify(content, null, 2),
|
|
22
|
-
});
|
|
23
|
-
}
|
package/src/fs/yaml-file.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { File } from "./file";
|
|
2
|
-
/**
|
|
3
|
-
* Creates a YAML file with formatted content
|
|
4
|
-
*
|
|
5
|
-
* @example
|
|
6
|
-
* // Create a YAML configuration file
|
|
7
|
-
* const config = await YamlFile("config.yaml", {
|
|
8
|
-
* server:
|
|
9
|
-
* host: "localhost"
|
|
10
|
-
* port: 3000
|
|
11
|
-
* database:
|
|
12
|
-
* url: "postgresql://localhost:5432/db"
|
|
13
|
-
* pool:
|
|
14
|
-
* min: 1
|
|
15
|
-
* max: 10
|
|
16
|
-
* });
|
|
17
|
-
*/
|
|
18
|
-
export type YamlFile = File;
|
|
19
|
-
|
|
20
|
-
export async function YamlFile(id: string, content: any): Promise<YamlFile> {
|
|
21
|
-
const yaml = await import("yaml");
|
|
22
|
-
return File(id, {
|
|
23
|
-
path: id,
|
|
24
|
-
content: yaml.stringify(content),
|
|
25
|
-
});
|
|
26
|
-
}
|
package/src/internal/docs.ts
DELETED
|
@@ -1,338 +0,0 @@
|
|
|
1
|
-
import { type } from "arktype";
|
|
2
|
-
import fs from "fs/promises";
|
|
3
|
-
import path from "path";
|
|
4
|
-
import { Data } from "../ai/data";
|
|
5
|
-
import { Document } from "../ai/document";
|
|
6
|
-
import { alchemy } from "../alchemy";
|
|
7
|
-
import { Folder } from "../fs/folder";
|
|
8
|
-
import { VitePressProject } from "../vitepress/vitepress";
|
|
9
|
-
|
|
10
|
-
export interface DocsProps {
|
|
11
|
-
docs?: boolean | number;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export type AlchemyDocs = Awaited<ReturnType<typeof AlchemyDocs>>;
|
|
15
|
-
|
|
16
|
-
export async function AlchemyDocs({ docs: isDocsEnabled }: DocsProps) {
|
|
17
|
-
const root = (await Folder("alchemy-web")).path;
|
|
18
|
-
|
|
19
|
-
const docs = (await Folder(path.join(root, "docs"))).path;
|
|
20
|
-
|
|
21
|
-
const providersDir = (await Folder(path.join(docs, "providers"))).path;
|
|
22
|
-
|
|
23
|
-
const exclude = ["util", "test", "vitepress", "vite", "shadcn", "internal"];
|
|
24
|
-
|
|
25
|
-
// Get all folders in the alchemy/src directory
|
|
26
|
-
let providers = (
|
|
27
|
-
await fs.readdir(path.resolve("alchemy", "src"), {
|
|
28
|
-
withFileTypes: true,
|
|
29
|
-
})
|
|
30
|
-
)
|
|
31
|
-
.filter((dirent) => dirent.isDirectory() && !exclude.includes(dirent.name))
|
|
32
|
-
.map((dirent) => path.join(dirent.parentPath, dirent.name));
|
|
33
|
-
|
|
34
|
-
// For each provider, list all files
|
|
35
|
-
if (isDocsEnabled === false) {
|
|
36
|
-
return;
|
|
37
|
-
} else if (typeof isDocsEnabled === "number") {
|
|
38
|
-
providers = providers.slice(0, isDocsEnabled);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const providerDocs = await Promise.all(
|
|
42
|
-
providers.map(async (provider) => {
|
|
43
|
-
const providerName = path.basename(provider);
|
|
44
|
-
const files = (
|
|
45
|
-
await fs.readdir(path.resolve(provider), {
|
|
46
|
-
withFileTypes: true,
|
|
47
|
-
})
|
|
48
|
-
)
|
|
49
|
-
.filter((dirent) => dirent.isFile())
|
|
50
|
-
.map((dirent) =>
|
|
51
|
-
path.relative(process.cwd(), path.resolve(provider, dirent.name)),
|
|
52
|
-
)
|
|
53
|
-
.filter((file) => file.endsWith(".ts") && !file.endsWith("index.ts"));
|
|
54
|
-
|
|
55
|
-
const {
|
|
56
|
-
object: { groups },
|
|
57
|
-
} = await Data(`docs/${providerName}`, {
|
|
58
|
-
schema: type({
|
|
59
|
-
groups: type({
|
|
60
|
-
title: type("string").describe(
|
|
61
|
-
"The title of the group, should be the Resource Name exactly without spaces, e.g. Bucket or Static Site.",
|
|
62
|
-
),
|
|
63
|
-
filename: type("string").describe(
|
|
64
|
-
"The filename of the Resource's Document, e.g. bucket.md or static-site.md",
|
|
65
|
-
),
|
|
66
|
-
category: type("'Resource'|'Client'|'Utility'|'Types'").describe(
|
|
67
|
-
"The classification of the Resource's Document, one of: Resource, Client, Utility, or Types.",
|
|
68
|
-
),
|
|
69
|
-
}).array(),
|
|
70
|
-
}),
|
|
71
|
-
system: await alchemy`
|
|
72
|
-
You are a technical writer tasked with identifying the distinct documents that need to be written for a document group (folder) in a documentation site.
|
|
73
|
-
You will be provided with a list of documents and instructions on how to classify them.
|
|
74
|
-
Each document has a title, file name, and category.
|
|
75
|
-
`,
|
|
76
|
-
prompt: await alchemy`
|
|
77
|
-
Identify and classify the documents that need to be written for the '${provider}' Service's Alchemy Resources.
|
|
78
|
-
For background knowledge on Alchemy, see ${alchemy.file("./README.md")}.
|
|
79
|
-
For background knowledge on the structure of an Alchemy Resource, see ${alchemy.file("./.cursorrules")}.
|
|
80
|
-
|
|
81
|
-
The ${provider} Service has the following resources:
|
|
82
|
-
${alchemy.files(files)}
|
|
83
|
-
|
|
84
|
-
A file is considered a "Resource" if it contains a const <ResourceName> = Resource(...) call or if it is a function that calls a Resource function, e.g. const TypeScriptFile = () => File(...).
|
|
85
|
-
A file is considered a "Client" if it exposes a wrapper around creating a SDK client or fetch.
|
|
86
|
-
A file is considered a "Utility" if it contains utility functions that are not resources or clients.
|
|
87
|
-
A file is considered a "Types" if it contains just type definitions and maybe helpers around working with those types.
|
|
88
|
-
|
|
89
|
-
The title should be simply the name of the resource, e.g. "Bucket" or "Function", except with spaces, e.g. "Static Site" instead of "StaticSite". Maintain all other casing.
|
|
90
|
-
`,
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
const providerDocsDir = (
|
|
94
|
-
await Folder(path.join(providersDir, providerName))
|
|
95
|
-
).path;
|
|
96
|
-
|
|
97
|
-
const documents = await Promise.all(
|
|
98
|
-
groups
|
|
99
|
-
.filter((g) => g.category === "Resource")
|
|
100
|
-
.map(async (g) =>
|
|
101
|
-
Document(`docs/${providerName}/${g.title}`, {
|
|
102
|
-
title: g.title,
|
|
103
|
-
path: path.join(
|
|
104
|
-
providerDocsDir,
|
|
105
|
-
`${g.filename.replace(".ts", "").replace(".md", "")}.md`,
|
|
106
|
-
),
|
|
107
|
-
prompt: await alchemy`
|
|
108
|
-
You are a technical writer writing API documentation for an Alchemy IaC Resource.
|
|
109
|
-
See ${alchemy.file("./README.md")} to understand the overview of Alchemy.
|
|
110
|
-
See ${alchemy.file("./.cursorrules")} to better understand the structure and convention of an Alchemy Resource.
|
|
111
|
-
|
|
112
|
-
Relevant files for the ${providerName} Service:
|
|
113
|
-
${alchemy.files(files)}
|
|
114
|
-
|
|
115
|
-
Write concise documentation for the "${g.title}" Resource.
|
|
116
|
-
|
|
117
|
-
> [!CAUTION]
|
|
118
|
-
> Avoid the temptation to over explain or over describe. Focus on concise, simple, high value snippets. One heading and 0-1 descriptions per snippet.
|
|
119
|
-
|
|
120
|
-
> [!TIP]
|
|
121
|
-
> Make sure the examples follow a natural progression from the minimal example to logical next steps of how the Resource might be used.
|
|
122
|
-
|
|
123
|
-
Each document must follow the following format:
|
|
124
|
-
|
|
125
|
-
# ${g.title}
|
|
126
|
-
|
|
127
|
-
(simple description with an external link to the provider's website)
|
|
128
|
-
e.g.
|
|
129
|
-
The Efs component lets you add [Amazon Elastic File System (EFS)](https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html) to your app.
|
|
130
|
-
|
|
131
|
-
# Minimal Example
|
|
132
|
-
|
|
133
|
-
\`\`\`ts
|
|
134
|
-
import { ${g.title.replaceAll(" ", "")} } from "alchemy/${providerName}";
|
|
135
|
-
|
|
136
|
-
(example)
|
|
137
|
-
\`\`\`
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
# Create the ${g.title}
|
|
141
|
-
|
|
142
|
-
\`\`\`ts
|
|
143
|
-
import { ${g.title.replaceAll(" ", "")} } from "alchemy/${providerName}";
|
|
144
|
-
|
|
145
|
-
(example)
|
|
146
|
-
\`\`\`
|
|
147
|
-
|
|
148
|
-
${
|
|
149
|
-
providerName === "cloudflare"
|
|
150
|
-
? await alchemy`# Bind to a Worker
|
|
151
|
-
(if it is a Cloudflare Resource)
|
|
152
|
-
|
|
153
|
-
\`\`\`ts
|
|
154
|
-
import { Worker, ${g.title.replaceAll(" ", "")} } from "alchemy/${providerName}";
|
|
155
|
-
|
|
156
|
-
const myResource = await ${g.title.replaceAll(" ", "")}("my-resource", {
|
|
157
|
-
// ...
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
await Worker("my-worker", {
|
|
161
|
-
name: "my-worker",
|
|
162
|
-
script: "console.log('Hello, world!')",
|
|
163
|
-
bindings: {
|
|
164
|
-
myResource,
|
|
165
|
-
},
|
|
166
|
-
});
|
|
167
|
-
\`\`\``
|
|
168
|
-
: ""
|
|
169
|
-
}
|
|
170
|
-
`,
|
|
171
|
-
}),
|
|
172
|
-
),
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
return {
|
|
176
|
-
dir: providerDocsDir,
|
|
177
|
-
provider: providerName,
|
|
178
|
-
documents,
|
|
179
|
-
} as const;
|
|
180
|
-
}),
|
|
181
|
-
);
|
|
182
|
-
|
|
183
|
-
await VitePressProject("docs", {
|
|
184
|
-
name: "alchemy-web",
|
|
185
|
-
title: "Alchemy",
|
|
186
|
-
description: "Alchemy is an TypeScript-native, embeddable IaC library",
|
|
187
|
-
overwrite: true,
|
|
188
|
-
delete: false,
|
|
189
|
-
tsconfig: {
|
|
190
|
-
extends: "../tsconfig.base.json",
|
|
191
|
-
references: ["../alchemy/tsconfig.json"],
|
|
192
|
-
},
|
|
193
|
-
devDependencies: {
|
|
194
|
-
alchemy: "workspace:*",
|
|
195
|
-
},
|
|
196
|
-
theme: {
|
|
197
|
-
light: "light-plus",
|
|
198
|
-
dark: "dark-plus",
|
|
199
|
-
},
|
|
200
|
-
home: {
|
|
201
|
-
layout: "home",
|
|
202
|
-
hero: {
|
|
203
|
-
name: "Alchemy",
|
|
204
|
-
text: "Materialize all the things! 🪄",
|
|
205
|
-
tagline: "TypeScript-native Infrastructure-as-Code (IaC)",
|
|
206
|
-
image: {
|
|
207
|
-
src: "./public/alchemist.png",
|
|
208
|
-
alt: "The Alchemist",
|
|
209
|
-
},
|
|
210
|
-
actions: [
|
|
211
|
-
{
|
|
212
|
-
text: "Get Started",
|
|
213
|
-
link: "/docs",
|
|
214
|
-
theme: "brand",
|
|
215
|
-
},
|
|
216
|
-
],
|
|
217
|
-
},
|
|
218
|
-
features: [
|
|
219
|
-
{
|
|
220
|
-
title: "JS-native",
|
|
221
|
-
details:
|
|
222
|
-
"No second language, toolchains, dependencies, processes, services, etc. to lug around.",
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
title: "Async",
|
|
226
|
-
details:
|
|
227
|
-
"Resources are just async functions - no complex abstraction to learn.",
|
|
228
|
-
},
|
|
229
|
-
{
|
|
230
|
-
title: "ESM",
|
|
231
|
-
details:
|
|
232
|
-
"Built exclusively on ESM, with a slight preference for modern JS runtimes like Bun.",
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
title: "Embeddable",
|
|
236
|
-
details:
|
|
237
|
-
"Runs in any JavaScript/TypeScript environment, including the browser!",
|
|
238
|
-
},
|
|
239
|
-
{
|
|
240
|
-
title: "Extensible",
|
|
241
|
-
details: "Implement your own resources with a simple function.",
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
title: "AI-first",
|
|
245
|
-
details:
|
|
246
|
-
"Create, copy, fork, and modify resources using LLMs to fit your needs.",
|
|
247
|
-
},
|
|
248
|
-
{
|
|
249
|
-
title: "No dependencies",
|
|
250
|
-
details: "The alchemy core package has 0 required dependencies.",
|
|
251
|
-
},
|
|
252
|
-
{
|
|
253
|
-
title: "No service",
|
|
254
|
-
details:
|
|
255
|
-
"State files are stored locally in your project for easy inspection and version control.",
|
|
256
|
-
},
|
|
257
|
-
{
|
|
258
|
-
title: "No strong opinions",
|
|
259
|
-
details:
|
|
260
|
-
"Structure your codebase however you want, store state anywhere - we don't care!",
|
|
261
|
-
},
|
|
262
|
-
],
|
|
263
|
-
},
|
|
264
|
-
themeConfig: {
|
|
265
|
-
sidebar: {
|
|
266
|
-
"/blog/": [{ text: "Blog", items: [{ text: "Blog", link: "/blog/" }] }],
|
|
267
|
-
"/docs/": [
|
|
268
|
-
{
|
|
269
|
-
text: "Getting Started",
|
|
270
|
-
items: [{ text: "Install", link: "/docs/getting-started/install" }],
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
text: "Guides",
|
|
274
|
-
items: [
|
|
275
|
-
{
|
|
276
|
-
text: "Custom Resource",
|
|
277
|
-
link: "/docs/guides/custom-resource",
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
text: "Automating with LLMs",
|
|
281
|
-
link: "/docs/guides/llms",
|
|
282
|
-
},
|
|
283
|
-
],
|
|
284
|
-
},
|
|
285
|
-
{
|
|
286
|
-
text: "Core",
|
|
287
|
-
collapsed: true,
|
|
288
|
-
items: [
|
|
289
|
-
{ text: "App", link: "/docs/core/app" },
|
|
290
|
-
{ text: "Resource", link: "/docs/core/resource" },
|
|
291
|
-
{ text: "Scope", link: "/docs/core/scope" },
|
|
292
|
-
{ text: "Phase", link: "/docs/core/phase" },
|
|
293
|
-
{ text: "Finalize", link: "/docs/core/finalize" },
|
|
294
|
-
{ text: "State", link: "/docs/core/state" },
|
|
295
|
-
{ text: "Secret", link: "/docs/core/secret" },
|
|
296
|
-
{ text: "Context", link: "/docs/core/context" },
|
|
297
|
-
],
|
|
298
|
-
},
|
|
299
|
-
{
|
|
300
|
-
text: "Providers",
|
|
301
|
-
items: providerDocs
|
|
302
|
-
.map((provider) => ({
|
|
303
|
-
text: provider.provider,
|
|
304
|
-
link: `/docs/providers/${provider.provider}`,
|
|
305
|
-
collapsed: true,
|
|
306
|
-
items: provider.documents.map((document) => ({
|
|
307
|
-
text: document.title,
|
|
308
|
-
link: `/docs/providers/${provider.provider}/${path.basename(document.path, ".md")}`,
|
|
309
|
-
})),
|
|
310
|
-
}))
|
|
311
|
-
.sort((a, b) => a.text.localeCompare(b.text)),
|
|
312
|
-
},
|
|
313
|
-
],
|
|
314
|
-
"/examples/": [
|
|
315
|
-
{
|
|
316
|
-
text: "Examples",
|
|
317
|
-
items: [{ text: "Foo", link: "/examples/foo" }],
|
|
318
|
-
},
|
|
319
|
-
],
|
|
320
|
-
"/": [
|
|
321
|
-
{
|
|
322
|
-
text: "Home",
|
|
323
|
-
items: [
|
|
324
|
-
{ text: "Markdown Examples", link: "/markdown-examples" },
|
|
325
|
-
{ text: "Runtime API Examples", link: "/api-examples" },
|
|
326
|
-
],
|
|
327
|
-
},
|
|
328
|
-
],
|
|
329
|
-
},
|
|
330
|
-
socialLinks: [
|
|
331
|
-
{
|
|
332
|
-
icon: "github",
|
|
333
|
-
link: "https://github.com/sam-goodwin/alchemy",
|
|
334
|
-
},
|
|
335
|
-
],
|
|
336
|
-
},
|
|
337
|
-
});
|
|
338
|
-
}
|
package/src/shadcn/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./component";
|
package/src/vite/index.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./vite";
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import yaml from "yaml";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Image that can be themed for light/dark mode
|
|
5
|
-
*/
|
|
6
|
-
export interface ThemeableImage {
|
|
7
|
-
/**
|
|
8
|
-
* Image source URL
|
|
9
|
-
*/
|
|
10
|
-
src?: string;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Image alt text
|
|
14
|
-
*/
|
|
15
|
-
alt?: string;
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Light theme image URL
|
|
19
|
-
*/
|
|
20
|
-
light?: string;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Dark theme image URL
|
|
24
|
-
*/
|
|
25
|
-
dark?: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Hero action button configuration
|
|
30
|
-
*/
|
|
31
|
-
export interface HeroAction {
|
|
32
|
-
/**
|
|
33
|
-
* Color theme of the button
|
|
34
|
-
* @default "brand"
|
|
35
|
-
*/
|
|
36
|
-
theme?: "brand" | "alt";
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Label of the button
|
|
40
|
-
*/
|
|
41
|
-
text: string;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Destination link of the button
|
|
45
|
-
*/
|
|
46
|
-
link: string;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Link target attribute
|
|
50
|
-
*/
|
|
51
|
-
target?: string;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Link rel attribute
|
|
55
|
-
*/
|
|
56
|
-
rel?: string;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Hero section configuration
|
|
61
|
-
*/
|
|
62
|
-
export interface Hero {
|
|
63
|
-
/**
|
|
64
|
-
* The string shown top of text. Comes with brand color
|
|
65
|
-
* and expected to be short, such as product name.
|
|
66
|
-
*/
|
|
67
|
-
name?: string;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* The main text for the hero section. This will be defined
|
|
71
|
-
* as h1 tag.
|
|
72
|
-
*/
|
|
73
|
-
text: string;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Tagline displayed below text
|
|
77
|
-
*/
|
|
78
|
-
tagline?: string;
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* The image displayed next to the text and tagline area
|
|
82
|
-
*/
|
|
83
|
-
image?: string | ThemeableImage;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Action buttons to display in home hero section
|
|
87
|
-
*/
|
|
88
|
-
actions?: HeroAction[];
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Feature item configuration
|
|
93
|
-
*/
|
|
94
|
-
export interface Feature {
|
|
95
|
-
/**
|
|
96
|
-
* Show icon on each feature box
|
|
97
|
-
*/
|
|
98
|
-
icon?: string | ThemeableImage;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Title of the feature
|
|
102
|
-
*/
|
|
103
|
-
title: string;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Details of the feature
|
|
107
|
-
*/
|
|
108
|
-
details: string;
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Link when clicked on feature component
|
|
112
|
-
*/
|
|
113
|
-
link?: string;
|
|
114
|
-
|
|
115
|
-
/**
|
|
116
|
-
* Link text to be shown inside feature component
|
|
117
|
-
*/
|
|
118
|
-
linkText?: string;
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Link rel attribute
|
|
122
|
-
*/
|
|
123
|
-
rel?: string;
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
* Link target attribute
|
|
127
|
-
*/
|
|
128
|
-
target?: string;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* VitePress home page configuration
|
|
133
|
-
*/
|
|
134
|
-
export interface HomePage {
|
|
135
|
-
/**
|
|
136
|
-
* Use home page layout
|
|
137
|
-
*/
|
|
138
|
-
layout: "home";
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Hero section configuration
|
|
142
|
-
*/
|
|
143
|
-
hero?: Hero;
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Features section configuration
|
|
147
|
-
*/
|
|
148
|
-
features?: Feature[];
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Whether to apply default markdown styles
|
|
152
|
-
* @default true
|
|
153
|
-
*/
|
|
154
|
-
markdownStyles?: boolean;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Parse YAML frontmatter to home page config
|
|
159
|
-
*/
|
|
160
|
-
export function parseHomePage(content: string): HomePage {
|
|
161
|
-
const match = content.match(/^---\n([\s\S]*?)\n---/);
|
|
162
|
-
if (!match) {
|
|
163
|
-
throw new Error("Invalid frontmatter format");
|
|
164
|
-
}
|
|
165
|
-
return yaml.parse(match[1]) as HomePage;
|
|
166
|
-
}
|
|
File without changes
|
|
File without changes
|