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.
- package/bin/alchemy.js +1 -1
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +15 -0
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.js +1 -1
- package/lib/apply.js.map +1 -1
- package/lib/cloudflare/compatibility-date.gen.d.ts +1 -1
- package/lib/cloudflare/compatibility-date.gen.js +1 -1
- package/lib/cloudflare/index.d.ts +2 -0
- package/lib/cloudflare/index.d.ts.map +1 -1
- package/lib/cloudflare/index.js +2 -0
- package/lib/cloudflare/index.js.map +1 -1
- package/lib/cloudflare/rule.d.ts +462 -0
- package/lib/cloudflare/rule.d.ts.map +1 -0
- package/lib/cloudflare/rule.js +2 -0
- package/lib/cloudflare/rule.js.map +1 -0
- package/lib/cloudflare/ruleset.d.ts +169 -0
- package/lib/cloudflare/ruleset.d.ts.map +1 -0
- package/lib/cloudflare/ruleset.js +118 -0
- package/lib/cloudflare/ruleset.js.map +1 -0
- package/lib/state/instrumented-state-store.d.ts.map +1 -1
- package/lib/state/instrumented-state-store.js +14 -5
- package/lib/state/instrumented-state-store.js.map +1 -1
- package/package.json +1 -1
- package/src/alchemy.ts +17 -0
- package/src/apply.ts +1 -1
- package/src/cloudflare/compatibility-date.gen.ts +1 -1
- package/src/cloudflare/index.ts +2 -0
- package/src/cloudflare/rule.ts +531 -0
- package/src/cloudflare/ruleset.ts +257 -0
- package/src/state/instrumented-state-store.ts +17 -9
|
@@ -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;
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
|
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":"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,OAAO,MAAM,EAAE,EAAE
|
|
1
|
+
{"version":3,"file":"instrumented-state-store.js","sourceRoot":"","sources":["../../src/state/instrumented-state-store.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
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
package/src/cloudflare/index.ts
CHANGED
|
@@ -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";
|