@orieljs/framework 0.1.0-alpha.1 → 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/NOTICE +7 -0
- package/README.md +10 -1
- package/TRADEMARKS.md +33 -0
- package/dist/{chunk-WI7E7Q46.js → chunk-24673JQF.js} +8 -4
- package/dist/chunk-24673JQF.js.map +1 -0
- package/dist/{chunk-K6MAA3RM.js → chunk-HTJKT2R2.js} +9 -1
- package/dist/chunk-HTJKT2R2.js.map +1 -0
- package/dist/chunk-KDE5BLI3.js +8776 -0
- package/dist/chunk-KDE5BLI3.js.map +1 -0
- package/dist/chunk-MURTCTRH.js +3253 -0
- package/dist/chunk-MURTCTRH.js.map +1 -0
- package/dist/contracts.d.ts +852 -168
- package/dist/contracts.js +9 -1
- package/dist/index.d-WQpfdIbG.d.ts +630 -0
- package/dist/index.d.ts +3015 -5160
- package/dist/index.js +7628 -2640
- package/dist/index.js.map +1 -1
- package/dist/{jsx-runtime-B8J6xq-7.d.ts → jsx-runtime-6um4Mwfb.d.ts} +99 -149
- package/dist/jsx-runtime.d.ts +3 -1
- package/dist/jsx-runtime.js +3 -3
- package/dist/testing-CKwfWJGn.d.ts +1586 -0
- package/dist/testing.d.ts +3 -1408
- package/dist/testing.js +29 -5
- package/docs/authentication.md +487 -0
- package/docs/authorization.md +435 -0
- package/docs/cache.md +647 -0
- package/docs/collections.md +2270 -0
- package/docs/configuration.md +334 -0
- package/docs/console.md +654 -0
- package/docs/container.md +430 -0
- package/docs/controllers.md +406 -0
- package/docs/csrf.md +126 -0
- package/docs/database-testing.md +144 -0
- package/docs/database.md +236 -0
- package/docs/deployment.md +371 -0
- package/docs/eloquent-collections.md +218 -0
- package/docs/eloquent-factories.md +255 -0
- package/docs/eloquent-mutators.md +254 -0
- package/docs/eloquent-observers.md +145 -0
- package/docs/eloquent-relationships.md +557 -0
- package/docs/eloquent.md +494 -0
- package/docs/encryption.md +104 -0
- package/docs/errors.md +318 -0
- package/docs/events.md +336 -0
- package/docs/export.md +93 -0
- package/docs/facades.md +278 -0
- package/docs/hashing.md +118 -0
- package/docs/helpers.md +1281 -0
- package/docs/http-tests.md +386 -0
- package/docs/inertia.md +485 -0
- package/docs/installation.md +219 -0
- package/docs/lifecycle.md +234 -0
- package/docs/live-tests.md +226 -0
- package/docs/live.md +910 -0
- package/docs/logging.md +255 -0
- package/docs/mail.md +619 -0
- package/docs/middleware.md +385 -0
- package/docs/migrations.md +416 -0
- package/docs/mocking.md +264 -0
- package/docs/navigation.json +277 -0
- package/docs/notifications.md +225 -0
- package/docs/pagination.md +247 -0
- package/docs/passwords.md +207 -0
- package/docs/providers.md +187 -0
- package/docs/queries.md +600 -0
- package/docs/queues.md +330 -0
- package/docs/requests.md +533 -0
- package/docs/responses.md +444 -0
- package/docs/routing.md +738 -0
- package/docs/scheduling.md +277 -0
- package/docs/seeding.md +122 -0
- package/docs/session.md +409 -0
- package/docs/starter-kits.md +399 -0
- package/docs/storage.md +192 -0
- package/docs/structure.md +264 -0
- package/docs/testing.md +165 -0
- package/docs/time-travel.md +138 -0
- package/docs/validation.md +1792 -0
- package/docs/verification.md +152 -0
- package/docs/views.md +566 -0
- package/docs/vite.md +400 -0
- package/package.json +37 -30
- package/dist/chunk-AI2RFMBT.js +0 -745
- package/dist/chunk-AI2RFMBT.js.map +0 -1
- package/dist/chunk-BZPCRKFQ.js +0 -2941
- package/dist/chunk-BZPCRKFQ.js.map +0 -1
- package/dist/chunk-K6MAA3RM.js.map +0 -1
- package/dist/chunk-WI7E7Q46.js.map +0 -1
package/docs/vite.md
ADDED
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# Asset bundling (Vite)
|
|
2
|
+
|
|
3
|
+
Vite bundles your pages' scripts and styles. While you work, it serves them and updates them in the browser as you
|
|
4
|
+
edit them; for production, it builds them into `public/build`.
|
|
5
|
+
|
|
6
|
+
## Introduction
|
|
7
|
+
|
|
8
|
+
Oriel's Vite plugin, `oriel()` from `@orieljs/vite`, connects Vite and your app, as Laravel's `laravel-vite-plugin`
|
|
9
|
+
does: your views load the right files with `vite()`, from the dev server while it runs and from the build otherwise.
|
|
10
|
+
|
|
11
|
+
Every starter kit except the API kit has Vite set up. The API kit has no pages, so it has no `vite.config.ts` and no
|
|
12
|
+
`dev` or `build` script.
|
|
13
|
+
|
|
14
|
+
## Installation and setup
|
|
15
|
+
|
|
16
|
+
### Installing Node
|
|
17
|
+
|
|
18
|
+
Vite runs on Node 22 or later, or Bun, as your app does.
|
|
19
|
+
|
|
20
|
+
### Installing Vite and the Oriel plugin
|
|
21
|
+
|
|
22
|
+
Every new app lists `vite` and `@orieljs/vite` in `package.json`, the API kit's too: its tests use them. To give an API
|
|
23
|
+
app pages, add a `vite.config.ts` as below, and `"dev": "vite"` and `"build": "vite build"` to its scripts.
|
|
24
|
+
|
|
25
|
+
### Configuring Vite
|
|
26
|
+
|
|
27
|
+
`vite.config.ts`, in your app's root, lists your entry points, the files your pages load:
|
|
28
|
+
|
|
29
|
+
```ts title="vite.config.ts"
|
|
30
|
+
import { oriel } from '@orieljs/vite'
|
|
31
|
+
import { defineConfig } from 'vite'
|
|
32
|
+
|
|
33
|
+
export default defineConfig({
|
|
34
|
+
plugins: [oriel({ input: ['resources/css/app.css', 'resources/js/app.ts'] })],
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
An Inertia app names its framework, which loads that framework's Vite plugin (`@vitejs/plugin-react` for React), and
|
|
39
|
+
its server entry for SSR. The React kit's:
|
|
40
|
+
|
|
41
|
+
```ts title="vite.config.ts"
|
|
42
|
+
import { oriel } from '@orieljs/vite'
|
|
43
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
44
|
+
import { defineConfig } from 'vite'
|
|
45
|
+
|
|
46
|
+
export default defineConfig({
|
|
47
|
+
plugins: [
|
|
48
|
+
tailwindcss(),
|
|
49
|
+
oriel({ framework: 'react', input: ['resources/css/app.css', 'resources/js/app.tsx'], ssr: 'resources/js/ssr.tsx' }),
|
|
50
|
+
],
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`framework` is `'react'`, `'vue'`, `'svelte'`, `'solid'` or `'angular'`. The Live kit names none: its components render
|
|
55
|
+
on the server.
|
|
56
|
+
|
|
57
|
+
| Option | What it is |
|
|
58
|
+
| --- | --- |
|
|
59
|
+
| `input` | The entry points |
|
|
60
|
+
| `framework` | The Inertia framework, whose Vite plugin it loads |
|
|
61
|
+
| `frameworkOptions` | Options for that plugin |
|
|
62
|
+
| `ssr` | The SSR entry, found by itself (`resources/js/ssr.tsx`) unless you name it; `false` turns SSR off |
|
|
63
|
+
| `inertia` | Options for `@inertiajs/vite`, or `false` to leave it out |
|
|
64
|
+
| `refresh` | The server files that reload the page when they change: `true` for the defaults, `false`, or your own globs |
|
|
65
|
+
| `types` | The generated page and route types: `true`, `false`, or `{ pages, routes, command }` |
|
|
66
|
+
| `publicDirectory`, `buildDirectory` | Where the build goes: `public` and `build` |
|
|
67
|
+
| `hotFile` | The file that tells your app the dev server is running: `public/hot` |
|
|
68
|
+
| `ssrOutputDirectory` | Where the SSR build goes: `bootstrap/ssr` |
|
|
69
|
+
|
|
70
|
+
### Loading your scripts and styles
|
|
71
|
+
|
|
72
|
+
`vite()` in a view writes the tags for your entry points:
|
|
73
|
+
|
|
74
|
+
```tsx title="resources/views/app.tsx"
|
|
75
|
+
import { vite } from '@orieljs/framework'
|
|
76
|
+
|
|
77
|
+
export default function App() {
|
|
78
|
+
return (
|
|
79
|
+
<html lang="en">
|
|
80
|
+
<head>
|
|
81
|
+
<meta charset="utf-8" />
|
|
82
|
+
{vite(['resources/css/app.css', 'resources/js/app.ts'])}
|
|
83
|
+
</head>
|
|
84
|
+
<body>...</body>
|
|
85
|
+
</html>
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
While the dev server runs, the tags point at it. Otherwise they point at the built files, with the scripts and styles
|
|
91
|
+
they import preloaded. Each script and stylesheet tag carries `data-navigate-track`, so Live's `o:navigate` loads a
|
|
92
|
+
page in full when it names a new build's files; `useScriptTagAttributes({ 'data-navigate-track': false })` leaves it
|
|
93
|
+
out. A file that isn't in the build throws a `ViteError`: "Unable to locate file in Vite manifest:
|
|
94
|
+
resources/js/app.ts.".
|
|
95
|
+
|
|
96
|
+
A React app also needs `viteReactRefresh()` before `vite()`, so that React's fast refresh works while you work:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
const head = (
|
|
100
|
+
<head>
|
|
101
|
+
{viteReactRefresh()}
|
|
102
|
+
{vite(['resources/css/app.css', 'resources/js/app.tsx'])}
|
|
103
|
+
</head>
|
|
104
|
+
)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Running Vite
|
|
108
|
+
|
|
109
|
+
`npm run dev` starts the dev server, and `npm run build` builds your assets for production:
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
npm run dev
|
|
113
|
+
|
|
114
|
+
npm run build
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Run your app's server next to the dev server, in a second terminal: `node oriel serve --watch`.
|
|
118
|
+
[Running your application](installation.md#running-your-application) explains how the two work together.
|
|
119
|
+
|
|
120
|
+
The kits with SSR build twice, `vite build && vite build --ssr`: the browser's bundle into `public/build`, and the
|
|
121
|
+
server's into `bootstrap/ssr`.
|
|
122
|
+
|
|
123
|
+
While the dev server runs, it writes its URL to `public/hot`, and deletes the file when it stops. Don't deploy that
|
|
124
|
+
file: while it exists, your pages load their assets from a dev server that isn't there.
|
|
125
|
+
|
|
126
|
+
## Working with JavaScript
|
|
127
|
+
|
|
128
|
+
### Aliases
|
|
129
|
+
|
|
130
|
+
`@` is `resources/js`, so you can import `@/components/Button` from anywhere in your scripts.
|
|
131
|
+
|
|
132
|
+
### Inertia
|
|
133
|
+
|
|
134
|
+
The plugin loads `@inertiajs/vite`, which finds your pages in `resources/js/pages` and builds the SSR bundle. The
|
|
135
|
+
[Inertia](inertia.md) page covers the rest.
|
|
136
|
+
|
|
137
|
+
### Generated types
|
|
138
|
+
|
|
139
|
+
In an Inertia app, the plugin writes your pages' prop types to `resources/js/oriel/pages.d.ts` and runs
|
|
140
|
+
`oriel route:types`, which writes the route table behind `route()` in your pages. It runs both when Vite starts, and
|
|
141
|
+
again while `npm run dev` runs: the page types when a file in `app` or `routes` changes, the route types when one in
|
|
142
|
+
`routes` or `app/Http/Controllers` does. `types: false` turns it off, and `types: { routes: false }` keeps the page
|
|
143
|
+
types only.
|
|
144
|
+
|
|
145
|
+
### Environment variables
|
|
146
|
+
|
|
147
|
+
Vite gives your scripts the variables in `.env` that start with `VITE_`, and only those:
|
|
148
|
+
|
|
149
|
+
```sh
|
|
150
|
+
VITE_SENTRY_DSN_PUBLIC=https://example.com
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
```ts nocheck
|
|
154
|
+
const dsn = import.meta.env.VITE_SENTRY_DSN_PUBLIC
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
> [!WARNING]
|
|
158
|
+
> Every `VITE_` variable ends up in the scripts anyone can download. Keep your secrets in other variables.
|
|
159
|
+
|
|
160
|
+
## Working with stylesheets
|
|
161
|
+
|
|
162
|
+
Give your CSS file to `input`, or import it from a script, and Vite processes it: the kits' `resources/css/app.css` is
|
|
163
|
+
built with Tailwind CSS, through `@tailwindcss/vite`. Vite's own CSS features, such as PostCSS and CSS modules, work as
|
|
164
|
+
its documentation describes.
|
|
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
|
+
|
|
244
|
+
## Working with views and routes
|
|
245
|
+
|
|
246
|
+
### Processing static assets with Vite
|
|
247
|
+
|
|
248
|
+
An image your script imports is in the build, with a hashed name. `vite().asset()` gives its URL in a view; to have
|
|
249
|
+
images that no script imports built too, import them as a glob in your entry point:
|
|
250
|
+
|
|
251
|
+
```ts title="resources/js/app.ts"
|
|
252
|
+
import.meta.glob(['../images/**'])
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
```tsx
|
|
256
|
+
const logo = <img src={vite().asset('resources/images/logo.png')} alt="Logo" />
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
`vite().content('resources/css/mail.css')` gives a built file's contents, such as styles to put in a mail.
|
|
260
|
+
|
|
261
|
+
### Refreshing on save
|
|
262
|
+
|
|
263
|
+
When a view, a route file, a translation or a Live component changes, Vite reloads the page in the browser:
|
|
264
|
+
|
|
265
|
+
| Folder | Reloads |
|
|
266
|
+
| --- | --- |
|
|
267
|
+
| `resources/views/**` | Views |
|
|
268
|
+
| `routes/**` | Route files |
|
|
269
|
+
| `app/Live/**` | Live components |
|
|
270
|
+
| `lang/**`, `resources/lang/**` | Translations |
|
|
271
|
+
|
|
272
|
+
`refresh` takes your own list instead: `refresh: ['resources/views/**', 'app/Http/Controllers/**']`.
|
|
273
|
+
|
|
274
|
+
> [!NOTE]
|
|
275
|
+
> Vite reloads the page as soon as the file changes, often before `serve --watch` has restarted the server, and it
|
|
276
|
+
> doesn't reload again once the new server is up. After "Restarting server...", reload the page once more.
|
|
277
|
+
|
|
278
|
+
## Custom base URLs
|
|
279
|
+
|
|
280
|
+
To serve your built assets from another host, such as a CDN, set `ASSET_URL` in `.env`. The build reads it, so the
|
|
281
|
+
URLs inside your scripts and styles start with it:
|
|
282
|
+
|
|
283
|
+
```sh
|
|
284
|
+
ASSET_URL=https://cdn.example.com
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
The tags `vite()` writes, and `asset()`, use `app.asset_url`. A new app's `config/app.ts` doesn't have it, so add it:
|
|
288
|
+
|
|
289
|
+
```ts title="config/app.ts"
|
|
290
|
+
import { env } from '@orieljs/framework'
|
|
291
|
+
|
|
292
|
+
export default {
|
|
293
|
+
// ...
|
|
294
|
+
asset_url: env('ASSET_URL'),
|
|
295
|
+
}
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Disabling Vite in tests
|
|
299
|
+
|
|
300
|
+
A test that renders a page needs the build's manifest, unless Vite is off. `withoutVite()` makes `vite()` and
|
|
301
|
+
`viteReactRefresh()` write nothing for the rest of the test. The `TestCase` of the starter kits with pages calls it
|
|
302
|
+
for every test:
|
|
303
|
+
|
|
304
|
+
```ts title="tests/TestCase.ts"
|
|
305
|
+
import { TestCase as BaseTestCase } from '@orieljs/framework/testing'
|
|
306
|
+
import type { Application } from '@orieljs/framework'
|
|
307
|
+
import { afterEach, beforeEach } from 'vitest'
|
|
308
|
+
import { createApplication } from '../bootstrap/app'
|
|
309
|
+
|
|
310
|
+
export class TestCase extends BaseTestCase {
|
|
311
|
+
static override hooks = { beforeEach, afterEach }
|
|
312
|
+
|
|
313
|
+
override createApplication(): Promise<Application> {
|
|
314
|
+
return createApplication()
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
override async setUp(): Promise<void> {
|
|
318
|
+
await super.setUp()
|
|
319
|
+
this.withoutVite()
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Decorators in tests
|
|
325
|
+
|
|
326
|
+
Vitest transforms your TypeScript with Oxc, which leaves TC39 decorators, such as Live's `@On`, in place, and Node
|
|
327
|
+
can't run them yet. The `decorators()` plugin lowers them; a new app's `vitest.config.ts` has it:
|
|
328
|
+
|
|
329
|
+
```ts title="vitest.config.ts"
|
|
330
|
+
import { decorators } from '@orieljs/vite'
|
|
331
|
+
import { defineConfig } from 'vitest/config'
|
|
332
|
+
|
|
333
|
+
export default defineConfig({
|
|
334
|
+
plugins: [decorators()],
|
|
335
|
+
})
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## Server-side rendering (SSR)
|
|
339
|
+
|
|
340
|
+
`ssr` names the server entry of an Inertia app, and `vite build --ssr` builds it into `bootstrap/ssr`. While the dev
|
|
341
|
+
server runs, it renders the pages on the server itself. The Angular kit has no SSR. [Inertia
|
|
342
|
+
SSR](starter-kits.md#inertia-ssr) covers running the SSR server.
|
|
343
|
+
|
|
344
|
+
## Script and style tag attributes
|
|
345
|
+
|
|
346
|
+
### Content Security Policy (CSP) nonce
|
|
347
|
+
|
|
348
|
+
`vite().useCspNonce()` makes a nonce for the request, and the tags `vite()` writes carry it. Call it in a middleware,
|
|
349
|
+
and send the same nonce in your policy:
|
|
350
|
+
|
|
351
|
+
```ts title="app/Http/Middleware/AddContentSecurityPolicyHeaders.ts"
|
|
352
|
+
import { vite } from '@orieljs/framework'
|
|
353
|
+
import type { HttpRequest, Middleware, Next } from '@orieljs/framework/contracts'
|
|
354
|
+
|
|
355
|
+
export class AddContentSecurityPolicyHeaders implements Middleware {
|
|
356
|
+
async handle(request: HttpRequest, next: Next): Promise<Response> {
|
|
357
|
+
const nonce = vite().useCspNonce()
|
|
358
|
+
|
|
359
|
+
const response = await next(request)
|
|
360
|
+
|
|
361
|
+
response.headers.set('Content-Security-Policy', `script-src 'nonce-${nonce}'`)
|
|
362
|
+
|
|
363
|
+
return response
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
`vite().cspNonce()` gives the nonce, for your own inline scripts: `<script nonce={vite().cspNonce()}>`. The starter
|
|
369
|
+
kits' appearance script and welcome page use it. Each request has its own `vite()`, so the nonce stays in its request.
|
|
370
|
+
|
|
371
|
+
### Subresource Integrity (SRI)
|
|
372
|
+
|
|
373
|
+
When the manifest gives each file an `integrity` hash, such as one a plugin like `vite-plugin-manifest-sri` adds, the
|
|
374
|
+
tags carry it. `vite().useIntegrityKey('hash')` reads another key, and `useIntegrityKey(false)` leaves it out.
|
|
375
|
+
|
|
376
|
+
### Arbitrary attributes
|
|
377
|
+
|
|
378
|
+
`useScriptTagAttributes()` and `useStyleTagAttributes()` add attributes to the tags, as an object or a function of the
|
|
379
|
+
file:
|
|
380
|
+
|
|
381
|
+
```ts
|
|
382
|
+
vite().useScriptTagAttributes({ 'data-turbo-track': 'reload', async: true })
|
|
383
|
+
|
|
384
|
+
vite().useStyleTagAttributes((src) => (src === 'resources/css/app.css' ? { 'data-theme': 'main' } : {}))
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
A value of `true` writes a bare attribute, and `false` leaves the attribute out. `usePreloadTagAttributes(false)` drops
|
|
388
|
+
the preload tags.
|
|
389
|
+
|
|
390
|
+
## Advanced customization
|
|
391
|
+
|
|
392
|
+
`vite()` also has `useHotFile()`, `useBuildDirectory()`, `useManifestFilename()` and `createAssetPathsUsing()`, for a
|
|
393
|
+
build that isn't in the usual place. Set them in a middleware, as the nonce is, or pass the build folder to `vite()`:
|
|
394
|
+
`vite(['resources/js/admin.ts'], 'admin-build')`.
|
|
395
|
+
|
|
396
|
+
### Dev server CORS
|
|
397
|
+
|
|
398
|
+
Your pages, on your app's URL, load scripts from the dev server, on another port. The dev server lets your `APP_URL`,
|
|
399
|
+
`localhost` and any `.test` host load them. For another origin, set `server.cors` in `vite.config.ts`, as Vite's
|
|
400
|
+
documentation describes.
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
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",
|
|
7
|
+
"homepage": "https://orieljs.vercel.app",
|
|
7
8
|
"sideEffects": false,
|
|
8
9
|
"repository": {
|
|
9
10
|
"type": "git",
|
|
@@ -37,8 +38,10 @@
|
|
|
37
38
|
},
|
|
38
39
|
"files": [
|
|
39
40
|
"dist",
|
|
41
|
+
"docs",
|
|
40
42
|
"LICENSE",
|
|
41
|
-
"NOTICE"
|
|
43
|
+
"NOTICE",
|
|
44
|
+
"TRADEMARKS.md"
|
|
42
45
|
],
|
|
43
46
|
"dependencies": {
|
|
44
47
|
"@aws-sdk/client-s3": "3.1139.0",
|
|
@@ -55,33 +58,37 @@
|
|
|
55
58
|
"pluralize": "8.0.0"
|
|
56
59
|
},
|
|
57
60
|
"devDependencies": {
|
|
58
|
-
"@orieljs/auth": "0.1.0-alpha.
|
|
59
|
-
"@orieljs/
|
|
60
|
-
"@orieljs/
|
|
61
|
-
"@orieljs/
|
|
62
|
-
"@orieljs/
|
|
63
|
-
"@orieljs/
|
|
64
|
-
"@orieljs/
|
|
65
|
-
"@orieljs/
|
|
66
|
-
"@orieljs/
|
|
67
|
-
"@orieljs/
|
|
68
|
-
"@orieljs/encryption": "0.1.0-alpha.
|
|
69
|
-
"@orieljs/events": "0.1.0-alpha.
|
|
70
|
-
"@orieljs/filesystem": "0.1.0-alpha.
|
|
71
|
-
"@orieljs/
|
|
72
|
-
"@orieljs/
|
|
73
|
-
"@orieljs/
|
|
74
|
-
"@orieljs/
|
|
75
|
-
"@orieljs/
|
|
76
|
-
"@orieljs/
|
|
77
|
-
"@orieljs/
|
|
78
|
-
"@orieljs/
|
|
79
|
-
"@orieljs/
|
|
80
|
-
"@orieljs/
|
|
81
|
-
"@orieljs/support": "0.1.0-alpha.
|
|
82
|
-
"@orieljs/testing": "0.1.0-alpha.
|
|
83
|
-
"@orieljs/
|
|
84
|
-
"@orieljs/
|
|
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"
|
|
85
92
|
},
|
|
86
93
|
"peerDependencies": {
|
|
87
94
|
"pg": "^8.23.0",
|
|
@@ -96,6 +103,6 @@
|
|
|
96
103
|
}
|
|
97
104
|
},
|
|
98
105
|
"scripts": {
|
|
99
|
-
"build": "tsup && node ../../../scripts/copy-license.mjs"
|
|
106
|
+
"build": "tsup && node ../../../scripts/copy-license.mjs && node ../../../scripts/copy-docs.mjs"
|
|
100
107
|
}
|
|
101
108
|
}
|