@xata.io/drizzle 0.0.0-alpha.vdd8d5bd666d1807ed5f272e3ccba99605495f3aa → 0.0.0-alpha.vddec8625ad4dd2e901ec75eef5769e604f210360
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/.turbo/turbo-build.log +16 -5
- package/CHANGELOG.md +43 -2
- package/dist/index.cjs +54 -40
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +23 -14
- package/dist/index.mjs +56 -43
- package/dist/index.mjs.map +1 -1
- package/dist/pg.cjs +212 -0
- package/dist/pg.cjs.map +1 -0
- package/dist/pg.d.ts +61 -0
- package/dist/pg.mjs +206 -0
- package/dist/pg.mjs.map +1 -0
- package/package.json +11 -6
- package/test/drizzle.test.ts +77 -196
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@xata.io/drizzle",
|
3
|
-
"version": "0.0.0-alpha.
|
3
|
+
"version": "0.0.0-alpha.vddec8625ad4dd2e901ec75eef5769e604f210360",
|
4
4
|
"description": "",
|
5
5
|
"main": "./dist/index.cjs",
|
6
6
|
"module": "./dist/index.mjs",
|
@@ -10,6 +10,11 @@
|
|
10
10
|
"import": "./dist/index.mjs",
|
11
11
|
"require": "./dist/index.cjs",
|
12
12
|
"types": "./dist/index.d.ts"
|
13
|
+
},
|
14
|
+
"./pg": {
|
15
|
+
"import": "./dist/pg.mjs",
|
16
|
+
"require": "./dist/pg.cjs",
|
17
|
+
"types": "./dist/pg.d.ts"
|
13
18
|
}
|
14
19
|
},
|
15
20
|
"author": "",
|
@@ -18,15 +23,15 @@
|
|
18
23
|
"url": "https://github.com/xataio/client-ts/issues"
|
19
24
|
},
|
20
25
|
"dependencies": {
|
21
|
-
"
|
22
|
-
"@xata.io/client": "0.0.0-alpha.vdd8d5bd666d1807ed5f272e3ccba99605495f3aa"
|
26
|
+
"@xata.io/client": "0.0.0-alpha.vddec8625ad4dd2e901ec75eef5769e604f210360"
|
23
27
|
},
|
24
28
|
"devDependencies": {
|
25
|
-
"@types/pg": "^8.11.
|
26
|
-
"drizzle-orm": "^0.
|
29
|
+
"@types/pg": "^8.11.10",
|
30
|
+
"drizzle-orm": "^0.33.0",
|
31
|
+
"pg": "^8.13.0"
|
27
32
|
},
|
28
33
|
"peerDependencies": {
|
29
|
-
"drizzle-orm": "
|
34
|
+
"drizzle-orm": "*"
|
30
35
|
},
|
31
36
|
"scripts": {
|
32
37
|
"build": "rimraf dist && rollup -c",
|
package/test/drizzle.test.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
import { BaseClient, HostProvider, parseProviderString, XataApiClient } from '@xata.io/client';
|
2
2
|
import 'dotenv/config';
|
3
|
-
import { desc, DrizzleError, eq, gt, gte, or, placeholder, sql
|
3
|
+
import { desc, DrizzleError, eq, gt, gte, or, placeholder, sql } from 'drizzle-orm';
|
4
4
|
import { Client } from 'pg';
|
5
5
|
import { afterAll, afterEach, beforeAll, beforeEach, describe, expectTypeOf, test } from 'vitest';
|
6
6
|
import { drizzle as drizzlePg, type XataDatabase } from '../src/pg';
|
@@ -9,7 +9,7 @@ import * as schema from './schema';
|
|
9
9
|
|
10
10
|
const { usersTable, postsTable, commentsTable, usersToGroupsTable, groupsTable } = schema;
|
11
11
|
|
12
|
-
const ENABLE_LOGGING =
|
12
|
+
const ENABLE_LOGGING = false;
|
13
13
|
|
14
14
|
declare module 'vitest' {
|
15
15
|
export interface TestContext {
|
@@ -51,25 +51,48 @@ function getDomain(host: HostProvider) {
|
|
51
51
|
}
|
52
52
|
}
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
54
|
+
function getDrizzleClient(type: string, database: string, branch: string) {
|
55
|
+
if (type === 'http') {
|
56
|
+
const xata = new BaseClient({
|
57
|
+
apiKey,
|
58
|
+
host,
|
59
|
+
clientName: 'sdk-tests',
|
60
|
+
databaseURL: `https://${workspace}.${region}.${getDomain(host)}/db/${database}`,
|
61
|
+
branch
|
62
|
+
});
|
61
63
|
|
62
|
-
|
64
|
+
return { db: drizzleHttp(xata, { schema, logger: ENABLE_LOGGING }) };
|
65
|
+
} else if (type === 'pg') {
|
66
|
+
const client = new Client({
|
67
|
+
connectionString: `postgresql://${workspace}:${apiKey}@${region}.sql.${getDomain(
|
68
|
+
host
|
69
|
+
)}:5432/${database}:${branch}`,
|
70
|
+
ssl: true
|
71
|
+
});
|
63
72
|
|
64
|
-
|
65
|
-
|
66
|
-
|
73
|
+
return { db: drizzlePg(client, { schema, logger: ENABLE_LOGGING }), client };
|
74
|
+
} else {
|
75
|
+
throw new Error(`Unknown type: ${type}`);
|
76
|
+
}
|
77
|
+
}
|
67
78
|
|
68
|
-
|
69
|
-
const
|
79
|
+
describe.concurrent.each([{ type: 'pg' }, { type: 'http' }])('Drizzle $type', ({ type }) => {
|
80
|
+
const dbName = `${database}-${type}`;
|
70
81
|
|
71
|
-
|
72
|
-
|
82
|
+
beforeAll(async () => {
|
83
|
+
await api.databases.createDatabase({
|
84
|
+
pathParams: { workspaceId: workspace, dbName },
|
85
|
+
body: { region, branchName: 'main', postgresEnabled: true }
|
86
|
+
});
|
87
|
+
|
88
|
+
await waitForReplication(dbName);
|
89
|
+
|
90
|
+
// For now, run the migrations via wire protocol
|
91
|
+
const { client, db } = getDrizzleClient('pg', dbName, 'main');
|
92
|
+
await client?.connect();
|
93
|
+
|
94
|
+
await db.execute(
|
95
|
+
sql`
|
73
96
|
CREATE TABLE "users" (
|
74
97
|
"id" serial PRIMARY KEY NOT NULL,
|
75
98
|
"name" text NOT NULL,
|
@@ -77,27 +100,27 @@ beforeAll(async () => {
|
|
77
100
|
"invited_by" int REFERENCES "users"("id")
|
78
101
|
);
|
79
102
|
`
|
80
|
-
|
81
|
-
|
82
|
-
|
103
|
+
);
|
104
|
+
await db.execute(
|
105
|
+
sql`
|
83
106
|
CREATE TABLE IF NOT EXISTS "groups" (
|
84
107
|
"id" serial PRIMARY KEY NOT NULL,
|
85
108
|
"name" text NOT NULL,
|
86
109
|
"description" text
|
87
110
|
);
|
88
111
|
`
|
89
|
-
|
90
|
-
|
91
|
-
|
112
|
+
);
|
113
|
+
await db.execute(
|
114
|
+
sql`
|
92
115
|
CREATE TABLE IF NOT EXISTS "users_to_groups" (
|
93
116
|
"id" serial PRIMARY KEY NOT NULL,
|
94
117
|
"user_id" int REFERENCES "users"("id"),
|
95
118
|
"group_id" int REFERENCES "groups"("id")
|
96
119
|
);
|
97
120
|
`
|
98
|
-
|
99
|
-
|
100
|
-
|
121
|
+
);
|
122
|
+
await db.execute(
|
123
|
+
sql`
|
101
124
|
CREATE TABLE IF NOT EXISTS "posts" (
|
102
125
|
"id" serial PRIMARY KEY NOT NULL,
|
103
126
|
"content" text NOT NULL,
|
@@ -105,9 +128,9 @@ beforeAll(async () => {
|
|
105
128
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
106
129
|
);
|
107
130
|
`
|
108
|
-
|
109
|
-
|
110
|
-
|
131
|
+
);
|
132
|
+
await db.execute(
|
133
|
+
sql`
|
111
134
|
CREATE TABLE IF NOT EXISTS "comments" (
|
112
135
|
"id" serial PRIMARY KEY NOT NULL,
|
113
136
|
"content" text NOT NULL,
|
@@ -116,9 +139,9 @@ beforeAll(async () => {
|
|
116
139
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
117
140
|
);
|
118
141
|
`
|
119
|
-
|
120
|
-
|
121
|
-
|
142
|
+
);
|
143
|
+
await db.execute(
|
144
|
+
sql`
|
122
145
|
CREATE TABLE IF NOT EXISTS "comment_likes" (
|
123
146
|
"id" serial PRIMARY KEY NOT NULL,
|
124
147
|
"creator" int REFERENCES "users"("id"),
|
@@ -126,47 +149,32 @@ beforeAll(async () => {
|
|
126
149
|
"created_at" timestamp with time zone DEFAULT now() NOT NULL
|
127
150
|
);
|
128
151
|
`
|
129
|
-
|
152
|
+
);
|
130
153
|
|
131
|
-
|
132
|
-
});
|
154
|
+
await client?.end();
|
155
|
+
});
|
133
156
|
|
134
|
-
afterAll(async () => {
|
135
|
-
|
136
|
-
});
|
157
|
+
afterAll(async () => {
|
158
|
+
await api.databases.deleteDatabase({ pathParams: { workspaceId: workspace, dbName } });
|
159
|
+
});
|
137
160
|
|
138
|
-
describe.concurrent.each([{ type: 'pg' } /**{ type: 'http' }**/])('Drizzle $type', ({ type }) => {
|
139
161
|
beforeEach(async (ctx) => {
|
140
162
|
ctx.branch = `test-${Math.random().toString(36).substring(7)}`;
|
141
|
-
await api.
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
ctx.db = drizzleHttp(xata, { schema, logger: ENABLE_LOGGING });
|
153
|
-
} else if (type === 'pg') {
|
154
|
-
ctx.client = new Client({
|
155
|
-
connectionString: `postgresql://${workspace}:${apiKey}@${region}.sql.${getDomain(host)}:5432/${database}:${
|
156
|
-
ctx.branch
|
157
|
-
}`
|
158
|
-
});
|
159
|
-
|
160
|
-
await ctx.client.connect();
|
161
|
-
ctx.db = drizzlePg(ctx.client, { schema, logger: ENABLE_LOGGING });
|
162
|
-
} else {
|
163
|
-
throw new Error(`Unknown type: ${type}`);
|
164
|
-
}
|
163
|
+
await api.branch.createBranch({
|
164
|
+
pathParams: { workspace, region, dbBranchName: `${dbName}:${ctx.branch}` },
|
165
|
+
body: { from: 'main' }
|
166
|
+
});
|
167
|
+
|
168
|
+
const { db, client } = getDrizzleClient(type, dbName, ctx.branch);
|
169
|
+
await client?.connect();
|
170
|
+
|
171
|
+
ctx.db = db;
|
172
|
+
ctx.client = client;
|
165
173
|
});
|
166
174
|
|
167
175
|
afterEach(async (ctx) => {
|
168
176
|
await ctx.client?.end();
|
169
|
-
await api.
|
177
|
+
await api.branch.deleteBranch({ pathParams: { workspace, region, dbBranchName: `${dbName}:${ctx.branch}` } });
|
170
178
|
});
|
171
179
|
|
172
180
|
/*
|
@@ -886,133 +894,6 @@ describe.concurrent.each([{ type: 'pg' } /**{ type: 'http' }**/])('Drizzle $type
|
|
886
894
|
});
|
887
895
|
});
|
888
896
|
|
889
|
-
test('[Find Many] Get users with posts in transaction', async (ctx) => {
|
890
|
-
let usersWithPosts: {
|
891
|
-
id: number;
|
892
|
-
name: string;
|
893
|
-
verified: boolean;
|
894
|
-
invitedBy: number | null;
|
895
|
-
posts: {
|
896
|
-
id: number;
|
897
|
-
content: string;
|
898
|
-
ownerId: number | null;
|
899
|
-
createdAt: Date;
|
900
|
-
}[];
|
901
|
-
}[] = [];
|
902
|
-
|
903
|
-
await ctx.db.transaction(async (tx) => {
|
904
|
-
await tx.insert(usersTable).values([
|
905
|
-
{ id: 1, name: 'Dan' },
|
906
|
-
{ id: 2, name: 'Andrew' },
|
907
|
-
{ id: 3, name: 'Alex' }
|
908
|
-
]);
|
909
|
-
|
910
|
-
await tx.insert(postsTable).values([
|
911
|
-
{ ownerId: 1, content: 'Post1' },
|
912
|
-
{ ownerId: 1, content: 'Post1.1' },
|
913
|
-
{ ownerId: 2, content: 'Post2' },
|
914
|
-
{ ownerId: 3, content: 'Post3' }
|
915
|
-
]);
|
916
|
-
|
917
|
-
usersWithPosts = await tx.query.usersTable.findMany({
|
918
|
-
where: ({ id }, { eq }) => eq(id, 1),
|
919
|
-
with: {
|
920
|
-
posts: {
|
921
|
-
where: ({ id }, { eq }) => eq(id, 1)
|
922
|
-
}
|
923
|
-
}
|
924
|
-
});
|
925
|
-
});
|
926
|
-
|
927
|
-
expectTypeOf(usersWithPosts).toEqualTypeOf<
|
928
|
-
{
|
929
|
-
id: number;
|
930
|
-
name: string;
|
931
|
-
verified: boolean;
|
932
|
-
invitedBy: number | null;
|
933
|
-
posts: {
|
934
|
-
id: number;
|
935
|
-
content: string;
|
936
|
-
ownerId: number | null;
|
937
|
-
createdAt: Date;
|
938
|
-
}[];
|
939
|
-
}[]
|
940
|
-
>();
|
941
|
-
|
942
|
-
ctx.expect(usersWithPosts.length).eq(1);
|
943
|
-
ctx.expect(usersWithPosts[0]?.posts.length).eq(1);
|
944
|
-
|
945
|
-
ctx.expect(usersWithPosts[0]).toEqual({
|
946
|
-
id: 1,
|
947
|
-
name: 'Dan',
|
948
|
-
verified: false,
|
949
|
-
invitedBy: null,
|
950
|
-
posts: [{ id: 1, ownerId: 1, content: 'Post1', createdAt: usersWithPosts[0]?.posts[0]?.createdAt }]
|
951
|
-
});
|
952
|
-
});
|
953
|
-
|
954
|
-
test('[Find Many] Get users with posts in rollbacked transaction', async (ctx) => {
|
955
|
-
let usersWithPosts: {
|
956
|
-
id: number;
|
957
|
-
name: string;
|
958
|
-
verified: boolean;
|
959
|
-
invitedBy: number | null;
|
960
|
-
posts: {
|
961
|
-
id: number;
|
962
|
-
content: string;
|
963
|
-
ownerId: number | null;
|
964
|
-
createdAt: Date;
|
965
|
-
}[];
|
966
|
-
}[] = [];
|
967
|
-
|
968
|
-
await ctx
|
969
|
-
.expect(
|
970
|
-
ctx.db.transaction(async (tx) => {
|
971
|
-
await tx.insert(usersTable).values([
|
972
|
-
{ id: 1, name: 'Dan' },
|
973
|
-
{ id: 2, name: 'Andrew' },
|
974
|
-
{ id: 3, name: 'Alex' }
|
975
|
-
]);
|
976
|
-
|
977
|
-
await tx.insert(postsTable).values([
|
978
|
-
{ ownerId: 1, content: 'Post1' },
|
979
|
-
{ ownerId: 1, content: 'Post1.1' },
|
980
|
-
{ ownerId: 2, content: 'Post2' },
|
981
|
-
{ ownerId: 3, content: 'Post3' }
|
982
|
-
]);
|
983
|
-
|
984
|
-
tx.rollback();
|
985
|
-
|
986
|
-
usersWithPosts = await tx.query.usersTable.findMany({
|
987
|
-
where: ({ id }, { eq }) => eq(id, 1),
|
988
|
-
with: {
|
989
|
-
posts: {
|
990
|
-
where: ({ id }, { eq }) => eq(id, 1)
|
991
|
-
}
|
992
|
-
}
|
993
|
-
});
|
994
|
-
})
|
995
|
-
)
|
996
|
-
.rejects.toThrowError(new TransactionRollbackError());
|
997
|
-
|
998
|
-
expectTypeOf(usersWithPosts).toEqualTypeOf<
|
999
|
-
{
|
1000
|
-
id: number;
|
1001
|
-
name: string;
|
1002
|
-
verified: boolean;
|
1003
|
-
invitedBy: number | null;
|
1004
|
-
posts: {
|
1005
|
-
id: number;
|
1006
|
-
content: string;
|
1007
|
-
ownerId: number | null;
|
1008
|
-
createdAt: Date;
|
1009
|
-
}[];
|
1010
|
-
}[]
|
1011
|
-
>();
|
1012
|
-
|
1013
|
-
ctx.expect(usersWithPosts.length).eq(0);
|
1014
|
-
});
|
1015
|
-
|
1016
897
|
// select only custom
|
1017
898
|
test('[Find Many] Get only custom fields', async (ctx) => {
|
1018
899
|
await ctx.db.insert(usersTable).values([
|
@@ -6404,12 +6285,12 @@ describe.concurrent.each([{ type: 'pg' } /**{ type: 'http' }**/])('Drizzle $type
|
|
6404
6285
|
});
|
6405
6286
|
});
|
6406
6287
|
|
6407
|
-
async function waitForReplication(): Promise<void> {
|
6288
|
+
async function waitForReplication(dbName: string): Promise<void> {
|
6408
6289
|
try {
|
6409
|
-
await api.branches.getBranchList({ workspace, database, region });
|
6410
|
-
} catch (error) {
|
6411
|
-
console.log(`Waiting for create database replication to finish...`);
|
6412
6290
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
6413
|
-
|
6291
|
+
await api.branch.getBranchList({ pathParams: { workspace, dbName, region } });
|
6292
|
+
} catch (error) {
|
6293
|
+
console.log(`Replication not ready yet, retrying...`);
|
6294
|
+
return await waitForReplication(dbName);
|
6414
6295
|
}
|
6415
6296
|
}
|