Skip to content

Releases: joy-framework/joy

Getting closer to 1.0!

26 Jul 17:43
Compare
Choose a tag to compare

Ch-ch-changes!

First, I want to give a shout out to

@goto-engineering for fixing the response duration logging code!
@hammywhammy / @hweeks for all of the hard work on the docker/ci stuff!

  • keyword routes
  • default middleware function
  • before/after functions
  • a new, simpler starting template

keyword routes

Tired of having to define all of your routes in two different files, me too!

(route :get "/" :home)

(defn home [r])

This is how the new template works too:

(route :get "/todos" :todos/index)
(route :get "/todos/new" :todos/new)
(route :get "/todos/:id" :todos/show)
(route :post "/todos" :todos/create)
(route :get "/todos/:id/edit" :todos/edit)
(route :patch "/todos/:id" :todos/patch)
(route :delete "/todos/:id" :todos/delete)

You can imagine the corresponding functions.

default middleware function

Before:

(def routes (routes [:get "/" :home]))

(def app (as-> (handler routes) ?
               (layout ? layout/app)
               (csrf-token ?)
               (session ?)
               (extra-methods ?)
               (query-string ?)
               (body-parser ?)
               (server-error ?)
               (x-headers ?)
               (static-files ?)
               (not-found ?)
               (logger ? )))

After:

(def routes (routes [:get "/" :home]))

(def app (app {:routes routes :layout layout-fn}))

You can also turn middleware on/off by changing the dictionary passed to app:

(app {:layout false :extra-methods false :session false :x-headers false :static-files false})

There are a few more options too like changing the cookie options for sessions, things like that.

before/after functions

Don't want to bother writing a whole middleware function just to append things to the request on certain routes? Me neither!

(before "/*" :run-before)

(defn run-before [req]
  (put req :a 1))

You can use a combination of wildcard routes and the before function to modify the request dictionary before any matching routes. Make sure you return the request from your before functions.

Similarly, the after function works the same way, except on the response, you also need to return the response as well.

new starter template

.
├── Procfile
├── main.janet
├── project.janet
└── public
    ├── app.css
    └── app.js

5 files with a Procfile! One thing I didn't add to the default template is a Dockerfile which I'm kind of fine tuning still, it works great with dokku!

That's it for now, there are a few more new things, but you can find me online anywhere or consult the docs if you want to know more

Function Routes

14 May 23:37
Compare
Choose a tag to compare

Warning Breaking changes ahead, only if you're using the css, js or app functions

I try not to make too many breaking changes, but it's still early days
and hopefully no one was using the js/css bundler stuff.

Also I don't plan on introducing breaking changes EVER after 1.0

In fact my strategy is if I want to break things too much, I will release a whole new repo named joy2.

Let's hope it never comes to that.

Change script/link functions

Anyway if you were using those functions change this:

(css "/style1.css" "/style2.css")

to this

(link {:href ["/style1.css" "/style2.css"]})

and the js is similar:

(js "/js1.js" "/js2.js")

to:

(script {:src ["/js1.js" "/js2.js"]})

with the added benefit now of adding other attributes, like :defer

Function routes

Again, this doesn't happen often (or at all) but sometimes a new feature
is just too good to pass up.
If you are using the app function, it has changed to handlers, so this:

(app (handler routes1) (handler routes2))

is now this:

(handlers (handler routes1) (handler routes2))

What do you get from this breaking change?

Let me show you something really cool:

(use joy)

(defn / [request]
  (text/html
    [:h1 "You found joy!"]))

(def app (app))

(server app 9001) # go ahead and visit http://localhost:9001 I dare ya

