Skip to content

Commit

Permalink
Relations (#251)
Browse files Browse the repository at this point in the history
* start work on relations

* Json db doesn't respect `dbName` option on field #72

* many to one based on it's own field - implemented

* a few more tests

* fixed another test

* Fixed test

* Moved Fields to a separate file

* helped support update etc... with many to one

* one to many started working

* added repository insert, count and find

* Added failing test

* added more testsw

* cleaned up tests

* replaced match with field

* removed limit from that api

* inherited from field options

* refactored to use regular repositories

* fixed test

* fixed include of many to one relation

* fixed to respect auto include and override

* fixed null etc

* fixed update

* made sure we get id

* included include in to and from json

* started

* refactored

* 🛑 added field reference and removed first parameter

* basic optimization

* progress on optimization

* more work on optimizations

* handled recursion fetch

* stabilized optimization

* more todos

* added internal export and fixed some typing and added types to index

* release 0.22.9-exp.0

* set new version number

* live query basics work

* added support for load in active record

* release 0.23.0-exp.1

* optional types options

* release 0.23.0-exp.2

* added support for query

* fixed load issue with older fileds

* fixed optional relation field issue

* more fixes

* improved typing

* more work on todo

* git this test to work

* more progress

* new way of defining id columns

* Added lifecycle events

* improved lifecycle events

* made second parameter for one mandatory

* Added thoughts

* made one work like reference

* merged reference with one

* renamed fields to relations

* release 0.23.0-exp.3

* updated changelog

* fixed readme

* release 0.23.0-exp.4

* more fix readme

* release 0.23.0-exp.5

* more tests

* release 0.23.0-exp.6

* mre readme work

* release 0.23.0-exp.7

* fixed readme

* saving row moved to backend

* Made progress on typing

* more typing work

* more typing

* fixed auto many to one relation - and exposed class type

* release 0.23.0-exp.8

* reduced in with one value to eq

* release 0.23.0-exp.9

* fixed relation bug

* release 0.23.0-exp.10

* fixed issue with sort

* release 0.23.0-exp.11

* Strip out "toMany" from GraphQL for now (#253)

* 🐛 FIX: strip out toMany from GraphQL for now

* 👌 FIX: code style

* more todo

* another exp

* release 0.23.0-exp.12

* 4564

* house keeping

* updated more stuff

* improved todo icons

* give error on missing field

* fixed lazy typing etc...

* a little more homework

* fixed toRawFilter

* fixed extra info on options

* release 0.23.0-exp.13

* fixed test

* release 0.23.0-exp.14

* update changelog

* stam commit

* Fixed typing issue

* release 0.23.0-exp.15

* Entity relations doc

* updated docs

* fixed index

* updated script

* 🚸 UPDATE: a few tweaks (#266)

* 🚸 UPDATE: a few tweaks

* Minor adjustments

* Item C

* applied JY comments

---------

Co-authored-by: Noam Honig <noam.honig@gmail.com>

* Fixed issue with updating of and related columns race

* release 0.23.0-exp.16

* Another null issue

* release 0.23.0-exp.17

* fixed another null issue

* release 0.23.0-exp.18

* Fixed typedoc markdown

* Updated docs

* minor doc update

* added comments

* udpated todo

* fixed included in api to be an expression

* fix

* release 0.23.0-exp.19

* fix sort

* release 0.23.0-exp.20

* fixed sort

* Fixed sort issue

* release 0.23.0-exp.21

* one more todo comment

* fixed compound id for svelte and added with remult

* release 0.23.0-exp.22

* one more minor issue

* release 0.23.0-exp.23

* 🎉 NEW: add offset arg in graphql on connection (#280)

* updates sveletkit tests

* release 0.23.0-exp.24

* more todos

* docs

* ⚡ NEW: ensure working also on non public schema (#288)

* apiRequireId returns 403 when using in Statement  #290

* release 0.23.0-exp.25

* fixed it only tests

* release 0.23.0-exp.26

* more notes

* Fixed equal to null issue

* release 0.23.0-exp.27

* More work

* updated todo

* ok

* More notes

* release 0.23.0-exp.28

* todo

* release 0.23.0-exp.29

* fixed update bug with compound id

* release 0.23.0-exp.30

* Fixed comment

* added lifecycle event to index

* release 0.23.0-exp.31

* update topics

* םל

* stabilized it

* added relations to docs

* another note

* todo

* fixed saving on field options

* added something interesting

* Removed use cache as default for findid

* Fixed typing issue

* Fixed db name

* updated todo

* update minor mongo db version

* update sqlite version

* fixed relation on change

* more progress

* more fix to todo

* fixed relation auto removal of data

* release 0.23.0-exp.32

* remult hapi supports crud

* updated the todo

* fixed a typing build error

* removed functions for fields etc...

* release 0.23.0-exp.33

* reverted omit functions

* release 0.23.0-exp.34

* Added hapi to change log and docs

* ok

* autocomplete with Relation.toOne

* demo problem

* compared api

* OmitFunctions

* TS hack for $ and _

* OmitFunctions

* aligned MembersOnly

* fixed package json

* release 0.23.0-exp.35

* Another note

* updated todo

* fixed _ $

* fixed null issue

* updated build

* release 0.23.0-exp.36

* finalized types

* release 0.23.0-exp.37

* fixed members only to exclude entity base

* release 0.23.0-exp.38

---------

Co-authored-by: JYC <jycouet@gmail.com>
Co-authored-by: Yoni Rapoport <yoni@fireflymigration.com>
  • Loading branch information
3 people committed Dec 11, 2023
1 parent fca6f34 commit 3c7257d
Show file tree
Hide file tree
Showing 129 changed files with 9,506 additions and 1,890 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Expand Up @@ -27,7 +27,7 @@ jobs:
MYSQL_PASSWORD: MASTERKEY
environment:
DATABASE_URL: postgres://postgres:password@127.0.0.1:5432/test_db # Connection string
# MONGO_TEST_URL: $MONGO_TEST_URL
# MONGO_TEST_URL: $MONGO_TEST_URL
MONGO_NO_TRANS_TEST_URL: mongodb://localhost:27017/local
TEST_MYSQL: true
TEST_MYSQL2: true
Expand All @@ -45,7 +45,7 @@ workflows:
build:
jobs:
- node/run:
version: "18.18"
version: '18.18'
name: build
npm-run: build-core
npm-run: build
- test-remult
49 changes: 48 additions & 1 deletion .vscode/settings.json
Expand Up @@ -38,5 +38,52 @@
"websql"
],
"typescript.tsdk": "node_modules\\typescript\\lib",
"cSpell.ignoreWords": ["allowapicrud"]
"cSpell.ignoreWords": ["allowapicrud"],
"todo-tree.highlights.customHighlight": {
"BUG": {
"icon": "bug"
},
"HACK": {
"icon": "tools"
},
"FIXME": {
"icon": "flame"
},
"XXX": {
"icon": "x"
},
"[ ]": {
"icon": "issue-draft"
},
"[x]": {
"icon": "issue-closed"
},
"p1": {
"icon": "alert-fill",
"iconColour": "orange"
},
"y1": {
"icon": "bell",
"iconColour": "orange",
"background": "orange"
},
"y2": {
"icon": "bell",
"iconColour": "green"
}
},
"todo-tree.general.tags": [
"BUG",
"HACK",
"FIXME",
"TODO",
"XXX",
"[ ]",
"[x]",
"p1",
"p1.5",
"p2",
"y1",
"y2"
]
}
13 changes: 13 additions & 0 deletions .vscode/tasks.json
@@ -0,0 +1,13 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "npm",
"script": "build-tests",
"group": "build",
"problemMatcher": ["$tsc-watch"],
"label": "npm: build-tests",
"detail": "tsc --watch -p tsconfig.tests.json"
}
]
}
30 changes: 30 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,36 @@

