alchemy 0.2.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/lib/ai/astro-file.d.ts +137 -0
- package/lib/ai/astro-file.js +173 -0
- package/lib/ai/client.d.ts +2 -10
- package/lib/ai/client.js +8 -24
- package/lib/ai/css-file.d.ts +131 -0
- package/lib/ai/css-file.js +158 -0
- package/lib/ai/data.d.ts +45 -5
- package/lib/ai/data.js +45 -10
- package/lib/ai/document.d.ts +44 -20
- package/lib/ai/document.js +95 -28
- package/lib/ai/html-file.d.ts +128 -0
- package/lib/ai/html-file.js +155 -0
- package/lib/ai/index.d.ts +7 -0
- package/lib/ai/index.js +7 -0
- package/lib/ai/json-file.d.ts +160 -0
- package/lib/ai/json-file.js +208 -0
- package/lib/ai/typescript-file.d.ts +140 -0
- package/lib/ai/typescript-file.js +176 -0
- package/lib/ai/vue-file.d.ts +126 -0
- package/lib/ai/vue-file.js +153 -0
- package/lib/ai/yaml-file.d.ts +169 -0
- package/lib/ai/yaml-file.js +236 -0
- package/lib/cloudflare/dns.d.ts +88 -0
- package/lib/cloudflare/dns.js +192 -0
- 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/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/file-system-state-store.d.ts +17 -0
- package/lib/fs/file-system-state-store.js +87 -0
- package/lib/fs/folder.d.ts +10 -0
- package/lib/fs/folder.js +2 -2
- package/lib/fs/index.d.ts +4 -4
- package/lib/fs/index.js +4 -4
- package/lib/fs/{json-file.d.ts → static-json-file.d.ts} +2 -2
- package/lib/fs/static-json-file.js +14 -0
- package/lib/fs/{text-file.d.ts → static-text-file.d.ts} +2 -2
- package/lib/fs/{text-file.js → static-text-file.js} +1 -1
- package/lib/fs/{typescript-file.d.ts → static-typescript-file.d.ts} +2 -2
- package/lib/fs/{typescript-file.js → static-typescript-file.js} +1 -1
- package/lib/fs/{yaml-file.d.ts → static-yaml-file.d.ts} +2 -2
- package/lib/fs/{yaml-file.js → static-yaml-file.js} +1 -1
- package/lib/internal/getting-started.d.ts +10 -0
- package/lib/internal/getting-started.js +94 -0
- package/lib/internal/project.d.ts +13 -0
- package/lib/internal/project.js +101 -0
- package/lib/internal/providers.d.ts +23 -0
- package/lib/internal/providers.js +148 -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/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 +244 -0
- package/lib/web/vitepress/home-page.js +134 -0
- package/lib/{vitepress → web/vitepress}/index.d.ts +1 -0
- package/lib/{vitepress → web/vitepress}/index.js +1 -0
- package/lib/{vitepress → web/vitepress}/vitepress.d.ts +10 -8
- package/lib/{vitepress → web/vitepress}/vitepress.js +11 -12
- package/package.json +6 -2
- package/src/ai/astro-file.ts +288 -0
- package/src/ai/client.ts +8 -28
- package/src/ai/css-file.ts +266 -0
- package/src/ai/data.ts +53 -16
- package/src/ai/document.ts +130 -33
- package/src/ai/html-file.ts +263 -0
- package/src/ai/index.ts +7 -0
- package/src/ai/json-file.ts +349 -0
- package/src/ai/typescript-file.ts +293 -0
- package/src/ai/vue-file.ts +261 -0
- package/src/ai/yaml-file.ts +368 -0
- package/src/apply.ts +0 -1
- package/src/cloudflare/dns.ts +344 -0
- 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/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/file-system-state-store.ts +109 -0
- package/src/fs/folder.ts +14 -2
- package/src/fs/index.ts +4 -4
- package/src/fs/{json-file.ts → static-json-file.ts} +13 -3
- package/src/fs/{text-file.ts → static-text-file.ts} +5 -2
- package/src/fs/{typescript-file.ts → static-typescript-file.ts} +3 -3
- package/src/fs/{yaml-file.ts → static-yaml-file.ts} +5 -2
- package/src/internal/getting-started.ts +107 -0
- package/src/internal/project.ts +119 -0
- package/src/internal/providers.ts +209 -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/custom-theme.ts +514 -0
- package/src/{vitepress → web/vitepress}/dependencies.ts +2 -2
- package/src/web/vitepress/home-page.ts +363 -0
- package/src/{vitepress → web/vitepress}/index.ts +1 -0
- package/src/{vitepress → web/vitepress}/vitepress.ts +34 -27
- 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/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/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,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DNS record types supported across different providers
|
|
3
|
+
*/
|
|
4
|
+
export type DnsRecordType =
|
|
5
|
+
| "A"
|
|
6
|
+
| "AAAA"
|
|
7
|
+
| "MX"
|
|
8
|
+
| "TXT"
|
|
9
|
+
| "NS"
|
|
10
|
+
| "CNAME"
|
|
11
|
+
| "SOA"
|
|
12
|
+
| "SRV"
|
|
13
|
+
| "PTR";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Default DNS record types to fetch
|
|
17
|
+
*/
|
|
18
|
+
export const DEFAULT_RECORD_TYPES: readonly DnsRecordType[] = [
|
|
19
|
+
"A",
|
|
20
|
+
"AAAA",
|
|
21
|
+
"MX",
|
|
22
|
+
"TXT",
|
|
23
|
+
"NS",
|
|
24
|
+
"CNAME",
|
|
25
|
+
"SOA",
|
|
26
|
+
"SRV",
|
|
27
|
+
] as const;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Base DNS record interface with common properties
|
|
31
|
+
*/
|
|
32
|
+
export interface DnsRecordBase {
|
|
33
|
+
/**
|
|
34
|
+
* DNS record name (e.g., "example.com", "subdomain.example.com")
|
|
35
|
+
*/
|
|
36
|
+
name: string;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Record type (A, AAAA, CNAME, etc.)
|
|
40
|
+
*/
|
|
41
|
+
type: DnsRecordType;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* DNS record response structure from DNS-over-HTTPS APIs
|
|
46
|
+
*/
|
|
47
|
+
export interface DohDnsRecord extends DnsRecordBase {
|
|
48
|
+
/**
|
|
49
|
+
* Time To Live in seconds
|
|
50
|
+
*/
|
|
51
|
+
TTL: number;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Record data/content (varies by record type)
|
|
55
|
+
*/
|
|
56
|
+
data: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Comprehensive DNS record structure for creating/managing records
|
|
61
|
+
*/
|
|
62
|
+
export interface DnsRecord extends DnsRecordBase {
|
|
63
|
+
/**
|
|
64
|
+
* DNS record content (e.g., IP address, hostname)
|
|
65
|
+
*/
|
|
66
|
+
content: string;
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Time To Live (TTL) in seconds
|
|
70
|
+
* Setting to 1 means 'automatic'
|
|
71
|
+
* Value must be between 60 and 86400, with minimum reduced to 30 for Enterprise zones
|
|
72
|
+
* @default 1
|
|
73
|
+
*/
|
|
74
|
+
ttl?: number;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Whether the record is receiving proxied traffic through Cloudflare
|
|
78
|
+
* @default false
|
|
79
|
+
*/
|
|
80
|
+
proxied?: boolean;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Comments or notes about the record
|
|
84
|
+
*/
|
|
85
|
+
comment?: string;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Record tags
|
|
89
|
+
*/
|
|
90
|
+
tags?: string[];
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Priority value for MX/SRV records
|
|
94
|
+
*/
|
|
95
|
+
priority?: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* DNS record with provider-specific ID and metadata
|
|
100
|
+
*/
|
|
101
|
+
export interface DnsRecordWithMetadata extends DnsRecord {
|
|
102
|
+
/**
|
|
103
|
+
* Record ID
|
|
104
|
+
*/
|
|
105
|
+
id: string;
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Zone or domain ID the record belongs to
|
|
109
|
+
*/
|
|
110
|
+
zoneId: string;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Time at which the record was created
|
|
114
|
+
*/
|
|
115
|
+
createdAt: number;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Time at which the record was last modified
|
|
119
|
+
*/
|
|
120
|
+
modifiedAt?: number;
|
|
121
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import type { Scope } from "../scope";
|
|
4
|
+
import type { State, StateStore } from "../state";
|
|
5
|
+
import { ignore } from "../util/ignore";
|
|
6
|
+
import { deserialize, serialize } from "../util/serde";
|
|
7
|
+
|
|
8
|
+
const stateRootDir = path.join(process.cwd(), ".alchemy");
|
|
9
|
+
|
|
10
|
+
export class FileSystemStateStore implements StateStore {
|
|
11
|
+
public readonly dir: string;
|
|
12
|
+
constructor(public readonly scope: Scope) {
|
|
13
|
+
this.dir = path.join(stateRootDir, ...scope.chain);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async init(): Promise<void> {
|
|
17
|
+
await fs.mkdir(stateRootDir, { recursive: true });
|
|
18
|
+
await fs.mkdir(this.dir, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async deinit(): Promise<void> {
|
|
22
|
+
await ignore("ENOENT", () => fs.rmdir(this.dir));
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async count(): Promise<number> {
|
|
26
|
+
return Object.keys(await this.list()).length;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async list(): Promise<string[]> {
|
|
30
|
+
try {
|
|
31
|
+
const files = await fs.readdir(this.dir, {
|
|
32
|
+
withFileTypes: true,
|
|
33
|
+
});
|
|
34
|
+
return files
|
|
35
|
+
.filter((dirent) => dirent.isFile() && dirent.name.endsWith(".json"))
|
|
36
|
+
.map((dirent) => dirent.name.replace(/\.json$/, ""))
|
|
37
|
+
.map((key) => key.replaceAll(":", "/"));
|
|
38
|
+
} catch (error: any) {
|
|
39
|
+
if (error.code === "ENOENT") {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async get(key: string): Promise<State | undefined> {
|
|
47
|
+
try {
|
|
48
|
+
const content = await fs.readFile(await this.getPath(key), "utf8");
|
|
49
|
+
const state = (await deserialize(
|
|
50
|
+
this.scope,
|
|
51
|
+
JSON.parse(content),
|
|
52
|
+
)) as State;
|
|
53
|
+
if (state.output === undefined) {
|
|
54
|
+
state.output = {} as any;
|
|
55
|
+
}
|
|
56
|
+
state.output.Scope = this.scope;
|
|
57
|
+
return state;
|
|
58
|
+
} catch (error: any) {
|
|
59
|
+
if (error.code === "ENOENT") {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async set(key: string, value: State): Promise<void> {
|
|
67
|
+
return fs.writeFile(
|
|
68
|
+
await this.getPath(key),
|
|
69
|
+
JSON.stringify(await serialize(this.scope, value), null, 2),
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
async delete(key: string): Promise<void> {
|
|
74
|
+
return fs.unlink(await this.getPath(key));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async all(): Promise<Record<string, State>> {
|
|
78
|
+
return this.getBatch(await this.list());
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async getBatch(ids: string[]): Promise<Record<string, State>> {
|
|
82
|
+
return Object.fromEntries(
|
|
83
|
+
(
|
|
84
|
+
await Promise.all(
|
|
85
|
+
Array.from(ids).flatMap(async (id) => {
|
|
86
|
+
const s = await this.get(id);
|
|
87
|
+
if (s === undefined) {
|
|
88
|
+
return [] as const;
|
|
89
|
+
}
|
|
90
|
+
return [[id, s]] as const;
|
|
91
|
+
}),
|
|
92
|
+
)
|
|
93
|
+
).flat(),
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
private async getPath(key: string): Promise<string> {
|
|
98
|
+
if (key.includes(":")) {
|
|
99
|
+
throw new Error(`ID cannot include colons: ${key}`);
|
|
100
|
+
}
|
|
101
|
+
if (key.includes("/")) {
|
|
102
|
+
key = key.replaceAll("/", ":");
|
|
103
|
+
}
|
|
104
|
+
const file = path.join(this.dir, `${key}.json`);
|
|
105
|
+
const dir = path.dirname(file);
|
|
106
|
+
await fs.mkdir(dir, { recursive: true });
|
|
107
|
+
return file;
|
|
108
|
+
}
|
|
109
|
+
}
|
package/src/fs/folder.ts
CHANGED
|
@@ -13,6 +13,18 @@ export interface FolderProps {
|
|
|
13
13
|
* @default true
|
|
14
14
|
*/
|
|
15
15
|
delete?: boolean;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Whether to clean the folder during the deletion phase (even if it contains existing files)
|
|
19
|
+
* @default false
|
|
20
|
+
*/
|
|
21
|
+
clean?: boolean;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Whether to create the folder recursively
|
|
25
|
+
* @default true
|
|
26
|
+
*/
|
|
27
|
+
recursive?: boolean;
|
|
16
28
|
}
|
|
17
29
|
|
|
18
30
|
/**
|
|
@@ -56,13 +68,13 @@ export const Folder = Resource(
|
|
|
56
68
|
if (props?.delete !== false) {
|
|
57
69
|
// we just do a best effort attempt
|
|
58
70
|
await ignore(["ENOENT", "ENOTEMPTY"], async () =>
|
|
59
|
-
fs.promises.rmdir(dirPath),
|
|
71
|
+
fs.promises.rmdir(dirPath, { recursive: props?.clean ?? false }),
|
|
60
72
|
);
|
|
61
73
|
}
|
|
62
74
|
return this.destroy();
|
|
63
75
|
} else {
|
|
64
76
|
await ignore("EEXIST", async () =>
|
|
65
|
-
fs.promises.mkdir(dirPath, { recursive: true }),
|
|
77
|
+
fs.promises.mkdir(dirPath, { recursive: props?.recursive ?? true }),
|
|
66
78
|
);
|
|
67
79
|
}
|
|
68
80
|
return this({
|
package/src/fs/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ export * from "./file";
|
|
|
2
2
|
export * from "./file-collection";
|
|
3
3
|
export * from "./file-ref";
|
|
4
4
|
export * from "./folder";
|
|
5
|
-
export * from "./json-file";
|
|
6
|
-
export * from "./text-file";
|
|
7
|
-
export * from "./typescript-file";
|
|
8
|
-
export * from "./yaml-file";
|
|
5
|
+
export * from "./static-json-file";
|
|
6
|
+
export * from "./static-text-file";
|
|
7
|
+
export * from "./static-typescript-file";
|
|
8
|
+
export * from "./static-yaml-file";
|
|
@@ -13,11 +13,21 @@ import { File } from "./file";
|
|
|
13
13
|
* features: ["auth", "logging"]
|
|
14
14
|
* });
|
|
15
15
|
*/
|
|
16
|
-
export type
|
|
16
|
+
export type StaticJsonFile = File;
|
|
17
17
|
|
|
18
|
-
export function
|
|
18
|
+
export async function StaticJsonFile(
|
|
19
|
+
id: string,
|
|
20
|
+
content: any,
|
|
21
|
+
): Promise<StaticJsonFile> {
|
|
22
|
+
const prettier = await import("prettier");
|
|
19
23
|
return File(id, {
|
|
20
24
|
path: id,
|
|
21
|
-
content: JSON.stringify(content,
|
|
25
|
+
content: await prettier.format(JSON.stringify(content), {
|
|
26
|
+
parser: "json",
|
|
27
|
+
editor: {
|
|
28
|
+
tabWidth: 2,
|
|
29
|
+
indentWidth: 2,
|
|
30
|
+
},
|
|
31
|
+
}),
|
|
22
32
|
});
|
|
23
33
|
}
|
|
@@ -9,9 +9,12 @@ import { File } from "./file";
|
|
|
9
9
|
* "# Project Name\n\nProject description goes here."
|
|
10
10
|
* );
|
|
11
11
|
*/
|
|
12
|
-
export type
|
|
12
|
+
export type StaticTextFile = File;
|
|
13
13
|
|
|
14
|
-
export function
|
|
14
|
+
export function StaticTextFile(
|
|
15
|
+
id: string,
|
|
16
|
+
content: string,
|
|
17
|
+
): Promise<StaticTextFile> {
|
|
15
18
|
return File(id, {
|
|
16
19
|
path: id,
|
|
17
20
|
content,
|
|
@@ -16,12 +16,12 @@ import { File } from "./file";
|
|
|
16
16
|
* }
|
|
17
17
|
* `);
|
|
18
18
|
*/
|
|
19
|
-
export type
|
|
19
|
+
export type StaticTypeScriptFile = File;
|
|
20
20
|
|
|
21
|
-
export async function
|
|
21
|
+
export async function StaticTypeScriptFile(
|
|
22
22
|
id: string,
|
|
23
23
|
content: string,
|
|
24
|
-
): Promise<
|
|
24
|
+
): Promise<StaticTypeScriptFile> {
|
|
25
25
|
const prettier = await import("prettier");
|
|
26
26
|
return File(id, {
|
|
27
27
|
path: id,
|
|
@@ -15,9 +15,12 @@ import { File } from "./file";
|
|
|
15
15
|
* max: 10
|
|
16
16
|
* });
|
|
17
17
|
*/
|
|
18
|
-
export type
|
|
18
|
+
export type StaticYamlFile = File;
|
|
19
19
|
|
|
20
|
-
export async function
|
|
20
|
+
export async function StaticYamlFile(
|
|
21
|
+
id: string,
|
|
22
|
+
content: any,
|
|
23
|
+
): Promise<StaticYamlFile> {
|
|
21
24
|
const yaml = await import("yaml");
|
|
22
25
|
return File(id, {
|
|
23
26
|
path: id,
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import alchemy from "alchemy";
|
|
2
|
+
import { Document } from "alchemy/ai";
|
|
3
|
+
import type { Folder } from "alchemy/fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
|
|
6
|
+
export interface GettingStartedProps {
|
|
7
|
+
/**
|
|
8
|
+
* The output directory for the getting started document.
|
|
9
|
+
*/
|
|
10
|
+
outDir: string | Folder;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export type GettingStarted = Document;
|
|
14
|
+
|
|
15
|
+
export async function GettingStarted({
|
|
16
|
+
outDir,
|
|
17
|
+
}: GettingStartedProps): Promise<Document> {
|
|
18
|
+
outDir = typeof outDir === "string" ? outDir : outDir.path;
|
|
19
|
+
return Document(`docs/getting-started`, {
|
|
20
|
+
title: "Getting Started with Alchemy",
|
|
21
|
+
path: path.join(outDir, "index.md"),
|
|
22
|
+
prompt: await alchemy`
|
|
23
|
+
You are a technical writer creating a getting started guide for Alchemy, an infrastructure as code (IaC) framework.
|
|
24
|
+
See ${alchemy.file("../README.md")} to understand the overview of Alchemy.
|
|
25
|
+
See ${alchemy.file("../.cursorrules")} to better understand the structure and conventions of Alchemy.
|
|
26
|
+
|
|
27
|
+
See ${alchemy.file("../alchemy/test/cloudflare/worker.test.ts")} for an example of how testing works.
|
|
28
|
+
|
|
29
|
+
Write a comprehensive getting started guide for Alchemy that covers the following topics:
|
|
30
|
+
|
|
31
|
+
# Getting Started with Alchemy
|
|
32
|
+
|
|
33
|
+
(Brief introduction to Alchemy as an infrastructure as code framework)
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
\`\`\`bash
|
|
38
|
+
# Install Alchemy
|
|
39
|
+
bun add alchemy
|
|
40
|
+
\`\`\`
|
|
41
|
+
|
|
42
|
+
## Creating Your First Alchemy Project
|
|
43
|
+
|
|
44
|
+
(Step-by-step guide to creating a basic Alchemy project)
|
|
45
|
+
|
|
46
|
+
\`\`\`ts
|
|
47
|
+
// Example of a simple Alchemy project
|
|
48
|
+
import alchemy from "alchemy";
|
|
49
|
+
|
|
50
|
+
// Sample code here
|
|
51
|
+
\`\`\`
|
|
52
|
+
|
|
53
|
+
## Core Concepts
|
|
54
|
+
|
|
55
|
+
### Resources
|
|
56
|
+
|
|
57
|
+
(Explanation of Alchemy resources and how they work)
|
|
58
|
+
|
|
59
|
+
\`\`\`ts
|
|
60
|
+
// Example of creating a resource
|
|
61
|
+
\`\`\`
|
|
62
|
+
|
|
63
|
+
### Context
|
|
64
|
+
|
|
65
|
+
(Explanation of Alchemy context and lifecycle management)
|
|
66
|
+
|
|
67
|
+
\`\`\`ts
|
|
68
|
+
// Example of working with context
|
|
69
|
+
\`\`\`
|
|
70
|
+
|
|
71
|
+
## Working with Secrets
|
|
72
|
+
|
|
73
|
+
(How to handle secrets in Alchemy)
|
|
74
|
+
|
|
75
|
+
\`\`\`ts
|
|
76
|
+
// Example of using alchemy.secret()
|
|
77
|
+
const apiKey = alchemy.secret("API_KEY");
|
|
78
|
+
\`\`\`
|
|
79
|
+
|
|
80
|
+
## Testing
|
|
81
|
+
|
|
82
|
+
(How to test Alchemy resources)
|
|
83
|
+
|
|
84
|
+
\`\`\`ts
|
|
85
|
+
// Example of testing Alchemy resources
|
|
86
|
+
\`\`\`
|
|
87
|
+
|
|
88
|
+
## Deployment
|
|
89
|
+
|
|
90
|
+
(How to deploy resources with Alchemy)
|
|
91
|
+
|
|
92
|
+
\`\`\`ts
|
|
93
|
+
// Example of deployment
|
|
94
|
+
\`\`\`
|
|
95
|
+
|
|
96
|
+
## Next Steps
|
|
97
|
+
|
|
98
|
+
(Where to go next to learn more about Alchemy)
|
|
99
|
+
|
|
100
|
+
> [!CAUTION]
|
|
101
|
+
> Avoid the temptation to over explain or over describe. Focus on concise, simple, high value snippets.
|
|
102
|
+
|
|
103
|
+
> [!TIP]
|
|
104
|
+
> Make sure the examples follow a natural progression from minimal examples to more complex use cases.
|
|
105
|
+
`,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { VitePressProject } from "../web/vitepress";
|
|
3
|
+
import type { AlchemyProviderDocs } from "./providers";
|
|
4
|
+
|
|
5
|
+
export interface AlchemyProjectProps {
|
|
6
|
+
hero: {
|
|
7
|
+
text: string;
|
|
8
|
+
tagline: string;
|
|
9
|
+
};
|
|
10
|
+
docs: {
|
|
11
|
+
providers?: AlchemyProviderDocs;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type AlchemyProject = VitePressProject;
|
|
16
|
+
|
|
17
|
+
export function AlchemyProject({
|
|
18
|
+
hero,
|
|
19
|
+
docs,
|
|
20
|
+
}: AlchemyProjectProps): Promise<AlchemyProject> {
|
|
21
|
+
return VitePressProject("project", {
|
|
22
|
+
name: "alchemy-web",
|
|
23
|
+
title: "Alchemy",
|
|
24
|
+
dir: process.cwd(),
|
|
25
|
+
description: "Alchemy is an TypeScript-native, embeddable IaC library",
|
|
26
|
+
overwrite: true,
|
|
27
|
+
delete: false,
|
|
28
|
+
scripts: {
|
|
29
|
+
deploy: "bun --env-file ../.env alchemy.run.ts",
|
|
30
|
+
},
|
|
31
|
+
tsconfig: {
|
|
32
|
+
extends: "../tsconfig.base.json",
|
|
33
|
+
references: ["../alchemy/tsconfig.json"],
|
|
34
|
+
},
|
|
35
|
+
devDependencies: {
|
|
36
|
+
alchemy: "workspace:*",
|
|
37
|
+
},
|
|
38
|
+
theme: {
|
|
39
|
+
light: "light-plus",
|
|
40
|
+
dark: "dark-plus",
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
themeConfig: {
|
|
44
|
+
sidebar: {
|
|
45
|
+
"/blog/": [{ text: "Blog", items: [{ text: "Blog", link: "/blog/" }] }],
|
|
46
|
+
"/docs/": [
|
|
47
|
+
{
|
|
48
|
+
text: "Getting Started",
|
|
49
|
+
items: [{ text: "Install", link: "/docs/getting-started/install" }],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
text: "Guides",
|
|
53
|
+
items: [
|
|
54
|
+
{
|
|
55
|
+
text: "Custom Resource",
|
|
56
|
+
link: "/docs/guides/custom-resource",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
text: "Automating with LLMs",
|
|
60
|
+
link: "/docs/guides/llms",
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
text: "Core",
|
|
66
|
+
collapsed: true,
|
|
67
|
+
items: [
|
|
68
|
+
{ text: "App", link: "/docs/core/app" },
|
|
69
|
+
{ text: "Resource", link: "/docs/core/resource" },
|
|
70
|
+
{ text: "Scope", link: "/docs/core/scope" },
|
|
71
|
+
{ text: "Phase", link: "/docs/core/phase" },
|
|
72
|
+
{ text: "Finalize", link: "/docs/core/finalize" },
|
|
73
|
+
{ text: "State", link: "/docs/core/state" },
|
|
74
|
+
{ text: "Secret", link: "/docs/core/secret" },
|
|
75
|
+
{ text: "Context", link: "/docs/core/context" },
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
text: "Providers",
|
|
80
|
+
items: (docs.providers ?? [])
|
|
81
|
+
.map((provider) => ({
|
|
82
|
+
text: provider.provider,
|
|
83
|
+
// link: `/docs/providers/${provider.provider}`,
|
|
84
|
+
collapsed: true,
|
|
85
|
+
items: provider.documents
|
|
86
|
+
.map((document) => ({
|
|
87
|
+
text: document.title,
|
|
88
|
+
link: `/docs/providers/${provider.provider}/${path.basename(document.path, ".md")}`,
|
|
89
|
+
}))
|
|
90
|
+
.sort((a, b) => a.text.localeCompare(b.text)),
|
|
91
|
+
}))
|
|
92
|
+
.sort((a, b) => a.text.localeCompare(b.text)),
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
"/examples/": [
|
|
96
|
+
{
|
|
97
|
+
text: "Examples",
|
|
98
|
+
items: [{ text: "Foo", link: "/examples/foo" }],
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
"/": [
|
|
102
|
+
{
|
|
103
|
+
text: "Home",
|
|
104
|
+
items: [
|
|
105
|
+
{ text: "Markdown Examples", link: "/markdown-examples" },
|
|
106
|
+
{ text: "Runtime API Examples", link: "/api-examples" },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
},
|
|
111
|
+
socialLinks: [
|
|
112
|
+
{
|
|
113
|
+
icon: "github",
|
|
114
|
+
link: "https://github.com/sam-goodwin/alchemy",
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
}
|