Skip to content

Commit

Permalink
Update example and add types
Browse files Browse the repository at this point in the history
  • Loading branch information
mohd-akram committed May 13, 2023
1 parent fd81835 commit 008c9e6
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 114 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
node_modules
node_modules/
package-lock.json
*.db
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
"typeorm-example"
],
"dependencies": {
"mysql": "^2.15.0",
"typeorm": "^0.2.0"
"better-sqlite3": "^8.3.0",
"mysql": "^2.18.1",
"typeorm": "^0.3.15"
}
}
17 changes: 0 additions & 17 deletions src/app3-es6/entity/CategorySchema.js

This file was deleted.

29 changes: 0 additions & 29 deletions src/app3-es6/entity/PostSchema.js

This file was deleted.

81 changes: 33 additions & 48 deletions src/app3-es6/index.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,33 @@
const typeorm = require("typeorm"); // import * as typeorm from "typeorm";
const Post = require("./model/Post").Post; // import {Post} from "./model/Post";
const Category = require("./model/Category").Category; // import {Category} from "./model/Category";

typeorm.createConnection({
type: "mysql",
host: "localhost",
port: 3306,
username: "test",
password: "test",
database: "test",
synchronize: true,
logging: false,
entities: [
require("./entity/PostSchema"),
require("./entity/CategorySchema")
]
}).then(function (connection) {

const category1 = new Category(0, "TypeScript");
const category2 = new Category(0, "Programming");

return connection
.manager
.save([category1, category2])
.then(() => {

let post = new Post();
post.title = "Control flow based type analysis";
post.text = "TypeScript 2.0 implements a control flow-based type analysis for local variables and parameters.";
post.categories = [category1, category2];

let postRepository = connection.getRepository(Post);
postRepository.save(post)
.then(function(savedPost) {
console.log("Post has been saved: ", savedPost);
console.log("Now lets load all posts: ");

return postRepository.find();
})
.then(function(allPosts) {
console.log("All posts: ", allPosts);
});
});

}).catch(function(error) {
console.log("Error: ", error);
});
import { DataSource } from "typeorm";

import Post from "./model/Post.js";
import Category from "./model/Category.js";

const dataSource = new DataSource({
type: "better-sqlite3",
database: "app3-es6.db",
synchronize: true,
logging: false,
entities: [Post.schema, Category.schema],
});

await dataSource.initialize();

const category1 = new Category(1, "TypeScript");
const category2 = new Category(2, "Programming");

await Category.save([category1, category2]);

const post = new Post();
post.title = "Control flow based type analysis";
post.text =
"TypeScript 2.0 implements a control flow-based type analysis for local variables and parameters.";
post.categories = [category1, category2];

const savedPost = await post.save();
console.log("Post has been saved: ", savedPost);
console.log("Now lets load all posts: ");

const allPosts = await Post.find({ relations: { categories: true } });

console.log("All posts: ", allPosts);
7 changes: 7 additions & 0 deletions src/app3-es6/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"checkJs": true,
"module": "Node16",
"strict": true
}
}
38 changes: 30 additions & 8 deletions src/app3-es6/model/Category.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
/*export */ class Category {
constructor(id, name) {
this.id = id;
this.name = name;
}
import { BaseEntity, EntitySchema } from "typeorm";

export default class Category extends BaseEntity {
/**
*
* @param {number} [id]
* @param {string} [name]
*/
constructor(id, name) {
super();
this.id = id;
this.name = name;
}
}

module.exports = {
Category: Category
};
/** @satisfies {import('typeorm').EntitySchemaOptions<Record<string, unknown>>} */
const definition = {
name: "Category",
columns: {
id: {
primary: true,
type: "int",
generated: true,
},
name: {
type: "varchar",
},
},
};

Category.definition = definition;
Category.schema = new EntitySchema({ ...definition, target: Category });
53 changes: 44 additions & 9 deletions src/app3-es6/model/Post.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,48 @@
/*export */ class Post {
constructor(id, title, text, categories) {
this.id = id;
this.title = title;
this.text = text;
this.categories = categories;
}
import { BaseEntity, EntitySchema } from "typeorm";

export default class Post extends BaseEntity {
/**
*
* @param {number} [id]
* @param {string} [title]
* @param {string} [text]
* @param {import('./Category.js').default[]} [categories]
*/
constructor(id, title, text, categories) {
super();
this.id = id;
this.title = title;
this.text = text;
this.categories = categories;
}
}

module.exports = {
Post: Post
/** @satisfies {import('typeorm').EntitySchemaOptions<Record<string, unknown>>} */
const definition = {
name: "Post",
columns: {
id: {
primary: true,
type: "int",
generated: true,
},
title: {
type: "varchar",
},
text: {
type: "text",
},
},
relations: {
categories: {
target: /** @type {const} */ ("Category"),
type: "many-to-many",
joinTable: true,
cascade: true,
},
},
};

Post.definition = definition;
// @ts-expect-error
Post.schema = new EntitySchema({ ...definition, target: Post });
1 change: 1 addition & 0 deletions src/app3-es6/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"type": "module"}
45 changes: 45 additions & 0 deletions src/app3-es6/types/helpers.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
type Nullables<T> = {
[P in keyof T]: T[P] extends { nullable: true } ? P : never;
}[keyof T];

type Type<T> = T extends "varchar" | "text"
? string
: T extends "boolean"
? boolean
: T extends "int" | "integer"
? number
: T extends "datetime"
? Date
: T extends "blob"
? Buffer
: unknown;

type ColumnProps<T> = {
-readonly [P in keyof T]: Type<T[P]["type"]>;
};

type Model<T> = import("./models.js").Models[T];

type Relation<T> = T["type"] extends "many-to-many" | "one-to-many"
? Model<T["target"]>[]
: T["type"] extends "many-to-one" | "one-to-one"
? Model<T["target"]>
: unknown;

type RelationProps<T> = {
-readonly [P in keyof T]: Relation<T[P]>;
};

type Union<A, B> = unknown extends A ? B : unknown extends B ? A : A | B;

type Merge<A, B, N> = {
-readonly [P in Exclude<keyof A | keyof B, N>]: Union<A[P], B[P]>;
} & {
-readonly [P in N]?: Union<A[P], B[P]>;
};

export type EntityProps<T> = Merge<
ColumnProps<T["columns"]>,
RelationProps<T["relations"]>,
Nullables<T["columns"]>
>;
21 changes: 21 additions & 0 deletions src/app3-es6/types/models.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { EntityProps } from "./helpers.js";

/** Add your models here to get automatic types for them */

import Category from "../model/Category.js";
import Post from "../model/Category.js";

module "../model/Category.js" {
export type CategoryProps = EntityProps<typeof Category.definition>;
export default interface Category extends CategoryProps {}
}

module "../model/Post.js" {
export type PostProps = EntityProps<typeof Post.definition>;
export default interface Post extends PostProps {}
}

export type Models = {
Category: Category;
Post: Post;
};

0 comments on commit 008c9e6

Please sign in to comment.