alchemy 0.2.3 → 0.2.4

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.
Files changed (138) hide show
  1. package/lib/ai/ark.d.ts +11 -0
  2. package/lib/ai/ark.js +86 -0
  3. package/lib/ai/client.d.ts +51 -0
  4. package/lib/ai/client.js +29 -0
  5. package/lib/ai/document.d.ts +97 -0
  6. package/lib/ai/document.js +82 -0
  7. package/lib/{docs → ai}/index.d.ts +1 -0
  8. package/lib/{docs → ai}/index.js +1 -0
  9. package/lib/ai/object.d.ts +101 -0
  10. package/lib/ai/object.js +70 -0
  11. package/lib/alchemy.d.ts +83 -2
  12. package/lib/alchemy.js +31 -3
  13. package/lib/aws/bucket.d.ts +87 -1
  14. package/lib/aws/bucket.js +48 -1
  15. package/lib/aws/function.d.ts +186 -1
  16. package/lib/aws/function.js +62 -8
  17. package/lib/aws/oidc/github-oidc-provider.d.ts +81 -0
  18. package/lib/aws/oidc/github-oidc-provider.js +68 -0
  19. package/lib/aws/oidc/oidc-provider.d.ts +14 -6
  20. package/lib/aws/oidc/oidc-provider.js +26 -5
  21. package/lib/aws/policy-attachment.d.ts +44 -1
  22. package/lib/aws/policy-attachment.js +31 -0
  23. package/lib/aws/policy.d.ts +160 -1
  24. package/lib/aws/policy.js +78 -0
  25. package/lib/aws/queue.d.ts +83 -1
  26. package/lib/aws/queue.js +39 -0
  27. package/lib/aws/role.d.ts +162 -1
  28. package/lib/aws/role.js +114 -0
  29. package/lib/aws/ses.d.ts +57 -2
  30. package/lib/aws/ses.js +42 -1
  31. package/lib/aws/table.d.ts +96 -1
  32. package/lib/aws/table.js +36 -0
  33. package/lib/cloudflare/asset-manifest.js +0 -1
  34. package/lib/cloudflare/bound.js +0 -1
  35. package/lib/cloudflare/bucket.d.ts +37 -1
  36. package/lib/cloudflare/bucket.js +36 -0
  37. package/lib/cloudflare/durable-object-namespace.d.ts +25 -0
  38. package/lib/cloudflare/durable-object-namespace.js +22 -0
  39. package/lib/cloudflare/kv-namespace.d.ts +37 -1
  40. package/lib/cloudflare/kv-namespace.js +36 -0
  41. package/lib/cloudflare/static-site.d.ts +53 -1
  42. package/lib/cloudflare/static-site.js +53 -1
  43. package/lib/cloudflare/worker-metadata.js +0 -1
  44. package/lib/cloudflare/worker.d.ts +64 -1
  45. package/lib/cloudflare/worker.js +63 -0
  46. package/lib/cloudflare/wrangler.json.d.ts +1 -1
  47. package/lib/cloudflare/zone-settings.js +0 -1
  48. package/lib/cloudflare/zone.d.ts +56 -1
  49. package/lib/cloudflare/zone.js +55 -0
  50. package/lib/destroy.js +1 -1
  51. package/lib/esbuild/bundle.d.ts +43 -4
  52. package/lib/esbuild/bundle.js +16 -0
  53. package/lib/fs/file-collection.d.ts +16 -0
  54. package/lib/fs/file-collection.js +6 -0
  55. package/lib/fs/file-ref.d.ts +14 -0
  56. package/lib/fs/file-ref.js +6 -0
  57. package/lib/fs/file.d.ts +71 -25
  58. package/lib/fs/file.js +20 -44
  59. package/lib/fs/folder.d.ts +37 -5
  60. package/lib/fs/folder.js +26 -2
  61. package/lib/fs/index.d.ts +6 -0
  62. package/lib/fs/index.js +6 -0
  63. package/lib/fs/json-file.d.ts +16 -0
  64. package/lib/fs/json-file.js +7 -0
  65. package/lib/fs/text-file.d.ts +12 -0
  66. package/lib/fs/text-file.js +7 -0
  67. package/lib/fs/typescript-file.d.ts +19 -0
  68. package/lib/fs/typescript-file.js +14 -0
  69. package/lib/fs/yaml-file.d.ts +19 -0
  70. package/lib/fs/yaml-file.js +8 -0
  71. package/lib/github/secret.d.ts +63 -2
  72. package/lib/github/secret.js +61 -1
  73. package/lib/internal/docs.d.ts +5 -0
  74. package/lib/internal/docs.js +324 -0
  75. package/lib/resource.d.ts +1 -1
  76. package/lib/secret.d.ts +67 -0
  77. package/lib/secret.js +67 -0
  78. package/lib/shadcn/component.d.ts +1 -1
  79. package/lib/stripe/price.d.ts +51 -1
  80. package/lib/stripe/price.js +50 -0
  81. package/lib/stripe/product.d.ts +39 -1
  82. package/lib/stripe/product.js +38 -0
  83. package/lib/stripe/webhook.d.ts +46 -1
  84. package/lib/stripe/webhook.js +45 -0
  85. package/lib/test/bun.d.ts +64 -0
  86. package/lib/test/bun.js +35 -3
  87. package/lib/util/serde.js +14 -0
  88. package/lib/vite/vite.d.ts +1 -1
  89. package/lib/vitepress/dependencies.d.ts +2 -6
  90. package/lib/vitepress/vitepress.d.ts +12 -1
  91. package/lib/vitepress/vitepress.js +29 -23
  92. package/package.json +8 -3
  93. package/src/ai/ark.ts +118 -0
  94. package/src/ai/client.ts +78 -0
  95. package/src/ai/document.ts +160 -0
  96. package/src/{docs → ai}/index.ts +1 -0
  97. package/src/ai/object.ts +149 -0
  98. package/src/alchemy.ts +88 -5
  99. package/src/aws/bucket.ts +111 -7
  100. package/src/aws/function.ts +231 -10
  101. package/src/aws/oidc/github-oidc-provider.ts +83 -0
  102. package/src/aws/oidc/oidc-provider.ts +39 -7
  103. package/src/aws/policy-attachment.ts +44 -1
  104. package/src/aws/policy.ts +177 -2
  105. package/src/aws/queue.ts +89 -0
  106. package/src/aws/role.ts +174 -2
  107. package/src/aws/ses.ts +56 -1
  108. package/src/aws/table.ts +103 -0
  109. package/src/cloudflare/bucket.ts +36 -0
  110. package/src/cloudflare/durable-object-namespace.ts +25 -0
  111. package/src/cloudflare/kv-namespace.ts +36 -0
  112. package/src/cloudflare/static-site.ts +53 -1
  113. package/src/cloudflare/worker.ts +63 -0
  114. package/src/cloudflare/zone.ts +55 -0
  115. package/src/destroy.ts +1 -1
  116. package/src/esbuild/bundle.ts +53 -3
  117. package/src/fs/file-collection.ts +24 -0
  118. package/src/fs/file-ref.ts +22 -0
  119. package/src/fs/file.ts +70 -77
  120. package/src/fs/folder.ts +44 -5
  121. package/src/fs/index.ts +6 -0
  122. package/src/fs/json-file.ts +23 -0
  123. package/src/fs/text-file.ts +19 -0
  124. package/src/fs/typescript-file.ts +36 -0
  125. package/src/fs/yaml-file.ts +26 -0
  126. package/src/github/secret.ts +65 -2
  127. package/src/internal/docs.ts +369 -0
  128. package/src/resource.ts +1 -1
  129. package/src/secret.ts +67 -0
  130. package/src/stripe/price.ts +50 -0
  131. package/src/stripe/product.ts +38 -0
  132. package/src/stripe/webhook.ts +45 -0
  133. package/src/test/bun.ts +83 -3
  134. package/src/util/serde.ts +17 -0
  135. package/src/vitepress/vitepress.ts +47 -26
  136. package/lib/docs/document.d.ts +0 -123
  137. package/lib/docs/document.js +0 -67
  138. package/src/docs/document.ts +0 -225
