alchemy 0.59.2 → 0.60.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,118 @@
1
+ import { Resource } from "../resource.js";
2
+ import { handleApiError } from "./api-error.js";
3
+ import { createCloudflareApi, } from "./api.js";
4
+ import { findZoneForHostname } from "./zone.js";
5
+ /**
6
+ * Cloudflare Ruleset manages rules within a specific phase's entrypoint ruleset.
7
+ * This resource allows you to configure rules for various phases like rate limiting,
8
+ * firewall, transforms, and more.
9
+ *
10
+ * @example
11
+ * // Create a rate limiting ruleset
12
+ * const rateLimits = await Ruleset("api-rate-limits", {
13
+ * zone: "example.com",
14
+ * phase: "http_ratelimit",
15
+ * rules: [
16
+ * {
17
+ * description: "API rate limit",
18
+ * expression: "(http.request.uri.path wildcard r\"/api/*\")",
19
+ * action: "block",
20
+ * ratelimit: {
21
+ * characteristics: ["ip.src"],
22
+ * period: 60,
23
+ * requests_per_period: 100,
24
+ * mitigation_timeout: 600
25
+ * }
26
+ * }
27
+ * ]
28
+ * });
29
+ *
30
+ * @example
31
+ * // Create a custom firewall ruleset
32
+ * const firewall = await Ruleset("custom-firewall", {
33
+ * zone: myZone,
34
+ * phase: "http_request_firewall_custom",
35
+ * rules: [
36
+ * {
37
+ * description: "Block bad IPs",
38
+ * expression: "ip.src in {1.2.3.4 1.2.3.5}",
39
+ * action: "block"
40
+ * },
41
+ * {
42
+ * description: "Challenge suspicious requests",
43
+ * expression: "cf.threat_score > 50",
44
+ * action: "challenge"
45
+ * }
46
+ * ]
47
+ * });
48
+ *
49
+ * @example
50
+ * // Create a transform ruleset for request headers
51
+ * const transforms = await Ruleset("header-transforms", {
52
+ * zone: "example.com",
53
+ * phase: "http_request_transform",
54
+ * rules: [
55
+ * {
56
+ * description: "Add custom header",
57
+ * expression: "true",
58
+ * action: "rewrite",
59
+ * action_parameters: {
60
+ * headers: {
61
+ * "X-Custom-Header": { value: "my-value" }
62
+ * }
63
+ * }
64
+ * }
65
+ * ]
66
+ * });
67
+ */
68
+ export const Ruleset = Resource("cloudflare::Ruleset", async function (_id, props) {
69
+ const api = await createCloudflareApi(props);
70
+ // Default phase to http_ratelimit if not specified
71
+ const phase = props.phase || "http_ratelimit";
72
+ // Get zone ID from zone name
73
+ const zoneId = typeof props.zone === "string"
74
+ ? (await findZoneForHostname(api, props.zone)).zoneId
75
+ : props.zone.id;
76
+ if (this.phase === "delete") {
77
+ // Overwrite entire entrypoint with empty rules
78
+ await updateRuleset(api, zoneId, phase, { rules: [] });
79
+ return this.destroy();
80
+ }
81
+ // Overwrite entire entrypoint with only the provided rules
82
+ const result = await updateRuleset(api, zoneId, phase, {
83
+ rules: props.rules,
84
+ ...(props.name && { name: props.name }),
85
+ ...(props.description && { description: props.description }),
86
+ });
87
+ // Transform response back to our format
88
+ return this({
89
+ id: result.id,
90
+ zoneId,
91
+ phase: props.phase,
92
+ name: result.name || props.name || `${phase} ruleset`,
93
+ description: result.description || props.description,
94
+ rules: result.rules ?? [],
95
+ lastUpdated: result.last_updated,
96
+ version: result.version,
97
+ });
98
+ });
99
+ /**
100
+ * Update a ruleset for a specific zone and phase
101
+ * Ensures consistent error handling on non-2xx responses
102
+ */
103
+ export async function updateRuleset(api, zoneId,
104
+ /** Phase of the ruleset */
105
+ phase, body) {
106
+ const response = await api.put(`/zones/${zoneId}/rulesets/phases/${phase}/entrypoint`, body);
107
+ if (!response.ok) {
108
+ await handleApiError(response, "updating", "ruleset", `${zoneId}/${phase}`);
109
+ }
110
+ const data = (await response.json());
111
+ return data.result;
112
+ }
113
+ export async function getRuleset(api, zoneId, phase) {
114
+ const response = await api.get(`/zones/${zoneId}/rulesets/phases/${phase}/entrypoint`);
115
+ const data = (await response.json());
116
+ return data.result;
117
+ }
118
+ //# sourceMappingURL=ruleset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ruleset.js","sourceRoot":"","sources":["../../src/cloudflare/ruleset.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"instrumented-state-store.d.ts","sourceRoot":"","sources":["../../src/state/instrumented-state-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAIpE,qBAAa,sBAAsB,CAAC,CAAC,SAAS,UAAU,CACtD,YAAW,UAAU;IAErB,gBAAgB;IAChB,SAAS,CAAC,EAAE,CAAC,CAAC;IACd,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmB;IACnD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB;YAMvD,iBAAiB;IAkBzB,IAAI;IASJ,MAAM;IASN,IAAI;IAMJ,KAAK;IAML,GAAG,CAAC,GAAG,EAAE,MAAM;IAMf,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE;IAMtB,GAAG;IAMH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;IAM7B,MAAM,CAAC,GAAG,EAAE,MAAM;CAMzB"}
1
+ {"version":3,"file":"instrumented-state-store.d.ts","sourceRoot":"","sources":["../../src/state/instrumented-state-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAIpE,qBAAa,sBAAsB,CAAC,CAAC,SAAS,UAAU,CACtD,YAAW,UAAU;IAErB,gBAAgB;IAChB,SAAS,CAAC,EAAE,CAAC,CAAC;IACd,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmB;IACnD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;gBAE7B,UAAU,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB;YAMvD,iBAAiB;IA0BzB,IAAI;IASJ,MAAM;IASN,IAAI;IAMJ,KAAK;IAML,GAAG,CAAC,GAAG,EAAE,MAAM;IAMf,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE;IAMtB,GAAG;IAMH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK;IAM7B,MAAM,CAAC,GAAG,EAAE,MAAM;CAMzB"}
@@ -13,16 +13,25 @@ export class InstrumentedStateStore {
13
13
  async callWithTelemetry(event, fn) {
14
14
  const start = performance.now();
15
15
  let error;
16
- return await fn()
17
- .catch((err) => (error = err))
18
- .finally(() => {
16
+ try {
17
+ return await fn();
18
+ }
19
+ catch (err) {
20
+ error = err;
21
+ throw err;
22
+ }
23
+ finally {
19
24
  this.telemetryClient.record({
20
25
  event,
21
26
  stateStoreClass: this.stateStoreClass,
22
27
  elapsed: performance.now() - start,
23
- error: error instanceof Error ? error : new Error(String(error)),
28
+ error: error instanceof Error
29
+ ? error
30
+ : error
31
+ ? new Error(String(error))
32
+ : undefined,
24
33
  });
25
- });
34
+ }
26
35
  }
27
36
  async init() {
28
37
  if (this.stateStore.init == null) {
@@ -1 +1 @@
1
- {"version":3,"file":"instrumented-state-store.js","sourceRoot":"","sources":["../../src/state/instrumented-state-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instrumented-state-store.js","sourceRoot":"","sources":["../../src/state/instrumented-state-store.ts"],"names":[],"mappings":"AAIA,iDAAiD;AACjD,MAAM,OAAO,sBAAsB;IAGjC,gBAAgB;IAChB,SAAS,CAAK;IACG,UAAU,CAAa;IACvB,eAAe,CAAmB;IAClC,eAAe,CAAS;IAEzC,YAAY,UAAsB,EAAE,eAAiC;QACnE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,eAAe,GAAG,UAAU,CAAC,WAAW,CAAC,IAAI,CAAC;IACrD,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAC7B,KAAyC,EACzC,EAAoB;QAEpB,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,IAAI,KAAc,CAAC;QACnB,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,KAAK,GAAG,GAAG,CAAC;YACZ,MAAM,GAAG,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;gBAC1B,KAAK;gBACL,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,OAAO,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK;gBAClC,KAAK,EACH,KAAK,YAAY,KAAK;oBACpB,CAAC,CAAC,KAAK;oBACP,CAAC,CAAC,KAAK;wBACL,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;wBAC1B,CAAC,CAAC,SAAS;aAClB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACjC,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,iBAAiB,CAC1B,iBAAiB,EACjB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAC3C,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,MAAM;QACV,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;YACnC,OAAO;QACT,CAAC;QACD,MAAM,IAAI,CAAC,iBAAiB,CAC1B,mBAAmB,EACnB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAC7C,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI;QACR,OAAO,MAAM,IAAI,CAAC,iBAAiB,CACjC,iBAAiB,EACjB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAC3C,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,KAAK;QACT,OAAO,MAAM,IAAI,CAAC,iBAAiB,CACjC,kBAAkB,EAClB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAC5C,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,OAAO,MAAM,IAAI,CAAC,iBAAiB,CACjC,gBAAgB,EAChB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAC/C,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,QAAQ,CAAC,GAAa;QAC1B,OAAO,MAAM,IAAI,CAAC,iBAAiB,CACjC,qBAAqB,EACrB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CACpD,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,GAAG;QACP,OAAO,MAAM,IAAI,CAAC,iBAAiB,CACjC,gBAAgB,EAChB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAC1C,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAY;QACjC,MAAM,IAAI,CAAC,iBAAiB,CAC1B,gBAAgB,EAChB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,EAAE,KAAK,CAAC,CACtD,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,MAAM,CAAC,GAAW;QACtB,MAAM,IAAI,CAAC,iBAAiB,CAC1B,mBAAmB,EACnB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAClD,CAAC;IACJ,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "alchemy",
3
- "version": "0.59.2",
3
+ "version": "0.60.0",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Sam Goodwin <sam@alchemy.run>",
6
6
  "homepage": "https://alchemy.run",
package/src/alchemy.ts CHANGED
@@ -156,6 +156,23 @@ async function _alchemy(
156
156
  ...cliOptions,
157
157
  ...options,
158
158
  };
159
+ if (
160
+ mergedOptions.stateStore === undefined &&
161
+ process.env.CI &&
162
+ process.env.ALCHEMY_CI_STATE_STORE_CHECK !== "false"
163
+ ) {
164
+ throw new Error(`You are running Alchemy in a CI environment with the default local state store.
165
+ This can lead to orphaned infrastructure and is rarely what you want to do.
166
+
167
+ Instead, you should choose a persistent state store:
168
+ 1. CloudflareStateStore (https://alchemy.run/concepts/state/#cloudflare-state-store)
169
+ 2. S3StateStore (https://alchemy.run/providers/aws/s3-state-store/)
170
+
171
+ You can read more about State and State Stores here: https://alchemy.run/concepts/state/#customizing-state-storage
172
+
173
+ If this is a mistake, you can disable this check by setting the ALCHEMY_CI_STATE_STORE_CHECK=false.
174
+ `);
175
+ }
159
176
 
160
177
  const phase = isRuntime ? "read" : (mergedOptions?.phase ?? "up");
161
178
  const telemetryClient =
package/src/apply.ts CHANGED
@@ -93,7 +93,7 @@ async function _apply<Out extends Resource>(
93
93
  },
94
94
  // deps: [...deps],
95
95
  // there are no "old props" on initialization
96
- props: undefined,
96
+ props: {},
97
97
  };
98
98
  await scope.state.set(resource[ResourceID], state);
99
99
  }
@@ -4,4 +4,4 @@
4
4
  /**
5
5
  * The default Cloudflare Workers compatibility date, set based on the latest workerd release at the time of build.
6
6
  */
7
- export const DEFAULT_COMPATIBILITY_DATE = "2025-08-07";
7
+ export const DEFAULT_COMPATIBILITY_DATE = "2025-08-10";
@@ -44,6 +44,8 @@ export * from "./react-router/react-router.ts";
44
44
  export * from "./redirect-rule.ts";
45
45
  export * from "./redwood/redwood.ts";
46
46
  export * from "./route.ts";
47
+ export * from "./ruleset.ts";
48
+ export * from "./rule.ts";
47
49
  export * from "./secret-key.ts";
48
50
  export * from "./secret.ts";
49
51
  export * from "./secrets-store.ts";