• Stars
    star
    277
  • Rank 148,875 (Top 3 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 6 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

🎁 Simple, lightweight and customisable Laravel models in your JavaScript

Javel

🎁 Wrap your plain JavaScript objects into customizable Laravel-like models. Read introduction article.

cover

Installation

npm i javel -D

Overview

import Model from 'javel'

class Article extends Model {/* ... */}

await Article.all({ /* request */ })                        // => [ Article* ]
await Article.paginate({ query: { page: 2 } })              // => { data: [ Article* ], current_page: 2, ... }
await Article.find(1)                                       // => Article { id: 1, ... }

let article = await Article.create({ name: 'My article' })  // => Article { id: 2, name: 'My article' }
await article.update({ name: 'My updated article' })        // => Article { id: 2, name: 'My updated article' }
await article.delete()                                      // => Deleted from the server

article = new Article({ name: 'My draft blog post' })
article.name = 'My new blog post'
await article.save()                                        // => Article { id: 3, name: 'My new blog post', ... }

Getting started

Start by creating your base model that all other models will extends from. In there you can override any logic you want or, even better, attach additional behavior using mixins (see below).

import { Model as BaseModel } from 'javel'

export default class Model extends BaseModel {
    //
}

Typically, in this base model, you would set up how to reach your server by overriding the baseUrl and makeRequest methods like this:

export default class Model extends BaseModel {
    baseUrl () {
        return '/api'
    }
    makeRequest ({ method, url, data, query }) {
        return axios({ method, url, data, params: query })
    }
}

Note that baseUrl defaults to /api and that makeRequest will automatically use axios if it available in the window (which is the case by default in Laravel).

Next, create specific models for your application.

import Model from './Model.js'

export default class Article extends Model {
    // Your logic here...
}

Finally you will likely want to configure which URL should be used for each actions (find, create, update, etc.). You might also want to add some behavior right before or after requests are made and customize how to handle the response. You can learn all about this in the documentation of the MakesRequests mixin.

A chain of mixins

Javel uses the mixwith library to separate each functionality of a Model into dedicated mixins (comparable to how Eloquent uses traits in Laravel). For the sake of convenience, Javel exposes the mixwith's API directly:

import { Model as BaseModel, Mixin, mix } from 'javel'

// Create a mixin
const ImmutableModels = Mixin(superclass => class extends superclass {
    //
})

// Use a mixin
class Model extends mix(BaseModel).with(ImmutableModels) {
    //
}

You can of course combine as many mixins as you want.

import { Model as BaseModel, mix } from 'javel'
import { MixinA, MixinB, MixinC } from './mixins'

// Use a mixin
class Model extends mix(BaseModel).with(MixinA, MixinB, MixinC) {
    //
}

Note that the order in which you use your mixins is important. The mixins will be applied using inheritance from right to left. Therefore the previous example is comparable to:

class MixinA extends BaseModel {}
class MixinB extends MixinA {}
class MixinC extends MixinB {}
class Model extends MixinC {}

Check out the lifecycle of a base model before creating your own mixins.

Mixins included in Javel's Model

By default, the base Model provided by javel includes the following mixins (in this order, i.e. the lower overrides the higher). You can learn more about each of them by reading their dedicated documentation.

  • HasAttributes Defines the basis of getting and setting attributes on a Model and provide some useful methods like primaryKey, exists, is, clone, etc.
  • HasRelationships Enables models to configure their relationships with each other so that their attributes are automatically wrapped in the right model.
  • KeepsParentRelationship Ensures each child relationship keeps track of its parent and how to access itself from it. This enables models to climb up the relationship tree and even remove themselves from their parent when deleted.
  • MakesRequests Introduces async actions (find, create, update, etc.) to conveniently request the server and provides all the hooks necessary to customize how to handle your request/response proctol for each model.

Extra mixins available

Javel also provides some additional mixins that can be useful to plug in or to get inspired from when writing your own. Don't hesitate to PR your best mixins and share it with us.

  • GeneratesUniqueKey Attaches a unique key to every new model instanciated. If the model has a primary key available, the primary key will be used instead of generating a new unique key.
  • UsesMethodFieldWithFormData Transforms the update action to use the POST method with the _method=PATCH field when the provided data is an instance of FormData.
  • IntegratesQueryBuilder An easy way to build a query string compatible with "spatie/laravel-query-builder" (Has dependencies: js-query-builder).

Optional dependencies

Some extra mixins have additional dependencies that need to be resolved. For example, some mixins could wrap a third party library to make it work with Javel out-of-the-box. Because these mixins are optional (you can choose not to add them), their dependencies must also be optional so that you don't end up loading lots of dependencies you don't need.

This means, when you do decide to pull in a mixin that has dependencies, you have to install them yourself and tell Javel how to access it, like this:

npm i third-party-library
import ThirdPartyLibrary from 'third-party-library'
import { Model as BaseModel, mix, SomeMixinThatUsesThirdPartyLibraries, registerModule } from 'javel'

registerModule('third-party-library', ThirdPartyLibrary)

class Model extends mix(BaseModel).with(SomeMixinThatUsesThirdPartyLibraries) {
    //
}

Note: This behaviour has been designed as a workaround of webpack's optional externals which unfortunately creates warnings when optional dependencies are not present.

More Repositories

1

laravel-actions

⚡️ Laravel components that take care of one specific task
PHP
2,449
star
2

laravel-deployer

🚀 Zero-downtime deployment out-of-the-box
PHP
1,666
star
3

laravel-docker

🐳 Generic docker image for Laravel Applications
Dockerfile
931
star
4

laravel-search-string

🔍 Generates database queries based on one unique string
PHP
770
star
5

tailwindcss-plugins

🔌🌊 Set of useful plugins for tailwindcss
JavaScript
284
star
6

cron-translator

⏰️ Makes CRON expressions human-readable
PHP
281
star
7

artisan-ui

🧰 Run your artisan commands by pressing buttons
Blade
217
star
8

solana-twitter

Simple tweets as Solana accounts
Vue
201
star
9

solana-wallets-vue

Solana wallet integration for Vue 3
TypeScript
161
star
10

vuepress-plugin-seo

🔌 Generate SEO friendly meta header for every page
JavaScript
106
star
11

lody

🗄 Load files and classes as lazy collections in Laravel.
PHP
88
star
12

blog-google-calendar

🌐 Google Calendar Integration
PHP
49
star
13

vue-lab

👨‍🔬 Collection of reusable Vue.js goodies
Vue
45
star
14

laravel-add-select

🧱 Add your subSelect queries the Laravel way
PHP
33
star
15

blog-2019-vuepress

✍️ Personal website and blog (2019 edition)
Vue
30
star
16

vuepress-plugin-disqus

🔌 Register a global Disqus component to add to your layouts
JavaScript
29
star
17

request-controller

Use FormRequests as invokable controllers
PHP
28
star
18

dotfiles

❄️ Personal set of configurations for macOS
Shell
26
star
19

paparazzi

📸 Code base for the Single-Page Laravel course
PHP
16
star
20

kanuu-getting-started

Add billing to your app in 5 minutes with Paddle and Kanuu
PHP
12
star
21

solana-vue3-counter

A test repo for getting started with Anchor and Vue3
JavaScript
9
star
22

peppermint

[WIP] Metaplex SDK Mint example
Vue
7
star
23

enchant

🧙‍♂️ Auto-generated Laravel documentations [WIP]
PHP
7
star
24

minecravel

Just having fun with Minecraft mods (something Laravel related perhaps...)
Java
6
star
25

postpone

🦥 Handle asynchronous JS pipelines
TypeScript
5
star
26

learn-laravel-deployer

👨‍🏫 Dummy Laravel app used in the "Getting started with Laravel Deployer" video series
PHP
4
star
27

solana-core-programs

[WIP] Generated clients for core Solana programs
Rust
4
star
28

laravel-actions-docs

📚 Documentation for Laravel Actions
JavaScript
3
star
29

solana-trustpilot

A Umi/Kinobi demo
TypeScript
3
star
30

lab-deployer

Testing the deployment of a Laravel app with Deployer7
PHP
2
star
31

typedoc-plugin-expand-object-like-types

Expands TS definitions for object-like types
JavaScript
2
star
32

fail-fast-ci-tests

A GitHub Actions playground to figure out the best fail-fast strategy
2
star
33

js-next-cra-5

[WIP] Testing the Metaplex JS SDK on CRA 5
JavaScript
1
star
34

token-recipes

TypeScript
1
star
35

kinobi-template

Archived in favour of https://github.com/solana-program/create-solana-program
TypeScript
1
star