Skip to content

Commit 15250f8

Browse files
committed
Update example and add types
1 parent fd81835 commit 15250f8

11 files changed

+176
-115
lines changed

.gitignore

+3-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
node_modules
1+
node_modules/
2+
package-lock.json
3+
*.db

package.json

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222
"typeorm-example"
2323
],
2424
"dependencies": {
25-
"mysql": "^2.15.0",
26-
"typeorm": "^0.2.0"
25+
"better-sqlite3": "^8.3.0",
26+
"mysql": "^2.18.1",
27+
"typeorm": "^0.3.15"
2728
}
2829
}

src/app3-es6/entity/CategorySchema.js

-17
This file was deleted.

src/app3-es6/entity/PostSchema.js

-29
This file was deleted.

src/app3-es6/index.js

+33-48
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,33 @@
1-
const typeorm = require("typeorm"); // import * as typeorm from "typeorm";
2-
const Post = require("./model/Post").Post; // import {Post} from "./model/Post";
3-
const Category = require("./model/Category").Category; // import {Category} from "./model/Category";
4-
5-
typeorm.createConnection({
6-
type: "mysql",
7-
host: "localhost",
8-
port: 3306,
9-
username: "test",
10-
password: "test",
11-
database: "test",
12-
synchronize: true,
13-
logging: false,
14-
entities: [
15-
require("./entity/PostSchema"),
16-
require("./entity/CategorySchema")
17-
]
18-
}).then(function (connection) {
19-
20-
const category1 = new Category(0, "TypeScript");
21-
const category2 = new Category(0, "Programming");
22-
23-
return connection
24-
.manager
25-
.save([category1, category2])
26-
.then(() => {
27-
28-
let post = new Post();
29-
post.title = "Control flow based type analysis";
30-
post.text = "TypeScript 2.0 implements a control flow-based type analysis for local variables and parameters.";
31-
post.categories = [category1, category2];
32-
33-
let postRepository = connection.getRepository(Post);
34-
postRepository.save(post)
35-
.then(function(savedPost) {
36-
console.log("Post has been saved: ", savedPost);
37-
console.log("Now lets load all posts: ");
38-
39-
return postRepository.find();
40-
})
41-
.then(function(allPosts) {
42-
console.log("All posts: ", allPosts);
43-
});
44-
});
45-
46-
}).catch(function(error) {
47-
console.log("Error: ", error);
48-
});
1+
import { DataSource } from "typeorm";
2+
3+
import Post from "./model/Post.js";
4+
import Category from "./model/Category.js";
5+
6+
const dataSource = new DataSource({
7+
type: "better-sqlite3",
8+
database: "app3-es6.db",
9+
synchronize: true,
10+
logging: false,
11+
entities: [Post.schema, Category.schema],
12+
});
13+
14+
await dataSource.initialize();
15+
16+
const category1 = new Category(1, "TypeScript");
17+
const category2 = new Category(2, "Programming");
18+
19+
await Category.save([category1, category2]);
20+
21+
const post = new Post();
22+
post.title = "Control flow based type analysis";
23+
post.text =
24+
"TypeScript 2.0 implements a control flow-based type analysis for local variables and parameters.";
25+
post.categories = [category1, category2];
26+
27+
const savedPost = await post.save();
28+
console.log("Post has been saved: ", savedPost);
29+
console.log("Now lets load all posts: ");
30+
31+
const allPosts = await Post.find({ relations: { categories: true } });
32+
33+
console.log("All posts: ", allPosts);

src/app3-es6/jsconfig.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"compilerOptions": {
3+
"checkJs": true,
4+
"module": "Node16",
5+
"strict": true
6+
}
7+
}

src/app3-es6/model/Category.js

