Skip to content

Commit

Permalink
feat(core): adjust orm api
Browse files Browse the repository at this point in the history
  • Loading branch information
EYHN committed Jul 1, 2024
1 parent d72dbe6 commit 092fc57
Show file tree
Hide file tree
Showing 13 changed files with 111 additions and 240 deletions.
4 changes: 0 additions & 4 deletions packages/common/infra/src/orm/affine/client.ts

This file was deleted.

21 changes: 0 additions & 21 deletions packages/common/infra/src/orm/affine/hooks.ts

This file was deleted.

3 changes: 0 additions & 3 deletions packages/common/infra/src/orm/affine/index.ts

This file was deleted.

17 changes: 0 additions & 17 deletions packages/common/infra/src/orm/affine/schema.ts

This file was deleted.

22 changes: 5 additions & 17 deletions packages/common/infra/src/orm/core/__tests__/entity.spec.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import { nanoid } from 'nanoid';
import {
afterEach,
beforeEach,
describe,
expect,
test as t,
type TestAPI,
} from 'vitest';
import { beforeEach, describe, expect, test as t, type TestAPI } from 'vitest';

import {
createORMClientType,
createORMClient,
type DBSchemaBuilder,
f,
MemoryORMAdapter,
type ORMClient,
Table,
} from '../';

Expand All @@ -24,18 +18,12 @@ const TEST_SCHEMA = {
},
} satisfies DBSchemaBuilder;

const Client = createORMClientType(TEST_SCHEMA);
type Context = {
client: InstanceType<typeof Client>;
client: ORMClient<typeof TEST_SCHEMA>;
};

beforeEach<Context>(async t => {
t.client = new Client(new MemoryORMAdapter());
await t.client.connect();
});

afterEach<Context>(async t => {
await t.client.disconnect();
t.client = createORMClient(TEST_SCHEMA, MemoryORMAdapter);
});

const test = t as TestAPI<Context>;
Expand Down
43 changes: 15 additions & 28 deletions packages/common/infra/src/orm/core/__tests__/hook.spec.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,13 @@
import { nanoid } from 'nanoid';
import {
afterEach,
beforeEach,
describe,
expect,
test as t,
type TestAPI,
} from 'vitest';
import { beforeEach, describe, expect, test as t, type TestAPI } from 'vitest';

import {
createORMClientType,
createORMClient,
type DBSchemaBuilder,
type Entity,
f,
MemoryORMAdapter,
type ORMClient,
} from '../';

const TEST_SCHEMA = {
Expand All @@ -29,30 +23,23 @@ const TEST_SCHEMA = {
},
} satisfies DBSchemaBuilder;

const Client = createORMClientType(TEST_SCHEMA);

// define the hooks
Client.defineHook('tags', 'migrate field `color` to field `colors`', {
deserialize(data) {
if (!data.colors && data.color) {
data.colors = [data.color];
}

return data;
},
});

type Context = {
client: InstanceType<typeof Client>;
client: ORMClient<typeof TEST_SCHEMA>;
};

beforeEach<Context>(async t => {
t.client = new Client(new MemoryORMAdapter());
await t.client.connect();
});
t.client = createORMClient(TEST_SCHEMA, MemoryORMAdapter);

afterEach<Context>(async t => {
await t.client.disconnect();
// define the hooks
t.client.defineHook('tags', 'migrate field `color` to field `colors`', {
deserialize(data) {
if (!data.colors && data.color) {
data.colors = [data.color];
}

return data;
},
});
});

const test = t as TestAPI<Context>;
Expand Down
61 changes: 31 additions & 30 deletions packages/common/infra/src/orm/core/__tests__/schema.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
import { nanoid } from 'nanoid';
import { describe, expect, test } from 'vitest';

import { createORMClientType, f, MemoryORMAdapter } from '../';
import {
createORMClient,
type DBSchemaBuilder,
f,
MemoryORMAdapter,
} from '../';

function createClient<Schema extends DBSchemaBuilder>(schema: Schema) {
return createORMClient(schema, MemoryORMAdapter);
}