All notable changes to this project will be documented in this file.

## [0.23.0] TBD

- Added Relations - see [Relations](docs/lifecycle-hooks.html)
- Added LifecycleEvent info for saving,saved,deleting,deleted - see [Entity Lifecycle Hooks](https://remult.dev/docs/lifecycle-hooks.html)
- Breaking change - `saving` in `FieldOptions` now has a second parameter if EntityLifeCycle hook - and the fieldRef is the 3rd parameter.
- Saving, Saved, Deleting, Deleted all run only on the backend now
- include in api now supports expressions that use the current row
- Breaking change - instead of `if(repo.fields.name.includedInApi)` you now need `if(repo.fields.name.includedInApi(instance))`
- Changed the way an entity id is defined see [Entity id's doc](http://localhost:5173/docs/ref_entity.html#id)
Example:

```ts
@Entity<OrderDetails>("orderDetails", { id: { orderId: true, productCode: true } })
```

- added repo function which is A convenient shortcut function to quickly obtain a repository for a specific entity type in Remult.

```ts
await repo(Task).find()
```

- Added support for (Hapi api server)[https://hapi.dev/]
- Fixed exception with toRawFilter
- Fixed json db to support db names
- Fixed issue with sort result after live query
- Fix issue with compound id on middleware based servers
- Added with remult for sveltekit for usage before the remult hook
- Fixed issue with requireId not respecting in statement #290
- `findId` was changed to no longer use cache by default

## [0.22.12] 2023-11-26

- [#297](https://github.com/remult/remult/issues/297) - Crash on ensure schema failure
Expand Down
53 changes: 26 additions & 27 deletions README.md
Expand Up @@ -22,7 +22,6 @@
<a href="https://discord.gg/GXHk7ZfuG5" rel="nofollow">
<img alt="Join Discord" src="https://badgen.net/discord/online-members/GXHk7ZfuG5?icon=discord&label=Discord"/>
</a>
</a>
</div>

<br/>
Expand Down Expand Up @@ -101,14 +100,14 @@ npm i remult
```ts
// shared/product.ts

import { Entity, Fields } from "remult"
import { Entity, Fields } from 'remult'

@Entity("products", {
allowApiCrud: true
@Entity('products', {
allowApiCrud: true,
})
export class Product {
@Fields.string()
name = ""
name = ''

@Fields.number()
unitPrice = 0
Expand All @@ -120,17 +119,17 @@ export class Product {
```ts
// backend/index.ts

import express from "express"
import { remultExpress } from "remult/remult-express"
import { Product } from "../shared/product"
import express from 'express'
import { remultExpress } from 'remult/remult-express'
import { Product } from '../shared/product'

const port = 3001
const app = express()

app.use(
remultExpress({
entities: [Product]
})
entities: [Product],
}),
)

app.listen(port, () => {
Expand All @@ -151,13 +150,13 @@ app.listen(port, () => {
```ts
// frontend/code.ts

import { remult } from "remult"
import { Product } from "../shared/product"
import { remult } from 'remult'
import { Product } from '../shared/product'

async function increasePriceOfTofu(priceIncrease: number) {
const productsRepo = remult.repo(Product)

const product = await productsRepo.findFirst({ name: "Tofu" }) // filter is passed through API request all the way to the db
const product = await productsRepo.findFirst({ name: 'Tofu' }) // filter is passed through API request all the way to the db
product.unitPrice += priceIncrease
productsRepo.save(product) // mutation request updates the db with no boilerplate code
}
Expand All @@ -179,32 +178,32 @@ static async increasePriceOfTofu(priceIncrease: number) {
### :ballot_box_with_check: Data validation and constraints - defined once

```ts
import { Entity, Fields, Validators } from "remult"
import { Entity, Fields, Validators } from 'remult'

@Entity("products", {
allowApiCrud: true
@Entity('products', {
allowApiCrud: true,
})
export class Product {
@Fields.string({
validate: Validators.required
validate: Validators.required,
})
name = ""
name = ''

@Fields.string<Product>({
validate: (product) => {
if (product.description.trim().length < 50) {
throw "too short"
throw 'too short'
}
}
},
})
description = ""
description = ''

@Fields.number({
validate: (_, field) => {
if (field.value < 0) {
field.error = "must not be less than 0" // or: throw "must not be less than 0";
field.error = 'must not be less than 0' // or: throw "must not be less than 0";
}
}
},
})
unitPrice = 0
}
Expand Down Expand Up @@ -233,20 +232,20 @@ try {
### :lock: Secure the API with fine-grained authorization

```ts
@Entity<Article>("Articles", {
@Entity<Article>('Articles', {
allowApiRead: true,
allowApiInsert: (_, remult) => remult.authenticated(),
allowApiUpdate: (article, remult) => article.author.id == remult.user.id
allowApiUpdate: (article, remult) => article.author.id == remult.user.id,
})
export class Article {
@Fields.string({ allowApiUpdate: false })
slug = ""
slug = ''

@Field(() => Profile, { allowApiUpdate: false })
author!: Profile

@Fields.string()
content = ""
content = ''
}
```

Expand Down
11 changes: 7 additions & 4 deletions docs/.vitepress/config.ts
Expand Up @@ -141,16 +141,17 @@ export default defineConfig({
link: '/docs/entity-relations',
collapsed: true,
items: [
{
text: 'Lazy loading',
link: '/docs/lazy-loading-of-related-entities',
},
// {
// text: 'Lazy loading',
// link: '/docs/lazy-loading-of-related-entities',
// },
{
text: 'More on One to Many',
link: '/docs/techniques-regarding-one-to-many-relations',
},
],
},
{ text: 'Entity Lifecycle Hooks', link: '/docs/lifecycle-hooks' },
{
text: 'Generate from Existing DB',
link: '/docs/entities-codegen-from-db-schema',
Expand Down Expand Up @@ -207,6 +208,8 @@ export default defineConfig({
items: [
{ text: 'Entity', link: '/docs/ref_entity' },
{ text: 'Field', link: '/docs/ref_field' },
{ text: 'Relations', link: '/docs/ref_relations' },
{ text: 'RelationOptions', link: '/docs/ref_relationoptions' },
{ text: 'Remult', link: '/docs/ref_remult' },
{ text: 'Repository', link: '/docs/ref_repository' },
{
Expand Down
20 changes: 20 additions & 0 deletions docs/docs/add-remult-to-your-app.md
Expand Up @@ -117,6 +117,26 @@ export const handle = remultSveltekit({
})
```

### Hapi

```ts
import { type Plugin, server } from '@hapi/hapi'
import { remultHapi } from 'remult/remult-hapi'
;(async () => {
const hapi = server({ port: 3000 })

await hapi.register(
remultHapi({
entities: [
/* entity types */
],
}),
)

hapi.start()
})()
```

### Nest

```ts
Expand Down

0 comments on commit 3c7257d

Please sign in to comment.