alchemy 0.15.12 → 0.15.13
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/upstash/api.d.ts +52 -0
- package/lib/upstash/api.d.ts.map +1 -0
- package/lib/upstash/api.js +74 -0
- package/lib/upstash/api.js.map +1 -0
- package/lib/upstash/error.d.ts +22 -0
- package/lib/upstash/error.d.ts.map +1 -0
- package/lib/upstash/error.js +27 -0
- package/lib/upstash/error.js.map +1 -0
- package/lib/upstash/index.d.ts +4 -0
- package/lib/upstash/index.d.ts.map +1 -0
- package/lib/upstash/index.js +4 -0
- package/lib/upstash/index.js.map +1 -0
- package/lib/upstash/redis.d.ts +202 -0
- package/lib/upstash/redis.d.ts.map +1 -0
- package/lib/upstash/redis.js +178 -0
- package/lib/upstash/redis.js.map +1 -0
- package/package.json +2 -1
- package/src/upstash/api.ts +105 -0
- package/src/upstash/error.ts +28 -0
- package/src/upstash/index.ts +3 -0
- package/src/upstash/redis.ts +421 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Secret } from "../secret.js";
|
|
2
|
+
/**
|
|
3
|
+
* Options for Upstash API requests
|
|
4
|
+
*/
|
|
5
|
+
export interface UpstashApiOptions {
|
|
6
|
+
/**
|
|
7
|
+
* API key to use (overrides environment variable)
|
|
8
|
+
*/
|
|
9
|
+
apiKey?: Secret;
|
|
10
|
+
/**
|
|
11
|
+
* Email to use (overrides environment variable)
|
|
12
|
+
*/
|
|
13
|
+
email?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Minimal API client using raw fetch
|
|
17
|
+
*/
|
|
18
|
+
export declare class UpstashApi {
|
|
19
|
+
/** Base URL for API */
|
|
20
|
+
readonly baseUrl: string;
|
|
21
|
+
/** API key */
|
|
22
|
+
readonly apiKey: string;
|
|
23
|
+
/** Email */
|
|
24
|
+
readonly email: string;
|
|
25
|
+
/**
|
|
26
|
+
* Create a new API client
|
|
27
|
+
*
|
|
28
|
+
* @param options API options
|
|
29
|
+
*/
|
|
30
|
+
constructor(options?: UpstashApiOptions);
|
|
31
|
+
/**
|
|
32
|
+
* Make a request to the API
|
|
33
|
+
*
|
|
34
|
+
* @param path API path (without base URL)
|
|
35
|
+
* @param init Fetch init options
|
|
36
|
+
* @returns Raw Response object from fetch
|
|
37
|
+
*/
|
|
38
|
+
fetch(path: string, init?: RequestInit): Promise<Response>;
|
|
39
|
+
/**
|
|
40
|
+
* Helper for GET requests
|
|
41
|
+
*/
|
|
42
|
+
get(path: string, init?: RequestInit): Promise<Response>;
|
|
43
|
+
/**
|
|
44
|
+
* Helper for POST requests
|
|
45
|
+
*/
|
|
46
|
+
post(path: string, body: any, init?: RequestInit): Promise<Response>;
|
|
47
|
+
/**
|
|
48
|
+
* Helper for DELETE requests
|
|
49
|
+
*/
|
|
50
|
+
delete(path: string, init?: RequestInit): Promise<Response>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/upstash/api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,uBAAuB;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB,cAAc;IACd,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,YAAY;IACZ,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB;;;;OAIG;gBACS,OAAO,GAAE,iBAAsB;IAe3C;;;;;;OAMG;IACG,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAmBpE;;OAEG;IACG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;IAIlE;;OAEG;IACG,IAAI,CACR,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,GAAG,EACT,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,QAAQ,CAAC;IAQpB;;OAEG;IACG,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,WAAgB,GAAG,OAAO,CAAC,QAAQ,CAAC;CAGtE"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal API client using raw fetch
|
|
3
|
+
*/
|
|
4
|
+
export class UpstashApi {
|
|
5
|
+
/** Base URL for API */
|
|
6
|
+
baseUrl;
|
|
7
|
+
/** API key */
|
|
8
|
+
apiKey;
|
|
9
|
+
/** Email */
|
|
10
|
+
email;
|
|
11
|
+
/**
|
|
12
|
+
* Create a new API client
|
|
13
|
+
*
|
|
14
|
+
* @param options API options
|
|
15
|
+
*/
|
|
16
|
+
constructor(options = {}) {
|
|
17
|
+
this.baseUrl = "https://api.upstash.com/v2";
|
|
18
|
+
this.apiKey =
|
|
19
|
+
options.apiKey?.unencrypted ?? process.env.UPSTASH_API_KEY ?? "";
|
|
20
|
+
this.email = options.email ?? process.env.UPSTASH_EMAIL ?? "";
|
|
21
|
+
if (!this.apiKey) {
|
|
22
|
+
throw new Error("UPSTASH_API_KEY environment variable is required");
|
|
23
|
+
}
|
|
24
|
+
if (!this.email) {
|
|
25
|
+
throw new Error("UPSTASH_EMAIL environment variable is required");
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Make a request to the API
|
|
30
|
+
*
|
|
31
|
+
* @param path API path (without base URL)
|
|
32
|
+
* @param init Fetch init options
|
|
33
|
+
* @returns Raw Response object from fetch
|
|
34
|
+
*/
|
|
35
|
+
async fetch(path, init = {}) {
|
|
36
|
+
const headers = {
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
Authorization: `Basic ${btoa(`${this.email}:${this.apiKey}`)}`,
|
|
39
|
+
};
|
|
40
|
+
if (init.headers) {
|
|
41
|
+
const initHeaders = init.headers;
|
|
42
|
+
Object.keys(initHeaders).forEach((key) => {
|
|
43
|
+
headers[key] = initHeaders[key];
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return fetch(`${this.baseUrl}${path}`, {
|
|
47
|
+
...init,
|
|
48
|
+
headers,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Helper for GET requests
|
|
53
|
+
*/
|
|
54
|
+
async get(path, init = {}) {
|
|
55
|
+
return this.fetch(path, { ...init, method: "GET" });
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Helper for POST requests
|
|
59
|
+
*/
|
|
60
|
+
async post(path, body, init = {}) {
|
|
61
|
+
return this.fetch(path, {
|
|
62
|
+
...init,
|
|
63
|
+
method: "POST",
|
|
64
|
+
body: JSON.stringify(body),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Helper for DELETE requests
|
|
69
|
+
*/
|
|
70
|
+
async delete(path, init = {}) {
|
|
71
|
+
return this.fetch(path, { ...init, method: "DELETE" });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/upstash/api.ts"],"names":[],"mappings":"AAiBA;;GAEG;AACH,MAAM,OAAO,UAAU;IACrB,uBAAuB;IACd,OAAO,CAAS;IAEzB,cAAc;IACL,MAAM,CAAS;IAExB,YAAY;IACH,KAAK,CAAS;IAEvB;;;;OAIG;IACH,YAAY,UAA6B,EAAE;QACzC,IAAI,CAAC,OAAO,GAAG,4BAA4B,CAAC;QAC5C,IAAI,CAAC,MAAM;YACT,OAAO,CAAC,MAAM,EAAE,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC;QACnE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC;QAE9D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;QACtE,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CAAC,IAAY,EAAE,OAAoB,EAAE;QAC9C,MAAM,OAAO,GAA2B;YACtC,cAAc,EAAE,kBAAkB;YAClC,aAAa,EAAE,SAAS,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE;SAC/D,CAAC;QAEF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,WAAW,GAAG,IAAI,CAAC,OAAiC,CAAC;YAC3D,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBACvC,OAAO,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrC,GAAG,IAAI;YACP,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,IAAY,EAAE,OAAoB,EAAE;QAC5C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CACR,IAAY,EACZ,IAAS,EACT,OAAoB,EAAE;QAEtB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE;YACtB,GAAG,IAAI;YACP,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,OAAoB,EAAE;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;IACzD,CAAC;CACF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error class for Upstash API errors
|
|
3
|
+
*/
|
|
4
|
+
export declare class UpstashError extends Error {
|
|
5
|
+
/**
|
|
6
|
+
* HTTP status code
|
|
7
|
+
*/
|
|
8
|
+
statusCode: number;
|
|
9
|
+
/**
|
|
10
|
+
* Original response object
|
|
11
|
+
*/
|
|
12
|
+
response: Response;
|
|
13
|
+
/**
|
|
14
|
+
* Create a new Upstash error
|
|
15
|
+
*
|
|
16
|
+
* @param message Error message
|
|
17
|
+
* @param statusCode HTTP status code
|
|
18
|
+
* @param response Original response object
|
|
19
|
+
*/
|
|
20
|
+
constructor(message: string, statusCode: number, response: Response);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../src/upstash/error.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;IACrC;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,QAAQ,EAAE,QAAQ,CAAC;IAEnB;;;;;;OAMG;gBACS,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;CAMpE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error class for Upstash API errors
|
|
3
|
+
*/
|
|
4
|
+
export class UpstashError extends Error {
|
|
5
|
+
/**
|
|
6
|
+
* HTTP status code
|
|
7
|
+
*/
|
|
8
|
+
statusCode;
|
|
9
|
+
/**
|
|
10
|
+
* Original response object
|
|
11
|
+
*/
|
|
12
|
+
response;
|
|
13
|
+
/**
|
|
14
|
+
* Create a new Upstash error
|
|
15
|
+
*
|
|
16
|
+
* @param message Error message
|
|
17
|
+
* @param statusCode HTTP status code
|
|
18
|
+
* @param response Original response object
|
|
19
|
+
*/
|
|
20
|
+
constructor(message, statusCode, response) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "UpstashError";
|
|
23
|
+
this.statusCode = statusCode;
|
|
24
|
+
this.response = response;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/upstash/error.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,YAAa,SAAQ,KAAK;IACrC;;OAEG;IACH,UAAU,CAAS;IAEnB;;OAEG;IACH,QAAQ,CAAW;IAEnB;;;;;;OAMG;IACH,YAAY,OAAe,EAAE,UAAkB,EAAE,QAAkB;QACjE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/upstash/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/upstash/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import type { Context } from "../context.js";
|
|
2
|
+
import { Resource } from "../resource.js";
|
|
3
|
+
import type { Secret } from "../secret.js";
|
|
4
|
+
import { UpstashApi } from "./api.js";
|
|
5
|
+
/**
|
|
6
|
+
* Available regions for Upstash Redis databases
|
|
7
|
+
*/
|
|
8
|
+
export type UpstashRegion = "us-east-1" | "us-west-1" | "us-west-2" | "eu-west-1" | "eu-central-1" | "ap-southeast-1" | "ap-southeast-2" | "ap-northeast-1" | "sa-east-1";
|
|
9
|
+
/**
|
|
10
|
+
* Properties for creating or updating an UpstashRedis database
|
|
11
|
+
*/
|
|
12
|
+
export interface UpstashRedisProps {
|
|
13
|
+
/**
|
|
14
|
+
* Name of the database
|
|
15
|
+
*/
|
|
16
|
+
name: string;
|
|
17
|
+
/**
|
|
18
|
+
* Primary region for the database
|
|
19
|
+
*/
|
|
20
|
+
primaryRegion: UpstashRegion;
|
|
21
|
+
/**
|
|
22
|
+
* Read regions for the database
|
|
23
|
+
*/
|
|
24
|
+
readRegions?: UpstashRegion[];
|
|
25
|
+
/**
|
|
26
|
+
* Monthly budget for the database
|
|
27
|
+
*/
|
|
28
|
+
budget?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Whether to enable eviction for the database
|
|
31
|
+
*/
|
|
32
|
+
eviction?: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* API key to use (overrides environment variable)
|
|
35
|
+
*/
|
|
36
|
+
apiKey?: Secret;
|
|
37
|
+
/**
|
|
38
|
+
* Email to use (overrides environment variable)
|
|
39
|
+
*/
|
|
40
|
+
email?: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Output returned after UpstashRedis creation/update
|
|
44
|
+
*/
|
|
45
|
+
export interface UpstashRedis extends Resource<"upstash::Redis">, UpstashRedisProps {
|
|
46
|
+
/**
|
|
47
|
+
* ID of the database
|
|
48
|
+
*/
|
|
49
|
+
id: string;
|
|
50
|
+
/**
|
|
51
|
+
* Type of the database in terms of pricing model
|
|
52
|
+
*/
|
|
53
|
+
databaseType: string;
|
|
54
|
+
/**
|
|
55
|
+
* Region where database is hosted
|
|
56
|
+
*/
|
|
57
|
+
region: "global";
|
|
58
|
+
/**
|
|
59
|
+
* Database port for clients to connect
|
|
60
|
+
*/
|
|
61
|
+
port: number;
|
|
62
|
+
/**
|
|
63
|
+
* Creation time of the database as Unix time
|
|
64
|
+
*/
|
|
65
|
+
createdAt: number;
|
|
66
|
+
/**
|
|
67
|
+
* State of database (active or deleted)
|
|
68
|
+
*/
|
|
69
|
+
state: string;
|
|
70
|
+
/**
|
|
71
|
+
* Password of the database
|
|
72
|
+
*/
|
|
73
|
+
password: Secret;
|
|
74
|
+
/**
|
|
75
|
+
* Email or team id of the owner of the database
|
|
76
|
+
*/
|
|
77
|
+
userEmail: string;
|
|
78
|
+
/**
|
|
79
|
+
* Endpoint URL of the database
|
|
80
|
+
*/
|
|
81
|
+
endpoint: string;
|
|
82
|
+
/**
|
|
83
|
+
* Whether TLS is enabled
|
|
84
|
+
*/
|
|
85
|
+
tls: boolean;
|
|
86
|
+
/**
|
|
87
|
+
* REST token for the database
|
|
88
|
+
*/
|
|
89
|
+
restToken: Secret;
|
|
90
|
+
/**
|
|
91
|
+
* Read-only REST token for the database
|
|
92
|
+
*/
|
|
93
|
+
readOnlyRestToken: Secret;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Create and manage Upstash Redis databases
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* // Create a basic Redis database in us-east-1:
|
|
100
|
+
* const redis = await UpstashRedis("my-redis", {
|
|
101
|
+
* name: "my-redis",
|
|
102
|
+
* primaryRegion: "us-east-1"
|
|
103
|
+
* });
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* // Create a Redis database with read replicas:
|
|
107
|
+
* const redis = await UpstashRedis("my-redis", {
|
|
108
|
+
* name: "my-redis",
|
|
109
|
+
* primaryRegion: "us-east-1",
|
|
110
|
+
* readRegions: ["us-west-1", "us-west-2"]
|
|
111
|
+
* });
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* // Create a Redis database with a monthly budget:
|
|
115
|
+
* const redis = await UpstashRedis("my-redis", {
|
|
116
|
+
* name: "my-redis",
|
|
117
|
+
* primaryRegion: "us-east-1",
|
|
118
|
+
* budget: 100
|
|
119
|
+
* });
|
|
120
|
+
*/
|
|
121
|
+
export declare const UpstashRedis: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<UpstashRedis>, id: string, props: UpstashRedisProps) => Promise<UpstashRedis>);
|
|
122
|
+
/**
|
|
123
|
+
* Response from Upstash API for database operations
|
|
124
|
+
*/
|
|
125
|
+
interface UpstashDatabaseResponse {
|
|
126
|
+
database_id: string;
|
|
127
|
+
database_name: string;
|
|
128
|
+
database_type: string;
|
|
129
|
+
region: "global";
|
|
130
|
+
type: string;
|
|
131
|
+
port: number;
|
|
132
|
+
creation_time: number;
|
|
133
|
+
state: string;
|
|
134
|
+
password: string;
|
|
135
|
+
user_email: string;
|
|
136
|
+
endpoint: string;
|
|
137
|
+
tls: boolean;
|
|
138
|
+
rest_token: string;
|
|
139
|
+
read_only_rest_token: string;
|
|
140
|
+
eviction: boolean;
|
|
141
|
+
read_regions?: UpstashRegion[];
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Parameters for creating a Redis database
|
|
145
|
+
*/
|
|
146
|
+
export interface CreateRedisDatabaseParams {
|
|
147
|
+
name: string;
|
|
148
|
+
primary_region: UpstashRegion;
|
|
149
|
+
read_regions?: UpstashRegion[];
|
|
150
|
+
region: "global";
|
|
151
|
+
tls: boolean;
|
|
152
|
+
budget?: number;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Delete a Redis database
|
|
156
|
+
*
|
|
157
|
+
* @param api Upstash API client
|
|
158
|
+
* @param databaseId ID of the database to delete
|
|
159
|
+
*/
|
|
160
|
+
export declare function deleteRedisDatabase(api: UpstashApi, databaseId: string): Promise<void>;
|
|
161
|
+
/**
|
|
162
|
+
* Rename a Redis database
|
|
163
|
+
*
|
|
164
|
+
* @param api Upstash API client
|
|
165
|
+
* @param databaseId ID of the database to rename
|
|
166
|
+
* @param name New name for the database
|
|
167
|
+
*/
|
|
168
|
+
export declare function renameRedisDatabase(api: UpstashApi, databaseId: string, name: string): Promise<void>;
|
|
169
|
+
/**
|
|
170
|
+
* Update read regions for a Redis database
|
|
171
|
+
*
|
|
172
|
+
* @param api Upstash API client
|
|
173
|
+
* @param databaseId ID of the database to update
|
|
174
|
+
* @param readRegions Array of read regions
|
|
175
|
+
*/
|
|
176
|
+
export declare function updateRedisReadRegions(api: UpstashApi, databaseId: string, readRegions: UpstashRegion[]): Promise<void>;
|
|
177
|
+
/**
|
|
178
|
+
* Enable or disable eviction for a Redis database
|
|
179
|
+
*
|
|
180
|
+
* @param api Upstash API client
|
|
181
|
+
* @param databaseId ID of the database to update
|
|
182
|
+
* @param enable Whether to enable or disable eviction
|
|
183
|
+
*/
|
|
184
|
+
export declare function setRedisEviction(api: UpstashApi, databaseId: string, enable: boolean): Promise<void>;
|
|
185
|
+
/**
|
|
186
|
+
* Get information about a Redis database
|
|
187
|
+
*
|
|
188
|
+
* @param api Upstash API client
|
|
189
|
+
* @param databaseId ID of the database to get information about
|
|
190
|
+
* @returns Database information
|
|
191
|
+
*/
|
|
192
|
+
export declare function getRedisDatabase(api: UpstashApi, databaseId: string): Promise<UpstashDatabaseResponse>;
|
|
193
|
+
/**
|
|
194
|
+
* Create a new Redis database
|
|
195
|
+
*
|
|
196
|
+
* @param api Upstash API client
|
|
197
|
+
* @param params Parameters for the new database
|
|
198
|
+
* @returns Created database information
|
|
199
|
+
*/
|
|
200
|
+
export declare function createRedisDatabase(api: UpstashApi, params: CreateRedisDatabaseParams): Promise<UpstashDatabaseResponse>;
|
|
201
|
+
export {};
|
|
202
|
+
//# sourceMappingURL=redis.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/upstash/redis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { alchemy } from "../alchemy.js";
|
|
2
|
+
import { Resource } from "../resource.js";
|
|
3
|
+
import { UpstashApi } from "./api.js";
|
|
4
|
+
import { UpstashError } from "./error.js";
|
|
5
|
+
/**
|
|
6
|
+
* Create and manage Upstash Redis databases
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // Create a basic Redis database in us-east-1:
|
|
10
|
+
* const redis = await UpstashRedis("my-redis", {
|
|
11
|
+
* name: "my-redis",
|
|
12
|
+
* primaryRegion: "us-east-1"
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // Create a Redis database with read replicas:
|
|
17
|
+
* const redis = await UpstashRedis("my-redis", {
|
|
18
|
+
* name: "my-redis",
|
|
19
|
+
* primaryRegion: "us-east-1",
|
|
20
|
+
* readRegions: ["us-west-1", "us-west-2"]
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Create a Redis database with a monthly budget:
|
|
25
|
+
* const redis = await UpstashRedis("my-redis", {
|
|
26
|
+
* name: "my-redis",
|
|
27
|
+
* primaryRegion: "us-east-1",
|
|
28
|
+
* budget: 100
|
|
29
|
+
* });
|
|
30
|
+
*/
|
|
31
|
+
export const UpstashRedis = Resource("upstash::Redis", async function (id, props) {
|
|
32
|
+
const api = new UpstashApi({
|
|
33
|
+
apiKey: props.apiKey,
|
|
34
|
+
email: props.email,
|
|
35
|
+
});
|
|
36
|
+
if (this.phase === "delete") {
|
|
37
|
+
await deleteRedisDatabase(api, this.output.id);
|
|
38
|
+
return this.destroy();
|
|
39
|
+
}
|
|
40
|
+
const eviction = props.eviction ?? false;
|
|
41
|
+
// @ts-ignore This is overridden during update/create
|
|
42
|
+
let database = {};
|
|
43
|
+
if (this.phase === "update") {
|
|
44
|
+
// Update name if changed
|
|
45
|
+
if (props.name !== this.output.name) {
|
|
46
|
+
await renameRedisDatabase(api, this.output.id, props.name);
|
|
47
|
+
}
|
|
48
|
+
// Update read regions if changed
|
|
49
|
+
if (JSON.stringify(props.readRegions) !==
|
|
50
|
+
JSON.stringify(this.output.readRegions)) {
|
|
51
|
+
await updateRedisReadRegions(api, this.output.id, props.readRegions || []);
|
|
52
|
+
}
|
|
53
|
+
// Handle eviction setting if changed
|
|
54
|
+
if (props.eviction !== undefined &&
|
|
55
|
+
props.eviction !== this.output.eviction) {
|
|
56
|
+
await setRedisEviction(api, this.output.id, props.eviction);
|
|
57
|
+
}
|
|
58
|
+
// Get updated database info
|
|
59
|
+
database = await getRedisDatabase(api, this.output.id);
|
|
60
|
+
}
|
|
61
|
+
if (this.phase === "create") {
|
|
62
|
+
database = await createRedisDatabase(api, {
|
|
63
|
+
budget: props.budget,
|
|
64
|
+
name: props.name,
|
|
65
|
+
primary_region: props.primaryRegion,
|
|
66
|
+
read_regions: props.readRegions,
|
|
67
|
+
region: "global",
|
|
68
|
+
tls: true,
|
|
69
|
+
});
|
|
70
|
+
if (eviction) {
|
|
71
|
+
await setRedisEviction(api, database.database_id, eviction);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return this.create({
|
|
75
|
+
id: database.database_id,
|
|
76
|
+
name: database.database_name,
|
|
77
|
+
databaseType: database.database_type,
|
|
78
|
+
region: database.region,
|
|
79
|
+
port: database.port,
|
|
80
|
+
createdAt: database.creation_time,
|
|
81
|
+
state: database.state,
|
|
82
|
+
password: alchemy.secret(database.password),
|
|
83
|
+
userEmail: database.user_email,
|
|
84
|
+
endpoint: database.endpoint,
|
|
85
|
+
tls: database.tls,
|
|
86
|
+
restToken: alchemy.secret(database.rest_token),
|
|
87
|
+
readOnlyRestToken: alchemy.secret(database.read_only_rest_token),
|
|
88
|
+
primaryRegion: props.primaryRegion,
|
|
89
|
+
readRegions: props.readRegions,
|
|
90
|
+
budget: props.budget,
|
|
91
|
+
eviction: props.eviction ?? false,
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
/**
|
|
95
|
+
* Delete a Redis database
|
|
96
|
+
*
|
|
97
|
+
* @param api Upstash API client
|
|
98
|
+
* @param databaseId ID of the database to delete
|
|
99
|
+
*/
|
|
100
|
+
export async function deleteRedisDatabase(api, databaseId) {
|
|
101
|
+
const response = await api.delete(`/redis/database/${databaseId}`);
|
|
102
|
+
if (!response.ok && response.status !== 404) {
|
|
103
|
+
throw new UpstashError(`Error deleting database: ${response.statusText}`, response.status, response);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Rename a Redis database
|
|
108
|
+
*
|
|
109
|
+
* @param api Upstash API client
|
|
110
|
+
* @param databaseId ID of the database to rename
|
|
111
|
+
* @param name New name for the database
|
|
112
|
+
*/
|
|
113
|
+
export async function renameRedisDatabase(api, databaseId, name) {
|
|
114
|
+
const response = await api.post(`/redis/rename/${databaseId}`, {
|
|
115
|
+
name,
|
|
116
|
+
});
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
throw new UpstashError(`API error updating name: ${response.statusText}`, response.status, response);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Update read regions for a Redis database
|
|
123
|
+
*
|
|
124
|
+
* @param api Upstash API client
|
|
125
|
+
* @param databaseId ID of the database to update
|
|
126
|
+
* @param readRegions Array of read regions
|
|
127
|
+
*/
|
|
128
|
+
export async function updateRedisReadRegions(api, databaseId, readRegions) {
|
|
129
|
+
const response = await api.post(`/redis/update-regions/${databaseId}`, {
|
|
130
|
+
read_regions: readRegions,
|
|
131
|
+
});
|
|
132
|
+
if (!response.ok) {
|
|
133
|
+
throw new UpstashError(`API error updating regions: ${response.statusText}`, response.status, response);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Enable or disable eviction for a Redis database
|
|
138
|
+
*
|
|
139
|
+
* @param api Upstash API client
|
|
140
|
+
* @param databaseId ID of the database to update
|
|
141
|
+
* @param enable Whether to enable or disable eviction
|
|
142
|
+
*/
|
|
143
|
+
export async function setRedisEviction(api, databaseId, enable) {
|
|
144
|
+
const evictionEndpoint = enable ? "enable-eviction" : "disable-eviction";
|
|
145
|
+
const response = await api.post(`/redis/${evictionEndpoint}/${databaseId}`, {});
|
|
146
|
+
if (!response.ok) {
|
|
147
|
+
console.warn(`API error updating eviction (status: ${response.status}): ${response.statusText}. (Eviction may already be set)`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Get information about a Redis database
|
|
152
|
+
*
|
|
153
|
+
* @param api Upstash API client
|
|
154
|
+
* @param databaseId ID of the database to get information about
|
|
155
|
+
* @returns Database information
|
|
156
|
+
*/
|
|
157
|
+
export async function getRedisDatabase(api, databaseId) {
|
|
158
|
+
const response = await api.get(`/redis/database/${databaseId}`);
|
|
159
|
+
if (!response.ok) {
|
|
160
|
+
throw new UpstashError(`API error: ${response.statusText}`, response.status, response);
|
|
161
|
+
}
|
|
162
|
+
return await response.json();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Create a new Redis database
|
|
166
|
+
*
|
|
167
|
+
* @param api Upstash API client
|
|
168
|
+
* @param params Parameters for the new database
|
|
169
|
+
* @returns Created database information
|
|
170
|
+
*/
|
|
171
|
+
export async function createRedisDatabase(api, params) {
|
|
172
|
+
const response = await api.post("/redis/database", params);
|
|
173
|
+
if (!response.ok) {
|
|
174
|
+
throw new UpstashError(`API error creating database: ${response.statusText}`, response.status, response);
|
|
175
|
+
}
|
|
176
|
+
return await response.json();
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=redis.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/upstash/redis.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alchemy",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.13",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"module": "./lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"./shadcn": "./lib/shadcn/index.js",
|
|
27
27
|
"./stripe": "./lib/stripe/index.js",
|
|
28
28
|
"./test/bun": "./lib/test/bun.js",
|
|
29
|
+
"./upstash": "./lib/upstash/index.js",
|
|
29
30
|
"./web/astro": "./lib/web/astro/index.js",
|
|
30
31
|
"./web/tailwind": "./lib/web/tailwind/index.js",
|
|
31
32
|
"./web/vite": "./lib/web/vite/index.js",
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { Secret } from "../secret.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Options for Upstash API requests
|
|
5
|
+
*/
|
|
6
|
+
export interface UpstashApiOptions {
|
|
7
|
+
/**
|
|
8
|
+
* API key to use (overrides environment variable)
|
|
9
|
+
*/
|
|
10
|
+
apiKey?: Secret;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Email to use (overrides environment variable)
|
|
14
|
+
*/
|
|
15
|
+
email?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Minimal API client using raw fetch
|
|
20
|
+
*/
|
|
21
|
+
export class UpstashApi {
|
|
22
|
+
/** Base URL for API */
|
|
23
|
+
readonly baseUrl: string;
|
|
24
|
+
|
|
25
|
+
/** API key */
|
|
26
|
+
readonly apiKey: string;
|
|
27
|
+
|
|
28
|
+
/** Email */
|
|
29
|
+
readonly email: string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Create a new API client
|
|
33
|
+
*
|
|
34
|
+
* @param options API options
|
|
35
|
+
*/
|
|
36
|
+
constructor(options: UpstashApiOptions = {}) {
|
|
37
|
+
this.baseUrl = "https://api.upstash.com/v2";
|
|
38
|
+
this.apiKey =
|
|
39
|
+
options.apiKey?.unencrypted ?? process.env.UPSTASH_API_KEY ?? "";
|
|
40
|
+
this.email = options.email ?? process.env.UPSTASH_EMAIL ?? "";
|
|
41
|
+
|
|
42
|
+
if (!this.apiKey) {
|
|
43
|
+
throw new Error("UPSTASH_API_KEY environment variable is required");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!this.email) {
|
|
47
|
+
throw new Error("UPSTASH_EMAIL environment variable is required");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Make a request to the API
|
|
53
|
+
*
|
|
54
|
+
* @param path API path (without base URL)
|
|
55
|
+
* @param init Fetch init options
|
|
56
|
+
* @returns Raw Response object from fetch
|
|
57
|
+
*/
|
|
58
|
+
async fetch(path: string, init: RequestInit = {}): Promise<Response> {
|
|
59
|
+
const headers: Record<string, string> = {
|
|
60
|
+
"Content-Type": "application/json",
|
|
61
|
+
Authorization: `Basic ${btoa(`${this.email}:${this.apiKey}`)}`,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
if (init.headers) {
|
|
65
|
+
const initHeaders = init.headers as Record<string, string>;
|
|
66
|
+
Object.keys(initHeaders).forEach((key) => {
|
|
67
|
+
headers[key] = initHeaders[key];
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return fetch(`${this.baseUrl}${path}`, {
|
|
72
|
+
...init,
|
|
73
|
+
headers,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Helper for GET requests
|
|
79
|
+
*/
|
|
80
|
+
async get(path: string, init: RequestInit = {}): Promise<Response> {
|
|
81
|
+
return this.fetch(path, { ...init, method: "GET" });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Helper for POST requests
|
|
86
|
+
*/
|
|
87
|
+
async post(
|
|
88
|
+
path: string,
|
|
89
|
+
body: any,
|
|
90
|
+
init: RequestInit = {},
|
|
91
|
+
): Promise<Response> {
|
|
92
|
+
return this.fetch(path, {
|
|
93
|
+
...init,
|
|
94
|
+
method: "POST",
|
|
95
|
+
body: JSON.stringify(body),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Helper for DELETE requests
|
|
101
|
+
*/
|
|
102
|
+
async delete(path: string, init: RequestInit = {}): Promise<Response> {
|
|
103
|
+
return this.fetch(path, { ...init, method: "DELETE" });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom error class for Upstash API errors
|
|
3
|
+
*/
|
|
4
|
+
export class UpstashError extends Error {
|
|
5
|
+
/**
|
|
6
|
+
* HTTP status code
|
|
7
|
+
*/
|
|
8
|
+
statusCode: number;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Original response object
|
|
12
|
+
*/
|
|
13
|
+
response: Response;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Create a new Upstash error
|
|
17
|
+
*
|
|
18
|
+
* @param message Error message
|
|
19
|
+
* @param statusCode HTTP status code
|
|
20
|
+
* @param response Original response object
|
|
21
|
+
*/
|
|
22
|
+
constructor(message: string, statusCode: number, response: Response) {
|
|
23
|
+
super(message);
|
|
24
|
+
this.name = "UpstashError";
|
|
25
|
+
this.statusCode = statusCode;
|
|
26
|
+
this.response = response;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import { alchemy } from "../alchemy.js";
|
|
2
|
+
import type { Context } from "../context.js";
|
|
3
|
+
import { Resource } from "../resource.js";
|
|
4
|
+
import type { Secret } from "../secret.js";
|
|
5
|
+
import { UpstashApi } from "./api.js";
|
|
6
|
+
import { UpstashError } from "./error.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Available regions for Upstash Redis databases
|
|
10
|
+
*/
|
|
11
|
+
export type UpstashRegion =
|
|
12
|
+
| "us-east-1"
|
|
13
|
+
| "us-west-1"
|
|
14
|
+
| "us-west-2"
|
|
15
|
+
| "eu-west-1"
|
|
16
|
+
| "eu-central-1"
|
|
17
|
+
| "ap-southeast-1"
|
|
18
|
+
| "ap-southeast-2"
|
|
19
|
+
| "ap-northeast-1"
|
|
20
|
+
| "sa-east-1";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Properties for creating or updating an UpstashRedis database
|
|
24
|
+
*/
|
|
25
|
+
export interface UpstashRedisProps {
|
|
26
|
+
/**
|
|
27
|
+
* Name of the database
|
|
28
|
+
*/
|
|
29
|
+
name: string;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Primary region for the database
|
|
33
|
+
*/
|
|
34
|
+
primaryRegion: UpstashRegion;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Read regions for the database
|
|
38
|
+
*/
|
|
39
|
+
readRegions?: UpstashRegion[];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Monthly budget for the database
|
|
43
|
+
*/
|
|
44
|
+
budget?: number;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Whether to enable eviction for the database
|
|
48
|
+
*/
|
|
49
|
+
eviction?: boolean;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* API key to use (overrides environment variable)
|
|
53
|
+
*/
|
|
54
|
+
apiKey?: Secret;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Email to use (overrides environment variable)
|
|
58
|
+
*/
|
|
59
|
+
email?: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Output returned after UpstashRedis creation/update
|
|
64
|
+
*/
|
|
65
|
+
export interface UpstashRedis
|
|
66
|
+
extends Resource<"upstash::Redis">,
|
|
67
|
+
UpstashRedisProps {
|
|
68
|
+
/**
|
|
69
|
+
* ID of the database
|
|
70
|
+
*/
|
|
71
|
+
id: string;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Type of the database in terms of pricing model
|
|
75
|
+
*/
|
|
76
|
+
databaseType: string;
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Region where database is hosted
|
|
80
|
+
*/
|
|
81
|
+
region: "global";
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Database port for clients to connect
|
|
85
|
+
*/
|
|
86
|
+
port: number;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Creation time of the database as Unix time
|
|
90
|
+
*/
|
|
91
|
+
createdAt: number;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* State of database (active or deleted)
|
|
95
|
+
*/
|
|
96
|
+
state: string;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Password of the database
|
|
100
|
+
*/
|
|
101
|
+
password: Secret;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Email or team id of the owner of the database
|
|
105
|
+
*/
|
|
106
|
+
userEmail: string;
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Endpoint URL of the database
|
|
110
|
+
*/
|
|
111
|
+
endpoint: string;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Whether TLS is enabled
|
|
115
|
+
*/
|
|
116
|
+
tls: boolean;
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* REST token for the database
|
|
120
|
+
*/
|
|
121
|
+
restToken: Secret;
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Read-only REST token for the database
|
|
125
|
+
*/
|
|
126
|
+
readOnlyRestToken: Secret;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Create and manage Upstash Redis databases
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* // Create a basic Redis database in us-east-1:
|
|
134
|
+
* const redis = await UpstashRedis("my-redis", {
|
|
135
|
+
* name: "my-redis",
|
|
136
|
+
* primaryRegion: "us-east-1"
|
|
137
|
+
* });
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* // Create a Redis database with read replicas:
|
|
141
|
+
* const redis = await UpstashRedis("my-redis", {
|
|
142
|
+
* name: "my-redis",
|
|
143
|
+
* primaryRegion: "us-east-1",
|
|
144
|
+
* readRegions: ["us-west-1", "us-west-2"]
|
|
145
|
+
* });
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* // Create a Redis database with a monthly budget:
|
|
149
|
+
* const redis = await UpstashRedis("my-redis", {
|
|
150
|
+
* name: "my-redis",
|
|
151
|
+
* primaryRegion: "us-east-1",
|
|
152
|
+
* budget: 100
|
|
153
|
+
* });
|
|
154
|
+
*/
|
|
155
|
+
export const UpstashRedis = Resource(
|
|
156
|
+
"upstash::Redis",
|
|
157
|
+
async function (
|
|
158
|
+
this: Context<UpstashRedis>,
|
|
159
|
+
id: string,
|
|
160
|
+
props: UpstashRedisProps,
|
|
161
|
+
): Promise<UpstashRedis> {
|
|
162
|
+
const api = new UpstashApi({
|
|
163
|
+
apiKey: props.apiKey,
|
|
164
|
+
email: props.email,
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
if (this.phase === "delete") {
|
|
168
|
+
await deleteRedisDatabase(api, this.output.id);
|
|
169
|
+
return this.destroy();
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const eviction = props.eviction ?? false;
|
|
173
|
+
|
|
174
|
+
// @ts-ignore This is overridden during update/create
|
|
175
|
+
let database: UpstashDatabaseResponse = {};
|
|
176
|
+
|
|
177
|
+
if (this.phase === "update") {
|
|
178
|
+
// Update name if changed
|
|
179
|
+
if (props.name !== this.output.name) {
|
|
180
|
+
await renameRedisDatabase(api, this.output.id, props.name);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Update read regions if changed
|
|
184
|
+
if (
|
|
185
|
+
JSON.stringify(props.readRegions) !==
|
|
186
|
+
JSON.stringify(this.output.readRegions)
|
|
187
|
+
) {
|
|
188
|
+
await updateRedisReadRegions(
|
|
189
|
+
api,
|
|
190
|
+
this.output.id,
|
|
191
|
+
props.readRegions || [],
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Handle eviction setting if changed
|
|
196
|
+
if (
|
|
197
|
+
props.eviction !== undefined &&
|
|
198
|
+
props.eviction !== this.output.eviction
|
|
199
|
+
) {
|
|
200
|
+
await setRedisEviction(api, this.output.id, props.eviction);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Get updated database info
|
|
204
|
+
database = await getRedisDatabase(api, this.output.id);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (this.phase === "create") {
|
|
208
|
+
database = await createRedisDatabase(api, {
|
|
209
|
+
budget: props.budget,
|
|
210
|
+
name: props.name,
|
|
211
|
+
primary_region: props.primaryRegion,
|
|
212
|
+
read_regions: props.readRegions,
|
|
213
|
+
region: "global",
|
|
214
|
+
tls: true,
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
if (eviction) {
|
|
218
|
+
await setRedisEviction(api, database.database_id, eviction);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return this.create({
|
|
223
|
+
id: database.database_id,
|
|
224
|
+
name: database.database_name,
|
|
225
|
+
databaseType: database.database_type,
|
|
226
|
+
region: database.region,
|
|
227
|
+
port: database.port,
|
|
228
|
+
createdAt: database.creation_time,
|
|
229
|
+
state: database.state,
|
|
230
|
+
password: alchemy.secret(database.password),
|
|
231
|
+
userEmail: database.user_email,
|
|
232
|
+
endpoint: database.endpoint,
|
|
233
|
+
tls: database.tls,
|
|
234
|
+
restToken: alchemy.secret(database.rest_token),
|
|
235
|
+
readOnlyRestToken: alchemy.secret(database.read_only_rest_token),
|
|
236
|
+
primaryRegion: props.primaryRegion,
|
|
237
|
+
readRegions: props.readRegions,
|
|
238
|
+
budget: props.budget,
|
|
239
|
+
eviction: props.eviction ?? false,
|
|
240
|
+
});
|
|
241
|
+
},
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Response from Upstash API for database operations
|
|
246
|
+
*/
|
|
247
|
+
interface UpstashDatabaseResponse {
|
|
248
|
+
database_id: string;
|
|
249
|
+
database_name: string;
|
|
250
|
+
database_type: string;
|
|
251
|
+
region: "global";
|
|
252
|
+
type: string;
|
|
253
|
+
port: number;
|
|
254
|
+
creation_time: number;
|
|
255
|
+
state: string;
|
|
256
|
+
password: string;
|
|
257
|
+
user_email: string;
|
|
258
|
+
endpoint: string;
|
|
259
|
+
tls: boolean;
|
|
260
|
+
rest_token: string;
|
|
261
|
+
read_only_rest_token: string;
|
|
262
|
+
eviction: boolean;
|
|
263
|
+
read_regions?: UpstashRegion[];
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Parameters for creating a Redis database
|
|
268
|
+
*/
|
|
269
|
+
export interface CreateRedisDatabaseParams {
|
|
270
|
+
name: string;
|
|
271
|
+
primary_region: UpstashRegion;
|
|
272
|
+
read_regions?: UpstashRegion[];
|
|
273
|
+
region: "global";
|
|
274
|
+
tls: boolean;
|
|
275
|
+
budget?: number;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Delete a Redis database
|
|
280
|
+
*
|
|
281
|
+
* @param api Upstash API client
|
|
282
|
+
* @param databaseId ID of the database to delete
|
|
283
|
+
*/
|
|
284
|
+
export async function deleteRedisDatabase(
|
|
285
|
+
api: UpstashApi,
|
|
286
|
+
databaseId: string,
|
|
287
|
+
): Promise<void> {
|
|
288
|
+
const response = await api.delete(`/redis/database/${databaseId}`);
|
|
289
|
+
|
|
290
|
+
if (!response.ok && response.status !== 404) {
|
|
291
|
+
throw new UpstashError(
|
|
292
|
+
`Error deleting database: ${response.statusText}`,
|
|
293
|
+
response.status,
|
|
294
|
+
response,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Rename a Redis database
|
|
301
|
+
*
|
|
302
|
+
* @param api Upstash API client
|
|
303
|
+
* @param databaseId ID of the database to rename
|
|
304
|
+
* @param name New name for the database
|
|
305
|
+
*/
|
|
306
|
+
export async function renameRedisDatabase(
|
|
307
|
+
api: UpstashApi,
|
|
308
|
+
databaseId: string,
|
|
309
|
+
name: string,
|
|
310
|
+
): Promise<void> {
|
|
311
|
+
const response = await api.post(`/redis/rename/${databaseId}`, {
|
|
312
|
+
name,
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
if (!response.ok) {
|
|
316
|
+
throw new UpstashError(
|
|
317
|
+
`API error updating name: ${response.statusText}`,
|
|
318
|
+
response.status,
|
|
319
|
+
response,
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Update read regions for a Redis database
|
|
326
|
+
*
|
|
327
|
+
* @param api Upstash API client
|
|
328
|
+
* @param databaseId ID of the database to update
|
|
329
|
+
* @param readRegions Array of read regions
|
|
330
|
+
*/
|
|
331
|
+
export async function updateRedisReadRegions(
|
|
332
|
+
api: UpstashApi,
|
|
333
|
+
databaseId: string,
|
|
334
|
+
readRegions: UpstashRegion[],
|
|
335
|
+
): Promise<void> {
|
|
336
|
+
const response = await api.post(`/redis/update-regions/${databaseId}`, {
|
|
337
|
+
read_regions: readRegions,
|
|
338
|
+
});
|
|
339
|
+
|
|
340
|
+
if (!response.ok) {
|
|
341
|
+
throw new UpstashError(
|
|
342
|
+
`API error updating regions: ${response.statusText}`,
|
|
343
|
+
response.status,
|
|
344
|
+
response,
|
|
345
|
+
);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Enable or disable eviction for a Redis database
|
|
351
|
+
*
|
|
352
|
+
* @param api Upstash API client
|
|
353
|
+
* @param databaseId ID of the database to update
|
|
354
|
+
* @param enable Whether to enable or disable eviction
|
|
355
|
+
*/
|
|
356
|
+
export async function setRedisEviction(
|
|
357
|
+
api: UpstashApi,
|
|
358
|
+
databaseId: string,
|
|
359
|
+
enable: boolean,
|
|
360
|
+
): Promise<void> {
|
|
361
|
+
const evictionEndpoint = enable ? "enable-eviction" : "disable-eviction";
|
|
362
|
+
|
|
363
|
+
const response = await api.post(
|
|
364
|
+
`/redis/${evictionEndpoint}/${databaseId}`,
|
|
365
|
+
{},
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
if (!response.ok) {
|
|
369
|
+
console.warn(
|
|
370
|
+
`API error updating eviction (status: ${response.status}): ${response.statusText}. (Eviction may already be set)`,
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Get information about a Redis database
|
|
377
|
+
*
|
|
378
|
+
* @param api Upstash API client
|
|
379
|
+
* @param databaseId ID of the database to get information about
|
|
380
|
+
* @returns Database information
|
|
381
|
+
*/
|
|
382
|
+
export async function getRedisDatabase(
|
|
383
|
+
api: UpstashApi,
|
|
384
|
+
databaseId: string,
|
|
385
|
+
): Promise<UpstashDatabaseResponse> {
|
|
386
|
+
const response = await api.get(`/redis/database/${databaseId}`);
|
|
387
|
+
|
|
388
|
+
if (!response.ok) {
|
|
389
|
+
throw new UpstashError(
|
|
390
|
+
`API error: ${response.statusText}`,
|
|
391
|
+
response.status,
|
|
392
|
+
response,
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return await response.json();
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Create a new Redis database
|
|
401
|
+
*
|
|
402
|
+
* @param api Upstash API client
|
|
403
|
+
* @param params Parameters for the new database
|
|
404
|
+
* @returns Created database information
|
|
405
|
+
*/
|
|
406
|
+
export async function createRedisDatabase(
|
|
407
|
+
api: UpstashApi,
|
|
408
|
+
params: CreateRedisDatabaseParams,
|
|
409
|
+
): Promise<UpstashDatabaseResponse> {
|
|
410
|
+
const response = await api.post("/redis/database", params);
|
|
411
|
+
|
|
412
|
+
if (!response.ok) {
|
|
413
|
+
throw new UpstashError(
|
|
414
|
+
`API error creating database: ${response.statusText}`,
|
|
415
|
+
response.status,
|
|
416
|
+
response,
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return await response.json();
|
|
421
|
+
}
|