package/src/fs/file.ts CHANGED
@@ -5,45 +5,56 @@ import { Resource } from "../resource";
5
5
  import { ignore } from "../util/ignore";
6
6
 
7
7
  import { alchemy } from "../alchemy";
8
+ import type { FileCollection } from "./file-collection";
9
+ import type { FileRef } from "./file-ref";
8
10
 
9
11
  declare module "../alchemy" {
10
12
  interface Alchemy {
13
+ /**
14
+ * Creates a reference to a file in the filesystem.
15
+ * Used in template string interpolation to include file contents,
16
+ * commonly for documentation generation.
17
+ *
18
+ * @param path Path to the file
19
+ * @returns Promise resolving to a FileRef
20
+ *
21
+ * @example
22
+ * // Include a file in documentation generation
23
+ * await Document("api-docs", {
24
+ * prompt: await alchemy`
25
+ * Generate docs using the contents of:
26
+ * ${alchemy.file("./README.md")}
27
+ * `
28
+ * });
29
+ */
11
30
  file(path: string): Promise<FileRef>;
31
+
32
+ /**
33
+ * Creates a collection of files with their contents.
34
+ * Used in template string interpolation to include multiple file contents,
35
+ * commonly for bulk documentation generation.
36
+ *
37
+ * @param paths Array of file paths to include in collection
38
+ * @returns Promise resolving to a FileCollection
39
+ *
40
+ * @example
41
+ * // Include multiple source files in documentation generation
42
+ * await Document("provider-docs", {
43
+ * prompt: await alchemy`
44
+ * Generate comprehensive docs for these files:
45
+ * ${alchemy.files([
46
+ * "src/types.ts",
47
+ * "src/resource.ts",
48
+ * "src/provider.ts"
49
+ * ])}
50
+ * `
51
+ * });
52
+ */
12
53
  files(paths: string[]): Promise<FileCollection>;
13
54
  files(path: string, ...paths: string[]): Promise<FileCollection>;
14
55
  }
15
56
  }
