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,39 @@
|
|
|
1
|
+
import { File } from "./file";
|
|
2
|
+
|
|
3
|
+
export type StaticVueFile = File;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Creates a static Vue component file
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // Create a Vue component file with content
|
|
10
|
+
* const button = await StaticVueFile("Button.vue",
|
|
11
|
+
* `<template>
|
|
12
|
+
* <button class="btn">{{ text }}</button>
|
|
13
|
+
* </template>
|
|
14
|
+
*
|
|
15
|
+
* <script>
|
|
16
|
+
* export default {
|
|
17
|
+
* props: {
|
|
18
|
+
* text: String
|
|
19
|
+
* }
|
|
20
|
+
* }
|
|
21
|
+
* </script>
|
|
22
|
+
*
|
|
23
|
+
* <style>
|
|
24
|
+
* .btn {
|
|
25
|
+
* padding: 0.5rem 1rem;
|
|
26
|
+
* }
|
|
27
|
+
* </style>`
|
|
28
|
+
* );
|
|
29
|
+
*/
|
|
30
|
+
export function StaticVueFile(
|
|
31
|
+
id: string,
|
|
32
|
+
...args: [content: string] | [path: string, content: string]
|
|
33
|
+
): Promise<StaticVueFile> {
|
|
34
|
+
const [path, content] = args.length === 1 ? [id, args[0]] : args;
|
|
35
|
+
return File(id, {
|
|
36
|
+
path,
|
|
37
|
+
content,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
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 StaticYamlFile("config.yaml", {
|
|
8
|
+
* server: {
|
|
9
|
+
* host: "localhost",
|
|
10
|
+
* port: 3000
|
|
11
|
+
* },
|
|
12
|
+
* database: {
|
|
13
|
+
* url: "postgresql://localhost:5432/db",
|
|
14
|
+
* pool: {
|
|
15
|
+
* min: 1,
|
|
16
|
+
* max: 10
|
|
17
|
+
* }
|
|
18
|
+
* }
|
|
19
|
+
* });
|
|
20
|
+
*/
|
|
21
|
+
export type StaticYamlFile = File;
|
|
22
|
+
|
|
23
|
+
export async function StaticYamlFile(
|
|
24
|
+
id: string,
|
|
25
|
+
...args: [content: any] | [path: string, content: any]
|
|
26
|
+
): Promise<StaticYamlFile> {
|
|
27
|
+
const [path, content] = args.length === 1 ? [id, args[0]] : args;
|
|
28
|
+
const yaml = await import("yaml");
|
|
29
|
+
return File(id, {
|
|
30
|
+
path,
|
|
31
|
+
content: yaml.stringify(content),
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { Document } from "../ai";
|
|
2
|
+
import type { ModelConfig } from "../ai/client";
|
|
3
|
+
import { alchemy } from "../alchemy";
|
|
4
|
+
import type { Folder } from "../fs";
|
|
5
|
+
|
|
6
|
+
export interface GettingStartedProps {
|
|
7
|
+
/**
|
|
8
|
+
* The output directory for the getting started document.
|
|
9
|
+
*/
|
|
10
|
+
path: string | Folder;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The prompt to use for generating the getting started guide.
|
|
14
|
+
* This should include specific details about the product or framework.
|
|
15
|
+
*/
|
|
16
|
+
prompt: string;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Optional model configuration for generating the getting started guide.
|
|
20
|
+
* Defaults to Claude 3.5 Sonnet.
|
|
21
|
+
*/
|
|
22
|
+
model?: ModelConfig;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type GettingStarted = Document;
|
|
26
|
+
|
|
27
|
+
export async function GettingStarted({
|
|
28
|
+
path: outFile,
|
|
29
|
+
prompt,
|
|
30
|
+
model = {
|
|
31
|
+
id: "claude-3-5-sonnet-latest",
|
|
32
|
+
provider: "anthropic",
|
|
33
|
+
},
|
|
34
|
+
}: GettingStartedProps): Promise<Document> {
|
|
35
|
+
return Document(`docs/getting-started`, {
|
|
36
|
+
title: "Getting Started Guide",
|
|
37
|
+
path: typeof outFile === "string" ? outFile : outFile.path,
|
|
38
|
+
model,
|
|
39
|
+
prompt: await alchemy`
|
|
40
|
+
You are a technical writer creating a getting started guide.
|
|
41
|
+
|
|
42
|
+
${prompt}
|
|
43
|
+
|
|
44
|
+
If you need a template structure to follow, use this format:
|
|
45
|
+
|
|
46
|
+
# Getting Started with [Product/Framework Name]
|
|
47
|
+
|
|
48
|
+
(Brief introduction to the product/framework)
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
\`\`\`bash
|
|
53
|
+
# Installation command
|
|
54
|
+
\`\`\`
|
|
55
|
+
|
|
56
|
+
## Creating Your First Project
|
|
57
|
+
|
|
58
|
+
(Step-by-step guide to creating a basic project)
|
|
59
|
+
|
|
60
|
+
\`\`\`ts
|
|
61
|
+
// Example of a simple project
|
|
62
|
+
\`\`\`
|
|
63
|
+
|
|
64
|
+
## Core Concepts
|
|
65
|
+
|
|
66
|
+
### [Concept 1]
|
|
67
|
+
|
|
68
|
+
(Explanation of the first core concept)
|
|
69
|
+
|
|
70
|
+
\`\`\`ts
|
|
71
|
+
// Example of using the concept
|
|
72
|
+
\`\`\`
|
|
73
|
+
|
|
74
|
+
### [Concept 2]
|
|
75
|
+
|
|
76
|
+
(Explanation of the second core concept)
|
|
77
|
+
|
|
78
|
+
\`\`\`ts
|
|
79
|
+
// Example of using the concept
|
|
80
|
+
\`\`\`
|
|
81
|
+
|
|
82
|
+
## Working with [Feature]
|
|
83
|
+
|
|
84
|
+
(How to use a specific feature)
|
|
85
|
+
|
|
86
|
+
\`\`\`ts
|
|
87
|
+
// Example of using the feature
|
|
88
|
+
\`\`\`
|
|
89
|
+
|
|
90
|
+
## Testing
|
|
91
|
+
|
|
92
|
+
(How to test your project)
|
|
93
|
+
|
|
94
|
+
\`\`\`ts
|
|
95
|
+
// Example of testing
|
|
96
|
+
\`\`\`
|
|
97
|
+
|
|
98
|
+
## Deployment
|
|
99
|
+
|
|
100
|
+
(How to deploy your project)
|
|
101
|
+
|
|
102
|
+
\`\`\`ts
|
|
103
|
+
// Example of deployment
|
|
104
|
+
\`\`\`
|
|
105
|
+
|
|
106
|
+
## Next Steps
|
|
107
|
+
|
|
108
|
+
(Where to go next to learn more)
|
|
109
|
+
|
|
110
|
+
> [!TIP]
|
|
111
|
+
> Make sure the examples follow a natural progression from minimal examples to more complex use cases.
|
|
112
|
+
> Keep explanations concise and focused on high-value information.
|
|
113
|
+
`,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { type } from "arktype";
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { Data, Document } from "../ai";
|
|
5
|
+
import { alchemy } from "../alchemy";
|
|
6
|
+
import { Folder } from "../fs";
|
|
7
|
+
|
|
8
|
+
export interface DocsProps {
|
|
9
|
+
/**
|
|
10
|
+
* The output directory for the docs.
|
|
11
|
+
*/
|
|
12
|
+
outDir: string | Folder;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The source directory for the docs.
|
|
16
|
+
*/
|
|
17
|
+
srcDir: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Whether to filter the docs.
|
|
21
|
+
* If true, include all docs.
|
|
22
|
+
* If false, include none.
|
|
23
|
+
* If a number, include that many providers.
|
|
24
|
+
*
|
|
25
|
+
* @default true (all docs)
|
|
26
|
+
*/
|
|
27
|
+
filter?: boolean | number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type AlchemyProviderDocs = {
|
|
31
|
+
dir: string;
|
|
32
|
+
provider: string;
|
|
33
|
+
documents: Document[];
|
|
34
|
+
}[];
|
|
35
|
+
|
|
36
|
+
export async function AlchemyProviderDocs({
|
|
37
|
+
srcDir,
|
|
38
|
+
outDir,
|
|
39
|
+
filter,
|
|
40
|
+
}: DocsProps): Promise<AlchemyProviderDocs> {
|
|
41
|
+
outDir = typeof outDir === "string" ? outDir : outDir.path;
|
|
42
|
+
|
|
43
|
+
const exclude = [
|
|
44
|
+
"util",
|
|
45
|
+
"test",
|
|
46
|
+
"vitepress",
|
|
47
|
+
"vite",
|
|
48
|
+
"shadcn",
|
|
49
|
+
"internal",
|
|
50
|
+
"web",
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
// Get all folders in the alchemy/src directory
|
|
54
|
+
let providers = (
|
|
55
|
+
await fs.readdir(srcDir, {
|
|
56
|
+
withFileTypes: true,
|
|
57
|
+
})
|
|
58
|
+
)
|
|
59
|
+
.filter((dirent) => dirent.isDirectory() && !exclude.includes(dirent.name))
|
|
60
|
+
.map((dirent) => path.join(dirent.parentPath, dirent.name));
|
|
61
|
+
|
|
62
|
+
// For each provider, list all files
|
|
63
|
+
if (filter === false) {
|
|
64
|
+
return [];
|
|
65
|
+
} else if (typeof filter === "number") {
|
|
66
|
+
providers = providers.slice(0, filter);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return await Promise.all(
|
|
70
|
+
providers.map(async (provider) => {
|
|
71
|
+
const providerName = path.basename(provider);
|
|
72
|
+
const files = (
|
|
73
|
+
await fs.readdir(path.resolve(provider), {
|
|
74
|
+
withFileTypes: true,
|
|
75
|
+
})
|
|
76
|
+
)
|
|
77
|
+
.filter((dirent) => dirent.isFile())
|
|
78
|
+
.map((dirent) =>
|
|
79
|
+
path.relative(process.cwd(), path.resolve(provider, dirent.name))
|
|
80
|
+
)
|
|
81
|
+
.filter((file) => file.endsWith(".ts") && !file.endsWith("index.ts"));
|
|
82
|
+
|
|
83
|
+
const {
|
|
84
|
+
object: { groups },
|
|
85
|
+
} = await Data(`docs/${providerName}`, {
|
|
86
|
+
model: {
|
|
87
|
+
id: "o3-mini",
|
|
88
|
+
provider: "openai",
|
|
89
|
+
options: {
|
|
90
|
+
reasoningEffort: "high",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
temperature: 0.1,
|
|
94
|
+
schema: type({
|
|
95
|
+
groups: type({
|
|
96
|
+
title: type("string").describe(
|
|
97
|
+
"The title of the group, should be the Resource Name exactly as it's defined in code (const ResourceName translates to 'Resource Name') without spaces, e.g. Bucket or Static Site."
|
|
98
|
+
),
|
|
99
|
+
filename: type("string").describe(
|
|
100
|
+
"The filename of the Resource's Document, e.g. bucket.md or static-site.md"
|
|
101
|
+
),
|
|
102
|
+
category: type("'Resource'|'Client'|'Utility'|'Types'").describe(
|
|
103
|
+
"The classification of the Resource's Document, one of: Resource, Client, Utility, or Types."
|
|
104
|
+
),
|
|
105
|
+
}).array(),
|
|
106
|
+
}),
|
|
107
|
+
system: await alchemy`
|
|
108
|
+
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.
|
|
109
|
+
You will be provided with a list of documents and instructions on how to classify them.
|
|
110
|
+
Each document has a title, file name, and category.
|
|
111
|
+
`,
|
|
112
|
+
prompt: await alchemy`
|
|
113
|
+
Identify and classify the documents that need to be written for the '${provider}' Service's Alchemy Resources.
|
|
114
|
+
For background knowledge on Alchemy, see ${alchemy.file("./README.md")}.
|
|
115
|
+
For background knowledge on the structure of an Alchemy Resource, see ${alchemy.file("./.cursorrules")}.
|
|
116
|
+
|
|
117
|
+
The ${provider} Service has the following resources:
|
|
118
|
+
${alchemy.files(files)}
|
|
119
|
+
|
|
120
|
+
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(...).
|
|
121
|
+
A file is considered a "Client" if it exposes a wrapper around creating a SDK client or fetch.
|
|
122
|
+
A file is considered a "Utility" if it contains utility functions that are not resources or clients.
|
|
123
|
+
A file is considered a "Types" if it contains just type definitions and maybe helpers around working with those types.
|
|
124
|
+
|
|
125
|
+
The title should be simply the name of the resource's const in code (with spaces added in between each word), e.g. "Bucket" or "Function", except with spaces, e.g. "Static Site" for "const StaticSite". Maintain all other casing.
|
|
126
|
+
|
|
127
|
+
// "Resource Name"
|
|
128
|
+
const ResourceName = Resource(...)
|
|
129
|
+
`,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// console.log(groups);
|
|
133
|
+
|
|
134
|
+
const providerDocsDir = (await Folder(path.join(outDir, providerName)))
|
|
135
|
+
.path;
|
|
136
|
+
|
|
137
|
+
const documents = await Promise.allSettled(
|
|
138
|
+
groups
|
|
139
|
+
.filter((g) => g.category === "Resource")
|
|
140
|
+
.map(async (g) =>
|
|
141
|
+
Document(`docs/${providerName}/${g.title}`, {
|
|
142
|
+
title: g.title,
|
|
143
|
+
path: path.join(
|
|
144
|
+
providerDocsDir,
|
|
145
|
+
`${g.filename.replace(".ts", "").replace(".md", "")}.md`
|
|
146
|
+
),
|
|
147
|
+
model: {
|
|
148
|
+
id: "claude-3-5-sonnet-latest",
|
|
149
|
+
provider: "anthropic",
|
|
150
|
+
// options: {
|
|
151
|
+
// reasoningEffort: "high",
|
|
152
|
+
// },
|
|
153
|
+
},
|
|
154
|
+
prompt: await alchemy`
|
|
155
|
+
You are a technical writer writing API documentation for an Alchemy IaC Resource.
|
|
156
|
+
See ${alchemy.file("./README.md")} to understand the overview of Alchemy.
|
|
157
|
+
See ${alchemy.file("./.cursorrules")} to better understand the structure and convention of an Alchemy Resource.
|
|
158
|
+
|
|
159
|
+
Relevant files for the ${providerName} Service:
|
|
160
|
+
${alchemy.files(files)}
|
|
161
|
+
|
|
162
|
+
Write concise documentation for the "${g.title}" Resource.
|
|
163
|
+
|
|
164
|
+
> [!CAUTION]
|
|
165
|
+
> Avoid the temptation to over explain or over describe. Focus on concise, simple, high value snippets. One heading and 0-1 descriptions per snippet.
|
|
166
|
+
|
|
167
|
+
> [!TIP]
|
|
168
|
+
> Make sure the examples follow a natural progression from the minimal example to logical next steps of how the Resource might be used.
|
|
169
|
+
|
|
170
|
+
Each document must follow the following format:
|
|
171
|
+
|
|
172
|
+
# ${g.title}
|
|
173
|
+
|
|
174
|
+
(simple description with an external link to the provider's website)
|
|
175
|
+
e.g.
|
|
176
|
+
The Efs component lets you add [Amazon Elastic File System (EFS)](https://docs.aws.amazon.com/efs/latest/ug/whatisefs.html) to your app.
|
|
177
|
+
|
|
178
|
+
# Minimal Example
|
|
179
|
+
|
|
180
|
+
(brief 1-2 sentences of what it does)
|
|
181
|
+
|
|
182
|
+
\`\`\`ts
|
|
183
|
+
import { ${g.title.replaceAll(" ", "")} } from "alchemy/${providerName}";
|
|
184
|
+
|
|
185
|
+
(example)
|
|
186
|
+
\`\`\`
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
# Create the ${g.title}
|
|
190
|
+
|
|
191
|
+
\`\`\`ts
|
|
192
|
+
import { ${g.title.replaceAll(" ", "")} } from "alchemy/${providerName}";
|
|
193
|
+
|
|
194
|
+
(example)
|
|
195
|
+
\`\`\`
|
|
196
|
+
|
|
197
|
+
${
|
|
198
|
+
providerName === "cloudflare"
|
|
199
|
+
? await alchemy`# Bind to a Worker
|
|
200
|
+
(if it is a Cloudflare Resource)
|
|
201
|
+
|
|
202
|
+
\`\`\`ts
|
|
203
|
+
import { Worker, ${g.title.replaceAll(" ", "")} } from "alchemy/${providerName}";
|
|
204
|
+
|
|
205
|
+
const myResource = await ${g.title.replaceAll(" ", "")}("my-resource", {
|
|
206
|
+
// ...
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
await Worker("my-worker", {
|
|
210
|
+
name: "my-worker",
|
|
211
|
+
script: "console.log('Hello, world!')",
|
|
212
|
+
bindings: {
|
|
213
|
+
myResource,
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
\`\`\``
|
|
217
|
+
: ""
|
|
218
|
+
}
|
|
219
|
+
`,
|
|
220
|
+
})
|
|
221
|
+
)
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
// Unwrap all documents, fail if any rejected
|
|
225
|
+
const results = await Promise.all(
|
|
226
|
+
documents.map((r) => {
|
|
227
|
+
if (r.status === "rejected") {
|
|
228
|
+
throw r.reason;
|
|
229
|
+
}
|
|
230
|
+
return r.value;
|
|
231
|
+
})
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
return {
|
|
235
|
+
dir: providerDocsDir,
|
|
236
|
+
provider: providerName,
|
|
237
|
+
documents: results,
|
|
238
|
+
} as const;
|
|
239
|
+
})
|
|
240
|
+
);
|
|
241
|
+
}
|