alchemy 0.2.2 → 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.
- package/lib/ai/ark.d.ts +11 -0
- package/lib/ai/ark.js +86 -0
- package/lib/ai/client.d.ts +51 -0
- package/lib/ai/client.js +29 -0
- package/lib/ai/document.d.ts +97 -0
- package/lib/ai/document.js +82 -0
- package/lib/ai/index.d.ts +2 -0
- package/lib/ai/index.js +2 -0
- package/lib/ai/object.d.ts +101 -0
- package/lib/ai/object.js +70 -0
- package/lib/alchemy.d.ts +84 -2
- package/lib/alchemy.js +114 -10
- package/lib/apply.d.ts +1 -1
- package/lib/apply.js +13 -10
- package/lib/aws/bucket.d.ts +87 -1
- package/lib/aws/bucket.js +48 -1
- package/lib/aws/function.d.ts +186 -1
- package/lib/aws/function.js +62 -8
- package/lib/aws/oidc/github-oidc-provider.d.ts +81 -0
- package/lib/aws/oidc/github-oidc-provider.js +68 -0
- package/lib/aws/oidc/oidc-provider.d.ts +14 -6
- package/lib/aws/oidc/oidc-provider.js +26 -5
- package/lib/aws/policy-attachment.d.ts +44 -1
- package/lib/aws/policy-attachment.js +31 -0
- package/lib/aws/policy.d.ts +160 -1
- package/lib/aws/policy.js +78 -0
- package/lib/aws/queue.d.ts +83 -1
- package/lib/aws/queue.js +39 -0
- package/lib/aws/role.d.ts +162 -1
- package/lib/aws/role.js +114 -0
- package/lib/aws/ses.d.ts +57 -2
- package/lib/aws/ses.js +42 -1
- package/lib/aws/table.d.ts +96 -1
- package/lib/aws/table.js +36 -0
- package/lib/cloudflare/asset-manifest.js +0 -1
- package/lib/cloudflare/bound.js +0 -1
- package/lib/cloudflare/bucket.d.ts +37 -1
- package/lib/cloudflare/bucket.js +36 -0
- package/lib/cloudflare/durable-object-namespace.d.ts +25 -0
- package/lib/cloudflare/durable-object-namespace.js +22 -0
- package/lib/cloudflare/kv-namespace.d.ts +37 -1
- package/lib/cloudflare/kv-namespace.js +36 -0
- package/lib/cloudflare/static-site.d.ts +53 -1
- package/lib/cloudflare/static-site.js +53 -1
- package/lib/cloudflare/worker-metadata.js +0 -1
- package/lib/cloudflare/worker.d.ts +64 -1
- package/lib/cloudflare/worker.js +63 -0
- package/lib/cloudflare/wrangler.json.d.ts +1 -1
- package/lib/cloudflare/zone-settings.js +0 -1
- package/lib/cloudflare/zone.d.ts +56 -1
- package/lib/cloudflare/zone.js +55 -0
- package/lib/context.d.ts +9 -4
- package/lib/context.js +4 -2
- package/lib/destroy.js +9 -8
- package/lib/esbuild/bundle.d.ts +43 -4
- package/lib/esbuild/bundle.js +16 -0
- package/lib/fs/file-collection.d.ts +16 -0
- package/lib/fs/file-collection.js +6 -0
- package/lib/fs/file-ref.d.ts +14 -0
- package/lib/fs/file-ref.js +6 -0
- package/lib/fs/file.d.ts +78 -5
- package/lib/fs/file.js +39 -3
- package/lib/fs/folder.d.ts +37 -5
- package/lib/fs/folder.js +28 -3
- package/lib/fs/index.d.ts +6 -0
- package/lib/fs/index.js +6 -0
- package/lib/fs/json-file.d.ts +16 -0
- package/lib/fs/json-file.js +7 -0
- package/lib/fs/text-file.d.ts +12 -0
- package/lib/fs/text-file.js +7 -0
- package/lib/fs/typescript-file.d.ts +19 -0
- package/lib/fs/typescript-file.js +14 -0
- package/lib/fs/yaml-file.d.ts +19 -0
- package/lib/fs/yaml-file.js +8 -0
- package/lib/github/secret.d.ts +63 -2
- package/lib/github/secret.js +61 -1
- package/lib/internal/docs.d.ts +5 -0
- package/lib/internal/docs.js +324 -0
- package/lib/resource.d.ts +2 -2
- package/lib/resource.js +4 -0
- package/lib/scope.d.ts +1 -1
- package/lib/scope.js +6 -6
- package/lib/secret.d.ts +67 -0
- package/lib/secret.js +67 -0
- package/lib/shadcn/component.d.ts +1 -1
- package/lib/state.d.ts +1 -1
- package/lib/state.js +8 -1
- package/lib/stripe/price.d.ts +51 -1
- package/lib/stripe/price.js +50 -0
- package/lib/stripe/product.d.ts +39 -1
- package/lib/stripe/product.js +38 -0
- package/lib/stripe/webhook.d.ts +46 -1
- package/lib/stripe/webhook.js +45 -0
- package/lib/test/bun.d.ts +64 -0
- package/lib/test/bun.js +35 -3
- package/lib/util/serde.d.ts +3 -1
- package/lib/util/serde.js +20 -4
- package/lib/vite/vite.d.ts +1 -1
- package/lib/vitepress/dependencies.d.ts +12 -0
- package/lib/vitepress/dependencies.js +35 -0
- package/lib/vitepress/home-page.d.ts +133 -0
- package/lib/vitepress/home-page.js +11 -0
- package/lib/vitepress/index.d.ts +2 -0
- package/lib/vitepress/index.js +2 -0
- package/lib/vitepress/vitepress.d.ts +71 -0
- package/lib/vitepress/vitepress.js +266 -0
- package/package.json +22 -10
- package/src/ai/ark.ts +118 -0
- package/src/ai/client.ts +78 -0
- package/src/ai/document.ts +160 -0
- package/src/ai/index.ts +2 -0
- package/src/ai/object.ts +149 -0
- package/src/alchemy.ts +192 -17
- package/src/apply.ts +25 -13
- package/src/aws/bucket.ts +111 -7
- package/src/aws/function.ts +231 -10
- package/src/aws/oidc/github-oidc-provider.ts +83 -0
- package/src/aws/oidc/oidc-provider.ts +39 -7
- package/src/aws/policy-attachment.ts +44 -1
- package/src/aws/policy.ts +177 -2
- package/src/aws/queue.ts +89 -0
- package/src/aws/role.ts +174 -2
- package/src/aws/ses.ts +56 -1
- package/src/aws/table.ts +103 -0
- package/src/cloudflare/bucket.ts +36 -0
- package/src/cloudflare/durable-object-namespace.ts +25 -0
- package/src/cloudflare/kv-namespace.ts +36 -0
- package/src/cloudflare/static-site.ts +53 -1
- package/src/cloudflare/worker.ts +63 -0
- package/src/cloudflare/zone.ts +55 -0
- package/src/context.ts +30 -10
- package/src/destroy.ts +11 -8
- package/src/esbuild/bundle.ts +53 -3
- package/src/fs/file-collection.ts +24 -0
- package/src/fs/file-ref.ts +22 -0
- package/src/fs/file.ts +107 -6
- package/src/fs/folder.ts +45 -5
- package/src/fs/index.ts +6 -0
- package/src/fs/json-file.ts +23 -0
- package/src/fs/text-file.ts +19 -0
- package/src/fs/typescript-file.ts +36 -0
- package/src/fs/yaml-file.ts +26 -0
- package/src/github/secret.ts +65 -2
- package/src/internal/docs.ts +369 -0
- package/src/resource.ts +7 -2
- package/src/scope.ts +9 -9
- package/src/secret.ts +67 -0
- package/src/state.ts +9 -2
- package/src/stripe/price.ts +50 -0
- package/src/stripe/product.ts +38 -0
- package/src/stripe/webhook.ts +45 -0
- package/src/test/bun.ts +83 -3
- package/src/util/serde.ts +30 -4
- package/src/vitepress/dependencies.ts +68 -0
- package/src/vitepress/home-page.ts +166 -0
- package/src/vitepress/index.md +75 -0
- package/src/vitepress/index.ts +2 -0
- package/src/vitepress/vitepress.ts +382 -0
- package/lib/project/vite.d.ts +0 -90
- package/lib/project/vite.js +0 -228
- package/src/project/vite.ts +0 -406
package/lib/cloudflare/worker.js
CHANGED
|
@@ -7,6 +7,69 @@ import { slugify } from "../util/slugify";
|
|
|
7
7
|
import { createCloudflareApi } from "./api";
|
|
8
8
|
import { isDurableObjectNamespace, } from "./bindings";
|
|
9
9
|
import { isKVNamespace } from "./kv-namespace";
|
|
10
|
+
/**
|
|
11
|
+
* A Cloudflare Worker is a serverless function that can be deployed to the Cloudflare network.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // Create a basic HTTP handler worker with custom domain routing
|
|
15
|
+
* // and workers.dev URL:
|
|
16
|
+
* const api = await Worker("api", {
|
|
17
|
+
* name: "api-worker",
|
|
18
|
+
* entrypoint: "./src/api.ts",
|
|
19
|
+
* routes: ["api.example.com/*"],
|
|
20
|
+
* url: true
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Create a real-time chat worker using Durable Objects
|
|
25
|
+
* // for state management:
|
|
26
|
+
* const chatRooms = new DurableObjectNamespace("chat-rooms");
|
|
27
|
+
* const userStore = new DurableObjectNamespace("user-store");
|
|
28
|
+
*
|
|
29
|
+
* const chat = await Worker("chat", {
|
|
30
|
+
* name: "chat-worker",
|
|
31
|
+
* entrypoint: "./src/chat.ts",
|
|
32
|
+
* bindings: {
|
|
33
|
+
* ROOMS: chatRooms,
|
|
34
|
+
* USERS: userStore
|
|
35
|
+
* },
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* // Create a worker with KV namespace for caching and data storage:
|
|
40
|
+
* const cache = await KVNamespace("cache-store");
|
|
41
|
+
* const settings = await KVNamespace("user-settings");
|
|
42
|
+
*
|
|
43
|
+
* const cacheWorker = await Worker("cache", {
|
|
44
|
+
* name: "cache-worker",
|
|
45
|
+
* entrypoint: "./src/cache.ts",
|
|
46
|
+
* bindings: {
|
|
47
|
+
* CACHE: cache,
|
|
48
|
+
* SETTINGS: settings
|
|
49
|
+
* }
|
|
50
|
+
* });
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* // Create a worker with R2 bucket for object storage:
|
|
54
|
+
* const uploads = await R2Bucket("uploads", {
|
|
55
|
+
* name: "user-uploads"
|
|
56
|
+
* });
|
|
57
|
+
* const assets = await R2Bucket("assets", {
|
|
58
|
+
* name: "static-assets",
|
|
59
|
+
* allowPublicAccess: true
|
|
60
|
+
* });
|
|
61
|
+
*
|
|
62
|
+
* const storageWorker = await Worker("storage", {
|
|
63
|
+
* name: "storage-worker",
|
|
64
|
+
* entrypoint: "./src/storage.ts",
|
|
65
|
+
* bindings: {
|
|
66
|
+
* UPLOADS: uploads,
|
|
67
|
+
* ASSETS: assets
|
|
68
|
+
* }
|
|
69
|
+
* });
|
|
70
|
+
*
|
|
71
|
+
* @see https://developers.cloudflare.com/workers/
|
|
72
|
+
*/
|
|
10
73
|
export const Worker = Resource("cloudflare::Worker", {
|
|
11
74
|
alwaysUpdate: true,
|
|
12
75
|
}, async function (id, props) {
|
|
@@ -240,4 +240,4 @@ export interface WranglerJson extends Resource<"cloudflare::WranglerJson">, Wran
|
|
|
240
240
|
/**
|
|
241
241
|
* Resource for managing wrangler.json configuration files
|
|
242
242
|
*/
|
|
243
|
-
export declare const WranglerJson: ((this:
|
|
243
|
+
export declare const WranglerJson: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<WranglerJson>, id: string, props: WranglerJsonProps) => Promise<WranglerJson>);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/cloudflare/zone.d.ts
CHANGED
|
@@ -193,4 +193,59 @@ export interface Zone extends Resource<"cloudflare::Zone"> {
|
|
|
193
193
|
minTlsVersion: MinTLSVersionValue;
|
|
194
194
|
};
|
|
195
195
|
}
|
|
196
|
-
|
|
196
|
+
/**
|
|
197
|
+
* A Cloudflare Zone represents a domain and its configuration settings on Cloudflare.
|
|
198
|
+
* Zones allow you to manage DNS, SSL/TLS, caching, security and other settings for a domain.
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* // Create a basic zone with default settings
|
|
202
|
+
* const basicZone = await Zone("example.com", {
|
|
203
|
+
* name: "example.com",
|
|
204
|
+
* type: "full",
|
|
205
|
+
* jumpStart: true
|
|
206
|
+
* });
|
|
207
|
+
*
|
|
208
|
+
* @example
|
|
209
|
+
* // Create a zone with enhanced security settings
|
|
210
|
+
* const secureZone = await Zone("secure.example.com", {
|
|
211
|
+
* name: "secure.example.com",
|
|
212
|
+
* type: "full",
|
|
213
|
+
* settings: {
|
|
214
|
+
* ssl: "strict",
|
|
215
|
+
* alwaysUseHttps: "on",
|
|
216
|
+
* automaticHttpsRewrites: "on",
|
|
217
|
+
* minTlsVersion: "1.3",
|
|
218
|
+
* tls13: "zrt"
|
|
219
|
+
* }
|
|
220
|
+
* });
|
|
221
|
+
*
|
|
222
|
+
* @example
|
|
223
|
+
* // Create a zone with optimized performance settings
|
|
224
|
+
* const fastZone = await Zone("fast.example.com", {
|
|
225
|
+
* name: "fast.example.com",
|
|
226
|
+
* settings: {
|
|
227
|
+
* browserCacheTtl: 7200,
|
|
228
|
+
* brotli: "on",
|
|
229
|
+
* zeroRtt: "on",
|
|
230
|
+
* http2: "on",
|
|
231
|
+
* http3: "on",
|
|
232
|
+
* earlyHints: "on"
|
|
233
|
+
* }
|
|
234
|
+
* });
|
|
235
|
+
*
|
|
236
|
+
* @example
|
|
237
|
+
* // Create a development zone with specific features
|
|
238
|
+
* const devZone = await Zone("dev.example.com", {
|
|
239
|
+
* name: "dev.example.com",
|
|
240
|
+
* settings: {
|
|
241
|
+
* developmentMode: "on",
|
|
242
|
+
* emailObfuscation: "on",
|
|
243
|
+
* hotlinkProtection: "on",
|
|
244
|
+
* ipv6: "on",
|
|
245
|
+
* websockets: "on"
|
|
246
|
+
* }
|
|
247
|
+
* });
|
|
248
|
+
*
|
|
249
|
+
* @see https://developers.cloudflare.com/dns/zone-setups/
|
|
250
|
+
*/
|
|
251
|
+
export declare const Zone: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<Zone>, id: string, props: ZoneProps) => Promise<Zone>);
|
package/lib/cloudflare/zone.js
CHANGED
|
@@ -1,5 +1,60 @@
|
|
|
1
1
|
import { Resource } from "../resource";
|
|
2
2
|
import { createCloudflareApi } from "./api";
|
|
3
|
+
/**
|
|
4
|
+
* A Cloudflare Zone represents a domain and its configuration settings on Cloudflare.
|
|
5
|
+
* Zones allow you to manage DNS, SSL/TLS, caching, security and other settings for a domain.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // Create a basic zone with default settings
|
|
9
|
+
* const basicZone = await Zone("example.com", {
|
|
10
|
+
* name: "example.com",
|
|
11
|
+
* type: "full",
|
|
12
|
+
* jumpStart: true
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Create a zone with enhanced security settings
|
|
17
|
+
* const secureZone = await Zone("secure.example.com", {
|
|
18
|
+
* name: "secure.example.com",
|
|
19
|
+
* type: "full",
|
|
20
|
+
* settings: {
|
|
21
|
+
* ssl: "strict",
|
|
22
|
+
* alwaysUseHttps: "on",
|
|
23
|
+
* automaticHttpsRewrites: "on",
|
|
24
|
+
* minTlsVersion: "1.3",
|
|
25
|
+
* tls13: "zrt"
|
|
26
|
+
* }
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // Create a zone with optimized performance settings
|
|
31
|
+
* const fastZone = await Zone("fast.example.com", {
|
|
32
|
+
* name: "fast.example.com",
|
|
33
|
+
* settings: {
|
|
34
|
+
* browserCacheTtl: 7200,
|
|
35
|
+
* brotli: "on",
|
|
36
|
+
* zeroRtt: "on",
|
|
37
|
+
* http2: "on",
|
|
38
|
+
* http3: "on",
|
|
39
|
+
* earlyHints: "on"
|
|
40
|
+
* }
|
|
41
|
+
* });
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* // Create a development zone with specific features
|
|
45
|
+
* const devZone = await Zone("dev.example.com", {
|
|
46
|
+
* name: "dev.example.com",
|
|
47
|
+
* settings: {
|
|
48
|
+
* developmentMode: "on",
|
|
49
|
+
* emailObfuscation: "on",
|
|
50
|
+
* hotlinkProtection: "on",
|
|
51
|
+
* ipv6: "on",
|
|
52
|
+
* websockets: "on"
|
|
53
|
+
* }
|
|
54
|
+
* });
|
|
55
|
+
*
|
|
56
|
+
* @see https://developers.cloudflare.com/dns/zone-setups/
|
|
57
|
+
*/
|
|
3
58
|
export const Zone = Resource("cloudflare::Zone", async function (id, props) {
|
|
4
59
|
// Create Cloudflare API client with automatic account discovery
|
|
5
60
|
const api = await createCloudflareApi({
|
package/lib/context.d.ts
CHANGED
|
@@ -1,18 +1,21 @@
|
|
|
1
1
|
import type { Resource, ResourceFQN, ResourceID, ResourceKind, ResourceProps } from "./resource";
|
|
2
2
|
import type { Scope } from "./scope";
|
|
3
3
|
import type { State } from "./state";
|
|
4
|
-
export type Context<Out extends Resource> = CreateContext<Out> | UpdateContext<Out> | DeleteContext<Out>;
|
|
4
|
+
export type Context<Out extends Resource, Props extends ResourceProps = ResourceProps> = CreateContext<Out> | UpdateContext<Out, Props> | DeleteContext<Out, Props>;
|
|
5
5
|
export interface CreateContext<Out extends Resource> extends BaseContext<Out> {
|
|
6
6
|
phase: "create";
|
|
7
7
|
output?: undefined;
|
|
8
|
+
props?: undefined;
|
|
8
9
|
}
|
|
9
|
-
export interface UpdateContext<Out extends Resource> extends BaseContext<Out> {
|
|
10
|
+
export interface UpdateContext<Out extends Resource, Props extends ResourceProps = ResourceProps> extends BaseContext<Out> {
|
|
10
11
|
phase: "update";
|
|
11
12
|
output: Out;
|
|
13
|
+
props: Props;
|
|
12
14
|
}
|
|
13
|
-
export interface DeleteContext<Out extends Resource> extends BaseContext<Out> {
|
|
15
|
+
export interface DeleteContext<Out extends Resource, Props extends ResourceProps = ResourceProps> extends BaseContext<Out> {
|
|
14
16
|
phase: "delete";
|
|
15
17
|
output: Out;
|
|
18
|
+
props: Props;
|
|
16
19
|
}
|
|
17
20
|
export interface BaseContext<Out extends Resource> {
|
|
18
21
|
quiet: boolean;
|
|
@@ -44,15 +47,17 @@ export interface BaseContext<Out extends Resource> {
|
|
|
44
47
|
/**
|
|
45
48
|
* Create the Resource envelope (with Alchemy + User properties)
|
|
46
49
|
*/
|
|
50
|
+
(id: string, props: Omit<Out, keyof Resource>): Out;
|
|
47
51
|
(props: Omit<Out, keyof Resource>): Out;
|
|
48
52
|
}
|
|
49
|
-
export declare function context<Kind extends string, Props extends ResourceProps, Out extends Resource>({ scope, phase, kind, id, fqn, seq, state, replace, }: {
|
|
53
|
+
export declare function context<Kind extends string, Props extends ResourceProps | undefined, Out extends Resource>({ scope, phase, kind, id, fqn, seq, state, replace, }: {
|
|
50
54
|
scope: Scope;
|
|
51
55
|
phase: "create" | "update" | "delete";
|
|
52
56
|
kind: ResourceKind;
|
|
53
57
|
id: ResourceID;
|
|
54
58
|
fqn: ResourceFQN;
|
|
55
59
|
seq: number;
|
|
60
|
+
props: Props;
|
|
56
61
|
state: State<Kind, Props, Out>;
|
|
57
62
|
replace: () => void;
|
|
58
63
|
}): Context<Out>;
|
package/lib/context.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { DestroyedSignal } from "./destroy";
|
|
2
2
|
export function context({ scope, phase, kind, id, fqn, seq, state, replace, }) {
|
|
3
|
-
function create(
|
|
3
|
+
function create(...args) {
|
|
4
|
+
const [ID, props] = typeof args[0] === "string" ? args : [id, args[0]];
|
|
4
5
|
return {
|
|
5
6
|
...props,
|
|
6
7
|
Kind: kind,
|
|
7
|
-
ID
|
|
8
|
+
ID,
|
|
8
9
|
FQN: fqn,
|
|
9
10
|
Scope: scope,
|
|
10
11
|
Seq: seq,
|
|
@@ -17,6 +18,7 @@ export function context({ scope, phase, kind, id, fqn, seq, state, replace, }) {
|
|
|
17
18
|
fqn: fqn,
|
|
18
19
|
phase,
|
|
19
20
|
output: state.output,
|
|
21
|
+
props: state.props,
|
|
20
22
|
replace,
|
|
21
23
|
get: (key) => state.data[key],
|
|
22
24
|
set: async (key, value) => {
|
package/lib/destroy.js
CHANGED
|
@@ -12,12 +12,13 @@ function isScopeArgs(a) {
|
|
|
12
12
|
*/
|
|
13
13
|
export async function destroy(...args) {
|
|
14
14
|
if (isScopeArgs(args)) {
|
|
15
|
-
const [scope
|
|
16
|
-
const
|
|
15
|
+
const [scope] = args;
|
|
16
|
+
const options = {
|
|
17
|
+
strategy: "sequential",
|
|
18
|
+
...(args[1] ?? {}),
|
|
19
|
+
};
|
|
17
20
|
// destroy all active resources
|
|
18
|
-
await destroy.all(Array.from(scope.resources.values()),
|
|
19
|
-
strategy,
|
|
20
|
-
});
|
|
21
|
+
await destroy.all(Array.from(scope.resources.values()), options);
|
|
21
22
|
// then detect orphans and destroy them
|
|
22
23
|
const orphans = await scope.state.all();
|
|
23
24
|
await destroy.all(Object.values(orphans).map((orphan) => ({
|
|
@@ -34,7 +35,7 @@ export async function destroy(...args) {
|
|
|
34
35
|
}
|
|
35
36
|
const Provider = PROVIDERS.get(instance.Kind);
|
|
36
37
|
if (!Provider) {
|
|
37
|
-
throw new Error(`Cannot destroy resource type ${instance.Kind} - no provider found. You may need to import the provider in your alchemy.config.ts.`);
|
|
38
|
+
throw new Error(`Cannot destroy resource "${instance.FQN}" type ${instance.Kind} - no provider found. You may need to import the provider in your alchemy.config.ts.`);
|
|
38
39
|
}
|
|
39
40
|
const scope = instance.Scope;
|
|
40
41
|
if (!scope) {
|
|
@@ -45,9 +46,8 @@ export async function destroy(...args) {
|
|
|
45
46
|
if (!quiet) {
|
|
46
47
|
console.log(`Delete: "${instance.FQN}"`);
|
|
47
48
|
}
|
|
48
|
-
const state =
|
|
49
|
+
const state = await scope.state.get(instance.ID);
|
|
49
50
|
if (state === undefined) {
|
|
50
|
-
console.warn(`Resource "${instance.FQN}" not found`);
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
const ctx = context({
|
|
@@ -57,6 +57,7 @@ export async function destroy(...args) {
|
|
|
57
57
|
id: instance.ID,
|
|
58
58
|
fqn: instance.FQN,
|
|
59
59
|
seq: instance.Seq,
|
|
60
|
+
props: state.props,
|
|
60
61
|
state,
|
|
61
62
|
replace: () => {
|
|
62
63
|
throw new Error("Cannot replace a resource that is being deleted");
|
package/lib/esbuild/bundle.d.ts
CHANGED
|
@@ -1,25 +1,35 @@
|
|
|
1
1
|
import * as esbuild from "esbuild";
|
|
2
2
|
import type { Context } from "../context";
|
|
3
3
|
import { Resource } from "../resource";
|
|
4
|
+
/**
|
|
5
|
+
* Properties for creating or updating an esbuild bundle
|
|
6
|
+
*/
|
|
4
7
|
export interface BundleProps {
|
|
5
8
|
/**
|
|
6
9
|
* Entry point for the bundle
|
|
10
|
+
* Path to the source file to bundle (e.g., "src/handler.ts")
|
|
7
11
|
*/
|
|
8
12
|
entryPoint: string;
|
|
9
13
|
/**
|
|
10
14
|
* Output directory for the bundle
|
|
15
|
+
* Directory where the bundled file will be written
|
|
11
16
|
*/
|
|
12
17
|
outdir?: string;
|
|
13
18
|
/**
|
|
14
19
|
* Output filename for the bundle
|
|
20
|
+
* Full path to the output file, overrides outdir if specified
|
|
15
21
|
*/
|
|
16
22
|
outfile?: string;
|
|
17
23
|
/**
|
|
18
|
-
* Bundle format
|
|
24
|
+
* Bundle format
|
|
25
|
+
* iife: Immediately Invoked Function Expression
|
|
26
|
+
* cjs: CommonJS
|
|
27
|
+
* esm: ECMAScript Modules
|
|
19
28
|
*/
|
|
20
29
|
format?: "iife" | "cjs" | "esm";
|
|
21
30
|
/**
|
|
22
|
-
* Target environment
|
|
31
|
+
* Target environment
|
|
32
|
+
* Examples: 'node16', 'node18', 'es2020'
|
|
23
33
|
*/
|
|
24
34
|
target?: string | string[];
|
|
25
35
|
/**
|
|
@@ -28,32 +38,61 @@ export interface BundleProps {
|
|
|
28
38
|
minify?: boolean;
|
|
29
39
|
/**
|
|
30
40
|
* Whether to generate sourcemaps
|
|
41
|
+
* inline: Include sourcemap in bundle
|
|
42
|
+
* external: Generate separate .map file
|
|
43
|
+
* both: Generate both inline and external
|
|
31
44
|
*/
|
|
32
45
|
sourcemap?: boolean | "inline" | "external" | "both";
|
|
33
46
|
/**
|
|
34
47
|
* External packages to exclude from bundle
|
|
48
|
+
* Array of package names to mark as external
|
|
35
49
|
*/
|
|
36
50
|
external?: string[];
|
|
37
51
|
/**
|
|
38
|
-
* Platform to target
|
|
52
|
+
* Platform to target
|
|
53
|
+
* browser: Browser environment
|
|
54
|
+
* node: Node.js environment
|
|
55
|
+
* neutral: Platform-agnostic
|
|
39
56
|
*/
|
|
40
57
|
platform?: "browser" | "node" | "neutral";
|
|
41
58
|
/**
|
|
42
59
|
* Additional esbuild options
|
|
60
|
+
* Any other valid esbuild BuildOptions
|
|
43
61
|
*/
|
|
44
62
|
options?: Partial<esbuild.BuildOptions>;
|
|
45
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Output returned after bundle creation/update
|
|
66
|
+
*/
|
|
46
67
|
export interface Bundle extends Resource<"esbuild::Bundle"> {
|
|
47
68
|
/**
|
|
48
69
|
* Path to the bundled file
|
|
70
|
+
* Absolute or relative path to the generated bundle
|
|
49
71
|
*/
|
|
50
72
|
path: string;
|
|
51
73
|
/**
|
|
52
74
|
* SHA-256 hash of the bundle contents
|
|
75
|
+
* Used for cache busting and content verification
|
|
53
76
|
*/
|
|
54
77
|
hash: string;
|
|
55
78
|
}
|
|
56
|
-
|
|
79
|
+
/**
|
|
80
|
+
* esbuild Bundle Resource
|
|
81
|
+
*
|
|
82
|
+
* Creates and manages bundled JavaScript/TypeScript files using esbuild.
|
|
83
|
+
* Supports various output formats, sourcemaps, and platform targets.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* // Bundle a TypeScript file for Node.js
|
|
87
|
+
* const bundle = await Bundle("handler", {
|
|
88
|
+
* entryPoint: "src/handler.ts",
|
|
89
|
+
* outdir: ".alchemy/.out",
|
|
90
|
+
* format: "esm",
|
|
91
|
+
* platform: "node",
|
|
92
|
+
* target: "node18"
|
|
93
|
+
* });
|
|
94
|
+
*/
|
|
95
|
+
export declare const Bundle: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<Bundle>, id: string, props: BundleProps) => Promise<Bundle>);
|
|
57
96
|
export declare function bundle(props: BundleProps): Promise<esbuild.BuildResult<{
|
|
58
97
|
bundle: boolean;
|
|
59
98
|
splitting?: boolean;
|
package/lib/esbuild/bundle.js
CHANGED
|
@@ -3,6 +3,22 @@ import crypto from "node:crypto";
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { Resource } from "../resource";
|
|
6
|
+
/**
|
|
7
|
+
* esbuild Bundle Resource
|
|
8
|
+
*
|
|
9
|
+
* Creates and manages bundled JavaScript/TypeScript files using esbuild.
|
|
10
|
+
* Supports various output formats, sourcemaps, and platform targets.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Bundle a TypeScript file for Node.js
|
|
14
|
+
* const bundle = await Bundle("handler", {
|
|
15
|
+
* entryPoint: "src/handler.ts",
|
|
16
|
+
* outdir: ".alchemy/.out",
|
|
17
|
+
* format: "esm",
|
|
18
|
+
* platform: "node",
|
|
19
|
+
* target: "node18"
|
|
20
|
+
* });
|
|
21
|
+
*/
|
|
6
22
|
export const Bundle = Resource("esbuild::Bundle", {
|
|
7
23
|
alwaysUpdate: true,
|
|
8
24
|
}, async function (id, props) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collection of files with their contents
|
|
3
|
+
*/
|
|
4
|
+
export type FileCollection = {
|
|
5
|
+
/**
|
|
6
|
+
* Type identifier for FileCollection
|
|
7
|
+
*/
|
|
8
|
+
type: "fs::FileCollection";
|
|
9
|
+
/**
|
|
10
|
+
* Map of relative paths to file contents
|
|
11
|
+
*/
|
|
12
|
+
files: {
|
|
13
|
+
[relativePath: string]: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare function isFileCollection(value: unknown): value is FileCollection;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference to a file in the filesystem
|
|
3
|
+
*/
|
|
4
|
+
export type FileRef = {
|
|
5
|
+
/**
|
|
6
|
+
* Type identifier for FileRef
|
|
7
|
+
*/
|
|
8
|
+
kind: "fs::FileRef";
|
|
9
|
+
/**
|
|
10
|
+
* Path to the file
|
|
11
|
+
*/
|
|
12
|
+
path: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function isFileRef(value: unknown): value is FileRef;
|
package/lib/fs/file.d.ts
CHANGED
|
@@ -1,13 +1,86 @@
|
|
|
1
1
|
import type { Context } from "../context";
|
|
2
2
|
import { Resource } from "../resource";
|
|
3
|
+
import type { FileCollection } from "./file-collection";
|
|
4
|
+
import type { FileRef } from "./file-ref";
|
|
5
|
+
declare module "../alchemy" {
|
|
6
|
+
interface Alchemy {
|
|
7
|
+
/**
|
|
8
|
+
* Creates a reference to a file in the filesystem.
|
|
9
|
+
* Used in template string interpolation to include file contents,
|
|
10
|
+
* commonly for documentation generation.
|
|
11
|
+
*
|
|
12
|
+
* @param path Path to the file
|
|
13
|
+
* @returns Promise resolving to a FileRef
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Include a file in documentation generation
|
|
17
|
+
* await Document("api-docs", {
|
|
18
|
+
* prompt: await alchemy`
|
|
19
|
+
* Generate docs using the contents of:
|
|
20
|
+
* ${alchemy.file("./README.md")}
|
|
21
|
+
* `
|
|
22
|
+
* });
|
|
23
|
+
*/
|
|
24
|
+
file(path: string): Promise<FileRef>;
|
|
25
|
+
/**
|
|
26
|
+
* Creates a collection of files with their contents.
|
|
27
|
+
* Used in template string interpolation to include multiple file contents,
|
|
28
|
+
* commonly for bulk documentation generation.
|
|
29
|
+
*
|
|
30
|
+
* @param paths Array of file paths to include in collection
|
|
31
|
+
* @returns Promise resolving to a FileCollection
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Include multiple source files in documentation generation
|
|
35
|
+
* await Document("provider-docs", {
|
|
36
|
+
* prompt: await alchemy`
|
|
37
|
+
* Generate comprehensive docs for these files:
|
|
38
|
+
* ${alchemy.files([
|
|
39
|
+
* "src/types.ts",
|
|
40
|
+
* "src/resource.ts",
|
|
41
|
+
* "src/provider.ts"
|
|
42
|
+
* ])}
|
|
43
|
+
* `
|
|
44
|
+
* });
|
|
45
|
+
*/
|
|
46
|
+
files(paths: string[]): Promise<FileCollection>;
|
|
47
|
+
files(path: string, ...paths: string[]): Promise<FileCollection>;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Base file resource type
|
|
52
|
+
*/
|
|
3
53
|
export interface File extends Resource<"fs::File"> {
|
|
54
|
+
/**
|
|
55
|
+
* Path to the file
|
|
56
|
+
*/
|
|
4
57
|
path: string;
|
|
58
|
+
/**
|
|
59
|
+
* Content of the file
|
|
60
|
+
*/
|
|
5
61
|
content: string;
|
|
6
62
|
}
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
63
|
+
/**
|
|
64
|
+
* File Resource
|
|
65
|
+
*
|
|
66
|
+
* Creates and manages files in the filesystem with automatic directory creation
|
|
67
|
+
* and proper cleanup on deletion.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* // Create a simple text file
|
|
71
|
+
* const config = await File("config.txt", {
|
|
72
|
+
* path: "config.txt",
|
|
73
|
+
* content: "some configuration data"
|
|
74
|
+
* });
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* // Create a file in a nested directory
|
|
78
|
+
* const log = await File("logs/app.log", {
|
|
79
|
+
* path: "logs/app.log",
|
|
80
|
+
* content: "application log entry"
|
|
81
|
+
* });
|
|
82
|
+
*/
|
|
83
|
+
export declare const File: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<File>, id: string, props: {
|
|
11
84
|
path: string;
|
|
12
85
|
content: string;
|
|
13
|
-
}) =>
|
|
86
|
+
}) => Promise<File>);
|
package/lib/fs/file.js
CHANGED
|
@@ -2,7 +2,43 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { Resource } from "../resource";
|
|
4
4
|
import { ignore } from "../util/ignore";
|
|
5
|
-
|
|
5
|
+
import { alchemy } from "../alchemy";
|
|
6
|
+
alchemy.file = async (path) => ({
|
|
7
|
+
kind: "fs::FileRef",
|
|
8
|
+
path,
|
|
9
|
+
});
|
|
10
|
+
alchemy.files = async (...args) => {
|
|
11
|
+
const paths = typeof args[0] === "string" ? args : args[0];
|
|
12
|
+
return {
|
|
13
|
+
type: "fs::FileCollection",
|
|
14
|
+
files: Object.fromEntries(await Promise.all(paths.map(async (path) => [
|
|
15
|
+
path,
|
|
16
|
+
await fs.promises.readFile(path, "utf-8"),
|
|
17
|
+
]))),
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* File Resource
|
|
22
|
+
*
|
|
23
|
+
* Creates and manages files in the filesystem with automatic directory creation
|
|
24
|
+
* and proper cleanup on deletion.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Create a simple text file
|
|
28
|
+
* const config = await File("config.txt", {
|
|
29
|
+
* path: "config.txt",
|
|
30
|
+
* content: "some configuration data"
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* // Create a file in a nested directory
|
|
35
|
+
* const log = await File("logs/app.log", {
|
|
36
|
+
* path: "logs/app.log",
|
|
37
|
+
* content: "application log entry"
|
|
38
|
+
* });
|
|
39
|
+
*/
|
|
40
|
+
export const File = Resource("fs::File", async function (id, props) {
|
|
41
|
+
const filePath = props?.path ?? id;
|
|
6
42
|
if (this.phase === "delete") {
|
|
7
43
|
await ignore("ENOENT", async () => fs.promises.unlink(filePath));
|
|
8
44
|
return this.destroy();
|
|
@@ -11,10 +47,10 @@ export const File = Resource("fs::File", async function (id, { path: filePath, c
|
|
|
11
47
|
await fs.promises.mkdir(path.dirname(filePath), {
|
|
12
48
|
recursive: true,
|
|
13
49
|
});
|
|
14
|
-
await fs.promises.writeFile(filePath, content);
|
|
50
|
+
await fs.promises.writeFile(filePath, props.content);
|
|
15
51
|
}
|
|
16
52
|
return this({
|
|
17
53
|
path: filePath,
|
|
18
|
-
content,
|
|
54
|
+
content: props.content,
|
|
19
55
|
});
|
|
20
56
|
});
|