Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update example and add types #7

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
};