alchemy 0.73.1 → 0.74.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 +3311 -4413
- package/bin/alchemy.ts +2 -0
- package/bin/commands/configure.ts +4 -1
- package/bin/commands/util.ts +510 -0
- package/lib/cloudflare/bound.d.ts +1 -1
- package/lib/cloudflare/bound.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.js +6 -14
- package/lib/cloudflare/miniflare/miniflare-worker-proxy.js.map +1 -1
- package/lib/cloudflare/miniflare/remote-binding-proxy.d.ts.map +1 -1
- package/lib/cloudflare/miniflare/remote-binding-proxy.js +12 -4
- package/lib/cloudflare/miniflare/remote-binding-proxy.js.map +1 -1
- package/lib/cloudflare/tanstack-start/tanstack-start.d.ts.map +1 -1
- package/lib/cloudflare/tanstack-start/tanstack-start.js +8 -1
- package/lib/cloudflare/tanstack-start/tanstack-start.js.map +1 -1
- package/lib/cloudflare/vite/plugin.d.ts.map +1 -1
- package/lib/cloudflare/vite/plugin.js +23 -9
- package/lib/cloudflare/vite/plugin.js.map +1 -1
- package/lib/planetscale/branch.d.ts +6 -0
- package/lib/planetscale/branch.d.ts.map +1 -1
- package/lib/planetscale/branch.js +2 -1
- package/lib/planetscale/branch.js.map +1 -1
- package/lib/planetscale/database.d.ts +6 -0
- package/lib/planetscale/database.d.ts.map +1 -1
- package/lib/planetscale/database.js +2 -1
- package/lib/planetscale/database.js.map +1 -1
- package/lib/planetscale/password.d.ts +6 -0
- package/lib/planetscale/password.d.ts.map +1 -1
- package/lib/planetscale/password.js +2 -1
- package/lib/planetscale/password.js.map +1 -1
- package/lib/planetscale/role.d.ts +6 -0
- package/lib/planetscale/role.d.ts.map +1 -1
- package/lib/planetscale/role.js +2 -1
- package/lib/planetscale/role.js.map +1 -1
- package/lib/prisma-postgres/api/client.gen.d.ts +13 -0
- package/lib/prisma-postgres/api/client.gen.d.ts.map +1 -0
- package/lib/prisma-postgres/api/client.gen.js +6 -0
- package/lib/prisma-postgres/api/client.gen.js.map +1 -0
- package/lib/prisma-postgres/api/sdk.gen.d.ts +120 -0
- package/lib/prisma-postgres/api/sdk.gen.d.ts.map +1 -0
- package/lib/prisma-postgres/api/sdk.gen.js +219 -0
- package/lib/prisma-postgres/api/sdk.gen.js.map +1 -0
- package/lib/prisma-postgres/api/types.gen.d.ts +957 -0
- package/lib/prisma-postgres/api/types.gen.d.ts.map +1 -0
- package/lib/prisma-postgres/api/types.gen.js +2 -0
- package/lib/prisma-postgres/api/types.gen.js.map +1 -0
- package/lib/prisma-postgres/api.d.ts +29 -0
- package/lib/prisma-postgres/api.d.ts.map +1 -0
- package/lib/prisma-postgres/api.js +49 -0
- package/lib/prisma-postgres/api.js.map +1 -0
- package/lib/prisma-postgres/connection.d.ts +87 -0
- package/lib/prisma-postgres/connection.d.ts.map +1 -0
- package/lib/prisma-postgres/connection.js +73 -0
- package/lib/prisma-postgres/connection.js.map +1 -0
- package/lib/prisma-postgres/database.d.ts +104 -0
- package/lib/prisma-postgres/database.d.ts.map +1 -0
- package/lib/prisma-postgres/database.js +88 -0
- package/lib/prisma-postgres/database.js.map +1 -0
- package/lib/prisma-postgres/index.d.ts +5 -0
- package/lib/prisma-postgres/index.d.ts.map +1 -0
- package/lib/prisma-postgres/index.js +5 -0
- package/lib/prisma-postgres/index.js.map +1 -0
- package/lib/prisma-postgres/project.d.ts +69 -0
- package/lib/prisma-postgres/project.d.ts.map +1 -0
- package/lib/prisma-postgres/project.js +62 -0
- package/lib/prisma-postgres/project.js.map +1 -0
- package/lib/prisma-postgres/workspace.d.ts +18 -0
- package/lib/prisma-postgres/workspace.d.ts.map +1 -0
- package/lib/prisma-postgres/workspace.js +21 -0
- package/lib/prisma-postgres/workspace.js.map +1 -0
- package/lib/util/http.d.ts +5 -2
- package/lib/util/http.d.ts.map +1 -1
- package/lib/util/http.js +71 -26
- package/lib/util/http.js.map +1 -1
- package/package.json +9 -1
- package/src/cloudflare/bound.ts +3 -1
- package/src/cloudflare/miniflare/miniflare-worker-proxy.ts +10 -13
- package/src/cloudflare/miniflare/remote-binding-proxy.ts +12 -4
- package/src/cloudflare/tanstack-start/tanstack-start.ts +9 -1
- package/src/cloudflare/vite/plugin.ts +24 -10
- package/src/planetscale/branch.ts +9 -1
- package/src/planetscale/database.ts +9 -1
- package/src/planetscale/password.ts +9 -1
- package/src/planetscale/role.ts +9 -1
- package/src/prisma-postgres/api/client.gen.ts +27 -0
- package/src/prisma-postgres/api/sdk.gen.ts +437 -0
- package/src/prisma-postgres/api/types.gen.ts +1096 -0
- package/src/prisma-postgres/api.ts +79 -0
- package/src/prisma-postgres/connection.ts +154 -0
- package/src/prisma-postgres/database.ts +178 -0
- package/src/prisma-postgres/index.ts +4 -0
- package/src/prisma-postgres/project.ts +131 -0
- package/src/prisma-postgres/workspace.ts +27 -0
- package/src/util/http.ts +79 -33
- package/workers/cloudflare-state-store.js +1 -1
- package/workers/tunnel-proxy.js +1 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Resource } from "../resource.js";
|
|
2
|
+
import { createPrismaApi } from "./api.js";
|
|
3
|
+
/**
|
|
4
|
+
* Creates and manages Prisma Postgres projects.
|
|
5
|
+
*
|
|
6
|
+
* Prisma Postgres projects are containers for your databases and
|
|
7
|
+
* their configurations. Projects belong to a workspace and can
|
|
8
|
+
* contain multiple databases.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* // Create a database for a project
|
|
12
|
+
* import { Project, Database } from "alchemy/prisma-postgres";
|
|
13
|
+
* const project = await Project("my-app");
|
|
14
|
+
*/
|
|
15
|
+
export const Project = Resource("prisma::Project", async function (id, props) {
|
|
16
|
+
const api = createPrismaApi({
|
|
17
|
+
serviceToken: props?.serviceToken,
|
|
18
|
+
});
|
|
19
|
+
const name = props?.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
|
|
20
|
+
const shouldDelete = props?.delete ?? false;
|
|
21
|
+
if (this.phase === "delete") {
|
|
22
|
+
if (shouldDelete) {
|
|
23
|
+
await api.deleteProject({
|
|
24
|
+
path: { id: this.output.id },
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return this.destroy();
|
|
28
|
+
}
|
|
29
|
+
if (this.phase === "update") {
|
|
30
|
+
return this.replace();
|
|
31
|
+
}
|
|
32
|
+
const project = await api
|
|
33
|
+
.createProjectWithPostgresDatabase({
|
|
34
|
+
body: {
|
|
35
|
+
createDatabase: false,
|
|
36
|
+
name,
|
|
37
|
+
//! prisma seems to not support setting the workspace on project creation?
|
|
38
|
+
},
|
|
39
|
+
})
|
|
40
|
+
.then((response) => response.data.data);
|
|
41
|
+
return {
|
|
42
|
+
id: project.id,
|
|
43
|
+
name: project.name,
|
|
44
|
+
createdAt: project.createdAt,
|
|
45
|
+
workspace: project.workspace,
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
export async function findProjectByName(props) {
|
|
49
|
+
const api = createPrismaApi(props);
|
|
50
|
+
let hasMore = true;
|
|
51
|
+
let project;
|
|
52
|
+
while (hasMore) {
|
|
53
|
+
const response = await api.listProjects();
|
|
54
|
+
project = response.data.data.find((project) => project.name === props.name);
|
|
55
|
+
if (project != null) {
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
hasMore = response.data.pagination.hasMore;
|
|
59
|
+
}
|
|
60
|
+
return project;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/prisma-postgres/project.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAqD3C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAC7B,iBAAiB,EACjB,KAAK,WAEH,EAAU,EACV,KAAoB;IAEpB,MAAM,GAAG,GAAG,eAAe,CAAC;QAC1B,YAAY,EAAE,KAAK,EAAE,YAAY;KAClC,CAAC,CAAC;IACH,MAAM,IAAI,GACR,KAAK,EAAE,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;IACxE,MAAM,YAAY,GAAG,KAAK,EAAE,MAAM,IAAI,KAAK,CAAC;IAE5C,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,GAAG,CAAC,aAAa,CAAC;gBACtB,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE;aAC7B,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IACxB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,GAAG;SACtB,iCAAiC,CAAC;QACjC,IAAI,EAAE;YACJ,cAAc,EAAE,KAAK;YACrB,IAAI;YACJ,0EAA0E;SAC3E;KACF,CAAC;SACD,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAK,CAAC,CAAC;IAE3C,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,EAAE;QACd,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC;AACJ,CAAC,CACF,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAmB;IACzD,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IACnC,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,OAIS,CAAC;IACd,OAAO,OAAO,EAAE,CAAC;QACf,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,YAAY,EAAE,CAAC;QAC1C,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5E,IAAI,OAAO,IAAI,IAAI,EAAE,CAAC;YACpB,MAAM;QACR,CAAC;QACD,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;IAC7C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type PrismaApiOptions } from "./api.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Get a prisma workspace by id or name.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const workspace = await WorkspaceRef("alchemy-test");
|
|
7
|
+
*
|
|
8
|
+
* @param identifier The id or name of the workspace to get.
|
|
9
|
+
* @param props The api credentials to use.
|
|
10
|
+
* @returns The workspace.
|
|
11
|
+
*/
|
|
12
|
+
export declare function WorkspaceRef(identifier: string, props?: PrismaApiOptions): Promise<{
|
|
13
|
+
id: string;
|
|
14
|
+
type: "workspace";
|
|
15
|
+
name: string;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
}>;
|
|
18
|
+
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/prisma-postgres/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAElE;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,gBAAgB;;;;;GAYzB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { createPrismaApi } from "./api.js";
|
|
2
|
+
/**
|
|
3
|
+
* Get a prisma workspace by id or name.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* const workspace = await WorkspaceRef("alchemy-test");
|
|
7
|
+
*
|
|
8
|
+
* @param identifier The id or name of the workspace to get.
|
|
9
|
+
* @param props The api credentials to use.
|
|
10
|
+
* @returns The workspace.
|
|
11
|
+
*/
|
|
12
|
+
export async function WorkspaceRef(identifier, props) {
|
|
13
|
+
const api = createPrismaApi(props);
|
|
14
|
+
const workspaces = await api.listWorkspaces();
|
|
15
|
+
const workspace = workspaces.data.data.find((workspace) => workspace.id === identifier || workspace.name === identifier);
|
|
16
|
+
if (!workspace) {
|
|
17
|
+
throw new Error(`Workspace with identifier ${identifier} not found`);
|
|
18
|
+
}
|
|
19
|
+
return workspace;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=workspace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../src/prisma-postgres/workspace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAyB,MAAM,UAAU,CAAC;AAElE;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,UAAkB,EAClB,KAAwB;IAExB,MAAM,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;IAEnC,MAAM,UAAU,GAAG,MAAM,GAAG,CAAC,cAAc,EAAE,CAAC;IAC9C,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CACzC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,EAAE,KAAK,UAAU,IAAI,SAAS,CAAC,IAAI,KAAK,UAAU,CAC5E,CAAC;IACF,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,YAAY,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/lib/util/http.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import http from "node:http";
|
|
2
2
|
import { type Duplex } from "node:stream";
|
|
3
|
-
import {
|
|
3
|
+
import { WebSocket, WebSocketServer } from "ws";
|
|
4
4
|
export declare class HTTPServer {
|
|
5
5
|
httpServer: http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>;
|
|
6
6
|
webSocketServer?: WebSocketServer;
|
|
@@ -12,7 +12,10 @@ export declare class HTTPServer {
|
|
|
12
12
|
get url(): string;
|
|
13
13
|
close(): Promise<void>;
|
|
14
14
|
}
|
|
15
|
-
export declare function
|
|
15
|
+
export declare function createUpgradeHandler(props: {
|
|
16
|
+
wss: WebSocketServer;
|
|
17
|
+
createServerWebSocket: (req: http.IncomingMessage) => Promise<WebSocket>;
|
|
18
|
+
}): (req: http.IncomingMessage, socket: Duplex, head: Buffer) => Promise<void>;
|
|
16
19
|
export declare function toWebRequest(req: http.IncomingMessage, host?: string): Request;
|
|
17
20
|
export declare function writeNodeResponse(res: http.ServerResponse, response: Response): Promise<void>;
|
|
18
21
|
//# sourceMappingURL=http.d.ts.map
|
package/lib/util/http.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/util/http.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/util/http.ts"],"names":[],"mappings":"AACA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,KAAK,MAAM,EAAY,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAEhD,qBAAa,UAAU;IACrB,UAAU,uEAAuB;IACjC,eAAe,CAAC,EAAE,eAAe,CAAC;gBAEtB,OAAO,EAAE;QACnB,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;QACrD,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;KAChD;IAmBD,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM;IAYpB,IAAI,GAAG,WAON;IAEK,KAAK;CAIZ;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAC1C,GAAG,EAAE,eAAe,CAAC;IACrB,qBAAqB,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;CAC1E,IAoDe,KAAK,IAAI,CAAC,eAAe,EAAE,QAAQ,MAAM,EAAE,MAAM,MAAM,mBAQtE;AAED,wBAAgB,YAAY,CAC1B,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAeT;AAED,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,QAAQ,EAAE,QAAQ,iBAoBnB"}
|
package/lib/util/http.js
CHANGED
|
@@ -1,23 +1,24 @@
|
|
|
1
|
+
import { once } from "node:events";
|
|
1
2
|
import http from "node:http";
|
|
2
3
|
import { Readable } from "node:stream";
|
|
3
|
-
import { WebSocketServer } from "ws";
|
|
4
|
+
import { WebSocket, WebSocketServer } from "ws";
|
|
4
5
|
export class HTTPServer {
|
|
5
6
|
httpServer = http.createServer();
|
|
6
7
|
webSocketServer;
|
|
7
8
|
constructor(options) {
|
|
9
|
+
const websocket = options.websocket;
|
|
10
|
+
if (websocket) {
|
|
11
|
+
const wss = new WebSocketServer({ noServer: true });
|
|
12
|
+
this.webSocketServer = wss;
|
|
13
|
+
this.httpServer.on("upgrade", createUpgradeHandler({
|
|
14
|
+
wss,
|
|
15
|
+
createServerWebSocket: (req) => websocket(toWebRequest(req)),
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
8
18
|
this.httpServer.on("request", async (req, res) => {
|
|
9
19
|
const response = await options.fetch(toWebRequest(req));
|
|
10
20
|
await writeNodeResponse(res, response);
|
|
11
21
|
});
|
|
12
|
-
const websocket = options.websocket;
|
|
13
|
-
if (websocket) {
|
|
14
|
-
const webSocketServer = new WebSocketServer({ noServer: true });
|
|
15
|
-
this.webSocketServer = webSocketServer;
|
|
16
|
-
this.httpServer.on("upgrade", async (req, socket, head) => {
|
|
17
|
-
const ws = await websocket(toWebRequest(req));
|
|
18
|
-
coupleWebSocket(webSocketServer, req, socket, head, ws);
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
22
|
}
|
|
22
23
|
listen(port) {
|
|
23
24
|
return new Promise((resolve, reject) => {
|
|
@@ -39,25 +40,69 @@ export class HTTPServer {
|
|
|
39
40
|
return `http://${hostname}:${address.port}`;
|
|
40
41
|
}
|
|
41
42
|
async close() {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
this.webSocketServer?.close();
|
|
44
|
+
this.httpServer.close();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function createUpgradeHandler(props) {
|
|
48
|
+
async function waitForWebSocketOpen(server) {
|
|
49
|
+
if (server.readyState === WebSocket.CONNECTING) {
|
|
50
|
+
// Wait for client to be open before accepting worker pair (which would
|
|
51
|
+
// release buffered messages). Note this will throw if an "error" event is
|
|
52
|
+
// dispatched (https://github.com/cloudflare/miniflare/issues/229).
|
|
53
|
+
await once(server, "open");
|
|
54
|
+
}
|
|
55
|
+
else if (server.readyState >= WebSocket.CLOSING) {
|
|
56
|
+
throw new TypeError("Incoming WebSocket connection already closed.");
|
|
47
57
|
}
|
|
48
|
-
|
|
49
|
-
|
|
58
|
+
}
|
|
59
|
+
function forwardWebSocketEvents(from, to) {
|
|
60
|
+
const ready = waitForWebSocketOpen(to);
|
|
61
|
+
const ifOpen = (fn) => {
|
|
62
|
+
// Wait for target to be open before sending message
|
|
63
|
+
void ready.then(() => {
|
|
64
|
+
// Silently discard messages received after close:
|
|
65
|
+
// https://www.rfc-editor.org/rfc/rfc6455#section-1.4
|
|
66
|
+
if (to.readyState !== WebSocket.OPEN)
|
|
67
|
+
return;
|
|
68
|
+
fn();
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
from.on("message", (event, binary) => {
|
|
72
|
+
ifOpen(() => {
|
|
73
|
+
to.send(event, { binary });
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
from.on("close", (code, reason) => {
|
|
77
|
+
// Handle close events similar to Miniflare:
|
|
78
|
+
// https://github.com/cloudflare/workers-sdk/blob/88f081f4e2bd299e715d18bcfe181971f534ff76/packages/miniflare/src/http/websocket.ts#L276-L282
|
|
79
|
+
ifOpen(() => {
|
|
80
|
+
if (code === 1005 /* No Status Received */) {
|
|
81
|
+
to.close();
|
|
82
|
+
}
|
|
83
|
+
else if (code === 1006 /* Abnormal Closure */) {
|
|
84
|
+
to.terminate();
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
to.close(code, reason);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
from.on("error", (error) => {
|
|
92
|
+
console.error("Websocket error:", error);
|
|
93
|
+
ifOpen(() => {
|
|
94
|
+
to.terminate();
|
|
95
|
+
});
|
|
50
96
|
});
|
|
51
97
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
});
|
|
98
|
+
return async (req, socket, head) => {
|
|
99
|
+
const server = await props.createServerWebSocket(req);
|
|
100
|
+
props.wss.handleUpgrade(req, socket, head, async (client) => {
|
|
101
|
+
forwardWebSocketEvents(server, client);
|
|
102
|
+
forwardWebSocketEvents(client, server);
|
|
103
|
+
props.wss.emit("connection", client, req);
|
|
104
|
+
});
|
|
105
|
+
};
|
|
61
106
|
}
|
|
62
107
|
export function toWebRequest(req, host) {
|
|
63
108
|
const method = req.method ?? "GET";
|
package/lib/util/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/util/http.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/util/http.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alchemy",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.74.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"author": "Sam Goodwin <sam@alchemy.run>",
|
|
6
6
|
"homepage": "https://alchemy.run",
|
|
@@ -128,6 +128,10 @@
|
|
|
128
128
|
"bun": "./src/planetscale/index.ts",
|
|
129
129
|
"import": "./lib/planetscale/index.js"
|
|
130
130
|
},
|
|
131
|
+
"./prisma-postgres": {
|
|
132
|
+
"bun": "./src/prisma-postgres/index.ts",
|
|
133
|
+
"import": "./lib/prisma-postgres/index.js"
|
|
134
|
+
},
|
|
131
135
|
"./random": {
|
|
132
136
|
"bun": "./src/random/index.ts",
|
|
133
137
|
"import": "./lib/random/index.js"
|
|
@@ -209,6 +213,7 @@
|
|
|
209
213
|
"drizzle-orm": "^0.44.2",
|
|
210
214
|
"rwsdk": "^0.1.36",
|
|
211
215
|
"stripe": "^18.5.0",
|
|
216
|
+
"vite": ">=6.0.0",
|
|
212
217
|
"wrangler": "^4.42.2"
|
|
213
218
|
},
|
|
214
219
|
"peerDependenciesMeta": {
|
|
@@ -262,6 +267,9 @@
|
|
|
262
267
|
},
|
|
263
268
|
"stripe": {
|
|
264
269
|
"optional": true
|
|
270
|
+
},
|
|
271
|
+
"vite": {
|
|
272
|
+
"optional": true
|
|
265
273
|
}
|
|
266
274
|
},
|
|
267
275
|
"devDependencies": {
|
package/src/cloudflare/bound.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { once } from "node:events";
|
|
|
3
3
|
import http from "node:http";
|
|
4
4
|
import { Readable } from "node:stream";
|
|
5
5
|
import { WebSocket, WebSocketServer } from "ws";
|
|
6
|
-
import {
|
|
6
|
+
import { createUpgradeHandler } from "../../util/http.ts";
|
|
7
7
|
|
|
8
8
|
export interface MiniflareWorkerProxy {
|
|
9
9
|
url: URL;
|
|
@@ -20,15 +20,14 @@ export async function createMiniflareWorkerProxy(options: {
|
|
|
20
20
|
const server = http.createServer();
|
|
21
21
|
const wss = new WebSocketServer({ noServer: true });
|
|
22
22
|
|
|
23
|
-
server.on(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
});
|
|
23
|
+
server.on(
|
|
24
|
+
"upgrade",
|
|
25
|
+
createUpgradeHandler({
|
|
26
|
+
wss,
|
|
27
|
+
createServerWebSocket: (req) => createServerWebSocket(req),
|
|
28
|
+
}),
|
|
29
|
+
);
|
|
30
|
+
|
|
32
31
|
server.on("request", async (req, res) => {
|
|
33
32
|
try {
|
|
34
33
|
const response = await handleFetch(req);
|
|
@@ -84,13 +83,11 @@ export async function createMiniflareWorkerProxy(options: {
|
|
|
84
83
|
options.transformRequest?.(info);
|
|
85
84
|
const name = options.getWorkerName(info);
|
|
86
85
|
|
|
87
|
-
|
|
86
|
+
return new WebSocket(url, protocols, {
|
|
88
87
|
headers: {
|
|
89
88
|
"MF-Route-Override": name,
|
|
90
89
|
},
|
|
91
90
|
});
|
|
92
|
-
await once(server, "open");
|
|
93
|
-
return server;
|
|
94
91
|
};
|
|
95
92
|
|
|
96
93
|
server.listen(options.port);
|
|
@@ -61,11 +61,19 @@ export async function createRemoteProxyWorker(input: {
|
|
|
61
61
|
websocket: async (req) => {
|
|
62
62
|
const input = new URL(req.url);
|
|
63
63
|
const proxied = new URL(input.pathname + input.search, `https://${host}`);
|
|
64
|
+
const headers: Record<string, string> = {
|
|
65
|
+
"cf-workers-preview-token": token,
|
|
66
|
+
host,
|
|
67
|
+
};
|
|
68
|
+
// We don't want to include all headers because some can mess with websocket connections.
|
|
69
|
+
// However, it's important to include `mf-` prefixed headers to configure bindings for miniflare to work.
|
|
70
|
+
req.headers.forEach((value, key) => {
|
|
71
|
+
if (key.startsWith("mf-")) {
|
|
72
|
+
headers[key] = value;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
64
75
|
return new WebSocket(proxied, {
|
|
65
|
-
headers
|
|
66
|
-
"cf-workers-preview-token": token,
|
|
67
|
-
host,
|
|
68
|
-
},
|
|
76
|
+
headers,
|
|
69
77
|
});
|
|
70
78
|
},
|
|
71
79
|
fetch: async (req) => {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { exists } from "../../util/exists.ts";
|
|
1
3
|
import type { Assets } from "../assets.ts";
|
|
2
4
|
import type { Bindings } from "../bindings.ts";
|
|
3
5
|
import { Vite, type ViteProps } from "../vite/vite.ts";
|
|
@@ -14,6 +16,11 @@ export async function TanStackStart<B extends Bindings>(
|
|
|
14
16
|
id: string,
|
|
15
17
|
props?: Partial<TanStackStartProps<B>>,
|
|
16
18
|
): Promise<TanStackStart<B>> {
|
|
19
|
+
const main =
|
|
20
|
+
props?.wrangler?.main ??
|
|
21
|
+
((await exists(path.resolve(props?.cwd ?? process.cwd(), "src/server.ts")))
|
|
22
|
+
? "src/server.ts"
|
|
23
|
+
: undefined);
|
|
17
24
|
return await Vite(id, {
|
|
18
25
|
entrypoint: "dist/server/index.js",
|
|
19
26
|
assets: "dist/client",
|
|
@@ -23,9 +30,10 @@ export async function TanStackStart<B extends Bindings>(
|
|
|
23
30
|
...props,
|
|
24
31
|
wrangler: {
|
|
25
32
|
...props?.wrangler,
|
|
33
|
+
main,
|
|
26
34
|
transform: async (spec) => {
|
|
27
35
|
const transformed = (await props?.wrangler?.transform?.(spec)) ?? spec;
|
|
28
|
-
if (!
|
|
36
|
+
if (!main) {
|
|
29
37
|
transformed.main = "@tanstack/react-start/server-entry";
|
|
30
38
|
}
|
|
31
39
|
return transformed;
|
|
@@ -20,17 +20,31 @@ const alchemy = (config?: PluginConfig): PluginOption => {
|
|
|
20
20
|
if (typeof persistState === "object" && persistState.path.endsWith("v3")) {
|
|
21
21
|
persistState.path = path.dirname(persistState.path);
|
|
22
22
|
}
|
|
23
|
-
return
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
23
|
+
return [
|
|
24
|
+
cloudflare({
|
|
25
|
+
...config,
|
|
26
|
+
configPath: validateConfigPath(
|
|
27
|
+
// config path doesn't need to be in the root, it can be in the app dir
|
|
28
|
+
config?.configPath ?? getDefaultConfigPath(),
|
|
29
|
+
),
|
|
30
|
+
persistState,
|
|
31
|
+
experimental: config?.experimental ?? {
|
|
32
|
+
remoteBindings: true,
|
|
33
|
+
},
|
|
34
|
+
}),
|
|
35
|
+
{
|
|
36
|
+
name: "alchemy-supress-watch",
|
|
37
|
+
config() {
|
|
38
|
+
return {
|
|
39
|
+
server: {
|
|
40
|
+
watch: {
|
|
41
|
+
ignored: ["**/.alchemy/**"],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
},
|
|
32
46
|
},
|
|
33
|
-
|
|
47
|
+
] as PluginOption;
|
|
34
48
|
};
|
|
35
49
|
|
|
36
50
|
export default alchemy;
|
|
@@ -43,6 +43,13 @@ export interface BranchProps extends PlanetScaleProps {
|
|
|
43
43
|
*/
|
|
44
44
|
adopt?: boolean;
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Whether to delete the branch when the resource is destroyed.
|
|
48
|
+
* When false, the branch will only be removed from the state but not deleted via API.
|
|
49
|
+
* @default true
|
|
50
|
+
*/
|
|
51
|
+
delete?: boolean;
|
|
52
|
+
|
|
46
53
|
/**
|
|
47
54
|
* The parent branch name or Branch object
|
|
48
55
|
* @default "main"
|
|
@@ -179,6 +186,7 @@ export const Branch = Resource(
|
|
|
179
186
|
(typeof props.database === "string"
|
|
180
187
|
? props.database
|
|
181
188
|
: props.database.name);
|
|
189
|
+
const shouldDelete = props.delete ?? false;
|
|
182
190
|
|
|
183
191
|
if (!organization) {
|
|
184
192
|
throw new Error(
|
|
@@ -192,7 +200,7 @@ export const Branch = Resource(
|
|
|
192
200
|
}
|
|
193
201
|
|
|
194
202
|
if (this.phase === "delete") {
|
|
195
|
-
if (this.output?.name) {
|
|
203
|
+
if (shouldDelete && this.output?.name) {
|
|
196
204
|
const response = await api.deleteBranch({
|
|
197
205
|
path: {
|
|
198
206
|
organization,
|
|
@@ -28,6 +28,13 @@ interface BaseDatabaseProps extends PlanetScaleProps {
|
|
|
28
28
|
*/
|
|
29
29
|
adopt?: boolean;
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Whether to delete the database when the resource is destroyed.
|
|
33
|
+
* When false, the database will only be removed from the state but not deleted via API.
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
delete?: boolean;
|
|
37
|
+
|
|
31
38
|
/**
|
|
32
39
|
* The region where the database will be created (create only)
|
|
33
40
|
*/
|
|
@@ -227,6 +234,7 @@ export const Database = Resource(
|
|
|
227
234
|
"PlanetScale organization is required. Please set the `organization` property or the `PLANETSCALE_ORGANIZATION` environment variable.",
|
|
228
235
|
);
|
|
229
236
|
}
|
|
237
|
+
const shouldDelete = props.delete ?? false;
|
|
230
238
|
|
|
231
239
|
if (this.phase === "update" && this.output.name !== databaseName) {
|
|
232
240
|
await api.updateDatabaseSettings({
|
|
@@ -239,7 +247,7 @@ export const Database = Resource(
|
|
|
239
247
|
}
|
|
240
248
|
|
|
241
249
|
if (this.phase === "delete") {
|
|
242
|
-
if (this.output?.name) {
|
|
250
|
+
if (shouldDelete && this.output?.name) {
|
|
243
251
|
const response = await api.deleteDatabase({
|
|
244
252
|
path: {
|
|
245
253
|
organization,
|
|
@@ -58,6 +58,13 @@ export interface PasswordProps extends PlanetScaleProps {
|
|
|
58
58
|
* The CIDRs of the password
|
|
59
59
|
*/
|
|
60
60
|
cidrs?: string[];
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Whether to delete the password when the resource is destroyed.
|
|
64
|
+
* When false, the password will only be removed from the state but not deleted via API.
|
|
65
|
+
* @default true
|
|
66
|
+
*/
|
|
67
|
+
delete?: boolean;
|
|
61
68
|
}
|
|
62
69
|
|
|
63
70
|
/**
|
|
@@ -293,6 +300,7 @@ export const Password = Resource(
|
|
|
293
300
|
typeof props.branch === "string"
|
|
294
301
|
? props.branch
|
|
295
302
|
: (props.branch?.name ?? "main");
|
|
303
|
+
const shouldDelete = props.delete ?? false;
|
|
296
304
|
if (!organization) {
|
|
297
305
|
throw new Error(
|
|
298
306
|
"PlanetScale organization is required. Please set the `organization` property or the `PLANETSCALE_ORGANIZATION` environment variable.",
|
|
@@ -300,7 +308,7 @@ export const Password = Resource(
|
|
|
300
308
|
}
|
|
301
309
|
|
|
302
310
|
if (this.phase === "delete") {
|
|
303
|
-
if (this.output?.id) {
|
|
311
|
+
if (shouldDelete && this.output?.id) {
|
|
304
312
|
const res = await api.deletePassword({
|
|
305
313
|
path: {
|
|
306
314
|
organization,
|
package/src/planetscale/role.ts
CHANGED
|
@@ -44,6 +44,13 @@ export interface RoleProps extends PlanetScaleProps {
|
|
|
44
44
|
* You can also inherit from another Role resource.
|
|
45
45
|
*/
|
|
46
46
|
inheritedRoles: InheritedRole[] | Role;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Whether to delete the role when the resource is destroyed.
|
|
50
|
+
* When false, the role will only be removed from the state but not deleted via API.
|
|
51
|
+
* @default true
|
|
52
|
+
*/
|
|
53
|
+
delete?: boolean;
|
|
47
54
|
}
|
|
48
55
|
|
|
49
56
|
/**
|
|
@@ -189,10 +196,11 @@ export const Role = Resource(
|
|
|
189
196
|
const inheritedRoles = Array.isArray(props.inheritedRoles)
|
|
190
197
|
? props.inheritedRoles
|
|
191
198
|
: props.inheritedRoles.inheritedRoles;
|
|
199
|
+
const shouldDelete = props.delete ?? false;
|
|
192
200
|
|
|
193
201
|
switch (this.phase) {
|
|
194
202
|
case "delete": {
|
|
195
|
-
if (this.output?.id) {
|
|
203
|
+
if (shouldDelete && this.output?.id) {
|
|
196
204
|
const res = await api.deleteRole({
|
|
197
205
|
path: {
|
|
198
206
|
organization,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// This file is auto-generated by @hey-api/openapi-ts
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type ClientOptions,
|
|
5
|
+
type Config,
|
|
6
|
+
createClient,
|
|
7
|
+
createConfig,
|
|
8
|
+
} from "../../util/api/client/index.ts";
|
|
9
|
+
import type { ClientOptions as ClientOptions2 } from "./types.gen.ts";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The `createClientConfig()` function will be called on client initialization
|
|
13
|
+
* and the returned object will become the client's initial configuration.
|
|
14
|
+
*
|
|
15
|
+
* You may want to initialize your client this way instead of calling
|
|
16
|
+
* `setConfig()`. This is useful for example if you're using Next.js
|
|
17
|
+
* to ensure your client always has the correct values.
|
|
18
|
+
*/
|
|
19
|
+
export type CreateClientConfig<T extends ClientOptions = ClientOptions2> = (
|
|
20
|
+
override?: Config<ClientOptions & T>,
|
|
21
|
+
) => Config<Required<ClientOptions> & T>;
|
|
22
|
+
|
|
23
|
+
export const client = createClient(
|
|
24
|
+
createConfig<ClientOptions2>({
|
|
25
|
+
throwOnError: true,
|
|
26
|
+
}),
|
|
27
|
+
);
|