Skip to content

Commit

Permalink
0.30.0
Browse files Browse the repository at this point in the history
  • Loading branch information
terrablue committed Feb 25, 2024
1 parent 4f4794f commit d98da36
Show file tree
Hide file tree
Showing 17 changed files with 364 additions and 224 deletions.
5 changes: 5 additions & 0 deletions docs/blog/release-030.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"title": "Release 0.30: Windows support, new path parameter style and other improvements",
"epoch": 1708854056000,
"author": "terrablue"
}
163 changes: 163 additions & 0 deletions docs/blog/release-030.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
Today we're announcing the availability of the Primate 0.30 preview release.
This release introduces full Windows support and brings the path parameter
style used by Primate's filesystem-based routes in line with other frameworks,
in addition to several quality of life improvements.

!!!
If you're new to Primate, we recommend reading the [Getting started] page to
get an idea of it.
!!!

## Windows support

This release introduces full support for running Primate on Windows, including
Wasm routes, data stores as well as frontends.

## New path parameter style

In this release, Primate is switching from its original path parameter style,
using braces, to brackets.

If you had a path like `routes/user/{id}.js` before, you would now be using
`routes/user/[id].js` in line with most other filesystem-based frameworks.

To illustrate, here are a few examples of paths in 0.30.

* `index.js` is mapped to the root route (`/`)
* `user.js` is mapped to `/user`
* `user/[user_id].js` is mapped to a route with parameters, for example
`/user/1` (but also `/user/donald`)
* `user/[user_id=uuid].js` is mapped to a route where `user_id` is of the type
`uuid`, for example `/user/f6a3fac2-7c1d-432d-9e1c-68d0db925adc` (but not
`/user/1`)

## Quality of life improvements

### Default `loose` mode in stores

The default mode for `@primate/store` stores is now `loose`. This is similar to
before with the addition that fields not explicitly declared in the store
definition will be also saved. This is particulary useful for NoSQL databases
that do not have a rigid schema, in cases where you want to enforce types on
some fields and accept anything in others.

To make this applicable for SQL databases too, we will add a `catchall` type in
the future denoting a JSON column in which the data of any non-declared fields
is saved and properly deserialized when retrieved.

To enforce strictness in stores globally, pass in `{ mode: "strict" }` when
activating the store module. To enforce strictness on store level, use
`export const mode = "strict";` in the store file. To opt out of global
strictness per store, use `export const mode = "loose";`.

In the future, we will add the ability to mark fields as optional such that
it's possible to enforce a strict mode with explicit exceptions for optional
(nullable) fields.

### Loose default CSP

Previously, Primate enforced a strict CSP policy. In this release, the defaults
have been changed to no CSP policy. If you create a policy directive for
`script-src` or `style-src`, Primate will augment it with hashes for scripts
and stylesheets.

### Improved error handling of route return object

Starting with this release, Primate will tell you if you forget to return data
from your route or the body you return is invalid.

```sh
!! primate invalid body returned from route, got `undefined`
++ return a proper body from route
-> https://primatejs.com/guide/logging#invalid-body-returned
```

### Disabling body parsing

You can now tell Primate to not parse the body stream of the request, leaving
it pristine, by setting `request.body.parse` to `false` in your configuration
file.

```js caption=primate.config.js
export default {
request: {
body: {
parse: false,
},
},
};
```

This is particularly useful if you're using Primate as a programmable reverse
proxy with the `handle` hook and you want to pass the untouched request to
another application.

```js caption=primate.config.js
const upstream = "http://localhost:7171";

export default {
request: {
body: {
parse: false,
},
},
modules: [{
name: "reverse-proxy",
handle(request) {
const { method, headers, body } = request.original;
const input = `${upstream}${request.url.pathname}`;

return globalThis.fetch(input, { headers, method, body, duplex: "half" });
},
}],
};
```

## Migrating from 0.29

### update path parameters to new style

Change any `{` to `[` and `}` to `]` in your path parameters.

The following script will change any JavaScript route files you have in your
`routes` directory from the old to the new style.

```sh
find -name "*.js" -exec rename -v "{" "[" {} ";" &&
find -name "*.js" -exec rename -v "}" "]" {} ";"
```

If you used path parameters in any directory names, change them manually.

## Other changes

Consult the [full changelog][changelog] for a list of all relevant changes.

## Next on the road

Some of the things we plan to tackle in the upcoming weeks are,

