Skip to content

Commit 3ea2a7f

Browse files
B4nanclaude
andauthored
chore: update CI to Node 22, enable corepack, and fix lockfile (#60)
* chore: update CI to Node 22, enable corepack, and fix lockfile Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: migrate to Yarn v4 lockfile and add Node 24 to CI The CI was using `corepack prepare yarn@stable` which installs Yarn v4, but the lockfile was in Yarn v1 format causing "lockfile would have been modified" errors. Regenerate the lockfile in v4 format with node-modules linker. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: add explicit entities to mikro-orm config MikroORM v7 requires explicit entity registration. Import all EntitySchema definitions into the config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: mark BaseEntity schema as abstract Prevents 'Duplicate table names' error since BaseEntity is not a concrete entity and should not have its own table. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: migrate entities to defineEntity with setClass Replace EntitySchema definitions with the defineEntity + property builder API. Use setClass to register custom classes with constructors. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 19f16cd commit 3ea2a7f

File tree

11 files changed

+2988
-2395
lines changed

11 files changed

+2988
-2395
lines changed

.github/workflows/tests.yml

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
strategy:
1515
fail-fast: false
1616
matrix:
17-
node-version: [ 18, 20 ]
17+
node-version: [ 22, 24 ]
1818
steps:
1919
- name: Checkout Source code
2020
uses: actions/checkout@v6
@@ -24,11 +24,10 @@ jobs:
2424
with:
2525
node-version: ${{ matrix.node-version }}
2626

27-
- name: Cache node_modules
28-
uses: actions/cache@v5
29-
with:
30-
path: '**/node_modules'
31-
key: ${{ runner.os }}-${{ matrix.node-version }}-modules-${{ hashFiles('**/yarn.lock') }}
27+
- name: Enable corepack
28+
run: |
29+
corepack enable
30+
corepack prepare yarn@stable --activate
3231
3332
- name: Install
3433
run: yarn

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
temp
22
node_modules
33
.idea
4+
.yarn

.yarnrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nodeLinker: node-modules

app/entities/Author.js

Lines changed: 19 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,26 @@
11
'use strict';
22

3-
import { Collection, EntitySchema } from '@mikro-orm/core';
3+
import { defineEntity, p } from '@mikro-orm/core';
4+
import { BaseEntitySchema } from './BaseEntity.js';
45
import { Book } from './Book.js';
5-
import { BaseEntity } from './BaseEntity.js';
66

7-
/**
8-
* @property {string} name
9-
* @property {string} email
10-
* @property {number} age
11-
* @property {boolean} termsAccepted
12-
* @property {string[]} identities
13-
* @property {Date} born
14-
* @property {Collection<Book>} books
15-
* @property {Book} favouriteBook
16-
* @property {number} version
17-
* @property {string} versionAsString
18-
*/
19-
export class Author extends BaseEntity {
7+
export const AuthorSchema = defineEntity({
8+
extends: BaseEntitySchema,
9+
name: 'Author',
10+
properties: {
11+
name: p.string(),
12+
email: p.string(),
13+
age: p.integer().nullable(),
14+
termsAccepted: p.boolean(),
15+
identities: p.array().nullable(),
16+
born: p.datetime().nullable(),
17+
books: () => p.oneToMany(Book).mappedBy('author'),
18+
favouriteBook: () => p.manyToOne(Book).nullable(),
19+
},
20+
});
21+
22+
export class Author extends AuthorSchema.class {
2023

21-
/**
22-
* @param {string} name
23-
* @param {string} email
24-
*/
2524
constructor(name, email) {
2625
super();
2726
this.name = name;
@@ -31,28 +30,4 @@ export class Author extends BaseEntity {
3130

3231
}
3332

34-
Author.beforeDestroyCalled = 0;
35-
Author.afterDestroyCalled = 0;
36-
37-
export const schema = new EntitySchema({
38-
class: Author,
39-
extends: 'BaseEntity',
40-
properties: {
41-
name: { type: 'string' },
42-
email: { type: 'string' },
43-
age: { type: 'number', nullable: true },
44-
termsAccepted: { type: 'boolean' },
45-
identities: { type: 'string[]', nullable: true },
46-
born: { type: 'Date', nullable: true },
47-
books: {
48-
kind: '1:m',
49-
mappedBy: 'author',
50-
type: 'Book',
51-
},
52-
favouriteBook: {
53-
kind: 'm:1',
54-
type: 'Book',
55-
nullable: true,
56-
},
57-
},
58-
});
33+
AuthorSchema.setClass(Author);

app/entities/BaseEntity.js

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,13 @@
11
'use strict';
22

3-
import { Collection, ReferenceKind, EntitySchema, wrap } from '@mikro-orm/core';
3+
import { defineEntity, p } from '@mikro-orm/core';
44

5-
/**
6-
* @property {number} id
7-
* @property {Date} createdAt
8-
* @property {Date} updatedAt
9-
*/
10-
export class BaseEntity {
11-
12-
constructor() {
13-
this.createdAt = new Date();
14-
this.updatedAt = new Date();
15-
const props = wrap(this).__meta.properties;
16-
17-
Object.keys(props).forEach(prop => {
18-
if ([ReferenceKind.ONE_TO_MANY, ReferenceKind.MANY_TO_MANY].includes(props[prop].reference)) {
19-
this[prop] = new Collection(this);
20-
}
21-
});
22-
}
23-
24-
}
25-
26-
export const schema = new EntitySchema({
5+
export const BaseEntitySchema = defineEntity({
276
name: 'BaseEntity',
7+
abstract: true,
288
properties: {
29-
id: { primary: true, type: 'number' },
30-
createdAt: { type: 'Date' },
31-
updatedAt: { type: 'Date', onUpdate: () => new Date() },
9+
id: p.integer().primary(),
10+
createdAt: p.datetime().onCreate(() => new Date()),
11+
updatedAt: p.datetime().onCreate(() => new Date()).onUpdate(() => new Date()),
3212
},
3313
});

app/entities/Book.js

Lines changed: 16 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
11
'use strict';
22

3-
import { Collection, EntitySchema } from '@mikro-orm/core';
4-
import { Publisher } from './Publisher.js';
3+
import { defineEntity, p } from '@mikro-orm/core';
4+
import { BaseEntitySchema } from './BaseEntity.js';
55
import { Author } from './Author.js';
6+
import { Publisher } from './Publisher.js';
67
import { BookTag } from './BookTag.js';
7-
import { BaseEntity } from './BaseEntity.js';
88

9-
/**
10-
* @property {string} title
11-
* @property {Author} author
12-
* @property {Publisher} publisher
13-
* @property {Collection<BookTag>} tags
14-
*/
15-
export class Book extends BaseEntity {
9+
export const BookSchema = defineEntity({
10+
extends: BaseEntitySchema,
11+
name: 'Book',
12+
properties: {
13+
title: p.string(),
14+
author: () => p.manyToOne(Author),
15+
publisher: () => p.manyToOne(Publisher).nullable(),
16+
tags: () => p.manyToMany(BookTag).owner().inversedBy('books'),
17+
},
18+
});
19+
20+
export class Book extends BookSchema.class {
1621

17-
/**
18-
* @param {string} title
19-
* @param {Author} author
20-
*/
2122
constructor(title, author) {
2223
super();
2324
this.title = title;
@@ -26,25 +27,4 @@ export class Book extends BaseEntity {
2627

2728
}
2829

29-
export const schema = new EntitySchema({
30-
class: Book,
31-
extends: 'BaseEntity',
32-
properties: {
33-
title: { type: 'string' },
34-
author: {
35-
kind: 'm:1',
36-
type: 'Author',
37-
},
38-
publisher: {
39-
kind: 'm:1',
40-
type: 'Publisher',
41-
nullable: true,
42-
},
43-
tags: {
44-
kind: 'm:n',
45-
owner: true,
46-
inversedBy: 'books',
47-
type: 'BookTag',
48-
},
49-
},
50-
});
30+
BookSchema.setClass(Book);

app/entities/BookTag.js

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,25 @@
11
'use strict';
22

3-
import { Collection, EntitySchema } from '@mikro-orm/core';
3+
import { defineEntity, p } from '@mikro-orm/core';
4+
import { BaseEntitySchema } from './BaseEntity.js';
45
import { Book } from './Book.js';
5-
import { BaseEntity } from './BaseEntity.js';
66

7-
/**
8-
* @property {number} id
9-
* @property {string} name
10-
* @property {Collection<Book>} books
11-
*/
12-
export class BookTag extends BaseEntity {
7+
export const BookTagSchema = defineEntity({
8+
extends: BaseEntitySchema,
9+
name: 'BookTag',
10+
properties: {
11+
name: p.string(),
12+
books: () => p.manyToMany(Book).mappedBy('tags'),
13+
},
14+
});
15+
16+
export class BookTag extends BookTagSchema.class {
1317

14-
/**
15-
* @param {string} name
16-
*/
1718
constructor(name) {
1819
super();
1920
this.name = name;
2021
}
2122

2223
}
2324

24-
export const schema = new EntitySchema({
25-
class: BookTag,
26-
extends: 'BaseEntity',
27-
properties: {
28-
name: { type: 'string' },
29-
books: {
30-
kind: 'm:n',
31-
owner: false,
32-
mappedBy: 'tags',
33-
type: 'Book',
34-
},
35-
},
36-
});
25+
BookTagSchema.setClass(BookTag);

app/entities/Publisher.js

Lines changed: 14 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
'use strict';
22

3-
import { Collection, EntitySchema } from '@mikro-orm/core';
3+
import { defineEntity, p } from '@mikro-orm/core';
4+
import { BaseEntitySchema } from './BaseEntity.js';
45
import { Book } from './Book.js';
5-
import { BaseEntity } from './BaseEntity.js';
66

7-
/**
8-
* @property {string} name
9-
* @property {string} type
10-
* @property {Collection<Book>} books
11-
*/
12-
export class Publisher extends BaseEntity {
7+
export const PublisherSchema = defineEntity({
8+
extends: BaseEntitySchema,
9+
name: 'Publisher',
10+
properties: {
11+
name: p.string(),
12+
type: p.string(),
13+
books: () => p.oneToMany(Book).mappedBy('publisher'),
14+
},
15+
});
16+
17+
export class Publisher extends PublisherSchema.class {
1318

1419
constructor(name = 'asd', type = 'local') {
1520
super();
@@ -19,20 +24,4 @@ export class Publisher extends BaseEntity {
1924

2025
}
2126

22-
export const schema = new EntitySchema({
23-
class: Publisher,
24-
extends: 'BaseEntity',
25-
properties: {
26-
name: {
27-
type: 'string',
28-
},
29-
books: {
30-
kind: '1:m',
31-
mappedBy: 'publisher',
32-
type: 'Book',
33-
},
34-
type: {
35-
type: 'string',
36-
},
37-
},
38-
});
27+
PublisherSchema.setClass(Publisher);

app/mikro-orm.config.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
import { defineConfig } from '@mikro-orm/sqlite';
22
import { SqlHighlighter } from '@mikro-orm/sql-highlighter';
3+
import { BaseEntitySchema } from './entities/BaseEntity.js';
4+
import { AuthorSchema } from './entities/Author.js';
5+
import { BookSchema } from './entities/Book.js';
6+
import { BookTagSchema } from './entities/BookTag.js';
7+
import { PublisherSchema } from './entities/Publisher.js';
38

49
export default defineConfig({
510
dbName: 'mikro-orm-express-js',
11+
entities: [BaseEntitySchema, AuthorSchema, BookSchema, BookTagSchema, PublisherSchema],
612
highlighter: new SqlHighlighter(),
713
dynamicImportProvider: id => import(id),
814
});

package.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
"test": "mocha **/*.spec.js"
1212
},
1313
"dependencies": {
14-
"express": "^5.0.0",
15-
"express-promise-router": "^4.1.1",
1614
"@mikro-orm/core": "^7.0.1",
15+
"@mikro-orm/sql-highlighter": "^1.0.0",
1716
"@mikro-orm/sqlite": "^7.0.1",
18-
"@mikro-orm/sql-highlighter": "^1.0.0"
17+
"express": "^5.0.0",
18+
"express-promise-router": "^4.1.1"
1919
},
2020
"devDependencies": {
2121
"@mikro-orm/cli": "^7.0.1",
@@ -31,5 +31,6 @@
3131
"configPaths": [
3232
"./app/mikro-orm.config.js"
3333
]
34-
}
34+
},
35+
"packageManager": "yarn@4.13.0"
3536
}

0 commit comments

Comments
 (0)