alchemy 0.2.4 → 0.2.5
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/lib/ai/{object.d.ts → data.d.ts} +3 -3
- package/lib/ai/{object.js → data.js} +1 -1
- package/lib/ai/document.d.ts +4 -0
- package/lib/ai/index.d.ts +2 -1
- package/lib/ai/index.js +2 -1
- package/lib/internal/docs.js +174 -211
- package/package.json +1 -1
- package/src/ai/{object.ts → data.ts} +5 -5
- package/src/ai/document.ts +5 -0
- package/src/ai/index.ts +2 -1
- package/src/internal/docs.ts +163 -194
|
@@ -6,7 +6,7 @@ import { type ModelConfig } from "./client";
|
|
|
6
6
|
/**
|
|
7
7
|
* Properties for creating or updating an AI Object
|
|
8
8
|
*/
|
|
9
|
-
export interface
|
|
9
|
+
export interface DataProps<T extends Type<any, any>> {
|
|
10
10
|
/**
|
|
11
11
|
* The ArkType schema to validate and structure the generated content
|
|
12
12
|
*/
|
|
@@ -45,7 +45,7 @@ export interface ObjectProps<T extends Type<any, any>> {
|
|
|
45
45
|
/**
|
|
46
46
|
* A resource that uses AI to generate structured content based on a schema
|
|
47
47
|
*/
|
|
48
|
-
export interface
|
|
48
|
+
export interface Data<T> extends Resource<"ai::Object"> {
|
|
49
49
|
type: JsonSchema;
|
|
50
50
|
/**
|
|
51
51
|
* The generated content, typed according to the provided schema
|
|
@@ -98,4 +98,4 @@ export interface Object<T> extends Resource<"ai::Object"> {
|
|
|
98
98
|
* system: "You are a technical documentation writer"
|
|
99
99
|
* });
|
|
100
100
|
*/
|
|
101
|
-
export declare const
|
|
101
|
+
export declare const Data: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | (<const T extends Type<any, any>>(this: Context<Data<any>>, id: string, props: DataProps<T>) => Promise<Data<type.infer<T>>>);
|
|
@@ -44,7 +44,7 @@ import { createClient, getModelId, getModelOptions, } from "./client";
|
|
|
44
44
|
* system: "You are a technical documentation writer"
|
|
45
45
|
* });
|
|
46
46
|
*/
|
|
47
|
-
export const
|
|
47
|
+
export const Data = Resource("ai::Object", async function (id, props) {
|
|
48
48
|
if (this.phase === "delete") {
|
|
49
49
|
return this.destroy();
|
|
50
50
|
}
|
package/lib/ai/document.d.ts
CHANGED
package/lib/ai/index.d.ts
CHANGED
package/lib/ai/index.js
CHANGED
package/lib/internal/docs.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type } from "arktype";
|
|
2
2
|
import fs from "fs/promises";
|
|
3
3
|
import path from "path";
|
|
4
|
+
import { Data } from "../ai/data";
|
|
4
5
|
import { Document } from "../ai/document";
|
|
5
|
-
import { Object } from "../ai/object";
|
|
6
6
|
import { alchemy } from "../alchemy";
|
|
7
7
|
import { Folder } from "../fs/folder";
|
|
8
8
|
import { VitePressProject } from "../vitepress/vitepress";
|
|
@@ -24,29 +24,28 @@ export async function AlchemyDocs({ docs: isDocsEnabled }) {
|
|
|
24
24
|
else if (typeof isDocsEnabled === "number") {
|
|
25
25
|
providers = providers.slice(0, isDocsEnabled);
|
|
26
26
|
}
|
|
27
|
-
await Promise.all(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
system: await alchemy `
|
|
27
|
+
const providerDocs = await Promise.all(providers.map(async (provider) => {
|
|
28
|
+
const providerName = path.basename(provider);
|
|
29
|
+
const files = (await fs.readdir(path.resolve(provider), {
|
|
30
|
+
withFileTypes: true,
|
|
31
|
+
}))
|
|
32
|
+
.filter((dirent) => dirent.isFile())
|
|
33
|
+
.map((dirent) => path.relative(process.cwd(), path.resolve(provider, dirent.name)))
|
|
34
|
+
.filter((file) => file.endsWith(".ts") && !file.endsWith("index.ts"));
|
|
35
|
+
const { object: { groups }, } = await Data(`docs/${providerName}`, {
|
|
36
|
+
schema: type({
|
|
37
|
+
groups: type({
|
|
38
|
+
title: type("string").describe("The title of the group, should be the Resource Name exactly without spaces, e.g. Bucket or Static Site."),
|
|
39
|
+
filename: type("string").describe("The filename of the Resource's Document, e.g. bucket.md or static-site.md"),
|
|
40
|
+
category: type("'Resource'|'Client'|'Utility'|'Types'").describe("The classification of the Resource's Document, one of: Resource, Client, Utility, or Types."),
|
|
41
|
+
}).array(),
|
|
42
|
+
}),
|
|
43
|
+
system: await alchemy `
|
|
45
44
|
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.
|
|
46
45
|
You will be provided with a list of documents and instructions on how to classify them.
|
|
47
46
|
Each document has a title, file name, and category.
|
|
48
47
|
`,
|
|
49
|
-
|
|
48
|
+
prompt: await alchemy `
|
|
50
49
|
Identify and classify the documents that need to be written for the '${provider}' Service's Alchemy Resources.
|
|
51
50
|
For background knowledge on Alchemy, see ${alchemy.file("./README.md")}.
|
|
52
51
|
For background knowledge on the structure of an Alchemy Resource, see ${alchemy.file("./.cursorrules")}.
|
|
@@ -61,14 +60,14 @@ export async function AlchemyDocs({ docs: isDocsEnabled }) {
|
|
|
61
60
|
|
|
62
61
|
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.
|
|
63
62
|
`,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
63
|
+
});
|
|
64
|
+
const providerDocsDir = (await Folder(path.join(providersDir, providerName))).path;
|
|
65
|
+
const documents = await Promise.all(groups
|
|
66
|
+
.filter((g) => g.category === "Resource")
|
|
67
|
+
.map(async (g) => Document(`docs/${providerName}/${g.title}`, {
|
|
68
|
+
title: g.title,
|
|
69
|
+
path: path.join(providerDocsDir, `${g.filename.replace(".ts", "").replace(".md", "")}.md`),
|
|
70
|
+
prompt: await alchemy `
|
|
72
71
|
You are a technical writer writing API documentation for an Alchemy IaC Resource.
|
|
73
72
|
See ${alchemy.file("./README.md")} to understand the overview of Alchemy.
|
|
74
73
|
See ${alchemy.file("./.cursorrules")} to better understand the structure and convention of an Alchemy Resource.
|
|
@@ -110,7 +109,7 @@ export async function AlchemyDocs({ docs: isDocsEnabled }) {
|
|
|
110
109
|
\`\`\`
|
|
111
110
|
|
|
112
111
|
${providerName === "cloudflare"
|
|
113
|
-
|
|
112
|
+
? await alchemy `# Bind to a Worker
|
|
114
113
|
(if it is a Cloudflare Resource)
|
|
115
114
|
|
|
116
115
|
\`\`\`ts
|
|
@@ -128,197 +127,161 @@ export async function AlchemyDocs({ docs: isDocsEnabled }) {
|
|
|
128
127
|
},
|
|
129
128
|
});
|
|
130
129
|
\`\`\``
|
|
131
|
-
|
|
130
|
+
: ""}
|
|
132
131
|
`,
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
references: ["../alchemy/tsconfig.json"],
|
|
167
|
-
},
|
|
168
|
-
devDependencies: {
|
|
169
|
-
alchemy: "workspace:*",
|
|
170
|
-
},
|
|
171
|
-
theme: {
|
|
172
|
-
light: "light-plus",
|
|
173
|
-
dark: "dark-plus",
|
|
174
|
-
},
|
|
175
|
-
home: {
|
|
176
|
-
layout: "home",
|
|
177
|
-
hero: {
|
|
178
|
-
text: "Alchemy",
|
|
179
|
-
tagline: "Alchemy is a TypeScript-native, embeddable IaC library",
|
|
180
|
-
actions: [
|
|
181
|
-
{
|
|
182
|
-
text: "Get Started",
|
|
183
|
-
link: "/docs",
|
|
184
|
-
theme: "brand",
|
|
185
|
-
},
|
|
186
|
-
],
|
|
132
|
+
})));
|
|
133
|
+
return {
|
|
134
|
+
dir: providerDocsDir,
|
|
135
|
+
provider: providerName,
|
|
136
|
+
documents,
|
|
137
|
+
};
|
|
138
|
+
}));
|
|
139
|
+
await VitePressProject("docs", {
|
|
140
|
+
name: "alchemy-web",
|
|
141
|
+
title: "Alchemy",
|
|
142
|
+
description: "Alchemy is an TypeScript-native, embeddable IaC library",
|
|
143
|
+
overwrite: true,
|
|
144
|
+
delete: false,
|
|
145
|
+
tsconfig: {
|
|
146
|
+
extends: "../tsconfig.base.json",
|
|
147
|
+
references: ["../alchemy/tsconfig.json"],
|
|
148
|
+
},
|
|
149
|
+
devDependencies: {
|
|
150
|
+
alchemy: "workspace:*",
|
|
151
|
+
},
|
|
152
|
+
theme: {
|
|
153
|
+
light: "light-plus",
|
|
154
|
+
dark: "dark-plus",
|
|
155
|
+
},
|
|
156
|
+
home: {
|
|
157
|
+
layout: "home",
|
|
158
|
+
hero: {
|
|
159
|
+
name: "Alchemy",
|
|
160
|
+
text: "Materialize all the things! 🪄",
|
|
161
|
+
tagline: "TypeScript-native Infrastructure-as-Code (IaC)",
|
|
162
|
+
image: {
|
|
163
|
+
src: "./public/alchemist.png",
|
|
164
|
+
alt: "The Alchemist",
|
|
187
165
|
},
|
|
188
|
-
|
|
166
|
+
actions: [
|
|
189
167
|
{
|
|
190
|
-
|
|
191
|
-
|
|
168
|
+
text: "Get Started",
|
|
169
|
+
link: "/docs",
|
|
170
|
+
theme: "brand",
|
|
192
171
|
},
|
|
193
172
|
],
|
|
194
173
|
},
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
"
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
{
|
|
208
|
-
text: "Guides",
|
|
209
|
-
items: [
|
|
210
|
-
{
|
|
211
|
-
text: "Custom Resource",
|
|
212
|
-
link: "/docs/guides/custom-resource",
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
text: "Automating with LLMs",
|
|
216
|
-
link: "/docs/guides/llms",
|
|
217
|
-
},
|
|
218
|
-
],
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
text: "Core",
|
|
222
|
-
collapsed: true,
|
|
223
|
-
items: [
|
|
224
|
-
{ text: "App", link: "/docs/core/app" },
|
|
225
|
-
{ text: "Resource", link: "/docs/core/resource" },
|
|
226
|
-
{ text: "Scope", link: "/docs/core/scope" },
|
|
227
|
-
{ text: "Phase", link: "/docs/core/phase" },
|
|
228
|
-
{ text: "Finalize", link: "/docs/core/finalize" },
|
|
229
|
-
{ text: "State", link: "/docs/core/state" },
|
|
230
|
-
{ text: "Secret", link: "/docs/core/secret" },
|
|
231
|
-
{ text: "Context", link: "/docs/core/context" },
|
|
232
|
-
],
|
|
233
|
-
},
|
|
234
|
-
{
|
|
235
|
-
text: "Resources",
|
|
236
|
-
items: [
|
|
237
|
-
{
|
|
238
|
-
text: "AWS",
|
|
239
|
-
link: "/docs/aws",
|
|
240
|
-
collapsed: true,
|
|
241
|
-
items: [
|
|
242
|
-
{ text: "Bucket", link: "/docs/aws/bucket" },
|
|
243
|
-
{ text: "Function", link: "/docs/aws/function" },
|
|
244
|
-
{ text: "Policy", link: "/docs/aws/policy" },
|
|
245
|
-
{ text: "Queue", link: "/docs/aws/queue" },
|
|
246
|
-
{ text: "Table", link: "/docs/aws/table" },
|
|
247
|
-
{ text: "Simple Email Service", link: "/docs/aws/ses" },
|
|
248
|
-
].sort((a, b) => a.text.localeCompare(b.text)),
|
|
249
|
-
},
|
|
250
|
-
{
|
|
251
|
-
text: "Cloudflare",
|
|
252
|
-
link: "/docs/cloudflare",
|
|
253
|
-
collapsed: true,
|
|
254
|
-
items: [
|
|
255
|
-
{ text: "Bucket", link: "/docs/cloudflare/bucket" },
|
|
256
|
-
{
|
|
257
|
-
text: "Durable Object",
|
|
258
|
-
link: "/docs/cloudflare/durable-object",
|
|
259
|
-
},
|
|
260
|
-
{
|
|
261
|
-
text: "Static Site",
|
|
262
|
-
link: "/docs/cloudflare/static-site",
|
|
263
|
-
},
|
|
264
|
-
{
|
|
265
|
-
text: "KV Namespace",
|
|
266
|
-
link: "/docs/cloudflare/kv-namespace",
|
|
267
|
-
},
|
|
268
|
-
{ text: "Worker", link: "/docs/cloudflare/worker" },
|
|
269
|
-
{ text: "Zone", link: "/docs/cloudflare/zone" },
|
|
270
|
-
].sort((a, b) => a.text.localeCompare(b.text)),
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
text: "Stripe",
|
|
274
|
-
link: "/docs/stripe",
|
|
275
|
-
collapsed: true,
|
|
276
|
-
items: [
|
|
277
|
-
{ text: "Product", link: "/docs/stripe/product" },
|
|
278
|
-
{ text: "Price", link: "/docs/stripe/price" },
|
|
279
|
-
],
|
|
280
|
-
},
|
|
281
|
-
{
|
|
282
|
-
text: "GitHub",
|
|
283
|
-
link: "/docs/github",
|
|
284
|
-
collapsed: true,
|
|
285
|
-
items: [{ text: "Secret", link: "/docs/github/secret" }],
|
|
286
|
-
},
|
|
287
|
-
{
|
|
288
|
-
text: "File System",
|
|
289
|
-
link: "/docs/fs",
|
|
290
|
-
collapsed: true,
|
|
291
|
-
items: [
|
|
292
|
-
{ text: "File", link: "/docs/fs/file" },
|
|
293
|
-
{ text: "Folder", link: "/docs/fs/folder" },
|
|
294
|
-
],
|
|
295
|
-
},
|
|
296
|
-
].sort((a, b) => a.text.localeCompare(b.text)),
|
|
297
|
-
},
|
|
298
|
-
],
|
|
299
|
-
"/examples/": [
|
|
300
|
-
{
|
|
301
|
-
text: "Examples",
|
|
302
|
-
items: [{ text: "Foo", link: "/examples/foo" }],
|
|
303
|
-
},
|
|
304
|
-
],
|
|
305
|
-
"/": [
|
|
306
|
-
{
|
|
307
|
-
text: "Home",
|
|
308
|
-
items: [
|
|
309
|
-
{ text: "Markdown Examples", link: "/markdown-examples" },
|
|
310
|
-
{ text: "Runtime API Examples", link: "/api-examples" },
|
|
311
|
-
],
|
|
312
|
-
},
|
|
313
|
-
],
|
|
174
|
+
features: [
|
|
175
|
+
{
|
|
176
|
+
title: "JS-native",
|
|
177
|
+
details: "No second language, toolchains, dependencies, processes, services, etc. to lug around.",
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
title: "Async",
|
|
181
|
+
details: "Resources are just async functions - no complex abstraction to learn.",
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
title: "ESM",
|
|
185
|
+
details: "Built exclusively on ESM, with a slight preference for modern JS runtimes like Bun.",
|
|
314
186
|
},
|
|
315
|
-
|
|
187
|
+
{
|
|
188
|
+
title: "Embeddable",
|
|
189
|
+
details: "Runs in any JavaScript/TypeScript environment, including the browser!",
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
title: "Extensible",
|
|
193
|
+
details: "Implement your own resources with a simple function.",
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
title: "AI-first",
|
|
197
|
+
details: "Create, copy, fork, and modify resources using LLMs to fit your needs.",
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
title: "No dependencies",
|
|
201
|
+
details: "The alchemy core package has 0 required dependencies.",
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
title: "No service",
|
|
205
|
+
details: "State files are stored locally in your project for easy inspection and version control.",
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
title: "No strong opinions",
|
|
209
|
+
details: "Structure your codebase however you want, store state anywhere - we don't care!",
|
|
210
|
+
},
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
themeConfig: {
|
|
214
|
+
sidebar: {
|
|
215
|
+
"/blog/": [{ text: "Blog", items: [{ text: "Blog", link: "/blog/" }] }],
|
|
216
|
+
"/docs/": [
|
|
316
217
|
{
|
|
317
|
-
|
|
318
|
-
link: "
|
|
218
|
+
text: "Getting Started",
|
|
219
|
+
items: [{ text: "Install", link: "/docs/getting-started/install" }],
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
text: "Guides",
|
|
223
|
+
items: [
|
|
224
|
+
{
|
|
225
|
+
text: "Custom Resource",
|
|
226
|
+
link: "/docs/guides/custom-resource",
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
text: "Automating with LLMs",
|
|
230
|
+
link: "/docs/guides/llms",
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
text: "Core",
|
|
236
|
+
collapsed: true,
|
|
237
|
+
items: [
|
|
238
|
+
{ text: "App", link: "/docs/core/app" },
|
|
239
|
+
{ text: "Resource", link: "/docs/core/resource" },
|
|
240
|
+
{ text: "Scope", link: "/docs/core/scope" },
|
|
241
|
+
{ text: "Phase", link: "/docs/core/phase" },
|
|
242
|
+
{ text: "Finalize", link: "/docs/core/finalize" },
|
|
243
|
+
{ text: "State", link: "/docs/core/state" },
|
|
244
|
+
{ text: "Secret", link: "/docs/core/secret" },
|
|
245
|
+
{ text: "Context", link: "/docs/core/context" },
|
|
246
|
+
],
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
text: "Providers",
|
|
250
|
+
items: providerDocs
|
|
251
|
+
.map((provider) => ({
|
|
252
|
+
text: provider.provider,
|
|
253
|
+
link: `/docs/providers/${provider.provider}`,
|
|
254
|
+
collapsed: true,
|
|
255
|
+
items: provider.documents.map((document) => ({
|
|
256
|
+
text: document.title,
|
|
257
|
+
link: `/docs/providers/${provider.provider}/${path.basename(document.path, ".md")}`,
|
|
258
|
+
})),
|
|
259
|
+
}))
|
|
260
|
+
.sort((a, b) => a.text.localeCompare(b.text)),
|
|
261
|
+
},
|
|
262
|
+
],
|
|
263
|
+
"/examples/": [
|
|
264
|
+
{
|
|
265
|
+
text: "Examples",
|
|
266
|
+
items: [{ text: "Foo", link: "/examples/foo" }],
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
"/": [
|
|
270
|
+
{
|
|
271
|
+
text: "Home",
|
|
272
|
+
items: [
|
|
273
|
+
{ text: "Markdown Examples", link: "/markdown-examples" },
|
|
274
|
+
{ text: "Runtime API Examples", link: "/api-examples" },
|
|
275
|
+
],
|
|
319
276
|
},
|
|
320
277
|
],
|
|
321
278
|
},
|
|
322
|
-
|
|
323
|
-
|
|
279
|
+
socialLinks: [
|
|
280
|
+
{
|
|
281
|
+
icon: "github",
|
|
282
|
+
link: "https://github.com/sam-goodwin/alchemy",
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
});
|
|
324
287
|
}
|
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
/**
|
|
15
15
|
* Properties for creating or updating an AI Object
|
|
16
16
|
*/
|
|
17
|
-
export interface
|
|
17
|
+
export interface DataProps<T extends Type<any, any>> {
|
|
18
18
|
/**
|
|
19
19
|
* The ArkType schema to validate and structure the generated content
|
|
20
20
|
*/
|
|
@@ -59,7 +59,7 @@ export interface ObjectProps<T extends Type<any, any>> {
|
|
|
59
59
|
/**
|
|
60
60
|
* A resource that uses AI to generate structured content based on a schema
|
|
61
61
|
*/
|
|
62
|
-
export interface
|
|
62
|
+
export interface Data<T> extends Resource<"ai::Object"> {
|
|
63
63
|
type: JsonSchema;
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -115,10 +115,10 @@ export interface Object<T> extends Resource<"ai::Object"> {
|
|
|
115
115
|
* system: "You are a technical documentation writer"
|
|
116
116
|
* });
|
|
117
117
|
*/
|
|
118
|
-
export const
|
|
118
|
+
export const Data = Resource("ai::Object", async function <
|
|
119
119
|
const T extends Type<any, any>,
|
|
120
|
-
>(this: Context<
|
|
121
|
-
|
|
120
|
+
>(this: Context<Data<any>>, id: string, props: DataProps<T>): Promise<
|
|
121
|
+
Data<type.infer<T>>
|
|
122
122
|
> {
|
|
123
123
|
if (this.phase === "delete") {
|
|
124
124
|
return this.destroy();
|
package/src/ai/document.ts
CHANGED
package/src/ai/index.ts
CHANGED
package/src/internal/docs.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type } from "arktype";
|
|
2
2
|
import fs from "fs/promises";
|
|
3
3
|
import path from "path";
|
|
4
|
+
import { Data } from "../ai/data";
|
|
4
5
|
import { Document } from "../ai/document";
|
|
5
|
-
import { Object } from "../ai/object";
|
|
6
6
|
import { alchemy } from "../alchemy";
|
|
7
7
|
import { Folder } from "../fs/folder";
|
|
8
8
|
import { VitePressProject } from "../vitepress/vitepress";
|
|
@@ -38,8 +38,8 @@ export async function AlchemyDocs({ docs: isDocsEnabled }: DocsProps) {
|
|
|
38
38
|
providers = providers.slice(0, isDocsEnabled);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
await Promise.all(
|
|
42
|
-
|
|
41
|
+
const providerDocs = await Promise.all(
|
|
42
|
+
providers.map(async (provider) => {
|
|
43
43
|
const providerName = path.basename(provider);
|
|
44
44
|
const files = (
|
|
45
45
|
await fs.readdir(path.resolve(provider), {
|
|
@@ -54,7 +54,7 @@ export async function AlchemyDocs({ docs: isDocsEnabled }: DocsProps) {
|
|
|
54
54
|
|
|
55
55
|
const {
|
|
56
56
|
object: { groups },
|
|
57
|
-
} = await
|
|
57
|
+
} = await Data(`docs/${providerName}`, {
|
|
58
58
|
schema: type({
|
|
59
59
|
groups: type({
|
|
60
60
|
title: type("string").describe(
|
|
@@ -94,11 +94,12 @@ export async function AlchemyDocs({ docs: isDocsEnabled }: DocsProps) {
|
|
|
94
94
|
await Folder(path.join(providersDir, providerName))
|
|
95
95
|
).path;
|
|
96
96
|
|
|
97
|
-
await Promise.all(
|
|
97
|
+
const documents = await Promise.all(
|
|
98
98
|
groups
|
|
99
99
|
.filter((g) => g.category === "Resource")
|
|
100
|
-
.map(async (g) =>
|
|
101
|
-
|
|
100
|
+
.map(async (g) =>
|
|
101
|
+
Document(`docs/${providerName}/${g.title}`, {
|
|
102
|
+
title: g.title,
|
|
102
103
|
path: path.join(
|
|
103
104
|
providerDocsDir,
|
|
104
105
|
`${g.filename.replace(".ts", "").replace(".md", "")}.md`,
|
|
@@ -167,203 +168,171 @@ export async function AlchemyDocs({ docs: isDocsEnabled }: DocsProps) {
|
|
|
167
168
|
: ""
|
|
168
169
|
}
|
|
169
170
|
`,
|
|
170
|
-
})
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
// E.g.
|
|
174
|
-
// \`\`\`ts twoslash
|
|
175
|
-
// import alchemy from "alchemy";
|
|
176
|
-
|
|
177
|
-
// alchemy
|
|
178
|
-
// // ^?
|
|
179
|
-
|
|
180
|
-
// // it needs to be placed under the symbol like so:
|
|
181
|
-
// const foo = "string";
|
|
182
|
-
// // ^?
|
|
183
|
-
|
|
184
|
-
// const basicBucket = await Bucket("my-app-storage", {
|
|
185
|
-
// // ^?
|
|
186
|
-
// bucketName: "my-app-storage",
|
|
187
|
-
// tags: {
|
|
188
|
-
// Environment: "production",
|
|
189
|
-
// Project: "my-app"
|
|
190
|
-
// }
|
|
191
|
-
// });
|
|
192
|
-
|
|
193
|
-
// alchemy.ru
|
|
194
|
-
// // ^|
|
|
195
|
-
// \`\`\`
|
|
196
|
-
|
|
197
|
-
// The \`^?\` syntax is for displaying the type of an expression.
|
|
198
|
-
// The \`^|\` syntax is for displaying auto-completions after a dot and (optional prefix)
|
|
199
|
-
}),
|
|
171
|
+
}),
|
|
172
|
+
),
|
|
200
173
|
);
|
|
201
|
-
}),
|
|
202
174
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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",
|
|
232
209
|
},
|
|
233
|
-
|
|
210
|
+
actions: [
|
|
234
211
|
{
|
|
235
|
-
|
|
236
|
-
|
|
212
|
+
text: "Get Started",
|
|
213
|
+
link: "/docs",
|
|
214
|
+
theme: "brand",
|
|
237
215
|
},
|
|
238
216
|
],
|
|
239
217
|
},
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
"
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
{
|
|
256
|
-
text: "Custom Resource",
|
|
257
|
-
link: "/docs/guides/custom-resource",
|
|
258
|
-
},
|
|
259
|
-
{
|
|
260
|
-
text: "Automating with LLMs",
|
|
261
|
-
link: "/docs/guides/llms",
|
|
262
|
-
},
|
|
263
|
-
],
|
|
264
|
-
},
|
|
265
|
-
{
|
|
266
|
-
text: "Core",
|
|
267
|
-
collapsed: true,
|
|
268
|
-
items: [
|
|
269
|
-
{ text: "App", link: "/docs/core/app" },
|
|
270
|
-
{ text: "Resource", link: "/docs/core/resource" },
|
|
271
|
-
{ text: "Scope", link: "/docs/core/scope" },
|
|
272
|
-
{ text: "Phase", link: "/docs/core/phase" },
|
|
273
|
-
{ text: "Finalize", link: "/docs/core/finalize" },
|
|
274
|
-
{ text: "State", link: "/docs/core/state" },
|
|
275
|
-
{ text: "Secret", link: "/docs/core/secret" },
|
|
276
|
-
{ text: "Context", link: "/docs/core/context" },
|
|
277
|
-
],
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
text: "Resources",
|
|
281
|
-
items: [
|
|
282
|
-
{
|
|
283
|
-
text: "AWS",
|
|
284
|
-
link: "/docs/aws",
|
|
285
|
-
collapsed: true,
|
|
286
|
-
items: [
|
|
287
|
-
{ text: "Bucket", link: "/docs/aws/bucket" },
|
|
288
|
-
{ text: "Function", link: "/docs/aws/function" },
|
|
289
|
-
{ text: "Policy", link: "/docs/aws/policy" },
|
|
290
|
-
{ text: "Queue", link: "/docs/aws/queue" },
|
|
291
|
-
{ text: "Table", link: "/docs/aws/table" },
|
|
292
|
-
{ text: "Simple Email Service", link: "/docs/aws/ses" },
|
|
293
|
-
].sort((a, b) => a.text.localeCompare(b.text)),
|
|
294
|
-
},
|
|
295
|
-
{
|
|
296
|
-
text: "Cloudflare",
|
|
297
|
-
link: "/docs/cloudflare",
|
|
298
|
-
collapsed: true,
|
|
299
|
-
items: [
|
|
300
|
-
{ text: "Bucket", link: "/docs/cloudflare/bucket" },
|
|
301
|
-
{
|
|
302
|
-
text: "Durable Object",
|
|
303
|
-
link: "/docs/cloudflare/durable-object",
|
|
304
|
-
},
|
|
305
|
-
{
|
|
306
|
-
text: "Static Site",
|
|
307
|
-
link: "/docs/cloudflare/static-site",
|
|
308
|
-
},
|
|
309
|
-
{
|
|
310
|
-
text: "KV Namespace",
|
|
311
|
-
link: "/docs/cloudflare/kv-namespace",
|
|
312
|
-
},
|
|
313
|
-
{ text: "Worker", link: "/docs/cloudflare/worker" },
|
|
314
|
-
{ text: "Zone", link: "/docs/cloudflare/zone" },
|
|
315
|
-
].sort((a, b) => a.text.localeCompare(b.text)),
|
|
316
|
-
},
|
|
317
|
-
{
|
|
318
|
-
text: "Stripe",
|
|
319
|
-
link: "/docs/stripe",
|
|
320
|
-
collapsed: true,
|
|
321
|
-
items: [
|
|
322
|
-
{ text: "Product", link: "/docs/stripe/product" },
|
|
323
|
-
{ text: "Price", link: "/docs/stripe/price" },
|
|
324
|
-
],
|
|
325
|
-
},
|
|
326
|
-
{
|
|
327
|
-
text: "GitHub",
|
|
328
|
-
link: "/docs/github",
|
|
329
|
-
collapsed: true,
|
|
330
|
-
items: [{ text: "Secret", link: "/docs/github/secret" }],
|
|
331
|
-
},
|
|
332
|
-
{
|
|
333
|
-
text: "File System",
|
|
334
|
-
link: "/docs/fs",
|
|
335
|
-
collapsed: true,
|
|
336
|
-
items: [
|
|
337
|
-
{ text: "File", link: "/docs/fs/file" },
|
|
338
|
-
{ text: "Folder", link: "/docs/fs/folder" },
|
|
339
|
-
],
|
|
340
|
-
},
|
|
341
|
-
].sort((a, b) => a.text.localeCompare(b.text)),
|
|
342
|
-
},
|
|
343
|
-
],
|
|
344
|
-
"/examples/": [
|
|
345
|
-
{
|
|
346
|
-
text: "Examples",
|
|
347
|
-
items: [{ text: "Foo", link: "/examples/foo" }],
|
|
348
|
-
},
|
|
349
|
-
],
|
|
350
|
-
"/": [
|
|
351
|
-
{
|
|
352
|
-
text: "Home",
|
|
353
|
-
items: [
|
|
354
|
-
{ text: "Markdown Examples", link: "/markdown-examples" },
|
|
355
|
-
{ text: "Runtime API Examples", link: "/api-examples" },
|
|
356
|
-
],
|
|
357
|
-
},
|
|
358
|
-
],
|
|
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.",
|
|
359
233
|
},
|
|
360
|
-
|
|
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/": [
|
|
361
268
|
{
|
|
362
|
-
|
|
363
|
-
link: "
|
|
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
|
+
],
|
|
364
327
|
},
|
|
365
328
|
],
|
|
366
329
|
},
|
|
367
|
-
|
|
368
|
-
|
|
330
|
+
socialLinks: [
|
|
331
|
+
{
|
|
332
|
+
icon: "github",
|
|
333
|
+
link: "https://github.com/sam-goodwin/alchemy",
|
|
334
|
+
},
|
|
335
|
+
],
|
|
336
|
+
},
|
|
337
|
+
});
|
|
369
338
|
}
|