* Add projections and relations to stores
* Multidriver transactions
* Add a `command` hook that would allow modules to register command line
namespaces, to be able to run `npx primate [namespace] [command] [flags]`
* Use this new hook to create database migrations for SQL-flavored databases
* Add hydration and SPA support for `@primate/vue`
* Flesh out stores with default values, additional predicates and relations
between tables/collections
* Add more type variants

This list isn't exhaustive or binding. None, some or all of these features may
be included in 0.31, and other features may be prioritized according to
feedback.

## Fin

If you like Primate, consider [joining our channel #primate][irc] on
irc.libera.chat.

Otherwise, have a blast with the new version!

[Getting started]: /guide/getting-started
[irc]: https://web.libera.chat#primate
[changelog]: https://github.com/primatejs/primate/releases/tag/0.30.0
80 changes: 38 additions & 42 deletions docs/guide/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,16 @@ export default {
http: {
host: "localhost",
port: 6161,
csp: {
"default-src": "'self'",
"style-src": "'self'",
"script-src": "'self'",
"object-src": "'none'",
"frame-ancestors": "'none'",
"form-action": "'self'",
"base-uri": "'self'",
},
csp: {},
static: {
root: "/",
},
},
request:
body: {
parse: true,
},
},
location: {
components: "components",
pages: "pages",
Expand All @@ -58,9 +55,6 @@ export default {
mapper: identity,
},
},
types: {
explicit: false,
},
};
```

Expand Down Expand Up @@ -106,19 +100,16 @@ export default {
http: {
host: "localhost",
port: 6262,
csp: {
"default-src": "'self'",
"style-src": "'self'",
"script-src": "'self'",
"object-src": "'none'",
"frame-ancestors": "'none'",
"form-action": "'self'",
"base-uri": "'self'",
},
csp: {},
static: {
root: "/",
},
},
request:
body: {
parse: true,
},
},
location: {
components: "components",
pages: "pages",
Expand All @@ -137,9 +128,6 @@ export default {
mapper: identity,
},
},
types: {
explicit: false,
},
};
```

Expand All @@ -152,8 +140,6 @@ Default `"/"`
Your app's base path. If your app is running from a domain's root path, leave
the default as is. If your app is running from a subpath, adjust accordingly.

This is used in CSP paths.

### modules

Default `[]`
Expand Down Expand Up @@ -217,27 +203,32 @@ The HTTP port to be used. This value is directly passed to the runtime.

### http.csp

Default
Default `{}`

The Content Security Policy (CSP) to be used. Empty by default.

If you wanted a fairly restrictive policy, you would use something like this.

```js
{
// all content must come from own origin, excluding subdomains
"default-src": "'self'",
"default-src": ["'self'"],
// styles must come from own origin, excluding subdomains
"style-src": "'self'",
"style-src": ["'self'"],
// disallow <object>, <embed> and <applet> elements
"object-src": "'none'",
"object-src": ["'none'"],
// disallow embedding
"frame-ancestors": "'none'",
"frame-ancestors": ["'none'"],
// all form submissions must be to own origin
"form-action": "'self'",
"form-action": ["'self'"],
// allow only own origin in <base>
"base-uri": "'self'",
"base-uri": ["'self'"],
}
```

The Content Security Policy (CSP) to be used. Primate's defaults are intended
to be secure, and you would need to change them for decreased security.
If existing, `script-src` and `style-src` will be concatenated with hashes of
scripts and styles picked up by Primate (either through the `components` or the
`static` directory).

### http.static.root

Expand All @@ -261,6 +252,18 @@ Primate does not load the key or certificate into memory. It only resolves
their paths as necessary and passes them to the [rcompat](https://github.com/rcompat/rcompat).
!!!

### Request options

### request.body.parse

Default: `true`

Whether the body should be parsed according to the content type. Turning this
off is useful if you're using Primate as a programmable reverse proxy and
forwarding the requests to another app. The headers, the querystring and
cookies will be still parsed and available to `request`, and
`request.original` will contain the untouched original request.

### Location options

Locations of Primate standard directories. If any of these locations are
Expand Down Expand Up @@ -355,13 +358,6 @@ A file content mapper for the files specified in `build.transform.files`.

Configuring [runtime types](/guide/types).

### types.explicit

Default `false`

Whether Primate should autotype path parameters. If set to `true`, path
parameters and types having the exact same name won't be automatically typed.

## pages/app.html

If you use the `view` or `html` [handler](/guide/responses#view), Primate will
Expand Down
Loading

0 comments on commit d98da36

Please sign in to comment.