alchemy 0.43.4 → 0.44.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.mjs +430 -346
- package/bin/alchemy.ts +7 -21
- package/bin/commands/create.ts +79 -23
- package/bin/services/package-manager.ts +0 -3
- package/bin/services/template-manager.ts +9 -4
- package/bin/services/vibe-rules.ts +47 -0
- package/bin/types.ts +25 -5
- package/lib/alchemy.d.ts.map +1 -1
- package/lib/alchemy.js +8 -11
- package/lib/alchemy.js.map +1 -1
- package/lib/apply.js +2 -0
- package/lib/apply.js.map +1 -1
- package/lib/build-date.d.ts +1 -1
- package/lib/build-date.js +1 -1
- package/lib/cloudflare/assets.d.ts +1 -1
- package/lib/cloudflare/assets.d.ts.map +1 -1
- package/lib/cloudflare/bucket.d.ts.map +1 -1
- package/lib/cloudflare/bucket.js +9 -6
- package/lib/cloudflare/bucket.js.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker-dev.d.ts.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker-dev.js +4 -1
- package/lib/cloudflare/bundle/bundle-worker-dev.js.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker.d.ts.map +1 -1
- package/lib/cloudflare/bundle/bundle-worker.js +4 -1
- package/lib/cloudflare/bundle/bundle-worker.js.map +1 -1
- package/lib/cloudflare/bundle/external.d.ts +1 -0
- package/lib/cloudflare/bundle/external.d.ts.map +1 -1
- package/lib/cloudflare/bundle/external.js +1 -1
- package/lib/cloudflare/bundle/external.js.map +1 -1
- package/lib/cloudflare/bundle/nodejs-import-warning-plugin.d.ts +10 -0
- package/lib/cloudflare/bundle/nodejs-import-warning-plugin.d.ts.map +1 -0
- package/lib/cloudflare/bundle/nodejs-import-warning-plugin.js +67 -0
- package/lib/cloudflare/bundle/nodejs-import-warning-plugin.js.map +1 -0
- package/lib/cloudflare/container.d.ts +27 -2
- package/lib/cloudflare/container.d.ts.map +1 -1
- package/lib/cloudflare/container.js +82 -24
- package/lib/cloudflare/container.js.map +1 -1
- package/lib/cloudflare/redirect-rule.js +1 -1
- package/lib/cloudflare/redirect-rule.js.map +1 -1
- package/lib/cloudflare/website.d.ts +17 -0
- package/lib/cloudflare/website.d.ts.map +1 -1
- package/lib/cloudflare/website.js +1 -0
- package/lib/cloudflare/website.js.map +1 -1
- package/lib/cloudflare/worker/miniflare.d.ts +4 -1
- package/lib/cloudflare/worker/miniflare.d.ts.map +1 -1
- package/lib/cloudflare/worker/miniflare.js +22 -2
- package/lib/cloudflare/worker/miniflare.js.map +1 -1
- package/lib/cloudflare/worker-metadata.d.ts.map +1 -1
- package/lib/cloudflare/worker-metadata.js +12 -0
- package/lib/cloudflare/worker-metadata.js.map +1 -1
- package/lib/cloudflare/worker.d.ts +1 -1
- package/lib/cloudflare/wrangler.json.d.ts +24 -0
- package/lib/cloudflare/wrangler.json.d.ts.map +1 -1
- package/lib/cloudflare/wrangler.json.js +20 -2
- package/lib/cloudflare/wrangler.json.js.map +1 -1
- package/lib/context.d.ts +6 -1
- package/lib/context.d.ts.map +1 -1
- package/lib/context.js +2 -1
- package/lib/context.js.map +1 -1
- package/lib/destroy.d.ts.map +1 -1
- package/lib/destroy.js +1 -0
- package/lib/destroy.js.map +1 -1
- package/lib/docker/api.d.ts +11 -0
- package/lib/docker/api.d.ts.map +1 -1
- package/lib/docker/api.js +41 -1
- package/lib/docker/api.js.map +1 -1
- package/lib/docker/image.d.ts +1 -1
- package/lib/docker/image.d.ts.map +1 -1
- package/lib/docker/image.js +11 -5
- package/lib/docker/image.js.map +1 -1
- package/lib/esbuild/bundle.d.ts +2 -2
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/llms.cloudflare.txt +379 -0
- package/lib/llms.d.ts +10 -0
- package/lib/llms.d.ts.map +1 -0
- package/lib/llms.js +12 -0
- package/lib/llms.js.map +1 -0
- package/lib/planetscale/index.d.ts +3 -2
- package/lib/planetscale/index.d.ts.map +1 -1
- package/lib/planetscale/index.js +3 -2
- package/lib/planetscale/index.js.map +1 -1
- package/lib/planetscale/password.d.ts +233 -0
- package/lib/planetscale/password.d.ts.map +1 -0
- package/lib/planetscale/password.js +238 -0
- package/lib/planetscale/password.js.map +1 -0
- package/lib/scope.d.ts +6 -5
- package/lib/scope.d.ts.map +1 -1
- package/lib/scope.js +18 -7
- package/lib/scope.js.map +1 -1
- package/lib/test/bun.d.ts.map +1 -1
- package/lib/test/bun.js +1 -0
- package/lib/test/bun.js.map +1 -1
- package/lib/test/vitest.d.ts.map +1 -1
- package/lib/test/vitest.js +1 -0
- package/lib/test/vitest.js.map +1 -1
- package/lib/util/nanoid.d.ts +3 -0
- package/lib/util/nanoid.d.ts.map +1 -0
- package/lib/util/nanoid.js +13 -0
- package/lib/util/nanoid.js.map +1 -0
- package/lib/util/safe-fetch.d.ts.map +1 -1
- package/lib/util/safe-fetch.js +0 -1
- package/lib/util/safe-fetch.js.map +1 -1
- package/lib/util/telemetry/client.d.ts.map +1 -1
- package/lib/util/telemetry/client.js +13 -3
- package/lib/util/telemetry/client.js.map +1 -1
- package/lib/util/telemetry/constants.d.ts +2 -1
- package/lib/util/telemetry/constants.d.ts.map +1 -1
- package/lib/util/telemetry/constants.js +3 -2
- package/lib/util/telemetry/constants.js.map +1 -1
- package/package.json +10 -2
- package/src/alchemy.ts +8 -13
- package/src/apply.ts +2 -0
- package/src/build-date.ts +1 -1
- package/src/cloudflare/bucket.ts +22 -14
- package/src/cloudflare/bundle/bundle-worker-dev.ts +4 -1
- package/src/cloudflare/bundle/bundle-worker.ts +4 -1
- package/src/cloudflare/bundle/external.ts +1 -1
- package/src/cloudflare/bundle/nodejs-import-warning-plugin.ts +94 -0
- package/src/cloudflare/container.ts +113 -28
- package/src/cloudflare/redirect-rule.ts +1 -1
- package/src/cloudflare/website.ts +21 -1
- package/src/cloudflare/worker/miniflare.ts +33 -8
- package/src/cloudflare/worker-metadata.ts +15 -0
- package/src/cloudflare/wrangler.json.ts +61 -5
- package/src/context.ts +7 -0
- package/src/destroy.ts +1 -0
- package/src/docker/api.ts +57 -1
- package/src/docker/image.ts +15 -6
- package/src/index.ts +1 -0
- package/src/llms.cloudflare.txt +379 -0
- package/src/llms.ts +25 -0
- package/src/planetscale/index.ts +3 -2
- package/src/planetscale/password.ts +366 -0
- package/src/scope.ts +25 -11
- package/src/test/bun.ts +1 -0
- package/src/test/vitest.ts +1 -0
- package/src/util/nanoid.ts +13 -0
- package/src/util/safe-fetch.ts +0 -1
- package/src/util/telemetry/client.ts +17 -3
- package/src/util/telemetry/constants.ts +5 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/planetscale/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/planetscale/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
package/lib/planetscale/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/planetscale/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/planetscale/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import type { Context } from "../context.ts";
|
|
2
|
+
import { Resource } from "../resource.ts";
|
|
3
|
+
import type { Secret } from "../secret.ts";
|
|
4
|
+
import type { Branch } from "./branch.ts";
|
|
5
|
+
import type { Database } from "./database.ts";
|
|
6
|
+
/**
|
|
7
|
+
* Properties for creating or updating a PlanetScale Branch
|
|
8
|
+
*/
|
|
9
|
+
export interface PasswordProps {
|
|
10
|
+
/**
|
|
11
|
+
* The name of the password
|
|
12
|
+
*/
|
|
13
|
+
name: string;
|
|
14
|
+
/**
|
|
15
|
+
* The organization ID where the password will be created
|
|
16
|
+
* Required when using string database name, optional when using Database resource
|
|
17
|
+
*/
|
|
18
|
+
organizationId?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The database where the password will be created
|
|
21
|
+
* Can be either a database name (string) or Database resource
|
|
22
|
+
*/
|
|
23
|
+
database: string | Database;
|
|
24
|
+
/**
|
|
25
|
+
* The branch where the password will be created
|
|
26
|
+
* Can be either a branch name (string) or Branch resource
|
|
27
|
+
* Defaults to "main" if not provided
|
|
28
|
+
*/
|
|
29
|
+
branch?: string | Branch;
|
|
30
|
+
/**
|
|
31
|
+
* PlanetScale API token (overrides environment variable)
|
|
32
|
+
*/
|
|
33
|
+
apiKey?: Secret;
|
|
34
|
+
/**
|
|
35
|
+
* The password
|
|
36
|
+
*/
|
|
37
|
+
role: "reader" | "writer" | "admin" | "readwriter";
|
|
38
|
+
/**
|
|
39
|
+
* Whether the password is for a read replica
|
|
40
|
+
*/
|
|
41
|
+
replica?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The TTL of the password in seconds
|
|
44
|
+
*/
|
|
45
|
+
ttl?: number;
|
|
46
|
+
/**
|
|
47
|
+
* The CIDRs of the password
|
|
48
|
+
*/
|
|
49
|
+
cidrs?: string[];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Represents a PlanetScale Branch
|
|
53
|
+
*/
|
|
54
|
+
export interface Password extends Resource<"planetscale::Password">, PasswordProps {
|
|
55
|
+
/**
|
|
56
|
+
* The unique identifier for the password
|
|
57
|
+
*/
|
|
58
|
+
id: string;
|
|
59
|
+
/**
|
|
60
|
+
* The timestamp when the password expires (ISO 8601 format)
|
|
61
|
+
*/
|
|
62
|
+
expiresAt: string;
|
|
63
|
+
/**
|
|
64
|
+
* The host URL for database connection
|
|
65
|
+
*/
|
|
66
|
+
host: string;
|
|
67
|
+
/**
|
|
68
|
+
* The username for database authentication
|
|
69
|
+
*/
|
|
70
|
+
username: string;
|
|
71
|
+
/**
|
|
72
|
+
* The encrypted password for database authentication
|
|
73
|
+
*/
|
|
74
|
+
password: Secret<string>;
|
|
75
|
+
/**
|
|
76
|
+
* The name slug for the password
|
|
77
|
+
*/
|
|
78
|
+
nameSlug: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create and manage database passwords for PlanetScale branches. Database passwords provide secure access to your database with specific roles and permissions.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ## Basic Reader Password
|
|
85
|
+
*
|
|
86
|
+
* Create a read-only password for a database branch:
|
|
87
|
+
*
|
|
88
|
+
* ```ts
|
|
89
|
+
* import { Password } from "alchemy/planetscale";
|
|
90
|
+
*
|
|
91
|
+
* const readerPassword = await Password("app-reader", {
|
|
92
|
+
* name: "app-reader",
|
|
93
|
+
* organizationId: "my-org",
|
|
94
|
+
* database: "my-app-db",
|
|
95
|
+
* branch: "main",
|
|
96
|
+
* role: "reader"
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* // Access connection details
|
|
100
|
+
* console.log(`Host: ${readerPassword.password.host}`);
|
|
101
|
+
* console.log(`Username: ${readerPassword.password.username}`);
|
|
102
|
+
* console.log(`Password: ${readerPassword.password.password.unencrypted}`);
|
|
103
|
+
* ```
|
|
104
|
+
*
|
|
105
|
+
* @example
|
|
106
|
+
* ## Writer Password with TTL
|
|
107
|
+
*
|
|
108
|
+
* Create a writer password that expires after 24 hours:
|
|
109
|
+
*
|
|
110
|
+
* ```ts
|
|
111
|
+
* import { Password } from "alchemy/planetscale";
|
|
112
|
+
*
|
|
113
|
+
* const writerPassword = await Password("app-writer", {
|
|
114
|
+
* name: "app-writer",
|
|
115
|
+
* organizationId: "my-org",
|
|
116
|
+
* database: "my-app-db",
|
|
117
|
+
* branch: "development",
|
|
118
|
+
* role: "writer",
|
|
119
|
+
* ttl: 86400 // 24 hours in seconds
|
|
120
|
+
* });
|
|
121
|
+
*
|
|
122
|
+
* // Password will expire at the specified time
|
|
123
|
+
* console.log(`Expires at: ${writerPassword.expiresAt}`);
|
|
124
|
+
* ```
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ## Admin Password with IP Restrictions
|
|
128
|
+
*
|
|
129
|
+
* Create an admin password that only allows connections from specific IP addresses:
|
|
130
|
+
*
|
|
131
|
+
* ```ts
|
|
132
|
+
* import { Password } from "alchemy/planetscale";
|
|
133
|
+
*
|
|
134
|
+
* const adminPassword = await Password("admin-access", {
|
|
135
|
+
* name: "admin-access",
|
|
136
|
+
* organizationId: "my-org",
|
|
137
|
+
* database: "my-app-db",
|
|
138
|
+
* branch: "main",
|
|
139
|
+
* role: "admin",
|
|
140
|
+
* cidrs: ["203.0.113.0/24", "198.51.100.0/24"],
|
|
141
|
+
* ttl: 3600 // 1 hour
|
|
142
|
+
* });
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* ## Database Password with Custom API Key
|
|
147
|
+
*
|
|
148
|
+
* Create a password using a specific API key instead of the default environment variable:
|
|
149
|
+
*
|
|
150
|
+
* ```ts
|
|
151
|
+
* import { Password } from "alchemy/planetscale";
|
|
152
|
+
*
|
|
153
|
+
* const password = await Password("custom-auth", {
|
|
154
|
+
* name: "custom-auth",
|
|
155
|
+
* organizationId: "my-org",
|
|
156
|
+
* database: "my-app-db",
|
|
157
|
+
* branch: "main",
|
|
158
|
+
* role: "readwriter",
|
|
159
|
+
* apiKey: alchemy.secret(process.env.CUSTOM_PLANETSCALE_TOKEN)
|
|
160
|
+
* });
|
|
161
|
+
* ```
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ## Read Replica Password
|
|
165
|
+
*
|
|
166
|
+
* Create a password for accessing a read replica:
|
|
167
|
+
*
|
|
168
|
+
* ```ts
|
|
169
|
+
* import { Password } from "alchemy/planetscale";
|
|
170
|
+
*
|
|
171
|
+
* const replicaPassword = await Password("replica-reader", {
|
|
172
|
+
* name: "replica-reader",
|
|
173
|
+
* organizationId: "my-org",
|
|
174
|
+
* database: "my-app-db",
|
|
175
|
+
* branch: "main",
|
|
176
|
+
* role: "reader",
|
|
177
|
+
* replica: true
|
|
178
|
+
* });
|
|
179
|
+
*
|
|
180
|
+
* @example
|
|
181
|
+
* ## Using Database Resource Instance
|
|
182
|
+
*
|
|
183
|
+
* Create a password using a Database resource instead of string:
|
|
184
|
+
*
|
|
185
|
+
* ```ts
|
|
186
|
+
* import { Database, Password } from "alchemy/planetscale";
|
|
187
|
+
*
|
|
188
|
+
* const database = await Database("my-db", {
|
|
189
|
+
* name: "my-app-db",
|
|
190
|
+
* organizationId: "my-org",
|
|
191
|
+
* clusterSize: "PS_10"
|
|
192
|
+
* });
|
|
193
|
+
*
|
|
194
|
+
* const password = await Password("db-reader", {
|
|
195
|
+
* name: "db-reader",
|
|
196
|
+
* database: database, // Using Database resource
|
|
197
|
+
* role: "reader"
|
|
198
|
+
* });
|
|
199
|
+
* ```
|
|
200
|
+
*
|
|
201
|
+
* @example
|
|
202
|
+
* ## Using Both Database and Branch Resources
|
|
203
|
+
*
|
|
204
|
+
* Create a password using both Database and Branch resources:
|
|
205
|
+
*
|
|
206
|
+
* ```ts
|
|
207
|
+
* import { Database, Branch, Password } from "alchemy/planetscale";
|
|
208
|
+
*
|
|
209
|
+
* const database = await Database("my-db", {
|
|
210
|
+
* name: "my-app-db",
|
|
211
|
+
* organizationId: "my-org",
|
|
212
|
+
* clusterSize: "PS_10"
|
|
213
|
+
* });
|
|
214
|
+
*
|
|
215
|
+
* const branch = await Branch("feature-branch", {
|
|
216
|
+
* name: "feature-branch",
|
|
217
|
+
* organizationId: "my-org",
|
|
218
|
+
* databaseName: "my-app-db",
|
|
219
|
+
* parentBranch: "main",
|
|
220
|
+
* isProduction: false
|
|
221
|
+
* });
|
|
222
|
+
*
|
|
223
|
+
* const password = await Password("feature-writer", {
|
|
224
|
+
* name: "feature-writer",
|
|
225
|
+
* database: database, // Using Database resource
|
|
226
|
+
* branch: branch, // Using Branch resource
|
|
227
|
+
* role: "writer"
|
|
228
|
+
* });
|
|
229
|
+
* ```
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
export declare const Password: (((this: any, id: string, props?: {}) => never) & (new (_: never) => never)) | ((this: Context<Password>, _id: string, props: PasswordProps) => Promise<Password>);
|
|
233
|
+
//# sourceMappingURL=password.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.d.ts","sourceRoot":"","sources":["../../src/planetscale/password.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAC;IAE5B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,YAAY,CAAC;IAEnD;;OAEG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,QACf,SAAQ,QAAQ,CAAC,uBAAuB,CAAC,EACvC,aAAa;IACf;;OAEG;IACH,EAAE,EAAE,MAAM,CAAC;IAEX;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IAEzB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuJG;AACH,eAAO,MAAM,QAAQ,yFAGX,OAAO,CAAC,QAAQ,CAAC,OAClB,MAAM,SACJ,aAAa,KACnB,OAAO,CAAC,QAAQ,CAAC,CA0GrB,CAAC"}
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { alchemy } from "../alchemy.js";
|
|
2
|
+
import { Resource } from "../resource.js";
|
|
3
|
+
import { logger } from "../util/logger.js";
|
|
4
|
+
import { lowercaseId } from "../util/nanoid.js";
|
|
5
|
+
import { PlanetScaleApi } from "./api.js";
|
|
6
|
+
/**
|
|
7
|
+
* Create and manage database passwords for PlanetScale branches. Database passwords provide secure access to your database with specific roles and permissions.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ## Basic Reader Password
|
|
11
|
+
*
|
|
12
|
+
* Create a read-only password for a database branch:
|
|
13
|
+
*
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { Password } from "alchemy/planetscale";
|
|
16
|
+
*
|
|
17
|
+
* const readerPassword = await Password("app-reader", {
|
|
18
|
+
* name: "app-reader",
|
|
19
|
+
* organizationId: "my-org",
|
|
20
|
+
* database: "my-app-db",
|
|
21
|
+
* branch: "main",
|
|
22
|
+
* role: "reader"
|
|
23
|
+
* });
|
|
24
|
+
*
|
|
25
|
+
* // Access connection details
|
|
26
|
+
* console.log(`Host: ${readerPassword.password.host}`);
|
|
27
|
+
* console.log(`Username: ${readerPassword.password.username}`);
|
|
28
|
+
* console.log(`Password: ${readerPassword.password.password.unencrypted}`);
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ## Writer Password with TTL
|
|
33
|
+
*
|
|
34
|
+
* Create a writer password that expires after 24 hours:
|
|
35
|
+
*
|
|
36
|
+
* ```ts
|
|
37
|
+
* import { Password } from "alchemy/planetscale";
|
|
38
|
+
*
|
|
39
|
+
* const writerPassword = await Password("app-writer", {
|
|
40
|
+
* name: "app-writer",
|
|
41
|
+
* organizationId: "my-org",
|
|
42
|
+
* database: "my-app-db",
|
|
43
|
+
* branch: "development",
|
|
44
|
+
* role: "writer",
|
|
45
|
+
* ttl: 86400 // 24 hours in seconds
|
|
46
|
+
* });
|
|
47
|
+
*
|
|
48
|
+
* // Password will expire at the specified time
|
|
49
|
+
* console.log(`Expires at: ${writerPassword.expiresAt}`);
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ## Admin Password with IP Restrictions
|
|
54
|
+
*
|
|
55
|
+
* Create an admin password that only allows connections from specific IP addresses:
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* import { Password } from "alchemy/planetscale";
|
|
59
|
+
*
|
|
60
|
+
* const adminPassword = await Password("admin-access", {
|
|
61
|
+
* name: "admin-access",
|
|
62
|
+
* organizationId: "my-org",
|
|
63
|
+
* database: "my-app-db",
|
|
64
|
+
* branch: "main",
|
|
65
|
+
* role: "admin",
|
|
66
|
+
* cidrs: ["203.0.113.0/24", "198.51.100.0/24"],
|
|
67
|
+
* ttl: 3600 // 1 hour
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ## Database Password with Custom API Key
|
|
73
|
+
*
|
|
74
|
+
* Create a password using a specific API key instead of the default environment variable:
|
|
75
|
+
*
|
|
76
|
+
* ```ts
|
|
77
|
+
* import { Password } from "alchemy/planetscale";
|
|
78
|
+
*
|
|
79
|
+
* const password = await Password("custom-auth", {
|
|
80
|
+
* name: "custom-auth",
|
|
81
|
+
* organizationId: "my-org",
|
|
82
|
+
* database: "my-app-db",
|
|
83
|
+
* branch: "main",
|
|
84
|
+
* role: "readwriter",
|
|
85
|
+
* apiKey: alchemy.secret(process.env.CUSTOM_PLANETSCALE_TOKEN)
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ## Read Replica Password
|
|
91
|
+
*
|
|
92
|
+
* Create a password for accessing a read replica:
|
|
93
|
+
*
|
|
94
|
+
* ```ts
|
|
95
|
+
* import { Password } from "alchemy/planetscale";
|
|
96
|
+
*
|
|
97
|
+
* const replicaPassword = await Password("replica-reader", {
|
|
98
|
+
* name: "replica-reader",
|
|
99
|
+
* organizationId: "my-org",
|
|
100
|
+
* database: "my-app-db",
|
|
101
|
+
* branch: "main",
|
|
102
|
+
* role: "reader",
|
|
103
|
+
* replica: true
|
|
104
|
+
* });
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* ## Using Database Resource Instance
|
|
108
|
+
*
|
|
109
|
+
* Create a password using a Database resource instead of string:
|
|
110
|
+
*
|
|
111
|
+
* ```ts
|
|
112
|
+
* import { Database, Password } from "alchemy/planetscale";
|
|
113
|
+
*
|
|
114
|
+
* const database = await Database("my-db", {
|
|
115
|
+
* name: "my-app-db",
|
|
116
|
+
* organizationId: "my-org",
|
|
117
|
+
* clusterSize: "PS_10"
|
|
118
|
+
* });
|
|
119
|
+
*
|
|
120
|
+
* const password = await Password("db-reader", {
|
|
121
|
+
* name: "db-reader",
|
|
122
|
+
* database: database, // Using Database resource
|
|
123
|
+
* role: "reader"
|
|
124
|
+
* });
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* ## Using Both Database and Branch Resources
|
|
129
|
+
*
|
|
130
|
+
* Create a password using both Database and Branch resources:
|
|
131
|
+
*
|
|
132
|
+
* ```ts
|
|
133
|
+
* import { Database, Branch, Password } from "alchemy/planetscale";
|
|
134
|
+
*
|
|
135
|
+
* const database = await Database("my-db", {
|
|
136
|
+
* name: "my-app-db",
|
|
137
|
+
* organizationId: "my-org",
|
|
138
|
+
* clusterSize: "PS_10"
|
|
139
|
+
* });
|
|
140
|
+
*
|
|
141
|
+
* const branch = await Branch("feature-branch", {
|
|
142
|
+
* name: "feature-branch",
|
|
143
|
+
* organizationId: "my-org",
|
|
144
|
+
* databaseName: "my-app-db",
|
|
145
|
+
* parentBranch: "main",
|
|
146
|
+
* isProduction: false
|
|
147
|
+
* });
|
|
148
|
+
*
|
|
149
|
+
* const password = await Password("feature-writer", {
|
|
150
|
+
* name: "feature-writer",
|
|
151
|
+
* database: database, // Using Database resource
|
|
152
|
+
* branch: branch, // Using Branch resource
|
|
153
|
+
* role: "writer"
|
|
154
|
+
* });
|
|
155
|
+
* ```
|
|
156
|
+
* ```
|
|
157
|
+
*/
|
|
158
|
+
export const Password = Resource("planetscale::Password", async function (_id, props) {
|
|
159
|
+
const apiKey = props.apiKey?.unencrypted || process.env.PLANETSCALE_API_TOKEN;
|
|
160
|
+
if (!apiKey) {
|
|
161
|
+
throw new Error("PLANETSCALE_API_TOKEN environment variable is required");
|
|
162
|
+
}
|
|
163
|
+
const nameSlug = this.isReplacement
|
|
164
|
+
? lowercaseId()
|
|
165
|
+
: (this.output?.nameSlug ?? lowercaseId());
|
|
166
|
+
const name = `${props.name.toLowerCase()}-${nameSlug}`;
|
|
167
|
+
const api = new PlanetScaleApi({ apiKey });
|
|
168
|
+
const branchName = props.branch == null
|
|
169
|
+
? "main"
|
|
170
|
+
: typeof props.branch === "string"
|
|
171
|
+
? props.branch
|
|
172
|
+
: props.branch.name;
|
|
173
|
+
const databaseName = typeof props.database === "string" ? props.database : props.database.name;
|
|
174
|
+
if (this.phase === "delete") {
|
|
175
|
+
try {
|
|
176
|
+
if (this.output?.name) {
|
|
177
|
+
const response = await api.delete(`/organizations/${props.organizationId}/databases/${databaseName}/branches/${branchName}/passwords/${this.output.id}`);
|
|
178
|
+
if (!response.ok && response.status !== 404) {
|
|
179
|
+
throw new Error(`Failed to delete branch: ${response.statusText} ${await response.text()}`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
logger.error("Error deleting password:", error);
|
|
185
|
+
throw error;
|
|
186
|
+
}
|
|
187
|
+
return this.destroy();
|
|
188
|
+
}
|
|
189
|
+
if (this.phase === "update") {
|
|
190
|
+
if (this.output?.name === name &&
|
|
191
|
+
((this.output?.cidrs === undefined && props.cidrs === undefined) ||
|
|
192
|
+
(Array.isArray(this.output?.cidrs) &&
|
|
193
|
+
Array.isArray(props.cidrs) &&
|
|
194
|
+
this.output.cidrs.length === props.cidrs.length &&
|
|
195
|
+
this.output.cidrs.every((cidr, i) => cidr === props.cidrs[i])))) {
|
|
196
|
+
return this.replace();
|
|
197
|
+
}
|
|
198
|
+
const updateResponse = await api.patch(`/organizations/${props.organizationId}/databases/${databaseName}/branches/${branchName}/passwords/${this.output.id}`, {
|
|
199
|
+
name,
|
|
200
|
+
cidrs: props.cidrs,
|
|
201
|
+
});
|
|
202
|
+
if (!updateResponse.ok) {
|
|
203
|
+
throw new Error(`Failed to update password: ${updateResponse.statusText} ${await updateResponse.text()}`);
|
|
204
|
+
}
|
|
205
|
+
return this({
|
|
206
|
+
...this.output,
|
|
207
|
+
...props,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
try {
|
|
211
|
+
const createResponse = await api.post(`/organizations/${props.organizationId}/databases/${databaseName}/branches/${branchName}/passwords`, {
|
|
212
|
+
name,
|
|
213
|
+
role: props.role,
|
|
214
|
+
replica: props.replica,
|
|
215
|
+
ttl: props.ttl,
|
|
216
|
+
cidrs: props.cidrs,
|
|
217
|
+
});
|
|
218
|
+
if (!createResponse.ok) {
|
|
219
|
+
throw new Error(`Failed to create password: ${createResponse.statusText} ${await createResponse.text()}`);
|
|
220
|
+
}
|
|
221
|
+
const data = await createResponse.json();
|
|
222
|
+
return this({
|
|
223
|
+
id: data.id,
|
|
224
|
+
expiresAt: data.expires_at,
|
|
225
|
+
host: data.access_host_url,
|
|
226
|
+
username: data.username,
|
|
227
|
+
password: alchemy.secret(data.plain_text),
|
|
228
|
+
nameSlug,
|
|
229
|
+
...props,
|
|
230
|
+
name: `${props.name}-${nameSlug}`,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
catch (error) {
|
|
234
|
+
logger.error("Error managing password:", error);
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
//# sourceMappingURL=password.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"password.js","sourceRoot":"","sources":["../../src/planetscale/password.ts"],"names":[],"mappings":"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"}
|
package/lib/scope.d.ts
CHANGED
|
@@ -10,10 +10,9 @@ export declare class RootScopeStateAttemptError extends Error {
|
|
|
10
10
|
constructor();
|
|
11
11
|
}
|
|
12
12
|
export interface ScopeOptions {
|
|
13
|
-
appName?: string;
|
|
14
13
|
stage?: string;
|
|
15
|
-
parent
|
|
16
|
-
scopeName
|
|
14
|
+
parent: Scope | undefined;
|
|
15
|
+
scopeName: string;
|
|
17
16
|
password?: string;
|
|
18
17
|
stateStore?: StateStoreType;
|
|
19
18
|
quiet?: boolean;
|
|
@@ -26,6 +25,7 @@ export type PendingDeletions = Array<{
|
|
|
26
25
|
resource: Resource<string>;
|
|
27
26
|
oldProps?: ResourceProps;
|
|
28
27
|
}>;
|
|
28
|
+
export declare const DEFAULT_STAGE: string;
|
|
29
29
|
declare global {
|
|
30
30
|
var __ALCHEMY_STORAGE__: AsyncLocalStorage<Scope>;
|
|
31
31
|
var __ALCHEMY_GLOBALS__: Scope[];
|
|
@@ -42,9 +42,9 @@ export declare class Scope {
|
|
|
42
42
|
static get current(): Scope;
|
|
43
43
|
readonly resources: Map<string, PendingResource<unknown>>;
|
|
44
44
|
readonly children: Map<ResourceID, Scope>;
|
|
45
|
-
readonly appName: string | undefined;
|
|
46
45
|
readonly stage: string;
|
|
47
|
-
readonly
|
|
46
|
+
readonly name: string;
|
|
47
|
+
readonly scopeName: string;
|
|
48
48
|
readonly parent: Scope | undefined;
|
|
49
49
|
readonly password: string | undefined;
|
|
50
50
|
readonly state: StateStore;
|
|
@@ -59,6 +59,7 @@ export declare class Scope {
|
|
|
59
59
|
private finalized;
|
|
60
60
|
private startedAt;
|
|
61
61
|
private deferred;
|
|
62
|
+
get appName(): string;
|
|
62
63
|
constructor(options: ScopeOptions);
|
|
63
64
|
get root(): Scope;
|
|
64
65
|
deleteResource(resourceID: ResourceID): Promise<void>;
|
package/lib/scope.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../src/scope.ts"],"names":[],"mappings":"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"}
|
package/lib/scope.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import util from "node:util";
|
|
3
|
+
import { DOStateStore } from "./cloudflare/do-state-store/index.js";
|
|
3
4
|
import { destroy, destroyAll } from "./destroy.js";
|
|
4
5
|
import { FileSystemStateStore } from "./fs/file-system-state-store.js";
|
|
5
6
|
import { ResourceFQN, ResourceID, ResourceKind, ResourceScope, ResourceSeq, } from "./resource.js";
|
|
@@ -11,7 +12,7 @@ export class RootScopeStateAttemptError extends Error {
|
|
|
11
12
|
}
|
|
12
13
|
}
|
|
13
14
|
// TODO: support browser
|
|
14
|
-
const DEFAULT_STAGE = process.env.ALCHEMY_STAGE ??
|
|
15
|
+
export const DEFAULT_STAGE = process.env.ALCHEMY_STAGE ??
|
|
15
16
|
process.env.USER ??
|
|
16
17
|
process.env.USERNAME ??
|
|
17
18
|
"dev";
|
|
@@ -46,8 +47,8 @@ export class Scope {
|
|
|
46
47
|
}
|
|
47
48
|
resources = new Map();
|
|
48
49
|
children = new Map();
|
|
49
|
-
appName;
|
|
50
50
|
stage;
|
|
51
|
+
name;
|
|
51
52
|
scopeName;
|
|
52
53
|
parent;
|
|
53
54
|
password;
|
|
@@ -63,13 +64,21 @@ export class Scope {
|
|
|
63
64
|
finalized = false;
|
|
64
65
|
startedAt = performance.now();
|
|
65
66
|
deferred = [];
|
|
67
|
+
get appName() {
|
|
68
|
+
if (this.parent) {
|
|
69
|
+
return this.parent.appName;
|
|
70
|
+
}
|
|
71
|
+
return this.scopeName;
|
|
72
|
+
}
|
|
66
73
|
constructor(options) {
|
|
67
|
-
this.
|
|
68
|
-
this.
|
|
69
|
-
|
|
74
|
+
this.scopeName = options.scopeName;
|
|
75
|
+
this.name = this.scopeName;
|
|
76
|
+
this.parent = options.parent ?? Scope.getScope();
|
|
77
|
+
const isChild = this.parent !== undefined;
|
|
78
|
+
if (this.scopeName?.includes(":") && isChild) {
|
|
79
|
+
// TODO(sam): relax this constraint once we move to SQLite3 store
|
|
70
80
|
throw new Error(`Scope name "${this.scopeName}" cannot contain double colons`);
|
|
71
81
|
}
|
|
72
|
-
this.parent = options.parent ?? Scope.getScope();
|
|
73
82
|
this.stage = options?.stage ?? this.parent?.stage ?? DEFAULT_STAGE;
|
|
74
83
|
this.parent?.children.set(this.scopeName, this);
|
|
75
84
|
this.quiet = options.quiet ?? this.parent?.quiet ?? false;
|
|
@@ -96,7 +105,9 @@ export class Scope {
|
|
|
96
105
|
this.stateStore =
|
|
97
106
|
options.stateStore ??
|
|
98
107
|
this.parent?.stateStore ??
|
|
99
|
-
((scope) =>
|
|
108
|
+
((scope) => process.env.ALCHEMY_STATE_STORE === "cloudflare"
|
|
109
|
+
? new DOStateStore(scope)
|
|
110
|
+
: new FileSystemStateStore(scope));
|
|
100
111
|
this.state = this.stateStore(this);
|
|
101
112
|
if (!options.telemetryClient && !this.parent?.telemetryClient) {
|
|
102
113
|
throw new Error("Telemetry client is required");
|