@orieljs/framework 0.1.0-alpha.10 → 0.1.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-VOYW3R5J.js → chunk-24673JQF.js} +3 -3
- package/dist/{chunk-GVNLZZTN.js → chunk-HTJKT2R2.js} +3 -1
- package/dist/chunk-HTJKT2R2.js.map +1 -0
- package/dist/{chunk-OXAATQA6.js → chunk-KDE5BLI3.js} +432 -89
- package/dist/chunk-KDE5BLI3.js.map +1 -0
- package/dist/{chunk-7ZQZYDOC.js → chunk-MURTCTRH.js} +2 -2
- package/dist/contracts.d.ts +12 -1
- package/dist/contracts.js +3 -1
- package/dist/index.d.ts +121 -4
- package/dist/index.js +296 -56
- package/dist/index.js.map +1 -1
- package/dist/jsx-runtime.js +3 -3
- package/dist/testing.js +3 -3
- package/docs/console.md +2 -0
- package/docs/deployment.md +95 -0
- package/docs/export.md +93 -0
- package/docs/installation.md +10 -0
- package/docs/middleware.md +1 -0
- package/docs/navigation.json +4 -0
- package/docs/starter-kits.md +3 -0
- package/docs/vite.md +78 -0
- package/package.json +32 -30
- package/dist/chunk-GVNLZZTN.js.map +0 -1
- package/dist/chunk-OXAATQA6.js.map +0 -1
- /package/dist/{chunk-VOYW3R5J.js.map → chunk-24673JQF.js.map} +0 -0
- /package/dist/{chunk-7ZQZYDOC.js.map → chunk-MURTCTRH.js.map} +0 -0
package/dist/jsx-runtime.js
CHANGED
package/dist/testing.js
CHANGED
|
@@ -52,9 +52,9 @@ import {
|
|
|
52
52
|
travelBack,
|
|
53
53
|
travelTo,
|
|
54
54
|
usingInMemoryDatabase
|
|
55
|
-
} from "./chunk-
|
|
56
|
-
import "./chunk-
|
|
57
|
-
import "./chunk-
|
|
55
|
+
} from "./chunk-KDE5BLI3.js";
|
|
56
|
+
import "./chunk-MURTCTRH.js";
|
|
57
|
+
import "./chunk-HTJKT2R2.js";
|
|
58
58
|
export {
|
|
59
59
|
AnonymousNotifiable,
|
|
60
60
|
AssertableInertia,
|
package/docs/console.md
CHANGED
|
@@ -55,6 +55,7 @@ These are the commands every app has. A new app adds one of its own, `inspire`,
|
|
|
55
55
|
| Command | What it does |
|
|
56
56
|
| --- | --- |
|
|
57
57
|
| `about` | Shows your app's name, the Oriel and Node versions, the environment, debug mode and URL |
|
|
58
|
+
| `export` | Saves your app's pages as files any static host serves ([Static export](export.md)) |
|
|
58
59
|
| `help` | Shows a command's help screen |
|
|
59
60
|
| `list` | Lists the commands, all of them or one group's |
|
|
60
61
|
| `serve` | Serves your app on Oriel's server; `--watch` restarts it when your code changes |
|
|
@@ -115,6 +116,7 @@ These are the commands every app has. A new app adds one of its own, `inspire`,
|
|
|
115
116
|
| `schedule:run` | Runs the scheduled tasks that are due |
|
|
116
117
|
| `schedule:work` | Runs the tasks that are due, every minute, until you stop it |
|
|
117
118
|
| `storage:link` | Links `public/storage` to `storage/app/public` |
|
|
119
|
+
| `vercel:build` | Writes your app's build for Vercel into `.vercel/output` ([Deploying to Vercel](deployment.md#deploying-to-vercel)) |
|
|
118
120
|
|
|
119
121
|
`node oriel help <command>` lists a command's options. A few that are worth knowing up front:
|
|
120
122
|
|
package/docs/deployment.md
CHANGED
|
@@ -10,6 +10,10 @@ So deploying it means starting that process, keeping it running, and restarting
|
|
|
10
10
|
the processes beside it: the queue workers, the scheduler and, for the Inertia kits with server-side rendering, the
|
|
11
11
|
SSR server.
|
|
12
12
|
|
|
13
|
+
An app whose pages are the same for every visitor can skip the server altogether: [Static export](export.md) saves its
|
|
14
|
+
pages as files any static host serves. On Vercel, your app runs without a server of its own, in a function that starts
|
|
15
|
+
when requests come: see [Deploying to Vercel](#deploying-to-vercel).
|
|
16
|
+
|
|
13
17
|
## Server requirements
|
|
14
18
|
|
|
15
19
|
Your server needs **Node 22** or later, or **Bun 1.2** or later. On Node, your app's TypeScript runs through `tsx`,
|
|
@@ -238,6 +242,97 @@ node oriel inertia:stop-ssr
|
|
|
238
242
|
|
|
239
243
|
Laravel's `reload` command, which does both, isn't in Oriel.
|
|
240
244
|
|
|
245
|
+
## Deploying to Vercel
|
|
246
|
+
|
|
247
|
+
On Vercel there is no server to keep running: Vercel's CDN sends the files in `public`, and every other request goes
|
|
248
|
+
to a function that runs your app. `node oriel vercel:build` writes both into `.vercel/output`, the folder Vercel
|
|
249
|
+
deploys (its [Build Output API](https://vercel.com/docs/build-output-api)): `static` holds `public`, whose built
|
|
250
|
+
assets are cached for a year as `serve()` sends them, and the function holds your app's code,
|
|
251
|
+
`public/build/manifest.json` and your production dependencies. Your `.env` files and your
|
|
252
|
+
SQLite databases are left out: the secrets come from Vercel's environment variables, and the database from a server.
|
|
253
|
+
|
|
254
|
+
### Setting up the project
|
|
255
|
+
|
|
256
|
+
Add a `vercel.json` to your app, so that Vercel's build runs the command:
|
|
257
|
+
|
|
258
|
+
```json title="vercel.json"
|
|
259
|
+
{
|
|
260
|
+
"framework": null,
|
|
261
|
+
"buildCommand": "npm run build && node oriel migrate --force && node oriel vercel:build"
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
The API kit has no `build` script: leave `npm run build &&` out. Then import your repository in Vercel, or deploy from
|
|
266
|
+
your machine with `npx vercel deploy`: either way, the build runs on Vercel's machines, which run Linux, as its
|
|
267
|
+
functions do. The function holds native packages built for the machine that ran the build, such as esbuild, which
|
|
268
|
+
`tsx` needs, so a function built on macOS or Windows fails on Vercel. `vercel:build` warns when it runs elsewhere than
|
|
269
|
+
Linux: don't deploy that build with `vercel deploy --prebuilt`.
|
|
270
|
+
|
|
271
|
+
`migrate --force` runs on every deploy, the previews' too. Give the Preview environment a database of its own, such as
|
|
272
|
+
a branch of your production database, so that a preview never migrates your live data.
|
|
273
|
+
|
|
274
|
+
### Environment variables
|
|
275
|
+
|
|
276
|
+
Set your app's values in the project's settings, under Environment Variables:
|
|
277
|
+
|
|
278
|
+
```dotenv
|
|
279
|
+
APP_ENV=production
|
|
280
|
+
APP_DEBUG=false
|
|
281
|
+
APP_KEY=base64:...
|
|
282
|
+
APP_URL=https://example.vercel.app
|
|
283
|
+
DB_CONNECTION=pgsql
|
|
284
|
+
DB_URL=postgres://...
|
|
285
|
+
SESSION_DRIVER=database
|
|
286
|
+
CACHE_STORE=database
|
|
287
|
+
QUEUE_CONNECTION=sync
|
|
288
|
+
INERTIA_SSR_ENABLED=false
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Vercel gives them to the build, which runs the migrations, and to the function. PostgreSQL needs `pg` in your
|
|
292
|
+
dependencies (`npm install pg`); Vercel's Marketplace has PostgreSQL databases with a free plan, which set `DB_URL`'s
|
|
293
|
+
value for you under a name of their own, such as `DATABASE_URL`: copy it into `DB_URL`. When the address says
|
|
294
|
+
`sslmode=require`, as Neon's do, `pg` warns on every cold start: write `sslmode=verify-full`, which also checks the
|
|
295
|
+
server's certificate.
|
|
296
|
+
|
|
297
|
+
### What changes on Vercel
|
|
298
|
+
|
|
299
|
+
Vercel starts an instance of the function when requests come, and stops it when they stop. The first request to a new
|
|
300
|
+
instance boots your app; the next ones reuse it. Nothing your app keeps in memory or on disk outlasts the instance,
|
|
301
|
+
and each instance has its own, so:
|
|
302
|
+
|
|
303
|
+
- **Your database is a server**, PostgreSQL or MySQL. The function's files are read-only, so SQLite can't write.
|
|
304
|
+
- **Sessions and the cache** need a store every instance shares: `database` (the kits have the `sessions` and `cache`
|
|
305
|
+
tables' migrations) or `redis`. Sessions can also use `cookie`. `file` and `array` don't outlast the instance.
|
|
306
|
+
- **Logs** go to stderr, which Vercel's logs show: the function sets `LOG_CHANNEL=stderr` when you don't set it.
|
|
307
|
+
- **Vercel's proxy is trusted.** Every request reaches the function through it, and it sets the `X-Forwarded-*`
|
|
308
|
+
headers itself, so the function trusts them when `trusted_proxies`, in `config/http.ts`, is empty: your URLs keep
|
|
309
|
+
the browser's `https`, and `request().ip()` is the visitor's (see
|
|
310
|
+
[Configuring trusted proxies](requests.md#configuring-trusted-proxies)).
|
|
311
|
+
- **Files your app stores** go on an `s3` disk (see [File storage](storage.md)): the `local` and `public` disks write
|
|
312
|
+
into `storage`, which the function can't.
|
|
313
|
+
- **No queue worker or scheduler runs.** With `QUEUE_CONNECTION=sync`, a job runs during the request that dispatches
|
|
314
|
+
it.
|
|
315
|
+
- **Inertia pages render in the browser**, as they do when no SSR server answers: the SSR server doesn't run on
|
|
316
|
+
Vercel. `INERTIA_SSR_ENABLED=false` skips asking it.
|
|
317
|
+
|
|
318
|
+
### Caching pages on the CDN
|
|
319
|
+
|
|
320
|
+
Pages that are the same for every visitor can be kept by Vercel's CDN, so that most requests for them never reach the
|
|
321
|
+
function. The `cache.headers` middleware sets their `Cache-Control`: `s_maxage` is how many seconds the CDN keeps a
|
|
322
|
+
page, and `stale_while_revalidate` how long it may still send the old copy while it fetches a new one:
|
|
323
|
+
|
|
324
|
+
```ts title="routes/web.ts"
|
|
325
|
+
import { Route, StartSession, VerifyCsrfToken, view } from '@orieljs/framework'
|
|
326
|
+
|
|
327
|
+
Route.get('/pricing', () => view('pricing'))
|
|
328
|
+
.middleware('cache.headers:public;s_maxage=3600;stale_while_revalidate=60')
|
|
329
|
+
.withoutMiddleware(StartSession, VerifyCsrfToken)
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
`cache.headers` leaves a response that sets a cookie alone, so that the CDN never hands one visitor's cookies to the
|
|
333
|
+
next. The `web` group's `StartSession` and `VerifyCsrfToken` set cookies on every page: take them off the pages you
|
|
334
|
+
cache, as above. Those pages have no session, so they can't show who is signed in.
|
|
335
|
+
|
|
241
336
|
## Debug mode
|
|
242
337
|
|
|
243
338
|
`debug` in `config/app.ts` reads `APP_DEBUG`, and decides how much an error response shows (see
|
package/docs/export.md
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Static export
|
|
2
|
+
|
|
3
|
+
When every visitor sees the same pages, `oriel export` saves your app's pages as plain files that any static host can
|
|
4
|
+
serve, with no Oriel server running.
|
|
5
|
+
|
|
6
|
+
## Introduction
|
|
7
|
+
|
|
8
|
+
A documentation site, a blog without comments, a product page: some apps answer every visitor the same way. For them,
|
|
9
|
+
running a server is optional. `oriel export` starts your app, asks it for each page the way a browser would, and writes
|
|
10
|
+
the answers to a folder. Upload the folder to any static host, such as Vercel, Netlify, GitHub Pages or an S3 bucket,
|
|
11
|
+
and the site works without a server.
|
|
12
|
+
|
|
13
|
+
The pages are still made by your app: its routes, controllers, views and middleware all run, once per page, while you
|
|
14
|
+
export. What an export can't keep is anything that happens per request: forms that post, sessions, logins, Live
|
|
15
|
+
components and anything else that needs the server to answer.
|
|
16
|
+
|
|
17
|
+
## Exporting your app
|
|
18
|
+
|
|
19
|
+
Build the assets first, then export:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
npm run build
|
|
23
|
+
node oriel export
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The site is written to `dist/`. The command lists the redirects it met and how many pages it wrote:
|
|
27
|
+
|
|
28
|
+
```text
|
|
29
|
+
Redirect /old → /about, not written.
|
|
30
|
+
Exported 24 pages to [dist] in 840 ms.
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`--output` writes somewhere else:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
node oriel export --output=site
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
The export only replaces a folder it made itself (or an empty one), so pointing `--output` at a folder that holds
|
|
40
|
+
other files stops it without deleting anything. It also stops while the Vite dev server runs (`public/hot` exists),
|
|
41
|
+
since the pages would point at the dev server: stop `npm run dev`, build, then export.
|
|
42
|
+
|
|
43
|
+
## Which pages are exported
|
|
44
|
+
|
|
45
|
+
The export starts at `/` and follows every link to the same site, using the origin of `app.url`. A link to another
|
|
46
|
+
site, a `mailto:` or `tel:` link, or a link to a file in `public/` is left alone. Query strings and `#anchors` are
|
|
47
|
+
ignored, so `/docs/routing?tab=1#named` exports `/docs/routing`.
|
|
48
|
+
|
|
49
|
+
Pages nothing links to, such as a feed, are listed in `paths`. Pages to leave out are listed in `exclude`, where `*`
|
|
50
|
+
matches anything. A redirect is listed in the command's output and not written; its target is exported when something
|
|
51
|
+
links to it.
|
|
52
|
+
|
|
53
|
+
A page that answers with an error (4xx or 5xx) stops the export and names the page. The site is written into a
|
|
54
|
+
temporary folder first, so the last export stays as it was.
|
|
55
|
+
|
|
56
|
+
## Configuration
|
|
57
|
+
|
|
58
|
+
Add a `config/export.ts` file to change the defaults:
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
export default {
|
|
62
|
+
output: 'dist',
|
|
63
|
+
crawl: true,
|
|
64
|
+
paths: ['/feed.xml'],
|
|
65
|
+
exclude: ['/drafts/*'],
|
|
66
|
+
file_names: 'html',
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
| Key | Default | |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| `output` | `'dist'` | The folder the site is written to, relative to the app |
|
|
73
|
+
| `crawl` | `true` | Follow links from `/` and from `paths`; `false` exports only those |
|
|
74
|
+
| `paths` | `[]` | Pages to export besides `/` |
|
|
75
|
+
| `exclude` | `[]` | Pages to leave out; `*` matches anything |
|
|
76
|
+
| `file_names` | `'html'` | `'html'` writes `/docs/routing` as `docs/routing.html`; `'directory'` writes `docs/routing/index.html` |
|
|
77
|
+
|
|
78
|
+
A path with an extension, such as `/feed.xml`, keeps its name in either style. The files in `public/`, your built
|
|
79
|
+
assets among them, are copied into the folder first.
|
|
80
|
+
|
|
81
|
+
## The 404 page
|
|
82
|
+
|
|
83
|
+
When your app has a 404 page (`resources/views/errors/404.tsx`), the export writes it as `404.html`. Vercel, Netlify
|
|
84
|
+
and GitHub Pages show that file for an address that doesn't exist.
|
|
85
|
+
|
|
86
|
+
## Hosting the files
|
|
87
|
+
|
|
88
|
+
- **Vercel and Netlify** serve `docs/routing.html` at `/docs/routing` when clean URLs are on (Vercel's `cleanUrls`,
|
|
89
|
+
Netlify's pretty URLs).
|
|
90
|
+
- **GitHub Pages** and most other hosts serve `docs/routing.html` at `/docs/routing.html`, and
|
|
91
|
+
`docs/routing/index.html` at `/docs/routing/`: export with `file_names: 'directory'` for addresses without `.html`.
|
|
92
|
+
|
|
93
|
+
To run your app live instead, with forms, sessions and Live components, see [Deployment](deployment.md).
|
package/docs/installation.md
CHANGED
|
@@ -197,6 +197,16 @@ node oriel migrate
|
|
|
197
197
|
|
|
198
198
|
For MySQL, `DB_CONNECTION` is `mysql` and the port is usually 3306.
|
|
199
199
|
|
|
200
|
+
## Editor support
|
|
201
|
+
|
|
202
|
+
The OrielJS extension for VS Code covers the strings Oriel reads at run time, where TypeScript can't help: it completes
|
|
203
|
+
validation rules, `config()` keys, `env()` names, view names, and the actions and properties in Live's `o:` attributes,
|
|
204
|
+
shows their docs when you hover, and warns about one your app doesn't have. It also runs `route:types` and
|
|
205
|
+
`inertia:types` again when your routes, controllers or pages change, and puts the `oriel` commands in the command
|
|
206
|
+
palette. Install it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=orieljs.orieljs),
|
|
207
|
+
or search for OrielJS in the editor's Extensions view. It needs Oriel 0.1.0-alpha.9 or later, and reads your app only
|
|
208
|
+
in a trusted workspace.
|
|
209
|
+
|
|
200
210
|
## Next steps
|
|
201
211
|
|
|
202
212
|
Read how an app is laid out in [Directory structure](structure.md), and how it reads its settings in
|
package/docs/middleware.md
CHANGED
|
@@ -231,6 +231,7 @@ they own.
|
|
|
231
231
|
| Alias | Middleware | What it does |
|
|
232
232
|
| --- | --- | --- |
|
|
233
233
|
| `auth` | `Authenticate` | Lets signed-in users through. A guest gets a 401 for JSON, or a redirect to the login page. `auth:token` names the guard; with several, the first that has a user wins |
|
|
234
|
+
| `cache.headers` | `SetCacheHeaders` | Sets `Cache-Control` on GET and HEAD responses, as `cache.headers:public;max_age=3600;s_maxage=86400;etag` (`etag` adds an ETag and answers 304 when it matches); a response that sets a cookie is left alone, so a CDN never stores one visitor's page |
|
|
234
235
|
| `can` | `Authorize` | Checks an ability with the gate, as `can:update,post`; a parameter that names a route parameter passes the bound model. A denial is a 403 |
|
|
235
236
|
| `guest` | `RedirectIfAuthenticated` | Lets guests through, and redirects signed-in users |
|
|
236
237
|
| `inertia.encrypt` | `EncryptHistory` | Encrypts the browser history state of the Inertia pages behind it |
|
package/docs/navigation.json
CHANGED
package/docs/starter-kits.md
CHANGED
|
@@ -194,6 +194,9 @@ And the component classes the pages are built from:
|
|
|
194
194
|
|
|
195
195
|
Utilities still override them: `<button class="btn btn-sm w-full">`.
|
|
196
196
|
|
|
197
|
+
In a production build, these names and Tailwind's are scrambled into short ones: every kit's `vite.config.ts` sets
|
|
198
|
+
`obfuscate: true` (see [Class name scrambling](vite.md#class-name-scrambling)).
|
|
199
|
+
|
|
197
200
|
### Accessibility
|
|
198
201
|
|
|
199
202
|
The kits are built to be read by everyone:
|
package/docs/vite.md
CHANGED
|
@@ -163,6 +163,84 @@ Give your CSS file to `input`, or import it from a script, and Vite processes it
|
|
|
163
163
|
built with Tailwind CSS, through `@tailwindcss/vite`. Vite's own CSS features, such as PostCSS and CSS modules, work as
|
|
164
164
|
its documentation describes.
|
|
165
165
|
|
|
166
|
+
## Class name scrambling
|
|
167
|
+
|
|
168
|
+
A production build can give your classes short, meaningless names: `items-center` becomes something like `k3vq` in the
|
|
169
|
+
built CSS, in your scripts, and in the HTML Oriel sends, so your pages give nothing away about how they are styled.
|
|
170
|
+
Every starter kit turns it on; `npm run dev` and your tests keep the names you wrote.
|
|
171
|
+
|
|
172
|
+
```ts title="vite.config.ts"
|
|
173
|
+
import { oriel } from '@orieljs/vite'
|
|
174
|
+
import { defineConfig } from 'vite'
|
|
175
|
+
|
|
176
|
+
export default defineConfig({
|
|
177
|
+
plugins: [oriel({ input: ['resources/css/app.css', 'resources/js/app.ts'], obfuscate: true })],
|
|
178
|
+
})
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
`npm run build` writes the names it chose to `bootstrap/cache/classes.json`, out of `public/`, where anyone could
|
|
182
|
+
download them and read your class names back. The SSR build reads them, so it runs after the client build, as the
|
|
183
|
+
kits' `build` script does. Oriel reads them too, and renames the classes in every HTML page it sends: your views,
|
|
184
|
+
Inertia's server-rendered pages, and Live's components and their updates, with Live's `o:loading-class` and
|
|
185
|
+
`o:offline-class`. Deploy `bootstrap/cache/classes.json` with your built assets. While `npm run dev` runs
|
|
186
|
+
(`public/hot` exists), and while your tests run, Oriel renames nothing.
|
|
187
|
+
|
|
188
|
+
A class keeps the same short name from one build to the next, so a script that didn't change keeps its contents and
|
|
189
|
+
its file name, and the browser's cached copy stays right.
|
|
190
|
+
|
|
191
|
+
### What gets renamed
|
|
192
|
+
|
|
193
|
+
In your scripts, the names in class positions: `class` and `className` props, properties named like `activeClass`,
|
|
194
|
+
`swatchClass` or `iconClasses`, `classList.add()` and its kin, `clsx()`, `cn()` and `classNames()`,
|
|
195
|
+
`el.className = …`, `setAttribute('class', …)`, the selectors you give `querySelector()`, `querySelectorAll()`,
|
|
196
|
+
`closest()` and `matches()`, and each framework's own forms: Vue's `:class`, Svelte's `class:` directives, Solid's
|
|
197
|
+
`classList`, Angular's `[class.name]`. A string anywhere else keeps its words, so `type: 'hidden'` is still a hidden
|
|
198
|
+
input, and a name your CSS doesn't define keeps its name.
|
|
199
|
+
|
|
200
|
+
Your dependencies keep their class names, and so do the classes their style sheets define, so a library's markup
|
|
201
|
+
always matches its CSS, whether you import it or the library injects it. CSS modules' names are hashed already, and
|
|
202
|
+
stay as Vite wrote them. `dark` is never renamed: the kits' appearance script sets it before the page draws.
|
|
203
|
+
|
|
204
|
+
### Names built from pieces
|
|
205
|
+
|
|
206
|
+
A class built from pieces at run time can't be renamed: `` `btn-${variant}` `` asks for `btn-primary`, which the
|
|
207
|
+
built CSS calls something else. The build lists each one it finds, with its file and line:
|
|
208
|
+
|
|
209
|
+
```text
|
|
210
|
+
These class names are built from pieces, so they aren't scrambled:
|
|
211
|
+
resources/js/components/Button.tsx:12: `btn-${variant}` builds a class name from pieces, so it keeps its name; …
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Write the whole name in a class position instead:
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
declare const button: { className: string }
|
|
218
|
+
declare const variant: 'primary' | 'danger'
|
|
219
|
+
// ---cut---
|
|
220
|
+
button.className = variant === 'danger' ? 'btn btn-danger' : 'btn btn-primary'
|
|
221
|
+
|
|
222
|
+
const variants = {
|
|
223
|
+
primary: { label: 'Save', buttonClass: 'btn btn-primary' },
|
|
224
|
+
danger: { label: 'Delete', buttonClass: 'btn btn-danger' },
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Or keep those names as they are, with `keep`:
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
import { oriel } from '@orieljs/vite'
|
|
232
|
+
// ---cut---
|
|
233
|
+
oriel({ input: ['resources/css/app.css', 'resources/js/app.ts'], obfuscate: { keep: ['btn-primary', 'btn-danger'] } })
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
`keep` is also for a class something outside the build looks for, such as a script on another site or a test that
|
|
237
|
+
reads a production page.
|
|
238
|
+
|
|
239
|
+
### Turning it off
|
|
240
|
+
|
|
241
|
+
`obfuscate: false`, or no `obfuscate` at all, which is the default: the build keeps your class names, removes an
|
|
242
|
+
earlier build's `classes.json`, and Oriel sends your HTML as it is.
|
|
243
|
+
|
|
166
244
|
## Working with views and routes
|
|
167
245
|
|
|
168
246
|
### Processing static assets with Vite
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orieljs/framework",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.11",
|
|
4
4
|
"description": "Oriel: a Laravel-style, full-stack TypeScript framework for Node.js and Bun.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -58,35 +58,37 @@
|
|
|
58
58
|
"pluralize": "8.0.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@orieljs/
|
|
62
|
-
"@orieljs/
|
|
63
|
-
"@orieljs/console": "0.1.0-alpha.
|
|
64
|
-
"@orieljs/
|
|
65
|
-
"@orieljs/
|
|
66
|
-
"@orieljs/
|
|
67
|
-
"@orieljs/
|
|
68
|
-
"@orieljs/
|
|
69
|
-
"@orieljs/
|
|
70
|
-
"@orieljs/
|
|
71
|
-
"@orieljs/
|
|
72
|
-
"@orieljs/
|
|
73
|
-
"@orieljs/
|
|
74
|
-
"@orieljs/
|
|
75
|
-
"@orieljs/
|
|
76
|
-
"@orieljs/
|
|
77
|
-
"@orieljs/
|
|
78
|
-
"@orieljs/log": "0.1.0-alpha.
|
|
79
|
-
"@orieljs/mail": "0.1.0-alpha.
|
|
80
|
-
"@orieljs/notifications": "0.1.0-alpha.
|
|
81
|
-
"@orieljs/
|
|
82
|
-
"@orieljs/
|
|
83
|
-
"@orieljs/
|
|
84
|
-
"@orieljs/
|
|
85
|
-
"@orieljs/
|
|
86
|
-
"@orieljs/
|
|
87
|
-
"@orieljs/
|
|
88
|
-
"@orieljs/view": "0.1.0-alpha.
|
|
89
|
-
"@orieljs/routing": "0.1.0-alpha.
|
|
61
|
+
"@orieljs/auth": "0.1.0-alpha.11",
|
|
62
|
+
"@orieljs/collections": "0.1.0-alpha.11",
|
|
63
|
+
"@orieljs/console": "0.1.0-alpha.11",
|
|
64
|
+
"@orieljs/config": "0.1.0-alpha.11",
|
|
65
|
+
"@orieljs/contracts": "0.1.0-alpha.11",
|
|
66
|
+
"@orieljs/container": "0.1.0-alpha.11",
|
|
67
|
+
"@orieljs/cache": "0.1.0-alpha.11",
|
|
68
|
+
"@orieljs/bus": "0.1.0-alpha.11",
|
|
69
|
+
"@orieljs/database": "0.1.0-alpha.11",
|
|
70
|
+
"@orieljs/cookie": "0.1.0-alpha.11",
|
|
71
|
+
"@orieljs/encryption": "0.1.0-alpha.11",
|
|
72
|
+
"@orieljs/events": "0.1.0-alpha.11",
|
|
73
|
+
"@orieljs/filesystem": "0.1.0-alpha.11",
|
|
74
|
+
"@orieljs/hashing": "0.1.0-alpha.11",
|
|
75
|
+
"@orieljs/http": "0.1.0-alpha.11",
|
|
76
|
+
"@orieljs/inertia": "0.1.0-alpha.11",
|
|
77
|
+
"@orieljs/live": "0.1.0-alpha.11",
|
|
78
|
+
"@orieljs/log": "0.1.0-alpha.11",
|
|
79
|
+
"@orieljs/mail": "0.1.0-alpha.11",
|
|
80
|
+
"@orieljs/notifications": "0.1.0-alpha.11",
|
|
81
|
+
"@orieljs/obfuscate": "0.1.0-alpha.11",
|
|
82
|
+
"@orieljs/pipeline": "0.1.0-alpha.11",
|
|
83
|
+
"@orieljs/queue": "0.1.0-alpha.11",
|
|
84
|
+
"@orieljs/support": "0.1.0-alpha.11",
|
|
85
|
+
"@orieljs/testing": "0.1.0-alpha.11",
|
|
86
|
+
"@orieljs/foundation": "0.1.0-alpha.11",
|
|
87
|
+
"@orieljs/validation": "0.1.0-alpha.11",
|
|
88
|
+
"@orieljs/view": "0.1.0-alpha.11",
|
|
89
|
+
"@orieljs/routing": "0.1.0-alpha.11",
|
|
90
|
+
"@orieljs/session": "0.1.0-alpha.11",
|
|
91
|
+
"@orieljs/vercel": "0.1.0-alpha.11"
|
|
90
92
|
},
|
|
91
93
|
"peerDependencies": {
|
|
92
94
|
"pg": "^8.23.0",
|