16
57
 
17
- export type FileRef = {
18
- kind: "fs::FileRef";
19
- path: string;
20
- };
21
-
22
- export function isFileRef(value: unknown): value is FileRef {
23
- return (
24
- typeof value === "object" &&
25
- value !== null &&
26
- "kind" in value &&
27
- value.kind === "fs::FileRef"
28
- );
29
- }
30
-
31
- export type FileCollection = {
32
- type: "fs::FileCollection";
33
- files: {
34
- [relativePath: string]: string;
35
- };
36
- };
37
-
38
- export function isFileCollection(value: unknown): value is FileCollection {
39
- return (
40
- typeof value === "object" &&
41
- value !== null &&
42
- "type" in value &&
43
- value.type === "fs::FileCollection"
44
- );
45
- }
46
-
47
58
  alchemy.file = async (path: string) => ({
48
59
  kind: "fs::FileRef",
49
60
  path,
@@ -67,11 +78,40 @@ alchemy.files = async (
67
78
  };
68
79
  };
69
80
 
81
+ /**
82
+ * Base file resource type
83
+ */
70
84
  export interface File extends Resource<"fs::File"> {
85
+ /**
86
+ * Path to the file
87
+ */
71
88
  path: string;
89
+ /**
90
+ * Content of the file
91
+ */
72
92
  content: string;
73
93
  }
74
94
 
95
+ /**
96
+ * File Resource
97
+ *
98
+ * Creates and manages files in the filesystem with automatic directory creation
99
+ * and proper cleanup on deletion.
100
+ *
101
+ * @example
102
+ * // Create a simple text file
103
+ * const config = await File("config.txt", {
104
+ * path: "config.txt",
105
+ * content: "some configuration data"
106
+ * });
107
+ *
108
+ * @example
109
+ * // Create a file in a nested directory
110
+ * const log = await File("logs/app.log", {
111
+ * path: "logs/app.log",
112
+ * content: "application log entry"
113
+ * });
114
+ */
75
115
  export const File = Resource(
76
116
  "fs::File",
77
117
  async function (
@@ -98,50 +138,3 @@ export const File = Resource(
98
138
  });
99
139
  },
100
140
  );
101
-
102
- export type JsonFile = File;
103
-
104
- export function JsonFile(id: string, content: any): Promise<JsonFile> {
105
- return File(id, {
106
- path: id,
107
- content: JSON.stringify(content, null, 2),
108
- });
109
- }
110
-
111
- export type TextFile = File;
112
-
113
- export function TextFile(id: string, content: string): Promise<TextFile> {
114
- return File(id, {
115
- path: id,
116
- content,
117
- });
118
- }
119
-
120
- export type YamlFile = File;
121
-
122
- export async function YamlFile(id: string, content: any): Promise<YamlFile> {
123
- const yaml = await import("yaml");
124
- return File(id, {
125
- path: id,
126
- content: yaml.stringify(content),
127
- });
128
- }
129
-
130
- export type TypeScriptFile = File;
131
-
132
- export async function TypeScriptFile(
133
- id: string,
134
- content: string,
135
- ): Promise<TypeScriptFile> {
136
- const prettier = await import("prettier");
137
- return File(id, {
138
- path: id,
139
- content: await prettier.format(content, {
140
- parser: "typescript",
141
- editor: {
142
- tabWidth: 2,
143
- indentWidth: 2,
144
- },
145
- }),
146
- });
147
- }
package/src/fs/folder.ts CHANGED
@@ -3,23 +3,62 @@ import type { Context } from "../context";
3
3
  import { Resource } from "../resource";
