@xata.io/drizzle 0.0.0-alpha.ve727a51 → 0.0.0-alpha.ve755cefe0595fea075a3e6c459f09c60ecc5d523
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 +101 -2
- package/dist/index.cjs +85 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +44 -65
- package/dist/index.mjs +82 -113
- package/dist/index.mjs.map +1 -1
- package/dist/pg.cjs +201 -0
- package/dist/pg.cjs.map +1 -0
- package/dist/pg.d.ts +58 -0
- package/dist/pg.mjs +195 -0
- package/dist/pg.mjs.map +1 -0
- package/package.json +10 -3
- package/test/drizzle.test.ts +6293 -0
- package/test/files.test.ts +94 -0
- package/test/schema.ts +85 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test } from 'vitest';
|
2
|
+
import { XataClient } from '../../../packages/codegen/example/xata';
|
3
|
+
import { TestEnvironmentResult, setUpTestEnvironment } from '../../../test/utils/setup';
|
4
|
+
import { XataFile } from '../../../packages/client/src';
|
5
|
+
import { drizzle as drizzlePg, type XataDatabase } from '../src/pg';
|
6
|
+
import { drizzle as drizzleHttp, type XataHttpDatabase } from '../src/http';
|
7
|
+
import { Client } from 'pg';
|
8
|
+
import { pgTable, serial, text } from 'drizzle-orm/pg-core';
|
9
|
+
import { xataFileArray, xataFile } from '../src/types/files';
|
10
|
+
import { eq } from 'drizzle-orm';
|
11
|
+
|
12
|
+
let xata: XataClient;
|
13
|
+
let hooks: TestEnvironmentResult['hooks'];
|
14
|
+
let db: XataDatabase<any> | XataHttpDatabase<any>;
|
15
|
+
let pg: Client;
|
16
|
+
|
17
|
+
const file = new Blob(['hello'], { type: 'text/plain' });
|
18
|
+
|
19
|
+
const usersTable = pgTable('users', {
|
20
|
+
xata_id: text('id').primaryKey(),
|
21
|
+
name: text('name').notNull(),
|
22
|
+
attachments: xataFileArray('attachments'),
|
23
|
+
photo: xataFile('photo')
|
24
|
+
});
|
25
|
+
|
26
|
+
describe.concurrent.each([{ type: 'pg' }, { type: 'http' }])('Drizzle $type file support', ({ type }) => {
|
27
|
+
beforeAll(async (ctx) => {
|
28
|
+
const result = await setUpTestEnvironment('files');
|
29
|
+
|
30
|
+
xata = result.client;
|
31
|
+
hooks = result.hooks;
|
32
|
+
|
33
|
+
if (type === 'pg') {
|
34
|
+
pg = new Client({ connectionString: xata.sql.connectionString });
|
35
|
+
await pg.connect();
|
36
|
+
db = drizzlePg(pg);
|
37
|
+
} else {
|
38
|
+
db = drizzleHttp(result.client);
|
39
|
+
}
|
40
|
+
|
41
|
+
return hooks.beforeAll(ctx);
|
42
|
+
});
|
43
|
+
|
44
|
+
afterAll(async (ctx) => {
|
45
|
+
await pg?.end();
|
46
|
+
await hooks.afterAll(ctx);
|
47
|
+
});
|
48
|
+
|
49
|
+
beforeEach(async (ctx) => {
|
50
|
+
await hooks.beforeEach(ctx);
|
51
|
+
});
|
52
|
+
|
53
|
+
afterEach(async (ctx) => {
|
54
|
+
await hooks.afterEach(ctx);
|
55
|
+
});
|
56
|
+
|
57
|
+
test('read file from record', async () => {
|
58
|
+
const record = await xata.db.users.create(
|
59
|
+
{
|
60
|
+
name: 'test',
|
61
|
+
attachments: [XataFile.fromBlob(file, { name: 'hello.txt' })],
|
62
|
+
photo: XataFile.fromBlob(file, { name: 'hello.txt' })
|
63
|
+
},
|
64
|
+
['attachments.*', 'attachments.base64Content', 'photo.*', 'photo.base64Content']
|
65
|
+
);
|
66
|
+
|
67
|
+
expect(record.attachments?.[0]?.id).toBeDefined();
|
68
|
+
expect(record.attachments?.[0]?.name).toBe('hello.txt');
|
69
|
+
expect(record.attachments?.[0]?.base64Content).toBeDefined();
|
70
|
+
expect(record.attachments?.[0]?.toBlob()).toBeInstanceOf(Blob);
|
71
|
+
expect(record.attachments?.[0]?.toString()).toBe('hello');
|
72
|
+
expect(record.attachments?.[0]?.mediaType).toBe('text/plain');
|
73
|
+
|
74
|
+
expect(record.photo?.name).toBe('hello.txt');
|
75
|
+
expect(record.photo?.base64Content).toBeDefined();
|
76
|
+
expect(record.photo?.size).toBeGreaterThan(0);
|
77
|
+
expect(record.photo?.toBlob()).toBeInstanceOf(Blob);
|
78
|
+
expect(record.photo?.toString()).toBe('hello');
|
79
|
+
|
80
|
+
// Check for default public access (photo is public by default, attachments are not)
|
81
|
+
expect(record.attachments?.[0]?.enablePublicUrl).toBe(false);
|
82
|
+
expect(record.photo?.enablePublicUrl).toBe(true);
|
83
|
+
|
84
|
+
const result = await db.select().from(usersTable).where(eq(usersTable.xata_id, record.id)).execute();
|
85
|
+
expect(result).toHaveLength(1);
|
86
|
+
expect(result[0].attachments).toHaveLength(1);
|
87
|
+
expect(result[0].photo).toBeDefined();
|
88
|
+
|
89
|
+
expect(result[0].attachments?.[0].name).toBe('hello.txt');
|
90
|
+
expect(result[0].attachments?.[0].mediaType).toBe('text/plain');
|
91
|
+
expect(result[0].photo?.name).toBe('hello.txt');
|
92
|
+
expect(result[0].photo?.mediaType).toBe('text/plain');
|
93
|
+
});
|
94
|
+
});
|
package/test/schema.ts
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
import { boolean, integer, type PgColumn, pgTable, primaryKey, serial, text, timestamp } from 'drizzle-orm/pg-core';
|
2
|
+
|
3
|
+
import { relations } from 'drizzle-orm';
|
4
|
+
|
5
|
+
export const usersTable = pgTable('users', {
|
6
|
+
id: serial('id').primaryKey(),
|
7
|
+
name: text('name').notNull(),
|
8
|
+
verified: boolean('verified').notNull().default(false),
|
9
|
+
invitedBy: integer('invited_by').references((): PgColumn => usersTable.id)
|
10
|
+
});
|
11
|
+
|
12
|
+
export const usersConfig = relations(usersTable, ({ one, many }) => ({
|
13
|
+
invitee: one(usersTable, { fields: [usersTable.invitedBy], references: [usersTable.id] }),
|
14
|
+
usersToGroups: many(usersToGroupsTable),
|
15
|
+
posts: many(postsTable)
|
16
|
+
}));
|
17
|
+
|
18
|
+
export const groupsTable = pgTable('groups', {
|
19
|
+
id: serial('id').primaryKey(),
|
20
|
+
name: text('name').notNull(),
|
21
|
+
description: text('description')
|
22
|
+
});
|
23
|
+
|
24
|
+
export const groupsConfig = relations(groupsTable, ({ many }) => ({
|
25
|
+
usersToGroups: many(usersToGroupsTable)
|
26
|
+
}));
|
27
|
+
|
28
|
+
export const usersToGroupsTable = pgTable(
|
29
|
+
'users_to_groups',
|
30
|
+
{
|
31
|
+
id: serial('id').primaryKey(),
|
32
|
+
userId: integer('user_id')
|
33
|
+
.notNull()
|
34
|
+
.references(() => usersTable.id),
|
35
|
+
groupId: integer('group_id')
|
36
|
+
.notNull()
|
37
|
+
.references(() => groupsTable.id)
|
38
|
+
},
|
39
|
+
(t) => ({
|
40
|
+
pk: primaryKey(t.groupId, t.userId)
|
41
|
+
})
|
42
|
+
);
|
43
|
+
|
44
|
+
export const usersToGroupsConfig = relations(usersToGroupsTable, ({ one }) => ({
|
45
|
+
group: one(groupsTable, { fields: [usersToGroupsTable.groupId], references: [groupsTable.id] }),
|
46
|
+
user: one(usersTable, { fields: [usersToGroupsTable.userId], references: [usersTable.id] })
|
47
|
+
}));
|
48
|
+
|
49
|
+
export const postsTable = pgTable('posts', {
|
50
|
+
id: serial('id').primaryKey(),
|
51
|
+
content: text('content').notNull(),
|
52
|
+
ownerId: integer('owner_id').references(() => usersTable.id),
|
53
|
+
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow()
|
54
|
+
});
|
55
|
+
|
56
|
+
export const postsConfig = relations(postsTable, ({ one, many }) => ({
|
57
|
+
author: one(usersTable, { fields: [postsTable.ownerId], references: [usersTable.id] }),
|
58
|
+
comments: many(commentsTable)
|
59
|
+
}));
|
60
|
+
|
61
|
+
export const commentsTable = pgTable('comments', {
|
62
|
+
id: serial('id').primaryKey(),
|
63
|
+
content: text('content').notNull(),
|
64
|
+
creator: integer('creator').references(() => usersTable.id),
|
65
|
+
postId: integer('post_id').references(() => postsTable.id),
|
66
|
+
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow()
|
67
|
+
});
|
68
|
+
|
69
|
+
export const commentsConfig = relations(commentsTable, ({ one, many }) => ({
|
70
|
+
post: one(postsTable, { fields: [commentsTable.postId], references: [postsTable.id] }),
|
71
|
+
author: one(usersTable, { fields: [commentsTable.creator], references: [usersTable.id] }),
|
72
|
+
likes: many(commentLikesTable)
|
73
|
+
}));
|
74
|
+
|
75
|
+
export const commentLikesTable = pgTable('comment_likes', {
|
76
|
+
id: serial('id').primaryKey(),
|
77
|
+
creator: integer('creator').references(() => usersTable.id),
|
78
|
+
commentId: integer('comment_id').references(() => commentsTable.id),
|
79
|
+
createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow()
|
80
|
+
});
|
81
|
+
|
82
|
+
export const commentLikesConfig = relations(commentLikesTable, ({ one }) => ({
|
83
|
+
comment: one(commentsTable, { fields: [commentLikesTable.commentId], references: [commentsTable.id] }),
|
84
|
+
author: one(usersTable, { fields: [commentLikesTable.creator], references: [usersTable.id] })
|
85
|
+
}));
|