That is all it takes now to get a joy app up and running!

  • fcb95e6 - Bump version
  • a4d42cd - Handle not found routes better. Fix query string routes
  • a62b780 - Stop manually symlinking to /usr/local/bin
  • 7ef7935 - Use dotenv, remove env.janet
  • 636318d - Depend on dotenv
  • 4cf4697 - Rename app to handlers. Use app as default middleware stack function.
  • fcc34ef - Change script/link functions. Delete css/js functions.
  • 1dc5576 - Handle trailing slashes in routes
  • 8c830c0 - Update link to janet-html
  • abf7bd8 - Add dotenv/load to new project template
  • cee8f4d - Smaller routing code, add wildcard routes
  • a0b9fed - Check for layout-fn before trying to call it
  • 6dd1c5b - Decode json body as keywords
  • 06f95a1 - Fix csrf-field comments
  • 9c1d3e8 - Comment csrf functions and cli/migrations
  • 80ab541 - Update README.md

More bugfixes and improvements

14 May 23:28
Compare
Choose a tag to compare
  • 76f19e4 - Bump version 0.7.4
  • a860b30 - Use absolute paths for bundles
  • b26c7e3 - Only call layout when handler returns a tuple
  • 4f98b70 - Attempt to symlink to /usr/local/bin on install

Bugfixes and improvements

14 May 23:26
Compare
Choose a tag to compare
  • 67f1ee2 - Pass :database-url to db/connect
  • bd1e98e - Bump to 0.7.3
  • 5cb7d6e - Use latest joy in template
  • 06b1316 - Remove joy/db import from generated routes
  • c918798 - Fix route generation

Insensitivity Training

14 May 23:24
Compare
Choose a tag to compare

A few bugfixes, notably though, headers are case-insensitive now with a new, handy headers function:

(header request :x-csrf-token) # or whatever you want

Oh! There's also a new json-body-parser middleware that parses incoming json requests with a content-type: application/json header

Escape from LA

14 May 23:19
Compare
Choose a tag to compare

Tiny release, just fixing up html escaping

  • a67fb4d - Escape html characters again

Colors of the wind

14 May 23:17
Compare
Choose a tag to compare

Notable things in this release:

  • Tentative postgresql support via the db library
  • Better logging, where the request is always logged, even if the response isn't
  • Routes can now be dynamically found within the routes/ folder like so:
(use joy)

(defroutes routes
  [:get "/" :home/index])

Assuming you have a file: src/routes/home.janet and then within that file, this code:

(defn index [request])
  • Array body parsing, so you can have inputs in a form like this:
[:input {:type "text" :name "tag[]"}] 
[:input {:type "text" :name "tag[]"}] 
[:input {:type "text" :name "tag[]"}] 

and on the server you'll have your body look like this:

(defn a-post [request]
  (def body (request :body))

  (body :tag)) # => @["tag1" "tag2" "tag3"]
  • session cookies now default to SameSite=Lax instead of strict
  • Lots of other little bugs fixed and improvements made