+29-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
1-
/*export */ class Category {
2-
constructor(id, name) {
3-
this.id = id;
4-
this.name = name;
5-
}
1+
import { BaseEntity, EntitySchema } from "typeorm";
2+
3+
export default class Category extends BaseEntity {
4+
/**
5+
*
6+
* @param {number} [id]
7+
* @param {string} [name]
8+
*/
9+
constructor(id, name) {
10+
super();
11+
this.id = id;
12+
this.name = name;
13+
}
614
}
715

8-
module.exports = {
9-
Category: Category
10-
};
16+
Category.definition = /** @type {const} */ ({
17+
name: "Category",
18+
target: Category,
19+
columns: {
20+
id: {
21+
primary: true,
22+
type: "int",
23+
generated: true,
24+
},
25+
name: {
26+
type: "varchar",
27+
},
28+
},
29+
});
30+
31+
Category.schema = new EntitySchema(Category.definition);

src/app3-es6/model/Post.js

+44-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,47 @@
1-
/*export */ class Post {
2-
constructor(id, title, text, categories) {
3-
this.id = id;
4-
this.title = title;
5-
this.text = text;
6-
this.categories = categories;
7-
}
1+
import { BaseEntity, EntitySchema } from "typeorm";
2+
3+
export default class Post extends BaseEntity {
4+
/**
5+
*
6+
* @param {number} [id]
7+
* @param {string} [title]
8+
* @param {string} [text]
9+
* @param {import('./Category.js').default[]} [categories]
10+
*/
11+
constructor(id, title, text, categories) {
12+
super();
13+
this.id = id;
14+
this.title = title;
15+
this.text = text;
16+
this.categories = categories;
17+
}
818
}
919

10-
module.exports = {
11-
Post: Post
12-
};
20+
Post.definition = /** @type {const} */ ({
21+
name: "Post",
22+
target: Post,
23+
columns: {
24+
id: {
25+
primary: true,
26+
type: "int",
27+
generated: true,
28+
},
29+
title: {
30+
type: "varchar",
31+
},
32+
text: {
33+
type: "text",
34+
},
35+
},
36+
relations: {
37+
categories: {
38+
target: "Category",
39+
type: "many-to-many",
40+
joinTable: true,
41+
cascade: true,
42+
},
43+
},
44+
});
1345

46+
// @ts-expect-error
47+
Post.schema = new EntitySchema(Post.definition);

src/app3-es6/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"type": "module"}

src/app3-es6/types/helpers.d.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
type Nullables<T> = {
2+
[P in keyof T]: T[P] extends { nullable: true } ? P : never;
3+
}[keyof T];
4+
5+
type Type<T> = T extends "varchar" | "text"
6+
? string
7+
: T extends "boolean"
8+
? boolean
9+
: T extends "int"
10+
? number
11+
: T extends "datetime"
12+
? Date
13+
: T extends "blob"
14+
? Buffer
15+
: unknown;
16+
17+
type ColumnProps<T> = {
18+
-readonly [P in Exclude<keyof T, Nullables<T>>]: Type<T[P]["type"]>;
19+
} & {
20+
-readonly [P in Nullables<T>]?: Type<T[P]["type"]>;
21+
};
22+
23+
type Model<T> = import("./models.js").Models[T];
24+
25+
type RelationProps<T> = {
26+
-readonly [P in keyof T]: T[P]["type"] extends "many-to-many" | "one-to-many"
27+
? Model<T[P]["target"]>[]
28+
: T[P]["type"] extends "many-to-one" | "one-to-one"
29+
? Model<T[P]["target"]>
30+
: unknown;
31+
};
32+
33+
/** Helper type to automatically extract props from schema definition */
34+
export type EntityProps<T> = ColumnProps<T["columns"]> &
35+
RelationProps<T["relations"]>;

src/app3-es6/types/models.d.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { EntityProps } from "./helpers.js";
2+
3+
/** Add your models here to get automatic types for them */
4+
5+
import Category from "../model/Category.js";
6+
import Post from "../model/Category.js";
7+
8+
module "../model/Category.js" {
9+
export type CategoryProps = EntityProps<typeof Category.definition>;
10+
export default interface Category extends CategoryProps {}
11+
}
12+
13+
module "../model/Post.js" {
14+
export type PostProps = EntityProps<typeof Post.definition>;
15+
export default interface Post extends PostProps {}
16+
}
17+
18+
export type Models = {
19+
Category: Category;
20+
Post: Post;
21+
};

0 commit comments

Comments
 (0)