describe('Schema validations', () => {
test('primary key must be set', () => {
expect(() =>
createORMClientType({
createClient({
tags: {
id: f.string(),
name: f.string(),
Expand All @@ -19,7 +28,7 @@ describe('Schema validations', () => {

test('primary key must be unique', () => {
expect(() =>
createORMClientType({
createClient({
tags: {
id: f.string().primaryKey(),
name: f.string().primaryKey(),
Expand All @@ -32,7 +41,7 @@ describe('Schema validations', () => {

test('primary key should not be optional without default value', () => {
expect(() =>
createORMClientType({
createClient({
tags: {
id: f.string().primaryKey().optional(),
name: f.string(),
Expand All @@ -45,7 +54,7 @@ describe('Schema validations', () => {

test('primary key can be optional with default value', async () => {
expect(() =>
createORMClientType({
createClient({
tags: {
id: f.string().primaryKey().optional().default(nanoid),
name: f.string(),
Expand All @@ -56,20 +65,18 @@ describe('Schema validations', () => {
});

describe('Entity validations', () => {
const Client = createORMClientType({
tags: {
id: f.string().primaryKey().default(nanoid),
name: f.string(),
color: f.string(),
},
});

function createClient() {
return new Client(new MemoryORMAdapter());
function createTagsClient() {
return createClient({
tags: {
id: f.string().primaryKey().default(nanoid),
name: f.string(),
color: f.string(),
},
});
}

test('should not update primary key', () => {
const client = createClient();
const client = createTagsClient();

const tag = client.tags.create({
name: 'tag',
Expand All @@ -83,7 +90,7 @@ describe('Entity validations', () => {
});

test('should throw when trying to create entity with missing required field', () => {
const client = createClient();
const client = createTagsClient();

// @ts-expect-error test
expect(() => client.tags.create({ name: 'test' })).toThrow(
Expand All @@ -92,7 +99,7 @@ describe('Entity validations', () => {
});

test('should throw when trying to create entity with extra field', () => {
const client = createClient();
const client = createTagsClient();

expect(() =>
// @ts-expect-error test
Expand All @@ -101,34 +108,28 @@ describe('Entity validations', () => {
});

test('should throw when trying to create entity with unexpected field type', () => {
const client = createClient();
const client = createTagsClient();

expect(() =>
// @ts-expect-error test
client.tags.create({ name: 'test', color: 123 })
).toThrow(
// @ts-expect-error test
expect(() => client.tags.create({ name: 'test', color: 123 })).toThrow(
"[Table(tags)]: Field 'color' type mismatch. Expected type 'string' but got 'number'."
);

expect(() =>
// @ts-expect-error test
client.tags.create({ name: 'test', color: [123] })
).toThrow(
// @ts-expect-error test
expect(() => client.tags.create({ name: 'test', color: [123] })).toThrow(
"[Table(tags)]: Field 'color' type mismatch. Expected type 'string' but got 'json'"
);
});

test('should be able to assign `null` to json field', () => {
expect(() => {
const Client = createORMClientType({
const client = createClient({
tags: {
id: f.string().primaryKey().default(nanoid),
info: f.json(),
},
});

const client = new Client(new MemoryORMAdapter());

const tag = client.tags.create({ info: null });

expect(tag.info).toBe(null);
Expand Down
53 changes: 23 additions & 30 deletions packages/common/infra/src/orm/core/__tests__/sync.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import { DocEngine } from '../../../sync';
import { MiniSyncServer } from '../../../sync/doc/__tests__/utils';
import { MemoryStorage } from '../../../sync/doc/storage';
import {
createORMClientType,
createORMClient,
type DBSchemaBuilder,
f,
type ORMClient,
YjsDBAdapter,
} from '../';

Expand All @@ -29,27 +30,14 @@ const TEST_SCHEMA = {
},
} satisfies DBSchemaBuilder;

const Client = createORMClientType(TEST_SCHEMA);

// define the hooks
Client.defineHook('tags', 'migrate field `color` to field `colors`', {
deserialize(data) {
if (!data.colors && data.color) {
data.colors = [data.color];
}

return data;
},
});

type Context = {
server: MiniSyncServer;
user1: {
client: InstanceType<typeof Client>;
client: ORMClient<typeof TEST_SCHEMA>;
engine: DocEngine;
};
user2: {
client: InstanceType<typeof Client>;
client: ORMClient<typeof TEST_SCHEMA>;
engine: DocEngine;
};
};
Expand All @@ -60,16 +48,25 @@ function createEngine(server: MiniSyncServer) {

async function createClient(server: MiniSyncServer, clientId: number) {
const engine = createEngine(server);
const client = new Client(
new YjsDBAdapter({
getDoc(guid: string) {
const doc = new Doc({ guid });
doc.clientID = clientId;
engine.addDoc(doc);
return doc;
},
})
);
const client = createORMClient(TEST_SCHEMA, YjsDBAdapter, {
getDoc(guid: string) {
const doc = new Doc({ guid });
doc.clientID = clientId;
engine.addDoc(doc);
return doc;
},
});

// define the hooks
client.defineHook('tags', 'migrate field `color` to field `colors`', {
deserialize(data) {
if (!data.colors && data.color) {
data.colors = [data.color];
}

return data;
},
});

return {
engine,
Expand All @@ -85,14 +82,10 @@ beforeEach<Context>(async t => {
t.user2 = await createClient(t.server, 2);

t.user1.engine.start();
await t.user1.client.connect();
t.user2.engine.start();
await t.user2.client.connect();
});

afterEach<Context>(async t => {
t.user1.client.disconnect();
t.user2.client.disconnect();
t.user1.engine.stop();
t.user2.engine.stop();
});
Expand Down
Loading

0 comments on commit 092fc57

Please sign in to comment.