4
4
  import { ignore } from "../util/ignore";
5
5
 
6
+ export interface FolderProps {
7
+ /**
8
+ * The path of the folder
9
+ */
10
+ path?: string;
11
+ /**
12
+ * Whether to delete the folder during the delete phase
13
+ * @default true
14
+ */
15
+ delete?: boolean;
16
+ }
17
+
18
+ /**
19
+ * Base folder resource type
20
+ */
6
21
  export interface Folder extends Resource<"fs::Folder"> {
7
22
  path: string;
8
23
  }
9
24
 
25
+ /**
26
+ * Folder Resource
27
+ *
28
+ * Creates and manages directories in the filesystem with automatic parent
29
+ * directory creation and cleanup on deletion.
30
+ *
31
+ * @example
32
+ * // Create a directory using id as path
33
+ * const dir = await Folder("uploads");
34
+ *
35
+ * @example
36
+ * // Create a directory with explicit path
37
+ * const dir = await Folder("uploads", {
38
+ * path: "uploads"
39
+ * });
40
+ *
41
+ * @example
42
+ * // Create a nested directory structure
43
+ * const logs = await Folder("var/log/app", {
44
+ * path: "var/log/app"
45
+ * });
46
+ */
10
47
  export const Folder = Resource(
11
48
  "fs::Folder",
12
49
  async function (
13
50
  this: Context<Folder>,
14
51
  id: string,
15
- props?: { path: string },
52
+ props?: FolderProps,
16
53
  ): Promise<Folder> {
17
54
  const dirPath = props?.path ?? id;
18
55
  if (this.phase === "delete") {
19
- // we just do a best effort attempt
20
- await ignore(["ENOENT", "ENOTEMPTY"], async () =>
21
- fs.promises.rmdir(dirPath),
22
- );
56
+ if (props?.delete !== false) {
57
+ // we just do a best effort attempt
58
+ await ignore(["ENOENT", "ENOTEMPTY"], async () =>
59
+ fs.promises.rmdir(dirPath),
60
+ );
61
+ }
23
62
  return this.destroy();
24
63
  } else {
25
64
  await ignore("EEXIST", async () =>
package/src/fs/index.ts CHANGED
@@ -1,2 +1,8 @@
1
1
  export * from "./file";
2
+ export * from "./file-collection";
3
+ export * from "./file-ref";
2
4
  export * from "./folder";
5
+ export * from "./json-file";
6
+ export * from "./text-file";
7
+ export * from "./typescript-file";
8
+ export * from "./yaml-file";
@@ -0,0 +1,23 @@
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
+ }
@@ -0,0 +1,19 @@
1
+ import { File } from "./file";
2
+
3
+ /**
4
+ * Creates a plain text file
5
+ *
6
+ * @example
7
+ * // Create a text file with content
8
+ * const readme = await TextFile("README.md",
9
+ * "# Project Name\n\nProject description goes here."
10
+ * );
11
+ */
12
+ export type TextFile = File;
13
+
14
+ export function TextFile(id: string, content: string): Promise<TextFile> {
15
+ return File(id, {
16
+ path: id,
17
+ content,
18
+ });
19
+ }
@@ -0,0 +1,36 @@
1
+ import { File } from "./file";
2
+
3
+ /**
4
+ * Creates a TypeScript file with formatted content using prettier
5
+ *
6
+ * @example
7
+ * // Create a TypeScript file
8
+ * const component = await TypeScriptFile("Component.ts", `
9
+ * interface Props {
10
+ * name: string;
11
+ * age: number;
12
+ * }
13
+ *
14
+ * export function Component({ name, age }: Props) {
15
+ * return <div>Hello {name}, you are {age} years old</div>;
16
+ * }
17
+ * `);
18
+ */
19
+ export type TypeScriptFile = File;
20
+
21
+ export async function TypeScriptFile(
22
+ id: string,
23
+ content: string,
24
+ ): Promise<TypeScriptFile> {
25
+ const prettier = await import("prettier");
26
+ return File(id, {
27
+ path: id,
28
+ content: await prettier.format(content, {
29
+ parser: "typescript",
30
+ editor: {
31
+ tabWidth: 2,
32
+ indentWidth: 2,
33
+ },
34
+ }),
35
+ });
36
+ }
@@ -0,0 +1,26 @@
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
+ }
@@ -29,8 +29,11 @@ export interface GitHubSecretProps {
29
29
 
30
30
  /**
31
31
  * Optional GitHub API token (overrides environment variable)
32
+ * If not provided, will use GITHUB_TOKEN environment variable
33
+ * Token must have 'repo' scope for private repositories
34
+ * or 'public_repo' scope for public repositories
32
35
  */
33
- token?: string;
36
+ token?: Secret;
34
37
  }
35
38
 
36
39
  /**
@@ -52,6 +55,64 @@ export interface GitHubSecretOutput
52
55
 
53
56
  /**
54
57
  * Resource for managing GitHub repository secrets
58
+ *
59
+ * Authentication is handled in the following order:
60
+ * 1. `token` parameter in the resource props (if provided)
61
+ * 2. `GITHUB_TOKEN` environment variable
62
+ *
63
+ * The token must have the following permissions:
64
+ * - 'repo' scope for private repositories
65
+ * - 'public_repo' scope for public repositories
66
+ *
67
+ * @example
68
+ * // Create a secret using GITHUB_TOKEN environment variable:
69
+ * const secret = await GitHubSecret("my-secret", {
70
+ * owner: "my-github-username",
71
+ * repository: "my-repo",
72
+ * name: "API_KEY",
73
+ * value: alchemy.secret("my-secret-value")
74
+ * });
75
+ *
76
+ * @example
77
+ * // Create a secret with a custom GitHub token:
78
+ * const secret = await GitHubSecret("my-secret", {
79
+ * owner: "my-github-username",
80
+ * repository: "my-repo",
81
+ * name: "API_KEY",
82
+ * value: alchemy.secret("my-secret-value"),
83
+ * token: alchemy.secret(process.env.CUSTOM_GITHUB_TOKEN)
84
+ * });
85
+ *
86
+ * @example
87
+ * // Create multiple secrets with environment variables:
88
+ * const secrets = await Promise.all([
89
+ * GitHubSecret("aws-secret", {
90
+ * owner: "my-github-username",
91
+ * repository: "cloud-app",
92
+ * name: "AWS_ROLE_ARN",
93
+ * value: alchemy.secret(process.env.AWS_ROLE_ARN)
94
+ * }),
95
+ * GitHubSecret("cf-secret", {
96
+ * owner: "my-github-username",
97
+ * repository: "cloud-app",
98
+ * name: "CLOUDFLARE_API_KEY",
99
+ * value: alchemy.secret(process.env.CLOUDFLARE_API_KEY)
100
+ * })
101
+ * ]);
102
+ *
103
+ * @example
104
+ * // Create a secret in a secure scope with a password:
105
+ * await alchemy.run("secure-scope", {
106
+ * password: process.env.SECRET_PASSPHRASE
107
+ * }, async () => {
108
+ * const secret = await GitHubSecret("deploy-secret", {
109
+ * owner: "my-github-username",
110
+ * repository: "my-app",
111
+ * name: "DEPLOY_TOKEN",
112
+ * value: alchemy.secret(process.env.DEPLOY_TOKEN),
113
+ * token: alchemy.secret(process.env.GITHUB_TOKEN)
114
+ * });
115
+ * });
55
116
  */
56
117
  export const GitHubSecret = Resource(
57
118
  "github::Secret",
@@ -62,7 +123,9 @@ export const GitHubSecret = Resource(
62
123
  ): Promise<GitHubSecretOutput> {
63
124
  // Create authenticated Octokit client - will automatically handle token resolution
64
125
  /// TODO: use fetch
65
- const octokit = await createGitHubClient({ token: props.token });
126
+ const octokit = await createGitHubClient({
127
+ token: props.token?.unencrypted,
128
+ });
66
129
 
67
130
  // Verify authentication and permissions
68
131
  if (!this.quiet) {