Here's the full commit log for the curious:

  • 3c44891 - Case insensitive request method checking for csrf token
  • fdb194a - Put :duration in the request
  • e0a18dc - Array body parsing
  • 4210817 - Relax on the html escaping
  • 2d6a545 - Use tables in http-test
  • 3ae4123 - Use tables in logger-test
  • af124fa - Use db lib
  • a32fc4f - Just return a table from map-keys. Use :pairs
  • 3fee9ad - Add encode helper. Change up html/escape
  • 0c3b09e - Log requests separately from responses
  • 71eec5f - Add helper functions for json/html/plain responses
  • 7a83be7 - Get dynamic route importing working
  • 83f3740 - Set csrf token in meta tag update layout template with text/html
  • 332c438 - Move csrf code to csrf file
  • 08ad2ec - Add implicit route handlers with keywords in defroutes
  • c64fb28 - Default samesite to lax on session cookie
  • 51e8682 - Fix db-test
  • 152650e - Remove set-cookie middleware
  • d9f47f0 - Check for indexed? in logger not tuple?
  • 1884b22 - Don't use WAL in db1
  • 37a524a - Check if actually production
  • 68d5a36 - Don't use WAL
  • 0e910ac - Set prefix as db/ for next janet version
  • 1d7c17f - Remove weird smiley guy in template project
  • cef02e9 - Remove ENV from project generator code
  • 1ecb904 - Clean up migrate/rollback
  • 86b8f3e - Better bundling
  • 2aa07d6 - Delete ENV from template
  • ca69be1 - update dependecy: andrewchambers/janet-uri"
  • 990a20b - Use latest json
  • e8fbd66 - Use propagate instead of re-throwing error
  • 2773b83 - Set theme jekyll-theme-cayman
  • f140978 - Use development? pred
  • 7cb45b2 - Add naive bundler
  • 588f6f9 - Add env helpers for joy-env
  • e2bbff6 - Replace %project-name% in ENV
  • 7bbf586 - Use merge in query string middleware
  • fb18209 - Add ENV/Procfile for piku support
  • d29ae02 - Bring back main in template
  • fecbaf6 - Use latest tester and joy in template
  • 1b6d7f5 - Change default db name from dev to development
  • ad984d0 - Stop throwing if .env isn't there
  • 0bd6d0c - Singularize table names in route templates
  • 8a440f2 - Only escape strings in html attributes
  • 7294b76 - Set a default for optional content
  • 7643c97 - Add file uploads to test. Use db module.
  • 2ffdacb - Rename db/find to db/find-by. Change db/find to where with pk
  • 83ea1f3 - Use latest tester
  • 1d43a90 - Add form-with helper
  • 3492c2e - Add naive multipart file upload middleware
  • 9510e24 - Expose db/http module on
  • 584d3cd - Read docs and clean up server-error middleware
  • fae8d51 - Add file-field helper
  • 2a413d4 - disconnect from db after http server stops on SIGINT
  • bd6bbd9 - Bump halo
  • 747c975 - Fix db/from with null param in where clause
  • 060170e - Create a test .env file
  • e7afa27 - Add db/find
  • f9653be - Update docs
  • 649d567 - Stop base64 encoding encryption keys. Copy rails for request forgery
  • d9a8462 - Use uri to parse forms
  • 99fc956 - Bump codec

Dyno-mite

10 Feb 06:04
Compare
Choose a tag to compare

This one was a doozy, but I'm fairly sure there were no breaking changes 🤞

  • Add new rescue-from fn
  • Fix a regression when parsing request bodies, a space would be a + character
  • Joy now sets foreign keys and journal_mode to WAL in with-db-connection
  • DB_NAME is now DATABASE_URL to help with heroku deployments (if there are any)
  • Use a dyn for the database connection instead of opening/closing a connection on each request
  • Fixed a bug where the server-error middleware would totally ruin the handler's janet env
  • Fixed a bug where when you switch joy apps the cookie decryption would fail and just throw errors
  • Changed the default new joy app template

It doesn't seem like a lot, but it is. Here's the gist of it:

Before:

(import joy :prefix "")

(defn index [request]
  (let [{:db db} request]
    (fetch-all db [:todos])))

Now:

(import joy :prefix "")
(import joy/db)

(db/connect)

(defn index [request]
  (db/fetch-all [:todos])))

This change sets joy up for it's own console a la joy console from the terminal similar to rails console which sets up the database connection and lets you mess around with data.

Bob Dole

03 Feb 18:31
Compare
Choose a tag to compare

What's new?

  • New version of tester
  • Now uses janet-uri for uri encoding/decoding/parsing
  • A little house cleaning with the tests
  • A few /docs + docstrings added
  • The request map now has the response map inside of it for things like conditional menus when people are logged in, etc.
  • when is now supported in vector-html
  • base64/encode now doesn't leave you with a trailing \0 char
  • New rest macro
  • A new uri validator !

What's breaking?

label

It went from this

(label :field-name)

to this

(label :field-name "label string")

so watch out.

submit

This:

(submit "save" [:class "red"])

to this:

(submit "save" :class "red")

delete-all

Also changed, it's now:

 (with-db-connection [db "dev.sqlite3"]
    (delete-all db :post :where {:draft true} :limit 1))

or

(delete-all db :post)

Which will delete all rows in the post table.

Check if files exist in middleware first

05 Jan 18:17
Compare
Choose a tag to compare

Check if static files exist in middleware first so they actually return 404s